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

//
// Build the intermediate representation.
//

#include <float.h>
#include <limits.h>
#include <algorithm>

#include "localintermediate.h"
#include "SymbolTable.h"

bool CompareStructure(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray);

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

static bool ValidateMultiplication(TOperator op, const TType &left, const TType &right)
{
	switch(op)
	{
	case EOpMul:
	case EOpMulAssign:
		return left.getNominalSize() == right.getNominalSize() &&
		       left.getSecondarySize() == right.getSecondarySize();
	case EOpVectorTimesScalar:
	case EOpVectorTimesScalarAssign:
		return true;
	case EOpVectorTimesMatrix:
		return left.getNominalSize() == right.getSecondarySize();
	case EOpVectorTimesMatrixAssign:
		return left.getNominalSize() == right.getSecondarySize() &&
		       left.getNominalSize() == right.getNominalSize();
	case EOpMatrixTimesVector:
		return left.getNominalSize() == right.getNominalSize();
	case EOpMatrixTimesScalar:
	case EOpMatrixTimesScalarAssign:
		return true;
	case EOpMatrixTimesMatrix:
		return left.getNominalSize() == right.getSecondarySize();
	case EOpMatrixTimesMatrixAssign:
		return left.getNominalSize() == right.getNominalSize() &&
		       left.getSecondarySize() == right.getSecondarySize();
	default:
		UNREACHABLE();
		return false;
	}
}

const char* getOperatorString(TOperator op) {
    switch (op) {
      case EOpInitialize: return "=";
      case EOpAssign: return "=";
      case EOpAddAssign: return "+=";
      case EOpSubAssign: return "-=";
      case EOpDivAssign: return "/=";
      case EOpIModAssign: return "%=";
      case EOpBitShiftLeftAssign: return "<<=";
      case EOpBitShiftRightAssign: return ">>=";
      case EOpBitwiseAndAssign: return "&=";
      case EOpBitwiseXorAssign: return "^=";
      case EOpBitwiseOrAssign: return "|=";

      // Fall-through.
      case EOpMulAssign:
      case EOpVectorTimesMatrixAssign:
      case EOpVectorTimesScalarAssign:
      case EOpMatrixTimesScalarAssign:
      case EOpMatrixTimesMatrixAssign: return "*=";

      // Fall-through.
      case EOpIndexDirect:
      case EOpIndexIndirect: return "[]";

      case EOpIndexDirectStruct: return ".";
      case EOpVectorSwizzle: return ".";
      case EOpAdd: return "+";
      case EOpSub: return "-";
      case EOpMul: return "*";
      case EOpDiv: return "/";
      case EOpMod: UNIMPLEMENTED(); break;
      case EOpEqual: return "==";
      case EOpNotEqual: return "!=";
      case EOpLessThan: return "<";
      case EOpGreaterThan: return ">";
      case EOpLessThanEqual: return "<=";
      case EOpGreaterThanEqual: return ">=";

      // Fall-through.
      case EOpVectorTimesScalar:
      case EOpVectorTimesMatrix:
      case EOpMatrixTimesVector:
      case EOpMatrixTimesScalar:
      case EOpMatrixTimesMatrix: return "*";

      case EOpLogicalOr: return "||";
      case EOpLogicalXor: return "^^";
      case EOpLogicalAnd: return "&&";
      case EOpIMod: return "%";
      case EOpBitShiftLeft: return "<<";
      case EOpBitShiftRight: return ">>";
      case EOpBitwiseAnd: return "&";
      case EOpBitwiseXor: return "^";
      case EOpBitwiseOr: return "|";
      case EOpNegative: return "-";
      case EOpVectorLogicalNot: return "not";
      case EOpLogicalNot: return "!";
      case EOpBitwiseNot: return "~";
      case EOpPostIncrement: return "++";
      case EOpPostDecrement: return "--";
      case EOpPreIncrement: return "++";
      case EOpPreDecrement: return "--";

      case EOpRadians: return "radians";
      case EOpDegrees: return "degrees";
      case EOpSin: return "sin";
      case EOpCos: return "cos";
      case EOpTan: return "tan";
      case EOpAsin: return "asin";
      case EOpAcos: return "acos";
      case EOpAtan: return "atan";
      case EOpSinh: return "sinh";
      case EOpCosh: return "cosh";
      case EOpTanh: return "tanh";
      case EOpAsinh: return "asinh";
      case EOpAcosh: return "acosh";
      case EOpAtanh: return "atanh";
      case EOpExp: return "exp";
      case EOpLog: return "log";
      case EOpExp2: return "exp2";
      case EOpLog2: return "log2";
      case EOpSqrt: return "sqrt";
      case EOpInverseSqrt: return "inversesqrt";
      case EOpAbs: return "abs";
      case EOpSign: return "sign";
      case EOpFloor: return "floor";
      case EOpTrunc: return "trunc";
      case EOpRound: return "round";
      case EOpRoundEven: return "roundEven";
      case EOpCeil: return "ceil";
      case EOpFract: return "fract";
      case EOpLength: return "length";
      case EOpNormalize: return "normalize";
      case EOpDFdx: return "dFdx";
      case EOpDFdy: return "dFdy";
      case EOpFwidth: return "fwidth";
      case EOpAny: return "any";
      case EOpAll: return "all";
      case EOpIsNan: return "isnan";
      case EOpIsInf: return "isinf";
      case EOpOuterProduct: return "outerProduct";
      case EOpTranspose: return "transpose";
      case EOpDeterminant: return "determinant";
      case EOpInverse: return "inverse";

      default: break;
    }
    return "";
}

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

//
// Add a terminal node for an identifier in an expression.
//
// Returns the added node.
//
TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, TSourceLoc line)
{
    TIntermSymbol* node = new TIntermSymbol(id, name, type);
    node->setLine(line);

    return node;
}

//
// Connect two nodes with a new parent that does a binary operation on the nodes.
//
// Returns the added node.
//
TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
{
    switch (op) {
        case EOpEqual:
        case EOpNotEqual:
            if (left->isArray())
                return 0;
            break;
        case EOpLessThan:
        case EOpGreaterThan:
        case EOpLessThanEqual:
        case EOpGreaterThanEqual:
            if (left->isMatrix() || left->isArray() || left->isVector() || left->getBasicType() == EbtStruct) {
                return 0;
            }
            break;
        case EOpLogicalOr:
        case EOpLogicalXor:
        case EOpLogicalAnd:
            if (left->getBasicType() != EbtBool || left->isMatrix() || left->isArray() || left->isVector()) {
                return 0;
            }
            break;
        case EOpBitwiseOr:
        case EOpBitwiseXor:
        case EOpBitwiseAnd:
            if (!IsInteger(left->getBasicType()) || left->isMatrix() || left->isArray()) {
                return 0;
            }
            break;
        case EOpAdd:
        case EOpSub:
        case EOpDiv:
        case EOpMul:
            if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool) {
                return 0;
            }
            break;
        case EOpIMod:
            // Note that this is only for the % operator, not for mod()
            if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat) {
                return 0;
            }
            break;
        default: break;
    }

    if (left->getBasicType() != right->getBasicType())
    {
        return 0;
    }

    //
    // Need a new node holding things together then.  Make
    // one and promote it to the right type.
    //
    TIntermBinary* node = new TIntermBinary(op);
    if (line == 0)
        line = right->getLine();
    node->setLine(line);

    node->setLeft(left);
    node->setRight(right);
    if (!node->promote(infoSink))
        return 0;

    //
    // See if we can fold constants.
    //
    TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
    TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
    if (leftTempConstant && rightTempConstant) {
        TIntermTyped *typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink);

        if (typedReturnNode)
            return typedReturnNode;
    }

    return node;
}

//
// Connect two nodes through an assignment.
//
// Returns the added node.
//
TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
{
    if (left->getType().getStruct() || right->getType().getStruct())
    {
        if (left->getType() != right->getType())
        {
            return 0;
        }
    }

    TIntermBinary* node = new TIntermBinary(op);
    if(line == 0)
        line = left->getLine();
    node->setLine(line);

    node->setLeft(left);
    node->setRight(right);
    if (! node->promote(infoSink))
        return 0;

    return node;
}

//
// Connect two nodes through an index operator, where the left node is the base
// of an array or struct, and the right node is a direct or indirect offset.
//
// Returns the added node.
// The caller should set the type of the returned node.
//
TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc line)
{
    TIntermBinary* node = new TIntermBinary(op);
    if (line == 0)
        line = index->getLine();
    node->setLine(line);
    node->setLeft(base);
    node->setRight(index);

    // caller should set the type

    return node;
}

//
// Add one node as the parent of another that it operates on.
//
// Returns the added node.
//
TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc line)
{
    TIntermUnary* node;
    TIntermTyped* child = childNode->getAsTyped();

    if (child == 0) {
        infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line);
        return 0;
    }

    switch (op) {
        case EOpBitwiseNot:
            if (!IsInteger(child->getType().getBasicType()) || child->getType().isMatrix() || child->getType().isArray()) {
                return 0;
            }
            break;

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

        case EOpPostIncrement:
        case EOpPreIncrement:
        case EOpPostDecrement:
        case EOpPreDecrement:
        case EOpNegative:
            if (child->getType().getBasicType() == EbtStruct || child->getType().isArray())
                return 0;
        default: break;
    }

    TIntermConstantUnion *childTempConstant = 0;
    if (child->getAsConstantUnion())
        childTempConstant = child->getAsConstantUnion();

    //
    // Make a new node for the operator.
    //
    node = new TIntermUnary(op);
    if (line == 0)
        line = child->getLine();
    node->setLine(line);
    node->setOperand(child);

    if (! node->promote(infoSink))
        return 0;

    if (childTempConstant)  {
        TIntermTyped* newChild = childTempConstant->fold(op, 0, infoSink);

        if (newChild)
            return newChild;
    }

    return node;
}

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

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

    //
    // Set the operator.
    //
    aggNode->setOp(op);
    if (line != 0)
        aggNode->setLine(line);

    return aggNode;
}

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

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

    if (right)
        aggNode->getSequence().push_back(right);

    if (line != 0)
        aggNode->setLine(line);

    return aggNode;
}

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

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

    if (line != 0)
        aggNode->setLine(line);
    else
        aggNode->setLine(node->getLine());

    return aggNode;
}

//
// For "if" test nodes.  There are three children; a condition,
// a true path, and a false path.  The two paths are in the
// nodePair.
//
// Returns the selection node created.
//
TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, TSourceLoc line)
{
    //
    // For compile time constant selections, prune the code and
    // test now.
    //

    if (cond->getAsTyped() && cond->getAsTyped()->getAsConstantUnion()) {
        if (cond->getAsConstantUnion()->getBConst(0) == true)
            return nodePair.node1 ? setAggregateOperator(nodePair.node1, EOpSequence, nodePair.node1->getLine()) : NULL;
        else
            return nodePair.node2 ? setAggregateOperator(nodePair.node2, EOpSequence, nodePair.node2->getLine()) : NULL;
    }

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

    return node;
}


TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
{
    if (left->getType().getQualifier() == EvqConstExpr && right->getType().getQualifier() == EvqConstExpr) {
        return right;
    } else {
        TIntermTyped *commaAggregate = growAggregate(left, right, line);
        commaAggregate->getAsAggregate()->setOp(EOpComma);
        commaAggregate->setType(right->getType());
        commaAggregate->getTypePointer()->setQualifier(EvqTemporary);
        return commaAggregate;
    }
}

//
// For "?:" test nodes.  There are three children; a condition,
// a true path, and a false path.  The two paths are specified
// as separate parameters.
//
// Returns the selection node created, or 0 if one could not be.
//
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc line)
{
    if (trueBlock->getType() != falseBlock->getType())
    {
        return 0;
    }

    //
    // See if all the operands are constant, then fold it otherwise not.
    //

    if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) {
        if (cond->getAsConstantUnion()->getBConst(0))
            return trueBlock;
        else
            return falseBlock;
    }

    //
    // Make a selection node.
    //
    TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
    node->getTypePointer()->setQualifier(EvqTemporary);
    node->setLine(line);

    return node;
}

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

TIntermConstantUnion* TIntermediate::addConstantUnion(ConstantUnion* unionArrayPointer, const TType& t, TSourceLoc line)
{
    TIntermConstantUnion* node = new TIntermConstantUnion(unionArrayPointer, t);
    node->setLine(line);

    return node;
}

TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line)
{

    TIntermAggregate* node = new TIntermAggregate(EOpSequence);

    node->setLine(line);
    TIntermConstantUnion* constIntNode;
    TIntermSequence &sequenceVector = node->getSequence();
    ConstantUnion* unionArray;

    for (int i = 0; i < fields.num; i++) {
        unionArray = new ConstantUnion[1];
        unionArray->setIConst(fields.offsets[i]);
        constIntNode = addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConstExpr), line);
        sequenceVector.push_back(constIntNode);
    }

    return node;
}

//
// Create loop nodes.
//
TIntermNode* TIntermediate::addLoop(TLoopType type, TIntermNode* init, TIntermTyped* cond, TIntermTyped* expr, TIntermNode* body, TSourceLoc line)
{
    TIntermNode* node = new TIntermLoop(type, init, cond, expr, body);
    node->setLine(line);

    return node;
}

//
// Add branches.
//
TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TSourceLoc line)
{
    return addBranch(branchOp, 0, line);
}

TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, TSourceLoc line)
{
    TIntermBranch* node = new TIntermBranch(branchOp, expression);
    node->setLine(line);

    return node;
}

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

    //
    // First, finish off the top level sequence, if any
    //
    TIntermAggregate* aggRoot = root->getAsAggregate();
    if (aggRoot && aggRoot->getOp() == EOpNull)
        aggRoot->setOp(EOpSequence);

    return true;
}

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

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

//
// returns true if the operator is for one of the constructors
//
bool TIntermOperator::isConstructor() const
{
    switch (op) {
        case EOpConstructVec2:
        case EOpConstructVec3:
        case EOpConstructVec4:
        case EOpConstructMat2:
        case EOpConstructMat2x3:
        case EOpConstructMat2x4:
        case EOpConstructMat3x2:
        case EOpConstructMat3:
        case EOpConstructMat3x4:
        case EOpConstructMat4x2:
        case EOpConstructMat4x3:
        case EOpConstructMat4:
        case EOpConstructFloat:
        case EOpConstructIVec2:
        case EOpConstructIVec3:
        case EOpConstructIVec4:
        case EOpConstructInt:
        case EOpConstructUVec2:
        case EOpConstructUVec3:
        case EOpConstructUVec4:
        case EOpConstructUInt:
        case EOpConstructBVec2:
        case EOpConstructBVec3:
        case EOpConstructBVec4:
        case EOpConstructBool:
        case EOpConstructStruct:
            return true;
        default:
            return false;
    }
}

//
// Make sure the type of a unary operator is appropriate for its
// combination of operation and operand type.
//
// Returns false in nothing makes sense.
//
bool TIntermUnary::promote(TInfoSink&)
{
    switch (op) {
        case EOpLogicalNot:
            if (operand->getBasicType() != EbtBool)
                return false;
            break;
        case EOpBitwiseNot:
            if (!IsInteger(operand->getBasicType()))
                return false;
            break;
        case EOpNegative:
        case EOpPostIncrement:
        case EOpPostDecrement:
        case EOpPreIncrement:
        case EOpPreDecrement:
            if (operand->getBasicType() == EbtBool)
                return false;
            break;

            // operators for built-ins are already type checked against their prototype
        case EOpAny:
        case EOpAll:
        case EOpVectorLogicalNot:
            return true;

        default:
            if (operand->getBasicType() != EbtFloat)
                return false;
    }

    setType(operand->getType());

	// Unary operations results in temporary variables unless const.
    if (operand->getQualifier() != EvqConstExpr) {
        getTypePointer()->setQualifier(EvqTemporary);
    }

    return true;
}

//
// Establishes the type of the resultant operation, as well as
// makes the operator the correct one for the operands.
//
// Returns false if operator can't work on operands.
//
bool TIntermBinary::promote(TInfoSink& infoSink)
{
    // This function only handles scalars, vectors, and matrices.
    if (left->isArray() || right->isArray()) {
        infoSink.info.message(EPrefixInternalError, "Invalid operation for arrays", getLine());
        return false;
    }

    // GLSL ES 2.0 does not support implicit type casting.
    // So the basic type should always match.
    if (left->getBasicType() != right->getBasicType())
    {
        return false;
    }

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

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

    // Binary operations results in temporary variables unless both
    // operands are const.
    if (left->getQualifier() != EvqConstExpr || right->getQualifier() != EvqConstExpr) {
        getTypePointer()->setQualifier(EvqTemporary);
    }

    int primarySize = std::max(left->getNominalSize(), right->getNominalSize());

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

            //
            // And and Or operate on conditionals
            //
            case EOpLogicalAnd:
            case EOpLogicalOr:
            case EOpLogicalXor:
                // Both operands must be of type bool.
                if (left->getBasicType() != EbtBool || right->getBasicType() != EbtBool)
                    return false;
                setType(TType(EbtBool, EbpUndefined));
                break;

            default:
                break;
        }
        return true;
    }

    // If we reach here, at least one of the operands is vector or matrix.
    // The other operand could be a scalar, vector, or matrix.
    // Can these two operands be combined?
    //
    TBasicType basicType = left->getBasicType();
    switch (op) {
        case EOpMul:
            if (!left->isMatrix() && right->isMatrix()) {
                if (left->isVector())
                {
                    op = EOpVectorTimesMatrix;
                    setType(TType(basicType, higherPrecision, EvqTemporary,
                        static_cast<unsigned char>(right->getNominalSize()), 1));
                }
                else {
                    op = EOpMatrixTimesScalar;
                    setType(TType(basicType, higherPrecision, EvqTemporary,
                        static_cast<unsigned char>(right->getNominalSize()), static_cast<unsigned char>(right->getSecondarySize())));
                }
            } else if (left->isMatrix() && !right->isMatrix()) {
                if (right->isVector()) {
                    op = EOpMatrixTimesVector;
                    setType(TType(basicType, higherPrecision, EvqTemporary,
                        static_cast<unsigned char>(left->getSecondarySize()), 1));
                } else {
                    op = EOpMatrixTimesScalar;
                }
            } else if (left->isMatrix() && right->isMatrix()) {
                op = EOpMatrixTimesMatrix;
                setType(TType(basicType, higherPrecision, EvqTemporary,
                    static_cast<unsigned char>(right->getNominalSize()), static_cast<unsigned char>(left->getSecondarySize())));
            } else if (!left->isMatrix() && !right->isMatrix()) {
                if (left->isVector() && right->isVector()) {
                    // leave as component product
                } else if (left->isVector() || right->isVector()) {
                    op = EOpVectorTimesScalar;
                    setType(TType(basicType, higherPrecision, EvqTemporary,
                        static_cast<unsigned char>(primarySize), 1));
                }
            } else {
                infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
                return false;
            }

            if(!ValidateMultiplication(op, left->getType(), right->getType()))
            {
                return false;
            }
            break;
        case EOpMulAssign:
            if (!left->isMatrix() && right->isMatrix()) {
                if (left->isVector())
                    op = EOpVectorTimesMatrixAssign;
                else {
                    return false;
                }
            } else if (left->isMatrix() && !right->isMatrix()) {
                if (right->isVector()) {
                    return false;
                } else {
                    op = EOpMatrixTimesScalarAssign;
                }
            } else if (left->isMatrix() && right->isMatrix()) {
                op = EOpMatrixTimesMatrixAssign;
                setType(TType(basicType, higherPrecision, EvqTemporary,
                    static_cast<unsigned char>(right->getNominalSize()), static_cast<unsigned char>(left->getSecondarySize())));
            } else if (!left->isMatrix() && !right->isMatrix()) {
                if (left->isVector() && right->isVector()) {
                    // leave as component product
                } else if (left->isVector() || right->isVector()) {
                    if (! left->isVector())
                        return false;
                    op = EOpVectorTimesScalarAssign;
                    setType(TType(basicType, higherPrecision, EvqTemporary,
                        static_cast<unsigned char>(left->getNominalSize()), 1));
                }
            } else {
                infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
                return false;
            }

            if(!ValidateMultiplication(op, left->getType(), right->getType()))
            {
                return false;
            }
            break;

        case EOpAssign:
        case EOpInitialize:
            // No more additional checks are needed.
            if ((left->getNominalSize() != right->getNominalSize()) ||
                (left->getSecondarySize() != right->getSecondarySize()))
                return false;
            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:
            if ((left->isMatrix() && right->isVector()) ||
                (left->isVector() && right->isMatrix()))
                return false;

            // Are the sizes compatible?
            if(left->getNominalSize() != right->getNominalSize() ||
               left->getSecondarySize() != right->getSecondarySize())
            {
                // If the nominal sizes of operands do not match:
                // One of them must be a scalar.
                if(!left->isScalar() && !right->isScalar())
                    return false;

                // In the case of compound assignment other than multiply-assign,
                // the right side needs to be a scalar. Otherwise a vector/matrix
                // would be assigned to a scalar. A scalar can't be shifted by a
                // vector either.
                if(!right->isScalar() && (modifiesState() || op == EOpBitShiftLeft || op == EOpBitShiftRight))
                    return false;
            }

            {
                const int secondarySize = std::max(
                    left->getSecondarySize(), right->getSecondarySize());
                setType(TType(basicType, higherPrecision, EvqTemporary,
                    static_cast<unsigned char>(primarySize), static_cast<unsigned char>(secondarySize)));
                if(left->isArray())
                {
                    ASSERT(left->getArraySize() == right->getArraySize());
                    type.setArraySize(left->getArraySize());
                }
            }
            break;

        case EOpEqual:
        case EOpNotEqual:
        case EOpLessThan:
        case EOpGreaterThan:
        case EOpLessThanEqual:
        case EOpGreaterThanEqual:
            if ((left->getNominalSize() != right->getNominalSize()) ||
                (left->getSecondarySize() != right->getSecondarySize()))
                return false;
            setType(TType(EbtBool, EbpUndefined));
            break;

		case EOpOuterProduct:
			if(!left->isVector() || !right->isVector())
				return false;
			setType(TType(EbtFloat, right->getNominalSize(), left->getNominalSize()));
			break;

		case EOpTranspose:
			if(!right->isMatrix())
				return false;
			setType(TType(EbtFloat, right->getSecondarySize(), right->getNominalSize()));
			break;

		case EOpDeterminant:
			if(!right->isMatrix())
				return false;
			setType(TType(EbtFloat));
			break;

		case EOpInverse:
			if(!right->isMatrix() || right->getNominalSize() != right->getSecondarySize())
				return false;
			setType(right->getType());
			break;

        default:
            return false;
    }
    
    return true;
}

bool CompareStruct(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray)
{
    const TFieldList& fields = leftNodeType.getStruct()->fields();

    size_t structSize = fields.size();
    int index = 0;

    for (size_t j = 0; j < structSize; j++) {
        int size = fields[j]->type()->getObjectSize();
        for (int i = 0; i < size; i++) {
            if (fields[j]->type()->getBasicType() == EbtStruct) {
                if (!CompareStructure(*(fields[j]->type()), &rightUnionArray[index], &leftUnionArray[index]))
                    return false;
            } else {
                if (leftUnionArray[index] != rightUnionArray[index])
                    return false;
                index++;
            }

        }
    }
    return true;
}

bool CompareStructure(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray)
{
    if (leftNodeType.isArray()) {
        TType typeWithoutArrayness = leftNodeType;
        typeWithoutArrayness.clearArrayness();

        int arraySize = leftNodeType.getArraySize();

        for (int i = 0; i < arraySize; ++i) {
            int offset = typeWithoutArrayness.getObjectSize() * i;
            if (!CompareStruct(typeWithoutArrayness, &rightUnionArray[offset], &leftUnionArray[offset]))
                return false;
        }
    } else
        return CompareStruct(leftNodeType, rightUnionArray, leftUnionArray);

    return true;
}

float determinant2(float m00, float m01, float m10, float m11)
{
	return m00 * m11 - m01 * m10;
}

float determinant3(float m00, float m01, float m02,
                   float m10, float m11, float m12,
                   float m20, float m21, float m22)
{
	return m00 * determinant2(m11, m12, m21, m22) -
	       m10 * determinant2(m01, m02, m21, m22) +
	       m20 * determinant2(m01, m02, m11, m12);
}

float determinant4(float m00, float m01, float m02, float m03,
                   float m10, float m11, float m12, float m13,
                   float m20, float m21, float m22, float m23,
                   float m30, float m31, float m32, float m33)
{
	return m00 * determinant3(m11, m12, m13, m21, m22, m23, m31, m32, m33) -
	       m10 * determinant3(m01, m02, m03, m21, m22, m23, m31, m32, m33) +
	       m20 * determinant3(m01, m02, m03, m11, m12, m13, m31, m32, m33) -
	       m30 * determinant3(m01, m02, m03, m11, m12, m13, m21, m22, m23);
}

float ComputeDeterminant(int size, ConstantUnion* unionArray)
{
	switch(size)
	{
	case 2:
		return determinant2(unionArray[0].getFConst(),
		                    unionArray[1].getFConst(),
		                    unionArray[2].getFConst(),
		                    unionArray[3].getFConst());
	case 3:
		return determinant3(unionArray[0].getFConst(),
		                    unionArray[1].getFConst(),
		                    unionArray[2].getFConst(),
		                    unionArray[3].getFConst(),
		                    unionArray[4].getFConst(),
		                    unionArray[5].getFConst(),
		                    unionArray[6].getFConst(),
		                    unionArray[7].getFConst(),
		                    unionArray[8].getFConst());
	case 4:
		return determinant4(unionArray[0].getFConst(),
		                    unionArray[1].getFConst(),
		                    unionArray[2].getFConst(),
		                    unionArray[3].getFConst(),
		                    unionArray[4].getFConst(),
		                    unionArray[5].getFConst(),
		                    unionArray[6].getFConst(),
		                    unionArray[7].getFConst(),
		                    unionArray[8].getFConst(),
		                    unionArray[9].getFConst(),
		                    unionArray[10].getFConst(),
		                    unionArray[11].getFConst(),
		                    unionArray[12].getFConst(),
		                    unionArray[13].getFConst(),
		                    unionArray[14].getFConst(),
		                    unionArray[15].getFConst());
	default:
		UNREACHABLE();
		return 0.0f;
	}
}

ConstantUnion* CreateInverse(TIntermConstantUnion* node, ConstantUnion* unionArray)
{
	ConstantUnion* tempConstArray = 0;
	int size = node->getNominalSize();
	float determinant = ComputeDeterminant(size, unionArray);
	if(determinant != 0.0f)
	{
		float invDet = 1.0f / determinant;
		tempConstArray = new ConstantUnion[size*size];
		switch(size)
		{
		case 2:
			{
				float m00 = unionArray[0].getFConst();			// Matrix is:
				float m01 = unionArray[1].getFConst();			// (m00, m01)
				float m10 = unionArray[2].getFConst();			// (m10, m11)
				float m11 = unionArray[3].getFConst();
				tempConstArray[0].setFConst( invDet * m11);
				tempConstArray[1].setFConst(-invDet * m01);
				tempConstArray[2].setFConst(-invDet * m10);
				tempConstArray[3].setFConst( invDet * m00);
			}
			break;
		case 3:
			{
				float m00 = unionArray[0].getFConst();			// Matrix is:
				float m01 = unionArray[1].getFConst();			// (m00, m01, m02)
				float m02 = unionArray[2].getFConst();			// (m10, m11, m12)
				float m10 = unionArray[3].getFConst();			// (m20, m21, m22)
				float m11 = unionArray[4].getFConst();
				float m12 = unionArray[5].getFConst();
				float m20 = unionArray[6].getFConst();
				float m21 = unionArray[7].getFConst();
				float m22 = unionArray[8].getFConst();
				tempConstArray[0].setFConst(invDet * determinant2(m11, m12, m21, m22)); // m00 =  invDet * (m11 * m22 - m12 * m21)
				tempConstArray[1].setFConst(invDet * determinant2(m12, m10, m22, m20)); // m01 = -invDet * (m10 * m22 - m12 * m20)
				tempConstArray[2].setFConst(invDet * determinant2(m10, m11, m20, m21)); // m02 =  invDet * (m10 * m21 - m11 * m20)
				tempConstArray[3].setFConst(invDet * determinant2(m21, m22, m01, m02)); // m10 = -invDet * (m01 * m22 - m02 * m21)
				tempConstArray[4].setFConst(invDet * determinant2(m00, m02, m20, m22)); // m11 =  invDet * (m00 * m22 - m02 * m20)
				tempConstArray[5].setFConst(invDet * determinant2(m20, m21, m00, m01)); // m12 = -invDet * (m00 * m21 - m01 * m20)
				tempConstArray[6].setFConst(invDet * determinant2(m01, m02, m11, m12)); // m20 =  invDet * (m01 * m12 - m02 * m11)
				tempConstArray[7].setFConst(invDet * determinant2(m10, m12, m00, m02)); // m21 = -invDet * (m00 * m12 - m02 * m10)
				tempConstArray[8].setFConst(invDet * determinant2(m00, m01, m10, m11)); // m22 =  invDet * (m00 * m11 - m01 * m10)
			}
			break;
		case 4:
			{
				float m00 = unionArray[0].getFConst();			// Matrix is:
				float m01 = unionArray[1].getFConst();			// (m00, m01, m02, m03)
				float m02 = unionArray[2].getFConst();			// (m10, m11, m12, m13)
				float m03 = unionArray[3].getFConst();			// (m20, m21, m22, m23)
				float m10 = unionArray[4].getFConst();			// (m30, m31, m32, m33)
				float m11 = unionArray[5].getFConst();
				float m12 = unionArray[6].getFConst();
				float m13 = unionArray[7].getFConst();
				float m20 = unionArray[8].getFConst();
				float m21 = unionArray[9].getFConst();
				float m22 = unionArray[10].getFConst();
				float m23 = unionArray[11].getFConst();
				float m30 = unionArray[12].getFConst();
				float m31 = unionArray[13].getFConst();
				float m32 = unionArray[14].getFConst();
				float m33 = unionArray[15].getFConst();
				tempConstArray[ 0].setFConst( invDet * determinant3(m11, m12, m13, m21, m22, m23, m31, m32, m33)); // m00
				tempConstArray[ 1].setFConst(-invDet * determinant3(m10, m12, m13, m20, m22, m23, m30, m32, m33)); // m01
				tempConstArray[ 2].setFConst( invDet * determinant3(m10, m11, m13, m20, m21, m23, m30, m31, m33)); // m02
				tempConstArray[ 3].setFConst(-invDet * determinant3(m10, m11, m12, m20, m21, m22, m30, m31, m32)); // m03
				tempConstArray[ 4].setFConst( invDet * determinant3(m01, m02, m03, m21, m22, m23, m31, m32, m33)); // m10
				tempConstArray[ 5].setFConst(-invDet * determinant3(m00, m02, m03, m20, m22, m23, m30, m32, m33)); // m11
				tempConstArray[ 6].setFConst( invDet * determinant3(m00, m01, m03, m20, m21, m23, m30, m31, m33)); // m12
				tempConstArray[ 7].setFConst(-invDet * determinant3(m00, m01, m02, m20, m21, m22, m30, m31, m32)); // m13
				tempConstArray[ 8].setFConst( invDet * determinant3(m01, m02, m03, m11, m12, m13, m31, m32, m33)); // m20
				tempConstArray[ 9].setFConst(-invDet * determinant3(m00, m02, m03, m10, m12, m13, m30, m32, m33)); // m21
				tempConstArray[10].setFConst( invDet * determinant3(m00, m01, m03, m10, m11, m13, m30, m31, m33)); // m22
				tempConstArray[11].setFConst(-invDet * determinant3(m00, m01, m02, m10, m11, m12, m30, m31, m32)); // m23
				tempConstArray[12].setFConst( invDet * determinant3(m01, m02, m03, m11, m12, m13, m21, m22, m23)); // m30
				tempConstArray[13].setFConst(-invDet * determinant3(m00, m02, m03, m10, m12, m13, m20, m22, m23)); // m31
				tempConstArray[14].setFConst( invDet * determinant3(m00, m01, m03, m10, m11, m13, m20, m21, m23)); // m32
				tempConstArray[15].setFConst(-invDet * determinant3(m00, m01, m02, m10, m11, m12, m20, m21, m22)); // m33
			}
			break;
		default:
			UNREACHABLE();
		}
	}
	return tempConstArray;
}

//
// The fold functions see if an operation on a constant can be done in place,
// without generating run-time code.
//
// Returns the node to keep using, which may or may not be the node passed in.
//

TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNode, TInfoSink& infoSink)
{
    ConstantUnion *unionArray = getUnionArrayPointer();
    int objectSize = getType().getObjectSize();

    if (constantNode) {  // binary operations
        TIntermConstantUnion *node = constantNode->getAsConstantUnion();
        ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
        TType returnType = getType();

        // for a case like float f = 1.2 + vec4(2,3,4,5);
        if (constantNode->getType().getObjectSize() == 1 && objectSize > 1) {
            rightUnionArray = new ConstantUnion[objectSize];
            for (int i = 0; i < objectSize; ++i)
                rightUnionArray[i] = *node->getUnionArrayPointer();
            returnType = getType();
        } else if (constantNode->getType().getObjectSize() > 1 && objectSize == 1) {
            // for a case like float f = vec4(2,3,4,5) + 1.2;
            unionArray = new ConstantUnion[constantNode->getType().getObjectSize()];
            for (int i = 0; i < constantNode->getType().getObjectSize(); ++i)
                unionArray[i] = *getUnionArrayPointer();
            returnType = node->getType();
            objectSize = constantNode->getType().getObjectSize();
        }

        ConstantUnion* tempConstArray = 0;
        TIntermConstantUnion *tempNode;

        bool boolNodeFlag = false;
        switch(op) {
            case EOpAdd:
                tempConstArray = new ConstantUnion[objectSize];
                {// support MSVC++6.0
                    for (int i = 0; i < objectSize; i++)
                        tempConstArray[i] = unionArray[i] + rightUnionArray[i];
                }
                break;
            case EOpSub:
                tempConstArray = new ConstantUnion[objectSize];
                {// support MSVC++6.0
                    for (int i = 0; i < objectSize; i++)
                        tempConstArray[i] = unionArray[i] - rightUnionArray[i];
                }
                break;

            case EOpMul:
            case EOpVectorTimesScalar:
            case EOpMatrixTimesScalar:
                tempConstArray = new ConstantUnion[objectSize];
                {// support MSVC++6.0
                    for (int i = 0; i < objectSize; i++)
                        tempConstArray[i] = unionArray[i] * rightUnionArray[i];
                }
                break;
            case EOpMatrixTimesMatrix:
                if (getType().getBasicType() != EbtFloat || node->getBasicType() != EbtFloat) {
                    infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix multiply", getLine());
                    return 0;
                }
                {// support MSVC++6.0
                    int leftNumCols = getNominalSize();
                    int leftNumRows = getSecondarySize();
                    int rightNumCols = node->getNominalSize();
                    int rightNumRows = node->getSecondarySize();
                    if(leftNumCols != rightNumRows) {
                        infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix multiply", getLine());
                        return 0;
                    }
                    int tempNumCols = rightNumCols;
                    int tempNumRows = leftNumRows;
                    int tempNumAdds = leftNumCols;
                    tempConstArray = new ConstantUnion[tempNumCols*tempNumRows];
                    for (int row = 0; row < tempNumRows; row++) {
                        for (int column = 0; column < tempNumCols; column++) {
                            tempConstArray[tempNumRows * column + row].setFConst(0.0f);
                            for (int i = 0; i < tempNumAdds; i++) {
                                tempConstArray[tempNumRows * column + row].setFConst(tempConstArray[tempNumRows * column + row].getFConst() + unionArray[i * leftNumRows + row].getFConst() * (rightUnionArray[column * rightNumRows + i].getFConst()));
                            }
                        }
                    }
                    // update return type for matrix product
                    returnType.setNominalSize(static_cast<unsigned char>(tempNumCols));
                    returnType.setSecondarySize(static_cast<unsigned char>(tempNumRows));
                }
                break;

			case EOpOuterProduct:
				{
					int leftSize = getNominalSize();
					int rightSize = node->getNominalSize();
					tempConstArray = new ConstantUnion[leftSize*rightSize];
					for(int row = 0; row < leftSize; row++) {
						for(int column = 0; column < rightSize; column++) {
							tempConstArray[leftSize * column + row].setFConst(unionArray[row].getFConst() * rightUnionArray[column].getFConst());
						}
					}
					// update return type for outer product
					returnType.setNominalSize(static_cast<unsigned char>(rightSize));
					returnType.setSecondarySize(static_cast<unsigned char>(leftSize));
				}
				break;

			case EOpTranspose:
				{
					int rightCol = node->getNominalSize();
					int rightRow = node->getSecondarySize();
					tempConstArray = new ConstantUnion[rightCol*rightRow];
					for(int row = 0; row < rightRow; row++) {
						for(int column = 0; column < rightCol; column++) {
							tempConstArray[rightRow * column + row].setFConst(rightUnionArray[rightCol * row + column].getFConst());
						}
					}
					// update return type for transpose
					returnType.setNominalSize(static_cast<unsigned char>(rightRow));
					returnType.setSecondarySize(static_cast<unsigned char>(rightCol));
				}
				break;

			case EOpDeterminant:
				{
					ASSERT(node->getNominalSize() == node->getSecondarySize());

					tempConstArray = new ConstantUnion[1];
					tempConstArray[0].setFConst(ComputeDeterminant(node->getNominalSize(), rightUnionArray));
					// update return type for determinant
					returnType.setNominalSize(1);
					returnType.setSecondarySize(1);
				}
				break;

			case EOpInverse:
				{
					ASSERT(node->getNominalSize() == node->getSecondarySize());

					tempConstArray = CreateInverse(node, rightUnionArray);
					if(!tempConstArray)
					{
						// Singular matrix, just copy
						tempConstArray = new ConstantUnion[objectSize];
						for(int i = 0; i < objectSize; i++)
							tempConstArray[i] = rightUnionArray[i];
					}
				}
				break;

            case EOpDiv:
            case EOpIMod:
                tempConstArray = new ConstantUnion[objectSize];
                {// support MSVC++6.0
                    for (int i = 0; i < objectSize; i++) {
                        switch (getType().getBasicType()) {
                            case EbtFloat:
                                if (rightUnionArray[i] == 0.0f) {
                                    infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
                                    tempConstArray[i].setFConst(FLT_MAX);
                                } else {
                                    ASSERT(op == EOpDiv);
                                    tempConstArray[i].setFConst(unionArray[i].getFConst() / rightUnionArray[i].getFConst());
                                }
                                break;

                            case EbtInt:
                                if (rightUnionArray[i] == 0) {
                                    infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
                                    tempConstArray[i].setIConst(INT_MAX);
                                } else {
                                    if(op == EOpDiv) {
                                        tempConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst());
                                    } else {
                                        ASSERT(op == EOpIMod);
                                        tempConstArray[i].setIConst(unionArray[i].getIConst() % rightUnionArray[i].getIConst());
                                    }
                                }
                                break;
                            case EbtUInt:
                                if (rightUnionArray[i] == 0) {
                                    infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
                                    tempConstArray[i].setUConst(UINT_MAX);
                                } else {
                                    if(op == EOpDiv) {
                                        tempConstArray[i].setUConst(unionArray[i].getUConst() / rightUnionArray[i].getUConst());
                                    } else {
                                        ASSERT(op == EOpIMod);
                                        tempConstArray[i].setUConst(unionArray[i].getUConst() % rightUnionArray[i].getUConst());
                                    }
                                }
                                break;
                            default:
                                infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLine());
                                return 0;
                        }
                    }
                }
                break;

            case EOpMatrixTimesVector:
                if (node->getBasicType() != EbtFloat) {
                    infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix times vector", getLine());
                    return 0;
                }
                tempConstArray = new ConstantUnion[getNominalSize()];

                {// support MSVC++6.0
                    for (int size = getNominalSize(), i = 0; i < size; i++) {
                        tempConstArray[i].setFConst(0.0f);
                        for (int j = 0; j < size; j++) {
                            tempConstArray[i].setFConst(tempConstArray[i].getFConst() + ((unionArray[j*size + i].getFConst()) * rightUnionArray[j].getFConst()));
                        }
                    }
                }

                tempNode = new TIntermConstantUnion(tempConstArray, node->getType());
                tempNode->setLine(getLine());

                return tempNode;

            case EOpVectorTimesMatrix:
                if (getType().getBasicType() != EbtFloat) {
                    infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for vector times matrix", getLine());
                    return 0;
                }

                tempConstArray = new ConstantUnion[getNominalSize()];
                {// support MSVC++6.0
                    for (int size = getNominalSize(), i = 0; i < size; i++) {
                        tempConstArray[i].setFConst(0.0f);
                        for (int j = 0; j < size; j++) {
                            tempConstArray[i].setFConst(tempConstArray[i].getFConst() + ((unionArray[j].getFConst()) * rightUnionArray[i*size + j].getFConst()));
                        }
                    }
                }
                break;

            case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently
                tempConstArray = new ConstantUnion[objectSize];
                {// support MSVC++6.0
                    for (int i = 0; i < objectSize; i++)
                        tempConstArray[i] = unionArray[i] && rightUnionArray[i];
                }
                break;

            case EOpLogicalOr: // this code is written for possible future use, will not get executed currently
                tempConstArray = new ConstantUnion[objectSize];
                {// support MSVC++6.0
                    for (int i = 0; i < objectSize; i++)
                        tempConstArray[i] = unionArray[i] || rightUnionArray[i];
                }
                break;

            case EOpLogicalXor:
                tempConstArray = new ConstantUnion[objectSize];
                {// support MSVC++6.0
                    for (int i = 0; i < objectSize; i++)
                        switch (getType().getBasicType()) {
                            case EbtBool: tempConstArray[i].setBConst((unionArray[i] == rightUnionArray[i]) ? false : true); break;
                            default: assert(false && "Default missing");
                    }
                }
                break;

            case EOpBitwiseAnd:
                tempConstArray = new ConstantUnion[objectSize];
                for(int i = 0; i < objectSize; i++)
                    tempConstArray[i] = unionArray[i] & rightUnionArray[i];
                break;
            case EOpBitwiseXor:
                tempConstArray = new ConstantUnion[objectSize];
                for(int i = 0; i < objectSize; i++)
                    tempConstArray[i] = unionArray[i] ^ rightUnionArray[i];
                break;
            case EOpBitwiseOr:
                tempConstArray = new ConstantUnion[objectSize];
                for(int i = 0; i < objectSize; i++)
                    tempConstArray[i] = unionArray[i] | rightUnionArray[i];
                break;
            case EOpBitShiftLeft:
                tempConstArray = new ConstantUnion[objectSize];
                for(int i = 0; i < objectSize; i++)
                    tempConstArray[i] = unionArray[i] << rightUnionArray[i];
                break;
            case EOpBitShiftRight:
                tempConstArray = new ConstantUnion[objectSize];
                for(int i = 0; i < objectSize; i++)
                    tempConstArray[i] = unionArray[i] >> rightUnionArray[i];
                break;

            case EOpLessThan:
                assert(objectSize == 1);
                tempConstArray = new ConstantUnion[1];
                tempConstArray->setBConst(*unionArray < *rightUnionArray);
                returnType = TType(EbtBool, EbpUndefined, EvqConstExpr);
                break;
            case EOpGreaterThan:
                assert(objectSize == 1);
                tempConstArray = new ConstantUnion[1];
                tempConstArray->setBConst(*unionArray > *rightUnionArray);
                returnType = TType(EbtBool, EbpUndefined, EvqConstExpr);
                break;
            case EOpLessThanEqual:
                {
                    assert(objectSize == 1);
                    ConstantUnion constant;
                    constant.setBConst(*unionArray > *rightUnionArray);
                    tempConstArray = new ConstantUnion[1];
                    tempConstArray->setBConst(!constant.getBConst());
                    returnType = TType(EbtBool, EbpUndefined, EvqConstExpr);
                    break;
                }
            case EOpGreaterThanEqual:
                {
                    assert(objectSize == 1);
                    ConstantUnion constant;
                    constant.setBConst(*unionArray < *rightUnionArray);
                    tempConstArray = new ConstantUnion[1];
                    tempConstArray->setBConst(!constant.getBConst());
                    returnType = TType(EbtBool, EbpUndefined, EvqConstExpr);
                    break;
                }

            case EOpEqual:
                if (getType().getBasicType() == EbtStruct) {
                    if (!CompareStructure(node->getType(), node->getUnionArrayPointer(), unionArray))
                        boolNodeFlag = true;
                } else {
                    for (int i = 0; i < objectSize; i++) {
                        if (unionArray[i] != rightUnionArray[i]) {
                            boolNodeFlag = true;
                            break;  // break out of for loop
                        }
                    }
                }

                tempConstArray = new ConstantUnion[1];
                if (!boolNodeFlag) {
                    tempConstArray->setBConst(true);
                }
                else {
                    tempConstArray->setBConst(false);
                }

                tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EbpUndefined, EvqConstExpr));
                tempNode->setLine(getLine());

                return tempNode;

            case EOpNotEqual:
                if (getType().getBasicType() == EbtStruct) {
                    if (CompareStructure(node->getType(), node->getUnionArrayPointer(), unionArray))
                        boolNodeFlag = true;
                } else {
                    for (int i = 0; i < objectSize; i++) {
                        if (unionArray[i] == rightUnionArray[i]) {
                            boolNodeFlag = true;
                            break;  // break out of for loop
                        }
                    }
                }

                tempConstArray = new ConstantUnion[1];
                if (!boolNodeFlag) {
                    tempConstArray->setBConst(true);
                }
                else {
                    tempConstArray->setBConst(false);
                }

                tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EbpUndefined, EvqConstExpr));
                tempNode->setLine(getLine());

                return tempNode;

            default:
                infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", getLine());
                return 0;
        }
        tempNode = new TIntermConstantUnion(tempConstArray, returnType);
        tempNode->setLine(getLine());

        return tempNode;
    } else {
        //
        // Do unary operations
        //
        TIntermConstantUnion *newNode = 0;
        ConstantUnion* tempConstArray = new ConstantUnion[objectSize];
        for (int i = 0; i < objectSize; i++) {
            switch(op) {
                case EOpNegative:
                    switch (getType().getBasicType()) {
                        case EbtFloat: tempConstArray[i].setFConst(-unionArray[i].getFConst()); break;
                        case EbtInt:   tempConstArray[i].setIConst(-unionArray[i].getIConst()); break;
                        default:
                            infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
                            return 0;
                    }
                    break;
                case EOpLogicalNot: // this code is written for possible future use, will not get executed currently
                    switch (getType().getBasicType()) {
                        case EbtBool:  tempConstArray[i].setBConst(!unionArray[i].getBConst()); break;
                        default:
                            infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
                            return 0;
                    }
                    break;
                case EOpBitwiseNot:
                    switch(getType().getBasicType()) {
                        case EbtInt: tempConstArray[i].setIConst(~unionArray[i].getIConst()); break;
                        case EbtUInt: tempConstArray[i].setUConst(~unionArray[i].getUConst()); break;
                        default:
                            infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
                            return 0;
                    }
                    break;
                default:
                    return 0;
            }
        }
        newNode = new TIntermConstantUnion(tempConstArray, getType());
        newNode->setLine(getLine());
        return newNode;
    }
}

TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node)
{
    int size = node->getType().getObjectSize();

    ConstantUnion *leftUnionArray = new ConstantUnion[size];

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

        switch (promoteTo) {
            case EbtFloat:
                switch (node->getType().getBasicType()) {
                    case EbtInt:
                        leftUnionArray[i].setFConst(static_cast<float>(node->getIConst(i)));
                        break;
                    case EbtUInt:
                        leftUnionArray[i].setFConst(static_cast<float>(node->getUConst(i)));
                        break;
                    case EbtBool:
                        leftUnionArray[i].setFConst(static_cast<float>(node->getBConst(i)));
                        break;
                    case EbtFloat:
                        leftUnionArray[i].setFConst(static_cast<float>(node->getFConst(i)));
                        break;
                    default:
                        infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
                        return 0;
                }
                break;
            case EbtInt:
                switch (node->getType().getBasicType()) {
                    case EbtInt:
                        leftUnionArray[i].setIConst(static_cast<int>(node->getIConst(i)));
                        break;
                    case EbtUInt:
                        leftUnionArray[i].setIConst(static_cast<int>(node->getUConst(i)));
                        break;
                    case EbtBool:
                        leftUnionArray[i].setIConst(static_cast<int>(node->getBConst(i)));
                        break;
                    case EbtFloat:
                        leftUnionArray[i].setIConst(static_cast<int>(node->getFConst(i)));
                        break;
                    default:
                        infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
                        return 0;
                }
                break;
            case EbtUInt:
                switch (node->getType().getBasicType()) {
                    case EbtInt:
                        leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getIConst(i)));
                        break;
                    case EbtUInt:
                        leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getUConst(i)));
                        break;
                    case EbtBool:
                        leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getBConst(i)));
                        break;
                    case EbtFloat:
                        leftUnionArray[i].setUConst(static_cast<unsigned int>(node->getFConst(i)));
                        break;
                    default:
                        infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
                        return 0;
                }
                break;
            case EbtBool:
                switch (node->getType().getBasicType()) {
                    case EbtInt:
                        leftUnionArray[i].setBConst(node->getIConst(i) != 0);
                        break;
                    case EbtUInt:
                        leftUnionArray[i].setBConst(node->getUConst(i) != 0);
                        break;
                    case EbtBool:
                        leftUnionArray[i].setBConst(node->getBConst(i));
                        break;
                    case EbtFloat:
                        leftUnionArray[i].setBConst(node->getFConst(i) != 0.0f);
                        break;
                    default:
                        infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
                        return 0;
                }

                break;
            default:
                infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLine());
                return 0;
        }

    }

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

	return addConstantUnion(leftUnionArray, TType(promoteTo, t.getPrecision(), t.getQualifier(), t.getNominalSize(), t.getSecondarySize(), t.isArray()), node->getLine());
}

