Home | History | Annotate | Download | only in MachineIndependent
      1 //
      2 //Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
      3 //Copyright (C) 2012-2015 LunarG, Inc.
      4 //Copyright (C) 2015-2016 Google, Inc.
      5 //
      6 //All rights reserved.
      7 //
      8 //Redistribution and use in source and binary forms, with or without
      9 //modification, are permitted provided that the following conditions
     10 //are met:
     11 //
     12 //    Redistributions of source code must retain the above copyright
     13 //    notice, this list of conditions and the following disclaimer.
     14 //
     15 //    Redistributions in binary form must reproduce the above
     16 //    copyright notice, this list of conditions and the following
     17 //    disclaimer in the documentation and/or other materials provided
     18 //    with the distribution.
     19 //
     20 //    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
     21 //    contributors may be used to endorse or promote products derived
     22 //    from this software without specific prior written permission.
     23 //
     24 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     25 //"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     26 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     27 //FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     28 //COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     29 //INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     30 //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     31 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     32 //CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     33 //LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     34 //ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35 //POSSIBILITY OF SUCH DAMAGE.
     36 //
     37 
     38 //
     39 // Build the intermediate representation.
     40 //
     41 
     42 #include "localintermediate.h"
     43 #include "RemoveTree.h"
     44 #include "SymbolTable.h"
     45 #include "propagateNoContraction.h"
     46 
     47 #include <float.h>
     48 
     49 namespace glslang {
     50 
     51 ////////////////////////////////////////////////////////////////////////////
     52 //
     53 // First set of functions are to help build the intermediate representation.
     54 // These functions are not member functions of the nodes.
     55 // They are called from parser productions.
     56 //
     57 /////////////////////////////////////////////////////////////////////////////
     58 
     59 //
     60 // Add a terminal node for an identifier in an expression.
     61 //
     62 // Returns the added node.
     63 //
     64 
     65 TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, const TConstUnionArray& constArray,
     66                                         TIntermTyped* constSubtree, const TSourceLoc& loc)
     67 {
     68     TIntermSymbol* node = new TIntermSymbol(id, name, type);
     69     node->setLoc(loc);
     70     node->setConstArray(constArray);
     71     node->setConstSubtree(constSubtree);
     72 
     73     return node;
     74 }
     75 
     76 TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable)
     77 {
     78     glslang::TSourceLoc loc; // just a null location
     79     loc.init();
     80 
     81     return addSymbol(variable, loc);
     82 }
     83 
     84 TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable, const TSourceLoc& loc)
     85 {
     86     return addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), variable.getConstArray(), variable.getConstSubtree(), loc);
     87 }
     88 
     89 TIntermSymbol* TIntermediate::addSymbol(const TType& type, const TSourceLoc& loc)
     90 {
     91     TConstUnionArray unionArray;  // just a null constant
     92 
     93     return addSymbol(0, "", type, unionArray, nullptr, loc);
     94 }
     95 
     96 //
     97 // Connect two nodes with a new parent that does a binary operation on the nodes.
     98 //
     99 // Returns the added node.
    100 //
    101 TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc)
    102 {
    103     // No operations work on blocks
    104     if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock)
    105         return 0;
    106 
    107     // Try converting the children's base types to compatible types.
    108     TIntermTyped* child = addConversion(op, left->getType(), right);
    109     if (child)
    110         right = child;
    111     else {
    112         child = addConversion(op, right->getType(), left);
    113         if (child)
    114             left = child;
    115         else
    116             return 0;
    117     }
    118 
    119     //
    120     // Need a new node holding things together.  Make
    121     // one and promote it to the right type.
    122     //
    123     TIntermBinary* node = new TIntermBinary(op);
    124     if (loc.line == 0)
    125         loc = right->getLoc();
    126     node->setLoc(loc);
    127 
    128     node->setLeft(left);
    129     node->setRight(right);
    130     if (! node->promote())
    131         return 0;
    132 
    133     node->updatePrecision();
    134 
    135     //
    136     // If they are both (non-specialization) constants, they must be folded.
    137     // (Unless it's the sequence (comma) operator, but that's handled in addComma().)
    138     //
    139     TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
    140     TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
    141     if (leftTempConstant && rightTempConstant) {
    142         TIntermTyped* folded = leftTempConstant->fold(node->getOp(), rightTempConstant);
    143         if (folded)
    144             return folded;
    145     }
    146 
    147     // If either is a specialization constant, while the other is
    148     // a constant (or specialization constant), the result is still
    149     // a specialization constant, if the operation is an allowed
    150     // specialization-constant operation.
    151     if (( left->getType().getQualifier().isSpecConstant() && right->getType().getQualifier().isConstant()) ||
    152         (right->getType().getQualifier().isSpecConstant() &&  left->getType().getQualifier().isConstant()))
    153         if (isSpecializationOperation(*node))
    154             node->getWritableType().getQualifier().makeSpecConstant();
    155 
    156     return node;
    157 }
    158 
    159 //
    160 // Connect two nodes through an assignment.
    161 //
    162 // Returns the added node.
    163 //
    164 TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc)
    165 {
    166     // No block assignment
    167     if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock)
    168         return 0;
    169 
    170     //
    171     // Like adding binary math, except the conversion can only go
    172     // from right to left.
    173     //
    174     TIntermBinary* node = new TIntermBinary(op);
    175     if (loc.line == 0)
    176         loc = left->getLoc();
    177     node->setLoc(loc);
    178 
    179     TIntermTyped* child = addConversion(op, left->getType(), right);
    180     if (child == 0)
    181         return 0;
    182 
    183     node->setLeft(left);
    184     node->setRight(child);
    185     if (! node->promote())
    186         return 0;
    187 
    188     node->updatePrecision();
    189 
    190     return node;
    191 }
    192 
    193 //
    194 // Connect two nodes through an index operator, where the left node is the base
    195 // of an array or struct, and the right node is a direct or indirect offset.
    196 //
    197 // Returns the added node.
    198 // The caller should set the type of the returned node.
    199 //
    200 TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc loc)
    201 {
    202     TIntermBinary* node = new TIntermBinary(op);
    203     if (loc.line == 0)
    204         loc = index->getLoc();
    205     node->setLoc(loc);
    206     node->setLeft(base);
    207     node->setRight(index);
    208 
    209     // caller should set the type
    210 
    211     return node;
    212 }
    213 
    214 //
    215 // Add one node as the parent of another that it operates on.
    216 //
    217 // Returns the added node.
    218 //
    219 TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSourceLoc loc)
    220 {
    221     if (child == 0)
    222         return 0;
    223 
    224     if (child->getType().getBasicType() == EbtBlock)
    225         return 0;
    226 
    227     switch (op) {
    228     case EOpLogicalNot:
    229         if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) {
    230             return 0;
    231         }
    232         break;
    233 
    234     case EOpPostIncrement:
    235     case EOpPreIncrement:
    236     case EOpPostDecrement:
    237     case EOpPreDecrement:
    238     case EOpNegative:
    239         if (child->getType().getBasicType() == EbtStruct || child->getType().isArray())
    240             return 0;
    241     default: break; // some compilers want this
    242     }
    243 
    244     //
    245     // Do we need to promote the operand?
    246     //
    247     TBasicType newType = EbtVoid;
    248     switch (op) {
    249     case EOpConstructInt:    newType = EbtInt;    break;
    250     case EOpConstructUint:   newType = EbtUint;   break;
    251     case EOpConstructInt64:  newType = EbtInt64;  break;
    252     case EOpConstructUint64: newType = EbtUint64; break;
    253     case EOpConstructBool:   newType = EbtBool;   break;
    254     case EOpConstructFloat:  newType = EbtFloat;  break;
    255     case EOpConstructDouble: newType = EbtDouble; break;
    256     default: break; // some compilers want this
    257     }
    258 
    259     if (newType != EbtVoid) {
    260         child = addConversion(op, TType(newType, EvqTemporary, child->getVectorSize(),
    261                                                                child->getMatrixCols(),
    262                                                                child->getMatrixRows()),
    263                               child);
    264         if (child == 0)
    265             return 0;
    266     }
    267 
    268     //
    269     // For constructors, we are now done, it was all in the conversion.
    270     // TODO: but, did this bypass constant folding?
    271     //
    272     switch (op) {
    273     case EOpConstructInt:
    274     case EOpConstructUint:
    275     case EOpConstructInt64:
    276     case EOpConstructUint64:
    277     case EOpConstructBool:
    278     case EOpConstructFloat:
    279     case EOpConstructDouble:
    280         return child;
    281     default: break; // some compilers want this
    282     }
    283 
    284     //
    285     // Make a new node for the operator.
    286     //
    287     TIntermUnary* node = new TIntermUnary(op);
    288     if (loc.line == 0)
    289         loc = child->getLoc();
    290     node->setLoc(loc);
    291     node->setOperand(child);
    292 
    293     if (! node->promote())
    294         return 0;
    295 
    296     node->updatePrecision();
    297 
    298     // If it's a (non-specialization) constant, it must be folded.
    299     if (child->getAsConstantUnion())
    300         return child->getAsConstantUnion()->fold(op, node->getType());
    301 
    302     // If it's a specialization constant, the result is too,
    303     // if the operation is allowed for specialization constants.
    304     if (child->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*node))
    305         node->getWritableType().getQualifier().makeSpecConstant();
    306 
    307     return node;
    308 }
    309 
    310 TIntermTyped* TIntermediate::addBuiltInFunctionCall(const TSourceLoc& loc, TOperator op, bool unary, TIntermNode* childNode, const TType& returnType)
    311 {
    312     if (unary) {
    313         //
    314         // Treat it like a unary operator.
    315         // addUnaryMath() should get the type correct on its own;
    316         // including constness (which would differ from the prototype).
    317         //
    318         TIntermTyped* child = childNode->getAsTyped();
    319         if (child == 0)
    320             return 0;
    321 
    322         if (child->getAsConstantUnion()) {
    323             TIntermTyped* folded = child->getAsConstantUnion()->fold(op, returnType);
    324             if (folded)
    325                 return folded;
    326         }
    327 
    328         TIntermUnary* node = new TIntermUnary(op);
    329         node->setLoc(child->getLoc());
    330         node->setOperand(child);
    331         node->setType(returnType);
    332 
    333         // propagate precision up from child
    334         if (profile == EEsProfile && returnType.getQualifier().precision == EpqNone && returnType.getBasicType() != EbtBool)
    335             node->getQualifier().precision = child->getQualifier().precision;
    336 
    337         // propagate precision down to child
    338         if (node->getQualifier().precision != EpqNone)
    339             child->propagatePrecision(node->getQualifier().precision);
    340 
    341         return node;
    342     } else {
    343         // setAggregateOperater() calls fold() for constant folding
    344         TIntermTyped* node = setAggregateOperator(childNode, op, returnType, loc);
    345 
    346         // if not folded, we'll still have an aggregate node to propagate precision with
    347         if (node->getAsAggregate()) {
    348             TPrecisionQualifier correctPrecision = returnType.getQualifier().precision;
    349             if (correctPrecision == EpqNone && profile == EEsProfile) {
    350                 // find the maximum precision from the arguments, for the built-in's return precision
    351                 TIntermSequence& sequence = node->getAsAggregate()->getSequence();
    352                 for (unsigned int arg = 0; arg < sequence.size(); ++arg)
    353                     correctPrecision = std::max(correctPrecision, sequence[arg]->getAsTyped()->getQualifier().precision);
    354             }
    355 
    356             // Propagate precision through this node and its children. That algorithm stops
    357             // when a precision is found, so start by clearing this subroot precision
    358             node->getQualifier().precision = EpqNone;
    359             node->propagatePrecision(correctPrecision);
    360         }
    361 
    362         return node;
    363     }
    364 }
    365 
    366 //
    367 // This is the safe way to change the operator on an aggregate, as it
    368 // does lots of error checking and fixing.  Especially for establishing
    369 // a function call's operation on it's set of parameters.  Sequences
    370 // of instructions are also aggregates, but they just directly set
    371 // their operator to EOpSequence.
    372 //
    373 // Returns an aggregate node, which could be the one passed in if
    374 // it was already an aggregate.
    375 //
    376 TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type, TSourceLoc loc)
    377 {
    378     TIntermAggregate* aggNode;
    379 
    380     //
    381     // Make sure we have an aggregate.  If not turn it into one.
    382     //
    383     if (node) {
    384         aggNode = node->getAsAggregate();
    385         if (aggNode == 0 || aggNode->getOp() != EOpNull) {
    386             //
    387             // Make an aggregate containing this node.
    388             //
    389             aggNode = new TIntermAggregate();
    390             aggNode->getSequence().push_back(node);
    391             if (loc.line == 0)
    392                 loc = node->getLoc();
    393         }
    394     } else
    395         aggNode = new TIntermAggregate();
    396 
    397     //
    398     // Set the operator.
    399     //
    400     aggNode->setOperator(op);
    401     if (loc.line != 0)
    402         aggNode->setLoc(loc);
    403 
    404     aggNode->setType(type);
    405 
    406     return fold(aggNode);
    407 }
    408 
    409 //
    410 // Convert the node's type to the given type, as allowed by the operation involved: 'op'.
    411 // For implicit conversions, 'op' is not the requested conversion, it is the explicit
    412 // operation requiring the implicit conversion.
    413 //
    414 // Returns a node representing the conversion, which could be the same
    415 // node passed in if no conversion was needed.
    416 //
    417 // Return 0 if a conversion can't be done.
    418 //
    419 TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node) const
    420 {
    421     //
    422     // Does the base type even allow the operation?
    423     //
    424     switch (node->getBasicType()) {
    425     case EbtVoid:
    426         return 0;
    427     case EbtAtomicUint:
    428     case EbtSampler:
    429         // opaque types can be passed to functions
    430         if (op == EOpFunction)
    431             break;
    432         // samplers can get assigned via a sampler constructor
    433         // (well, not yet, but code in the rest of this function is ready for it)
    434         if (node->getBasicType() == EbtSampler && op == EOpAssign &&
    435             node->getAsOperator() != nullptr && node->getAsOperator()->getOp() == EOpConstructTextureSampler)
    436             break;
    437 
    438         // otherwise, opaque types can't even be operated on, let alone converted
    439         return 0;
    440     default:
    441         break;
    442     }
    443 
    444     // Otherwise, if types are identical, no problem
    445     if (type == node->getType())
    446         return node;
    447 
    448     // If one's a structure, then no conversions.
    449     if (type.isStruct() || node->isStruct())
    450         return 0;
    451 
    452     // If one's an array, then no conversions.
    453     if (type.isArray() || node->getType().isArray())
    454         return 0;
    455 
    456     // Note: callers are responsible for other aspects of shape,
    457     // like vector and matrix sizes.
    458 
    459     TBasicType promoteTo;
    460 
    461     switch (op) {
    462     //
    463     // Explicit conversions (unary operations)
    464     //
    465     case EOpConstructBool:
    466         promoteTo = EbtBool;
    467         break;
    468     case EOpConstructFloat:
    469         promoteTo = EbtFloat;
    470         break;
    471     case EOpConstructDouble:
    472         promoteTo = EbtDouble;
    473         break;
    474     case EOpConstructInt:
    475         promoteTo = EbtInt;
    476         break;
    477     case EOpConstructUint:
    478         promoteTo = EbtUint;
    479         break;
    480     case EOpConstructInt64:
    481         promoteTo = EbtInt64;
    482         break;
    483     case EOpConstructUint64:
    484         promoteTo = EbtUint64;
    485         break;
    486 
    487     //
    488     // List all the binary ops that can implicitly convert one operand to the other's type;
    489     // This implements the 'policy' for implicit type conversion.
    490     //
    491     case EOpLessThan:
    492     case EOpGreaterThan:
    493     case EOpLessThanEqual:
    494     case EOpGreaterThanEqual:
    495     case EOpEqual:
    496     case EOpNotEqual:
    497 
    498     case EOpAdd:
    499     case EOpSub:
    500     case EOpMul:
    501     case EOpDiv:
    502     case EOpMod:
    503 
    504     case EOpVectorTimesScalar:
    505     case EOpVectorTimesMatrix:
    506     case EOpMatrixTimesVector:
    507     case EOpMatrixTimesScalar:
    508 
    509     case EOpAnd:
    510     case EOpInclusiveOr:
    511     case EOpExclusiveOr:
    512     case EOpAndAssign:
    513     case EOpInclusiveOrAssign:
    514     case EOpExclusiveOrAssign:
    515 
    516     case EOpFunctionCall:
    517     case EOpReturn:
    518     case EOpAssign:
    519     case EOpAddAssign:
    520     case EOpSubAssign:
    521     case EOpMulAssign:
    522     case EOpVectorTimesScalarAssign:
    523     case EOpMatrixTimesScalarAssign:
    524     case EOpDivAssign:
    525     case EOpModAssign:
    526 
    527     case EOpSequence:
    528     case EOpConstructStruct:
    529 
    530         if (type.getBasicType() == node->getType().getBasicType())
    531             return node;
    532 
    533         if (canImplicitlyPromote(node->getType().getBasicType(), type.getBasicType()))
    534             promoteTo = type.getBasicType();
    535         else
    536             return 0;
    537 
    538         break;
    539 
    540     // Shifts can have mixed types as long as they are integer, without converting.
    541     // It's the left operand's type that determines the resulting type, so no issue
    542     // with assign shift ops either.
    543     case EOpLeftShift:
    544     case EOpRightShift:
    545     case EOpLeftShiftAssign:
    546     case EOpRightShiftAssign:
    547         if ((type.getBasicType() == EbtInt ||
    548              type.getBasicType() == EbtUint ||
    549              type.getBasicType() == EbtInt64 ||
    550              type.getBasicType() == EbtUint64) &&
    551             (node->getType().getBasicType() == EbtInt ||
    552              node->getType().getBasicType() == EbtUint ||
    553              node->getType().getBasicType() == EbtInt64 ||
    554              node->getType().getBasicType() == EbtUint64))
    555 
    556             return node;
    557         else
    558             return 0;
    559 
    560     default:
    561         // default is to require a match; all exceptions should have case statements above
    562 
    563         if (type.getBasicType() == node->getType().getBasicType())
    564             return node;
    565         else
    566             return 0;
    567     }
    568 
    569     if (node->getAsConstantUnion())
    570         return promoteConstantUnion(promoteTo, node->getAsConstantUnion());
    571 
    572     //
    573     // Add a new newNode for the conversion.
    574     //
    575     TIntermUnary* newNode = 0;
    576 
    577     TOperator newOp = EOpNull;
    578 
    579     // This is 'mechanism' here, it does any conversion told.  The policy comes
    580     // from the shader or the above code.
    581     switch (promoteTo) {
    582     case EbtDouble:
    583         switch (node->getBasicType()) {
    584         case EbtInt:   newOp = EOpConvIntToDouble;   break;
    585         case EbtUint:  newOp = EOpConvUintToDouble;  break;
    586         case EbtBool:  newOp = EOpConvBoolToDouble;  break;
    587         case EbtFloat: newOp = EOpConvFloatToDouble; break;
    588         case EbtInt64: newOp = EOpConvInt64ToDouble; break;
    589         case EbtUint64: newOp = EOpConvUint64ToDouble; break;
    590         default:
    591             return 0;
    592         }
    593         break;
    594     case EbtFloat:
    595         switch (node->getBasicType()) {
    596         case EbtInt:    newOp = EOpConvIntToFloat;    break;
    597         case EbtUint:   newOp = EOpConvUintToFloat;   break;
    598         case EbtBool:   newOp = EOpConvBoolToFloat;   break;
    599         case EbtDouble: newOp = EOpConvDoubleToFloat; break;
    600         case EbtInt64:  newOp = EOpConvInt64ToFloat;  break;
    601         case EbtUint64: newOp = EOpConvUint64ToFloat; break;
    602         default:
    603             return 0;
    604         }
    605         break;
    606     case EbtBool:
    607         switch (node->getBasicType()) {
    608         case EbtInt:    newOp = EOpConvIntToBool;    break;
    609         case EbtUint:   newOp = EOpConvUintToBool;   break;
    610         case EbtFloat:  newOp = EOpConvFloatToBool;  break;
    611         case EbtDouble: newOp = EOpConvDoubleToBool; break;
    612         case EbtInt64:  newOp = EOpConvInt64ToBool;  break;
    613         case EbtUint64: newOp = EOpConvUint64ToBool; break;
    614         default:
    615             return 0;
    616         }
    617         break;
    618     case EbtInt:
    619         switch (node->getBasicType()) {
    620         case EbtUint:   newOp = EOpConvUintToInt;   break;
    621         case EbtBool:   newOp = EOpConvBoolToInt;   break;
    622         case EbtFloat:  newOp = EOpConvFloatToInt;  break;
    623         case EbtDouble: newOp = EOpConvDoubleToInt; break;
    624         case EbtInt64:  newOp = EOpConvInt64ToInt;  break;
    625         case EbtUint64: newOp = EOpConvUint64ToInt; break;
    626         default:
    627             return 0;
    628         }
    629         break;
    630     case EbtUint:
    631         switch (node->getBasicType()) {
    632         case EbtInt:    newOp = EOpConvIntToUint;    break;
    633         case EbtBool:   newOp = EOpConvBoolToUint;   break;
    634         case EbtFloat:  newOp = EOpConvFloatToUint;  break;
    635         case EbtDouble: newOp = EOpConvDoubleToUint; break;
    636         case EbtInt64:  newOp = EOpConvInt64ToUint;  break;
    637         case EbtUint64: newOp = EOpConvUint64ToUint; break;
    638         default:
    639             return 0;
    640         }
    641         break;
    642     case EbtInt64:
    643         switch (node->getBasicType()) {
    644         case EbtInt:    newOp = EOpConvIntToInt64;    break;
    645         case EbtUint:   newOp = EOpConvUintToInt64;   break;
    646         case EbtBool:   newOp = EOpConvBoolToInt64;   break;
    647         case EbtFloat:  newOp = EOpConvFloatToInt64;  break;
    648         case EbtDouble: newOp = EOpConvDoubleToInt64; break;
    649         case EbtUint64: newOp = EOpConvUint64ToInt64; break;
    650         default:
    651             return 0;
    652         }
    653         break;
    654     case EbtUint64:
    655         switch (node->getBasicType()) {
    656         case EbtInt:    newOp = EOpConvIntToUint64;    break;
    657         case EbtUint:   newOp = EOpConvUintToUint64;   break;
    658         case EbtBool:   newOp = EOpConvBoolToUint64;   break;
    659         case EbtFloat:  newOp = EOpConvFloatToUint64;  break;
    660         case EbtDouble: newOp = EOpConvDoubleToUint64; break;
    661         case EbtInt64:  newOp = EOpConvInt64ToUint64;  break;
    662         default:
    663             return 0;
    664         }
    665         break;
    666     default:
    667         return 0;
    668     }
    669 
    670     TType newType(promoteTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows());
    671     newNode = new TIntermUnary(newOp, newType);
    672     newNode->setLoc(node->getLoc());
    673     newNode->setOperand(node);
    674 
    675     // TODO: it seems that some unary folding operations should occur here, but are not
    676 
    677     // Propagate specialization-constant-ness, if allowed
    678     if (node->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*newNode))
    679         newNode->getWritableType().getQualifier().makeSpecConstant();
    680 
    681     return newNode;
    682 }
    683 
    684 //
    685 // See if the 'from' type is allowed to be implicitly converted to the
    686 // 'to' type.  This is not about vector/array/struct, only about basic type.
    687 //
    688 bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to) const
    689 {
    690     if (profile == EEsProfile || version == 110)
    691         return false;
    692 
    693     switch (to) {
    694     case EbtDouble:
    695         switch (from) {
    696         case EbtInt:
    697         case EbtUint:
    698         case EbtInt64:
    699         case EbtUint64:
    700         case EbtFloat:
    701         case EbtDouble:
    702             return true;
    703         default:
    704             return false;
    705         }
    706     case EbtFloat:
    707         switch (from) {
    708         case EbtInt:
    709         case EbtUint:
    710         case EbtFloat:
    711             return true;
    712         default:
    713             return false;
    714         }
    715     case EbtUint:
    716         switch (from) {
    717         case EbtInt:
    718             return version >= 400;
    719         case EbtUint:
    720             return true;
    721         default:
    722             return false;
    723         }
    724     case EbtInt:
    725         switch (from) {
    726         case EbtInt:
    727             return true;
    728         default:
    729             return false;
    730         }
    731     case EbtUint64:
    732         switch (from) {
    733         case EbtInt:
    734         case EbtUint:
    735         case EbtInt64:
    736         case EbtUint64:
    737             return true;
    738         default:
    739             return false;
    740         }
    741     case EbtInt64:
    742         switch (from) {
    743         case EbtInt:
    744         case EbtInt64:
    745             return true;
    746         default:
    747             return false;
    748         }
    749     default:
    750         return false;
    751     }
    752 }
    753 
    754 //
    755 // Safe way to combine two nodes into an aggregate.  Works with null pointers,
    756 // a node that's not a aggregate yet, etc.
    757 //
    758 // Returns the resulting aggregate, unless 0 was passed in for
    759 // both existing nodes.
    760 //
    761 TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right)
    762 {
    763     if (left == 0 && right == 0)
    764         return 0;
    765 
    766     TIntermAggregate* aggNode = 0;
    767     if (left)
    768         aggNode = left->getAsAggregate();
    769     if (! aggNode || aggNode->getOp() != EOpNull) {
    770         aggNode = new TIntermAggregate;
    771         if (left)
    772             aggNode->getSequence().push_back(left);
    773     }
    774 
    775     if (right)
    776         aggNode->getSequence().push_back(right);
    777 
    778     return aggNode;
    779 }
    780 
    781 TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc& loc)
    782 {
    783     TIntermAggregate* aggNode = growAggregate(left, right);
    784     if (aggNode)
    785         aggNode->setLoc(loc);
    786 
    787     return aggNode;
    788 }
    789 
    790 //
    791 // Turn an existing node into an aggregate.
    792 //
    793 // Returns an aggregate, unless 0 was passed in for the existing node.
    794 //
    795 TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node)
    796 {
    797     if (node == 0)
    798         return 0;
    799 
    800     TIntermAggregate* aggNode = new TIntermAggregate;
    801     aggNode->getSequence().push_back(node);
    802     aggNode->setLoc(node->getLoc());
    803 
    804     return aggNode;
    805 }
    806 
    807 TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, const TSourceLoc& loc)
    808 {
    809     if (node == 0)
    810         return 0;
    811 
    812     TIntermAggregate* aggNode = new TIntermAggregate;
    813     aggNode->getSequence().push_back(node);
    814     aggNode->setLoc(loc);
    815 
    816     return aggNode;
    817 }
    818 
    819 //
    820 // For "if" test nodes.  There are three children; a condition,
    821 // a true path, and a false path.  The two paths are in the
    822 // nodePair.
    823 //
    824 // Returns the selection node created.
    825 //
    826 TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& loc)
    827 {
    828     //
    829     // Don't prune the false path for compile-time constants; it's needed
    830     // for static access analysis.
    831     //
    832 
    833     TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
    834     node->setLoc(loc);
    835 
    836     return node;
    837 }
    838 
    839 
    840 TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc& loc)
    841 {
    842     // However, the lowest precedence operators of the sequence operator ( , ) and the assignment operators
    843     // ... are not included in the operators that can create a constant expression.
    844     //
    845     //if (left->getType().getQualifier().storage == EvqConst &&
    846     //    right->getType().getQualifier().storage == EvqConst) {
    847 
    848     //    return right;
    849     //}
    850 
    851     TIntermTyped *commaAggregate = growAggregate(left, right, loc);
    852     commaAggregate->getAsAggregate()->setOperator(EOpComma);
    853     commaAggregate->setType(right->getType());
    854     commaAggregate->getWritableType().getQualifier().makeTemporary();
    855 
    856     return commaAggregate;
    857 }
    858 
    859 TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type, const TString* name, const TSourceLoc& loc)
    860 {
    861     TIntermMethod* method = new TIntermMethod(object, type, *name);
    862     method->setLoc(loc);
    863 
    864     return method;
    865 }
    866 
    867 //
    868 // For "?:" test nodes.  There are three children; a condition,
    869 // a true path, and a false path.  The two paths are specified
    870 // as separate parameters.
    871 //
    872 // Returns the selection node created, or 0 if one could not be.
    873 //
    874 TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& loc)
    875 {
    876     //
    877     // Get compatible types.
    878     //
    879     TIntermTyped* child = addConversion(EOpSequence, trueBlock->getType(), falseBlock);
    880     if (child)
    881         falseBlock = child;
    882     else {
    883         child = addConversion(EOpSequence, falseBlock->getType(), trueBlock);
    884         if (child)
    885             trueBlock = child;
    886         else
    887             return 0;
    888     }
    889 
    890     // After conversion, types have to match.
    891     if (falseBlock->getType() != trueBlock->getType())
    892         return 0;
    893 
    894     //
    895     // See if all the operands are constant, then fold it otherwise not.
    896     //
    897 
    898     if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) {
    899         if (cond->getAsConstantUnion()->getConstArray()[0].getBConst())
    900             return trueBlock;
    901         else
    902             return falseBlock;
    903     }
    904 
    905     //
    906     // Make a selection node.
    907     //
    908     TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
    909     node->getQualifier().makeTemporary();
    910     node->setLoc(loc);
    911     node->getQualifier().precision = std::max(trueBlock->getQualifier().precision, falseBlock->getQualifier().precision);
    912 
    913     return node;
    914 }
    915 
    916 //
    917 // Constant terminal nodes.  Has a union that contains bool, float or int constants
    918 //
    919 // Returns the constant union node created.
    920 //
    921 
    922 TIntermConstantUnion* TIntermediate::addConstantUnion(const TConstUnionArray& unionArray, const TType& t, const TSourceLoc& loc, bool literal) const
    923 {
    924     TIntermConstantUnion* node = new TIntermConstantUnion(unionArray, t);
    925     node->getQualifier().storage = EvqConst;
    926     node->setLoc(loc);
    927     if (literal)
    928         node->setLiteral();
    929 
    930     return node;
    931 }
    932 
    933 TIntermConstantUnion* TIntermediate::addConstantUnion(int i, const TSourceLoc& loc, bool literal) const
    934 {
    935     TConstUnionArray unionArray(1);
    936     unionArray[0].setIConst(i);
    937 
    938     return addConstantUnion(unionArray, TType(EbtInt, EvqConst), loc, literal);
    939 }
    940 
    941 TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned int u, const TSourceLoc& loc, bool literal) const
    942 {
    943     TConstUnionArray unionArray(1);
    944     unionArray[0].setUConst(u);
    945 
    946     return addConstantUnion(unionArray, TType(EbtUint, EvqConst), loc, literal);
    947 }
    948 
    949 TIntermConstantUnion* TIntermediate::addConstantUnion(long long i64, const TSourceLoc& loc, bool literal) const
    950 {
    951     TConstUnionArray unionArray(1);
    952     unionArray[0].setI64Const(i64);
    953 
    954     return addConstantUnion(unionArray, TType(EbtInt64, EvqConst), loc, literal);
    955 }
    956 
    957 TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned long long u64, const TSourceLoc& loc, bool literal) const
    958 {
    959     TConstUnionArray unionArray(1);
    960     unionArray[0].setU64Const(u64);
    961 
    962     return addConstantUnion(unionArray, TType(EbtUint64, EvqConst), loc, literal);
    963 }
    964 
    965 TIntermConstantUnion* TIntermediate::addConstantUnion(bool b, const TSourceLoc& loc, bool literal) const
    966 {
    967     TConstUnionArray unionArray(1);
    968     unionArray[0].setBConst(b);
    969 
    970     return addConstantUnion(unionArray, TType(EbtBool, EvqConst), loc, literal);
    971 }
    972 
    973 TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseType, const TSourceLoc& loc, bool literal) const
    974 {
    975     assert(baseType == EbtFloat || baseType == EbtDouble);
    976 
    977     TConstUnionArray unionArray(1);
    978     unionArray[0].setDConst(d);
    979 
    980     return addConstantUnion(unionArray, TType(baseType, EvqConst), loc, literal);
    981 }
    982 
    983 TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, const TSourceLoc& loc)
    984 {
    985     TIntermAggregate* node = new TIntermAggregate(EOpSequence);
    986 
    987     node->setLoc(loc);
    988     TIntermConstantUnion* constIntNode;
    989     TIntermSequence &sequenceVector = node->getSequence();
    990 
    991     for (int i = 0; i < fields.num; i++) {
    992         constIntNode = addConstantUnion(fields.offsets[i], loc);
    993         sequenceVector.push_back(constIntNode);
    994     }
    995 
    996     return node;
    997 }
    998 
    999 //
   1000 // Follow the left branches down to the root of an l-value
   1001 // expression (just "." and []).
   1002 //
   1003 // Return the base of the l-value (where following indexing quits working).
   1004 // Return nullptr if a chain following dereferences cannot be followed.
   1005 //
   1006 // 'swizzleOkay' says whether or not it is okay to consider a swizzle
   1007 // a valid part of the dereference chain.
   1008 //
   1009 const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay)
   1010 {
   1011     do {
   1012         const TIntermBinary* binary = node->getAsBinaryNode();
   1013         if (binary == nullptr)
   1014             return node;
   1015         TOperator op = binary->getOp();
   1016         if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle)
   1017             return nullptr;
   1018         if (! swizzleOkay) {
   1019             if (op == EOpVectorSwizzle)
   1020                 return nullptr;
   1021             if ((op == EOpIndexDirect || op == EOpIndexIndirect) &&
   1022                 (binary->getLeft()->getType().isVector() || binary->getLeft()->getType().isScalar()) &&
   1023                 ! binary->getLeft()->getType().isArray())
   1024                 return nullptr;
   1025         }
   1026         node = node->getAsBinaryNode()->getLeft();
   1027     } while (true);
   1028 }
   1029 
   1030 //
   1031 // Create while and do-while loop nodes.
   1032 //
   1033 TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc)
   1034 {
   1035     TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
   1036     node->setLoc(loc);
   1037 
   1038     return node;
   1039 }
   1040 
   1041 //
   1042 // Create a for-loop sequence.
   1043 //
   1044 TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* initializer, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc)
   1045 {
   1046     TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
   1047     node->setLoc(loc);
   1048 
   1049     // make a sequence of the initializer and statement
   1050     TIntermAggregate* loopSequence = makeAggregate(initializer, loc);
   1051     loopSequence = growAggregate(loopSequence, node);
   1052     loopSequence->setOperator(EOpSequence);
   1053 
   1054     return loopSequence;
   1055 }
   1056 
   1057 //
   1058 // Add branches.
   1059 //
   1060 TIntermBranch* TIntermediate::addBranch(TOperator branchOp, const TSourceLoc& loc)
   1061 {
   1062     return addBranch(branchOp, 0, loc);
   1063 }
   1064 
   1065 TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, const TSourceLoc& loc)
   1066 {
   1067     TIntermBranch* node = new TIntermBranch(branchOp, expression);
   1068     node->setLoc(loc);
   1069 
   1070     return node;
   1071 }
   1072 
   1073 //
   1074 // This is to be executed after the final root is put on top by the parsing
   1075 // process.
   1076 //
   1077 bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/)
   1078 {
   1079     if (root == 0)
   1080         return true;
   1081 
   1082     // Finish off the top-level sequence
   1083     TIntermAggregate* aggRoot = root->getAsAggregate();
   1084     if (aggRoot && aggRoot->getOp() == EOpNull)
   1085         aggRoot->setOperator(EOpSequence);
   1086 
   1087     // Propagate 'noContraction' label in backward from 'precise' variables.
   1088     glslang::PropagateNoContraction(*this);
   1089 
   1090     return true;
   1091 }
   1092 
   1093 void TIntermediate::addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage language, TSymbolTable& symbolTable)
   1094 {
   1095     // Add top-level nodes for declarations that must be checked cross
   1096     // compilation unit by a linker, yet might not have been referenced
   1097     // by the AST.
   1098     //
   1099     // Almost entirely, translation of symbols is driven by what's present
   1100     // in the AST traversal, not by translating the symbol table.
   1101     //
   1102     // However, there are some special cases:
   1103     //  - From the specification: "Special built-in inputs gl_VertexID and
   1104     //    gl_InstanceID are also considered active vertex attributes."
   1105     //  - Linker-based type mismatch error reporting needs to see all
   1106     //    uniforms/ins/outs variables and blocks.
   1107     //  - ftransform() can make gl_Vertex and gl_ModelViewProjectionMatrix active.
   1108     //
   1109 
   1110     //if (ftransformUsed) {
   1111         // TODO: 1.1 lowering functionality: track ftransform() usage
   1112     //    addSymbolLinkageNode(root, symbolTable, "gl_Vertex");
   1113     //    addSymbolLinkageNode(root, symbolTable, "gl_ModelViewProjectionMatrix");
   1114     //}
   1115 
   1116     if (language == EShLangVertex) {
   1117         // the names won't be found in the symbol table unless the versions are right,
   1118         // so version logic does not need to be repeated here
   1119         addSymbolLinkageNode(linkage, symbolTable, "gl_VertexID");
   1120         addSymbolLinkageNode(linkage, symbolTable, "gl_InstanceID");
   1121     }
   1122 
   1123     // Add a child to the root node for the linker objects
   1124     linkage->setOperator(EOpLinkerObjects);
   1125     treeRoot = growAggregate(treeRoot, linkage);
   1126 }
   1127 
   1128 //
   1129 // Add the given name or symbol to the list of nodes at the end of the tree used
   1130 // for link-time checking and external linkage.
   1131 //
   1132 
   1133 void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable& symbolTable, const TString& name)
   1134 {
   1135     TSymbol* symbol = symbolTable.find(name);
   1136     if (symbol)
   1137         addSymbolLinkageNode(linkage, *symbol->getAsVariable());
   1138 }
   1139 
   1140 void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol& symbol)
   1141 {
   1142     const TVariable* variable = symbol.getAsVariable();
   1143     if (! variable) {
   1144         // This must be a member of an anonymous block, and we need to add the whole block
   1145         const TAnonMember* anon = symbol.getAsAnonMember();
   1146         variable = &anon->getAnonContainer();
   1147     }
   1148     TIntermSymbol* node = addSymbol(*variable);
   1149     linkage = growAggregate(linkage, node);
   1150 }
   1151 
   1152 //
   1153 // Add a caller->callee relationship to the call graph.
   1154 // Assumes the strings are unique per signature.
   1155 //
   1156 void TIntermediate::addToCallGraph(TInfoSink& /*infoSink*/, const TString& caller, const TString& callee)
   1157 {
   1158     // Duplicates are okay, but faster to not keep them, and they come grouped by caller,
   1159     // as long as new ones are push on the same end we check on for duplicates
   1160     for (TGraph::const_iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
   1161         if (call->caller != caller)
   1162             break;
   1163         if (call->callee == callee)
   1164             return;
   1165     }
   1166 
   1167     callGraph.push_front(TCall(caller, callee));
   1168 }
   1169 
   1170 //
   1171 // This deletes the tree.
   1172 //
   1173 void TIntermediate::removeTree()
   1174 {
   1175     if (treeRoot)
   1176         RemoveAllTreeNodes(treeRoot);
   1177 }
   1178 
   1179 //
   1180 // Implement the part of KHR_vulkan_glsl that lists the set of operations
   1181 // that can result in a specialization constant operation.
   1182 //
   1183 // "5.x Specialization Constant Operations"
   1184 //
   1185 //    Only some operations discussed in this section may be applied to a
   1186 //    specialization constant and still yield a result that is as
   1187 //    specialization constant.  The operations allowed are listed below.
   1188 //    When a specialization constant is operated on with one of these
   1189 //    operators and with another constant or specialization constant, the
   1190 //    result is implicitly a specialization constant.
   1191 //
   1192 //     - int(), uint(), and bool() constructors for type conversions
   1193 //       from any of the following types to any of the following types:
   1194 //         * int
   1195 //         * uint
   1196 //         * bool
   1197 //     - vector versions of the above conversion constructors
   1198 //     - allowed implicit conversions of the above
   1199 //     - swizzles (e.g., foo.yx)
   1200 //     - The following when applied to integer or unsigned integer types:
   1201 //         * unary negative ( - )
   1202 //         * binary operations ( + , - , * , / , % )
   1203 //         * shift ( <<, >> )
   1204 //         * bitwise operations ( & , | , ^ )
   1205 //     - The following when applied to integer or unsigned integer scalar types:
   1206 //         * comparison ( == , != , > , >= , < , <= )
   1207 //     - The following when applied to the Boolean scalar type:
   1208 //         * not ( ! )
   1209 //         * logical operations ( && , || , ^^ )
   1210 //         * comparison ( == , != )"
   1211 //
   1212 // This function just handles binary and unary nodes.  Construction
   1213 // rules are handled in construction paths that are not covered by the unary
   1214 // and binary paths, while required conversions will still show up here
   1215 // as unary converters in the from a construction operator.
   1216 //
   1217 bool TIntermediate::isSpecializationOperation(const TIntermOperator& node) const
   1218 {
   1219     // The operations resulting in floating point are quite limited
   1220     // (However, some floating-point operations result in bool, like ">",
   1221     // so are handled later.)
   1222     if (node.getType().isFloatingDomain()) {
   1223         switch (node.getOp()) {
   1224         case EOpIndexDirect:
   1225         case EOpIndexIndirect:
   1226         case EOpIndexDirectStruct:
   1227         case EOpVectorSwizzle:
   1228             return true;
   1229         default:
   1230             return false;
   1231         }
   1232     }
   1233 
   1234     // Check for floating-point arguments
   1235     if (const TIntermBinary* bin = node.getAsBinaryNode())
   1236         if (bin->getLeft() ->getType().isFloatingDomain() ||
   1237             bin->getRight()->getType().isFloatingDomain())
   1238             return false;
   1239 
   1240     // So, for now, we can assume everything left is non-floating-point...
   1241 
   1242     // Now check for integer/bool-based operations
   1243     switch (node.getOp()) {
   1244 
   1245     // dereference/swizzle
   1246     case EOpIndexDirect:
   1247     case EOpIndexIndirect:
   1248     case EOpIndexDirectStruct:
   1249     case EOpVectorSwizzle:
   1250 
   1251     // conversion constructors
   1252     case EOpConvIntToBool:
   1253     case EOpConvUintToBool:
   1254     case EOpConvUintToInt:
   1255     case EOpConvBoolToInt:
   1256     case EOpConvIntToUint:
   1257     case EOpConvBoolToUint:
   1258 
   1259     // unary operations
   1260     case EOpNegative:
   1261     case EOpLogicalNot:
   1262     case EOpBitwiseNot:
   1263 
   1264     // binary operations
   1265     case EOpAdd:
   1266     case EOpSub:
   1267     case EOpMul:
   1268     case EOpVectorTimesScalar:
   1269     case EOpDiv:
   1270     case EOpMod:
   1271     case EOpRightShift:
   1272     case EOpLeftShift:
   1273     case EOpAnd:
   1274     case EOpInclusiveOr:
   1275     case EOpExclusiveOr:
   1276     case EOpLogicalOr:
   1277     case EOpLogicalXor:
   1278     case EOpLogicalAnd:
   1279     case EOpEqual:
   1280     case EOpNotEqual:
   1281     case EOpLessThan:
   1282     case EOpGreaterThan:
   1283     case EOpLessThanEqual:
   1284     case EOpGreaterThanEqual:
   1285         return true;
   1286     default:
   1287         return false;
   1288     }
   1289 }
   1290 
   1291 ////////////////////////////////////////////////////////////////
   1292 //
   1293 // Member functions of the nodes used for building the tree.
   1294 //
   1295 ////////////////////////////////////////////////////////////////
   1296 
   1297 //
   1298 // Say whether or not an operation node changes the value of a variable.
   1299 //
   1300 // Returns true if state is modified.
   1301 //
   1302 bool TIntermOperator::modifiesState() const
   1303 {
   1304     switch (op) {
   1305     case EOpPostIncrement:
   1306     case EOpPostDecrement:
   1307     case EOpPreIncrement:
   1308     case EOpPreDecrement:
   1309     case EOpAssign:
   1310     case EOpAddAssign:
   1311     case EOpSubAssign:
   1312     case EOpMulAssign:
   1313     case EOpVectorTimesMatrixAssign:
   1314     case EOpVectorTimesScalarAssign:
   1315     case EOpMatrixTimesScalarAssign:
   1316     case EOpMatrixTimesMatrixAssign:
   1317     case EOpDivAssign:
   1318     case EOpModAssign:
   1319     case EOpAndAssign:
   1320     case EOpInclusiveOrAssign:
   1321     case EOpExclusiveOrAssign:
   1322     case EOpLeftShiftAssign:
   1323     case EOpRightShiftAssign:
   1324         return true;
   1325     default:
   1326         return false;
   1327     }
   1328 }
   1329 
   1330 //
   1331 // returns true if the operator is for one of the constructors
   1332 //
   1333 bool TIntermOperator::isConstructor() const
   1334 {
   1335     return op > EOpConstructGuardStart && op < EOpConstructGuardEnd;
   1336 }
   1337 
   1338 //
   1339 // Make sure the type of a unary operator is appropriate for its
   1340 // combination of operation and operand type.
   1341 //
   1342 // Returns false in nothing makes sense.
   1343 //
   1344 bool TIntermUnary::promote()
   1345 {
   1346     switch (op) {
   1347     case EOpLogicalNot:
   1348         if (operand->getBasicType() != EbtBool)
   1349 
   1350             return false;
   1351         break;
   1352     case EOpBitwiseNot:
   1353         if (operand->getBasicType() != EbtInt &&
   1354             operand->getBasicType() != EbtUint &&
   1355             operand->getBasicType() != EbtInt64 &&
   1356             operand->getBasicType() != EbtUint64)
   1357 
   1358             return false;
   1359         break;
   1360     case EOpNegative:
   1361     case EOpPostIncrement:
   1362     case EOpPostDecrement:
   1363     case EOpPreIncrement:
   1364     case EOpPreDecrement:
   1365         if (operand->getBasicType() != EbtInt &&
   1366             operand->getBasicType() != EbtUint &&
   1367             operand->getBasicType() != EbtInt64 &&
   1368             operand->getBasicType() != EbtUint64 &&
   1369             operand->getBasicType() != EbtFloat &&
   1370             operand->getBasicType() != EbtDouble)
   1371 
   1372             return false;
   1373         break;
   1374 
   1375     default:
   1376         if (operand->getBasicType() != EbtFloat)
   1377 
   1378             return false;
   1379     }
   1380 
   1381     setType(operand->getType());
   1382     getWritableType().getQualifier().makeTemporary();
   1383 
   1384     return true;
   1385 }
   1386 
   1387 void TIntermUnary::updatePrecision()
   1388 {
   1389     if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat) {
   1390         if (operand->getQualifier().precision > getQualifier().precision)
   1391             getQualifier().precision = operand->getQualifier().precision;
   1392     }
   1393 }
   1394 
   1395 //
   1396 // Establishes the type of the resultant operation, as well as
   1397 // makes the operator the correct one for the operands.
   1398 //
   1399 // Returns false if operator can't work on operands.
   1400 //
   1401 bool TIntermBinary::promote()
   1402 {
   1403     // Arrays and structures have to be exact matches.
   1404     if ((left->isArray() || right->isArray() || left->getBasicType() == EbtStruct || right->getBasicType() == EbtStruct)
   1405         && left->getType() != right->getType())
   1406         return false;
   1407 
   1408     // Base assumption:  just make the type the same as the left
   1409     // operand.  Only deviations from this will be coded.
   1410     setType(left->getType());
   1411     type.getQualifier().clear();
   1412 
   1413     // Composite and opaque types don't having pending operator changes, e.g.,
   1414     // array, structure, and samplers.  Just establish final type and correctness.
   1415     if (left->isArray() || left->getBasicType() == EbtStruct || left->getBasicType() == EbtSampler) {
   1416         switch (op) {
   1417         case EOpEqual:
   1418         case EOpNotEqual:
   1419             if (left->getBasicType() == EbtSampler) {
   1420                 // can't compare samplers
   1421                 return false;
   1422             } else {
   1423                 // Promote to conditional
   1424                 setType(TType(EbtBool));
   1425             }
   1426 
   1427             return true;
   1428 
   1429         case EOpAssign:
   1430             // Keep type from above
   1431 
   1432             return true;
   1433 
   1434         default:
   1435             return false;
   1436         }
   1437     }
   1438 
   1439     //
   1440     // We now have only scalars, vectors, and matrices to worry about.
   1441     //
   1442 
   1443     // Do general type checks against individual operands (comparing left and right is coming up, checking mixed shapes after that)
   1444     switch (op) {
   1445     case EOpLessThan:
   1446     case EOpGreaterThan:
   1447     case EOpLessThanEqual:
   1448     case EOpGreaterThanEqual:
   1449         // Relational comparisons need matching numeric types and will promote to scalar Boolean.
   1450         if (left->getBasicType() == EbtBool || left->getType().isVector() || left->getType().isMatrix())
   1451             return false;
   1452 
   1453         // Fall through
   1454 
   1455     case EOpEqual:
   1456     case EOpNotEqual:
   1457         // All the above comparisons result in a bool (but not the vector compares)
   1458         setType(TType(EbtBool));
   1459         break;
   1460 
   1461     case EOpLogicalAnd:
   1462     case EOpLogicalOr:
   1463     case EOpLogicalXor:
   1464         // logical ops operate only on scalar Booleans and will promote to scalar Boolean.
   1465         if (left->getBasicType() != EbtBool || left->isVector() || left->isMatrix())
   1466             return false;
   1467 
   1468         setType(TType(EbtBool));
   1469         break;
   1470 
   1471     case EOpRightShift:
   1472     case EOpLeftShift:
   1473     case EOpRightShiftAssign:
   1474     case EOpLeftShiftAssign:
   1475 
   1476     case EOpMod:
   1477     case EOpModAssign:
   1478 
   1479     case EOpAnd:
   1480     case EOpInclusiveOr:
   1481     case EOpExclusiveOr:
   1482     case EOpAndAssign:
   1483     case EOpInclusiveOrAssign:
   1484     case EOpExclusiveOrAssign:
   1485         // Check for integer-only operands.
   1486         if ((left->getBasicType() != EbtInt &&  left->getBasicType() != EbtUint &&
   1487              left->getBasicType() != EbtInt64 &&  left->getBasicType() != EbtUint64) ||
   1488             (right->getBasicType() != EbtInt && right->getBasicType() != EbtUint &&
   1489              right->getBasicType() != EbtInt64 && right->getBasicType() != EbtUint64))
   1490             return false;
   1491         if (left->isMatrix() || right->isMatrix())
   1492             return false;
   1493 
   1494         break;
   1495 
   1496     case EOpAdd:
   1497     case EOpSub:
   1498     case EOpDiv:
   1499     case EOpMul:
   1500     case EOpAddAssign:
   1501     case EOpSubAssign:
   1502     case EOpMulAssign:
   1503     case EOpDivAssign:
   1504         // check for non-Boolean operands
   1505         if (left->getBasicType() == EbtBool || right->getBasicType() == EbtBool)
   1506             return false;
   1507 
   1508     default:
   1509         break;
   1510     }
   1511 
   1512     // Compare left and right, and finish with the cases where the operand types must match
   1513     switch (op) {
   1514     case EOpLessThan:
   1515     case EOpGreaterThan:
   1516     case EOpLessThanEqual:
   1517     case EOpGreaterThanEqual:
   1518 
   1519     case EOpEqual:
   1520     case EOpNotEqual:
   1521 
   1522     case EOpLogicalAnd:
   1523     case EOpLogicalOr:
   1524     case EOpLogicalXor:
   1525         return left->getType() == right->getType();
   1526 
   1527     // no shifts: they can mix types (scalar int can shift a vector uint, etc.)
   1528 
   1529     case EOpMod:
   1530     case EOpModAssign:
   1531 
   1532     case EOpAnd:
   1533     case EOpInclusiveOr:
   1534     case EOpExclusiveOr:
   1535     case EOpAndAssign:
   1536     case EOpInclusiveOrAssign:
   1537     case EOpExclusiveOrAssign:
   1538 
   1539     case EOpAdd:
   1540     case EOpSub:
   1541     case EOpDiv:
   1542     case EOpAddAssign:
   1543     case EOpSubAssign:
   1544     case EOpDivAssign:
   1545         // Quick out in case the types do match
   1546         if (left->getType() == right->getType())
   1547             return true;
   1548 
   1549         // Fall through
   1550 
   1551     case EOpMul:
   1552     case EOpMulAssign:
   1553         // At least the basic type has to match
   1554         if (left->getBasicType() != right->getBasicType())
   1555             return false;
   1556 
   1557     default:
   1558         break;
   1559     }
   1560 
   1561     // Finish handling the case, for all ops, where both operands are scalars.
   1562     if (left->isScalar() && right->isScalar())
   1563         return true;
   1564 
   1565     // Finish handling the case, for all ops, where there are two vectors of different sizes
   1566     if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize())
   1567         return false;
   1568 
   1569     //
   1570     // We now have a mix of scalars, vectors, or matrices, for non-relational operations.
   1571     //
   1572 
   1573     // Can these two operands be combined, what is the resulting type?
   1574     TBasicType basicType = left->getBasicType();
   1575     switch (op) {
   1576     case EOpMul:
   1577         if (!left->isMatrix() && right->isMatrix()) {
   1578             if (left->isVector()) {
   1579                 if (left->getVectorSize() != right->getMatrixRows())
   1580                     return false;
   1581                 op = EOpVectorTimesMatrix;
   1582                 setType(TType(basicType, EvqTemporary, right->getMatrixCols()));
   1583             } else {
   1584                 op = EOpMatrixTimesScalar;
   1585                 setType(TType(basicType, EvqTemporary, 0, right->getMatrixCols(), right->getMatrixRows()));
   1586             }
   1587         } else if (left->isMatrix() && !right->isMatrix()) {
   1588             if (right->isVector()) {
   1589                 if (left->getMatrixCols() != right->getVectorSize())
   1590                     return false;
   1591                 op = EOpMatrixTimesVector;
   1592                 setType(TType(basicType, EvqTemporary, left->getMatrixRows()));
   1593             } else {
   1594                 op = EOpMatrixTimesScalar;
   1595             }
   1596         } else if (left->isMatrix() && right->isMatrix()) {
   1597             if (left->getMatrixCols() != right->getMatrixRows())
   1598                 return false;
   1599             op = EOpMatrixTimesMatrix;
   1600             setType(TType(basicType, EvqTemporary, 0, right->getMatrixCols(), left->getMatrixRows()));
   1601         } else if (! left->isMatrix() && ! right->isMatrix()) {
   1602             if (left->isVector() && right->isVector()) {
   1603                 ; // leave as component product
   1604             } else if (left->isVector() || right->isVector()) {
   1605                 op = EOpVectorTimesScalar;
   1606                 if (right->isVector())
   1607                     setType(TType(basicType, EvqTemporary, right->getVectorSize()));
   1608             }
   1609         } else {
   1610             return false;
   1611         }
   1612         break;
   1613     case EOpMulAssign:
   1614         if (! left->isMatrix() && right->isMatrix()) {
   1615             if (left->isVector()) {
   1616                 if (left->getVectorSize() != right->getMatrixRows() || left->getVectorSize() != right->getMatrixCols())
   1617                     return false;
   1618                 op = EOpVectorTimesMatrixAssign;
   1619             } else {
   1620                 return false;
   1621             }
   1622         } else if (left->isMatrix() && !right->isMatrix()) {
   1623             if (right->isVector()) {
   1624                 return false;
   1625             } else {
   1626                 op = EOpMatrixTimesScalarAssign;
   1627             }
   1628         } else if (left->isMatrix() && right->isMatrix()) {
   1629             if (left->getMatrixCols() != left->getMatrixRows() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixCols() != right->getMatrixRows())
   1630                 return false;
   1631             op = EOpMatrixTimesMatrixAssign;
   1632         } else if (!left->isMatrix() && !right->isMatrix()) {
   1633             if (left->isVector() && right->isVector()) {
   1634                 // leave as component product
   1635             } else if (left->isVector() || right->isVector()) {
   1636                 if (! left->isVector())
   1637                     return false;
   1638                 op = EOpVectorTimesScalarAssign;
   1639             }
   1640         } else {
   1641             return false;
   1642         }
   1643         break;
   1644 
   1645     case EOpRightShift:
   1646     case EOpLeftShift:
   1647     case EOpRightShiftAssign:
   1648     case EOpLeftShiftAssign:
   1649         if (right->isVector() && (! left->isVector() || right->getVectorSize() != left->getVectorSize()))
   1650             return false;
   1651         break;
   1652 
   1653     case EOpAssign:
   1654         if (left->getVectorSize() != right->getVectorSize() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows())
   1655             return false;
   1656         // fall through
   1657 
   1658     case EOpAdd:
   1659     case EOpSub:
   1660     case EOpDiv:
   1661     case EOpMod:
   1662     case EOpAnd:
   1663     case EOpInclusiveOr:
   1664     case EOpExclusiveOr:
   1665     case EOpAddAssign:
   1666     case EOpSubAssign:
   1667     case EOpDivAssign:
   1668     case EOpModAssign:
   1669     case EOpAndAssign:
   1670     case EOpInclusiveOrAssign:
   1671     case EOpExclusiveOrAssign:
   1672         if ((left->isMatrix() && right->isVector()) ||
   1673             (left->isVector() && right->isMatrix()) ||
   1674             left->getBasicType() != right->getBasicType())
   1675             return false;
   1676         if (left->isMatrix() && right->isMatrix() && (left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows()))
   1677             return false;
   1678         if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize())
   1679             return false;
   1680         if (right->isVector() || right->isMatrix()) {
   1681             type.shallowCopy(right->getType());
   1682             type.getQualifier().makeTemporary();
   1683         }
   1684         break;
   1685 
   1686     default:
   1687         return false;
   1688     }
   1689 
   1690     //
   1691     // One more check for assignment.
   1692     //
   1693     switch (op) {
   1694     // The resulting type has to match the left operand.
   1695     case EOpAssign:
   1696     case EOpAddAssign:
   1697     case EOpSubAssign:
   1698     case EOpMulAssign:
   1699     case EOpDivAssign:
   1700     case EOpModAssign:
   1701     case EOpAndAssign:
   1702     case EOpInclusiveOrAssign:
   1703     case EOpExclusiveOrAssign:
   1704     case EOpLeftShiftAssign:
   1705     case EOpRightShiftAssign:
   1706         if (getType() != left->getType())
   1707             return false;
   1708         break;
   1709     default:
   1710         break;
   1711     }
   1712 
   1713     return true;
   1714 }
   1715 
   1716 void TIntermBinary::updatePrecision()
   1717 {
   1718     if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat) {
   1719         getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision);
   1720         if (getQualifier().precision != EpqNone) {
   1721             left->propagatePrecision(getQualifier().precision);
   1722             right->propagatePrecision(getQualifier().precision);
   1723         }
   1724     }
   1725 }
   1726 
   1727 void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision)
   1728 {
   1729     if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtUint && getBasicType() != EbtFloat))
   1730         return;
   1731 
   1732     getQualifier().precision = newPrecision;
   1733 
   1734     TIntermBinary* binaryNode = getAsBinaryNode();
   1735     if (binaryNode) {
   1736         binaryNode->getLeft()->propagatePrecision(newPrecision);
   1737         binaryNode->getRight()->propagatePrecision(newPrecision);
   1738 
   1739         return;
   1740     }
   1741 
   1742     TIntermUnary* unaryNode = getAsUnaryNode();
   1743     if (unaryNode) {
   1744         unaryNode->getOperand()->propagatePrecision(newPrecision);
   1745 
   1746         return;
   1747     }
   1748 
   1749     TIntermAggregate* aggregateNode = getAsAggregate();
   1750     if (aggregateNode) {
   1751         TIntermSequence operands = aggregateNode->getSequence();
   1752         for (unsigned int i = 0; i < operands.size(); ++i) {
   1753             TIntermTyped* typedNode = operands[i]->getAsTyped();
   1754             if (! typedNode)
   1755                 break;
   1756             typedNode->propagatePrecision(newPrecision);
   1757         }
   1758 
   1759         return;
   1760     }
   1761 
   1762     TIntermSelection* selectionNode = getAsSelectionNode();
   1763     if (selectionNode) {
   1764         TIntermTyped* typedNode = selectionNode->getTrueBlock()->getAsTyped();
   1765         if (typedNode) {
   1766             typedNode->propagatePrecision(newPrecision);
   1767             typedNode = selectionNode->getFalseBlock()->getAsTyped();
   1768             if (typedNode)
   1769                 typedNode->propagatePrecision(newPrecision);
   1770         }
   1771 
   1772         return;
   1773     }
   1774 }
   1775 
   1776 TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) const
   1777 {
   1778     const TConstUnionArray& rightUnionArray = node->getConstArray();
   1779     int size = node->getType().computeNumComponents();
   1780 
   1781     TConstUnionArray leftUnionArray(size);
   1782 
   1783     for (int i=0; i < size; i++) {
   1784         switch (promoteTo) {
   1785         case EbtFloat:
   1786             switch (node->getType().getBasicType()) {
   1787             case EbtInt:
   1788                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getIConst()));
   1789                 break;
   1790             case EbtUint:
   1791                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getUConst()));
   1792                 break;
   1793             case EbtInt64:
   1794                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getI64Const()));
   1795                 break;
   1796             case EbtUint64:
   1797                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getU64Const()));
   1798                 break;
   1799             case EbtBool:
   1800                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst()));
   1801                 break;
   1802             case EbtFloat:
   1803                 leftUnionArray[i] = rightUnionArray[i];
   1804                 break;
   1805             case EbtDouble:
   1806                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getDConst()));
   1807                 break;
   1808             default:
   1809                 return node;
   1810             }
   1811             break;
   1812         case EbtDouble:
   1813             switch (node->getType().getBasicType()) {
   1814             case EbtInt:
   1815                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getIConst()));
   1816                 break;
   1817             case EbtUint:
   1818                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getUConst()));
   1819                 break;
   1820             case EbtInt64:
   1821                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getI64Const()));
   1822                 break;
   1823             case EbtUint64:
   1824                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getU64Const()));
   1825                 break;
   1826             case EbtBool:
   1827                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst()));
   1828                 break;
   1829             case EbtFloat:
   1830             case EbtDouble:
   1831                 leftUnionArray[i] = rightUnionArray[i];
   1832                 break;
   1833             default:
   1834                 return node;
   1835             }
   1836             break;
   1837         case EbtInt:
   1838             switch (node->getType().getBasicType()) {
   1839             case EbtInt:
   1840                 leftUnionArray[i] = rightUnionArray[i];
   1841                 break;
   1842             case EbtUint:
   1843                 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getUConst()));
   1844                 break;
   1845             case EbtInt64:
   1846                 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getI64Const()));
   1847                 break;
   1848             case EbtUint64:
   1849                 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getU64Const()));
   1850                 break;
   1851             case EbtBool:
   1852                 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getBConst()));
   1853                 break;
   1854             case EbtFloat:
   1855             case EbtDouble:
   1856                 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getDConst()));
   1857                 break;
   1858             default:
   1859                 return node;
   1860             }
   1861             break;
   1862         case EbtUint:
   1863             switch (node->getType().getBasicType()) {
   1864             case EbtInt:
   1865                 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getIConst()));
   1866                 break;
   1867             case EbtUint:
   1868                 leftUnionArray[i] = rightUnionArray[i];
   1869                 break;
   1870             case EbtInt64:
   1871                 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getI64Const()));
   1872                 break;
   1873             case EbtUint64:
   1874                 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getU64Const()));
   1875                 break;
   1876             case EbtBool:
   1877                 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getBConst()));
   1878                 break;
   1879             case EbtFloat:
   1880             case EbtDouble:
   1881                 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getDConst()));
   1882                 break;
   1883             default:
   1884                 return node;
   1885             }
   1886             break;
   1887         case EbtBool:
   1888             switch (node->getType().getBasicType()) {
   1889             case EbtInt:
   1890                 leftUnionArray[i].setBConst(rightUnionArray[i].getIConst() != 0);
   1891                 break;
   1892             case EbtUint:
   1893                 leftUnionArray[i].setBConst(rightUnionArray[i].getUConst() != 0);
   1894                 break;
   1895             case EbtInt64:
   1896                 leftUnionArray[i].setBConst(rightUnionArray[i].getI64Const() != 0);
   1897                 break;
   1898             case EbtUint64:
   1899                 leftUnionArray[i].setBConst(rightUnionArray[i].getU64Const() != 0);
   1900                 break;
   1901             case EbtBool:
   1902                 leftUnionArray[i] = rightUnionArray[i];
   1903                 break;
   1904             case EbtFloat:
   1905             case EbtDouble:
   1906                 leftUnionArray[i].setBConst(rightUnionArray[i].getDConst() != 0.0);
   1907                 break;
   1908             default:
   1909                 return node;
   1910             }
   1911             break;
   1912         case EbtInt64:
   1913             switch (node->getType().getBasicType()) {
   1914             case EbtInt:
   1915                 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getIConst()));
   1916                 break;
   1917             case EbtUint:
   1918                 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getUConst()));
   1919                 break;
   1920             case EbtInt64:
   1921                 leftUnionArray[i] = rightUnionArray[i];
   1922                 break;
   1923             case EbtUint64:
   1924                 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getU64Const()));
   1925                 break;
   1926             case EbtBool:
   1927                 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getBConst()));
   1928                 break;
   1929             case EbtFloat:
   1930             case EbtDouble:
   1931                 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getDConst()));
   1932                 break;
   1933             default:
   1934                 return node;
   1935             }
   1936             break;
   1937         case EbtUint64:
   1938             switch (node->getType().getBasicType()) {
   1939             case EbtInt:
   1940                 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getIConst()));
   1941                 break;
   1942             case EbtUint:
   1943                 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getUConst()));
   1944                 break;
   1945             case EbtInt64:
   1946                 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getI64Const()));
   1947                 break;
   1948             case EbtUint64:
   1949                 leftUnionArray[i] = rightUnionArray[i];
   1950                 break;
   1951             case EbtBool:
   1952                 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getBConst()));
   1953                 break;
   1954             case EbtFloat:
   1955             case EbtDouble:
   1956                 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getDConst()));
   1957                 break;
   1958             default:
   1959                 return node;
   1960             }
   1961             break;
   1962         default:
   1963             return node;
   1964         }
   1965     }
   1966 
   1967     const TType& t = node->getType();
   1968 
   1969     return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier().storage, t.getVectorSize(), t.getMatrixCols(), t.getMatrixRows()),
   1970                             node->getLoc());
   1971 }
   1972 
   1973 void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable)
   1974 {
   1975     assert(!pragmaTable);
   1976     pragmaTable = new TPragmaTable();
   1977     *pragmaTable = pTable;
   1978 }
   1979 
   1980 } // end namespace glslang
   1981