1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 #include "ParseHelper.h"
21 #include "preprocessor/SourceLocation.h"
22 #include "ValidateGlobalInitializer.h"
23 #include "ValidateSwitch.h"
25 ///////////////////////////////////////////////////////////////////////
27 // Sub- vector and matrix fields
29 ////////////////////////////////////////////////////////////////////////
32 // Look at a '.' field selector string and change it into offsets
35 bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, const TSourceLoc &line)
37 fields.num = (int) compString.size();
39 error(line, "illegal vector field selection", compString.c_str());
49 for (int i = 0; i < fields.num; ++i) {
50 switch (compString[i]) {
52 fields.offsets[i] = 0;
56 fields.offsets[i] = 0;
60 fields.offsets[i] = 0;
64 fields.offsets[i] = 1;
68 fields.offsets[i] = 1;
72 fields.offsets[i] = 1;
76 fields.offsets[i] = 2;
80 fields.offsets[i] = 2;
84 fields.offsets[i] = 2;
88 fields.offsets[i] = 3;
92 fields.offsets[i] = 3;
96 fields.offsets[i] = 3;
100 error(line, "illegal vector field selection", compString.c_str());
105 for (int i = 0; i < fields.num; ++i) {
106 if (fields.offsets[i] >= vecSize) {
107 error(line, "vector field selection out of range", compString.c_str());
112 if (fieldSet[i] != fieldSet[i-1]) {
113 error(line, "illegal - vector component fields not from the same set", compString.c_str());
124 // Look at a '.' field selector string and change it into offsets
127 bool TParseContext::parseMatrixFields(const TString& compString, int matCols, int matRows, TMatrixFields& fields, const TSourceLoc &line)
129 fields.wholeRow = false;
130 fields.wholeCol = false;
134 if (compString.size() != 2) {
135 error(line, "illegal length of matrix field selection", compString.c_str());
139 if (compString[0] == '_') {
140 if (compString[1] < '0' || compString[1] > '3') {
141 error(line, "illegal matrix field selection", compString.c_str());
144 fields.wholeCol = true;
145 fields.col = compString[1] - '0';
146 } else if (compString[1] == '_') {
147 if (compString[0] < '0' || compString[0] > '3') {
148 error(line, "illegal matrix field selection", compString.c_str());
151 fields.wholeRow = true;
152 fields.row = compString[0] - '0';
154 if (compString[0] < '0' || compString[0] > '3' ||
155 compString[1] < '0' || compString[1] > '3') {
156 error(line, "illegal matrix field selection", compString.c_str());
159 fields.row = compString[0] - '0';
160 fields.col = compString[1] - '0';
163 if (fields.row >= matRows || fields.col >= matCols) {
164 error(line, "matrix field selection out of range", compString.c_str());
171 ///////////////////////////////////////////////////////////////////////
175 ////////////////////////////////////////////////////////////////////////
178 // Track whether errors have occurred.
180 void TParseContext::recover()
185 // Used by flex/bison to output all syntax and parsing errors.
187 void TParseContext::error(const TSourceLoc& loc,
188 const char* reason, const char* token,
189 const char* extraInfo)
191 pp::SourceLocation srcLoc(loc.first_file, loc.first_line);
192 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR,
193 srcLoc, reason, token, extraInfo);
197 void TParseContext::warning(const TSourceLoc& loc,
198 const char* reason, const char* token,
199 const char* extraInfo) {
200 pp::SourceLocation srcLoc(loc.first_file, loc.first_line);
201 mDiagnostics.writeInfo(pp::Diagnostics::PP_WARNING,
202 srcLoc, reason, token, extraInfo);
205 void TParseContext::trace(const char* str)
207 mDiagnostics.writeDebug(str);
211 // Same error message for all places assignments don't work.
213 void TParseContext::assignError(const TSourceLoc &line, const char* op, TString left, TString right)
215 std::stringstream extraInfoStream;
216 extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'";
217 std::string extraInfo = extraInfoStream.str();
218 error(line, "", op, extraInfo.c_str());
222 // Same error message for all places unary operations don't work.
224 void TParseContext::unaryOpError(const TSourceLoc &line, const char* op, TString operand)
226 std::stringstream extraInfoStream;
227 extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " << operand
228 << " (or there is no acceptable conversion)";
229 std::string extraInfo = extraInfoStream.str();
230 error(line, " wrong operand type", op, extraInfo.c_str());
234 // Same error message for all binary operations don't work.
236 void TParseContext::binaryOpError(const TSourceLoc &line, const char* op, TString left, TString right)
238 std::stringstream extraInfoStream;
239 extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" << left
240 << "' and a right operand of type '" << right << "' (or there is no acceptable conversion)";
241 std::string extraInfo = extraInfoStream.str();
242 error(line, " wrong operand types ", op, extraInfo.c_str());
245 bool TParseContext::precisionErrorCheck(const TSourceLoc &line, TPrecision precision, TBasicType type){
246 if (!mChecksPrecisionErrors)
250 if( precision == EbpUndefined ){
251 error( line, "No precision specified for (float)", "" );
256 if( precision == EbpUndefined ){
257 error( line, "No precision specified (int)", "" );
268 // Both test and if necessary, spit out an error, to see if the node is really
269 // an l-value that can be operated on this way.
271 // Returns true if the was an error.
273 bool TParseContext::lValueErrorCheck(const TSourceLoc &line, const char* op, TIntermTyped* node)
275 TIntermSymbol* symNode = node->getAsSymbolNode();
276 TIntermBinary* binaryNode = node->getAsBinaryNode();
281 switch(binaryNode->getOp()) {
283 case EOpIndexIndirect:
284 case EOpIndexDirectStruct:
285 return lValueErrorCheck(line, op, binaryNode->getLeft());
286 case EOpVectorSwizzle:
287 errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft());
289 int offset[4] = {0,0,0,0};
291 TIntermTyped* rightNode = binaryNode->getRight();
292 TIntermAggregate *aggrNode = rightNode->getAsAggregate();
294 for (TIntermSequence::iterator p = aggrNode->getSequence().begin();
295 p != aggrNode->getSequence().end(); p++) {
296 int value = (*p)->getAsTyped()->getAsConstantUnion()->getIConst(0);
298 if (offset[value] > 1) {
299 error(line, " l-value of swizzle cannot have duplicate components", op);
310 error(line, " l-value required", op);
316 const char* symbol = 0;
318 symbol = symNode->getSymbol().c_str();
320 const char* message = 0;
321 switch (node->getQualifier()) {
322 case EvqConstExpr: message = "can't modify a const"; break;
323 case EvqConstReadOnly: message = "can't modify a const"; break;
324 case EvqAttribute: message = "can't modify an attribute"; break;
325 case EvqFragmentIn: message = "can't modify an input"; break;
326 case EvqVertexIn: message = "can't modify an input"; break;
327 case EvqUniform: message = "can't modify a uniform"; break;
331 case EvqVaryingIn: message = "can't modify a varying"; break;
332 case EvqInput: message = "can't modify an input"; break;
333 case EvqFragCoord: message = "can't modify gl_FragCoord"; break;
334 case EvqFrontFacing: message = "can't modify gl_FrontFacing"; break;
335 case EvqPointCoord: message = "can't modify gl_PointCoord"; break;
336 case EvqInstanceID: message = "can't modify gl_InstanceID"; break;
340 // Type that can't be written to?
342 if(IsSampler(node->getBasicType()))
344 message = "can't modify a sampler";
346 else if(node->getBasicType() == EbtVoid)
348 message = "can't modify void";
352 if (message == 0 && binaryNode == 0 && symNode == 0) {
353 error(line, " l-value required", op);
360 // Everything else is okay, no error.
366 // If we get here, we have an error and a message.
369 std::stringstream extraInfoStream;
370 extraInfoStream << "\"" << symbol << "\" (" << message << ")";
371 std::string extraInfo = extraInfoStream.str();
372 error(line, " l-value required", op, extraInfo.c_str());
375 std::stringstream extraInfoStream;
376 extraInfoStream << "(" << message << ")";
377 std::string extraInfo = extraInfoStream.str();
378 error(line, " l-value required", op, extraInfo.c_str());
385 // Both test, and if necessary spit out an error, to see if the node is really
388 // Returns true if the was an error.
390 bool TParseContext::constErrorCheck(TIntermTyped* node)
392 if (node->getQualifier() == EvqConstExpr)
395 error(node->getLine(), "constant expression required", "");
401 // Both test, and if necessary spit out an error, to see if the node is really
404 // Returns true if the was an error.
406 bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token)
408 if (node->isScalarInt())
411 error(node->getLine(), "integer expression required", token);
417 // Both test, and if necessary spit out an error, to see if we are currently
420 // Returns true if the was an error.
422 bool TParseContext::globalErrorCheck(const TSourceLoc &line, bool global, const char* token)
427 error(line, "only allowed at global scope", token);
433 // For now, keep it simple: if it starts "gl_", it's reserved, independent
434 // of scope. Except, if the symbol table is at the built-in push-level,
435 // which is when we are parsing built-ins.
436 // Also checks for "webgl_" and "_webgl_" reserved identifiers if parsing a
439 // Returns true if there was an error.
441 bool TParseContext::reservedErrorCheck(const TSourceLoc &line, const TString& identifier)
443 static const char* reservedErrMsg = "reserved built-in name";
444 if (!symbolTable.atBuiltInLevel()) {
445 if (identifier.compare(0, 3, "gl_") == 0) {
446 error(line, reservedErrMsg, "gl_");
449 if (identifier.find("__") != TString::npos) {
450 error(line, "identifiers containing two consecutive underscores (__) are reserved as possible future keywords", identifier.c_str());
459 // Make sure there is enough data provided to the constructor to build
460 // something of the type of the constructor. Also returns the type of
463 // Returns true if there was an error in construction.
465 bool TParseContext::constructorErrorCheck(const TSourceLoc &line, TIntermNode* node, TFunction& function, TOperator op, TType* type)
467 *type = function.getReturnType();
469 bool constructingMatrix = false;
471 case EOpConstructMat2:
472 case EOpConstructMat2x3:
473 case EOpConstructMat2x4:
474 case EOpConstructMat3x2:
475 case EOpConstructMat3:
476 case EOpConstructMat3x4:
477 case EOpConstructMat4x2:
478 case EOpConstructMat4x3:
479 case EOpConstructMat4:
480 constructingMatrix = true;
487 // Note: It's okay to have too many components available, but not okay to have unused
488 // arguments. 'full' will go to true when enough args have been seen. If we loop
489 // again, there is an extra argument, so 'overfull' will become true.
494 bool overFull = false;
495 bool matrixInMatrix = false;
496 bool arrayArg = false;
497 for (size_t i = 0; i < function.getParamCount(); ++i) {
498 const TParameter& param = function.getParam(i);
499 size += param.type->getObjectSize();
501 if (constructingMatrix && param.type->isMatrix())
502 matrixInMatrix = true;
505 if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize())
507 if (param.type->isArray())
511 if(type->isArray()) {
512 if(type->getArraySize() == 0) {
513 type->setArraySize(function.getParamCount());
514 } else if(type->getArraySize() != (int)function.getParamCount()) {
515 error(line, "array constructor needs one argument per array element", "constructor");
520 if (arrayArg && op != EOpConstructStruct) {
521 error(line, "constructing from a non-dereferenced array", "constructor");
525 if (matrixInMatrix && !type->isArray()) {
526 if (function.getParamCount() != 1) {
527 error(line, "constructing matrix from matrix can only take one argument", "constructor");
533 error(line, "too many arguments", "constructor");
537 if (op == EOpConstructStruct && !type->isArray() && type->getStruct()->fields().size() != function.getParamCount()) {
538 error(line, "Number of constructor parameters does not match the number of structure fields", "constructor");
542 if (!type->isMatrix() || !matrixInMatrix) {
543 if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) ||
544 (op == EOpConstructStruct && size < type->getObjectSize())) {
545 error(line, "not enough data provided for construction", "constructor");
550 TIntermTyped *typed = node ? node->getAsTyped() : 0;
552 error(line, "constructor argument does not have a type", "constructor");
555 if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) {
556 error(line, "cannot convert a sampler", "constructor");
559 if (typed->getBasicType() == EbtVoid) {
560 error(line, "cannot convert a void", "constructor");
567 // This function checks to see if a void variable has been declared and raise an error message for such a case
569 // returns true in case of an error
571 bool TParseContext::voidErrorCheck(const TSourceLoc &line, const TString& identifier, const TBasicType& type)
573 if(type == EbtVoid) {
574 error(line, "illegal use of type 'void'", identifier.c_str());
581 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
583 // returns true in case of an error
585 bool TParseContext::boolErrorCheck(const TSourceLoc &line, const TIntermTyped* type)
587 if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) {
588 error(line, "boolean expression expected", "");
595 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
597 // returns true in case of an error
599 bool TParseContext::boolErrorCheck(const TSourceLoc &line, const TPublicType& pType)
601 if (pType.type != EbtBool || pType.array || (pType.primarySize > 1) || (pType.secondarySize > 1)) {
602 error(line, "boolean expression expected", "");
609 bool TParseContext::samplerErrorCheck(const TSourceLoc &line, const TPublicType& pType, const char* reason)
611 if (pType.type == EbtStruct) {
612 if (containsSampler(*pType.userDef)) {
613 error(line, reason, getBasicString(pType.type), "(structure contains a sampler)");
619 } else if (IsSampler(pType.type)) {
620 error(line, reason, getBasicString(pType.type));
628 bool TParseContext::structQualifierErrorCheck(const TSourceLoc &line, const TPublicType& pType)
630 switch(pType.qualifier)
643 if(pType.type == EbtStruct)
645 error(line, "cannot be used with a structure", getQualifierString(pType.qualifier));
654 if (pType.qualifier != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform"))
657 // check for layout qualifier issues
658 if (pType.qualifier != EvqVertexIn && pType.qualifier != EvqFragmentOut &&
659 layoutLocationErrorCheck(line, pType.layoutQualifier))
667 // These checks are common for all declarations starting a declarator list, and declarators that follow an empty
670 bool TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &identifierLocation)
672 switch(publicType.qualifier)
679 if(publicType.type == EbtStruct)
681 error(identifierLocation, "cannot be used with a structure",
682 getQualifierString(publicType.qualifier));
689 if(publicType.qualifier != EvqUniform && samplerErrorCheck(identifierLocation, publicType,
690 "samplers must be uniform"))
695 // check for layout qualifier issues
696 const TLayoutQualifier layoutQualifier = publicType.layoutQualifier;
698 if(layoutQualifier.matrixPacking != EmpUnspecified)
700 error(identifierLocation, "layout qualifier", getMatrixPackingString(layoutQualifier.matrixPacking),
701 "only valid for interface blocks");
705 if(layoutQualifier.blockStorage != EbsUnspecified)
707 error(identifierLocation, "layout qualifier", getBlockStorageString(layoutQualifier.blockStorage),
708 "only valid for interface blocks");
712 if(publicType.qualifier != EvqVertexIn && publicType.qualifier != EvqFragmentOut &&
713 layoutLocationErrorCheck(identifierLocation, publicType.layoutQualifier))
721 bool TParseContext::layoutLocationErrorCheck(const TSourceLoc &location, const TLayoutQualifier &layoutQualifier)
723 if(layoutQualifier.location != -1)
725 error(location, "invalid layout qualifier:", "location", "only valid on program inputs and outputs");
732 bool TParseContext::locationDeclaratorListCheck(const TSourceLoc& line, const TPublicType &pType)
734 if(pType.layoutQualifier.location != -1)
736 error(line, "location must only be specified for a single input or output variable", "location");
743 bool TParseContext::parameterSamplerErrorCheck(const TSourceLoc &line, TQualifier qualifier, const TType& type)
745 if ((qualifier == EvqOut || qualifier == EvqInOut) &&
746 type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
747 error(line, "samplers cannot be output parameters", type.getBasicString());
754 bool TParseContext::containsSampler(TType& type)
756 if (IsSampler(type.getBasicType()))
759 if (type.getBasicType() == EbtStruct) {
760 const TFieldList& fields = type.getStruct()->fields();
761 for(unsigned int i = 0; i < fields.size(); ++i) {
762 if (containsSampler(*fields[i]->type()))
771 // Do size checking for an array type's size.
773 // Returns true if there was an error.
775 bool TParseContext::arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped* expr, int& size)
777 TIntermConstantUnion* constant = expr->getAsConstantUnion();
779 if (constant == 0 || !constant->isScalarInt())
781 error(line, "array size must be a constant integer expression", "");
785 if (constant->getBasicType() == EbtUInt)
787 unsigned int uintSize = constant->getUConst(0);
788 if (uintSize > static_cast<unsigned int>(std::numeric_limits<int>::max()))
790 error(line, "array size too large", "");
795 size = static_cast<int>(uintSize);
799 size = constant->getIConst(0);
803 error(line, "array size must be a positive integer", "");
813 // See if this qualifier can be an array.
815 // Returns true if there is an error.
817 bool TParseContext::arrayQualifierErrorCheck(const TSourceLoc &line, TPublicType type)
819 if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqVertexIn) || (type.qualifier == EvqConstExpr && mShaderVersion < 300)) {
820 error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str());
828 // See if this type can be an array.
830 // Returns true if there is an error.
832 bool TParseContext::arrayTypeErrorCheck(const TSourceLoc &line, TPublicType type)
835 // Can the type be an array?
838 error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str());
845 bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, const TSourceLoc &line)
847 bool builtIn = false;
848 TSymbol* symbol = symbolTable.find(node->getSymbol(), mShaderVersion, &builtIn);
850 error(line, " undeclared identifier", node->getSymbol().c_str());
853 TVariable* variable = static_cast<TVariable*>(symbol);
855 type->setArrayInformationType(variable->getArrayInformationType());
856 variable->updateArrayInformationType(type);
858 // special casing to test index value of gl_FragData. If the accessed index is >= gl_MaxDrawBuffers
860 if (node->getSymbol() == "gl_FragData") {
861 TSymbol* fragData = symbolTable.find("gl_MaxDrawBuffers", mShaderVersion, &builtIn);
864 int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst();
865 if (fragDataValue <= size) {
866 error(line, "", "[", "gl_FragData can only have a max array size of up to gl_MaxDrawBuffers");
871 // we dont want to update the maxArraySize when this flag is not set, we just want to include this
872 // node type in the chain of node types so that its updated when a higher maxArraySize comes in.
877 variable->getType().setMaxArraySize(size);
878 type->setMaxArraySize(size);
881 while(tt->getArrayInformationType() != 0) {
882 tt = tt->getArrayInformationType();
883 tt->setMaxArraySize(size);
890 // Enforce non-initializer type/qualifier rules.
892 // Returns true if there was an error.
894 bool TParseContext::nonInitConstErrorCheck(const TSourceLoc &line, TString& identifier, TPublicType& type, bool array)
896 if (type.qualifier == EvqConstExpr)
898 // Make the qualifier make sense.
899 type.qualifier = EvqTemporary;
903 error(line, "arrays may not be declared constant since they cannot be initialized", identifier.c_str());
905 else if (type.isStructureContainingArrays())
907 error(line, "structures containing arrays may not be declared constant since they cannot be initialized", identifier.c_str());
911 error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
921 // Do semantic checking for a variable declaration that has no initializer,
922 // and update the symbol table.
924 // Returns true if there was an error.
926 bool TParseContext::nonInitErrorCheck(const TSourceLoc &line, const TString& identifier, TPublicType& type)
928 if(type.qualifier == EvqConstExpr)
930 // Make the qualifier make sense.
931 type.qualifier = EvqTemporary;
933 // Generate informative error messages for ESSL1.
934 // In ESSL3 arrays and structures containing arrays can be constant.
935 if(mShaderVersion < 300 && type.isStructureContainingArrays())
938 "structures containing arrays may not be declared constant since they cannot be initialized",
943 error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
948 if(type.isUnsizedArray())
950 error(line, "implicitly sized arrays need to be initialized", identifier.c_str());
956 // Do some simple checks that are shared between all variable declarations,
957 // and update the symbol table.
959 // Returns true if declaring the variable succeeded.
961 bool TParseContext::declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type,
962 TVariable **variable)
964 ASSERT((*variable) == nullptr);
966 // gl_LastFragData may be redeclared with a new precision qualifier
967 if(type.isArray() && identifier.compare(0, 15, "gl_LastFragData") == 0)
969 const TVariable *maxDrawBuffers =
970 static_cast<const TVariable *>(symbolTable.findBuiltIn("gl_MaxDrawBuffers", mShaderVersion));
971 if(type.getArraySize() != maxDrawBuffers->getConstPointer()->getIConst())
973 error(line, "redeclaration of gl_LastFragData with size != gl_MaxDrawBuffers", identifier.c_str());
978 if(reservedErrorCheck(line, identifier))
981 (*variable) = new TVariable(&identifier, type);
982 if(!symbolTable.declare(**variable))
984 error(line, "redefinition", identifier.c_str());
986 (*variable) = nullptr;
990 if(voidErrorCheck(line, identifier, type.getBasicType()))
996 bool TParseContext::paramErrorCheck(const TSourceLoc &line, TQualifier qualifier, TQualifier paramQualifier, TType* type)
998 if (qualifier != EvqConstReadOnly && qualifier != EvqTemporary) {
999 error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier));
1002 if (qualifier == EvqConstReadOnly && paramQualifier != EvqIn) {
1003 error(line, "qualifier not allowed with ", getQualifierString(qualifier), getQualifierString(paramQualifier));
1007 if (qualifier == EvqConstReadOnly)
1008 type->setQualifier(EvqConstReadOnly);
1010 type->setQualifier(paramQualifier);
1015 bool TParseContext::extensionErrorCheck(const TSourceLoc &line, const TString& extension)
1017 const TExtensionBehavior& extBehavior = extensionBehavior();
1018 TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str());
1019 if (iter == extBehavior.end()) {
1020 error(line, "extension", extension.c_str(), "is not supported");
1023 // In GLSL ES, an extension's default behavior is "disable".
1024 if (iter->second == EBhDisable || iter->second == EBhUndefined) {
1025 error(line, "extension", extension.c_str(), "is disabled");
1028 if (iter->second == EBhWarn) {
1029 warning(line, "extension", extension.c_str(), "is being used");
1036 bool TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *aggregate)
1038 for(size_t i = 0; i < fnCandidate->getParamCount(); ++i)
1040 TQualifier qual = fnCandidate->getParam(i).type->getQualifier();
1041 if(qual == EvqOut || qual == EvqInOut)
1043 TIntermTyped *node = (aggregate->getSequence())[i]->getAsTyped();
1044 if(lValueErrorCheck(node->getLine(), "assign", node))
1046 error(node->getLine(),
1047 "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
1056 void TParseContext::es3InvariantErrorCheck(const TQualifier qualifier, const TSourceLoc &invariantLocation)
1063 case EvqCentroidOut:
1065 case EvqFragmentOut:
1068 error(invariantLocation, "Only out variables can be invariant.", "invariant");
1074 bool TParseContext::supportsExtension(const char* extension)
1076 const TExtensionBehavior& extbehavior = extensionBehavior();
1077 TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
1078 return (iter != extbehavior.end());
1081 void TParseContext::handleExtensionDirective(const TSourceLoc &line, const char* extName, const char* behavior)
1083 pp::SourceLocation loc(line.first_file, line.first_line);
1084 mDirectiveHandler.handleExtension(loc, extName, behavior);
1087 void TParseContext::handlePragmaDirective(const TSourceLoc &line, const char* name, const char* value)
1089 pp::SourceLocation loc(line.first_file, line.first_line);
1090 mDirectiveHandler.handlePragma(loc, name, value);
1093 /////////////////////////////////////////////////////////////////////////////////
1097 /////////////////////////////////////////////////////////////////////////////////
1099 const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location,
1100 const TString *name,
1101 const TSymbol *symbol)
1103 const TVariable *variable = nullptr;
1107 error(location, "undeclared identifier", name->c_str());
1110 else if(!symbol->isVariable())
1112 error(location, "variable expected", name->c_str());
1117 variable = static_cast<const TVariable*>(symbol);
1119 if(symbolTable.findBuiltIn(variable->getName(), mShaderVersion))
1124 // Reject shaders using both gl_FragData and gl_FragColor
1125 TQualifier qualifier = variable->getType().getQualifier();
1126 if(qualifier == EvqFragData)
1128 mUsesFragData = true;
1130 else if(qualifier == EvqFragColor)
1132 mUsesFragColor = true;
1135 // This validation is not quite correct - it's only an error to write to
1136 // both FragData and FragColor. For simplicity, and because users shouldn't
1137 // be rewarded for reading from undefined variables, return an error
1138 // if they are both referenced, rather than assigned.
1139 if(mUsesFragData && mUsesFragColor)
1141 error(location, "cannot use both gl_FragData and gl_FragColor", name->c_str());
1148 TType type(EbtFloat, EbpUndefined);
1149 TVariable *fakeVariable = new TVariable(name, type);
1150 symbolTable.declare(*fakeVariable);
1151 variable = fakeVariable;
1158 // Look up a function name in the symbol table, and make sure it is a function.
1160 // Return the function symbol if found, otherwise 0.
1162 const TFunction* TParseContext::findFunction(const TSourceLoc &line, TFunction* call, bool *builtIn)
1164 // First find by unmangled name to check whether the function name has been
1165 // hidden by a variable name or struct typename.
1166 const TSymbol* symbol = symbolTable.find(call->getName(), mShaderVersion, builtIn);
1168 symbol = symbolTable.find(call->getMangledName(), mShaderVersion, builtIn);
1172 error(line, "no matching overloaded function found", call->getName().c_str());
1176 if (!symbol->isFunction()) {
1177 error(line, "function name expected", call->getName().c_str());
1181 return static_cast<const TFunction*>(symbol);
1185 // Initializers show up in several places in the grammar. Have one set of
1186 // code to handle them here.
1188 bool TParseContext::executeInitializer(const TSourceLoc& line, const TString& identifier, const TPublicType& pType,
1189 TIntermTyped *initializer, TIntermNode **intermNode)
1191 ASSERT(intermNode != nullptr);
1192 TType type = TType(pType);
1194 if(type.isArray() && (type.getArraySize() == 0))
1196 type.setArraySize(initializer->getArraySize());
1199 TVariable *variable = nullptr;
1200 if(!declareVariable(line, identifier, type, &variable))
1205 bool globalInitWarning = false;
1206 if(symbolTable.atGlobalLevel() && !ValidateGlobalInitializer(initializer, this, &globalInitWarning))
1208 // Error message does not completely match behavior with ESSL 1.00, but
1209 // we want to steer developers towards only using constant expressions.
1210 error(line, "global variable initializers must be constant expressions", "=");
1213 if(globalInitWarning)
1215 warning(line, "global variable initializers should be constant expressions "
1216 "(uniforms and globals are allowed in global initializers for legacy compatibility)", "=");
1220 // identifier must be of type constant, a global, or a temporary
1222 TQualifier qualifier = type.getQualifier();
1223 if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConstExpr)) {
1224 error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString());
1228 // test for and propagate constant
1231 if (qualifier == EvqConstExpr) {
1232 if (qualifier != initializer->getQualifier()) {
1233 std::stringstream extraInfoStream;
1234 extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
1235 std::string extraInfo = extraInfoStream.str();
1236 error(line, " assigning non-constant to", "=", extraInfo.c_str());
1237 variable->getType().setQualifier(EvqTemporary);
1241 if (type != initializer->getType()) {
1242 error(line, " non-matching types for const initializer ",
1243 variable->getType().getQualifierString());
1244 variable->getType().setQualifier(EvqTemporary);
1248 if (initializer->getAsConstantUnion()) {
1249 variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
1250 } else if (initializer->getAsSymbolNode()) {
1251 const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), 0);
1252 const TVariable* tVar = static_cast<const TVariable*>(symbol);
1254 ConstantUnion* constArray = tVar->getConstPointer();
1255 variable->shareConstPointer(constArray);
1259 if (!variable->isConstant()) {
1260 TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
1261 *intermNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
1262 if(*intermNode == nullptr) {
1263 assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
1267 *intermNode = nullptr;
1272 TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, bool invariant, TLayoutQualifier layoutQualifier, const TPublicType &typeSpecifier)
1274 TPublicType returnType = typeSpecifier;
1275 returnType.qualifier = qualifier;
1276 returnType.invariant = invariant;
1277 returnType.layoutQualifier = layoutQualifier;
1279 if(typeSpecifier.array)
1281 error(typeSpecifier.line, "not supported", "first-class array");
1283 returnType.clearArrayness();
1286 if(mShaderVersion < 300)
1288 if(qualifier == EvqAttribute && (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt))
1290 error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier));
1294 if((qualifier == EvqVaryingIn || qualifier == EvqVaryingOut) &&
1295 (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt))
1297 error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier));
1309 case EvqCentroidOut:
1311 if(typeSpecifier.type == EbtBool)
1313 error(typeSpecifier.line, "cannot be bool", getQualifierString(qualifier));
1316 if(typeSpecifier.type == EbtInt || typeSpecifier.type == EbtUInt)
1318 error(typeSpecifier.line, "must use 'flat' interpolation here", getQualifierString(qualifier));
1324 case EvqFragmentOut:
1327 if(typeSpecifier.type == EbtBool)
1329 error(typeSpecifier.line, "cannot be bool", getQualifierString(qualifier));
1341 TIntermAggregate *TParseContext::parseSingleDeclaration(TPublicType &publicType,
1342 const TSourceLoc &identifierOrTypeLocation,
1343 const TString &identifier)
1345 TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierOrTypeLocation);
1347 bool emptyDeclaration = (identifier == "");
1349 mDeferredSingleDeclarationErrorCheck = emptyDeclaration;
1351 if(emptyDeclaration)
1353 if(publicType.isUnsizedArray())
1355 // ESSL3 spec section 4.1.9: Array declaration which leaves the size unspecified is an error.
1356 // It is assumed that this applies to empty declarations as well.
1357 error(identifierOrTypeLocation, "empty array declaration needs to specify a size", identifier.c_str());
1362 if(singleDeclarationErrorCheck(publicType, identifierOrTypeLocation))
1365 if(nonInitErrorCheck(identifierOrTypeLocation, identifier, publicType))
1368 TVariable *variable = nullptr;
1369 if(!declareVariable(identifierOrTypeLocation, identifier, TType(publicType), &variable))
1372 if(variable && symbol)
1373 symbol->setId(variable->getUniqueId());
1376 return intermediate.makeAggregate(symbol, identifierOrTypeLocation);
1379 TIntermAggregate *TParseContext::parseSingleArrayDeclaration(TPublicType &publicType,
1380 const TSourceLoc &identifierLocation,
1381 const TString &identifier,
1382 const TSourceLoc &indexLocation,
1383 TIntermTyped *indexExpression)
1385 mDeferredSingleDeclarationErrorCheck = false;
1387 if(singleDeclarationErrorCheck(publicType, identifierLocation))
1390 if(nonInitErrorCheck(identifierLocation, identifier, publicType))
1393 if(arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType))
1398 TType arrayType(publicType);
1401 if(arraySizeErrorCheck(identifierLocation, indexExpression, size))
1405 // Make the type an array even if size check failed.
1406 // This ensures useless error messages regarding the variable's non-arrayness won't follow.
1407 arrayType.setArraySize(size);
1409 TVariable *variable = nullptr;
1410 if(!declareVariable(identifierLocation, identifier, arrayType, &variable))
1413 TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation);
1414 if(variable && symbol)
1415 symbol->setId(variable->getUniqueId());
1417 return intermediate.makeAggregate(symbol, identifierLocation);
1420 TIntermAggregate *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType,
1421 const TSourceLoc &identifierLocation,
1422 const TString &identifier,
1423 const TSourceLoc &initLocation,
1424 TIntermTyped *initializer)
1426 mDeferredSingleDeclarationErrorCheck = false;
1428 if(singleDeclarationErrorCheck(publicType, identifierLocation))
1431 TIntermNode *intermNode = nullptr;
1432 if(!executeInitializer(identifierLocation, identifier, publicType, initializer, &intermNode))
1435 // Build intermediate representation
1437 return intermNode ? intermediate.makeAggregate(intermNode, initLocation) : nullptr;
1446 TIntermAggregate *TParseContext::parseSingleArrayInitDeclaration(TPublicType &publicType,
1447 const TSourceLoc &identifierLocation,
1448 const TString &identifier,
1449 const TSourceLoc &indexLocation,
1450 TIntermTyped *indexExpression,
1451 const TSourceLoc &initLocation,
1452 TIntermTyped *initializer)
1454 mDeferredSingleDeclarationErrorCheck = false;
1456 if(singleDeclarationErrorCheck(publicType, identifierLocation))
1459 if(arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType))
1464 TPublicType arrayType(publicType);
1467 // If indexExpression is nullptr, then the array will eventually get its size implicitly from the initializer.
1468 if(indexExpression != nullptr && arraySizeErrorCheck(identifierLocation, indexExpression, size))
1472 // Make the type an array even if size check failed.
1473 // This ensures useless error messages regarding the variable's non-arrayness won't follow.
1474 arrayType.setArray(true, size);
1476 // initNode will correspond to the whole of "type b[n] = initializer".
1477 TIntermNode *initNode = nullptr;
1478 if(!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
1480 return initNode ? intermediate.makeAggregate(initNode, initLocation) : nullptr;
1489 TIntermAggregate *TParseContext::parseInvariantDeclaration(const TSourceLoc &invariantLoc,
1490 const TSourceLoc &identifierLoc,
1491 const TString *identifier,
1492 const TSymbol *symbol)
1494 // invariant declaration
1495 if(globalErrorCheck(invariantLoc, symbolTable.atGlobalLevel(), "invariant varying"))
1502 error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str());
1508 const TString kGlFrontFacing("gl_FrontFacing");
1509 if(*identifier == kGlFrontFacing)
1511 error(identifierLoc, "identifier should not be declared as invariant", identifier->c_str());
1515 symbolTable.addInvariantVarying(std::string(identifier->c_str()));
1516 const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
1518 const TType &type = variable->getType();
1519 TIntermSymbol *intermSymbol = intermediate.addSymbol(variable->getUniqueId(),
1520 *identifier, type, identifierLoc);
1522 TIntermAggregate *aggregate = intermediate.makeAggregate(intermSymbol, identifierLoc);
1523 aggregate->setOp(EOpInvariantDeclaration);
1528 TIntermAggregate *TParseContext::parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration,
1529 const TSourceLoc &identifierLocation, const TString &identifier)
1531 // If the declaration starting this declarator list was empty (example: int,), some checks were not performed.
1532 if(mDeferredSingleDeclarationErrorCheck)
1534 if(singleDeclarationErrorCheck(publicType, identifierLocation))
1536 mDeferredSingleDeclarationErrorCheck = false;
1539 if(locationDeclaratorListCheck(identifierLocation, publicType))
1542 if(nonInitErrorCheck(identifierLocation, identifier, publicType))
1545 TVariable *variable = nullptr;
1546 if(!declareVariable(identifierLocation, identifier, TType(publicType), &variable))
1549 TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation);
1550 if(variable && symbol)
1551 symbol->setId(variable->getUniqueId());
1553 return intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation);
1556 TIntermAggregate *TParseContext::parseArrayDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration,
1557 const TSourceLoc &identifierLocation, const TString &identifier,
1558 const TSourceLoc &arrayLocation, TIntermTyped *indexExpression)
1560 // If the declaration starting this declarator list was empty (example: int,), some checks were not performed.
1561 if(mDeferredSingleDeclarationErrorCheck)
1563 if(singleDeclarationErrorCheck(publicType, identifierLocation))
1565 mDeferredSingleDeclarationErrorCheck = false;
1568 if(locationDeclaratorListCheck(identifierLocation, publicType))
1571 if(nonInitErrorCheck(identifierLocation, identifier, publicType))
1574 if(arrayTypeErrorCheck(arrayLocation, publicType) || arrayQualifierErrorCheck(arrayLocation, publicType))
1580 TType arrayType = TType(publicType);
1582 if(arraySizeErrorCheck(arrayLocation, indexExpression, size))
1586 arrayType.setArraySize(size);
1588 TVariable *variable = nullptr;
1589 if(!declareVariable(identifierLocation, identifier, arrayType, &variable))
1592 TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation);
1593 if(variable && symbol)
1594 symbol->setId(variable->getUniqueId());
1596 return intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation);
1602 TIntermAggregate *TParseContext::parseInitDeclarator(const TPublicType &publicType, TIntermAggregate *aggregateDeclaration,
1603 const TSourceLoc &identifierLocation, const TString &identifier,
1604 const TSourceLoc &initLocation, TIntermTyped *initializer)
1606 // If the declaration starting this declarator list was empty (example: int,), some checks were not performed.
1607 if(mDeferredSingleDeclarationErrorCheck)
1609 if(singleDeclarationErrorCheck(publicType, identifierLocation))
1611 mDeferredSingleDeclarationErrorCheck = false;
1614 if(locationDeclaratorListCheck(identifierLocation, publicType))
1617 TIntermNode *intermNode = nullptr;
1618 if(!executeInitializer(identifierLocation, identifier, publicType, initializer, &intermNode))
1621 // build the intermediate representation
1625 return intermediate.growAggregate(aggregateDeclaration, intermNode, initLocation);
1629 return aggregateDeclaration;
1639 TIntermAggregate *TParseContext::parseArrayInitDeclarator(const TPublicType &publicType,
1640 TIntermAggregate *aggregateDeclaration,
1641 const TSourceLoc &identifierLocation,
1642 const TString &identifier,
1643 const TSourceLoc &indexLocation,
1644 TIntermTyped *indexExpression,
1645 const TSourceLoc &initLocation, TIntermTyped *initializer)
1647 // If the declaration starting this declarator list was empty (example: int,), some checks were not performed.
1648 if(mDeferredSingleDeclarationErrorCheck)
1650 if(singleDeclarationErrorCheck(publicType, identifierLocation))
1652 mDeferredSingleDeclarationErrorCheck = false;
1655 if(locationDeclaratorListCheck(identifierLocation, publicType))
1658 if(arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType))
1663 TPublicType arrayType(publicType);
1666 // If indexExpression is nullptr, then the array will eventually get its size implicitly from the initializer.
1667 if(indexExpression != nullptr && arraySizeErrorCheck(identifierLocation, indexExpression, size))
1671 // Make the type an array even if size check failed.
1672 // This ensures useless error messages regarding the variable's non-arrayness won't follow.
1673 arrayType.setArray(true, size);
1675 // initNode will correspond to the whole of "b[n] = initializer".
1676 TIntermNode *initNode = nullptr;
1677 if(!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
1681 return intermediate.growAggregate(aggregateDeclaration, initNode, initLocation);
1685 return aggregateDeclaration;
1695 void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier)
1697 if(mShaderVersion < 300)
1699 error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 only", "layout");
1704 if(typeQualifier.qualifier != EvqUniform)
1706 error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "global layout must be uniform");
1711 const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier;
1712 ASSERT(!layoutQualifier.isEmpty());
1714 if(layoutLocationErrorCheck(typeQualifier.line, typeQualifier.layoutQualifier))
1720 if(layoutQualifier.matrixPacking != EmpUnspecified)
1722 mDefaultMatrixPacking = layoutQualifier.matrixPacking;
1725 if(layoutQualifier.blockStorage != EbsUnspecified)
1727 mDefaultBlockStorage = layoutQualifier.blockStorage;
1731 TIntermAggregate *TParseContext::addFunctionPrototypeDeclaration(const TFunction &function, const TSourceLoc &location)
1733 // Note: symbolTableFunction could be the same as function if this is the first declaration.
1734 // Either way the instance in the symbol table is used to track whether the function is declared
1736 TFunction *symbolTableFunction =
1737 static_cast<TFunction *>(symbolTable.find(function.getMangledName(), getShaderVersion()));
1738 if(symbolTableFunction->hasPrototypeDeclaration() && mShaderVersion == 100)
1740 // ESSL 1.00.17 section 4.2.7.
1741 // Doesn't apply to ESSL 3.00.4: see section 4.2.3.
1742 error(location, "duplicate function prototype declarations are not allowed", "function");
1745 symbolTableFunction->setHasPrototypeDeclaration();
1747 TIntermAggregate *prototype = new TIntermAggregate;
1748 prototype->setType(function.getReturnType());
1749 prototype->setName(function.getMangledName());
1751 for(size_t i = 0; i < function.getParamCount(); i++)
1753 const TParameter ¶m = function.getParam(i);
1756 TVariable variable(param.name, *param.type);
1758 TIntermSymbol *paramSymbol = intermediate.addSymbol(
1759 variable.getUniqueId(), variable.getName(), variable.getType(), location);
1760 prototype = intermediate.growAggregate(prototype, paramSymbol, location);
1764 TIntermSymbol *paramSymbol = intermediate.addSymbol(0, "", *param.type, location);
1765 prototype = intermediate.growAggregate(prototype, paramSymbol, location);
1769 prototype->setOp(EOpPrototype);
1773 if(!symbolTable.atGlobalLevel())
1775 // ESSL 3.00.4 section 4.2.4.
1776 error(location, "local function prototype declarations are not allowed", "function");
1783 TIntermAggregate *TParseContext::addFunctionDefinition(const TFunction &function, TIntermAggregate *functionPrototype, TIntermAggregate *functionBody, const TSourceLoc &location)
1785 //?? Check that all paths return a value if return type != void ?
1786 // May be best done as post process phase on intermediate code
1787 if(mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue)
1789 error(location, "function does not return a value:", "", function.getName().c_str());
1793 TIntermAggregate *aggregate = intermediate.growAggregate(functionPrototype, functionBody, location);
1794 intermediate.setAggregateOperator(aggregate, EOpFunction, location);
1795 aggregate->setName(function.getMangledName().c_str());
1796 aggregate->setType(function.getReturnType());
1798 // store the pragma information for debug and optimize and other vendor specific
1799 // information. This information can be queried from the parse tree
1800 aggregate->setOptimize(pragma().optimize);
1801 aggregate->setDebug(pragma().debug);
1803 if(functionBody && functionBody->getAsAggregate())
1804 aggregate->setEndLine(functionBody->getAsAggregate()->getEndLine());
1810 void TParseContext::parseFunctionPrototype(const TSourceLoc &location, TFunction *function, TIntermAggregate **aggregateOut)
1812 const TSymbol *builtIn = symbolTable.findBuiltIn(function->getMangledName(), getShaderVersion());
1816 error(location, "built-in functions cannot be redefined", function->getName().c_str());
1820 TFunction *prevDec = static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion()));
1822 // Note: 'prevDec' could be 'function' if this is the first time we've seen function
1823 // as it would have just been put in the symbol table. Otherwise, we're looking up
1824 // an earlier occurance.
1826 if(prevDec->isDefined())
1828 // Then this function already has a body.
1829 error(location, "function already has a body", function->getName().c_str());
1832 prevDec->setDefined();
1834 // Overload the unique ID of the definition to be the same unique ID as the declaration.
1835 // Eventually we will probably want to have only a single definition and just swap the
1836 // arguments to be the definition's arguments.
1838 function->setUniqueId(prevDec->getUniqueId());
1840 // Raise error message if main function takes any parameters or return anything other than void
1841 if(function->getName() == "main")
1843 if(function->getParamCount() > 0)
1845 error(location, "function cannot take any parameter(s)", function->getName().c_str());
1848 if(function->getReturnType().getBasicType() != EbtVoid)
1850 error(location, "", function->getReturnType().getBasicString(), "main function cannot return a value");
1856 // Remember the return type for later checking for RETURN statements.
1858 mCurrentFunctionType = &(prevDec->getReturnType());
1859 mFunctionReturnsValue = false;
1862 // Insert parameters into the symbol table.
1863 // If the parameter has no name, it's not an error, just don't insert it
1864 // (could be used for unused args).
1866 // Also, accumulate the list of parameters into the HIL, so lower level code
1867 // knows where to find parameters.
1869 TIntermAggregate *paramNodes = new TIntermAggregate;
1870 for(size_t i = 0; i < function->getParamCount(); i++)
1872 const TParameter ¶m = function->getParam(i);
1875 TVariable *variable = new TVariable(param.name, *param.type);
1877 // Insert the parameters with name in the symbol table.
1879 if(!symbolTable.declare(*variable))
1881 error(location, "redefinition", variable->getName().c_str());
1883 paramNodes = intermediate.growAggregate(
1884 paramNodes, intermediate.addSymbol(0, "", *param.type, location), location);
1889 // Add the parameter to the HIL
1891 TIntermSymbol *symbol = intermediate.addSymbol(
1892 variable->getUniqueId(), variable->getName(), variable->getType(), location);
1894 paramNodes = intermediate.growAggregate(paramNodes, symbol, location);
1898 paramNodes = intermediate.growAggregate(
1899 paramNodes, intermediate.addSymbol(0, "", *param.type, location), location);
1902 intermediate.setAggregateOperator(paramNodes, EOpParameters, location);
1903 *aggregateOut = paramNodes;
1904 setLoopNestingLevel(0);
1907 TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TFunction *function)
1910 // We don't know at this point whether this is a function definition or a prototype.
1911 // The definition production code will check for redefinitions.
1912 // In the case of ESSL 1.00 the prototype production code will also check for redeclarations.
1914 // Return types and parameter qualifiers must match in all redeclarations, so those are checked
1917 TFunction *prevDec = static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion()));
1920 if(prevDec->getReturnType() != function->getReturnType())
1922 error(location, "overloaded functions must have the same return type",
1923 function->getReturnType().getBasicString());
1926 for(size_t i = 0; i < prevDec->getParamCount(); ++i)
1928 if(prevDec->getParam(i).type->getQualifier() != function->getParam(i).type->getQualifier())
1930 error(location, "overloaded functions must have the same parameter qualifiers",
1931 function->getParam(i).type->getQualifierString());
1938 // Check for previously declared variables using the same name.
1940 TSymbol *prevSym = symbolTable.find(function->getName(), getShaderVersion());
1943 if(!prevSym->isFunction())
1945 error(location, "redefinition", function->getName().c_str(), "function");
1950 // We're at the inner scope level of the function's arguments and body statement.
1951 // Add the function prototype to the surrounding scope instead.
1952 symbolTable.getOuterLevel()->insert(*function);
1955 // If this is a redeclaration, it could also be a definition, in which case, we want to use the
1956 // variable names from this one, and not the one that's
1957 // being redeclared. So, pass back up this declaration, not the one in the symbol table.
1962 TFunction *TParseContext::addConstructorFunc(const TPublicType &publicTypeIn)
1964 TPublicType publicType = publicTypeIn;
1965 TOperator op = EOpNull;
1966 if(publicType.userDef)
1968 op = EOpConstructStruct;
1972 switch(publicType.type)
1975 if(publicType.isMatrix())
1977 switch(publicType.getCols())
1980 switch(publicType.getRows())
1982 case 2: op = EOpConstructMat2; break;
1983 case 3: op = EOpConstructMat2x3; break;
1984 case 4: op = EOpConstructMat2x4; break;
1988 switch(publicType.getRows())
1990 case 2: op = EOpConstructMat3x2; break;
1991 case 3: op = EOpConstructMat3; break;
1992 case 4: op = EOpConstructMat3x4; break;
1996 switch(publicType.getRows())
1998 case 2: op = EOpConstructMat4x2; break;
1999 case 3: op = EOpConstructMat4x3; break;
2000 case 4: op = EOpConstructMat4; break;
2007 switch(publicType.getNominalSize())
2009 case 1: op = EOpConstructFloat; break;
2010 case 2: op = EOpConstructVec2; break;
2011 case 3: op = EOpConstructVec3; break;
2012 case 4: op = EOpConstructVec4; break;
2018 switch(publicType.getNominalSize())
2020 case 1: op = EOpConstructInt; break;
2021 case 2: op = EOpConstructIVec2; break;
2022 case 3: op = EOpConstructIVec3; break;
2023 case 4: op = EOpConstructIVec4; break;
2028 switch(publicType.getNominalSize())
2030 case 1: op = EOpConstructUInt; break;
2031 case 2: op = EOpConstructUVec2; break;
2032 case 3: op = EOpConstructUVec3; break;
2033 case 4: op = EOpConstructUVec4; break;
2038 switch(publicType.getNominalSize())
2040 case 1: op = EOpConstructBool; break;
2041 case 2: op = EOpConstructBVec2; break;
2042 case 3: op = EOpConstructBVec3; break;
2043 case 4: op = EOpConstructBVec4; break;
2052 error(publicType.line, "cannot construct this type", getBasicString(publicType.type));
2054 publicType.type = EbtFloat;
2055 op = EOpConstructFloat;
2060 TType type(publicType);
2061 return new TFunction(&tempString, type, op);
2064 // This function is used to test for the correctness of the parameters passed to various constructor functions
2065 // and also convert them to the right datatype if it is allowed and required.
2067 // Returns 0 for an error or the constructed node (aggregate or typed) for no error.
2069 TIntermTyped* TParseContext::addConstructor(TIntermNode* arguments, const TType* type, TOperator op, TFunction* fnCall, const TSourceLoc &line)
2071 TIntermAggregate *aggregateArguments = arguments->getAsAggregate();
2073 if(!aggregateArguments)
2075 aggregateArguments = new TIntermAggregate;
2076 aggregateArguments->getSequence().push_back(arguments);
2081 // GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of
2083 for(TIntermNode *&argNode : aggregateArguments->getSequence())
2085 const TType &argType = argNode->getAsTyped()->getType();
2086 // It has already been checked that the argument is not an array.
2087 ASSERT(!argType.isArray());
2088 if(!argType.sameElementType(*type))
2090 error(line, "Array constructor argument has an incorrect type", "Error");
2095 else if(op == EOpConstructStruct)
2097 const TFieldList &fields = type->getStruct()->fields();
2098 TIntermSequence &args = aggregateArguments->getSequence();
2100 for(size_t i = 0; i < fields.size(); i++)
2102 if(args[i]->getAsTyped()->getType() != *fields[i]->type())
2104 error(line, "Structure constructor arguments do not match structure fields", "Error");
2112 // Turn the argument list itself into a constructor
2113 TIntermAggregate *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
2114 TIntermTyped *constConstructor = foldConstConstructor(constructor, *type);
2115 if(constConstructor)
2117 return constConstructor;
2123 TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, const TType& type)
2125 aggrNode->setType(type);
2126 if (aggrNode->isConstantFoldable()) {
2127 bool returnVal = false;
2128 ConstantUnion* unionArray = new ConstantUnion[type.getObjectSize()];
2129 if (aggrNode->getSequence().size() == 1) {
2130 returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type, true);
2133 returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type);
2138 return intermediate.addConstantUnion(unionArray, type, aggrNode->getLine());
2145 // This function returns the tree representation for the vector field(s) being accessed from contant vector.
2146 // If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a contant node is
2147 // returned, else an aggregate node is returned (for v.xy). The input to this function could either be the symbol
2148 // node or it could be the intermediate tree representation of accessing fields in a constant structure or column of
2149 // a constant matrix.
2151 TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, const TSourceLoc &line)
2153 TIntermTyped* typedNode;
2154 TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
2156 ConstantUnion *unionArray;
2157 if (tempConstantNode) {
2158 unionArray = tempConstantNode->getUnionArrayPointer();
2163 } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
2164 error(line, "Cannot offset into the vector", "Error");
2170 ConstantUnion* constArray = new ConstantUnion[fields.num];
2172 int objSize = static_cast<int>(node->getType().getObjectSize());
2173 for (int i = 0; i < fields.num; i++) {
2174 if (fields.offsets[i] >= objSize) {
2175 std::stringstream extraInfoStream;
2176 extraInfoStream << "vector field selection out of range '" << fields.offsets[i] << "'";
2177 std::string extraInfo = extraInfoStream.str();
2178 error(line, "", "[", extraInfo.c_str());
2180 fields.offsets[i] = 0;
2183 constArray[i] = unionArray[fields.offsets[i]];
2186 typedNode = intermediate.addConstantUnion(constArray, node->getType(), line);
2191 // This function returns the column being accessed from a constant matrix. The values are retrieved from
2192 // the symbol table and parse-tree is built for a vector (each column of a matrix is a vector). The input
2193 // to the function could either be a symbol node (m[0] where m is a constant matrix)that represents a
2194 // constant matrix or it could be the tree representation of the constant matrix (s.m1[0] where s is a constant structure)
2196 TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, const TSourceLoc &line)
2198 TIntermTyped* typedNode;
2199 TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
2201 if (index >= node->getType().getNominalSize()) {
2202 std::stringstream extraInfoStream;
2203 extraInfoStream << "matrix field selection out of range '" << index << "'";
2204 std::string extraInfo = extraInfoStream.str();
2205 error(line, "", "[", extraInfo.c_str());
2210 if (tempConstantNode) {
2211 ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
2212 int size = tempConstantNode->getType().getNominalSize();
2213 typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line);
2215 error(line, "Cannot offset into the matrix", "Error");
2226 // This function returns an element of an array accessed from a constant array. The values are retrieved from
2227 // the symbol table and parse-tree is built for the type of the element. The input
2228 // to the function could either be a symbol node (a[0] where a is a constant array)that represents a
2229 // constant array or it could be the tree representation of the constant array (s.a1[0] where s is a constant structure)
2231 TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc &line)
2233 TIntermTyped* typedNode;
2234 TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
2235 TType arrayElementType = node->getType();
2236 arrayElementType.clearArrayness();
2238 if (index >= node->getType().getArraySize()) {
2239 std::stringstream extraInfoStream;
2240 extraInfoStream << "array field selection out of range '" << index << "'";
2241 std::string extraInfo = extraInfoStream.str();
2242 error(line, "", "[", extraInfo.c_str());
2247 size_t arrayElementSize = arrayElementType.getObjectSize();
2249 if (tempConstantNode) {
2250 ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
2251 typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line);
2253 error(line, "Cannot offset into the array", "Error");
2264 // This function returns the value of a particular field inside a constant structure from the symbol table.
2265 // If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr
2266 // function and returns the parse-tree with the values of the embedded/nested struct.
2268 TIntermTyped* TParseContext::addConstStruct(const TString& identifier, TIntermTyped* node, const TSourceLoc &line)
2270 const TFieldList &fields = node->getType().getStruct()->fields();
2271 TIntermTyped *typedNode;
2272 size_t instanceSize = 0;
2273 TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
2275 for(size_t index = 0; index < fields.size(); ++index) {
2276 if (fields[index]->name() == identifier) {
2279 instanceSize += fields[index]->type()->getObjectSize();
2283 if (tempConstantNode) {
2284 ConstantUnion* constArray = tempConstantNode->getUnionArrayPointer();
2286 typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function
2288 error(line, "Cannot offset into the structure", "Error");
2298 // Interface/uniform blocks
2300 TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TFieldList* fieldList,
2301 const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine)
2303 if(reservedErrorCheck(nameLine, blockName))
2306 if(typeQualifier.qualifier != EvqUniform)
2308 error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "interface blocks must be uniform");
2312 TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier;
2313 if(layoutLocationErrorCheck(typeQualifier.line, blockLayoutQualifier))
2318 if(blockLayoutQualifier.matrixPacking == EmpUnspecified)
2320 blockLayoutQualifier.matrixPacking = mDefaultMatrixPacking;
2323 if(blockLayoutQualifier.blockStorage == EbsUnspecified)
2325 blockLayoutQualifier.blockStorage = mDefaultBlockStorage;
2328 TSymbol* blockNameSymbol = new TSymbol(&blockName);
2329 if(!symbolTable.declare(*blockNameSymbol)) {
2330 error(nameLine, "redefinition", blockName.c_str(), "interface block name");
2334 // check for sampler types and apply layout qualifiers
2335 for(size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex) {
2336 TField* field = (*fieldList)[memberIndex];
2337 TType* fieldType = field->type();
2338 if(IsSampler(fieldType->getBasicType())) {
2339 error(field->line(), "unsupported type", fieldType->getBasicString(), "sampler types are not allowed in interface blocks");
2343 const TQualifier qualifier = fieldType->getQualifier();
2350 error(field->line(), "invalid qualifier on interface block member", getQualifierString(qualifier));
2355 // check layout qualifiers
2356 TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier();
2357 if(layoutLocationErrorCheck(field->line(), fieldLayoutQualifier))
2362 if(fieldLayoutQualifier.blockStorage != EbsUnspecified)
2364 error(field->line(), "invalid layout qualifier:", getBlockStorageString(fieldLayoutQualifier.blockStorage), "cannot be used here");
2368 if(fieldLayoutQualifier.matrixPacking == EmpUnspecified)
2370 fieldLayoutQualifier.matrixPacking = blockLayoutQualifier.matrixPacking;
2372 else if(!fieldType->isMatrix())
2374 error(field->line(), "invalid layout qualifier:", getMatrixPackingString(fieldLayoutQualifier.matrixPacking), "can only be used on matrix types");
2378 fieldType->setLayoutQualifier(fieldLayoutQualifier);
2385 if(arraySizeErrorCheck(arrayIndexLine, arrayIndex, arraySize))
2389 TInterfaceBlock* interfaceBlock = new TInterfaceBlock(&blockName, fieldList, instanceName, arraySize, blockLayoutQualifier);
2390 TType interfaceBlockType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier, arraySize);
2392 TString symbolName = "";
2397 // define symbols for the members of the interface block
2398 for(size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
2400 TField* field = (*fieldList)[memberIndex];
2401 TType* fieldType = field->type();
2403 // set parent pointer of the field variable
2404 fieldType->setInterfaceBlock(interfaceBlock);
2406 TVariable* fieldVariable = new TVariable(&field->name(), *fieldType);
2407 fieldVariable->setQualifier(typeQualifier.qualifier);
2409 if(!symbolTable.declare(*fieldVariable)) {
2410 error(field->line(), "redefinition", field->name().c_str(), "interface block member name");
2417 // add a symbol for this interface block
2418 TVariable* instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false);
2419 instanceTypeDef->setQualifier(typeQualifier.qualifier);
2421 if(!symbolTable.declare(*instanceTypeDef)) {
2422 error(instanceLine, "redefinition", instanceName->c_str(), "interface block instance name");
2426 symbolId = instanceTypeDef->getUniqueId();
2427 symbolName = instanceTypeDef->getName();
2430 TIntermAggregate *aggregate = intermediate.makeAggregate(intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line), nameLine);
2431 aggregate->setOp(EOpDeclaration);
2433 exitStructDeclaration();
2438 // Parse an array index expression
2440 TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc &location, TIntermTyped *indexExpression)
2442 TIntermTyped *indexedExpression = nullptr;
2444 if(!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector())
2446 if(baseExpression->getAsSymbolNode())
2448 error(location, " left of '[' is not of type array, matrix, or vector ",
2449 baseExpression->getAsSymbolNode()->getSymbol().c_str());
2453 error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
2458 TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion();
2460 if(indexExpression->getQualifier() == EvqConstExpr && indexConstantUnion)
2462 int index = indexConstantUnion->getIConst(0);
2465 std::stringstream infoStream;
2466 infoStream << index;
2467 std::string info = infoStream.str();
2468 error(location, "negative index", info.c_str());
2472 if(baseExpression->getType().getQualifier() == EvqConstExpr)
2474 if(baseExpression->isArray())
2476 // constant folding for arrays
2477 indexedExpression = addConstArrayNode(index, baseExpression, location);
2479 else if(baseExpression->isVector())
2481 // constant folding for vectors
2482 TVectorFields fields;
2484 fields.offsets[0] = index; // need to do it this way because v.xy sends fields integer array
2485 indexedExpression = addConstVectorNode(fields, baseExpression, location);
2487 else if(baseExpression->isMatrix())
2489 // constant folding for matrices
2490 indexedExpression = addConstMatrixNode(index, baseExpression, location);
2497 if(baseExpression->isArray())
2499 if(index >= baseExpression->getType().getArraySize())
2501 std::stringstream extraInfoStream;
2502 extraInfoStream << "array index out of range '" << index << "'";
2503 std::string extraInfo = extraInfoStream.str();
2504 error(location, "", "[", extraInfo.c_str());
2506 safeIndex = baseExpression->getType().getArraySize() - 1;
2509 else if((baseExpression->isVector() || baseExpression->isMatrix()) &&
2510 baseExpression->getType().getNominalSize() <= index)
2512 std::stringstream extraInfoStream;
2513 extraInfoStream << "field selection out of range '" << index << "'";
2514 std::string extraInfo = extraInfoStream.str();
2515 error(location, "", "[", extraInfo.c_str());
2517 safeIndex = baseExpression->getType().getNominalSize() - 1;
2520 // Don't modify the data of the previous constant union, because it can point
2521 // to builtins, like gl_MaxDrawBuffers. Instead use a new sanitized object.
2524 ConstantUnion *safeConstantUnion = new ConstantUnion();
2525 safeConstantUnion->setIConst(safeIndex);
2526 indexConstantUnion->replaceConstantUnion(safeConstantUnion);
2529 indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location);
2534 if(baseExpression->isInterfaceBlock())
2537 "[", "array indexes for interface blocks arrays must be constant integral expressions");
2540 else if(baseExpression->getQualifier() == EvqFragmentOut)
2542 error(location, "", "[", "array indexes for fragment outputs must be constant integral expressions");
2546 indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location);
2549 if(indexedExpression == 0)
2551 ConstantUnion *unionArray = new ConstantUnion[1];
2552 unionArray->setFConst(0.0f);
2553 indexedExpression = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConstExpr), location);
2555 else if(baseExpression->isArray())
2557 const TType &baseType = baseExpression->getType();
2558 if(baseType.getStruct())
2560 TType copyOfType(baseType.getStruct());
2561 indexedExpression->setType(copyOfType);
2563 else if(baseType.isInterfaceBlock())
2565 TType copyOfType(baseType.getInterfaceBlock(), EvqTemporary, baseType.getLayoutQualifier(), 0);
2566 indexedExpression->setType(copyOfType);
2570 indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),
2571 EvqTemporary, static_cast<unsigned char>(baseExpression->getNominalSize()),
2572 static_cast<unsigned char>(baseExpression->getSecondarySize())));
2575 if(baseExpression->getType().getQualifier() == EvqConstExpr)
2577 indexedExpression->getTypePointer()->setQualifier(EvqConstExpr);
2580 else if(baseExpression->isMatrix())
2582 TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConstExpr ? EvqConstExpr : EvqTemporary;
2583 indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),
2584 qualifier, static_cast<unsigned char>(baseExpression->getSecondarySize())));
2586 else if(baseExpression->isVector())
2588 TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConstExpr ? EvqConstExpr : EvqTemporary;
2589 indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier));
2593 indexedExpression->setType(baseExpression->getType());
2596 return indexedExpression;
2599 TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc &dotLocation,
2600 const TString &fieldString, const TSourceLoc &fieldLocation)
2602 TIntermTyped *indexedExpression = nullptr;
2604 if(baseExpression->isArray())
2606 error(fieldLocation, "cannot apply dot operator to an array", ".");
2610 if(baseExpression->isVector())
2612 TVectorFields fields;
2613 if(!parseVectorFields(fieldString, baseExpression->getNominalSize(), fields, fieldLocation))
2616 fields.offsets[0] = 0;
2620 if(baseExpression->getAsConstantUnion())
2622 // constant folding for vector fields
2623 indexedExpression = addConstVectorNode(fields, baseExpression, fieldLocation);
2624 if(indexedExpression == 0)
2627 indexedExpression = baseExpression;
2631 indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),
2632 EvqConstExpr, (unsigned char)(fieldString).size()));
2637 TString vectorString = fieldString;
2638 TIntermTyped *index = intermediate.addSwizzle(fields, fieldLocation);
2639 indexedExpression = intermediate.addIndex(EOpVectorSwizzle, baseExpression, index, dotLocation);
2640 indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),
2641 baseExpression->getQualifier() == EvqConstExpr ? EvqConstExpr : EvqTemporary, (unsigned char)vectorString.size()));
2644 else if(baseExpression->isMatrix())
2646 TMatrixFields fields;
2647 if(!parseMatrixFields(fieldString, baseExpression->getNominalSize(), baseExpression->getSecondarySize(), fields, fieldLocation))
2649 fields.wholeRow = false;
2650 fields.wholeCol = false;
2656 if(fields.wholeRow || fields.wholeCol)
2658 error(dotLocation, " non-scalar fields not implemented yet", ".");
2660 ConstantUnion *unionArray = new ConstantUnion[1];
2661 unionArray->setIConst(0);
2662 TIntermTyped *index = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConstExpr),
2664 indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, index, dotLocation);
2665 indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),
2666 EvqTemporary, static_cast<unsigned char>(baseExpression->getNominalSize()),
2667 static_cast<unsigned char>(baseExpression->getSecondarySize())));
2671 ConstantUnion *unionArray = new ConstantUnion[1];
2672 unionArray->setIConst(fields.col * baseExpression->getSecondarySize() + fields.row);
2673 TIntermTyped *index = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConstExpr),
2675 indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, index, dotLocation);
2676 indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision()));
2679 else if(baseExpression->getBasicType() == EbtStruct)
2681 bool fieldFound = false;
2682 const TFieldList &fields = baseExpression->getType().getStruct()->fields();
2685 error(dotLocation, "structure has no fields", "Internal Error");
2687 indexedExpression = baseExpression;
2692 for(i = 0; i < fields.size(); ++i)
2694 if(fields[i]->name() == fieldString)
2702 if(baseExpression->getType().getQualifier() == EvqConstExpr)
2704 indexedExpression = addConstStruct(fieldString, baseExpression, dotLocation);
2705 if(indexedExpression == 0)
2708 indexedExpression = baseExpression;
2712 indexedExpression->setType(*fields[i]->type());
2713 // change the qualifier of the return type, not of the structure field
2714 // as the structure definition is shared between various structures.
2715 indexedExpression->getTypePointer()->setQualifier(EvqConstExpr);
2720 ConstantUnion *unionArray = new ConstantUnion[1];
2721 unionArray->setIConst(i);
2722 TIntermTyped *index = intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation);
2723 indexedExpression = intermediate.addIndex(EOpIndexDirectStruct, baseExpression, index, dotLocation);
2724 indexedExpression->setType(*fields[i]->type());
2729 error(dotLocation, " no such field in structure", fieldString.c_str());
2731 indexedExpression = baseExpression;
2735 else if(baseExpression->isInterfaceBlock())
2737 bool fieldFound = false;
2738 const TFieldList &fields = baseExpression->getType().getInterfaceBlock()->fields();
2741 error(dotLocation, "interface block has no fields", "Internal Error");
2743 indexedExpression = baseExpression;
2748 for(i = 0; i < fields.size(); ++i)
2750 if(fields[i]->name() == fieldString)
2758 ConstantUnion *unionArray = new ConstantUnion[1];
2759 unionArray->setIConst(i);
2760 TIntermTyped *index = intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation);
2761 indexedExpression = intermediate.addIndex(EOpIndexDirectInterfaceBlock, baseExpression, index,
2763 indexedExpression->setType(*fields[i]->type());
2767 error(dotLocation, " no such field in interface block", fieldString.c_str());
2769 indexedExpression = baseExpression;
2775 if(mShaderVersion < 300)
2777 error(dotLocation, " field selection requires structure, vector, or matrix on left hand side",
2778 fieldString.c_str());
2783 " field selection requires structure, vector, matrix, or interface block on left hand side",
2784 fieldString.c_str());
2787 indexedExpression = baseExpression;
2790 return indexedExpression;
2793 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine)
2795 TLayoutQualifier qualifier;
2797 qualifier.location = -1;
2798 qualifier.matrixPacking = EmpUnspecified;
2799 qualifier.blockStorage = EbsUnspecified;
2801 if(qualifierType == "shared")
2803 qualifier.blockStorage = EbsShared;
2805 else if(qualifierType == "packed")
2807 qualifier.blockStorage = EbsPacked;
2809 else if(qualifierType == "std140")
2811 qualifier.blockStorage = EbsStd140;
2813 else if(qualifierType == "row_major")
2815 qualifier.matrixPacking = EmpRowMajor;
2817 else if(qualifierType == "column_major")
2819 qualifier.matrixPacking = EmpColumnMajor;
2821 else if(qualifierType == "location")
2823 error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "location requires an argument");
2828 error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
2835 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine)
2837 TLayoutQualifier qualifier;
2839 qualifier.location = -1;
2840 qualifier.matrixPacking = EmpUnspecified;
2841 qualifier.blockStorage = EbsUnspecified;
2843 if (qualifierType != "location")
2845 error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "only location may have arguments");
2850 // must check that location is non-negative
2853 error(intValueLine, "out of range:", intValueString.c_str(), "location must be non-negative");
2858 qualifier.location = intValue;
2865 TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier)
2867 TLayoutQualifier joinedQualifier = leftQualifier;
2869 if (rightQualifier.location != -1)
2871 joinedQualifier.location = rightQualifier.location;
2873 if(rightQualifier.matrixPacking != EmpUnspecified)
2875 joinedQualifier.matrixPacking = rightQualifier.matrixPacking;
2877 if(rightQualifier.blockStorage != EbsUnspecified)
2879 joinedQualifier.blockStorage = rightQualifier.blockStorage;
2882 return joinedQualifier;
2886 TPublicType TParseContext::joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier,
2887 const TSourceLoc &storageLoc, TQualifier storageQualifier)
2889 TQualifier mergedQualifier = EvqSmoothIn;
2891 if(storageQualifier == EvqFragmentIn) {
2892 if(interpolationQualifier == EvqSmooth)
2893 mergedQualifier = EvqSmoothIn;
2894 else if(interpolationQualifier == EvqFlat)
2895 mergedQualifier = EvqFlatIn;
2896 else UNREACHABLE(interpolationQualifier);
2898 else if(storageQualifier == EvqCentroidIn) {
2899 if(interpolationQualifier == EvqSmooth)
2900 mergedQualifier = EvqCentroidIn;
2901 else if(interpolationQualifier == EvqFlat)
2902 mergedQualifier = EvqFlatIn;
2903 else UNREACHABLE(interpolationQualifier);
2905 else if(storageQualifier == EvqVertexOut) {
2906 if(interpolationQualifier == EvqSmooth)
2907 mergedQualifier = EvqSmoothOut;
2908 else if(interpolationQualifier == EvqFlat)
2909 mergedQualifier = EvqFlatOut;
2910 else UNREACHABLE(interpolationQualifier);
2912 else if(storageQualifier == EvqCentroidOut) {
2913 if(interpolationQualifier == EvqSmooth)
2914 mergedQualifier = EvqCentroidOut;
2915 else if(interpolationQualifier == EvqFlat)
2916 mergedQualifier = EvqFlatOut;
2917 else UNREACHABLE(interpolationQualifier);
2920 error(interpolationLoc, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getQualifierString(interpolationQualifier));
2923 mergedQualifier = storageQualifier;
2927 type.setBasic(EbtVoid, mergedQualifier, storageLoc);
2931 TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList)
2933 if(voidErrorCheck(typeSpecifier.line, (*fieldList)[0]->name(), typeSpecifier.type))
2938 for(unsigned int i = 0; i < fieldList->size(); ++i)
2941 // Careful not to replace already known aspects of type, like array-ness
2943 TType *type = (*fieldList)[i]->type();
2944 type->setBasicType(typeSpecifier.type);
2945 type->setNominalSize(typeSpecifier.primarySize);
2946 type->setSecondarySize(typeSpecifier.secondarySize);
2947 type->setPrecision(typeSpecifier.precision);
2948 type->setQualifier(typeSpecifier.qualifier);
2949 type->setLayoutQualifier(typeSpecifier.layoutQualifier);
2951 // don't allow arrays of arrays
2954 if(arrayTypeErrorCheck(typeSpecifier.line, typeSpecifier))
2957 if(typeSpecifier.array)
2958 type->setArraySize(typeSpecifier.arraySize);
2959 if(typeSpecifier.userDef)
2961 type->setStruct(typeSpecifier.userDef->getStruct());
2964 if(structNestingErrorCheck(typeSpecifier.line, *(*fieldList)[i]))
2973 TPublicType TParseContext::addStructure(const TSourceLoc &structLine, const TSourceLoc &nameLine,
2974 const TString *structName, TFieldList *fieldList)
2976 TStructure *structure = new TStructure(structName, fieldList);
2977 TType *structureType = new TType(structure);
2979 // Store a bool in the struct if we're at global scope, to allow us to
2980 // skip the local struct scoping workaround in HLSL.
2981 structure->setUniqueId(TSymbolTableLevel::nextUniqueId());
2982 structure->setAtGlobalScope(symbolTable.atGlobalLevel());
2984 if(!structName->empty())
2986 if(reservedErrorCheck(nameLine, *structName))
2990 TVariable *userTypeDef = new TVariable(structName, *structureType, true);
2991 if(!symbolTable.declare(*userTypeDef))
2993 error(nameLine, "redefinition", structName->c_str(), "struct");
2998 // ensure we do not specify any storage qualifiers on the struct members
2999 for(unsigned int typeListIndex = 0; typeListIndex < fieldList->size(); typeListIndex++)
3001 const TField &field = *(*fieldList)[typeListIndex];
3002 const TQualifier qualifier = field.type()->getQualifier();
3009 error(field.line(), "invalid qualifier on struct member", getQualifierString(qualifier));
3015 TPublicType publicType;
3016 publicType.setBasic(EbtStruct, EvqTemporary, structLine);
3017 publicType.userDef = structureType;
3018 exitStructDeclaration();
3023 bool TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString& identifier)
3025 ++mStructNestingLevel;
3027 // Embedded structure definitions are not supported per GLSL ES spec.
3028 // They aren't allowed in GLSL either, but we need to detect this here
3029 // so we don't rely on the GLSL compiler to catch it.
3030 if (mStructNestingLevel > 1) {
3031 error(line, "", "Embedded struct definitions are not allowed");
3038 void TParseContext::exitStructDeclaration()
3040 --mStructNestingLevel;
3043 bool TParseContext::structNestingErrorCheck(const TSourceLoc &line, const TField &field)
3045 static const int kWebGLMaxStructNesting = 4;
3047 if(field.type()->getBasicType() != EbtStruct)
3052 // We're already inside a structure definition at this point, so add
3053 // one to the field's struct nesting.
3054 if(1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting)
3056 std::stringstream reasonStream;
3057 reasonStream << "Reference of struct type "
3058 << field.type()->getStruct()->name().c_str()
3059 << " exceeds maximum allowed nesting level of "
3060 << kWebGLMaxStructNesting;
3061 std::string reason = reasonStream.str();
3062 error(line, reason.c_str(), field.name().c_str(), "");
3069 TIntermTyped *TParseContext::createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc, const TType *funcReturnType)
3071 if(child == nullptr)
3079 if(child->getBasicType() != EbtBool ||
3080 child->isMatrix() ||
3088 if((child->getBasicType() != EbtInt && child->getBasicType() != EbtUInt) ||
3089 child->isMatrix() ||
3095 case EOpPostIncrement:
3096 case EOpPreIncrement:
3097 case EOpPostDecrement:
3098 case EOpPreDecrement:
3100 if(child->getBasicType() == EbtStruct ||
3101 child->getBasicType() == EbtBool ||
3106 // Operators for built-ins are already type checked against their prototype.
3111 return intermediate.addUnaryMath(op, child, loc, funcReturnType);
3114 TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
3116 TIntermTyped *node = createUnaryMath(op, child, loc, nullptr);
3119 unaryOpError(loc, getOperatorString(op), child->getCompleteString());
3126 TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
3128 if(lValueErrorCheck(loc, getOperatorString(op), child))
3130 return addUnaryMath(op, child, loc);
3133 bool TParseContext::binaryOpCommonCheck(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc)
3135 if(left->isArray() || right->isArray())
3137 if(mShaderVersion < 300)
3139 error(loc, "Invalid operation for arrays", getOperatorString(op));
3143 if(left->isArray() != right->isArray())
3145 error(loc, "array / non-array mismatch", getOperatorString(op));
3157 error(loc, "Invalid operation for arrays", getOperatorString(op));
3160 // At this point, size of implicitly sized arrays should be resolved.
3161 if(left->getArraySize() != right->getArraySize())
3163 error(loc, "array size mismatch", getOperatorString(op));
3168 // Check ops which require integer / ivec parameters
3169 bool isBitShift = false;
3172 case EOpBitShiftLeft:
3173 case EOpBitShiftRight:
3174 case EOpBitShiftLeftAssign:
3175 case EOpBitShiftRightAssign:
3176 // Unsigned can be bit-shifted by signed and vice versa, but we need to
3177 // check that the basic type is an integer type.
3179 if(!IsInteger(left->getBasicType()) || !IsInteger(right->getBasicType()))
3187 case EOpBitwiseAndAssign:
3188 case EOpBitwiseXorAssign:
3189 case EOpBitwiseOrAssign:
3190 // It is enough to check the type of only one operand, since later it
3191 // is checked that the operand types match.
3192 if(!IsInteger(left->getBasicType()))
3201 // GLSL ES 1.00 and 3.00 do not support implicit type casting.
3202 // So the basic type should usually match.
3203 if(!isBitShift && left->getBasicType() != right->getBasicType())
3208 // Check that type sizes match exactly on ops that require that.
3209 // Also check restrictions for structs that contain arrays or samplers.
3216 // ESSL 1.00 sections 5.7, 5.8, 5.9
3217 if(mShaderVersion < 300 && left->getType().isStructureContainingArrays())
3219 error(loc, "undefined operation for structs containing arrays", getOperatorString(op));
3222 // Samplers as l-values are disallowed also in ESSL 3.00, see section 4.1.7,
3223 // we interpret the spec so that this extends to structs containing samplers,
3224 // similarly to ESSL 1.00 spec.
3225 if((mShaderVersion < 300 || op == EOpAssign || op == EOpInitialize) &&
3226 left->getType().isStructureContainingSamplers())
3228 error(loc, "undefined operation for structs containing samplers", getOperatorString(op));
3232 case EOpGreaterThan:
3233 case EOpLessThanEqual:
3234 case EOpGreaterThanEqual:
3235 if((left->getNominalSize() != right->getNominalSize()) ||
3236 (left->getSecondarySize() != right->getSecondarySize()))
3247 TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &loc)
3249 TBasicType switchType = init->getBasicType();
3250 if((switchType != EbtInt && switchType != EbtUInt) ||
3255 error(init->getLine(), "init-expression in a switch statement must be a scalar integer", "switch");
3262 if(!ValidateSwitch::validate(switchType, this, statementList, loc))
3269 TIntermSwitch *node = intermediate.addSwitch(init, statementList, loc);
3272 error(loc, "erroneous switch statement", "switch");
3279 TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &loc)
3281 if(mSwitchNestingLevel == 0)
3283 error(loc, "case labels need to be inside switch statements", "case");
3287 if(condition == nullptr)
3289 error(loc, "case label must have a condition", "case");
3293 if((condition->getBasicType() != EbtInt && condition->getBasicType() != EbtUInt) ||
3294 condition->isMatrix() ||
3295 condition->isArray() ||
3296 condition->isVector())
3298 error(condition->getLine(), "case label must be a scalar integer", "case");
3301 TIntermConstantUnion *conditionConst = condition->getAsConstantUnion();
3302 if(conditionConst == nullptr)
3304 error(condition->getLine(), "case label must be constant", "case");
3307 TIntermCase *node = intermediate.addCase(condition, loc);
3310 error(loc, "erroneous case statement", "case");
3317 TIntermCase *TParseContext::addDefault(const TSourceLoc &loc)
3319 if(mSwitchNestingLevel == 0)
3321 error(loc, "default labels need to be inside switch statements", "default");
3325 TIntermCase *node = intermediate.addCase(nullptr, loc);
3328 error(loc, "erroneous default statement", "default");
3334 TIntermTyped *TParseContext::createAssign(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc)
3336 if(binaryOpCommonCheck(op, left, right, loc))
3338 return intermediate.addAssign(op, left, right, loc);
3343 TIntermTyped *TParseContext::addAssign(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc)
3345 TIntermTyped *node = createAssign(op, left, right, loc);
3348 assignError(loc, "assign", left->getCompleteString(), right->getCompleteString());
3355 TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, TIntermTyped *left, TIntermTyped *right,
3356 const TSourceLoc &loc)
3358 if(!binaryOpCommonCheck(op, left, right, loc))
3367 case EOpGreaterThan:
3368 case EOpLessThanEqual:
3369 case EOpGreaterThanEqual:
3370 ASSERT(!left->isArray() && !right->isArray());
3371 if(left->isMatrix() || left->isVector() ||
3372 left->getBasicType() == EbtStruct)
3380 ASSERT(!left->isArray() && !right->isArray());
3381 if(left->getBasicType() != EbtBool ||
3382 left->isMatrix() || left->isVector())
3391 ASSERT(!left->isArray() && !right->isArray());
3392 if(left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool)
3398 ASSERT(!left->isArray() && !right->isArray());
3399 // Note that this is only for the % operator, not for mod()
3400 if(left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat)
3405 // Note that for bitwise ops, type checking is done in promote() to
3406 // share code between ops and compound assignment
3411 return intermediate.addBinaryMath(op, left, right, loc);
3414 TIntermTyped *TParseContext::addBinaryMath(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc)
3416 TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
3419 binaryOpError(loc, getOperatorString(op), left->getCompleteString(), right->getCompleteString());
3426 TIntermTyped *TParseContext::addBinaryMathBooleanResult(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc)
3428 TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
3431 binaryOpError(loc, getOperatorString(op), left->getCompleteString(), right->getCompleteString());
3433 ConstantUnion *unionArray = new ConstantUnion[1];
3434 unionArray->setBConst(false);
3435 return intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConstExpr), loc);
3440 TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc)
3445 if(mLoopNestingLevel <= 0)
3447 error(loc, "continue statement only allowed in loops", "");
3452 if(mLoopNestingLevel <= 0 && mSwitchNestingLevel <= 0)
3454 error(loc, "break statement only allowed in loops and switch statements", "");
3459 if(mCurrentFunctionType->getBasicType() != EbtVoid)
3461 error(loc, "non-void function must return a value", "return");
3466 // No checks for discard
3469 return intermediate.addBranch(op, loc);
3472 TIntermBranch *TParseContext::addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc)
3474 ASSERT(op == EOpReturn);
3475 mFunctionReturnsValue = true;
3476 if(mCurrentFunctionType->getBasicType() == EbtVoid)
3478 error(loc, "void function cannot return a value", "return");
3481 else if(*mCurrentFunctionType != returnValue->getType())
3483 error(loc, "function return is not matching type:", "return");
3486 return intermediate.addBranch(op, returnValue, loc);
3489 TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, TIntermNode *paramNode, TIntermNode *thisNode, const TSourceLoc &loc, bool *fatalError)
3491 *fatalError = false;
3492 TOperator op = fnCall->getBuiltInOp();
3493 TIntermTyped *callNode = nullptr;
3495 if(thisNode != nullptr)
3497 ConstantUnion *unionArray = new ConstantUnion[1];
3499 TIntermTyped *typedThis = thisNode->getAsTyped();
3500 if(fnCall->getName() != "length")
3502 error(loc, "invalid method", fnCall->getName().c_str());
3505 else if(paramNode != nullptr)
3507 error(loc, "method takes no parameters", "length");
3510 else if(typedThis == nullptr || !typedThis->isArray())
3512 error(loc, "length can only be called on arrays", "length");
3517 arraySize = typedThis->getArraySize();
3518 if(typedThis->getAsSymbolNode() == nullptr)
3520 // This code path can be hit with expressions like these:
3522 // (func()).length()
3523 // (int[3](0, 1, 2)).length()
3524 // ESSL 3.00 section 5.9 defines expressions so that this is not actually a valid expression.
3525 // It allows "An array name with the length method applied" in contrast to GLSL 4.4 spec section 5.9
3526 // which allows "An array, vector or matrix expression with the length method applied".
3527 error(loc, "length can only be called on array names, not on array expressions", "length");
3531 unionArray->setIConst(arraySize);
3532 callNode = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConstExpr), loc);
3534 else if(op != EOpNull)
3537 // Then this should be a constructor.
3538 // Don't go through the symbol table for constructors.
3539 // Their parameters will be verified algorithmically.
3541 TType type(EbtVoid, EbpUndefined); // use this to get the type back
3542 if(!constructorErrorCheck(loc, paramNode, *fnCall, op, &type))
3545 // It's a constructor, of type 'type'.
3547 callNode = addConstructor(paramNode, &type, op, fnCall, loc);
3550 if(callNode == nullptr)
3553 callNode = intermediate.setAggregateOperator(nullptr, op, loc);
3559 // Not a constructor. Find it in the symbol table.
3561 const TFunction *fnCandidate;
3563 fnCandidate = findFunction(loc, fnCall, &builtIn);
3567 // A declared function.
3569 if(builtIn && !fnCandidate->getExtension().empty() &&
3570 extensionErrorCheck(loc, fnCandidate->getExtension()))
3574 op = fnCandidate->getBuiltInOp();
3575 if(builtIn && op != EOpNull)
3578 // A function call mapped to a built-in operation.
3580 if(fnCandidate->getParamCount() == 1)
3583 // Treat it like a built-in unary operator.
3585 callNode = createUnaryMath(op, paramNode->getAsTyped(), loc, &fnCandidate->getReturnType());
3586 if(callNode == nullptr)
3588 std::stringstream extraInfoStream;
3589 extraInfoStream << "built in unary operator function. Type: "
3590 << static_cast<TIntermTyped*>(paramNode)->getCompleteString();
3591 std::string extraInfo = extraInfoStream.str();
3592 error(paramNode->getLine(), " wrong operand type", "Internal Error", extraInfo.c_str());
3599 TIntermAggregate *aggregate = intermediate.setAggregateOperator(paramNode, op, loc);
3600 aggregate->setType(fnCandidate->getReturnType());
3602 // Some built-in functions have out parameters too.
3603 functionCallLValueErrorCheck(fnCandidate, aggregate);
3605 callNode = aggregate;
3607 if(fnCandidate->getParamCount() == 2)
3609 TIntermSequence ¶meters = paramNode->getAsAggregate()->getSequence();
3610 TIntermTyped *left = parameters[0]->getAsTyped();
3611 TIntermTyped *right = parameters[1]->getAsTyped();
3613 TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
3614 TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
3615 if (leftTempConstant && rightTempConstant)
3617 TIntermTyped *typedReturnNode = leftTempConstant->fold(op, rightTempConstant, infoSink());
3621 callNode = typedReturnNode;
3629 // This is a real function call
3631 TIntermAggregate *aggregate = intermediate.setAggregateOperator(paramNode, EOpFunctionCall, loc);
3632 aggregate->setType(fnCandidate->getReturnType());
3634 // this is how we know whether the given function is a builtIn function or a user defined function
3635 // if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also
3636 // if builtIn == true, it's definitely a builtIn function with EOpNull
3638 aggregate->setUserDefined();
3639 aggregate->setName(fnCandidate->getMangledName());
3641 callNode = aggregate;
3643 functionCallLValueErrorCheck(fnCandidate, aggregate);
3648 // error message was put out by findFunction()
3649 // Put on a dummy node for error recovery
3650 ConstantUnion *unionArray = new ConstantUnion[1];
3651 unionArray->setFConst(0.0f);
3652 callNode = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConstExpr), loc);
3660 TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &loc)
3662 if(boolErrorCheck(loc, cond))
3665 if(trueBlock->getType() != falseBlock->getType())
3667 binaryOpError(loc, ":", trueBlock->getCompleteString(), falseBlock->getCompleteString());
3671 // ESSL1 sections 5.2 and 5.7:
3672 // ESSL3 section 5.7:
3673 // Ternary operator is not among the operators allowed for structures/arrays.
3674 if(trueBlock->isArray() || trueBlock->getBasicType() == EbtStruct)
3676 error(loc, "ternary operator is not allowed for structures or arrays", ":");
3680 return intermediate.addSelection(cond, trueBlock, falseBlock, loc);
3684 // Parse an array of strings using yyparse.
3686 // Returns 0 for success.
3688 int PaParseStrings(int count, const char* const string[], const int length[],
3689 TParseContext* context) {
3690 if ((count == 0) || !string)
3693 if (glslang_initialize(context))
3696 int error = glslang_scan(count, string, length, context);
3698 error = glslang_parse(context);
3700 glslang_finalize(context);
3702 return (error == 0) && (context->numErrors() == 0) ? 0 : 1;