//
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

//
// Build the intermediate representation.
//

#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
#include <vector>

#include "common/mathutil.h"
#include "common/matrix_utils.h"
#include "compiler/translator/Diagnostics.h"
#include "compiler/translator/ImmutableString.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/util.h"

namespace sh
{

namespace
{

const float kPi                         = 3.14159265358979323846f;
const float kDegreesToRadiansMultiplier = kPi / 180.0f;
const float kRadiansToDegreesMultiplier = 180.0f / kPi;

TPrecision GetHigherPrecision(TPrecision left, TPrecision right)
{
    return left > right ? left : right;
}

TConstantUnion *Vectorize(const TConstantUnion &constant, size_t size)
{
    TConstantUnion *constUnion = new TConstantUnion[size];
    for (unsigned int i = 0; i < size; ++i)
        constUnion[i] = constant;

    return constUnion;
}

void UndefinedConstantFoldingError(const TSourceLoc &loc,
                                   TOperator op,
                                   TBasicType basicType,
                                   TDiagnostics *diagnostics,
                                   TConstantUnion *result)
{
    diagnostics->warning(loc, "operation result is undefined for the values passed in",
                         GetOperatorString(op));

    switch (basicType)
    {
        case EbtFloat:
            result->setFConst(0.0f);
            break;
        case EbtInt:
            result->setIConst(0);
            break;
        case EbtUInt:
            result->setUConst(0u);
            break;
        case EbtBool:
            result->setBConst(false);
            break;
        default:
            break;
    }
}

float VectorLength(const TConstantUnion *paramArray, size_t paramArraySize)
{
    float result = 0.0f;
    for (size_t i = 0; i < paramArraySize; i++)
    {
        float f = paramArray[i].getFConst();
        result += f * f;
    }
    return sqrtf(result);
}

float VectorDotProduct(const TConstantUnion *paramArray1,
                       const TConstantUnion *paramArray2,
                       size_t paramArraySize)
{
    float result = 0.0f;
    for (size_t i = 0; i < paramArraySize; i++)
        result += paramArray1[i].getFConst() * paramArray2[i].getFConst();
    return result;
}

TIntermTyped *CreateFoldedNode(const TConstantUnion *constArray, const TIntermTyped *originalNode)
{
    ASSERT(constArray != nullptr);
    // Note that we inherit whatever qualifier the folded node had. Nodes may be constant folded
    // without being qualified as constant.
    TIntermTyped *folded = new TIntermConstantUnion(constArray, originalNode->getType());
    folded->setLine(originalNode->getLine());
    return folded;
}

angle::Matrix<float> GetMatrix(const TConstantUnion *paramArray,
                               const unsigned int rows,
                               const unsigned int cols)
{
    std::vector<float> elements;
    for (size_t i = 0; i < rows * cols; i++)
        elements.push_back(paramArray[i].getFConst());
    // Transpose is used since the Matrix constructor expects arguments in row-major order,
    // whereas the paramArray is in column-major order. Rows/cols parameters are also flipped below
    // so that the created matrix will have the expected dimensions after the transpose.
    return angle::Matrix<float>(elements, cols, rows).transpose();
}

angle::Matrix<float> GetMatrix(const TConstantUnion *paramArray, const unsigned int size)
{
    std::vector<float> elements;
    for (size_t i = 0; i < size * size; i++)
        elements.push_back(paramArray[i].getFConst());
    // Transpose is used since the Matrix constructor expects arguments in row-major order,
    // whereas the paramArray is in column-major order.
    return angle::Matrix<float>(elements, size).transpose();
}

void SetUnionArrayFromMatrix(const angle::Matrix<float> &m, TConstantUnion *resultArray)
{
    // Transpose is used since the input Matrix is in row-major order,
    // whereas the actual result should be in column-major order.
    angle::Matrix<float> result       = m.transpose();
    std::vector<float> resultElements = result.elements();
    for (size_t i = 0; i < resultElements.size(); i++)
        resultArray[i].setFConst(resultElements[i]);
}

bool CanFoldAggregateBuiltInOp(TOperator op)
{
    switch (op)
    {
        case EOpAtan:
        case EOpPow:
        case EOpMod:
        case EOpMin:
        case EOpMax:
        case EOpClamp:
        case EOpMix:
        case EOpStep:
        case EOpSmoothstep:
        case EOpLdexp:
        case EOpMulMatrixComponentWise:
        case EOpOuterProduct:
        case EOpEqualComponentWise:
        case EOpNotEqualComponentWise:
        case EOpLessThanComponentWise:
        case EOpLessThanEqualComponentWise:
        case EOpGreaterThanComponentWise:
        case EOpGreaterThanEqualComponentWise:
        case EOpDistance:
        case EOpDot:
        case EOpCross:
        case EOpFaceforward:
        case EOpReflect:
        case EOpRefract:
        case EOpBitfieldExtract:
        case EOpBitfieldInsert:
            return true;
        default:
            return false;
    }
}

}  // namespace

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

TIntermExpression::TIntermExpression(const TType &t) : TIntermTyped(), mType(t) {}

void TIntermExpression::setTypePreservePrecision(const TType &t)
{
    TPrecision precision = getPrecision();
    mType                = t;
    ASSERT(mType.getBasicType() != EbtBool || precision == EbpUndefined);
    mType.setPrecision(precision);
}

#define REPLACE_IF_IS(node, type, original, replacement) \
    do                                                   \
    {                                                    \
        if (node == original)                            \
        {                                                \
            node = static_cast<type *>(replacement);     \
            return true;                                 \
        }                                                \
    } while (0)

size_t TIntermSymbol::getChildCount() const
{
    return 0;
}

TIntermNode *TIntermSymbol::getChildNode(size_t index) const
{
    UNREACHABLE();
    return nullptr;
}

size_t TIntermConstantUnion::getChildCount() const
{
    return 0;
}

TIntermNode *TIntermConstantUnion::getChildNode(size_t index) const
{
    UNREACHABLE();
    return nullptr;
}

size_t TIntermLoop::getChildCount() const
{
    return (mInit ? 1 : 0) + (mCond ? 1 : 0) + (mExpr ? 1 : 0) + (mBody ? 1 : 0);
}

TIntermNode *TIntermLoop::getChildNode(size_t index) const
{
    TIntermNode *children[4];
    unsigned int childIndex = 0;
    if (mInit)
    {
        children[childIndex] = mInit;
        ++childIndex;
    }
    if (mCond)
    {
        children[childIndex] = mCond;
        ++childIndex;
    }
    if (mExpr)
    {
        children[childIndex] = mExpr;
        ++childIndex;
    }
    if (mBody)
    {
        children[childIndex] = mBody;
        ++childIndex;
    }
    ASSERT(index < childIndex);
    return children[index];
}

bool TIntermLoop::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
{
    ASSERT(original != nullptr);  // This risks replacing multiple children.
    REPLACE_IF_IS(mInit, TIntermNode, original, replacement);
    REPLACE_IF_IS(mCond, TIntermTyped, original, replacement);
    REPLACE_IF_IS(mExpr, TIntermTyped, original, replacement);
    REPLACE_IF_IS(mBody, TIntermBlock, original, replacement);
    return false;
}

size_t TIntermBranch::getChildCount() const
{
    return (mExpression ? 1 : 0);
}

TIntermNode *TIntermBranch::getChildNode(size_t index) const
{
    ASSERT(mExpression);
    ASSERT(index == 0);
    return mExpression;
}

bool TIntermBranch::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
{
    REPLACE_IF_IS(mExpression, TIntermTyped, original, replacement);
    return false;
}

size_t TIntermSwizzle::getChildCount() const
{
    return 1;
}

TIntermNode *TIntermSwizzle::getChildNode(size_t index) const
{
    ASSERT(mOperand);
    ASSERT(index == 0);
    return mOperand;
}

bool TIntermSwizzle::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
{
    ASSERT(original->getAsTyped()->getType() == replacement->getAsTyped()->getType());
    REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement);
    return false;
}

size_t TIntermBinary::getChildCount() const
{
    return 2;
}

TIntermNode *TIntermBinary::getChildNode(size_t index) const
{
    ASSERT(index < 2);
    if (index == 0)
    {
        return mLeft;
    }
    return mRight;
}

bool TIntermBinary::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
{
    REPLACE_IF_IS(mLeft, TIntermTyped, original, replacement);
    REPLACE_IF_IS(mRight, TIntermTyped, original, replacement);
    return false;
}

size_t TIntermUnary::getChildCount() const
{
    return 1;
}

TIntermNode *TIntermUnary::getChildNode(size_t index) const
{
    ASSERT(mOperand);
    ASSERT(index == 0);
    return mOperand;
}

bool TIntermUnary::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
{
    ASSERT(original->getAsTyped()->getType() == replacement->getAsTyped()->getType());
    REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement);
    return false;
}

size_t TIntermInvariantDeclaration::getChildCount() const
{
    return 1;
}

TIntermNode *TIntermInvariantDeclaration::getChildNode(size_t index) const
{
    ASSERT(mSymbol);
    ASSERT(index == 0);
    return mSymbol;
}

bool TIntermInvariantDeclaration::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
{
    REPLACE_IF_IS(mSymbol, TIntermSymbol, original, replacement);
    return false;
}

size_t TIntermFunctionDefinition::getChildCount() const
{
    return 2;
}

TIntermNode *TIntermFunctionDefinition::getChildNode(size_t index) const
{
    ASSERT(index < 2);
    if (index == 0)
    {
        return mPrototype;
    }
    return mBody;
}

bool TIntermFunctionDefinition::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
{
    REPLACE_IF_IS(mPrototype, TIntermFunctionPrototype, original, replacement);
    REPLACE_IF_IS(mBody, TIntermBlock, original, replacement);
    return false;
}

size_t TIntermAggregate::getChildCount() const
{
    return mArguments.size();
}

TIntermNode *TIntermAggregate::getChildNode(size_t index) const
{
    return mArguments[index];
}

bool TIntermAggregate::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
{
    return replaceChildNodeInternal(original, replacement);
}

size_t TIntermBlock::getChildCount() const
{
    return mStatements.size();
}

TIntermNode *TIntermBlock::getChildNode(size_t index) const
{
    return mStatements[index];
}

bool TIntermBlock::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
{
    return replaceChildNodeInternal(original, replacement);
}

size_t TIntermFunctionPrototype::getChildCount() const
{
    return 0;
}

TIntermNode *TIntermFunctionPrototype::getChildNode(size_t index) const
{
    UNREACHABLE();
    return nullptr;
}

bool TIntermFunctionPrototype::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
{
    return false;
}

size_t TIntermDeclaration::getChildCount() const
{
    return mDeclarators.size();
}

TIntermNode *TIntermDeclaration::getChildNode(size_t index) const
{
    return mDeclarators[index];
}

bool TIntermDeclaration::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
{
    return replaceChildNodeInternal(original, replacement);
}

bool TIntermAggregateBase::replaceChildNodeInternal(TIntermNode *original, TIntermNode *replacement)
{
    for (size_t ii = 0; ii < getSequence()->size(); ++ii)
    {
        REPLACE_IF_IS((*getSequence())[ii], TIntermNode, original, replacement);
    }
    return false;
}

bool TIntermAggregateBase::replaceChildNodeWithMultiple(TIntermNode *original,
                                                        const TIntermSequence &replacements)
{
    for (auto it = getSequence()->begin(); it < getSequence()->end(); ++it)
    {
        if (*it == original)
        {
            it = getSequence()->erase(it);
            getSequence()->insert(it, replacements.begin(), replacements.end());
            return true;
        }
    }
    return false;
}

bool TIntermAggregateBase::insertChildNodes(TIntermSequence::size_type position,
                                            const TIntermSequence &insertions)
{
    if (position > getSequence()->size())
    {
        return false;
    }
    auto it = getSequence()->begin() + position;
    getSequence()->insert(it, insertions.begin(), insertions.end());
    return true;
}

TIntermSymbol::TIntermSymbol(const TVariable *variable) : TIntermTyped(), mVariable(variable) {}

bool TIntermSymbol::hasConstantValue() const
{
    return variable().getConstPointer() != nullptr;
}

const TConstantUnion *TIntermSymbol::getConstantValue() const
{
    return variable().getConstPointer();
}

const TSymbolUniqueId &TIntermSymbol::uniqueId() const
{
    return mVariable->uniqueId();
}

ImmutableString TIntermSymbol::getName() const
{
    return mVariable->name();
}

const TType &TIntermSymbol::getType() const
{
    return mVariable->getType();
}

TIntermAggregate *TIntermAggregate::CreateFunctionCall(const TFunction &func,
                                                       TIntermSequence *arguments)
{
    return new TIntermAggregate(&func, func.getReturnType(), EOpCallFunctionInAST, arguments);
}

TIntermAggregate *TIntermAggregate::CreateRawFunctionCall(const TFunction &func,
                                                          TIntermSequence *arguments)
{
    return new TIntermAggregate(&func, func.getReturnType(), EOpCallInternalRawFunction, arguments);
}

TIntermAggregate *TIntermAggregate::CreateBuiltInFunctionCall(const TFunction &func,
                                                              TIntermSequence *arguments)
{
    // op should be either EOpCallBuiltInFunction or a specific math op.
    ASSERT(func.getBuiltInOp() != EOpNull);
    return new TIntermAggregate(&func, func.getReturnType(), func.getBuiltInOp(), arguments);
}

TIntermAggregate *TIntermAggregate::CreateConstructor(const TType &type, TIntermSequence *arguments)
{
    return new TIntermAggregate(nullptr, type, EOpConstruct, arguments);
}

TIntermAggregate::TIntermAggregate(const TFunction *func,
                                   const TType &type,
                                   TOperator op,
                                   TIntermSequence *arguments)
    : TIntermOperator(op, type),
      mUseEmulatedFunction(false),
      mGotPrecisionFromChildren(false),
      mFunction(func)
{
    if (arguments != nullptr)
    {
        mArguments.swap(*arguments);
    }
    ASSERT(mFunction == nullptr || mFunction->symbolType() != SymbolType::Empty);
    setPrecisionAndQualifier();
}

void TIntermAggregate::setPrecisionAndQualifier()
{
    mType.setQualifier(EvqTemporary);
    if (mOp == EOpCallBuiltInFunction)
    {
        setBuiltInFunctionPrecision();
    }
    else if (!isFunctionCall())
    {
        if (isConstructor())
        {
            // Structs should not be precision qualified, the individual members may be.
            // Built-in types on the other hand should be precision qualified.
            if (getBasicType() != EbtStruct)
            {
                setPrecisionFromChildren();
            }
        }
        else
        {
            setPrecisionForBuiltInOp();
        }
        if (areChildrenConstQualified())
        {
            mType.setQualifier(EvqConst);
        }
    }
}

bool TIntermAggregate::areChildrenConstQualified()
{
    for (TIntermNode *&arg : mArguments)
    {
        TIntermTyped *typedArg = arg->getAsTyped();
        if (typedArg && typedArg->getQualifier() != EvqConst)
        {
            return false;
        }
    }
    return true;
}

void TIntermAggregate::setPrecisionFromChildren()
{
    mGotPrecisionFromChildren = true;
    if (getBasicType() == EbtBool)
    {
        mType.setPrecision(EbpUndefined);
        return;
    }

    TPrecision precision                = EbpUndefined;
    TIntermSequence::iterator childIter = mArguments.begin();
    while (childIter != mArguments.end())
    {
        TIntermTyped *typed = (*childIter)->getAsTyped();
        if (typed)
            precision = GetHigherPrecision(typed->getPrecision(), precision);
        ++childIter;
    }
    mType.setPrecision(precision);
}

void TIntermAggregate::setPrecisionForBuiltInOp()
{
    ASSERT(!isConstructor());
    ASSERT(!isFunctionCall());
    if (!setPrecisionForSpecialBuiltInOp())
    {
        setPrecisionFromChildren();
    }
}

bool TIntermAggregate::setPrecisionForSpecialBuiltInOp()
{
    switch (mOp)
    {
        case EOpBitfieldExtract:
            mType.setPrecision(mArguments[0]->getAsTyped()->getPrecision());
            mGotPrecisionFromChildren = true;
            return true;
        case EOpBitfieldInsert:
            mType.setPrecision(GetHigherPrecision(mArguments[0]->getAsTyped()->getPrecision(),
                                                  mArguments[1]->getAsTyped()->getPrecision()));
            mGotPrecisionFromChildren = true;
            return true;
        case EOpUaddCarry:
        case EOpUsubBorrow:
            mType.setPrecision(EbpHigh);
            return true;
        default:
            return false;
    }
}

void TIntermAggregate::setBuiltInFunctionPrecision()
{
    // All built-ins returning bool should be handled as ops, not functions.
    ASSERT(getBasicType() != EbtBool);
    ASSERT(mOp == EOpCallBuiltInFunction);

    TPrecision precision = EbpUndefined;
    for (TIntermNode *arg : mArguments)
    {
        TIntermTyped *typed = arg->getAsTyped();
        // ESSL spec section 8: texture functions get their precision from the sampler.
        if (typed && IsSampler(typed->getBasicType()))
        {
            precision = typed->getPrecision();
            break;
        }
    }
    // ESSL 3.0 spec section 8: textureSize always gets highp precision.
    // All other functions that take a sampler are assumed to be texture functions.
    if (mFunction->name() == "textureSize")
        mType.setPrecision(EbpHigh);
    else
        mType.setPrecision(precision);
}

const char *TIntermAggregate::functionName() const
{
    ASSERT(!isConstructor());
    switch (mOp)
    {
        case EOpCallInternalRawFunction:
        case EOpCallBuiltInFunction:
        case EOpCallFunctionInAST:
            return mFunction->name().data();
        default:
            return GetOperatorString(mOp);
    }
}

bool TIntermAggregate::hasConstantValue() const
{
    if (!isConstructor())
    {
        return false;
    }
    for (TIntermNode *constructorArg : mArguments)
    {
        if (!constructorArg->getAsTyped()->hasConstantValue())
        {
            return false;
        }
    }
    return true;
}

const TConstantUnion *TIntermAggregate::getConstantValue() const
{
    if (!hasConstantValue())
    {
        return nullptr;
    }
    ASSERT(isConstructor());
    ASSERT(mArguments.size() > 0u);

    TConstantUnion *constArray = nullptr;
    if (isArray())
    {
        size_t elementSize = mArguments.front()->getAsTyped()->getType().getObjectSize();
        constArray         = new TConstantUnion[elementSize * getOutermostArraySize()];

        size_t elementOffset = 0u;
        for (TIntermNode *constructorArg : mArguments)
        {
            const TConstantUnion *elementConstArray =
                constructorArg->getAsTyped()->getConstantValue();
            ASSERT(elementConstArray);
            size_t elementSizeBytes = sizeof(TConstantUnion) * elementSize;
            memcpy(static_cast<void *>(&constArray[elementOffset]),
                   static_cast<const void *>(elementConstArray), elementSizeBytes);
            elementOffset += elementSize;
        }
        return constArray;
    }

    size_t resultSize    = getType().getObjectSize();
    constArray           = new TConstantUnion[resultSize];
    TBasicType basicType = getBasicType();

    size_t resultIndex = 0u;

    if (mArguments.size() == 1u)
    {
        TIntermNode *argument                       = mArguments.front();
        TIntermTyped *argumentTyped                 = argument->getAsTyped();
        const TConstantUnion *argumentConstantValue = argumentTyped->getConstantValue();
        // Check the special case of constructing a matrix diagonal from a single scalar,
        // or a vector from a single scalar.
        if (argumentTyped->getType().getObjectSize() == 1u)
        {
            if (isMatrix())
            {
                int resultCols = getType().getCols();
                int resultRows = getType().getRows();
                for (int col = 0; col < resultCols; ++col)
                {
                    for (int row = 0; row < resultRows; ++row)
                    {
                        if (col == row)
                        {
                            constArray[resultIndex].cast(basicType, argumentConstantValue[0]);
                        }
                        else
                        {
                            constArray[resultIndex].setFConst(0.0f);
                        }
                        ++resultIndex;
                    }
                }
            }
            else
            {
                while (resultIndex < resultSize)
                {
                    constArray[resultIndex].cast(basicType, argumentConstantValue[0]);
                    ++resultIndex;
                }
            }
            ASSERT(resultIndex == resultSize);
            return constArray;
        }
        else if (isMatrix() && argumentTyped->isMatrix())
        {
            // The special case of constructing a matrix from a matrix.
            int argumentCols = argumentTyped->getType().getCols();
            int argumentRows = argumentTyped->getType().getRows();
            int resultCols   = getType().getCols();
            int resultRows   = getType().getRows();
            for (int col = 0; col < resultCols; ++col)
            {
                for (int row = 0; row < resultRows; ++row)
                {
                    if (col < argumentCols && row < argumentRows)
                    {
                        constArray[resultIndex].cast(
                            basicType, argumentConstantValue[col * argumentRows + row]);
                    }
                    else if (col == row)
                    {
                        constArray[resultIndex].setFConst(1.0f);
                    }
                    else
                    {
                        constArray[resultIndex].setFConst(0.0f);
                    }
                    ++resultIndex;
                }
            }
            ASSERT(resultIndex == resultSize);
            return constArray;
        }
    }

    for (TIntermNode *argument : mArguments)
    {
        TIntermTyped *argumentTyped                 = argument->getAsTyped();
        size_t argumentSize                         = argumentTyped->getType().getObjectSize();
        const TConstantUnion *argumentConstantValue = argumentTyped->getConstantValue();
        for (size_t i = 0u; i < argumentSize; ++i)
        {
            if (resultIndex >= resultSize)
                break;
            constArray[resultIndex].cast(basicType, argumentConstantValue[i]);
            ++resultIndex;
        }
    }
    ASSERT(resultIndex == resultSize);
    return constArray;
}

bool TIntermAggregate::hasSideEffects() const
{
    if (getQualifier() == EvqConst)
    {
        return false;
    }
    bool calledFunctionHasNoSideEffects =
        isFunctionCall() && mFunction != nullptr && mFunction->isKnownToNotHaveSideEffects();
    if (calledFunctionHasNoSideEffects || isConstructor())
    {
        for (TIntermNode *arg : mArguments)
        {
            if (arg->getAsTyped()->hasSideEffects())
            {
                return true;
            }
        }
        return false;
    }
    // Conservatively assume most aggregate operators have side-effects
    return true;
}

void TIntermBlock::appendStatement(TIntermNode *statement)
{
    // Declaration nodes with no children can appear if it was an empty declaration or if all the
    // declarators just added constants to the symbol table instead of generating code. We still
    // need to add the declaration to the AST in that case because it might be relevant to the
    // validity of switch/case.
    if (statement != nullptr)
    {
        mStatements.push_back(statement);
    }
}

void TIntermBlock::insertStatement(size_t insertPosition, TIntermNode *statement)
{
    ASSERT(statement != nullptr);
    mStatements.insert(mStatements.begin() + insertPosition, statement);
}

void TIntermDeclaration::appendDeclarator(TIntermTyped *declarator)
{
    ASSERT(declarator != nullptr);
    ASSERT(declarator->getAsSymbolNode() != nullptr ||
           (declarator->getAsBinaryNode() != nullptr &&
            declarator->getAsBinaryNode()->getOp() == EOpInitialize));
    ASSERT(mDeclarators.empty() ||
           declarator->getType().sameNonArrayType(mDeclarators.back()->getAsTyped()->getType()));
    mDeclarators.push_back(declarator);
}

size_t TIntermTernary::getChildCount() const
{
    return 3;
}

TIntermNode *TIntermTernary::getChildNode(size_t index) const
{
    ASSERT(index < 3);
    if (index == 0)
    {
        return mCondition;
    }
    if (index == 1)
    {
        return mTrueExpression;
    }
    return mFalseExpression;
}

bool TIntermTernary::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
{
    REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
    REPLACE_IF_IS(mTrueExpression, TIntermTyped, original, replacement);
    REPLACE_IF_IS(mFalseExpression, TIntermTyped, original, replacement);
    return false;
}

size_t TIntermIfElse::getChildCount() const
{
    return 1 + (mTrueBlock ? 1 : 0) + (mFalseBlock ? 1 : 0);
}

TIntermNode *TIntermIfElse::getChildNode(size_t index) const
{
    if (index == 0)
    {
        return mCondition;
    }
    if (mTrueBlock && index == 1)
    {
        return mTrueBlock;
    }
    return mFalseBlock;
}

bool TIntermIfElse::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
{
    REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
    REPLACE_IF_IS(mTrueBlock, TIntermBlock, original, replacement);
    REPLACE_IF_IS(mFalseBlock, TIntermBlock, original, replacement);
    return false;
}

size_t TIntermSwitch::getChildCount() const
{
    return 2;
}

TIntermNode *TIntermSwitch::getChildNode(size_t index) const
{
    ASSERT(index < 2);
    if (index == 0)
    {
        return mInit;
    }
    return mStatementList;
}

bool TIntermSwitch::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
{
    REPLACE_IF_IS(mInit, TIntermTyped, original, replacement);
    REPLACE_IF_IS(mStatementList, TIntermBlock, original, replacement);
    ASSERT(mStatementList);
    return false;
}

size_t TIntermCase::getChildCount() const
{
    return (mCondition ? 1 : 0);
}

TIntermNode *TIntermCase::getChildNode(size_t index) const
{
    ASSERT(index == 0);
    ASSERT(mCondition);
    return mCondition;
}

bool TIntermCase::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
{
    REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
    return false;
}

TIntermTyped::TIntermTyped(const TIntermTyped &node) : TIntermNode()
{
    // Copy constructor is disallowed for TIntermNode in order to disallow it for subclasses that
    // don't explicitly allow it, so normal TIntermNode constructor is used to construct the copy.
    // We need to manually copy any fields of TIntermNode.
    mLine = node.mLine;
}

bool TIntermTyped::hasConstantValue() const
{
    return false;
}

const TConstantUnion *TIntermTyped::getConstantValue() const
{
    return nullptr;
}

TIntermConstantUnion::TIntermConstantUnion(const TIntermConstantUnion &node)
    : TIntermExpression(node)
{
    mUnionArrayPointer = node.mUnionArrayPointer;
}

TIntermFunctionPrototype::TIntermFunctionPrototype(const TFunction *function)
    : TIntermTyped(), mFunction(function)
{
    ASSERT(mFunction->symbolType() != SymbolType::Empty);
}

const TType &TIntermFunctionPrototype::getType() const
{
    return mFunction->getReturnType();
}

TIntermAggregate::TIntermAggregate(const TIntermAggregate &node)
    : TIntermOperator(node),
      mUseEmulatedFunction(node.mUseEmulatedFunction),
      mGotPrecisionFromChildren(node.mGotPrecisionFromChildren),
      mFunction(node.mFunction)
{
    for (TIntermNode *arg : node.mArguments)
    {
        TIntermTyped *typedArg = arg->getAsTyped();
        ASSERT(typedArg != nullptr);
        TIntermTyped *argCopy = typedArg->deepCopy();
        mArguments.push_back(argCopy);
    }
}

TIntermAggregate *TIntermAggregate::shallowCopy() const
{
    TIntermSequence *copySeq = new TIntermSequence();
    copySeq->insert(copySeq->begin(), getSequence()->begin(), getSequence()->end());
    TIntermAggregate *copyNode = new TIntermAggregate(mFunction, mType, mOp, copySeq);
    copyNode->setLine(mLine);
    return copyNode;
}

TIntermSwizzle::TIntermSwizzle(const TIntermSwizzle &node) : TIntermExpression(node)
{
    TIntermTyped *operandCopy = node.mOperand->deepCopy();
    ASSERT(operandCopy != nullptr);
    mOperand                   = operandCopy;
    mSwizzleOffsets            = node.mSwizzleOffsets;
    mHasFoldedDuplicateOffsets = node.mHasFoldedDuplicateOffsets;
}

TIntermBinary::TIntermBinary(const TIntermBinary &node)
    : TIntermOperator(node), mAddIndexClamp(node.mAddIndexClamp)
{
    TIntermTyped *leftCopy  = node.mLeft->deepCopy();
    TIntermTyped *rightCopy = node.mRight->deepCopy();
    ASSERT(leftCopy != nullptr && rightCopy != nullptr);
    mLeft  = leftCopy;
    mRight = rightCopy;
}

TIntermUnary::TIntermUnary(const TIntermUnary &node)
    : TIntermOperator(node),
      mUseEmulatedFunction(node.mUseEmulatedFunction),
      mFunction(node.mFunction)
{
    TIntermTyped *operandCopy = node.mOperand->deepCopy();
    ASSERT(operandCopy != nullptr);
    mOperand = operandCopy;
}

TIntermTernary::TIntermTernary(const TIntermTernary &node) : TIntermExpression(node)
{
    TIntermTyped *conditionCopy = node.mCondition->deepCopy();
    TIntermTyped *trueCopy      = node.mTrueExpression->deepCopy();
    TIntermTyped *falseCopy     = node.mFalseExpression->deepCopy();
    ASSERT(conditionCopy != nullptr && trueCopy != nullptr && falseCopy != nullptr);
    mCondition       = conditionCopy;
    mTrueExpression  = trueCopy;
    mFalseExpression = falseCopy;
}

bool TIntermOperator::isAssignment() const
{
    return IsAssignment(mOp);
}

bool TIntermOperator::isMultiplication() const
{
    switch (mOp)
    {
        case EOpMul:
        case EOpMatrixTimesMatrix:
        case EOpMatrixTimesVector:
        case EOpMatrixTimesScalar:
        case EOpVectorTimesMatrix:
        case EOpVectorTimesScalar:
            return true;
        default:
            return false;
    }
}

bool TIntermOperator::isConstructor() const
{
    return (mOp == EOpConstruct);
}

bool TIntermOperator::isFunctionCall() const
{
    switch (mOp)
    {
        case EOpCallFunctionInAST:
        case EOpCallBuiltInFunction:
        case EOpCallInternalRawFunction:
            return true;
        default:
            return false;
    }
}

TOperator TIntermBinary::GetMulOpBasedOnOperands(const TType &left, const TType &right)
{
    if (left.isMatrix())
    {
        if (right.isMatrix())
        {
            return EOpMatrixTimesMatrix;
        }
        else
        {
            if (right.isVector())
            {
                return EOpMatrixTimesVector;
            }
            else
            {
                return EOpMatrixTimesScalar;
            }
        }
    }
    else
    {
        if (right.isMatrix())
        {
            if (left.isVector())
            {
                return EOpVectorTimesMatrix;
            }
            else
            {
                return EOpMatrixTimesScalar;
            }
        }
        else
        {
            // Neither operand is a matrix.
            if (left.isVector() == right.isVector())
            {
                // Leave as component product.
                return EOpMul;
            }
            else
            {
                return EOpVectorTimesScalar;
            }
        }
    }
}

TOperator TIntermBinary::GetMulAssignOpBasedOnOperands(const TType &left, const TType &right)
{
    if (left.isMatrix())
    {
        if (right.isMatrix())
        {
            return EOpMatrixTimesMatrixAssign;
        }
        else
        {
            // right should be scalar, but this may not be validated yet.
            return EOpMatrixTimesScalarAssign;
        }
    }
    else
    {
        if (right.isMatrix())
        {
            // Left should be a vector, but this may not be validated yet.
            return EOpVectorTimesMatrixAssign;
        }
        else
        {
            // Neither operand is a matrix.
            if (left.isVector() == right.isVector())
            {
                // Leave as component product.
                return EOpMulAssign;
            }
            else
            {
                // left should be vector and right should be scalar, but this may not be validated
                // yet.
                return EOpVectorTimesScalarAssign;
            }
        }
    }
}

//
// Make sure the type of a unary operator is appropriate for its
// combination of operation and operand type.
//
void TIntermUnary::promote()
{
    if (mOp == EOpArrayLength)
    {
        // Special case: the qualifier of .length() doesn't depend on the operand qualifier.
        setType(TType(EbtInt, EbpUndefined, EvqConst));
        return;
    }

    TQualifier resultQualifier = EvqTemporary;
    if (mOperand->getQualifier() == EvqConst)
        resultQualifier = EvqConst;

    unsigned char operandPrimarySize =
        static_cast<unsigned char>(mOperand->getType().getNominalSize());
    switch (mOp)
    {
        case EOpFloatBitsToInt:
            setType(TType(EbtInt, EbpHigh, resultQualifier, operandPrimarySize));
            break;
        case EOpFloatBitsToUint:
            setType(TType(EbtUInt, EbpHigh, resultQualifier, operandPrimarySize));
            break;
        case EOpIntBitsToFloat:
        case EOpUintBitsToFloat:
            setType(TType(EbtFloat, EbpHigh, resultQualifier, operandPrimarySize));
            break;
        case EOpPackSnorm2x16:
        case EOpPackUnorm2x16:
        case EOpPackHalf2x16:
        case EOpPackUnorm4x8:
        case EOpPackSnorm4x8:
            setType(TType(EbtUInt, EbpHigh, resultQualifier));
            break;
        case EOpUnpackSnorm2x16:
        case EOpUnpackUnorm2x16:
            setType(TType(EbtFloat, EbpHigh, resultQualifier, 2));
            break;
        case EOpUnpackHalf2x16:
            setType(TType(EbtFloat, EbpMedium, resultQualifier, 2));
            break;
        case EOpUnpackUnorm4x8:
        case EOpUnpackSnorm4x8:
            setType(TType(EbtFloat, EbpMedium, resultQualifier, 4));
            break;
        case EOpAny:
        case EOpAll:
            setType(TType(EbtBool, EbpUndefined, resultQualifier));
            break;
        case EOpLength:
        case EOpDeterminant:
            setType(TType(EbtFloat, mOperand->getType().getPrecision(), resultQualifier));
            break;
        case EOpTranspose:
            setType(TType(EbtFloat, mOperand->getType().getPrecision(), resultQualifier,
                          static_cast<unsigned char>(mOperand->getType().getRows()),
                          static_cast<unsigned char>(mOperand->getType().getCols())));
            break;
        case EOpIsinf:
        case EOpIsnan:
            setType(TType(EbtBool, EbpUndefined, resultQualifier, operandPrimarySize));
            break;
        case EOpBitfieldReverse:
            setType(TType(mOperand->getBasicType(), EbpHigh, resultQualifier, operandPrimarySize));
            break;
        case EOpBitCount:
            setType(TType(EbtInt, EbpLow, resultQualifier, operandPrimarySize));
            break;
        case EOpFindLSB:
            setType(TType(EbtInt, EbpLow, resultQualifier, operandPrimarySize));
            break;
        case EOpFindMSB:
            setType(TType(EbtInt, EbpLow, resultQualifier, operandPrimarySize));
            break;
        default:
            setType(mOperand->getType());
            mType.setQualifier(resultQualifier);
            break;
    }
}

TIntermSwizzle::TIntermSwizzle(TIntermTyped *operand, const TVector<int> &swizzleOffsets)
    : TIntermExpression(TType(EbtFloat, EbpUndefined)),
      mOperand(operand),
      mSwizzleOffsets(swizzleOffsets),
      mHasFoldedDuplicateOffsets(false)
{
    ASSERT(mOperand);
    ASSERT(mSwizzleOffsets.size() <= 4);
    promote();
}

TIntermUnary::TIntermUnary(TOperator op, TIntermTyped *operand, const TFunction *function)
    : TIntermOperator(op), mOperand(operand), mUseEmulatedFunction(false), mFunction(function)
{
    ASSERT(mOperand);
    promote();
}

TIntermBinary::TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right)
    : TIntermOperator(op), mLeft(left), mRight(right), mAddIndexClamp(false)
{
    ASSERT(mLeft);
    ASSERT(mRight);
    promote();
}

TIntermBinary *TIntermBinary::CreateComma(TIntermTyped *left,
                                          TIntermTyped *right,
                                          int shaderVersion)
{
    TIntermBinary *node = new TIntermBinary(EOpComma, left, right);
    node->getTypePointer()->setQualifier(GetCommaQualifier(shaderVersion, left, right));
    return node;
}

TIntermInvariantDeclaration::TIntermInvariantDeclaration(TIntermSymbol *symbol,
                                                         const TSourceLoc &line)
    : TIntermNode(), mSymbol(symbol)
{
    ASSERT(symbol);
    setLine(line);
}

TIntermTernary::TIntermTernary(TIntermTyped *cond,
                               TIntermTyped *trueExpression,
                               TIntermTyped *falseExpression)
    : TIntermExpression(trueExpression->getType()),
      mCondition(cond),
      mTrueExpression(trueExpression),
      mFalseExpression(falseExpression)
{
    ASSERT(mCondition);
    ASSERT(mTrueExpression);
    ASSERT(mFalseExpression);
    getTypePointer()->setQualifier(
        TIntermTernary::DetermineQualifier(cond, trueExpression, falseExpression));
}

TIntermLoop::TIntermLoop(TLoopType type,
                         TIntermNode *init,
                         TIntermTyped *cond,
                         TIntermTyped *expr,
                         TIntermBlock *body)
    : mType(type), mInit(init), mCond(cond), mExpr(expr), mBody(body)
{
    // Declaration nodes with no children can appear if all the declarators just added constants to
    // the symbol table instead of generating code. They're no-ops so don't add them to the tree.
    if (mInit && mInit->getAsDeclarationNode() &&
        mInit->getAsDeclarationNode()->getSequence()->empty())
    {
        mInit = nullptr;
    }
}

TIntermIfElse::TIntermIfElse(TIntermTyped *cond, TIntermBlock *trueB, TIntermBlock *falseB)
    : TIntermNode(), mCondition(cond), mTrueBlock(trueB), mFalseBlock(falseB)
{
    ASSERT(mCondition);
    // Prune empty false blocks so that there won't be unnecessary operations done on it.
    if (mFalseBlock && mFalseBlock->getSequence()->empty())
    {
        mFalseBlock = nullptr;
    }
}

TIntermSwitch::TIntermSwitch(TIntermTyped *init, TIntermBlock *statementList)
    : TIntermNode(), mInit(init), mStatementList(statementList)
{
    ASSERT(mInit);
    ASSERT(mStatementList);
}

void TIntermSwitch::setStatementList(TIntermBlock *statementList)
{
    ASSERT(statementList);
    mStatementList = statementList;
}

// static
TQualifier TIntermTernary::DetermineQualifier(TIntermTyped *cond,
                                              TIntermTyped *trueExpression,
                                              TIntermTyped *falseExpression)
{
    if (cond->getQualifier() == EvqConst && trueExpression->getQualifier() == EvqConst &&
        falseExpression->getQualifier() == EvqConst)
    {
        return EvqConst;
    }
    return EvqTemporary;
}

TIntermTyped *TIntermTernary::fold(TDiagnostics * /* diagnostics */)
{
    if (mCondition->getAsConstantUnion())
    {
        if (mCondition->getAsConstantUnion()->getBConst(0))
        {
            return mTrueExpression;
        }
        else
        {
            return mFalseExpression;
        }
    }
    return this;
}

void TIntermSwizzle::promote()
{
    TQualifier resultQualifier = EvqTemporary;
    if (mOperand->getQualifier() == EvqConst)
        resultQualifier = EvqConst;

    auto numFields = mSwizzleOffsets.size();
    setType(TType(mOperand->getBasicType(), mOperand->getPrecision(), resultQualifier,
                  static_cast<unsigned char>(numFields)));
}

bool TIntermSwizzle::hasDuplicateOffsets() const
{
    if (mHasFoldedDuplicateOffsets)
    {
        return true;
    }
    int offsetCount[4] = {0u, 0u, 0u, 0u};
    for (const auto offset : mSwizzleOffsets)
    {
        offsetCount[offset]++;
        if (offsetCount[offset] > 1)
        {
            return true;
        }
    }
    return false;
}

void TIntermSwizzle::setHasFoldedDuplicateOffsets(bool hasFoldedDuplicateOffsets)
{
    mHasFoldedDuplicateOffsets = hasFoldedDuplicateOffsets;
}

bool TIntermSwizzle::offsetsMatch(int offset) const
{
    return mSwizzleOffsets.size() == 1 && mSwizzleOffsets[0] == offset;
}

void TIntermSwizzle::writeOffsetsAsXYZW(TInfoSinkBase *out) const
{
    for (const int offset : mSwizzleOffsets)
    {
        switch (offset)
        {
            case 0:
                *out << "x";
                break;
            case 1:
                *out << "y";
                break;
            case 2:
                *out << "z";
                break;
            case 3:
                *out << "w";
                break;
            default:
                UNREACHABLE();
        }
    }
}

TQualifier TIntermBinary::GetCommaQualifier(int shaderVersion,
                                            const TIntermTyped *left,
                                            const TIntermTyped *right)
{
    // ESSL3.00 section 12.43: The result of a sequence operator is not a constant-expression.
    if (shaderVersion >= 300 || left->getQualifier() != EvqConst ||
        right->getQualifier() != EvqConst)
    {
        return EvqTemporary;
    }
    return EvqConst;
}

// Establishes the type of the result of the binary operation.
void TIntermBinary::promote()
{
    ASSERT(!isMultiplication() ||
           mOp == GetMulOpBasedOnOperands(mLeft->getType(), mRight->getType()));

    // Comma is handled as a special case. Note that the comma node qualifier depends on the shader
    // version and so is not being set here.
    if (mOp == EOpComma)
    {
        setType(mRight->getType());
        return;
    }

    // Base assumption:  just make the type the same as the left
    // operand.  Then only deviations from this need be coded.
    setType(mLeft->getType());

    TQualifier resultQualifier = EvqConst;
    // Binary operations results in temporary variables unless both
    // operands are const.
    if (mLeft->getQualifier() != EvqConst || mRight->getQualifier() != EvqConst)
    {
        resultQualifier = EvqTemporary;
        getTypePointer()->setQualifier(EvqTemporary);
    }

    // Handle indexing ops.
    switch (mOp)
    {
        case EOpIndexDirect:
        case EOpIndexIndirect:
            if (mLeft->isArray())
            {
                mType.toArrayElementType();
            }
            else if (mLeft->isMatrix())
            {
                setType(TType(mLeft->getBasicType(), mLeft->getPrecision(), resultQualifier,
                              static_cast<unsigned char>(mLeft->getRows())));
            }
            else if (mLeft->isVector())
            {
                setType(TType(mLeft->getBasicType(), mLeft->getPrecision(), resultQualifier));
            }
            else
            {
                UNREACHABLE();
            }
            return;
        case EOpIndexDirectStruct:
        {
            const TFieldList &fields = mLeft->getType().getStruct()->fields();
            const int i              = mRight->getAsConstantUnion()->getIConst(0);
            setType(*fields[i]->type());
            getTypePointer()->setQualifier(resultQualifier);
            return;
        }
        case EOpIndexDirectInterfaceBlock:
        {
            const TFieldList &fields = mLeft->getType().getInterfaceBlock()->fields();
            const int i              = mRight->getAsConstantUnion()->getIConst(0);
            setType(*fields[i]->type());
            getTypePointer()->setQualifier(resultQualifier);
            return;
        }
        default:
            break;
    }

    ASSERT(mLeft->isArray() == mRight->isArray());

    // The result gets promoted to the highest precision.
    TPrecision higherPrecision = GetHigherPrecision(mLeft->getPrecision(), mRight->getPrecision());
    getTypePointer()->setPrecision(higherPrecision);

    const int nominalSize = std::max(mLeft->getNominalSize(), mRight->getNominalSize());

    //
    // All scalars or structs. Code after this test assumes this case is removed!
    //
    if (nominalSize == 1)
    {
        switch (mOp)
        {
            //
            // Promote to conditional
            //
            case EOpEqual:
            case EOpNotEqual:
            case EOpLessThan:
            case EOpGreaterThan:
            case EOpLessThanEqual:
            case EOpGreaterThanEqual:
                setType(TType(EbtBool, EbpUndefined, resultQualifier));
                break;

            //
            // And and Or operate on conditionals
            //
            case EOpLogicalAnd:
            case EOpLogicalXor:
            case EOpLogicalOr:
                ASSERT(mLeft->getBasicType() == EbtBool && mRight->getBasicType() == EbtBool);
                setType(TType(EbtBool, EbpUndefined, resultQualifier));
                break;

            default:
                break;
        }
        return;
    }

    // If we reach here, at least one of the operands is vector or matrix.
    // The other operand could be a scalar, vector, or matrix.
    TBasicType basicType = mLeft->getBasicType();

    switch (mOp)
    {
        case EOpMul:
            break;
        case EOpMatrixTimesScalar:
            if (mRight->isMatrix())
            {
                setType(TType(basicType, higherPrecision, resultQualifier,
                              static_cast<unsigned char>(mRight->getCols()),
                              static_cast<unsigned char>(mRight->getRows())));
            }
            break;
        case EOpMatrixTimesVector:
            setType(TType(basicType, higherPrecision, resultQualifier,
                          static_cast<unsigned char>(mLeft->getRows()), 1));
            break;
        case EOpMatrixTimesMatrix:
            setType(TType(basicType, higherPrecision, resultQualifier,
                          static_cast<unsigned char>(mRight->getCols()),
                          static_cast<unsigned char>(mLeft->getRows())));
            break;
        case EOpVectorTimesScalar:
            setType(TType(basicType, higherPrecision, resultQualifier,
                          static_cast<unsigned char>(nominalSize), 1));
            break;
        case EOpVectorTimesMatrix:
            setType(TType(basicType, higherPrecision, resultQualifier,
                          static_cast<unsigned char>(mRight->getCols()), 1));
            break;
        case EOpMulAssign:
        case EOpVectorTimesScalarAssign:
        case EOpVectorTimesMatrixAssign:
        case EOpMatrixTimesScalarAssign:
        case EOpMatrixTimesMatrixAssign:
            ASSERT(mOp == GetMulAssignOpBasedOnOperands(mLeft->getType(), mRight->getType()));
            break;
        case EOpAssign:
        case EOpInitialize:
            ASSERT((mLeft->getNominalSize() == mRight->getNominalSize()) &&
                   (mLeft->getSecondarySize() == mRight->getSecondarySize()));
            break;
        case EOpAdd:
        case EOpSub:
        case EOpDiv:
        case EOpIMod:
        case EOpBitShiftLeft:
        case EOpBitShiftRight:
        case EOpBitwiseAnd:
        case EOpBitwiseXor:
        case EOpBitwiseOr:
        case EOpAddAssign:
        case EOpSubAssign:
        case EOpDivAssign:
        case EOpIModAssign:
        case EOpBitShiftLeftAssign:
        case EOpBitShiftRightAssign:
        case EOpBitwiseAndAssign:
        case EOpBitwiseXorAssign:
        case EOpBitwiseOrAssign:
        {
            const int secondarySize =
                std::max(mLeft->getSecondarySize(), mRight->getSecondarySize());
            setType(TType(basicType, higherPrecision, resultQualifier,
                          static_cast<unsigned char>(nominalSize),
                          static_cast<unsigned char>(secondarySize)));
            ASSERT(!mLeft->isArray() && !mRight->isArray());
            break;
        }
        case EOpEqual:
        case EOpNotEqual:
        case EOpLessThan:
        case EOpGreaterThan:
        case EOpLessThanEqual:
        case EOpGreaterThanEqual:
            ASSERT((mLeft->getNominalSize() == mRight->getNominalSize()) &&
                   (mLeft->getSecondarySize() == mRight->getSecondarySize()));
            setType(TType(EbtBool, EbpUndefined, resultQualifier));
            break;

        case EOpIndexDirect:
        case EOpIndexIndirect:
        case EOpIndexDirectInterfaceBlock:
        case EOpIndexDirectStruct:
            // These ops should be already fully handled.
            UNREACHABLE();
            break;
        default:
            UNREACHABLE();
            break;
    }
}

bool TIntermConstantUnion::hasConstantValue() const
{
    return true;
}

const TConstantUnion *TIntermConstantUnion::getConstantValue() const
{
    return mUnionArrayPointer;
}

const TConstantUnion *TIntermConstantUnion::FoldIndexing(const TType &type,
                                                         const TConstantUnion *constArray,
                                                         int index)
{
    if (type.isArray())
    {
        ASSERT(index < static_cast<int>(type.getOutermostArraySize()));
        TType arrayElementType(type);
        arrayElementType.toArrayElementType();
        size_t arrayElementSize = arrayElementType.getObjectSize();
        return &constArray[arrayElementSize * index];
    }
    else if (type.isMatrix())
    {
        ASSERT(index < type.getCols());
        int size = type.getRows();
        return &constArray[size * index];
    }
    else if (type.isVector())
    {
        ASSERT(index < type.getNominalSize());
        return &constArray[index];
    }
    else
    {
        UNREACHABLE();
        return nullptr;
    }
}

TIntermTyped *TIntermSwizzle::fold(TDiagnostics * /* diagnostics */)
{
    TIntermSwizzle *operandSwizzle = mOperand->getAsSwizzleNode();
    if (operandSwizzle)
    {
        // We need to fold the two swizzles into one, so that repeated swizzling can't cause stack
        // overflow in ParseContext::checkCanBeLValue().
        bool hadDuplicateOffsets = operandSwizzle->hasDuplicateOffsets();
        TVector<int> foldedOffsets;
        for (int offset : mSwizzleOffsets)
        {
            // Offset should already be validated.
            ASSERT(static_cast<size_t>(offset) < operandSwizzle->mSwizzleOffsets.size());
            foldedOffsets.push_back(operandSwizzle->mSwizzleOffsets[offset]);
        }
        operandSwizzle->mSwizzleOffsets = foldedOffsets;
        operandSwizzle->setType(getType());
        operandSwizzle->setHasFoldedDuplicateOffsets(hadDuplicateOffsets);
        return operandSwizzle;
    }
    TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion();
    if (operandConstant == nullptr)
    {
        return this;
    }

    TConstantUnion *constArray = new TConstantUnion[mSwizzleOffsets.size()];
    for (size_t i = 0; i < mSwizzleOffsets.size(); ++i)
    {
        constArray[i] = *TIntermConstantUnion::FoldIndexing(
            operandConstant->getType(), operandConstant->getConstantValue(), mSwizzleOffsets.at(i));
    }
    return CreateFoldedNode(constArray, this);
}

TIntermTyped *TIntermBinary::fold(TDiagnostics *diagnostics)
{
    const TConstantUnion *rightConstant = mRight->getConstantValue();
    switch (mOp)
    {
        case EOpComma:
        {
            if (mLeft->hasSideEffects())
            {
                return this;
            }
            return mRight;
        }
        case EOpIndexDirect:
        case EOpIndexDirectStruct:
        {
            if (rightConstant == nullptr)
            {
                return this;
            }
            size_t index                    = static_cast<size_t>(rightConstant->getIConst());
            TIntermAggregate *leftAggregate = mLeft->getAsAggregate();
            if (leftAggregate && leftAggregate->isConstructor() && leftAggregate->isArray() &&
                !leftAggregate->hasSideEffects())
            {
                ASSERT(index < leftAggregate->getSequence()->size());
                // This transformation can't add complexity as we're eliminating the constructor
                // entirely.
                return leftAggregate->getSequence()->at(index)->getAsTyped();
            }

            // If the indexed value is already a constant union, we can't increase duplication of
            // data by folding the indexing. Also fold the node in case it's generally beneficial to
            // replace this type of node with a constant union even if that would mean duplicating
            // data.
            if (mLeft->getAsConstantUnion() || getType().canReplaceWithConstantUnion())
            {
                const TConstantUnion *constantValue = getConstantValue();
                if (constantValue == nullptr)
                {
                    return this;
                }
                return CreateFoldedNode(constantValue, this);
            }
            return this;
        }
        case EOpIndexIndirect:
        case EOpIndexDirectInterfaceBlock:
        case EOpInitialize:
            // Can never be constant folded.
            return this;
        default:
        {
            if (rightConstant == nullptr)
            {
                return this;
            }
            const TConstantUnion *leftConstant = mLeft->getConstantValue();
            if (leftConstant == nullptr)
            {
                return this;
            }
            const TConstantUnion *constArray =
                TIntermConstantUnion::FoldBinary(mOp, leftConstant, mLeft->getType(), rightConstant,
                                                 mRight->getType(), diagnostics, mLeft->getLine());
            if (!constArray)
            {
                return this;
            }
            return CreateFoldedNode(constArray, this);
        }
    }
}

bool TIntermBinary::hasConstantValue() const
{
    switch (mOp)
    {
        case EOpIndexDirect:
        case EOpIndexDirectStruct:
        {
            if (mLeft->hasConstantValue() && mRight->hasConstantValue())
            {
                return true;
            }
            break;
        }
        default:
            break;
    }
    return false;
}

const TConstantUnion *TIntermBinary::getConstantValue() const
{
    if (!hasConstantValue())
    {
        return nullptr;
    }

    const TConstantUnion *leftConstantValue   = mLeft->getConstantValue();
    int index                                 = mRight->getConstantValue()->getIConst();
    const TConstantUnion *constIndexingResult = nullptr;
    if (mOp == EOpIndexDirect)
    {
        constIndexingResult =
            TIntermConstantUnion::FoldIndexing(mLeft->getType(), leftConstantValue, index);
    }
    else
    {
        ASSERT(mOp == EOpIndexDirectStruct);
        const TFieldList &fields = mLeft->getType().getStruct()->fields();

        size_t previousFieldsSize = 0;
        for (int i = 0; i < index; ++i)
        {
            previousFieldsSize += fields[i]->type()->getObjectSize();
        }
        constIndexingResult = leftConstantValue + previousFieldsSize;
    }
    return constIndexingResult;
}

const ImmutableString &TIntermBinary::getIndexStructFieldName() const
{
    ASSERT(mOp == EOpIndexDirectStruct);

    const TType &lhsType        = mLeft->getType();
    const TStructure *structure = lhsType.getStruct();
    const int index             = mRight->getAsConstantUnion()->getIConst(0);

    return structure->fields()[index]->name();
}

TIntermTyped *TIntermUnary::fold(TDiagnostics *diagnostics)
{
    TConstantUnion *constArray = nullptr;

    if (mOp == EOpArrayLength)
    {
        // The size of runtime-sized arrays may only be determined at runtime.
        if (mOperand->hasSideEffects() || mOperand->getType().isUnsizedArray())
        {
            return this;
        }
        constArray = new TConstantUnion[1];
        constArray->setIConst(mOperand->getOutermostArraySize());
    }
    else
    {
        TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion();
        if (operandConstant == nullptr)
        {
            return this;
        }

        switch (mOp)
        {
            case EOpAny:
            case EOpAll:
            case EOpLength:
            case EOpTranspose:
            case EOpDeterminant:
            case EOpInverse:
            case EOpPackSnorm2x16:
            case EOpUnpackSnorm2x16:
            case EOpPackUnorm2x16:
            case EOpUnpackUnorm2x16:
            case EOpPackHalf2x16:
            case EOpUnpackHalf2x16:
            case EOpPackUnorm4x8:
            case EOpPackSnorm4x8:
            case EOpUnpackUnorm4x8:
            case EOpUnpackSnorm4x8:
                constArray = operandConstant->foldUnaryNonComponentWise(mOp);
                break;
            default:
                constArray = operandConstant->foldUnaryComponentWise(mOp, diagnostics);
                break;
        }
    }
    if (constArray == nullptr)
    {
        return this;
    }
    return CreateFoldedNode(constArray, this);
}

TIntermTyped *TIntermAggregate::fold(TDiagnostics *diagnostics)
{
    // Make sure that all params are constant before actual constant folding.
    for (auto *param : *getSequence())
    {
        if (param->getAsConstantUnion() == nullptr)
        {
            return this;
        }
    }
    const TConstantUnion *constArray = nullptr;
    if (isConstructor())
    {
        if (mType.canReplaceWithConstantUnion())
        {
            constArray = getConstantValue();
            if (constArray && mType.getBasicType() == EbtUInt)
            {
                // Check if we converted a negative float to uint and issue a warning in that case.
                size_t sizeRemaining = mType.getObjectSize();
                for (TIntermNode *arg : mArguments)
                {
                    TIntermTyped *typedArg = arg->getAsTyped();
                    if (typedArg->getBasicType() == EbtFloat)
                    {
                        const TConstantUnion *argValue = typedArg->getConstantValue();
                        size_t castSize =
                            std::min(typedArg->getType().getObjectSize(), sizeRemaining);
                        for (size_t i = 0; i < castSize; ++i)
                        {
                            if (argValue[i].getFConst() < 0.0f)
                            {
                                // ESSL 3.00.6 section 5.4.1.
                                diagnostics->warning(
                                    mLine, "casting a negative float to uint is undefined",
                                    mType.getBuiltInTypeNameString());
                            }
                        }
                    }
                    sizeRemaining -= typedArg->getType().getObjectSize();
                }
            }
        }
    }
    else if (CanFoldAggregateBuiltInOp(mOp))
    {
        constArray = TIntermConstantUnion::FoldAggregateBuiltIn(this, diagnostics);
    }
    if (constArray == nullptr)
    {
        return this;
    }
    return CreateFoldedNode(constArray, this);
}

//
// The fold functions see if an operation on a constant can be done in place,
// without generating run-time code.
//
// Returns the constant value to keep using or nullptr.
//
const TConstantUnion *TIntermConstantUnion::FoldBinary(TOperator op,
                                                       const TConstantUnion *leftArray,
                                                       const TType &leftType,
                                                       const TConstantUnion *rightArray,
                                                       const TType &rightType,
                                                       TDiagnostics *diagnostics,
                                                       const TSourceLoc &line)
{
    ASSERT(leftArray && rightArray);

    size_t objectSize = leftType.getObjectSize();

    // for a case like float f = vec4(2, 3, 4, 5) + 1.2;
    if (rightType.getObjectSize() == 1 && objectSize > 1)
    {
        rightArray = Vectorize(*rightArray, objectSize);
    }
    else if (rightType.getObjectSize() > 1 && objectSize == 1)
    {
        // for a case like float f = 1.2 + vec4(2, 3, 4, 5);
        leftArray  = Vectorize(*leftArray, rightType.getObjectSize());
        objectSize = rightType.getObjectSize();
    }

    TConstantUnion *resultArray = nullptr;

    switch (op)
    {
        case EOpAdd:
            resultArray = new TConstantUnion[objectSize];
            for (size_t i = 0; i < objectSize; i++)
                resultArray[i] =
                    TConstantUnion::add(leftArray[i], rightArray[i], diagnostics, line);
            break;
        case EOpSub:
            resultArray = new TConstantUnion[objectSize];
            for (size_t i = 0; i < objectSize; i++)
                resultArray[i] =
                    TConstantUnion::sub(leftArray[i], rightArray[i], diagnostics, line);
            break;

        case EOpMul:
        case EOpVectorTimesScalar:
        case EOpMatrixTimesScalar:
            resultArray = new TConstantUnion[objectSize];
            for (size_t i = 0; i < objectSize; i++)
                resultArray[i] =
                    TConstantUnion::mul(leftArray[i], rightArray[i], diagnostics, line);
            break;

        case EOpMatrixTimesMatrix:
        {
            // TODO(jmadll): This code should check for overflows.
            ASSERT(leftType.getBasicType() == EbtFloat && rightType.getBasicType() == EbtFloat);

            const int leftCols   = leftType.getCols();
            const int leftRows   = leftType.getRows();
            const int rightCols  = rightType.getCols();
            const int rightRows  = rightType.getRows();
            const int resultCols = rightCols;
            const int resultRows = leftRows;

            resultArray = new TConstantUnion[resultCols * resultRows];
            for (int row = 0; row < resultRows; row++)
            {
                for (int column = 0; column < resultCols; column++)
                {
                    resultArray[resultRows * column + row].setFConst(0.0f);
                    for (int i = 0; i < leftCols; i++)
                    {
                        resultArray[resultRows * column + row].setFConst(
                            resultArray[resultRows * column + row].getFConst() +
                            leftArray[i * leftRows + row].getFConst() *
                                rightArray[column * rightRows + i].getFConst());
                    }
                }
            }
        }
        break;

        case EOpDiv:
        case EOpIMod:
        {
            resultArray = new TConstantUnion[objectSize];
            for (size_t i = 0; i < objectSize; i++)
            {
                switch (leftType.getBasicType())
                {
                    case EbtFloat:
                    {
                        ASSERT(op == EOpDiv);
                        float dividend = leftArray[i].getFConst();
                        float divisor  = rightArray[i].getFConst();
                        if (divisor == 0.0f)
                        {
                            if (dividend == 0.0f)
                            {
                                diagnostics->warning(
                                    line,
                                    "Zero divided by zero during constant folding generated NaN",
                                    "/");
                                resultArray[i].setFConst(std::numeric_limits<float>::quiet_NaN());
                            }
                            else
                            {
                                diagnostics->warning(line, "Divide by zero during constant folding",
                                                     "/");
                                bool negativeResult =
                                    std::signbit(dividend) != std::signbit(divisor);
                                resultArray[i].setFConst(
                                    negativeResult ? -std::numeric_limits<float>::infinity()
                                                   : std::numeric_limits<float>::infinity());
                            }
                        }
                        else if (gl::isInf(dividend) && gl::isInf(divisor))
                        {
                            diagnostics->warning(line,
                                                 "Infinity divided by infinity during constant "
                                                 "folding generated NaN",
                                                 "/");
                            resultArray[i].setFConst(std::numeric_limits<float>::quiet_NaN());
                        }
                        else
                        {
                            float result = dividend / divisor;
                            if (!gl::isInf(dividend) && gl::isInf(result))
                            {
                                diagnostics->warning(
                                    line, "Constant folded division overflowed to infinity", "/");
                            }
                            resultArray[i].setFConst(result);
                        }
                        break;
                    }
                    case EbtInt:
                        if (rightArray[i] == 0)
                        {
                            diagnostics->warning(
                                line, "Divide by zero error during constant folding", "/");
                            resultArray[i].setIConst(INT_MAX);
                        }
                        else
                        {
                            int lhs     = leftArray[i].getIConst();
                            int divisor = rightArray[i].getIConst();
                            if (op == EOpDiv)
                            {
                                // Check for the special case where the minimum representable number
                                // is
                                // divided by -1. If left alone this leads to integer overflow in
                                // C++.
                                // ESSL 3.00.6 section 4.1.3 Integers:
                                // "However, for the case where the minimum representable value is
                                // divided by -1, it is allowed to return either the minimum
                                // representable value or the maximum representable value."
                                if (lhs == -0x7fffffff - 1 && divisor == -1)
                                {
                                    resultArray[i].setIConst(0x7fffffff);
                                }
                                else
                                {
                                    resultArray[i].setIConst(lhs / divisor);
                                }
                            }
                            else
                            {
                                ASSERT(op == EOpIMod);
                                if (lhs < 0 || divisor < 0)
                                {
                                    // ESSL 3.00.6 section 5.9: Results of modulus are undefined
                                    // when either one of the operands is negative.
                                    diagnostics->warning(line,
                                                         "Negative modulus operator operand "
                                                         "encountered during constant folding. "
                                                         "Results are undefined.",
                                                         "%");
                                    resultArray[i].setIConst(0);
                                }
                                else
                                {
                                    resultArray[i].setIConst(lhs % divisor);
                                }
                            }
                        }
                        break;

                    case EbtUInt:
                        if (rightArray[i] == 0)
                        {
                            diagnostics->warning(
                                line, "Divide by zero error during constant folding", "/");
                            resultArray[i].setUConst(UINT_MAX);
                        }
                        else
                        {
                            if (op == EOpDiv)
                            {
                                resultArray[i].setUConst(leftArray[i].getUConst() /
                                                         rightArray[i].getUConst());
                            }
                            else
                            {
                                ASSERT(op == EOpIMod);
                                resultArray[i].setUConst(leftArray[i].getUConst() %
                                                         rightArray[i].getUConst());
                            }
                        }
                        break;

                    default:
                        UNREACHABLE();
                        return nullptr;
                }
            }
        }
        break;

        case EOpMatrixTimesVector:
        {
            // TODO(jmadll): This code should check for overflows.
            ASSERT(rightType.getBasicType() == EbtFloat);

            const int matrixCols = leftType.getCols();
            const int matrixRows = leftType.getRows();

            resultArray = new TConstantUnion[matrixRows];

            for (int matrixRow = 0; matrixRow < matrixRows; matrixRow++)
            {
                resultArray[matrixRow].setFConst(0.0f);
                for (int col = 0; col < matrixCols; col++)
                {
                    resultArray[matrixRow].setFConst(
                        resultArray[matrixRow].getFConst() +
                        leftArray[col * matrixRows + matrixRow].getFConst() *
                            rightArray[col].getFConst());
                }
            }
        }
        break;

        case EOpVectorTimesMatrix:
        {
            // TODO(jmadll): This code should check for overflows.
            ASSERT(leftType.getBasicType() == EbtFloat);

            const int matrixCols = rightType.getCols();
            const int matrixRows = rightType.getRows();

            resultArray = new TConstantUnion[matrixCols];

            for (int matrixCol = 0; matrixCol < matrixCols; matrixCol++)
            {
                resultArray[matrixCol].setFConst(0.0f);
                for (int matrixRow = 0; matrixRow < matrixRows; matrixRow++)
                {
                    resultArray[matrixCol].setFConst(
                        resultArray[matrixCol].getFConst() +
                        leftArray[matrixRow].getFConst() *
                            rightArray[matrixCol * matrixRows + matrixRow].getFConst());
                }
            }
        }
        break;

        case EOpLogicalAnd:
        {
            resultArray = new TConstantUnion[objectSize];
            for (size_t i = 0; i < objectSize; i++)
            {
                resultArray[i] = leftArray[i] && rightArray[i];
            }
        }
        break;

        case EOpLogicalOr:
        {
            resultArray = new TConstantUnion[objectSize];
            for (size_t i = 0; i < objectSize; i++)
            {
                resultArray[i] = leftArray[i] || rightArray[i];
            }
        }
        break;

        case EOpLogicalXor:
        {
            ASSERT(leftType.getBasicType() == EbtBool);
            resultArray = new TConstantUnion[objectSize];
            for (size_t i = 0; i < objectSize; i++)
            {
                resultArray[i].setBConst(leftArray[i] != rightArray[i]);
            }
        }
        break;

        case EOpBitwiseAnd:
            resultArray = new TConstantUnion[objectSize];
            for (size_t i = 0; i < objectSize; i++)
                resultArray[i] = leftArray[i] & rightArray[i];
            break;
        case EOpBitwiseXor:
            resultArray = new TConstantUnion[objectSize];
            for (size_t i = 0; i < objectSize; i++)
                resultArray[i] = leftArray[i] ^ rightArray[i];
            break;
        case EOpBitwiseOr:
            resultArray = new TConstantUnion[objectSize];
            for (size_t i = 0; i < objectSize; i++)
                resultArray[i] = leftArray[i] | rightArray[i];
            break;
        case EOpBitShiftLeft:
            resultArray = new TConstantUnion[objectSize];
            for (size_t i = 0; i < objectSize; i++)
                resultArray[i] =
                    TConstantUnion::lshift(leftArray[i], rightArray[i], diagnostics, line);
            break;
        case EOpBitShiftRight:
            resultArray = new TConstantUnion[objectSize];
            for (size_t i = 0; i < objectSize; i++)
                resultArray[i] =
                    TConstantUnion::rshift(leftArray[i], rightArray[i], diagnostics, line);
            break;

        case EOpLessThan:
            ASSERT(objectSize == 1);
            resultArray = new TConstantUnion[1];
            resultArray->setBConst(*leftArray < *rightArray);
            break;

        case EOpGreaterThan:
            ASSERT(objectSize == 1);
            resultArray = new TConstantUnion[1];
            resultArray->setBConst(*leftArray > *rightArray);
            break;

        case EOpLessThanEqual:
            ASSERT(objectSize == 1);
            resultArray = new TConstantUnion[1];
            resultArray->setBConst(!(*leftArray > *rightArray));
            break;

        case EOpGreaterThanEqual:
            ASSERT(objectSize == 1);
            resultArray = new TConstantUnion[1];
            resultArray->setBConst(!(*leftArray < *rightArray));
            break;

        case EOpEqual:
        case EOpNotEqual:
        {
            resultArray = new TConstantUnion[1];
            bool equal  = true;
            for (size_t i = 0; i < objectSize; i++)
            {
                if (leftArray[i] != rightArray[i])
                {
                    equal = false;
                    break;  // break out of for loop
                }
            }
            if (op == EOpEqual)
            {
                resultArray->setBConst(equal);
            }
            else
            {
                resultArray->setBConst(!equal);
            }
        }
        break;

        default:
            UNREACHABLE();
            return nullptr;
    }
    return resultArray;
}

// The fold functions do operations on a constant at GLSL compile time, without generating run-time
// code. Returns the constant value to keep using. Nullptr should not be returned.
TConstantUnion *TIntermConstantUnion::foldUnaryNonComponentWise(TOperator op)
{
    // Do operations where the return type may have a different number of components compared to the
    // operand type.

    const TConstantUnion *operandArray = getConstantValue();
    ASSERT(operandArray);

    size_t objectSize           = getType().getObjectSize();
    TConstantUnion *resultArray = nullptr;
    switch (op)
    {
        case EOpAny:
            ASSERT(getType().getBasicType() == EbtBool);
            resultArray = new TConstantUnion();
            resultArray->setBConst(false);
            for (size_t i = 0; i < objectSize; i++)
            {
                if (operandArray[i].getBConst())
                {
                    resultArray->setBConst(true);
                    break;
                }
            }
            break;

        case EOpAll:
            ASSERT(getType().getBasicType() == EbtBool);
            resultArray = new TConstantUnion();
            resultArray->setBConst(true);
            for (size_t i = 0; i < objectSize; i++)
            {
                if (!operandArray[i].getBConst())
                {
                    resultArray->setBConst(false);
                    break;
                }
            }
            break;

        case EOpLength:
            ASSERT(getType().getBasicType() == EbtFloat);
            resultArray = new TConstantUnion();
            resultArray->setFConst(VectorLength(operandArray, objectSize));
            break;

        case EOpTranspose:
        {
            ASSERT(getType().getBasicType() == EbtFloat);
            resultArray = new TConstantUnion[objectSize];
            angle::Matrix<float> result =
                GetMatrix(operandArray, getType().getRows(), getType().getCols()).transpose();
            SetUnionArrayFromMatrix(result, resultArray);
            break;
        }

        case EOpDeterminant:
        {
            ASSERT(getType().getBasicType() == EbtFloat);
            unsigned int size = getType().getNominalSize();
            ASSERT(size >= 2 && size <= 4);
            resultArray = new TConstantUnion();
            resultArray->setFConst(GetMatrix(operandArray, size).determinant());
            break;
        }

        case EOpInverse:
        {
            ASSERT(getType().getBasicType() == EbtFloat);
            unsigned int size = getType().getNominalSize();
            ASSERT(size >= 2 && size <= 4);
            resultArray                 = new TConstantUnion[objectSize];
            angle::Matrix<float> result = GetMatrix(operandArray, size).inverse();
            SetUnionArrayFromMatrix(result, resultArray);
            break;
        }

        case EOpPackSnorm2x16:
            ASSERT(getType().getBasicType() == EbtFloat);
            ASSERT(getType().getNominalSize() == 2);
            resultArray = new TConstantUnion();
            resultArray->setUConst(
                gl::packSnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
            break;

        case EOpUnpackSnorm2x16:
        {
            ASSERT(getType().getBasicType() == EbtUInt);
            resultArray = new TConstantUnion[2];
            float f1, f2;
            gl::unpackSnorm2x16(operandArray[0].getUConst(), &f1, &f2);
            resultArray[0].setFConst(f1);
            resultArray[1].setFConst(f2);
            break;
        }

        case EOpPackUnorm2x16:
            ASSERT(getType().getBasicType() == EbtFloat);
            ASSERT(getType().getNominalSize() == 2);
            resultArray = new TConstantUnion();
            resultArray->setUConst(
                gl::packUnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
            break;

        case EOpUnpackUnorm2x16:
        {
            ASSERT(getType().getBasicType() == EbtUInt);
            resultArray = new TConstantUnion[2];
            float f1, f2;
            gl::unpackUnorm2x16(operandArray[0].getUConst(), &f1, &f2);
            resultArray[0].setFConst(f1);
            resultArray[1].setFConst(f2);
            break;
        }

        case EOpPackHalf2x16:
            ASSERT(getType().getBasicType() == EbtFloat);
            ASSERT(getType().getNominalSize() == 2);
            resultArray = new TConstantUnion();
            resultArray->setUConst(
                gl::packHalf2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
            break;

        case EOpUnpackHalf2x16:
        {
            ASSERT(getType().getBasicType() == EbtUInt);
            resultArray = new TConstantUnion[2];
            float f1, f2;
            gl::unpackHalf2x16(operandArray[0].getUConst(), &f1, &f2);
            resultArray[0].setFConst(f1);
            resultArray[1].setFConst(f2);
            break;
        }

        case EOpPackUnorm4x8:
        {
            ASSERT(getType().getBasicType() == EbtFloat);
            resultArray = new TConstantUnion();
            resultArray->setUConst(
                gl::PackUnorm4x8(operandArray[0].getFConst(), operandArray[1].getFConst(),
                                 operandArray[2].getFConst(), operandArray[3].getFConst()));
            break;
        }
        case EOpPackSnorm4x8:
        {
            ASSERT(getType().getBasicType() == EbtFloat);
            resultArray = new TConstantUnion();
            resultArray->setUConst(
                gl::PackSnorm4x8(operandArray[0].getFConst(), operandArray[1].getFConst(),
                                 operandArray[2].getFConst(), operandArray[3].getFConst()));
            break;
        }
        case EOpUnpackUnorm4x8:
        {
            ASSERT(getType().getBasicType() == EbtUInt);
            resultArray = new TConstantUnion[4];
            float f[4];
            gl::UnpackUnorm4x8(operandArray[0].getUConst(), f);
            for (size_t i = 0; i < 4; ++i)
            {
                resultArray[i].setFConst(f[i]);
            }
            break;
        }
        case EOpUnpackSnorm4x8:
        {
            ASSERT(getType().getBasicType() == EbtUInt);
            resultArray = new TConstantUnion[4];
            float f[4];
            gl::UnpackSnorm4x8(operandArray[0].getUConst(), f);
            for (size_t i = 0; i < 4; ++i)
            {
                resultArray[i].setFConst(f[i]);
            }
            break;
        }

        default:
            UNREACHABLE();
            break;
    }

    return resultArray;
}

TConstantUnion *TIntermConstantUnion::foldUnaryComponentWise(TOperator op,
                                                             TDiagnostics *diagnostics)
{
    // Do unary operations where each component of the result is computed based on the corresponding
    // component of the operand. Also folds normalize, though the divisor in that case takes all
    // components into account.

    const TConstantUnion *operandArray = getConstantValue();
    ASSERT(operandArray);

    size_t objectSize = getType().getObjectSize();

    TConstantUnion *resultArray = new TConstantUnion[objectSize];
    for (size_t i = 0; i < objectSize; i++)
    {
        switch (op)
        {
            case EOpNegative:
                switch (getType().getBasicType())
                {
                    case EbtFloat:
                        resultArray[i].setFConst(-operandArray[i].getFConst());
                        break;
                    case EbtInt:
                        if (operandArray[i] == std::numeric_limits<int>::min())
                        {
                            // The minimum representable integer doesn't have a positive
                            // counterpart, rather the negation overflows and in ESSL is supposed to
                            // wrap back to the minimum representable integer. Make sure that we
                            // don't actually let the negation overflow, which has undefined
                            // behavior in C++.
                            resultArray[i].setIConst(std::numeric_limits<int>::min());
                        }
                        else
                        {
                            resultArray[i].setIConst(-operandArray[i].getIConst());
                        }
                        break;
                    case EbtUInt:
                        if (operandArray[i] == 0x80000000u)
                        {
                            resultArray[i].setUConst(0x80000000u);
                        }
                        else
                        {
                            resultArray[i].setUConst(static_cast<unsigned int>(
                                -static_cast<int>(operandArray[i].getUConst())));
                        }
                        break;
                    default:
                        UNREACHABLE();
                        return nullptr;
                }
                break;

            case EOpPositive:
                switch (getType().getBasicType())
                {
                    case EbtFloat:
                        resultArray[i].setFConst(operandArray[i].getFConst());
                        break;
                    case EbtInt:
                        resultArray[i].setIConst(operandArray[i].getIConst());
                        break;
                    case EbtUInt:
                        resultArray[i].setUConst(static_cast<unsigned int>(
                            static_cast<int>(operandArray[i].getUConst())));
                        break;
                    default:
                        UNREACHABLE();
                        return nullptr;
                }
                break;

            case EOpLogicalNot:
                switch (getType().getBasicType())
                {
                    case EbtBool:
                        resultArray[i].setBConst(!operandArray[i].getBConst());
                        break;
                    default:
                        UNREACHABLE();
                        return nullptr;
                }
                break;

            case EOpBitwiseNot:
                switch (getType().getBasicType())
                {
                    case EbtInt:
                        resultArray[i].setIConst(~operandArray[i].getIConst());
                        break;
                    case EbtUInt:
                        resultArray[i].setUConst(~operandArray[i].getUConst());
                        break;
                    default:
                        UNREACHABLE();
                        return nullptr;
                }
                break;

            case EOpRadians:
                ASSERT(getType().getBasicType() == EbtFloat);
                resultArray[i].setFConst(kDegreesToRadiansMultiplier * operandArray[i].getFConst());
                break;

            case EOpDegrees:
                ASSERT(getType().getBasicType() == EbtFloat);
                resultArray[i].setFConst(kRadiansToDegreesMultiplier * operandArray[i].getFConst());
                break;

            case EOpSin:
                foldFloatTypeUnary(operandArray[i], &sinf, &resultArray[i]);
                break;

            case EOpCos:
                foldFloatTypeUnary(operandArray[i], &cosf, &resultArray[i]);
                break;

            case EOpTan:
                foldFloatTypeUnary(operandArray[i], &tanf, &resultArray[i]);
                break;

            case EOpAsin:
                // For asin(x), results are undefined if |x| > 1, we are choosing to set result to
                // 0.
                if (fabsf(operandArray[i].getFConst()) > 1.0f)
                    UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(),
                                                  diagnostics, &resultArray[i]);
                else
                    foldFloatTypeUnary(operandArray[i], &asinf, &resultArray[i]);
                break;

            case EOpAcos:
                // For acos(x), results are undefined if |x| > 1, we are choosing to set result to
                // 0.
                if (fabsf(operandArray[i].getFConst()) > 1.0f)
                    UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(),
                                                  diagnostics, &resultArray[i]);
                else
                    foldFloatTypeUnary(operandArray[i], &acosf, &resultArray[i]);
                break;

            case EOpAtan:
                foldFloatTypeUnary(operandArray[i], &atanf, &resultArray[i]);
                break;

            case EOpSinh:
                foldFloatTypeUnary(operandArray[i], &sinhf, &resultArray[i]);
                break;

            case EOpCosh:
                foldFloatTypeUnary(operandArray[i], &coshf, &resultArray[i]);
                break;

            case EOpTanh:
                foldFloatTypeUnary(operandArray[i], &tanhf, &resultArray[i]);
                break;

            case EOpAsinh:
                foldFloatTypeUnary(operandArray[i], &asinhf, &resultArray[i]);
                break;

            case EOpAcosh:
                // For acosh(x), results are undefined if x < 1, we are choosing to set result to 0.
                if (operandArray[i].getFConst() < 1.0f)
                    UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(),
                                                  diagnostics, &resultArray[i]);
                else
                    foldFloatTypeUnary(operandArray[i], &acoshf, &resultArray[i]);
                break;

            case EOpAtanh:
                // For atanh(x), results are undefined if |x| >= 1, we are choosing to set result to
                // 0.
                if (fabsf(operandArray[i].getFConst()) >= 1.0f)
                    UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(),
                                                  diagnostics, &resultArray[i]);
                else
                    foldFloatTypeUnary(operandArray[i], &atanhf, &resultArray[i]);
                break;

            case EOpAbs:
                switch (getType().getBasicType())
                {
                    case EbtFloat:
                        resultArray[i].setFConst(fabsf(operandArray[i].getFConst()));
                        break;
                    case EbtInt:
                        resultArray[i].setIConst(abs(operandArray[i].getIConst()));
                        break;
                    default:
                        UNREACHABLE();
                        return nullptr;
                }
                break;

            case EOpSign:
                switch (getType().getBasicType())
                {
                    case EbtFloat:
                    {
                        float fConst  = operandArray[i].getFConst();
                        float fResult = 0.0f;
                        if (fConst > 0.0f)
                            fResult = 1.0f;
                        else if (fConst < 0.0f)
                            fResult = -1.0f;
                        resultArray[i].setFConst(fResult);
                        break;
                    }
                    case EbtInt:
                    {
                        int iConst  = operandArray[i].getIConst();
                        int iResult = 0;
                        if (iConst > 0)
                            iResult = 1;
                        else if (iConst < 0)
                            iResult = -1;
                        resultArray[i].setIConst(iResult);
                        break;
                    }
                    default:
                        UNREACHABLE();
                        return nullptr;
                }
                break;

            case EOpFloor:
                foldFloatTypeUnary(operandArray[i], &floorf, &resultArray[i]);
                break;

            case EOpTrunc:
                foldFloatTypeUnary(operandArray[i], &truncf, &resultArray[i]);
                break;

            case EOpRound:
                foldFloatTypeUnary(operandArray[i], &roundf, &resultArray[i]);
                break;

            case EOpRoundEven:
            {
                ASSERT(getType().getBasicType() == EbtFloat);
                float x = operandArray[i].getFConst();
                float result;
                float fractPart = modff(x, &result);
                if (fabsf(fractPart) == 0.5f)
                    result = 2.0f * roundf(x / 2.0f);
                else
                    result = roundf(x);
                resultArray[i].setFConst(result);
                break;
            }

            case EOpCeil:
                foldFloatTypeUnary(operandArray[i], &ceilf, &resultArray[i]);
                break;

            case EOpFract:
            {
                ASSERT(getType().getBasicType() == EbtFloat);
                float x = operandArray[i].getFConst();
                resultArray[i].setFConst(x - floorf(x));
                break;
            }

            case EOpIsnan:
                ASSERT(getType().getBasicType() == EbtFloat);
                resultArray[i].setBConst(gl::isNaN(operandArray[0].getFConst()));
                break;

            case EOpIsinf:
                ASSERT(getType().getBasicType() == EbtFloat);
                resultArray[i].setBConst(gl::isInf(operandArray[0].getFConst()));
                break;

            case EOpFloatBitsToInt:
                ASSERT(getType().getBasicType() == EbtFloat);
                resultArray[i].setIConst(gl::bitCast<int32_t>(operandArray[0].getFConst()));
                break;

            case EOpFloatBitsToUint:
                ASSERT(getType().getBasicType() == EbtFloat);
                resultArray[i].setUConst(gl::bitCast<uint32_t>(operandArray[0].getFConst()));
                break;

            case EOpIntBitsToFloat:
                ASSERT(getType().getBasicType() == EbtInt);
                resultArray[i].setFConst(gl::bitCast<float>(operandArray[0].getIConst()));
                break;

            case EOpUintBitsToFloat:
                ASSERT(getType().getBasicType() == EbtUInt);
                resultArray[i].setFConst(gl::bitCast<float>(operandArray[0].getUConst()));
                break;

            case EOpExp:
                foldFloatTypeUnary(operandArray[i], &expf, &resultArray[i]);
                break;

            case EOpLog:
                // For log(x), results are undefined if x <= 0, we are choosing to set result to 0.
                if (operandArray[i].getFConst() <= 0.0f)
                    UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(),
                                                  diagnostics, &resultArray[i]);
                else
                    foldFloatTypeUnary(operandArray[i], &logf, &resultArray[i]);
                break;

            case EOpExp2:
                foldFloatTypeUnary(operandArray[i], &exp2f, &resultArray[i]);
                break;

            case EOpLog2:
                // For log2(x), results are undefined if x <= 0, we are choosing to set result to 0.
                // And log2f is not available on some plarforms like old android, so just using
                // log(x)/log(2) here.
                if (operandArray[i].getFConst() <= 0.0f)
                    UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(),
                                                  diagnostics, &resultArray[i]);
                else
                {
                    foldFloatTypeUnary(operandArray[i], &logf, &resultArray[i]);
                    resultArray[i].setFConst(resultArray[i].getFConst() / logf(2.0f));
                }
                break;

            case EOpSqrt:
                // For sqrt(x), results are undefined if x < 0, we are choosing to set result to 0.
                if (operandArray[i].getFConst() < 0.0f)
                    UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(),
                                                  diagnostics, &resultArray[i]);
                else
                    foldFloatTypeUnary(operandArray[i], &sqrtf, &resultArray[i]);
                break;

            case EOpInversesqrt:
                // There is no stdlib built-in function equavalent for GLES built-in inversesqrt(),
                // so getting the square root first using builtin function sqrt() and then taking
                // its inverse.
                // Also, for inversesqrt(x), results are undefined if x <= 0, we are choosing to set
                // result to 0.
                if (operandArray[i].getFConst() <= 0.0f)
                    UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(),
                                                  diagnostics, &resultArray[i]);
                else
                {
                    foldFloatTypeUnary(operandArray[i], &sqrtf, &resultArray[i]);
                    resultArray[i].setFConst(1.0f / resultArray[i].getFConst());
                }
                break;

            case EOpLogicalNotComponentWise:
                ASSERT(getType().getBasicType() == EbtBool);
                resultArray[i].setBConst(!operandArray[i].getBConst());
                break;

            case EOpNormalize:
            {
                ASSERT(getType().getBasicType() == EbtFloat);
                float x      = operandArray[i].getFConst();
                float length = VectorLength(operandArray, objectSize);
                if (length)
                    resultArray[i].setFConst(x / length);
                else
                    UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(),
                                                  diagnostics, &resultArray[i]);
                break;
            }
            case EOpBitfieldReverse:
            {
                uint32_t value;
                if (getType().getBasicType() == EbtInt)
                {
                    value = static_cast<uint32_t>(operandArray[i].getIConst());
                }
                else
                {
                    ASSERT(getType().getBasicType() == EbtUInt);
                    value = operandArray[i].getUConst();
                }
                uint32_t result = gl::BitfieldReverse(value);
                if (getType().getBasicType() == EbtInt)
                {
                    resultArray[i].setIConst(static_cast<int32_t>(result));
                }
                else
                {
                    resultArray[i].setUConst(result);
                }
                break;
            }
            case EOpBitCount:
            {
                uint32_t value;
                if (getType().getBasicType() == EbtInt)
                {
                    value = static_cast<uint32_t>(operandArray[i].getIConst());
                }
                else
                {
                    ASSERT(getType().getBasicType() == EbtUInt);
                    value = operandArray[i].getUConst();
                }
                int result = gl::BitCount(value);
                resultArray[i].setIConst(result);
                break;
            }
            case EOpFindLSB:
            {
                uint32_t value;
                if (getType().getBasicType() == EbtInt)
                {
                    value = static_cast<uint32_t>(operandArray[i].getIConst());
                }
                else
                {
                    ASSERT(getType().getBasicType() == EbtUInt);
                    value = operandArray[i].getUConst();
                }
                resultArray[i].setIConst(gl::FindLSB(value));
                break;
            }
            case EOpFindMSB:
            {
                uint32_t value;
                if (getType().getBasicType() == EbtInt)
                {
                    int intValue = operandArray[i].getIConst();
                    value        = static_cast<uint32_t>(intValue);
                    if (intValue < 0)
                    {
                        // Look for zero instead of one in value. This also handles the intValue ==
                        // -1 special case, where the return value needs to be -1.
                        value = ~value;
                    }
                }
                else
                {
                    ASSERT(getType().getBasicType() == EbtUInt);
                    value = operandArray[i].getUConst();
                }
                resultArray[i].setIConst(gl::FindMSB(value));
                break;
            }
            case EOpDFdx:
            case EOpDFdy:
            case EOpFwidth:
                ASSERT(getType().getBasicType() == EbtFloat);
                // Derivatives of constant arguments should be 0.
                resultArray[i].setFConst(0.0f);
                break;

            default:
                return nullptr;
        }
    }

    return resultArray;
}

void TIntermConstantUnion::foldFloatTypeUnary(const TConstantUnion &parameter,
                                              FloatTypeUnaryFunc builtinFunc,
                                              TConstantUnion *result) const
{
    ASSERT(builtinFunc);

    ASSERT(getType().getBasicType() == EbtFloat);
    result->setFConst(builtinFunc(parameter.getFConst()));
}

// static
TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *aggregate,
                                                           TDiagnostics *diagnostics)
{
    TOperator op               = aggregate->getOp();
    TIntermSequence *arguments = aggregate->getSequence();
    unsigned int argsCount     = static_cast<unsigned int>(arguments->size());
    std::vector<const TConstantUnion *> unionArrays(argsCount);
    std::vector<size_t> objectSizes(argsCount);
    size_t maxObjectSize = 0;
    TBasicType basicType = EbtVoid;
    TSourceLoc loc;
    for (unsigned int i = 0; i < argsCount; i++)
    {
        TIntermConstantUnion *argConstant = (*arguments)[i]->getAsConstantUnion();
        ASSERT(argConstant != nullptr);  // Should be checked already.

        if (i == 0)
        {
            basicType = argConstant->getType().getBasicType();
            loc       = argConstant->getLine();
        }
        unionArrays[i] = argConstant->getConstantValue();
        objectSizes[i] = argConstant->getType().getObjectSize();
        if (objectSizes[i] > maxObjectSize)
            maxObjectSize = objectSizes[i];
    }

    if (!(*arguments)[0]->getAsTyped()->isMatrix() && aggregate->getOp() != EOpOuterProduct)
    {
        for (unsigned int i = 0; i < argsCount; i++)
            if (objectSizes[i] != maxObjectSize)
                unionArrays[i] = Vectorize(*unionArrays[i], maxObjectSize);
    }

    TConstantUnion *resultArray = nullptr;

    switch (op)
    {
        case EOpAtan:
        {
            ASSERT(basicType == EbtFloat);
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                float y = unionArrays[0][i].getFConst();
                float x = unionArrays[1][i].getFConst();
                // Results are undefined if x and y are both 0.
                if (x == 0.0f && y == 0.0f)
                    UndefinedConstantFoldingError(loc, op, basicType, diagnostics, &resultArray[i]);
                else
                    resultArray[i].setFConst(atan2f(y, x));
            }
            break;
        }

        case EOpPow:
        {
            ASSERT(basicType == EbtFloat);
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                float x = unionArrays[0][i].getFConst();
                float y = unionArrays[1][i].getFConst();
                // Results are undefined if x < 0.
                // Results are undefined if x = 0 and y <= 0.
                if (x < 0.0f)
                    UndefinedConstantFoldingError(loc, op, basicType, diagnostics, &resultArray[i]);
                else if (x == 0.0f && y <= 0.0f)
                    UndefinedConstantFoldingError(loc, op, basicType, diagnostics, &resultArray[i]);
                else
                    resultArray[i].setFConst(powf(x, y));
            }
            break;
        }

        case EOpMod:
        {
            ASSERT(basicType == EbtFloat);
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                float x = unionArrays[0][i].getFConst();
                float y = unionArrays[1][i].getFConst();
                resultArray[i].setFConst(x - y * floorf(x / y));
            }
            break;
        }

        case EOpMin:
        {
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                switch (basicType)
                {
                    case EbtFloat:
                        resultArray[i].setFConst(
                            std::min(unionArrays[0][i].getFConst(), unionArrays[1][i].getFConst()));
                        break;
                    case EbtInt:
                        resultArray[i].setIConst(
                            std::min(unionArrays[0][i].getIConst(), unionArrays[1][i].getIConst()));
                        break;
                    case EbtUInt:
                        resultArray[i].setUConst(
                            std::min(unionArrays[0][i].getUConst(), unionArrays[1][i].getUConst()));
                        break;
                    default:
                        UNREACHABLE();
                        break;
                }
            }
            break;
        }

        case EOpMax:
        {
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                switch (basicType)
                {
                    case EbtFloat:
                        resultArray[i].setFConst(
                            std::max(unionArrays[0][i].getFConst(), unionArrays[1][i].getFConst()));
                        break;
                    case EbtInt:
                        resultArray[i].setIConst(
                            std::max(unionArrays[0][i].getIConst(), unionArrays[1][i].getIConst()));
                        break;
                    case EbtUInt:
                        resultArray[i].setUConst(
                            std::max(unionArrays[0][i].getUConst(), unionArrays[1][i].getUConst()));
                        break;
                    default:
                        UNREACHABLE();
                        break;
                }
            }
            break;
        }

        case EOpStep:
        {
            ASSERT(basicType == EbtFloat);
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; i++)
                resultArray[i].setFConst(
                    unionArrays[1][i].getFConst() < unionArrays[0][i].getFConst() ? 0.0f : 1.0f);
            break;
        }

        case EOpLessThanComponentWise:
        {
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                switch (basicType)
                {
                    case EbtFloat:
                        resultArray[i].setBConst(unionArrays[0][i].getFConst() <
                                                 unionArrays[1][i].getFConst());
                        break;
                    case EbtInt:
                        resultArray[i].setBConst(unionArrays[0][i].getIConst() <
                                                 unionArrays[1][i].getIConst());
                        break;
                    case EbtUInt:
                        resultArray[i].setBConst(unionArrays[0][i].getUConst() <
                                                 unionArrays[1][i].getUConst());
                        break;
                    default:
                        UNREACHABLE();
                        break;
                }
            }
            break;
        }

        case EOpLessThanEqualComponentWise:
        {
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                switch (basicType)
                {
                    case EbtFloat:
                        resultArray[i].setBConst(unionArrays[0][i].getFConst() <=
                                                 unionArrays[1][i].getFConst());
                        break;
                    case EbtInt:
                        resultArray[i].setBConst(unionArrays[0][i].getIConst() <=
                                                 unionArrays[1][i].getIConst());
                        break;
                    case EbtUInt:
                        resultArray[i].setBConst(unionArrays[0][i].getUConst() <=
                                                 unionArrays[1][i].getUConst());
                        break;
                    default:
                        UNREACHABLE();
                        break;
                }
            }
            break;
        }

        case EOpGreaterThanComponentWise:
        {
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                switch (basicType)
                {
                    case EbtFloat:
                        resultArray[i].setBConst(unionArrays[0][i].getFConst() >
                                                 unionArrays[1][i].getFConst());
                        break;
                    case EbtInt:
                        resultArray[i].setBConst(unionArrays[0][i].getIConst() >
                                                 unionArrays[1][i].getIConst());
                        break;
                    case EbtUInt:
                        resultArray[i].setBConst(unionArrays[0][i].getUConst() >
                                                 unionArrays[1][i].getUConst());
                        break;
                    default:
                        UNREACHABLE();
                        break;
                }
            }
            break;
        }
        case EOpGreaterThanEqualComponentWise:
        {
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                switch (basicType)
                {
                    case EbtFloat:
                        resultArray[i].setBConst(unionArrays[0][i].getFConst() >=
                                                 unionArrays[1][i].getFConst());
                        break;
                    case EbtInt:
                        resultArray[i].setBConst(unionArrays[0][i].getIConst() >=
                                                 unionArrays[1][i].getIConst());
                        break;
                    case EbtUInt:
                        resultArray[i].setBConst(unionArrays[0][i].getUConst() >=
                                                 unionArrays[1][i].getUConst());
                        break;
                    default:
                        UNREACHABLE();
                        break;
                }
            }
        }
        break;

        case EOpEqualComponentWise:
        {
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                switch (basicType)
                {
                    case EbtFloat:
                        resultArray[i].setBConst(unionArrays[0][i].getFConst() ==
                                                 unionArrays[1][i].getFConst());
                        break;
                    case EbtInt:
                        resultArray[i].setBConst(unionArrays[0][i].getIConst() ==
                                                 unionArrays[1][i].getIConst());
                        break;
                    case EbtUInt:
                        resultArray[i].setBConst(unionArrays[0][i].getUConst() ==
                                                 unionArrays[1][i].getUConst());
                        break;
                    case EbtBool:
                        resultArray[i].setBConst(unionArrays[0][i].getBConst() ==
                                                 unionArrays[1][i].getBConst());
                        break;
                    default:
                        UNREACHABLE();
                        break;
                }
            }
            break;
        }

        case EOpNotEqualComponentWise:
        {
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                switch (basicType)
                {
                    case EbtFloat:
                        resultArray[i].setBConst(unionArrays[0][i].getFConst() !=
                                                 unionArrays[1][i].getFConst());
                        break;
                    case EbtInt:
                        resultArray[i].setBConst(unionArrays[0][i].getIConst() !=
                                                 unionArrays[1][i].getIConst());
                        break;
                    case EbtUInt:
                        resultArray[i].setBConst(unionArrays[0][i].getUConst() !=
                                                 unionArrays[1][i].getUConst());
                        break;
                    case EbtBool:
                        resultArray[i].setBConst(unionArrays[0][i].getBConst() !=
                                                 unionArrays[1][i].getBConst());
                        break;
                    default:
                        UNREACHABLE();
                        break;
                }
            }
            break;
        }

        case EOpDistance:
        {
            ASSERT(basicType == EbtFloat);
            TConstantUnion *distanceArray = new TConstantUnion[maxObjectSize];
            resultArray                   = new TConstantUnion();
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                float x = unionArrays[0][i].getFConst();
                float y = unionArrays[1][i].getFConst();
                distanceArray[i].setFConst(x - y);
            }
            resultArray->setFConst(VectorLength(distanceArray, maxObjectSize));
            break;
        }

        case EOpDot:
            ASSERT(basicType == EbtFloat);
            resultArray = new TConstantUnion();
            resultArray->setFConst(VectorDotProduct(unionArrays[0], unionArrays[1], maxObjectSize));
            break;

        case EOpCross:
        {
            ASSERT(basicType == EbtFloat && maxObjectSize == 3);
            resultArray = new TConstantUnion[maxObjectSize];
            float x0    = unionArrays[0][0].getFConst();
            float x1    = unionArrays[0][1].getFConst();
            float x2    = unionArrays[0][2].getFConst();
            float y0    = unionArrays[1][0].getFConst();
            float y1    = unionArrays[1][1].getFConst();
            float y2    = unionArrays[1][2].getFConst();
            resultArray[0].setFConst(x1 * y2 - y1 * x2);
            resultArray[1].setFConst(x2 * y0 - y2 * x0);
            resultArray[2].setFConst(x0 * y1 - y0 * x1);
            break;
        }

        case EOpReflect:
        {
            ASSERT(basicType == EbtFloat);
            // genType reflect (genType I, genType N) :
            //     For the incident vector I and surface orientation N, returns the reflection
            //     direction:
            //     I - 2 * dot(N, I) * N.
            resultArray      = new TConstantUnion[maxObjectSize];
            float dotProduct = VectorDotProduct(unionArrays[1], unionArrays[0], maxObjectSize);
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                float result = unionArrays[0][i].getFConst() -
                               2.0f * dotProduct * unionArrays[1][i].getFConst();
                resultArray[i].setFConst(result);
            }
            break;
        }

        case EOpMulMatrixComponentWise:
        {
            ASSERT(basicType == EbtFloat && (*arguments)[0]->getAsTyped()->isMatrix() &&
                   (*arguments)[1]->getAsTyped()->isMatrix());
            // Perform component-wise matrix multiplication.
            resultArray                 = new TConstantUnion[maxObjectSize];
            int rows                    = (*arguments)[0]->getAsTyped()->getRows();
            int cols                    = (*arguments)[0]->getAsTyped()->getCols();
            angle::Matrix<float> lhs    = GetMatrix(unionArrays[0], rows, cols);
            angle::Matrix<float> rhs    = GetMatrix(unionArrays[1], rows, cols);
            angle::Matrix<float> result = lhs.compMult(rhs);
            SetUnionArrayFromMatrix(result, resultArray);
            break;
        }

        case EOpOuterProduct:
        {
            ASSERT(basicType == EbtFloat);
            size_t numRows = (*arguments)[0]->getAsTyped()->getType().getObjectSize();
            size_t numCols = (*arguments)[1]->getAsTyped()->getType().getObjectSize();
            resultArray    = new TConstantUnion[numRows * numCols];
            angle::Matrix<float> result =
                GetMatrix(unionArrays[0], static_cast<int>(numRows), 1)
                    .outerProduct(GetMatrix(unionArrays[1], 1, static_cast<int>(numCols)));
            SetUnionArrayFromMatrix(result, resultArray);
            break;
        }

        case EOpClamp:
        {
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                switch (basicType)
                {
                    case EbtFloat:
                    {
                        float x   = unionArrays[0][i].getFConst();
                        float min = unionArrays[1][i].getFConst();
                        float max = unionArrays[2][i].getFConst();
                        // Results are undefined if min > max.
                        if (min > max)
                            UndefinedConstantFoldingError(loc, op, basicType, diagnostics,
                                                          &resultArray[i]);
                        else
                            resultArray[i].setFConst(gl::clamp(x, min, max));
                        break;
                    }

                    case EbtInt:
                    {
                        int x   = unionArrays[0][i].getIConst();
                        int min = unionArrays[1][i].getIConst();
                        int max = unionArrays[2][i].getIConst();
                        // Results are undefined if min > max.
                        if (min > max)
                            UndefinedConstantFoldingError(loc, op, basicType, diagnostics,
                                                          &resultArray[i]);
                        else
                            resultArray[i].setIConst(gl::clamp(x, min, max));
                        break;
                    }
                    case EbtUInt:
                    {
                        unsigned int x   = unionArrays[0][i].getUConst();
                        unsigned int min = unionArrays[1][i].getUConst();
                        unsigned int max = unionArrays[2][i].getUConst();
                        // Results are undefined if min > max.
                        if (min > max)
                            UndefinedConstantFoldingError(loc, op, basicType, diagnostics,
                                                          &resultArray[i]);
                        else
                            resultArray[i].setUConst(gl::clamp(x, min, max));
                        break;
                    }
                    default:
                        UNREACHABLE();
                        break;
                }
            }
            break;
        }

        case EOpMix:
        {
            ASSERT(basicType == EbtFloat);
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                float x         = unionArrays[0][i].getFConst();
                float y         = unionArrays[1][i].getFConst();
                TBasicType type = (*arguments)[2]->getAsTyped()->getType().getBasicType();
                if (type == EbtFloat)
                {
                    // Returns the linear blend of x and y, i.e., x * (1 - a) + y * a.
                    float a = unionArrays[2][i].getFConst();
                    resultArray[i].setFConst(x * (1.0f - a) + y * a);
                }
                else  // 3rd parameter is EbtBool
                {
                    ASSERT(type == EbtBool);
                    // Selects which vector each returned component comes from.
                    // For a component of a that is false, the corresponding component of x is
                    // returned.
                    // For a component of a that is true, the corresponding component of y is
                    // returned.
                    bool a = unionArrays[2][i].getBConst();
                    resultArray[i].setFConst(a ? y : x);
                }
            }
            break;
        }

        case EOpSmoothstep:
        {
            ASSERT(basicType == EbtFloat);
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                float edge0 = unionArrays[0][i].getFConst();
                float edge1 = unionArrays[1][i].getFConst();
                float x     = unionArrays[2][i].getFConst();
                // Results are undefined if edge0 >= edge1.
                if (edge0 >= edge1)
                {
                    UndefinedConstantFoldingError(loc, op, basicType, diagnostics, &resultArray[i]);
                }
                else
                {
                    // Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and performs smooth
                    // Hermite interpolation between 0 and 1 when edge0 < x < edge1.
                    float t = gl::clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
                    resultArray[i].setFConst(t * t * (3.0f - 2.0f * t));
                }
            }
            break;
        }

        case EOpLdexp:
        {
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                float x = unionArrays[0][i].getFConst();
                int exp = unionArrays[1][i].getIConst();
                if (exp > 128)
                {
                    UndefinedConstantFoldingError(loc, op, basicType, diagnostics, &resultArray[i]);
                }
                else
                {
                    resultArray[i].setFConst(gl::Ldexp(x, exp));
                }
            }
            break;
        }

        case EOpFaceforward:
        {
            ASSERT(basicType == EbtFloat);
            // genType faceforward(genType N, genType I, genType Nref) :
            //     If dot(Nref, I) < 0 return N, otherwise return -N.
            resultArray      = new TConstantUnion[maxObjectSize];
            float dotProduct = VectorDotProduct(unionArrays[2], unionArrays[1], maxObjectSize);
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                if (dotProduct < 0)
                    resultArray[i].setFConst(unionArrays[0][i].getFConst());
                else
                    resultArray[i].setFConst(-unionArrays[0][i].getFConst());
            }
            break;
        }

        case EOpRefract:
        {
            ASSERT(basicType == EbtFloat);
            // genType refract(genType I, genType N, float eta) :
            //     For the incident vector I and surface normal N, and the ratio of indices of
            //     refraction eta,
            //     return the refraction vector. The result is computed by
            //         k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I))
            //         if (k < 0.0)
            //             return genType(0.0)
            //         else
            //             return eta * I - (eta * dot(N, I) + sqrt(k)) * N
            resultArray      = new TConstantUnion[maxObjectSize];
            float dotProduct = VectorDotProduct(unionArrays[1], unionArrays[0], maxObjectSize);
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                float eta = unionArrays[2][i].getFConst();
                float k   = 1.0f - eta * eta * (1.0f - dotProduct * dotProduct);
                if (k < 0.0f)
                    resultArray[i].setFConst(0.0f);
                else
                    resultArray[i].setFConst(eta * unionArrays[0][i].getFConst() -
                                             (eta * dotProduct + sqrtf(k)) *
                                                 unionArrays[1][i].getFConst());
            }
            break;
        }
        case EOpBitfieldExtract:
        {
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; ++i)
            {
                int offset = unionArrays[1][0].getIConst();
                int bits   = unionArrays[2][0].getIConst();
                if (bits == 0)
                {
                    if (aggregate->getBasicType() == EbtInt)
                    {
                        resultArray[i].setIConst(0);
                    }
                    else
                    {
                        ASSERT(aggregate->getBasicType() == EbtUInt);
                        resultArray[i].setUConst(0);
                    }
                }
                else if (offset < 0 || bits < 0 || offset >= 32 || bits > 32 || offset + bits > 32)
                {
                    UndefinedConstantFoldingError(loc, op, aggregate->getBasicType(), diagnostics,
                                                  &resultArray[i]);
                }
                else
                {
                    // bits can be 32 here, so we need to avoid bit shift overflow.
                    uint32_t maskMsb = 1u << (bits - 1);
                    uint32_t mask    = ((maskMsb - 1u) | maskMsb) << offset;
                    if (aggregate->getBasicType() == EbtInt)
                    {
                        uint32_t value = static_cast<uint32_t>(unionArrays[0][i].getIConst());
                        uint32_t resultUnsigned = (value & mask) >> offset;
                        if ((resultUnsigned & maskMsb) != 0)
                        {
                            // The most significant bits (from bits+1 to the most significant bit)
                            // should be set to 1.
                            uint32_t higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;
                            resultUnsigned |= higherBitsMask;
                        }
                        resultArray[i].setIConst(static_cast<int32_t>(resultUnsigned));
                    }
                    else
                    {
                        ASSERT(aggregate->getBasicType() == EbtUInt);
                        uint32_t value = unionArrays[0][i].getUConst();
                        resultArray[i].setUConst((value & mask) >> offset);
                    }
                }
            }
            break;
        }
        case EOpBitfieldInsert:
        {
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; ++i)
            {
                int offset = unionArrays[2][0].getIConst();
                int bits   = unionArrays[3][0].getIConst();
                if (bits == 0)
                {
                    if (aggregate->getBasicType() == EbtInt)
                    {
                        int32_t base = unionArrays[0][i].getIConst();
                        resultArray[i].setIConst(base);
                    }
                    else
                    {
                        ASSERT(aggregate->getBasicType() == EbtUInt);
                        uint32_t base = unionArrays[0][i].getUConst();
                        resultArray[i].setUConst(base);
                    }
                }
                else if (offset < 0 || bits < 0 || offset >= 32 || bits > 32 || offset + bits > 32)
                {
                    UndefinedConstantFoldingError(loc, op, aggregate->getBasicType(), diagnostics,
                                                  &resultArray[i]);
                }
                else
                {
                    // bits can be 32 here, so we need to avoid bit shift overflow.
                    uint32_t maskMsb    = 1u << (bits - 1);
                    uint32_t insertMask = ((maskMsb - 1u) | maskMsb) << offset;
                    uint32_t baseMask   = ~insertMask;
                    if (aggregate->getBasicType() == EbtInt)
                    {
                        uint32_t base   = static_cast<uint32_t>(unionArrays[0][i].getIConst());
                        uint32_t insert = static_cast<uint32_t>(unionArrays[1][i].getIConst());
                        uint32_t resultUnsigned =
                            (base & baseMask) | ((insert << offset) & insertMask);
                        resultArray[i].setIConst(static_cast<int32_t>(resultUnsigned));
                    }
                    else
                    {
                        ASSERT(aggregate->getBasicType() == EbtUInt);
                        uint32_t base   = unionArrays[0][i].getUConst();
                        uint32_t insert = unionArrays[1][i].getUConst();
                        resultArray[i].setUConst((base & baseMask) |
                                                 ((insert << offset) & insertMask));
                    }
                }
            }
            break;
        }

        default:
            UNREACHABLE();
            return nullptr;
    }
    return resultArray;
}

// TIntermPreprocessorDirective implementation.
TIntermPreprocessorDirective::TIntermPreprocessorDirective(PreprocessorDirective directive,
                                                           ImmutableString command)
    : mDirective(directive), mCommand(std::move(command))
{}

TIntermPreprocessorDirective::~TIntermPreprocessorDirective() = default;

size_t TIntermPreprocessorDirective::getChildCount() const
{
    return 0;
}

TIntermNode *TIntermPreprocessorDirective::getChildNode(size_t index) const
{
    UNREACHABLE();
    return nullptr;
}
}  // namespace sh
