2 //Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
3 //Copyright (C) 2012-2013 LunarG, Inc.
7 //Redistribution and use in source and binary forms, with or without
8 //modification, are permitted provided that the following conditions
11 // Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
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.
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.
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.
38 // Build the intermediate representation.
41 #include "localintermediate.h"
42 #include "RemoveTree.h"
43 #include "SymbolTable.h"
49 ////////////////////////////////////////////////////////////////////////////
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.
55 /////////////////////////////////////////////////////////////////////////////
58 // Add a terminal node for an identifier in an expression.
60 // Returns the added node.
62 TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, const TSourceLoc& loc)
64 TIntermSymbol* node = new TIntermSymbol(id, name, type);
70 TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable, const TSourceLoc& loc)
72 return addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), loc);
76 // Connect two nodes with a new parent that does a binary operation on the nodes.
78 // Returns the added node.
80 TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc)
82 // No operations work on blocks
83 if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock)
86 // Try converting the children's base types to compatible types.
87 TIntermTyped* child = addConversion(op, left->getType(), right);
91 child = addConversion(op, right->getType(), left);
99 // Need a new node holding things together. Make
100 // one and promote it to the right type.
102 TIntermBinary* node = new TIntermBinary(op);
104 loc = right->getLoc();
108 node->setRight(right);
109 if (! node->promote())
112 node->updatePrecision();
115 // If they are both constants, they must be folded.
116 // (Unless it's the sequence (comma) operator, but that's handled in addComma().)
119 TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
120 TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
121 if (leftTempConstant && rightTempConstant) {
122 TIntermTyped* folded = leftTempConstant->fold(node->getOp(), rightTempConstant);
131 // Connect two nodes through an assignment.
133 // Returns the added node.
135 TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc)
137 // No block assignment
138 if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock)
142 // Like adding binary math, except the conversion can only go
143 // from right to left.
145 TIntermBinary* node = new TIntermBinary(op);
147 loc = left->getLoc();
150 TIntermTyped* child = addConversion(op, left->getType(), right);
155 node->setRight(child);
156 if (! node->promote())
159 node->updatePrecision();
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.
168 // Returns the added node.
169 // The caller should set the type of the returned node.
171 TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc loc)
173 TIntermBinary* node = new TIntermBinary(op);
175 loc = index->getLoc();
178 node->setRight(index);
180 // caller should set the type
186 // Add one node as the parent of another that it operates on.
188 // Returns the added node.
190 TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSourceLoc loc)
195 if (child->getType().getBasicType() == EbtBlock)
200 if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) {
205 case EOpPostIncrement:
206 case EOpPreIncrement:
207 case EOpPostDecrement:
208 case EOpPreDecrement:
210 if (child->getType().getBasicType() == EbtStruct || child->getType().isArray())
212 default: break; // some compilers want this
216 // Do we need to promote the operand?
218 TBasicType newType = EbtVoid;
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
228 if (newType != EbtVoid) {
229 child = addConversion(op, TType(newType, EvqTemporary, child->getVectorSize(),
230 child->getMatrixCols(),
231 child->getMatrixRows()),
238 // For constructors, we are now done, it was all in the conversion.
241 case EOpConstructInt:
242 case EOpConstructUint:
243 case EOpConstructBool:
244 case EOpConstructFloat:
245 case EOpConstructDouble:
247 default: break; // some compilers want this
251 // Make a new node for the operator.
253 TIntermUnary* node = new TIntermUnary(op);
255 loc = child->getLoc();
257 node->setOperand(child);
259 if (! node->promote())
262 node->updatePrecision();
264 if (child->getAsConstantUnion())
265 return child->getAsConstantUnion()->fold(op, node->getType());
270 TIntermTyped* TIntermediate::addBuiltInFunctionCall(const TSourceLoc& loc, TOperator op, bool unary, TIntermNode* childNode, const TType& returnType)
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).
278 TIntermTyped* child = childNode->getAsTyped();
282 if (child->getAsConstantUnion()) {
283 TIntermTyped* folded = child->getAsConstantUnion()->fold(op, returnType);
288 TIntermUnary* node = new TIntermUnary(op);
289 node->setLoc(child->getLoc());
290 node->setOperand(child);
291 node->setType(returnType);
293 // propagate precision up from child
294 if (profile == EEsProfile && returnType.getQualifier().precision == EpqNone && returnType.getBasicType() != EbtBool)
295 node->getQualifier().precision = child->getQualifier().precision;
297 // propagate precision down to child
298 if (node->getQualifier().precision != EpqNone)
299 child->propagatePrecision(node->getQualifier().precision);
303 // setAggregateOperater() calls fold() for constant folding
304 TIntermTyped* node = setAggregateOperator(childNode, op, returnType, loc);
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);
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);
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.
333 // Returns an aggregate node, which could be the one passed in if
334 // it was already an aggregate.
336 TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type, TSourceLoc loc)
338 TIntermAggregate* aggNode;
341 // Make sure we have an aggregate. If not turn it into one.
344 aggNode = node->getAsAggregate();
345 if (aggNode == 0 || aggNode->getOp() != EOpNull) {
347 // Make an aggregate containing this node.
349 aggNode = new TIntermAggregate();
350 aggNode->getSequence().push_back(node);
352 loc = node->getLoc();
355 aggNode = new TIntermAggregate();
360 aggNode->setOperator(op);
362 aggNode->setLoc(loc);
364 aggNode->setType(type);
366 return fold(aggNode);
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.
374 // Returns a node representing the conversion, which could be the same
375 // node passed in if no conversion was needed.
377 // Return 0 if a conversion can't be done.
379 TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node) const
382 // Does the base type allow operation?
384 switch (node->getBasicType()) {
389 if (op != EOpFunctionCall)
397 // Otherwise, if types are identical, no problem
399 if (type == node->getType())
403 // If one's a structure, then no conversions.
405 if (type.isStruct() || node->isStruct())
409 // If one's an array, then no conversions.
411 if (type.isArray() || node->getType().isArray())
414 // Note: callers are responsible for other aspects of shape,
415 // like vector and matrix sizes.
417 TBasicType promoteTo;
421 // Explicit conversions (unary operations)
423 case EOpConstructBool:
426 case EOpConstructFloat:
427 promoteTo = EbtFloat;
429 case EOpConstructDouble:
430 promoteTo = EbtDouble;
432 case EOpConstructInt:
435 case EOpConstructUint:
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.
445 case EOpLessThanEqual:
446 case EOpGreaterThanEqual:
455 case EOpVectorTimesScalar:
456 case EOpVectorTimesMatrix:
457 case EOpMatrixTimesVector:
458 case EOpMatrixTimesScalar:
460 case EOpFunctionCall:
466 case EOpVectorTimesScalarAssign:
467 case EOpMatrixTimesScalarAssign:
472 case EOpConstructStruct:
474 if (type.getBasicType() == node->getType().getBasicType())
477 if (canImplicitlyPromote(node->getType().getBasicType(), type.getBasicType()))
478 promoteTo = type.getBasicType();
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.
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))
501 // default is to require a match; all exceptions should have case statements above
503 if (type.getBasicType() == node->getType().getBasicType())
509 if (node->getAsConstantUnion())
510 return promoteConstantUnion(promoteTo, node->getAsConstantUnion());
513 // Add a new newNode for the conversion.
515 TIntermUnary* newNode = 0;
517 TOperator newOp = EOpNull;
519 // This is 'mechanism' here, it does any conversion told. The policy comes
520 // from the shader or the above code.
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;
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;
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;
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;
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;
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);
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.
588 bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to) const
590 if (profile == EEsProfile || version == 110)
616 return version >= 400;
635 // Safe way to combine two nodes into an aggregate. Works with null pointers,
636 // a node that's not a aggregate yet, etc.
638 // Returns the resulting aggregate, unless 0 was passed in for
639 // both existing nodes.
641 TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right)
643 if (left == 0 && right == 0)
646 TIntermAggregate* aggNode = 0;
648 aggNode = left->getAsAggregate();
649 if (! aggNode || aggNode->getOp() != EOpNull) {
650 aggNode = new TIntermAggregate;
652 aggNode->getSequence().push_back(left);
656 aggNode->getSequence().push_back(right);
661 TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc& loc)
663 TIntermAggregate* aggNode = growAggregate(left, right);
665 aggNode->setLoc(loc);
671 // Turn an existing node into an aggregate.
673 // Returns an aggregate, unless 0 was passed in for the existing node.
675 TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node)
680 TIntermAggregate* aggNode = new TIntermAggregate;
681 aggNode->getSequence().push_back(node);
682 aggNode->setLoc(node->getLoc());
687 TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, const TSourceLoc& loc)
692 TIntermAggregate* aggNode = new TIntermAggregate;
693 aggNode->getSequence().push_back(node);
694 aggNode->setLoc(loc);
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
704 // Returns the selection node created.
706 TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& loc)
709 // Don't prune the false path for compile-time constants; it's needed
710 // for static access analysis.
713 TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
720 TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc& loc)
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.
725 //if (left->getType().getQualifier().storage == EvqConst &&
726 // right->getType().getQualifier().storage == EvqConst) {
731 TIntermTyped *commaAggregate = growAggregate(left, right, loc);
732 commaAggregate->getAsAggregate()->setOperator(EOpComma);
733 commaAggregate->setType(right->getType());
734 commaAggregate->getWritableType().getQualifier().makeTemporary();
736 return commaAggregate;
739 TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type, const TString* name, const TSourceLoc& loc)
741 TIntermMethod* method = new TIntermMethod(object, type, *name);
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.
752 // Returns the selection node created, or 0 if one could not be.
754 TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& loc)
757 // Get compatible types.
759 TIntermTyped* child = addConversion(EOpSequence, trueBlock->getType(), falseBlock);
763 child = addConversion(EOpSequence, falseBlock->getType(), trueBlock);
770 // After conversion, types have to match.
771 if (falseBlock->getType() != trueBlock->getType())
775 // See if all the operands are constant, then fold it otherwise not.
778 if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) {
779 if (cond->getAsConstantUnion()->getConstArray()[0].getBConst())
786 // Make a selection node.
788 TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
789 node->getQualifier().storage = EvqTemporary;
791 node->getQualifier().precision = std::max(trueBlock->getQualifier().precision, falseBlock->getQualifier().precision);
797 // Constant terminal nodes. Has a union that contains bool, float or int constants
799 // Returns the constant union node created.
802 TIntermConstantUnion* TIntermediate::addConstantUnion(const TConstUnionArray& unionArray, const TType& t, const TSourceLoc& loc, bool literal) const
804 TIntermConstantUnion* node = new TIntermConstantUnion(unionArray, t);
812 TIntermConstantUnion* TIntermediate::addConstantUnion(int i, const TSourceLoc& loc, bool literal) const
814 TConstUnionArray unionArray(1);
815 unionArray[0].setIConst(i);
817 return addConstantUnion(unionArray, TType(EbtInt, EvqConst), loc, literal);
820 TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned int u, const TSourceLoc& loc, bool literal) const
822 TConstUnionArray unionArray(1);
823 unionArray[0].setUConst(u);
825 return addConstantUnion(unionArray, TType(EbtUint, EvqConst), loc, literal);
828 TIntermConstantUnion* TIntermediate::addConstantUnion(bool b, const TSourceLoc& loc, bool literal) const
830 TConstUnionArray unionArray(1);
831 unionArray[0].setBConst(b);
833 return addConstantUnion(unionArray, TType(EbtBool, EvqConst), loc, literal);
836 TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseType, const TSourceLoc& loc, bool literal) const
838 assert(baseType == EbtFloat || baseType == EbtDouble);
840 TConstUnionArray unionArray(1);
841 unionArray[0].setDConst(d);
843 return addConstantUnion(unionArray, TType(baseType, EvqConst), loc, literal);
846 TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, const TSourceLoc& loc)
849 TIntermAggregate* node = new TIntermAggregate(EOpSequence);
852 TIntermConstantUnion* constIntNode;
853 TIntermSequence &sequenceVector = node->getSequence();
855 for (int i = 0; i < fields.num; i++) {
856 constIntNode = addConstantUnion(fields.offsets[i], loc);
857 sequenceVector.push_back(constIntNode);
864 // Follow the left branches down to the root of an l-value
865 // expression (just "." and []).
867 // Return the base of the l-value (where following indexing quits working).
868 // Return nullptr if a chain following dereferences cannot be followed.
870 // 'swizzleOkay' says whether or not it is okay to consider a swizzle
871 // a valid part of the dereference chain.
873 const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay)
876 const TIntermBinary* binary = node->getAsBinaryNode();
877 if (binary == nullptr)
879 TOperator op = binary->getOp();
880 if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle)
883 if (op == EOpVectorSwizzle)
885 if ((op == EOpIndexDirect || op == EOpIndexIndirect) &&
886 (binary->getLeft()->getType().isVector() || binary->getLeft()->getType().isScalar()) &&
887 ! binary->getLeft()->getType().isArray())
890 node = node->getAsBinaryNode()->getLeft();
895 // Create loop nodes.
897 TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc)
899 TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
908 TIntermBranch* TIntermediate::addBranch(TOperator branchOp, const TSourceLoc& loc)
910 return addBranch(branchOp, 0, loc);
913 TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, const TSourceLoc& loc)
915 TIntermBranch* node = new TIntermBranch(branchOp, expression);
922 // This is to be executed after the final root is put on top by the parsing
925 bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/)
930 // Finish off the top-level sequence
931 TIntermAggregate* aggRoot = root->getAsAggregate();
932 if (aggRoot && aggRoot->getOp() == EOpNull)
933 aggRoot->setOperator(EOpSequence);
938 void TIntermediate::addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage language, TSymbolTable& symbolTable)
940 // Add top-level nodes for declarations that must be checked cross
941 // compilation unit by a linker, yet might not have been referenced
944 // Almost entirely, translation of symbols is driven by what's present
945 // in the AST traversal, not by translating the symbol table.
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.
955 //if (ftransformUsed) {
956 // TODO: 1.1 lowering functionality: track ftransform() usage
957 // addSymbolLinkageNode(root, symbolTable, "gl_Vertex");
958 // addSymbolLinkageNode(root, symbolTable, "gl_ModelViewProjectionMatrix");
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");
968 // Add a child to the root node for the linker objects
969 linkage->setOperator(EOpLinkerObjects);
970 treeRoot = growAggregate(treeRoot, linkage);
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.
978 void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable& symbolTable, const TString& name)
980 TSymbol* symbol = symbolTable.find(name);
982 addSymbolLinkageNode(linkage, *symbol->getAsVariable());
985 void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol& symbol)
987 const TVariable* variable = symbol.getAsVariable();
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();
993 TIntermSymbol* node = new TIntermSymbol(variable->getUniqueId(), variable->getName(), variable->getType());
994 node->setConstArray(variable->getConstArray());
995 linkage = growAggregate(linkage, node);
999 // Add a caller->callee relationship to the call graph.
1000 // Assumes the strings are unique per signature.
1002 void TIntermediate::addToCallGraph(TInfoSink& /*infoSink*/, const TString& caller, const TString& callee)
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)
1009 if (call->callee == callee)
1013 callGraph.push_front(TCall(caller, callee));
1017 // This deletes the tree.
1019 void TIntermediate::removeTree()
1022 RemoveAllTreeNodes(treeRoot);
1025 ////////////////////////////////////////////////////////////////
1027 // Member functions of the nodes used for building the tree.
1029 ////////////////////////////////////////////////////////////////
1032 // Say whether or not an operation node changes the value of a variable.
1034 // Returns true if state is modified.
1036 bool TIntermOperator::modifiesState() const
1039 case EOpPostIncrement:
1040 case EOpPostDecrement:
1041 case EOpPreIncrement:
1042 case EOpPreDecrement:
1047 case EOpVectorTimesMatrixAssign:
1048 case EOpVectorTimesScalarAssign:
1049 case EOpMatrixTimesScalarAssign:
1050 case EOpMatrixTimesMatrixAssign:
1054 case EOpInclusiveOrAssign:
1055 case EOpExclusiveOrAssign:
1056 case EOpLeftShiftAssign:
1057 case EOpRightShiftAssign:
1065 // returns true if the operator is for one of the constructors
1067 bool TIntermOperator::isConstructor() const
1069 return op > EOpConstructGuardStart && op < EOpConstructGuardEnd;
1073 // Make sure the type of a unary operator is appropriate for its
1074 // combination of operation and operand type.
1076 // Returns false in nothing makes sense.
1078 bool TIntermUnary::promote()
1082 if (operand->getBasicType() != EbtBool)
1087 if (operand->getBasicType() != EbtInt &&
1088 operand->getBasicType() != EbtUint)
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)
1106 if (operand->getBasicType() != EbtFloat)
1111 setType(operand->getType());
1112 getWritableType().getQualifier().makeTemporary();
1117 void TIntermUnary::updatePrecision()
1119 if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat) {
1120 if (operand->getQualifier().precision > getQualifier().precision)
1121 getQualifier().precision = operand->getQualifier().precision;
1126 // Establishes the type of the resultant operation, as well as
1127 // makes the operator the correct one for the operands.
1129 // Returns false if operator can't work on operands.
1131 bool TIntermBinary::promote()
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())
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();
1143 // Finish all array and structure operations.
1144 if (left->isArray() || left->getBasicType() == EbtStruct) {
1148 // Promote to conditional
1149 setType(TType(EbtBool));
1154 // Keep type from above
1164 // We now have only scalars, vectors, and matrices to worry about.
1167 // Do general type checks against individual operands (comparing left and right is coming up, checking mixed shapes after that)
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())
1181 // All the above comparisons result in a bool (but not the vector compares)
1182 setType(TType(EbtBool));
1188 // logical ops operate only on scalar Booleans and will promote to scalar Boolean.
1189 if (left->getBasicType() != EbtBool || left->isVector() || left->isMatrix())
1192 setType(TType(EbtBool));
1197 case EOpRightShiftAssign:
1198 case EOpLeftShiftAssign:
1204 case EOpInclusiveOr:
1205 case EOpExclusiveOr:
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))
1213 if (left->isMatrix() || right->isMatrix())
1226 // check for non-Boolean operands
1227 if (left->getBasicType() == EbtBool || right->getBasicType() == EbtBool)
1234 // Compare left and right, and finish with the cases where the operand types must match
1237 case EOpGreaterThan:
1238 case EOpLessThanEqual:
1239 case EOpGreaterThanEqual:
1247 return left->getType() == right->getType();
1249 // no shifts: they can mix types (scalar int can shift a vector uint, etc.)
1255 case EOpInclusiveOr:
1256 case EOpExclusiveOr:
1258 case EOpInclusiveOrAssign:
1259 case EOpExclusiveOrAssign:
1267 // Quick out in case the types do match
1268 if (left->getType() == right->getType())
1275 // At least the basic type has to match
1276 if (left->getBasicType() != right->getBasicType())
1283 // Finish handling the case, for all ops, where both operands are scalars.
1284 if (left->isScalar() && right->isScalar())
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())
1292 // We now have a mix of scalars, vectors, or matrices, for non-relational operations.
1295 // Can these two operands be combined, what is the resulting type?
1296 TBasicType basicType = left->getBasicType();
1299 if (!left->isMatrix() && right->isMatrix()) {
1300 if (left->isVector()) {
1301 if (left->getVectorSize() != right->getMatrixRows())
1303 op = EOpVectorTimesMatrix;
1304 setType(TType(basicType, EvqTemporary, right->getMatrixCols()));
1306 op = EOpMatrixTimesScalar;
1307 setType(TType(basicType, EvqTemporary, 0, right->getMatrixCols(), right->getMatrixRows()));
1309 } else if (left->isMatrix() && !right->isMatrix()) {
1310 if (right->isVector()) {
1311 if (left->getMatrixCols() != right->getVectorSize())
1313 op = EOpMatrixTimesVector;
1314 setType(TType(basicType, EvqTemporary, left->getMatrixRows()));
1316 op = EOpMatrixTimesScalar;
1318 } else if (left->isMatrix() && right->isMatrix()) {
1319 if (left->getMatrixCols() != right->getMatrixRows())
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()));
1336 if (! left->isMatrix() && right->isMatrix()) {
1337 if (left->isVector()) {
1338 if (left->getVectorSize() != right->getMatrixRows() || left->getVectorSize() != right->getMatrixCols())
1340 op = EOpVectorTimesMatrixAssign;
1344 } else if (left->isMatrix() && !right->isMatrix()) {
1345 if (right->isVector()) {
1348 op = EOpMatrixTimesScalarAssign;
1350 } else if (left->isMatrix() && right->isMatrix()) {
1351 if (left->getMatrixCols() != left->getMatrixRows() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixCols() != right->getMatrixRows())
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())
1360 op = EOpVectorTimesScalarAssign;
1369 case EOpRightShiftAssign:
1370 case EOpLeftShiftAssign:
1371 if (right->isVector() && (! left->isVector() || right->getVectorSize() != left->getVectorSize()))
1376 if (left->getVectorSize() != right->getVectorSize() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows())
1385 case EOpInclusiveOr:
1386 case EOpExclusiveOr:
1392 case EOpInclusiveOrAssign:
1393 case EOpExclusiveOrAssign:
1394 if ((left->isMatrix() && right->isVector()) ||
1395 (left->isVector() && right->isMatrix()) ||
1396 left->getBasicType() != right->getBasicType())
1398 if (left->isMatrix() && right->isMatrix() && (left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows()))
1400 if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize())
1402 if (right->isVector() || right->isMatrix())
1403 setType(TType(basicType, EvqTemporary, right->getVectorSize(), right->getMatrixCols(), right->getMatrixRows()));
1411 // One more check for assignment.
1414 // The resulting type has to match the left operand.
1422 case EOpInclusiveOrAssign:
1423 case EOpExclusiveOrAssign:
1424 case EOpLeftShiftAssign:
1425 case EOpRightShiftAssign:
1426 if (getType() != left->getType())
1436 void TIntermBinary::updatePrecision()
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);
1447 void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision)
1449 if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtUint && getBasicType() != EbtFloat))
1452 getQualifier().precision = newPrecision;
1454 TIntermBinary* binaryNode = getAsBinaryNode();
1456 binaryNode->getLeft()->propagatePrecision(newPrecision);
1457 binaryNode->getRight()->propagatePrecision(newPrecision);
1462 TIntermUnary* unaryNode = getAsUnaryNode();
1464 unaryNode->getOperand()->propagatePrecision(newPrecision);
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();
1476 typedNode->propagatePrecision(newPrecision);
1482 TIntermSelection* selectionNode = getAsSelectionNode();
1483 if (selectionNode) {
1484 TIntermTyped* typedNode = selectionNode->getTrueBlock()->getAsTyped();
1486 typedNode->propagatePrecision(newPrecision);
1487 typedNode = selectionNode->getFalseBlock()->getAsTyped();
1489 typedNode->propagatePrecision(newPrecision);
1496 TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) const
1498 const TConstUnionArray& rightUnionArray = node->getConstArray();
1499 int size = node->getType().computeNumComponents();
1501 TConstUnionArray leftUnionArray(size);
1503 for (int i=0; i < size; i++) {
1504 switch (promoteTo) {
1506 switch (node->getType().getBasicType()) {
1508 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getIConst()));
1511 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getUConst()));
1514 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst()));
1517 leftUnionArray[i] = rightUnionArray[i];
1520 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getDConst()));
1527 switch (node->getType().getBasicType()) {
1529 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getIConst()));
1532 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getUConst()));
1535 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst()));
1539 leftUnionArray[i] = rightUnionArray[i];
1546 switch (node->getType().getBasicType()) {
1548 leftUnionArray[i] = rightUnionArray[i];
1551 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getUConst()));
1554 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getBConst()));
1558 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getDConst()));
1565 switch (node->getType().getBasicType()) {
1567 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getIConst()));
1570 leftUnionArray[i] = rightUnionArray[i];
1573 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getBConst()));
1577 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getDConst()));
1584 switch (node->getType().getBasicType()) {
1586 leftUnionArray[i].setBConst(rightUnionArray[i].getIConst() != 0);
1589 leftUnionArray[i].setBConst(rightUnionArray[i].getUConst() != 0);
1592 leftUnionArray[i] = rightUnionArray[i];
1596 leftUnionArray[i].setBConst(rightUnionArray[i].getDConst() != 0.0);
1607 const TType& t = node->getType();
1609 return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier().storage, t.getVectorSize(), t.getMatrixCols(), t.getMatrixRows()),
1613 void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable)
1615 assert(!pragmaTable);
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
1621 void* memory = GetThreadPoolAllocator().allocate(sizeof(TPragmaTable));
1622 pragmaTable = new(memory) TPragmaTable();
1623 *pragmaTable = pTable;
1626 } // end namespace glslang