Free memory associated with SPIR-V generation.
[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, const 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, const 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 == 0)
193         return 0;
194
195     if (child->getType().getBasicType() == EbtBlock)
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(const 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, const 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, const 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, const 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, const 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, const 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, const 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, const 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, const 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, const 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, const 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, const 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, const 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 // Follow the left branches down to the root of an l-value
865 // expression (just "." and []).
866 //
867 // Return the base of the l-value (where following indexing quits working).
868 // Return nullptr if a chain following dereferences cannot be followed.
869 //
870 // 'swizzleOkay' says whether or not it is okay to consider a swizzle
871 // a valid part of the dereference chain.
872 //
873 const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay)
874 {
875     do {
876         const TIntermBinary* binary = node->getAsBinaryNode();
877         if (binary == nullptr)
878             return node;
879         TOperator op = binary->getOp();
880         if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle)
881             return nullptr;
882         if (! swizzleOkay) {
883             if (op == EOpVectorSwizzle)
884                 return nullptr;
885             if ((op == EOpIndexDirect || op == EOpIndexIndirect) &&
886                 (binary->getLeft()->getType().isVector() || binary->getLeft()->getType().isScalar()) &&
887                 ! binary->getLeft()->getType().isArray())
888                 return nullptr;
889         }
890         node = node->getAsBinaryNode()->getLeft();
891     } while (true);
892 }
893
894 //
895 // Create loop nodes.
896 //
897 TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc)
898 {
899     TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
900     node->setLoc(loc);
901
902     return node;
903 }
904
905 //
906 // Add branches.
907 //
908 TIntermBranch* TIntermediate::addBranch(TOperator branchOp, const TSourceLoc& loc)
909 {
910     return addBranch(branchOp, 0, loc);
911 }
912
913 TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, const TSourceLoc& loc)
914 {
915     TIntermBranch* node = new TIntermBranch(branchOp, expression);
916     node->setLoc(loc);
917
918     return node;
919 }
920
921 //
922 // This is to be executed after the final root is put on top by the parsing
923 // process.
924 //
925 bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/)
926 {
927     if (root == 0)
928         return true;
929
930     // Finish off the top-level sequence
931     TIntermAggregate* aggRoot = root->getAsAggregate();
932     if (aggRoot && aggRoot->getOp() == EOpNull)
933         aggRoot->setOperator(EOpSequence);
934
935     return true;
936 }
937
938 void TIntermediate::addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage language, TSymbolTable& symbolTable)
939 {
940     // Add top-level nodes for declarations that must be checked cross
941     // compilation unit by a linker, yet might not have been referenced
942     // by the AST.
943     //
944     // Almost entirely, translation of symbols is driven by what's present
945     // in the AST traversal, not by translating the symbol table.
946     //
947     // However, there are some special cases:
948     //  - From the specification: "Special built-in inputs gl_VertexID and
949     //    gl_InstanceID are also considered active vertex attributes."
950     //  - Linker-based type mismatch error reporting needs to see all
951     //    uniforms/ins/outs variables and blocks.
952     //  - ftransform() can make gl_Vertex and gl_ModelViewProjectionMatrix active.
953     //
954
955     //if (ftransformUsed) {
956         // TODO: 1.1 lowering functionality: track ftransform() usage
957     //    addSymbolLinkageNode(root, symbolTable, "gl_Vertex");
958     //    addSymbolLinkageNode(root, symbolTable, "gl_ModelViewProjectionMatrix");
959     //}
960
961     if (language == EShLangVertex) {
962         // the names won't be found in the symbol table unless the versions are right,
963         // so version logic does not need to be repeated here
964         addSymbolLinkageNode(linkage, symbolTable, "gl_VertexID");
965         addSymbolLinkageNode(linkage, symbolTable, "gl_InstanceID");
966     }
967
968     // Add a child to the root node for the linker objects
969     linkage->setOperator(EOpLinkerObjects);
970     treeRoot = growAggregate(treeRoot, linkage);
971 }
972
973 //
974 // Add the given name or symbol to the list of nodes at the end of the tree used
975 // for link-time checking and external linkage.
976 //
977
978 void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable& symbolTable, const TString& name)
979 {
980     TSymbol* symbol = symbolTable.find(name);
981     if (symbol)
982         addSymbolLinkageNode(linkage, *symbol->getAsVariable());
983 }
984
985 void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol& symbol)
986 {
987     const TVariable* variable = symbol.getAsVariable();
988     if (! variable) {
989         // This must be a member of an anonymous block, and we need to add the whole block
990         const TAnonMember* anon = symbol.getAsAnonMember();
991         variable = &anon->getAnonContainer();
992     }
993     TIntermSymbol* node = new TIntermSymbol(variable->getUniqueId(), variable->getName(), variable->getType());
994     node->setConstArray(variable->getConstArray());
995     linkage = growAggregate(linkage, node);
996 }
997
998 //
999 // Add a caller->callee relationship to the call graph.
1000 // Assumes the strings are unique per signature.
1001 //
1002 void TIntermediate::addToCallGraph(TInfoSink& /*infoSink*/, const TString& caller, const TString& callee)
1003 {
1004     // Duplicates are okay, but faster to not keep them, and they come grouped by caller,
1005     // as long as new ones are push on the same end we check on for duplicates
1006     for (TGraph::const_iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
1007         if (call->caller != caller)
1008             break;
1009         if (call->callee == callee)
1010             return;
1011     }
1012
1013     callGraph.push_front(TCall(caller, callee));
1014 }
1015
1016 //
1017 // This deletes the tree.
1018 //
1019 void TIntermediate::removeTree()
1020 {
1021     if (treeRoot)
1022         RemoveAllTreeNodes(treeRoot);
1023 }
1024
1025 ////////////////////////////////////////////////////////////////
1026 //
1027 // Member functions of the nodes used for building the tree.
1028 //
1029 ////////////////////////////////////////////////////////////////
1030
1031 //
1032 // Say whether or not an operation node changes the value of a variable.
1033 //
1034 // Returns true if state is modified.
1035 //
1036 bool TIntermOperator::modifiesState() const
1037 {
1038     switch (op) {
1039     case EOpPostIncrement:
1040     case EOpPostDecrement:
1041     case EOpPreIncrement:
1042     case EOpPreDecrement:
1043     case EOpAssign:
1044     case EOpAddAssign:
1045     case EOpSubAssign:
1046     case EOpMulAssign:
1047     case EOpVectorTimesMatrixAssign:
1048     case EOpVectorTimesScalarAssign:
1049     case EOpMatrixTimesScalarAssign:
1050     case EOpMatrixTimesMatrixAssign:
1051     case EOpDivAssign:
1052     case EOpModAssign:
1053     case EOpAndAssign:
1054     case EOpInclusiveOrAssign:
1055     case EOpExclusiveOrAssign:
1056     case EOpLeftShiftAssign:
1057     case EOpRightShiftAssign:
1058         return true;
1059     default:
1060         return false;
1061     }
1062 }
1063
1064 //
1065 // returns true if the operator is for one of the constructors
1066 //
1067 bool TIntermOperator::isConstructor() const
1068 {
1069     return op > EOpConstructGuardStart && op < EOpConstructGuardEnd;
1070 }
1071
1072 //
1073 // Make sure the type of a unary operator is appropriate for its
1074 // combination of operation and operand type.
1075 //
1076 // Returns false in nothing makes sense.
1077 //
1078 bool TIntermUnary::promote()
1079 {
1080     switch (op) {
1081     case EOpLogicalNot:
1082         if (operand->getBasicType() != EbtBool)
1083
1084             return false;
1085         break;
1086     case EOpBitwiseNot:
1087         if (operand->getBasicType() != EbtInt &&
1088             operand->getBasicType() != EbtUint)
1089
1090             return false;
1091         break;
1092     case EOpNegative:
1093     case EOpPostIncrement:
1094     case EOpPostDecrement:
1095     case EOpPreIncrement:
1096     case EOpPreDecrement:
1097         if (operand->getBasicType() != EbtInt &&
1098             operand->getBasicType() != EbtUint &&
1099             operand->getBasicType() != EbtFloat &&
1100             operand->getBasicType() != EbtDouble)
1101
1102             return false;
1103         break;
1104
1105     default:
1106         if (operand->getBasicType() != EbtFloat)
1107
1108             return false;
1109     }
1110
1111     setType(operand->getType());
1112     getWritableType().getQualifier().makeTemporary();
1113
1114     return true;
1115 }
1116
1117 void TIntermUnary::updatePrecision()
1118 {
1119     if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat) {
1120         if (operand->getQualifier().precision > getQualifier().precision)
1121             getQualifier().precision = operand->getQualifier().precision;
1122     }
1123 }
1124
1125 //
1126 // Establishes the type of the resultant operation, as well as
1127 // makes the operator the correct one for the operands.
1128 //
1129 // Returns false if operator can't work on operands.
1130 //
1131 bool TIntermBinary::promote()
1132 {
1133     // Arrays and structures have to be exact matches.
1134     if ((left->isArray() || right->isArray() || left->getBasicType() == EbtStruct || right->getBasicType() == EbtStruct)
1135         && left->getType() != right->getType())
1136         return false;
1137
1138     // Base assumption:  just make the type the same as the left
1139     // operand.  Only deviations from this will be coded.
1140     setType(left->getType());
1141     type.getQualifier().clear();
1142
1143     // Finish all array and structure operations.
1144     if (left->isArray() || left->getBasicType() == EbtStruct) {
1145         switch (op) {
1146         case EOpEqual:
1147         case EOpNotEqual:
1148             // Promote to conditional
1149             setType(TType(EbtBool));
1150
1151             return true;
1152
1153         case EOpAssign:
1154             // Keep type from above
1155
1156             return true;
1157
1158         default:
1159             return false;
1160         }
1161     }
1162
1163     //
1164     // We now have only scalars, vectors, and matrices to worry about.
1165     //
1166
1167     // Do general type checks against individual operands (comparing left and right is coming up, checking mixed shapes after that)
1168     switch (op) {
1169     case EOpLessThan:
1170     case EOpGreaterThan:
1171     case EOpLessThanEqual:
1172     case EOpGreaterThanEqual:
1173         // Relational comparisons need matching numeric types and will promote to scalar Boolean.
1174         if (left->getBasicType() == EbtBool || left->getType().isVector() || left->getType().isMatrix())
1175             return false;
1176
1177         // Fall through
1178
1179     case EOpEqual:
1180     case EOpNotEqual:
1181         // All the above comparisons result in a bool (but not the vector compares)
1182         setType(TType(EbtBool));
1183         break;
1184
1185     case EOpLogicalAnd:
1186     case EOpLogicalOr:
1187     case EOpLogicalXor:
1188         // logical ops operate only on scalar Booleans and will promote to scalar Boolean.
1189         if (left->getBasicType() != EbtBool || left->isVector() || left->isMatrix())
1190             return false;
1191
1192         setType(TType(EbtBool));
1193         break;
1194
1195     case EOpRightShift:
1196     case EOpLeftShift:
1197     case EOpRightShiftAssign:
1198     case EOpLeftShiftAssign:
1199
1200     case EOpMod:
1201     case EOpModAssign:
1202
1203     case EOpAnd:
1204     case EOpInclusiveOr:
1205     case EOpExclusiveOr:
1206     case EOpAndAssign:
1207     case EOpInclusiveOrAssign:
1208     case EOpExclusiveOrAssign:
1209         // Check for integer-only operands.
1210         if (( left->getBasicType() != EbtInt &&  left->getBasicType() != EbtUint) ||
1211             (right->getBasicType() != EbtInt && right->getBasicType() != EbtUint))
1212             return false;
1213         if (left->isMatrix() || right->isMatrix())
1214             return false;
1215
1216         break;
1217
1218     case EOpAdd:
1219     case EOpSub:
1220     case EOpDiv:
1221     case EOpMul:
1222     case EOpAddAssign:
1223     case EOpSubAssign:
1224     case EOpMulAssign:
1225     case EOpDivAssign:
1226         // check for non-Boolean operands
1227         if (left->getBasicType() == EbtBool || right->getBasicType() == EbtBool)
1228             return false;
1229
1230     default:
1231         break;
1232     }
1233
1234     // Compare left and right, and finish with the cases where the operand types must match
1235     switch (op) {
1236     case EOpLessThan:
1237     case EOpGreaterThan:
1238     case EOpLessThanEqual:
1239     case EOpGreaterThanEqual:
1240
1241     case EOpEqual:
1242     case EOpNotEqual:
1243
1244     case EOpLogicalAnd:
1245     case EOpLogicalOr:
1246     case EOpLogicalXor:
1247         return left->getType() == right->getType();
1248
1249     // no shifts: they can mix types (scalar int can shift a vector uint, etc.)
1250
1251     case EOpMod:
1252     case EOpModAssign:
1253
1254     case EOpAnd:
1255     case EOpInclusiveOr:
1256     case EOpExclusiveOr:
1257     case EOpAndAssign:
1258     case EOpInclusiveOrAssign:
1259     case EOpExclusiveOrAssign:
1260
1261     case EOpAdd:
1262     case EOpSub:
1263     case EOpDiv:
1264     case EOpAddAssign:
1265     case EOpSubAssign:
1266     case EOpDivAssign:
1267         // Quick out in case the types do match
1268         if (left->getType() == right->getType())
1269             return true;
1270
1271         // Fall through
1272
1273     case EOpMul:
1274     case EOpMulAssign:
1275         // At least the basic type has to match
1276         if (left->getBasicType() != right->getBasicType())
1277             return false;
1278
1279     default:
1280         break;
1281     }
1282
1283     // Finish handling the case, for all ops, where both operands are scalars.
1284     if (left->isScalar() && right->isScalar())
1285         return true;
1286
1287     // Finish handling the case, for all ops, where there are two vectors of different sizes
1288     if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize())
1289         return false;
1290
1291     //
1292     // We now have a mix of scalars, vectors, or matrices, for non-relational operations.
1293     //
1294
1295     // Can these two operands be combined, what is the resulting type?
1296     TBasicType basicType = left->getBasicType();
1297     switch (op) {
1298     case EOpMul:
1299         if (!left->isMatrix() && right->isMatrix()) {
1300             if (left->isVector()) {
1301                 if (left->getVectorSize() != right->getMatrixRows())
1302                     return false;
1303                 op = EOpVectorTimesMatrix;
1304                 setType(TType(basicType, EvqTemporary, right->getMatrixCols()));
1305             } else {
1306                 op = EOpMatrixTimesScalar;
1307                 setType(TType(basicType, EvqTemporary, 0, right->getMatrixCols(), right->getMatrixRows()));
1308             }
1309         } else if (left->isMatrix() && !right->isMatrix()) {
1310             if (right->isVector()) {
1311                 if (left->getMatrixCols() != right->getVectorSize())
1312                     return false;
1313                 op = EOpMatrixTimesVector;
1314                 setType(TType(basicType, EvqTemporary, left->getMatrixRows()));
1315             } else {
1316                 op = EOpMatrixTimesScalar;
1317             }
1318         } else if (left->isMatrix() && right->isMatrix()) {
1319             if (left->getMatrixCols() != right->getMatrixRows())
1320                 return false;
1321             op = EOpMatrixTimesMatrix;
1322             setType(TType(basicType, EvqTemporary, 0, right->getMatrixCols(), left->getMatrixRows()));
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                 op = EOpVectorTimesScalar;
1328                 if (right->isVector())
1329                     setType(TType(basicType, EvqTemporary, right->getVectorSize()));
1330             }
1331         } else {
1332             return false;
1333         }
1334         break;
1335     case EOpMulAssign:
1336         if (! left->isMatrix() && right->isMatrix()) {
1337             if (left->isVector()) {
1338                 if (left->getVectorSize() != right->getMatrixRows() || left->getVectorSize() != right->getMatrixCols())
1339                     return false;
1340                 op = EOpVectorTimesMatrixAssign;
1341             } else {
1342                 return false;
1343             }
1344         } else if (left->isMatrix() && !right->isMatrix()) {
1345             if (right->isVector()) {
1346                 return false;
1347             } else {
1348                 op = EOpMatrixTimesScalarAssign;
1349             }
1350         } else if (left->isMatrix() && right->isMatrix()) {
1351             if (left->getMatrixCols() != left->getMatrixRows() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixCols() != right->getMatrixRows())
1352                 return false;
1353             op = EOpMatrixTimesMatrixAssign;
1354         } else if (!left->isMatrix() && !right->isMatrix()) {
1355             if (left->isVector() && right->isVector()) {
1356                 // leave as component product
1357             } else if (left->isVector() || right->isVector()) {
1358                 if (! left->isVector())
1359                     return false;
1360                 op = EOpVectorTimesScalarAssign;
1361             }
1362         } else {
1363             return false;
1364         }
1365         break;
1366
1367     case EOpRightShift:
1368     case EOpLeftShift:
1369     case EOpRightShiftAssign:
1370     case EOpLeftShiftAssign:
1371         if (right->isVector() && (! left->isVector() || right->getVectorSize() != left->getVectorSize()))
1372             return false;
1373         break;
1374
1375     case EOpAssign:
1376         if (left->getVectorSize() != right->getVectorSize() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows())
1377             return false;
1378         // fall through
1379
1380     case EOpAdd:
1381     case EOpSub:
1382     case EOpDiv:
1383     case EOpMod:
1384     case EOpAnd:
1385     case EOpInclusiveOr:
1386     case EOpExclusiveOr:
1387     case EOpAddAssign:
1388     case EOpSubAssign:
1389     case EOpDivAssign:
1390     case EOpModAssign:
1391     case EOpAndAssign:
1392     case EOpInclusiveOrAssign:
1393     case EOpExclusiveOrAssign:
1394         if ((left->isMatrix() && right->isVector()) ||
1395             (left->isVector() && right->isMatrix()) ||
1396             left->getBasicType() != right->getBasicType())
1397             return false;
1398         if (left->isMatrix() && right->isMatrix() && (left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows()))
1399             return false;
1400         if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize())
1401             return false;
1402         if (right->isVector() || right->isMatrix())
1403             setType(TType(basicType, EvqTemporary, right->getVectorSize(), right->getMatrixCols(), right->getMatrixRows()));
1404         break;
1405
1406     default:
1407         return false;
1408     }
1409
1410     //
1411     // One more check for assignment.
1412     //
1413     switch (op) {
1414     // The resulting type has to match the left operand.
1415     case EOpAssign:
1416     case EOpAddAssign:
1417     case EOpSubAssign:
1418     case EOpMulAssign:
1419     case EOpDivAssign:
1420     case EOpModAssign:
1421     case EOpAndAssign:
1422     case EOpInclusiveOrAssign:
1423     case EOpExclusiveOrAssign:
1424     case EOpLeftShiftAssign:
1425     case EOpRightShiftAssign:
1426         if (getType() != left->getType())
1427             return false;
1428         break;
1429     default:
1430         break;
1431     }
1432
1433     return true;
1434 }
1435
1436 void TIntermBinary::updatePrecision()
1437 {
1438     if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat) {
1439         getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision);
1440         if (getQualifier().precision != EpqNone) {
1441             left->propagatePrecision(getQualifier().precision);
1442             right->propagatePrecision(getQualifier().precision);
1443         }
1444     }
1445 }
1446
1447 void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision)
1448 {
1449     if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtUint && getBasicType() != EbtFloat))
1450         return;
1451
1452     getQualifier().precision = newPrecision;
1453
1454     TIntermBinary* binaryNode = getAsBinaryNode();
1455     if (binaryNode) {
1456         binaryNode->getLeft()->propagatePrecision(newPrecision);
1457         binaryNode->getRight()->propagatePrecision(newPrecision);
1458
1459         return;
1460     }
1461
1462     TIntermUnary* unaryNode = getAsUnaryNode();
1463     if (unaryNode) {
1464         unaryNode->getOperand()->propagatePrecision(newPrecision);
1465
1466         return;
1467     }
1468
1469     TIntermAggregate* aggregateNode = getAsAggregate();
1470     if (aggregateNode) {
1471         TIntermSequence operands = aggregateNode->getSequence();
1472         for (unsigned int i = 0; i < operands.size(); ++i) {
1473             TIntermTyped* typedNode = operands[i]->getAsTyped();
1474             if (! typedNode)
1475                 break;
1476             typedNode->propagatePrecision(newPrecision);
1477         }
1478
1479         return;
1480     }
1481
1482     TIntermSelection* selectionNode = getAsSelectionNode();
1483     if (selectionNode) {
1484         TIntermTyped* typedNode = selectionNode->getTrueBlock()->getAsTyped();
1485         if (typedNode) {
1486             typedNode->propagatePrecision(newPrecision);
1487             typedNode = selectionNode->getFalseBlock()->getAsTyped();
1488             if (typedNode)
1489                 typedNode->propagatePrecision(newPrecision);
1490         }
1491
1492         return;
1493     }
1494 }
1495
1496 TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) const
1497 {
1498     const TConstUnionArray& rightUnionArray = node->getConstArray();
1499     int size = node->getType().computeNumComponents();
1500
1501     TConstUnionArray leftUnionArray(size);
1502
1503     for (int i=0; i < size; i++) {
1504         switch (promoteTo) {
1505         case EbtFloat:
1506             switch (node->getType().getBasicType()) {
1507             case EbtInt:
1508                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getIConst()));
1509                 break;
1510             case EbtUint:
1511                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getUConst()));
1512                 break;
1513             case EbtBool:
1514                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst()));
1515                 break;
1516             case EbtFloat:
1517                 leftUnionArray[i] = rightUnionArray[i];
1518                 break;
1519             case EbtDouble:
1520                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getDConst()));
1521                 break;
1522             default:
1523                 return node;
1524             }
1525             break;
1526         case EbtDouble:
1527             switch (node->getType().getBasicType()) {
1528             case EbtInt:
1529                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getIConst()));
1530                 break;
1531             case EbtUint:
1532                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getUConst()));
1533                 break;
1534             case EbtBool:
1535                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst()));
1536                 break;
1537             case EbtFloat:
1538             case EbtDouble:
1539                 leftUnionArray[i] = rightUnionArray[i];
1540                 break;
1541             default:
1542                 return node;
1543             }
1544             break;
1545         case EbtInt:
1546             switch (node->getType().getBasicType()) {
1547             case EbtInt:
1548                 leftUnionArray[i] = rightUnionArray[i];
1549                 break;
1550             case EbtUint:
1551                 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getUConst()));
1552                 break;
1553             case EbtBool:
1554                 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getBConst()));
1555                 break;
1556             case EbtFloat:
1557             case EbtDouble:
1558                 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getDConst()));
1559                 break;
1560             default:
1561                 return node;
1562             }
1563             break;
1564         case EbtUint:
1565             switch (node->getType().getBasicType()) {
1566             case EbtInt:
1567                 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getIConst()));
1568                 break;
1569             case EbtUint:
1570                 leftUnionArray[i] = rightUnionArray[i];
1571                 break;
1572             case EbtBool:
1573                 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getBConst()));
1574                 break;
1575             case EbtFloat:
1576             case EbtDouble:
1577                 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getDConst()));
1578                 break;
1579             default:
1580                 return node;
1581             }
1582             break;
1583         case EbtBool:
1584             switch (node->getType().getBasicType()) {
1585             case EbtInt:
1586                 leftUnionArray[i].setBConst(rightUnionArray[i].getIConst() != 0);
1587                 break;
1588             case EbtUint:
1589                 leftUnionArray[i].setBConst(rightUnionArray[i].getUConst() != 0);
1590                 break;
1591             case EbtBool:
1592                 leftUnionArray[i] = rightUnionArray[i];
1593                 break;
1594             case EbtFloat:
1595             case EbtDouble:
1596                 leftUnionArray[i].setBConst(rightUnionArray[i].getDConst() != 0.0);
1597                 break;
1598             default:
1599                 return node;
1600             }
1601             break;
1602         default:
1603             return node;
1604         }
1605     }
1606
1607     const TType& t = node->getType();
1608
1609     return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier().storage, t.getVectorSize(), t.getMatrixCols(), t.getMatrixRows()),
1610                             node->getLoc());
1611 }
1612
1613 void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable)
1614 {
1615     assert(!pragmaTable);
1616
1617     // We allocate this with the thread-pool allocator because the destructors
1618     // for TIntermNode's are never called. When TIntermNodes are no longer
1619     // needed, the pool allocator destroys all memory at once without
1620     // destruction.
1621     void* memory = GetThreadPoolAllocator().allocate(sizeof(TPragmaTable));
1622     pragmaTable = new(memory) TPragmaTable();
1623     *pragmaTable = pTable;
1624 }
1625
1626 } // end namespace glslang