2 // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
8 // Build the intermediate representation.
15 #include "compiler/translator/HashNames.h"
16 #include "compiler/translator/IntermNode.h"
17 #include "compiler/translator/SymbolTable.h"
22 TPrecision GetHigherPrecision(TPrecision left, TPrecision right)
24 return left > right ? left : right;
27 bool ValidateMultiplication(TOperator op, const TType &left, const TType &right)
33 return left.getNominalSize() == right.getNominalSize() &&
34 left.getSecondarySize() == right.getSecondarySize();
35 case EOpVectorTimesScalar:
36 case EOpVectorTimesScalarAssign:
38 case EOpVectorTimesMatrix:
39 return left.getNominalSize() == right.getRows();
40 case EOpVectorTimesMatrixAssign:
41 return left.getNominalSize() == right.getRows() &&
42 left.getNominalSize() == right.getCols();
43 case EOpMatrixTimesVector:
44 return left.getCols() == right.getNominalSize();
45 case EOpMatrixTimesScalar:
46 case EOpMatrixTimesScalarAssign:
48 case EOpMatrixTimesMatrix:
49 return left.getCols() == right.getRows();
50 case EOpMatrixTimesMatrixAssign:
51 return left.getCols() == right.getCols() &&
52 left.getRows() == right.getRows();
60 bool CompareStructure(const TType& leftNodeType,
61 ConstantUnion *rightUnionArray,
62 ConstantUnion *leftUnionArray);
64 bool CompareStruct(const TType &leftNodeType,
65 ConstantUnion *rightUnionArray,
66 ConstantUnion *leftUnionArray)
68 const TFieldList &fields = leftNodeType.getStruct()->fields();
70 size_t structSize = fields.size();
73 for (size_t j = 0; j < structSize; j++)
75 size_t size = fields[j]->type()->getObjectSize();
76 for (size_t i = 0; i < size; i++)
78 if (fields[j]->type()->getBasicType() == EbtStruct)
80 if (!CompareStructure(*fields[j]->type(),
81 &rightUnionArray[index],
82 &leftUnionArray[index]))
89 if (leftUnionArray[index] != rightUnionArray[index])
98 bool CompareStructure(const TType &leftNodeType,
99 ConstantUnion *rightUnionArray,
100 ConstantUnion *leftUnionArray)
102 if (leftNodeType.isArray())
104 TType typeWithoutArrayness = leftNodeType;
105 typeWithoutArrayness.clearArrayness();
107 size_t arraySize = leftNodeType.getArraySize();
109 for (size_t i = 0; i < arraySize; ++i)
111 size_t offset = typeWithoutArrayness.getObjectSize() * i;
112 if (!CompareStruct(typeWithoutArrayness,
113 &rightUnionArray[offset],
114 &leftUnionArray[offset]))
122 return CompareStruct(leftNodeType, rightUnionArray, leftUnionArray);
127 } // namespace anonymous
130 ////////////////////////////////////////////////////////////////
132 // Member functions of the nodes used for building the tree.
134 ////////////////////////////////////////////////////////////////
136 void TIntermTyped::setTypePreservePrecision(const TType &t)
138 TPrecision precision = getPrecision();
140 ASSERT(mType.getBasicType() != EbtBool || precision == EbpUndefined);
141 mType.setPrecision(precision);
144 #define REPLACE_IF_IS(node, type, original, replacement) \
145 if (node == original) { \
146 node = static_cast<type *>(replacement); \
150 bool TIntermLoop::replaceChildNode(
151 TIntermNode *original, TIntermNode *replacement)
153 REPLACE_IF_IS(mInit, TIntermNode, original, replacement);
154 REPLACE_IF_IS(mCond, TIntermTyped, original, replacement);
155 REPLACE_IF_IS(mExpr, TIntermTyped, original, replacement);
156 REPLACE_IF_IS(mBody, TIntermNode, original, replacement);
160 void TIntermLoop::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
164 nodeQueue->push(mInit);
168 nodeQueue->push(mCond);
172 nodeQueue->push(mExpr);
176 nodeQueue->push(mBody);
180 bool TIntermBranch::replaceChildNode(
181 TIntermNode *original, TIntermNode *replacement)
183 REPLACE_IF_IS(mExpression, TIntermTyped, original, replacement);
187 void TIntermBranch::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
191 nodeQueue->push(mExpression);
195 bool TIntermBinary::replaceChildNode(
196 TIntermNode *original, TIntermNode *replacement)
198 REPLACE_IF_IS(mLeft, TIntermTyped, original, replacement);
199 REPLACE_IF_IS(mRight, TIntermTyped, original, replacement);
203 void TIntermBinary::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
207 nodeQueue->push(mLeft);
211 nodeQueue->push(mRight);
215 bool TIntermUnary::replaceChildNode(
216 TIntermNode *original, TIntermNode *replacement)
218 REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement);
222 void TIntermUnary::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
226 nodeQueue->push(mOperand);
230 bool TIntermAggregate::replaceChildNode(
231 TIntermNode *original, TIntermNode *replacement)
233 for (size_t ii = 0; ii < mSequence.size(); ++ii)
235 REPLACE_IF_IS(mSequence[ii], TIntermNode, original, replacement);
240 void TIntermAggregate::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
242 for (size_t childIndex = 0; childIndex < mSequence.size(); childIndex++)
244 nodeQueue->push(mSequence[childIndex]);
248 void TIntermAggregate::setPrecisionFromChildren()
250 if (getBasicType() == EbtBool)
252 mType.setPrecision(EbpUndefined);
256 TPrecision precision = EbpUndefined;
257 TIntermSequence::iterator childIter = mSequence.begin();
258 while (childIter != mSequence.end())
260 TIntermTyped *typed = (*childIter)->getAsTyped();
262 precision = GetHigherPrecision(typed->getPrecision(), precision);
265 mType.setPrecision(precision);
268 void TIntermAggregate::setBuiltInFunctionPrecision()
270 // All built-ins returning bool should be handled as ops, not functions.
271 ASSERT(getBasicType() != EbtBool);
273 TPrecision precision = EbpUndefined;
274 TIntermSequence::iterator childIter = mSequence.begin();
275 while (childIter != mSequence.end())
277 TIntermTyped *typed = (*childIter)->getAsTyped();
278 // ESSL spec section 8: texture functions get their precision from the sampler.
279 if (typed && IsSampler(typed->getBasicType()))
281 precision = typed->getPrecision();
286 // ESSL 3.0 spec section 8: textureSize always gets highp precision.
287 // All other functions that take a sampler are assumed to be texture functions.
288 if (mName.find("textureSize") == 0)
289 mType.setPrecision(EbpHigh);
291 mType.setPrecision(precision);
294 bool TIntermSelection::replaceChildNode(
295 TIntermNode *original, TIntermNode *replacement)
297 REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
298 REPLACE_IF_IS(mTrueBlock, TIntermNode, original, replacement);
299 REPLACE_IF_IS(mFalseBlock, TIntermNode, original, replacement);
303 void TIntermSelection::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
307 nodeQueue->push(mCondition);
311 nodeQueue->push(mTrueBlock);
315 nodeQueue->push(mFalseBlock);
320 // Say whether or not an operation node changes the value of a variable.
322 bool TIntermOperator::isAssignment() const
326 case EOpPostIncrement:
327 case EOpPostDecrement:
328 case EOpPreIncrement:
329 case EOpPreDecrement:
334 case EOpVectorTimesMatrixAssign:
335 case EOpVectorTimesScalarAssign:
336 case EOpMatrixTimesScalarAssign:
337 case EOpMatrixTimesMatrixAssign:
346 // returns true if the operator is for one of the constructors
348 bool TIntermOperator::isConstructor() const
352 case EOpConstructVec2:
353 case EOpConstructVec3:
354 case EOpConstructVec4:
355 case EOpConstructMat2:
356 case EOpConstructMat3:
357 case EOpConstructMat4:
358 case EOpConstructFloat:
359 case EOpConstructIVec2:
360 case EOpConstructIVec3:
361 case EOpConstructIVec4:
362 case EOpConstructInt:
363 case EOpConstructUVec2:
364 case EOpConstructUVec3:
365 case EOpConstructUVec4:
366 case EOpConstructUInt:
367 case EOpConstructBVec2:
368 case EOpConstructBVec3:
369 case EOpConstructBVec4:
370 case EOpConstructBool:
371 case EOpConstructStruct:
379 // Make sure the type of a unary operator is appropriate for its
380 // combination of operation and operand type.
382 // Returns false in nothing makes sense.
384 bool TIntermUnary::promote(TInfoSink &)
389 if (mOperand->getBasicType() != EbtBool)
394 case EOpPostIncrement:
395 case EOpPostDecrement:
396 case EOpPreIncrement:
397 case EOpPreDecrement:
398 if (mOperand->getBasicType() == EbtBool)
402 // operators for built-ins are already type checked against their prototype
405 case EOpVectorLogicalNot:
409 if (mOperand->getBasicType() != EbtFloat)
413 setType(mOperand->getType());
414 mType.setQualifier(EvqTemporary);
420 // Establishes the type of the resultant operation, as well as
421 // makes the operator the correct one for the operands.
423 // Returns false if operator can't work on operands.
425 bool TIntermBinary::promote(TInfoSink &infoSink)
427 // This function only handles scalars, vectors, and matrices.
428 if (mLeft->isArray() || mRight->isArray())
430 infoSink.info.message(EPrefixInternalError, getLine(),
431 "Invalid operation for arrays");
435 // GLSL ES 2.0 does not support implicit type casting.
436 // So the basic type should always match.
437 if (mLeft->getBasicType() != mRight->getBasicType())
443 // Base assumption: just make the type the same as the left
444 // operand. Then only deviations from this need be coded.
446 setType(mLeft->getType());
448 // The result gets promoted to the highest precision.
449 TPrecision higherPrecision = GetHigherPrecision(
450 mLeft->getPrecision(), mRight->getPrecision());
451 getTypePointer()->setPrecision(higherPrecision);
453 // Binary operations results in temporary variables unless both
454 // operands are const.
455 if (mLeft->getQualifier() != EvqConst || mRight->getQualifier() != EvqConst)
457 getTypePointer()->setQualifier(EvqTemporary);
460 const int nominalSize =
461 std::max(mLeft->getNominalSize(), mRight->getNominalSize());
464 // All scalars or structs. Code after this test assumes this case is removed!
466 if (nominalSize == 1)
471 // Promote to conditional
477 case EOpLessThanEqual:
478 case EOpGreaterThanEqual:
479 setType(TType(EbtBool, EbpUndefined));
483 // And and Or operate on conditionals
487 // Both operands must be of type bool.
488 if (mLeft->getBasicType() != EbtBool || mRight->getBasicType() != EbtBool)
492 setType(TType(EbtBool, EbpUndefined));
501 // If we reach here, at least one of the operands is vector or matrix.
502 // The other operand could be a scalar, vector, or matrix.
503 // Can these two operands be combined?
505 TBasicType basicType = mLeft->getBasicType();
509 if (!mLeft->isMatrix() && mRight->isMatrix())
511 if (mLeft->isVector())
513 mOp = EOpVectorTimesMatrix;
514 setType(TType(basicType, higherPrecision, EvqTemporary,
515 mRight->getCols(), 1));
519 mOp = EOpMatrixTimesScalar;
520 setType(TType(basicType, higherPrecision, EvqTemporary,
521 mRight->getCols(), mRight->getRows()));
524 else if (mLeft->isMatrix() && !mRight->isMatrix())
526 if (mRight->isVector())
528 mOp = EOpMatrixTimesVector;
529 setType(TType(basicType, higherPrecision, EvqTemporary,
530 mLeft->getRows(), 1));
534 mOp = EOpMatrixTimesScalar;
537 else if (mLeft->isMatrix() && mRight->isMatrix())
539 mOp = EOpMatrixTimesMatrix;
540 setType(TType(basicType, higherPrecision, EvqTemporary,
541 mRight->getCols(), mLeft->getRows()));
543 else if (!mLeft->isMatrix() && !mRight->isMatrix())
545 if (mLeft->isVector() && mRight->isVector())
547 // leave as component product
549 else if (mLeft->isVector() || mRight->isVector())
551 mOp = EOpVectorTimesScalar;
552 setType(TType(basicType, higherPrecision, EvqTemporary,
558 infoSink.info.message(EPrefixInternalError, getLine(),
563 if (!ValidateMultiplication(mOp, mLeft->getType(), mRight->getType()))
570 if (!mLeft->isMatrix() && mRight->isMatrix())
572 if (mLeft->isVector())
574 mOp = EOpVectorTimesMatrixAssign;
581 else if (mLeft->isMatrix() && !mRight->isMatrix())
583 if (mRight->isVector())
589 mOp = EOpMatrixTimesScalarAssign;
592 else if (mLeft->isMatrix() && mRight->isMatrix())
594 mOp = EOpMatrixTimesMatrixAssign;
595 setType(TType(basicType, higherPrecision, EvqTemporary,
596 mRight->getCols(), mLeft->getRows()));
598 else if (!mLeft->isMatrix() && !mRight->isMatrix())
600 if (mLeft->isVector() && mRight->isVector())
602 // leave as component product
604 else if (mLeft->isVector() || mRight->isVector())
606 if (!mLeft->isVector())
608 mOp = EOpVectorTimesScalarAssign;
609 setType(TType(basicType, higherPrecision, EvqTemporary,
610 mLeft->getNominalSize(), 1));
615 infoSink.info.message(EPrefixInternalError, getLine(),
620 if (!ValidateMultiplication(mOp, mLeft->getType(), mRight->getType()))
634 if ((mLeft->isMatrix() && mRight->isVector()) ||
635 (mLeft->isVector() && mRight->isMatrix()))
640 // Are the sizes compatible?
641 if (mLeft->getNominalSize() != mRight->getNominalSize() ||
642 mLeft->getSecondarySize() != mRight->getSecondarySize())
644 // If the nominal size of operands do not match:
645 // One of them must be scalar.
646 if (!mLeft->isScalar() && !mRight->isScalar())
649 // Operator cannot be of type pure assignment.
650 if (mOp == EOpAssign || mOp == EOpInitialize)
655 const int secondarySize = std::max(
656 mLeft->getSecondarySize(), mRight->getSecondarySize());
657 setType(TType(basicType, higherPrecision, EvqTemporary,
658 nominalSize, secondarySize));
666 case EOpLessThanEqual:
667 case EOpGreaterThanEqual:
668 if ((mLeft->getNominalSize() != mRight->getNominalSize()) ||
669 (mLeft->getSecondarySize() != mRight->getSecondarySize()))
673 setType(TType(EbtBool, EbpUndefined));
683 // The fold functions see if an operation on a constant can be done in place,
684 // without generating run-time code.
686 // Returns the node to keep using, which may or may not be the node passed in.
688 TIntermTyped *TIntermConstantUnion::fold(
689 TOperator op, TIntermTyped *constantNode, TInfoSink &infoSink)
691 ConstantUnion *unionArray = getUnionArrayPointer();
696 size_t objectSize = getType().getObjectSize();
701 TIntermConstantUnion *node = constantNode->getAsConstantUnion();
702 ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
703 TType returnType = getType();
705 if (!rightUnionArray)
708 // for a case like float f = 1.2 + vec4(2,3,4,5);
709 if (constantNode->getType().getObjectSize() == 1 && objectSize > 1)
711 rightUnionArray = new ConstantUnion[objectSize];
712 for (size_t i = 0; i < objectSize; ++i)
714 rightUnionArray[i] = *node->getUnionArrayPointer();
716 returnType = getType();
718 else if (constantNode->getType().getObjectSize() > 1 && objectSize == 1)
720 // for a case like float f = vec4(2,3,4,5) + 1.2;
721 unionArray = new ConstantUnion[constantNode->getType().getObjectSize()];
722 for (size_t i = 0; i < constantNode->getType().getObjectSize(); ++i)
724 unionArray[i] = *getUnionArrayPointer();
726 returnType = node->getType();
727 objectSize = constantNode->getType().getObjectSize();
730 ConstantUnion *tempConstArray = NULL;
731 TIntermConstantUnion *tempNode;
733 bool boolNodeFlag = false;
737 tempConstArray = new ConstantUnion[objectSize];
738 for (size_t i = 0; i < objectSize; i++)
739 tempConstArray[i] = unionArray[i] + rightUnionArray[i];
742 tempConstArray = new ConstantUnion[objectSize];
743 for (size_t i = 0; i < objectSize; i++)
744 tempConstArray[i] = unionArray[i] - rightUnionArray[i];
748 case EOpVectorTimesScalar:
749 case EOpMatrixTimesScalar:
750 tempConstArray = new ConstantUnion[objectSize];
751 for (size_t i = 0; i < objectSize; i++)
752 tempConstArray[i] = unionArray[i] * rightUnionArray[i];
755 case EOpMatrixTimesMatrix:
757 if (getType().getBasicType() != EbtFloat ||
758 node->getBasicType() != EbtFloat)
760 infoSink.info.message(
761 EPrefixInternalError, getLine(),
762 "Constant Folding cannot be done for matrix multiply");
766 const int leftCols = getCols();
767 const int leftRows = getRows();
768 const int rightCols = constantNode->getType().getCols();
769 const int rightRows = constantNode->getType().getRows();
770 const int resultCols = rightCols;
771 const int resultRows = leftRows;
773 tempConstArray = new ConstantUnion[resultCols*resultRows];
774 for (int row = 0; row < resultRows; row++)
776 for (int column = 0; column < resultCols; column++)
778 tempConstArray[resultRows * column + row].setFConst(0.0f);
779 for (int i = 0; i < leftCols; i++)
781 tempConstArray[resultRows * column + row].setFConst(
782 tempConstArray[resultRows * column + row].getFConst() +
783 unionArray[i * leftRows + row].getFConst() *
784 rightUnionArray[column * rightRows + i].getFConst());
789 // update return type for matrix product
790 returnType.setPrimarySize(resultCols);
791 returnType.setSecondarySize(resultRows);
797 tempConstArray = new ConstantUnion[objectSize];
798 for (size_t i = 0; i < objectSize; i++)
800 switch (getType().getBasicType())
803 if (rightUnionArray[i] == 0.0f)
805 infoSink.info.message(
806 EPrefixWarning, getLine(),
807 "Divide by zero error during constant folding");
808 tempConstArray[i].setFConst(
809 unionArray[i].getFConst() < 0 ? -FLT_MAX : FLT_MAX);
813 tempConstArray[i].setFConst(
814 unionArray[i].getFConst() /
815 rightUnionArray[i].getFConst());
820 if (rightUnionArray[i] == 0)
822 infoSink.info.message(
823 EPrefixWarning, getLine(),
824 "Divide by zero error during constant folding");
825 tempConstArray[i].setIConst(INT_MAX);
829 tempConstArray[i].setIConst(
830 unionArray[i].getIConst() /
831 rightUnionArray[i].getIConst());
836 if (rightUnionArray[i] == 0)
838 infoSink.info.message(
839 EPrefixWarning, getLine(),
840 "Divide by zero error during constant folding");
841 tempConstArray[i].setUConst(UINT_MAX);
845 tempConstArray[i].setUConst(
846 unionArray[i].getUConst() /
847 rightUnionArray[i].getUConst());
852 infoSink.info.message(
853 EPrefixInternalError, getLine(),
854 "Constant folding cannot be done for \"/\"");
861 case EOpMatrixTimesVector:
863 if (node->getBasicType() != EbtFloat)
865 infoSink.info.message(
866 EPrefixInternalError, getLine(),
867 "Constant Folding cannot be done for matrix times vector");
871 const int matrixCols = getCols();
872 const int matrixRows = getRows();
874 tempConstArray = new ConstantUnion[matrixRows];
876 for (int matrixRow = 0; matrixRow < matrixRows; matrixRow++)
878 tempConstArray[matrixRow].setFConst(0.0f);
879 for (int col = 0; col < matrixCols; col++)
881 tempConstArray[matrixRow].setFConst(
882 tempConstArray[matrixRow].getFConst() +
883 unionArray[col * matrixRows + matrixRow].getFConst() *
884 rightUnionArray[col].getFConst());
888 returnType = node->getType();
889 returnType.setPrimarySize(matrixRows);
891 tempNode = new TIntermConstantUnion(tempConstArray, returnType);
892 tempNode->setLine(getLine());
897 case EOpVectorTimesMatrix:
899 if (getType().getBasicType() != EbtFloat)
901 infoSink.info.message(
902 EPrefixInternalError, getLine(),
903 "Constant Folding cannot be done for vector times matrix");
907 const int matrixCols = constantNode->getType().getCols();
908 const int matrixRows = constantNode->getType().getRows();
910 tempConstArray = new ConstantUnion[matrixCols];
912 for (int matrixCol = 0; matrixCol < matrixCols; matrixCol++)
914 tempConstArray[matrixCol].setFConst(0.0f);
915 for (int matrixRow = 0; matrixRow < matrixRows; matrixRow++)
917 tempConstArray[matrixCol].setFConst(
918 tempConstArray[matrixCol].getFConst() +
919 unionArray[matrixRow].getFConst() *
920 rightUnionArray[matrixCol * matrixRows + matrixRow].getFConst());
924 returnType.setPrimarySize(matrixCols);
929 // this code is written for possible future use,
930 // will not get executed currently
932 tempConstArray = new ConstantUnion[objectSize];
933 for (size_t i = 0; i < objectSize; i++)
935 tempConstArray[i] = unionArray[i] && rightUnionArray[i];
941 // this code is written for possible future use,
942 // will not get executed currently
944 tempConstArray = new ConstantUnion[objectSize];
945 for (size_t i = 0; i < objectSize; i++)
947 tempConstArray[i] = unionArray[i] || rightUnionArray[i];
954 tempConstArray = new ConstantUnion[objectSize];
955 for (size_t i = 0; i < objectSize; i++)
957 switch (getType().getBasicType())
960 tempConstArray[i].setBConst(
961 unionArray[i] == rightUnionArray[i] ? false : true);
972 ASSERT(objectSize == 1);
973 tempConstArray = new ConstantUnion[1];
974 tempConstArray->setBConst(*unionArray < *rightUnionArray);
975 returnType = TType(EbtBool, EbpUndefined, EvqConst);
979 ASSERT(objectSize == 1);
980 tempConstArray = new ConstantUnion[1];
981 tempConstArray->setBConst(*unionArray > *rightUnionArray);
982 returnType = TType(EbtBool, EbpUndefined, EvqConst);
985 case EOpLessThanEqual:
987 ASSERT(objectSize == 1);
988 ConstantUnion constant;
989 constant.setBConst(*unionArray > *rightUnionArray);
990 tempConstArray = new ConstantUnion[1];
991 tempConstArray->setBConst(!constant.getBConst());
992 returnType = TType(EbtBool, EbpUndefined, EvqConst);
996 case EOpGreaterThanEqual:
998 ASSERT(objectSize == 1);
999 ConstantUnion constant;
1000 constant.setBConst(*unionArray < *rightUnionArray);
1001 tempConstArray = new ConstantUnion[1];
1002 tempConstArray->setBConst(!constant.getBConst());
1003 returnType = TType(EbtBool, EbpUndefined, EvqConst);
1008 if (getType().getBasicType() == EbtStruct)
1010 if (!CompareStructure(node->getType(),
1011 node->getUnionArrayPointer(),
1014 boolNodeFlag = true;
1019 for (size_t i = 0; i < objectSize; i++)
1021 if (unionArray[i] != rightUnionArray[i])
1023 boolNodeFlag = true;
1024 break; // break out of for loop
1029 tempConstArray = new ConstantUnion[1];
1032 tempConstArray->setBConst(true);
1036 tempConstArray->setBConst(false);
1039 tempNode = new TIntermConstantUnion(
1040 tempConstArray, TType(EbtBool, EbpUndefined, EvqConst));
1041 tempNode->setLine(getLine());
1046 if (getType().getBasicType() == EbtStruct)
1048 if (CompareStructure(node->getType(),
1049 node->getUnionArrayPointer(),
1052 boolNodeFlag = true;
1057 for (size_t i = 0; i < objectSize; i++)
1059 if (unionArray[i] == rightUnionArray[i])
1061 boolNodeFlag = true;
1062 break; // break out of for loop
1067 tempConstArray = new ConstantUnion[1];
1070 tempConstArray->setBConst(true);
1074 tempConstArray->setBConst(false);
1077 tempNode = new TIntermConstantUnion(
1078 tempConstArray, TType(EbtBool, EbpUndefined, EvqConst));
1079 tempNode->setLine(getLine());
1084 infoSink.info.message(
1085 EPrefixInternalError, getLine(),
1086 "Invalid operator for constant folding");
1089 tempNode = new TIntermConstantUnion(tempConstArray, returnType);
1090 tempNode->setLine(getLine());
1097 // Do unary operations
1099 TIntermConstantUnion *newNode = 0;
1100 ConstantUnion* tempConstArray = new ConstantUnion[objectSize];
1101 for (size_t i = 0; i < objectSize; i++)
1106 switch (getType().getBasicType())
1109 tempConstArray[i].setFConst(-unionArray[i].getFConst());
1112 tempConstArray[i].setIConst(-unionArray[i].getIConst());
1115 tempConstArray[i].setUConst(static_cast<unsigned int>(
1116 -static_cast<int>(unionArray[i].getUConst())));
1119 infoSink.info.message(
1120 EPrefixInternalError, getLine(),
1121 "Unary operation not folded into constant");
1127 switch (getType().getBasicType())
1130 tempConstArray[i].setFConst(unionArray[i].getFConst());
1133 tempConstArray[i].setIConst(unionArray[i].getIConst());
1136 tempConstArray[i].setUConst(static_cast<unsigned int>(
1137 static_cast<int>(unionArray[i].getUConst())));
1140 infoSink.info.message(
1141 EPrefixInternalError, getLine(),
1142 "Unary operation not folded into constant");
1148 // this code is written for possible future use,
1149 // will not get executed currently
1150 switch (getType().getBasicType())
1153 tempConstArray[i].setBConst(!unionArray[i].getBConst());
1156 infoSink.info.message(
1157 EPrefixInternalError, getLine(),
1158 "Unary operation not folded into constant");
1167 newNode = new TIntermConstantUnion(tempConstArray, getType());
1168 newNode->setLine(getLine());
1174 TString TIntermTraverser::hash(const TString &name, ShHashFunction64 hashFunction)
1176 if (hashFunction == NULL || name.empty())
1178 khronos_uint64_t number = (*hashFunction)(name.c_str(), name.length());
1179 TStringStream stream;
1180 stream << HASHED_NAME_PREFIX << std::hex << number;
1181 TString hashedName = stream.str();