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