//
// Copyright 2002 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.
//

#ifdef UNSAFE_BUFFERS_BUILD
#    pragma allow_unsafe_buffers
#endif

//
// 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 "common/utilities.h"
#include "compiler/translator/Diagnostics.h"
#include "compiler/translator/ImmutableString.h"
#include "compiler/translator/ImmutableStringBuilder.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 (size_t i = 0; i < size; ++i)
        constUnion[i] = constant;

    return constUnion;
}

void UndefinedConstantFoldingError(const TSourceLoc &loc,
                                   const TFunction *function,
                                   TBasicType basicType,
                                   TDiagnostics *diagnostics,
                                   TConstantUnion *result)
{
    diagnostics->warning(loc, "operation result is undefined for the values passed in",
                         function->name().data());

    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 EOpFma:
        case EOpLdexp:
        case EOpMatrixCompMult:
        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:
        case EOpDFdx:
        case EOpDFdy:
        case EOpFwidth:
            return true;
        default:
            return false;
    }
}

void PropagatePrecisionIfApplicable(TIntermTyped *node, TPrecision precision)
{
    if (precision == EbpUndefined || node->getPrecision() != EbpUndefined)
    {
        return;
    }

    if (IsPrecisionApplicableToType(node->getBasicType()))
    {
        node->propagatePrecision(precision);
    }
}

}  // namespace

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

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

#define REPLACE_IF_IS(node, conversionFunc, original, replacement)                             \
    do                                                                                         \
    {                                                                                          \
        if (node == original)                                                                  \
        {                                                                                      \
            if (replacement == nullptr)                                                        \
            {                                                                                  \
                node = nullptr;                                                                \
            }                                                                                  \
            else                                                                               \
            {                                                                                  \
                auto replacementCasted = replacement->conversionFunc();                        \
                if (replacementCasted == nullptr)                                              \
                {                                                                              \
                    FATAL() << "Replacing a node with a node of invalid type: calling "        \
                               "replacement." #conversionFunc "() should not return nullptr."; \
                    return false;                                                              \
                }                                                                              \
                node = replacementCasted;                                                      \
            }                                                                                  \
            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) + 1;
}

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;
    }
    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, getAsNode, original, replacement);
    REPLACE_IF_IS(mCond, getAsTyped, original, replacement);
    REPLACE_IF_IS(mExpr, getAsTyped, original, replacement);
    REPLACE_IF_IS(mBody, getAsBlock, original, replacement);
    return false;
}

TIntermBranch::TIntermBranch(const TIntermBranch &node)
    : TIntermBranch(node.mFlowOp, node.mExpression ? node.mExpression->deepCopy() : nullptr)
{}

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, getAsTyped, 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, getAsTyped, 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, getAsTyped, original, replacement);
    REPLACE_IF_IS(mRight, getAsTyped, 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)
{
    // gl_ClipDistance and gl_CullDistance arrays may be replaced with an adjusted
    // array size. Allow mismatching types for the length() operation in this case.
    ASSERT(original->getAsTyped()->getType() == replacement->getAsTyped()->getType() ||
           (mOp == EOpArrayLength && (original->getAsTyped()->getQualifier() == EvqClipDistance ||
                                      original->getAsTyped()->getQualifier() == EvqCullDistance)));
    REPLACE_IF_IS(mOperand, getAsTyped, original, replacement);
    return false;
}

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

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

bool TIntermGlobalQualifierDeclaration::replaceChildNode(TIntermNode *original,
                                                         TIntermNode *replacement)
{
    REPLACE_IF_IS(mSymbol, getAsSymbolNode, 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, getAsFunctionPrototypeNode, original, replacement);
    REPLACE_IF_IS(mBody, getAsBlock, 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);
}

TIntermBlock::TIntermBlock(const TIntermBlock &node)
{
    for (TIntermNode *intermNode : node.mStatements)
    {
        mStatements.push_back(intermNode->deepCopy());
    }

    ASSERT(!node.mIsTreeRoot);
    mIsTreeRoot = false;
}

TIntermBlock::TIntermBlock(std::initializer_list<TIntermNode *> stmts)
{
    for (TIntermNode *stmt : stmts)
    {
        appendStatement(stmt);
    }
}

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);
}

void TIntermBlock::replaceAllChildren(TIntermSequence &&newStatements)
{
    mStatements = std::move(newStatements);
}

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;
}

TIntermDeclaration::TIntermDeclaration(const TVariable *var, TIntermTyped *initExpr)
{
    if (initExpr)
    {
        appendDeclarator(
            new TIntermBinary(TOperator::EOpInitialize, new TIntermSymbol(var), initExpr));
    }
    else
    {
        appendDeclarator(new TIntermSymbol(var));
    }
}

TIntermDeclaration::TIntermDeclaration(std::initializer_list<const TVariable *> declarators)
    : TIntermDeclaration()
{
    for (const TVariable *d : declarators)
    {
        appendDeclarator(new TIntermSymbol(d));
    }
}

TIntermDeclaration::TIntermDeclaration(std::initializer_list<TIntermTyped *> declarators)
    : TIntermDeclaration()
{
    for (TIntermTyped *d : declarators)
    {
        appendDeclarator(d);
    }
}

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);
}

TIntermDeclaration::TIntermDeclaration(const TIntermDeclaration &node)
{
    for (TIntermNode *intermNode : node.mDeclarators)
    {
        mDeclarators.push_back(intermNode->deepCopy());
    }
}

bool TIntermAggregateBase::replaceChildNodeInternal(TIntermNode *original, TIntermNode *replacement)
{
    for (size_t ii = 0; ii < getSequence()->size(); ++ii)
    {
        REPLACE_IF_IS((*getSequence())[ii], getAsNode, 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();
}

void TIntermSymbol::propagatePrecision(TPrecision precision)
{
    // Every declared variable should already have a precision.  Some built-ins don't have a defined
    // precision.  This is not asserted however:
    //
    // - A shader with no precision specified either globally or on a variable will fail with a
    //   compilation error later on.
    // - Transformations declaring variables without precision will be caught by AST validation.
}

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)
{
    // Every built-in function should have an 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::CreateConstructor(
    const TType &type,
    const std::initializer_list<TIntermNode *> &arguments)
{
    TIntermSequence argSequence(arguments);
    return CreateConstructor(type, &argSequence);
}

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

void TIntermAggregate::setPrecisionAndQualifier()
{
    mType.setQualifier(EvqTemporary);
    if ((!BuiltInGroup::IsBuiltIn(mOp) && !isFunctionCall()) || BuiltInGroup::IsMath(mOp))
    {
        if (areChildrenConstQualified())
        {
            mType.setQualifier(EvqConst);
        }
    }

    propagatePrecision(derivePrecision());
}

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

// Derive precision from children nodes
TPrecision TIntermAggregate::derivePrecision() const
{
    if (getBasicType() == EbtBool || getBasicType() == EbtVoid || getBasicType() == EbtStruct)
    {
        return EbpUndefined;
    }

    // For AST function calls, take the qualifier from the declared one.
    if (isFunctionCall())
    {
        return mType.getPrecision();
    }

    // Some built-ins explicitly specify their precision.
    switch (mOp)
    {
        case EOpBitfieldExtract:
            return mArguments[0]->getAsTyped()->getPrecision();
        case EOpBitfieldInsert:
            return GetHigherPrecision(mArguments[0]->getAsTyped()->getPrecision(),
                                      mArguments[1]->getAsTyped()->getPrecision());
        case EOpTextureSize:
        case EOpImageSize:
        case EOpUaddCarry:
        case EOpUsubBorrow:
        case EOpUmulExtended:
        case EOpImulExtended:
        case EOpFrexp:
        case EOpLdexp:
            return EbpHigh;
        default:
            break;
    }

    // The rest of the math operations and constructors get their precision from their arguments.
    if (BuiltInGroup::IsMath(mOp) || mOp == EOpConstruct)
    {
        TPrecision precision = EbpUndefined;
        for (TIntermNode *argument : mArguments)
        {
            precision = GetHigherPrecision(argument->getAsTyped()->getPrecision(), precision);
        }
        return precision;
    }

    // Atomic operations return highp.
    if (BuiltInGroup::IsImageAtomic(mOp) || BuiltInGroup::IsAtomicCounter(mOp) ||
        BuiltInGroup::IsAtomicMemory(mOp))
    {
        return EbpHigh;
    }

    // Texture functions return the same precision as that of the sampler (textureSize returns
    // highp, but that's handled above).  imageLoad similar takes the precision of the image.  The
    // same is true for dFd*, interpolateAt* and subpassLoad operations.
    if (BuiltInGroup::IsTexture(mOp) || BuiltInGroup::IsImageLoad(mOp) ||
        BuiltInGroup::IsDerivativesFS(mOp) || BuiltInGroup::IsInterpolationFS(mOp) ||
        mOp == EOpSubpassLoad || mOp == EOpInterpolateAtCenter)
    {
        return mArguments[0]->getAsTyped()->getPrecision();
    }

    // Every possibility must be explicitly handled.
    return EbpUndefined;
}

// Propagate precision to children nodes that don't already have it defined.
void TIntermAggregate::propagatePrecision(TPrecision precision)
{
    mType.setPrecision(precision);

    // For constructors, propagate precision to arguments.
    if (isConstructor())
    {
        for (TIntermNode *arg : mArguments)
        {
            PropagatePrecisionIfApplicable(arg->getAsTyped(), precision);
        }
        return;
    }

    // For function calls, propagate precision of each parameter to its corresponding argument.
    if (isFunctionCall())
    {
        for (size_t paramIndex = 0; paramIndex < mFunction->getParamCount(); ++paramIndex)
        {
            const TVariable *paramVariable = mFunction->getParam(paramIndex);
            PropagatePrecisionIfApplicable(mArguments[paramIndex]->getAsTyped(),
                                           paramVariable->getType().getPrecision());
        }
        return;
    }

    // Some built-ins explicitly specify the precision of their parameters.
    switch (mOp)
    {
        case EOpUaddCarry:
        case EOpUsubBorrow:
        case EOpUmulExtended:
        case EOpImulExtended:
            PropagatePrecisionIfApplicable(mArguments[0]->getAsTyped(), EbpHigh);
            PropagatePrecisionIfApplicable(mArguments[1]->getAsTyped(), EbpHigh);
            break;
        case EOpFindMSB:
        case EOpFrexp:
        case EOpLdexp:
            PropagatePrecisionIfApplicable(mArguments[0]->getAsTyped(), EbpHigh);
            break;
        default:
            break;
    }
}

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

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

bool TIntermAggregate::isConstantNullValue() const
{
    if (!isConstructor())
    {
        return false;
    }
    for (TIntermNode *constructorArg : mArguments)
    {
        if (!constructorArg->getAsTyped()->isConstantNullValue())
        {
            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())
            {
                const uint8_t resultCols = getType().getCols();
                const uint8_t resultRows = getType().getRows();
                for (uint8_t col = 0; col < resultCols; ++col)
                {
                    for (uint8_t 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.
            const uint8_t argumentCols = argumentTyped->getType().getCols();
            const uint8_t argumentRows = argumentTyped->getType().getRows();
            const uint8_t resultCols   = getType().getCols();
            const uint8_t resultRows   = getType().getRows();
            for (uint8_t col = 0; col < resultCols; ++col)
            {
                for (uint8_t 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;
    }

    // If the function itself is known to have a side effect, the expression has a side effect.
    const bool calledFunctionHasSideEffects =
        mFunction != nullptr && !mFunction->isKnownToNotHaveSideEffects();

    if (calledFunctionHasSideEffects)
    {
        return true;
    }

    // Otherwise it only has a side effect if one of the arguments does.
    for (TIntermNode *arg : mArguments)
    {
        if (arg->getAsTyped()->hasSideEffects())
        {
            return true;
        }
    }
    return false;
}

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, getAsTyped, original, replacement);
    REPLACE_IF_IS(mTrueExpression, getAsTyped, original, replacement);
    REPLACE_IF_IS(mFalseExpression, getAsTyped, 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, getAsTyped, original, replacement);
    REPLACE_IF_IS(mTrueBlock, getAsBlock, original, replacement);
    REPLACE_IF_IS(mFalseBlock, getAsBlock, 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, getAsTyped, original, replacement);
    REPLACE_IF_IS(mStatementList, getAsBlock, original, replacement);
    ASSERT(mStatementList);
    return false;
}

TIntermCase::TIntermCase(const TIntermCase &node) : TIntermCase(node.mCondition->deepCopy()) {}

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, getAsTyped, original, replacement);
    return false;
}

TIntermTyped::TIntermTyped() : mIsPrecise(false) {}
TIntermTyped::TIntermTyped(const TIntermTyped &node) : TIntermTyped()
{
    // 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;

    // Once deteremined, the tree is not expected to transform.
    ASSERT(!mIsPrecise);
}

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

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

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

TPrecision TIntermTyped::derivePrecision() const
{
    UNREACHABLE();
    return EbpUndefined;
}

void TIntermTyped::propagatePrecision(TPrecision precision)
{
    UNREACHABLE();
}

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),
      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;
    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)
{
    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 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, EbpHigh, EvqConst));
        return;
    }

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

    TType resultType = mOperand->getType();
    resultType.setQualifier(resultQualifier);

    // Result is an intermediate value, so make sure it's identified as such.
    resultType.setInterfaceBlock(nullptr);

    // Override type properties for special built-ins.  Precision is determined later by
    // |derivePrecision|.
    switch (mOp)
    {
        case EOpFloatBitsToInt:
            resultType.setBasicType(EbtInt);
            break;
        case EOpFloatBitsToUint:
            resultType.setBasicType(EbtUInt);
            break;
        case EOpIntBitsToFloat:
        case EOpUintBitsToFloat:
            resultType.setBasicType(EbtFloat);
            break;
        case EOpPackSnorm2x16:
        case EOpPackUnorm2x16:
        case EOpPackHalf2x16:
        case EOpPackUnorm4x8:
        case EOpPackSnorm4x8:
            resultType.setBasicType(EbtUInt);
            resultType.setPrimarySize(1);
            break;
        case EOpUnpackSnorm2x16:
        case EOpUnpackUnorm2x16:
        case EOpUnpackHalf2x16:
            resultType.setBasicType(EbtFloat);
            resultType.setPrimarySize(2);
            break;
        case EOpUnpackUnorm4x8:
        case EOpUnpackSnorm4x8:
            resultType.setBasicType(EbtFloat);
            resultType.setPrimarySize(4);
            break;
        case EOpAny:
        case EOpAll:
            resultType.setBasicType(EbtBool);
            resultType.setPrimarySize(1);
            break;
        case EOpLength:
        case EOpDeterminant:
            resultType.setBasicType(EbtFloat);
            resultType.setPrimarySize(1);
            resultType.setSecondarySize(1);
            break;
        case EOpTranspose:
            ASSERT(resultType.getBasicType() == EbtFloat);
            resultType.setPrimarySize(mOperand->getType().getRows());
            resultType.setSecondarySize(mOperand->getType().getCols());
            break;
        case EOpIsinf:
        case EOpIsnan:
            resultType.setBasicType(EbtBool);
            break;
        case EOpBitCount:
        case EOpFindLSB:
        case EOpFindMSB:
            resultType.setBasicType(EbtInt);
            break;
        default:
            break;
    }

    setType(resultType);
    propagatePrecision(derivePrecision());
}

// Derive precision from children nodes
TPrecision TIntermUnary::derivePrecision() const
{
    // Unary operators generally derive their precision from their operand, except for a few
    // built-ins where this is overridden.
    switch (mOp)
    {
        case EOpArrayLength:
        case EOpFloatBitsToInt:
        case EOpFloatBitsToUint:
        case EOpIntBitsToFloat:
        case EOpUintBitsToFloat:
        case EOpPackSnorm2x16:
        case EOpPackUnorm2x16:
        case EOpPackHalf2x16:
        case EOpPackUnorm4x8:
        case EOpPackSnorm4x8:
        case EOpUnpackSnorm2x16:
        case EOpUnpackUnorm2x16:
        case EOpBitfieldReverse:
            return EbpHigh;
        case EOpUnpackHalf2x16:
        case EOpUnpackUnorm4x8:
        case EOpUnpackSnorm4x8:
            return EbpMedium;
        case EOpBitCount:
        case EOpFindLSB:
        case EOpFindMSB:
            return EbpLow;
        case EOpAny:
        case EOpAll:
        case EOpIsinf:
        case EOpIsnan:
            return EbpUndefined;
        default:
            return mOperand->getPrecision();
    }
}

void TIntermUnary::propagatePrecision(TPrecision precision)
{
    mType.setPrecision(precision);

    // Generally precision of the operand and the precision of the result match.  A few built-ins
    // are exceptional.
    switch (mOp)
    {
        case EOpArrayLength:
        case EOpPackSnorm2x16:
        case EOpPackUnorm2x16:
        case EOpPackUnorm4x8:
        case EOpPackSnorm4x8:
        case EOpPackHalf2x16:
        case EOpBitCount:
        case EOpFindLSB:
        case EOpFindMSB:
        case EOpIsinf:
        case EOpIsnan:
            // Precision of result does not affect the operand in any way.
            break;
        case EOpFloatBitsToInt:
        case EOpFloatBitsToUint:
        case EOpIntBitsToFloat:
        case EOpUintBitsToFloat:
        case EOpUnpackSnorm2x16:
        case EOpUnpackUnorm2x16:
        case EOpUnpackUnorm4x8:
        case EOpUnpackSnorm4x8:
        case EOpUnpackHalf2x16:
        case EOpBitfieldReverse:
            PropagatePrecisionIfApplicable(mOperand, EbpHigh);
            break;
        default:
            PropagatePrecisionIfApplicable(mOperand, precision);
    }
}

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

TIntermUnary::TIntermUnary(TOperator op, TIntermTyped *operand, const TFunction *function)
    : TIntermOperator(op), mOperand(operand), mUseEmulatedFunction(false), mFunction(function)
{
    ASSERT(mOperand);
    ASSERT(!BuiltInGroup::IsBuiltIn(op) || (function != nullptr && function->getBuiltInOp() == op));
    promote();
}

TIntermBinary::TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right)
    : TIntermOperator(op), mLeft(left), mRight(right)
{
    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;
}

TIntermGlobalQualifierDeclaration::TIntermGlobalQualifierDeclaration(TIntermSymbol *symbol,
                                                                     bool isPrecise,
                                                                     const TSourceLoc &line)
    : TIntermNode(), mSymbol(symbol), mIsPrecise(isPrecise)
{
    ASSERT(symbol);
    setLine(line);
}

TIntermGlobalQualifierDeclaration::TIntermGlobalQualifierDeclaration(
    const TIntermGlobalQualifierDeclaration &node)
    : TIntermGlobalQualifierDeclaration(static_cast<TIntermSymbol *>(node.mSymbol->deepCopy()),
                                        node.mIsPrecise,
                                        node.mLine)
{}

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));

    propagatePrecision(derivePrecision());
}

TIntermLoop::TIntermLoop(TLoopType type,
                         TIntermNode *init,
                         TIntermTyped *cond,
                         TIntermTyped *expr,
                         TIntermBlock *body)
    : mType(type), mInit(init), mCond(cond), mExpr(expr), mBody(EnsureBody(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;
    }
}

TIntermLoop::TIntermLoop(const TIntermLoop &node)
    : TIntermLoop(node.mType,
                  node.mInit ? node.mInit->deepCopy() : nullptr,
                  node.mCond ? node.mCond->deepCopy() : nullptr,
                  node.mExpr ? node.mExpr->deepCopy() : nullptr,
                  node.mBody->deepCopy())
{}

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;
    }
}

TIntermIfElse::TIntermIfElse(const TIntermIfElse &node)
    : TIntermIfElse(node.mCondition->deepCopy(),
                    node.mTrueBlock->deepCopy(),
                    node.mFalseBlock ? node.mFalseBlock->deepCopy() : nullptr)
{}

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

TIntermSwitch::TIntermSwitch(const TIntermSwitch &node)
    : TIntermSwitch(node.mInit->deepCopy(), node.mStatementList->deepCopy())
{}

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;
}

// Derive precision from children nodes
TPrecision TIntermTernary::derivePrecision() const
{
    return GetHigherPrecision(mTrueExpression->getPrecision(), mFalseExpression->getPrecision());
}

void TIntermTernary::propagatePrecision(TPrecision precision)
{
    mType.setPrecision(precision);

    PropagatePrecisionIfApplicable(mTrueExpression, precision);
    PropagatePrecisionIfApplicable(mFalseExpression, precision);
}

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;

    size_t numFields = mSwizzleOffsets.size();
    setType(TType(mOperand->getBasicType(), EbpUndefined, resultQualifier,
                  static_cast<uint8_t>(numFields)));
    propagatePrecision(derivePrecision());
}

// Derive precision from children nodes
TPrecision TIntermSwizzle::derivePrecision() const
{
    return mOperand->getPrecision();
}

void TIntermSwizzle::propagatePrecision(TPrecision precision)
{
    mType.setPrecision(precision);

    PropagatePrecisionIfApplicable(mOperand, precision);
}

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

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

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

ImmutableString TIntermSwizzle::getOffsetsAsXYZW() const
{
    ImmutableStringBuilder offsets(mSwizzleOffsets.size());
    for (const uint32_t offset : mSwizzleOffsets)
    {
        switch (offset)
        {
            case 0:
                offsets << "x";
                break;
            case 1:
                offsets << "y";
                break;
            case 2:
                offsets << "z";
                break;
            case 3:
                offsets << "w";
                break;
            default:
                UNREACHABLE();
        }
    }
    return offsets;
}

void TIntermSwizzle::writeOffsetsAsXYZW(TInfoSinkBase *out) const
{
    *out << getOffsetsAsXYZW();
}

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 initializing a specialization constant, make the declarator also
    // EvqSpecConst.
    const bool isSpecConstInit = mOp == EOpInitialize && mLeft->getQualifier() == EvqSpecConst;
    const bool isEitherNonConst =
        mLeft->getQualifier() != EvqConst || mRight->getQualifier() != EvqConst;
    if (!isSpecConstInit && isEitherNonConst)
    {
        resultQualifier = EvqTemporary;
        getTypePointer()->setQualifier(EvqTemporary);
    }

    // Result is an intermediate value, so make sure it's identified as such.  That's not true for
    // interface block arrays being indexed.
    if (mOp != EOpIndexDirect && mOp != EOpIndexIndirect)
    {
        getTypePointer()->setInterfaceBlock(nullptr);
    }

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

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

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

    switch (mOp)
    {
        case EOpMul:
            break;
        case EOpMatrixTimesScalar:
            if (mRight->isMatrix())
            {
                getTypePointer()->setPrimarySize(mRight->getCols());
                getTypePointer()->setSecondarySize(mRight->getRows());
            }
            break;
        case EOpMatrixTimesVector:
            getTypePointer()->setPrimarySize(mLeft->getRows());
            getTypePointer()->setSecondarySize(1);
            break;
        case EOpMatrixTimesMatrix:
            getTypePointer()->setPrimarySize(mRight->getCols());
            getTypePointer()->setSecondarySize(mLeft->getRows());
            break;
        case EOpVectorTimesScalar:
            getTypePointer()->setPrimarySize(nominalSize);
            break;
        case EOpVectorTimesMatrix:
            getTypePointer()->setPrimarySize(mRight->getCols());
            ASSERT(getType().getSecondarySize() == 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:
        {
            ASSERT(!mLeft->isArray() && !mRight->isArray());
            const uint8_t secondarySize =
                std::max(mLeft->getSecondarySize(), mRight->getSecondarySize());
            getTypePointer()->setPrimarySize(nominalSize);
            getTypePointer()->setSecondarySize(secondarySize);
            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;

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

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

    propagatePrecision(derivePrecision());
}

// Derive precision from children nodes
TPrecision TIntermBinary::derivePrecision() const
{
    // Assignments use the type and precision of the lvalue-expression
    // GLSL ES spec section 5.8: Assignments
    // "The assignment operator stores the value of rvalue-expression into the l-value and returns
    // an r-value with the type and precision of lvalue-expression."
    if (IsAssignment(mOp))
    {
        return mLeft->getPrecision();
    }

    const TPrecision higherPrecision =
        GetHigherPrecision(mLeft->getPrecision(), mRight->getPrecision());

    switch (mOp)
    {
        case EOpComma:
            // Comma takes the right node's value.
            return mRight->getPrecision();

        case EOpIndexDirect:
        case EOpIndexIndirect:
        case EOpBitShiftLeft:
        case EOpBitShiftRight:
            // When indexing an array, the precision of the array is preserved (which is the left
            // node).
            // For shift operations, the precision is derived from the expression being shifted
            // (which is also the left node).
            return mLeft->getPrecision();

        case EOpIndexDirectStruct:
        case EOpIndexDirectInterfaceBlock:
        {
            // When selecting the field of a block, the precision is taken from the field's
            // declaration.
            const TFieldList &fields = mOp == EOpIndexDirectStruct
                                           ? mLeft->getType().getStruct()->fields()
                                           : mLeft->getType().getInterfaceBlock()->fields();
            const int fieldIndex     = mRight->getAsConstantUnion()->getIConst(0);
            return fields[fieldIndex]->type()->getPrecision();
        }

        case EOpEqual:
        case EOpNotEqual:
        case EOpLessThan:
        case EOpGreaterThan:
        case EOpLessThanEqual:
        case EOpGreaterThanEqual:
        case EOpLogicalAnd:
        case EOpLogicalXor:
        case EOpLogicalOr:
            // No precision specified on bool results.
            return EbpUndefined;

        default:
            // All other operations are evaluated at the higher of the two operands' precisions.
            return higherPrecision;
    }
}

void TIntermBinary::propagatePrecision(TPrecision precision)
{
    getTypePointer()->setPrecision(precision);

    if (mOp != EOpComma)
    {
        PropagatePrecisionIfApplicable(mLeft, precision);
    }

    if (mOp != EOpIndexDirect && mOp != EOpIndexIndirect && mOp != EOpIndexDirectStruct &&
        mOp != EOpIndexDirectInterfaceBlock)
    {
        PropagatePrecisionIfApplicable(mRight, precision);
    }

    // For indices, always apply highp.  This is purely for the purpose of making sure constant and
    // constructor nodes are also given a precision, so if they are hoisted to a temp variable,
    // there would be a precision to apply to that variable.
    if (mOp == EOpIndexDirect || mOp == EOpIndexIndirect)
    {
        PropagatePrecisionIfApplicable(mRight, EbpHigh);
    }
}

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

bool TIntermConstantUnion::isConstantNullValue() const
{
    const size_t size = mType.getObjectSize();
    for (size_t index = 0; index < size; ++index)
    {
        if (!mUnionArrayPointer[index].isZero())
        {
            return false;
        }
    }
    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());
        const uint8_t 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<uint32_t> foldedOffsets;
        for (uint32_t offset : mSwizzleOffsets)
        {
            // Offset should already be validated.
            ASSERT(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 CreateFoldedNode(constantValue, this);
                }
            }

            // If the indexed value is a swizzle, then the swizzle can be adjusted instead.
            TIntermSwizzle *leftSwizzle = mLeft->getAsSwizzleNode();
            if (leftSwizzle != nullptr)
            {
                const TVector<uint32_t> &swizzleOffsets = leftSwizzle->getSwizzleOffsets();
                ASSERT(index < swizzleOffsets.size());

                uint32_t remappedIndex = swizzleOffsets[index];
                return new TIntermSwizzle(leftSwizzle->getOperand(), {remappedIndex});
            }

            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.
        // This operation is folded for clip/cull distance arrays in RemoveArrayLengthMethod.
        if (mOperand->hasSideEffects() || mOperand->getType().isUnsizedArray() ||
            mOperand->getQualifier() == EvqClipDistance ||
            mOperand->getQualifier() == EvqCullDistance)
        {
            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, mFunction, 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 uint8_t leftCols   = leftType.getCols();
            const uint8_t leftRows   = leftType.getRows();
            const uint8_t rightCols  = rightType.getCols();
            const uint8_t rightRows  = rightType.getRows();
            const uint8_t resultCols = rightCols;
            const uint8_t resultRows = leftRows;

            resultArray = new TConstantUnion[resultCols * resultRows];
            for (uint8_t row = 0; row < resultRows; row++)
            {
                for (uint8_t column = 0; column < resultCols; column++)
                {
                    resultArray[resultRows * column + row].setFConst(0.0f);
                    for (uint8_t 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++)
            {
                if (leftType.getBasicType() == EbtFloat)
                {
                    // Float division requested, possibly with implicit conversion
                    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);
                    }
                }
                else
                {
                    // Types are either both int or both uint
                    switch (leftType.getBasicType())
                    {
                        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 uint8_t matrixCols = leftType.getCols();
            const uint8_t matrixRows = leftType.getRows();

            resultArray = new TConstantUnion[matrixRows];

            for (uint8_t matrixRow = 0; matrixRow < matrixRows; matrixRow++)
            {
                resultArray[matrixRow].setFConst(0.0f);
                for (uint8_t 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 uint8_t matrixCols = rightType.getCols();
            const uint8_t matrixRows = rightType.getRows();

            resultArray = new TConstantUnion[matrixCols];

            for (uint8_t matrixCol = 0; matrixCol < matrixCols; matrixCol++)
            {
                resultArray[matrixCol].setFConst(0.0f);
                for (uint8_t 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);
            const uint8_t size = getType().getNominalSize();
            ASSERT(size >= 2 && size <= 4);
            resultArray = new TConstantUnion();
            resultArray->setFConst(GetMatrix(operandArray, size).determinant());
            break;
        }

        case EOpInverse:
        {
            ASSERT(getType().getBasicType() == EbtFloat);
            const uint8_t 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,
                                                             const TFunction *function,
                                                             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(), function, 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(), function, 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(), function, 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(), function, 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[i].getFConst()));
                break;

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

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

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

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

            case EOpUintBitsToFloat:
                ASSERT(getType().getBasicType() == EbtUInt);
                resultArray[i].setFConst(gl::bitCast<float>(operandArray[i].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(), function, 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(), function, 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(), function, 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(), function, getType().getBasicType(),
                                                  diagnostics, &resultArray[i]);
                else
                {
                    foldFloatTypeUnary(operandArray[i], &sqrtf, &resultArray[i]);
                    resultArray[i].setFConst(1.0f / resultArray[i].getFConst());
                }
                break;

            case EOpNotComponentWise:
                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 != 0.0f)
                    resultArray[i].setFConst(x / length);
                else
                    UndefinedConstantFoldingError(getLine(), function, 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;
            }

            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()));
}

void TIntermConstantUnion::propagatePrecision(TPrecision precision)
{
    mType.setPrecision(precision);
}

// static
TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *aggregate,
                                                           TDiagnostics *diagnostics)
{
    const TOperator op         = aggregate->getOp();
    const TFunction *function  = aggregate->getFunction();
    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, function, 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, function, basicType, diagnostics,
                                                  &resultArray[i]);
                else if (x == 0.0f && y <= 0.0f)
                    UndefinedConstantFoldingError(loc, function, 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 EOpMatrixCompMult:
        {
            ASSERT(basicType == EbtFloat && (*arguments)[0]->getAsTyped()->isMatrix() &&
                   (*arguments)[1]->getAsTyped()->isMatrix());
            // Perform component-wise matrix multiplication.
            resultArray                 = new TConstantUnion[maxObjectSize];
            const uint8_t rows          = (*arguments)[0]->getAsTyped()->getRows();
            const uint8_t 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, function, 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, function, 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, function, basicType, diagnostics,
                                                          &resultArray[i]);
                        else
                            resultArray[i].setUConst(gl::clamp(x, min, max));
                        break;
                    }
                    default:
                        UNREACHABLE();
                        break;
                }
            }
            break;
        }

        case EOpMix:
        {
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                TBasicType type = (*arguments)[2]->getAsTyped()->getType().getBasicType();
                if (type == EbtFloat)
                {
                    ASSERT(basicType == EbtFloat);
                    float x = unionArrays[0][i].getFConst();
                    float y = unionArrays[1][i].getFConst();

                    // 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();
                    switch (basicType)
                    {
                        case EbtFloat:
                        {
                            float x = unionArrays[0][i].getFConst();
                            float y = unionArrays[1][i].getFConst();
                            resultArray[i].setFConst(a ? y : x);
                        }
                        break;
                        case EbtInt:
                        {
                            int x = unionArrays[0][i].getIConst();
                            int y = unionArrays[1][i].getIConst();
                            resultArray[i].setIConst(a ? y : x);
                        }
                        break;
                        case EbtUInt:
                        {
                            unsigned int x = unionArrays[0][i].getUConst();
                            unsigned int y = unionArrays[1][i].getUConst();
                            resultArray[i].setUConst(a ? y : x);
                        }
                        break;
                        case EbtBool:
                        {
                            bool x = unionArrays[0][i].getBConst();
                            bool y = unionArrays[1][i].getBConst();
                            resultArray[i].setBConst(a ? y : x);
                        }
                        break;
                        default:
                            UNREACHABLE();
                            break;
                    }
                }
            }
            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, function, 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 EOpFma:
        {
            ASSERT(basicType == EbtFloat);
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                float a = unionArrays[0][i].getFConst();
                float b = unionArrays[1][i].getFConst();
                float c = unionArrays[2][i].getFConst();

                // Returns a * b + c.
                resultArray[i].setFConst(a * b + c);
            }
            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, function, 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, function, 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, function, 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;
        }
        case EOpDFdx:
        case EOpDFdy:
        case EOpFwidth:
            ASSERT(basicType == EbtFloat);
            resultArray = new TConstantUnion[maxObjectSize];
            for (size_t i = 0; i < maxObjectSize; i++)
            {
                // Derivatives of constant arguments should be 0.
                resultArray[i].setFConst(0.0f);
            }
            break;

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

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

TIntermPreprocessorDirective::TIntermPreprocessorDirective(const TIntermPreprocessorDirective &node)
    : TIntermPreprocessorDirective(node.mDirective, node.mCommand)
{}

TIntermPreprocessorDirective::~TIntermPreprocessorDirective() = default;

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

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