OSDN Git Service

GLSL const arrays are allowed in OpenGL ES 3.0
[android-x86/external-swiftshader.git] / src / OpenGL / compiler / ParseHelper.cpp
1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
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
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
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.
14
15 #include "ParseHelper.h"
16
17 #include <stdarg.h>
18 #include <stdio.h>
19
20 #include "glslang.h"
21 #include "preprocessor/SourceLocation.h"
22 #include "ValidateGlobalInitializer.h"
23 #include "ValidateSwitch.h"
24
25 ///////////////////////////////////////////////////////////////////////
26 //
27 // Sub- vector and matrix fields
28 //
29 ////////////////////////////////////////////////////////////////////////
30
31 //
32 // Look at a '.' field selector string and change it into offsets
33 // for a vector.
34 //
35 bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, const TSourceLoc &line)
36 {
37         fields.num = (int) compString.size();
38         if (fields.num > 4) {
39                 error(line, "illegal vector field selection", compString.c_str());
40                 return false;
41         }
42
43         enum {
44                 exyzw,
45                 ergba,
46                 estpq
47         } fieldSet[4];
48
49         for (int i = 0; i < fields.num; ++i) {
50                 switch (compString[i])  {
51                 case 'x':
52                         fields.offsets[i] = 0;
53                         fieldSet[i] = exyzw;
54                         break;
55                 case 'r':
56                         fields.offsets[i] = 0;
57                         fieldSet[i] = ergba;
58                         break;
59                 case 's':
60                         fields.offsets[i] = 0;
61                         fieldSet[i] = estpq;
62                         break;
63                 case 'y':
64                         fields.offsets[i] = 1;
65                         fieldSet[i] = exyzw;
66                         break;
67                 case 'g':
68                         fields.offsets[i] = 1;
69                         fieldSet[i] = ergba;
70                         break;
71                 case 't':
72                         fields.offsets[i] = 1;
73                         fieldSet[i] = estpq;
74                         break;
75                 case 'z':
76                         fields.offsets[i] = 2;
77                         fieldSet[i] = exyzw;
78                         break;
79                 case 'b':
80                         fields.offsets[i] = 2;
81                         fieldSet[i] = ergba;
82                         break;
83                 case 'p':
84                         fields.offsets[i] = 2;
85                         fieldSet[i] = estpq;
86                         break;
87                 case 'w':
88                         fields.offsets[i] = 3;
89                         fieldSet[i] = exyzw;
90                         break;
91                 case 'a':
92                         fields.offsets[i] = 3;
93                         fieldSet[i] = ergba;
94                         break;
95                 case 'q':
96                         fields.offsets[i] = 3;
97                         fieldSet[i] = estpq;
98                         break;
99                 default:
100                         error(line, "illegal vector field selection", compString.c_str());
101                         return false;
102                 }
103         }
104
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());
108                         return false;
109                 }
110
111                 if (i > 0) {
112                         if (fieldSet[i] != fieldSet[i-1]) {
113                                 error(line, "illegal - vector component fields not from the same set", compString.c_str());
114                                 return false;
115                         }
116                 }
117         }
118
119         return true;
120 }
121
122
123 //
124 // Look at a '.' field selector string and change it into offsets
125 // for a matrix.
126 //
127 bool TParseContext::parseMatrixFields(const TString& compString, int matCols, int matRows, TMatrixFields& fields, const TSourceLoc &line)
128 {
129         fields.wholeRow = false;
130         fields.wholeCol = false;
131         fields.row = -1;
132         fields.col = -1;
133
134         if (compString.size() != 2) {
135                 error(line, "illegal length of matrix field selection", compString.c_str());
136                 return false;
137         }
138
139         if (compString[0] == '_') {
140                 if (compString[1] < '0' || compString[1] > '3') {
141                         error(line, "illegal matrix field selection", compString.c_str());
142                         return false;
143                 }
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());
149                         return false;
150                 }
151                 fields.wholeRow = true;
152                 fields.row = compString[0] - '0';
153         } else {
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());
157                         return false;
158                 }
159                 fields.row = compString[0] - '0';
160                 fields.col = compString[1] - '0';
161         }
162
163         if (fields.row >= matRows || fields.col >= matCols) {
164                 error(line, "matrix field selection out of range", compString.c_str());
165                 return false;
166         }
167
168         return true;
169 }
170
171 ///////////////////////////////////////////////////////////////////////
172 //
173 // Errors
174 //
175 ////////////////////////////////////////////////////////////////////////
176
177 //
178 // Track whether errors have occurred.
179 //
180 void TParseContext::recover()
181 {
182 }
183
184 //
185 // Used by flex/bison to output all syntax and parsing errors.
186 //
187 void TParseContext::error(const TSourceLoc& loc,
188                                                   const char* reason, const char* token,
189                                                   const char* extraInfo)
190 {
191         pp::SourceLocation srcLoc(loc.first_file, loc.first_line);
192         mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR,
193                                                    srcLoc, reason, token, extraInfo);
194
195 }
196
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);
203 }
204
205 void TParseContext::trace(const char* str)
206 {
207         mDiagnostics.writeDebug(str);
208 }
209
210 //
211 // Same error message for all places assignments don't work.
212 //
213 void TParseContext::assignError(const TSourceLoc &line, const char* op, TString left, TString right)
214 {
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());
219 }
220
221 //
222 // Same error message for all places unary operations don't work.
223 //
224 void TParseContext::unaryOpError(const TSourceLoc &line, const char* op, TString operand)
225 {
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());
231 }
232
233 //
234 // Same error message for all binary operations don't work.
235 //
236 void TParseContext::binaryOpError(const TSourceLoc &line, const char* op, TString left, TString right)
237 {
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());
243 }
244
245 bool TParseContext::precisionErrorCheck(const TSourceLoc &line, TPrecision precision, TBasicType type){
246         if (!mChecksPrecisionErrors)
247                 return false;
248         switch( type ){
249         case EbtFloat:
250                 if( precision == EbpUndefined ){
251                         error( line, "No precision specified for (float)", "" );
252                         return true;
253                 }
254                 break;
255         case EbtInt:
256                 if( precision == EbpUndefined ){
257                         error( line, "No precision specified (int)", "" );
258                         return true;
259                 }
260                 break;
261         default:
262                 return false;
263         }
264         return false;
265 }
266
267 //
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.
270 //
271 // Returns true if the was an error.
272 //
273 bool TParseContext::lValueErrorCheck(const TSourceLoc &line, const char* op, TIntermTyped* node)
274 {
275         TIntermSymbol* symNode = node->getAsSymbolNode();
276         TIntermBinary* binaryNode = node->getAsBinaryNode();
277
278         if (binaryNode) {
279                 bool errorReturn;
280
281                 switch(binaryNode->getOp()) {
282                 case EOpIndexDirect:
283                 case EOpIndexIndirect:
284                 case EOpIndexDirectStruct:
285                         return lValueErrorCheck(line, op, binaryNode->getLeft());
286                 case EOpVectorSwizzle:
287                         errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft());
288                         if (!errorReturn) {
289                                 int offset[4] = {0,0,0,0};
290
291                                 TIntermTyped* rightNode = binaryNode->getRight();
292                                 TIntermAggregate *aggrNode = rightNode->getAsAggregate();
293
294                                 for (TIntermSequence::iterator p = aggrNode->getSequence().begin();
295                                                                                            p != aggrNode->getSequence().end(); p++) {
296                                         int value = (*p)->getAsTyped()->getAsConstantUnion()->getIConst(0);
297                                         offset[value]++;
298                                         if (offset[value] > 1) {
299                                                 error(line, " l-value of swizzle cannot have duplicate components", op);
300
301                                                 return true;
302                                         }
303                                 }
304                         }
305
306                         return errorReturn;
307                 default:
308                         break;
309                 }
310                 error(line, " l-value required", op);
311
312                 return true;
313         }
314
315
316         const char* symbol = 0;
317         if (symNode != 0)
318                 symbol = symNode->getSymbol().c_str();
319
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;
328         case EvqSmoothIn:
329         case EvqFlatIn:
330         case EvqCentroidIn:
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;
337         default:
338
339                 //
340                 // Type that can't be written to?
341                 //
342                 if(IsSampler(node->getBasicType()))
343                 {
344                         message = "can't modify a sampler";
345                 }
346                 else if(node->getBasicType() == EbtVoid)
347                 {
348                         message = "can't modify void";
349                 }
350         }
351
352         if (message == 0 && binaryNode == 0 && symNode == 0) {
353                 error(line, " l-value required", op);
354
355                 return true;
356         }
357
358
359         //
360         // Everything else is okay, no error.
361         //
362         if (message == 0)
363                 return false;
364
365         //
366         // If we get here, we have an error and a message.
367         //
368         if (symNode) {
369                 std::stringstream extraInfoStream;
370                 extraInfoStream << "\"" << symbol << "\" (" << message << ")";
371                 std::string extraInfo = extraInfoStream.str();
372                 error(line, " l-value required", op, extraInfo.c_str());
373         }
374         else {
375                 std::stringstream extraInfoStream;
376                 extraInfoStream << "(" << message << ")";
377                 std::string extraInfo = extraInfoStream.str();
378                 error(line, " l-value required", op, extraInfo.c_str());
379         }
380
381         return true;
382 }
383
384 //
385 // Both test, and if necessary spit out an error, to see if the node is really
386 // a constant.
387 //
388 // Returns true if the was an error.
389 //
390 bool TParseContext::constErrorCheck(TIntermTyped* node)
391 {
392         if (node->getQualifier() == EvqConstExpr)
393                 return false;
394
395         error(node->getLine(), "constant expression required", "");
396
397         return true;
398 }
399
400 //
401 // Both test, and if necessary spit out an error, to see if the node is really
402 // an integer.
403 //
404 // Returns true if the was an error.
405 //
406 bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token)
407 {
408         if (node->isScalarInt())
409                 return false;
410
411         error(node->getLine(), "integer expression required", token);
412
413         return true;
414 }
415
416 //
417 // Both test, and if necessary spit out an error, to see if we are currently
418 // globally scoped.
419 //
420 // Returns true if the was an error.
421 //
422 bool TParseContext::globalErrorCheck(const TSourceLoc &line, bool global, const char* token)
423 {
424         if (global)
425                 return false;
426
427         error(line, "only allowed at global scope", token);
428
429         return true;
430 }
431
432 //
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
437 // webgl shader.
438 //
439 // Returns true if there was an error.
440 //
441 bool TParseContext::reservedErrorCheck(const TSourceLoc &line, const TString& identifier)
442 {
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_");
447                         return true;
448                 }
449                 if (identifier.find("__") != TString::npos) {
450                         error(line, "identifiers containing two consecutive underscores (__) are reserved as possible future keywords", identifier.c_str());
451                         return true;
452                 }
453         }
454
455         return false;
456 }
457
458 //
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
461 // the constructor.
462 //
463 // Returns true if there was an error in construction.
464 //
465 bool TParseContext::constructorErrorCheck(const TSourceLoc &line, TIntermNode* node, TFunction& function, TOperator op, TType* type)
466 {
467         *type = function.getReturnType();
468
469         bool constructingMatrix = false;
470         switch(op) {
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;
481                 break;
482         default:
483                 break;
484         }
485
486         //
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.
490         //
491
492         size_t size = 0;
493         bool full = false;
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();
500
501                 if (constructingMatrix && param.type->isMatrix())
502                         matrixInMatrix = true;
503                 if (full)
504                         overFull = true;
505                 if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize())
506                         full = true;
507                 if (param.type->isArray())
508                         arrayArg = true;
509         }
510
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");
516                         return true;
517                 }
518         }
519
520         if (arrayArg && op != EOpConstructStruct) {
521                 error(line, "constructing from a non-dereferenced array", "constructor");
522                 return true;
523         }
524
525         if (matrixInMatrix && !type->isArray()) {
526                 if (function.getParamCount() != 1) {
527                   error(line, "constructing matrix from matrix can only take one argument", "constructor");
528                   return true;
529                 }
530         }
531
532         if (overFull) {
533                 error(line, "too many arguments", "constructor");
534                 return true;
535         }
536
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");
539                 return true;
540         }
541
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");
546                         return true;
547                 }
548         }
549
550         TIntermTyped *typed = node ? node->getAsTyped() : 0;
551         if (typed == 0) {
552                 error(line, "constructor argument does not have a type", "constructor");
553                 return true;
554         }
555         if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) {
556                 error(line, "cannot convert a sampler", "constructor");
557                 return true;
558         }
559         if (typed->getBasicType() == EbtVoid) {
560                 error(line, "cannot convert a void", "constructor");
561                 return true;
562         }
563
564         return false;
565 }
566
567 // This function checks to see if a void variable has been declared and raise an error message for such a case
568 //
569 // returns true in case of an error
570 //
571 bool TParseContext::voidErrorCheck(const TSourceLoc &line, const TString& identifier, const TBasicType& type)
572 {
573         if(type == EbtVoid) {
574                 error(line, "illegal use of type 'void'", identifier.c_str());
575                 return true;
576         }
577
578         return false;
579 }
580
581 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
582 //
583 // returns true in case of an error
584 //
585 bool TParseContext::boolErrorCheck(const TSourceLoc &line, const TIntermTyped* type)
586 {
587         if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) {
588                 error(line, "boolean expression expected", "");
589                 return true;
590         }
591
592         return false;
593 }
594
595 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
596 //
597 // returns true in case of an error
598 //
599 bool TParseContext::boolErrorCheck(const TSourceLoc &line, const TPublicType& pType)
600 {
601         if (pType.type != EbtBool || pType.array || (pType.primarySize > 1) || (pType.secondarySize > 1)) {
602                 error(line, "boolean expression expected", "");
603                 return true;
604         }
605
606         return false;
607 }
608
609 bool TParseContext::samplerErrorCheck(const TSourceLoc &line, const TPublicType& pType, const char* reason)
610 {
611         if (pType.type == EbtStruct) {
612                 if (containsSampler(*pType.userDef)) {
613                         error(line, reason, getBasicString(pType.type), "(structure contains a sampler)");
614
615                         return true;
616                 }
617
618                 return false;
619         } else if (IsSampler(pType.type)) {
620                 error(line, reason, getBasicString(pType.type));
621
622                 return true;
623         }
624
625         return false;
626 }
627
628 bool TParseContext::structQualifierErrorCheck(const TSourceLoc &line, const TPublicType& pType)
629 {
630         switch(pType.qualifier)
631         {
632         case EvqVaryingOut:
633         case EvqSmooth:
634         case EvqFlat:
635         case EvqCentroidOut:
636         case EvqVaryingIn:
637         case EvqSmoothIn:
638         case EvqFlatIn:
639         case EvqCentroidIn:
640         case EvqAttribute:
641         case EvqVertexIn:
642         case EvqFragmentOut:
643                 if(pType.type == EbtStruct)
644                 {
645                         error(line, "cannot be used with a structure", getQualifierString(pType.qualifier));
646
647                         return true;
648                 }
649                 break;
650         default:
651                 break;
652         }
653
654         if (pType.qualifier != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform"))
655                 return true;
656
657         // check for layout qualifier issues
658         if (pType.qualifier != EvqVertexIn && pType.qualifier != EvqFragmentOut &&
659                 layoutLocationErrorCheck(line, pType.layoutQualifier))
660         {
661                 return true;
662         }
663
664         return false;
665 }
666
667 // These checks are common for all declarations starting a declarator list, and declarators that follow an empty
668 // declaration.
669 //
670 bool TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &identifierLocation)
671 {
672         switch(publicType.qualifier)
673         {
674         case EvqVaryingIn:
675         case EvqVaryingOut:
676         case EvqAttribute:
677         case EvqVertexIn:
678         case EvqFragmentOut:
679                 if(publicType.type == EbtStruct)
680                 {
681                         error(identifierLocation, "cannot be used with a structure",
682                                 getQualifierString(publicType.qualifier));
683                         return true;
684                 }
685
686         default: break;
687         }
688
689         if(publicType.qualifier != EvqUniform && samplerErrorCheck(identifierLocation, publicType,
690                 "samplers must be uniform"))
691         {
692                 return true;
693         }
694
695         // check for layout qualifier issues
696         const TLayoutQualifier layoutQualifier = publicType.layoutQualifier;
697
698         if(layoutQualifier.matrixPacking != EmpUnspecified)
699         {
700                 error(identifierLocation, "layout qualifier", getMatrixPackingString(layoutQualifier.matrixPacking),
701                         "only valid for interface blocks");
702                 return true;
703         }
704
705         if(layoutQualifier.blockStorage != EbsUnspecified)
706         {
707                 error(identifierLocation, "layout qualifier", getBlockStorageString(layoutQualifier.blockStorage),
708                         "only valid for interface blocks");
709                 return true;
710         }
711
712         if(publicType.qualifier != EvqVertexIn && publicType.qualifier != EvqFragmentOut &&
713                 layoutLocationErrorCheck(identifierLocation, publicType.layoutQualifier))
714         {
715                 return true;
716         }
717
718         return false;
719 }
720
721 bool TParseContext::layoutLocationErrorCheck(const TSourceLoc &location, const TLayoutQualifier &layoutQualifier)
722 {
723         if(layoutQualifier.location != -1)
724         {
725                 error(location, "invalid layout qualifier:", "location", "only valid on program inputs and outputs");
726                 return true;
727         }
728
729         return false;
730 }
731
732 bool TParseContext::locationDeclaratorListCheck(const TSourceLoc& line, const TPublicType &pType)
733 {
734         if(pType.layoutQualifier.location != -1)
735         {
736                 error(line, "location must only be specified for a single input or output variable", "location");
737                 return true;
738         }
739
740         return false;
741 }
742
743 bool TParseContext::parameterSamplerErrorCheck(const TSourceLoc &line, TQualifier qualifier, const TType& type)
744 {
745         if ((qualifier == EvqOut || qualifier == EvqInOut) &&
746                          type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
747                 error(line, "samplers cannot be output parameters", type.getBasicString());
748                 return true;
749         }
750
751         return false;
752 }
753
754 bool TParseContext::containsSampler(TType& type)
755 {
756         if (IsSampler(type.getBasicType()))
757                 return true;
758
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()))
763                                 return true;
764                 }
765         }
766
767         return false;
768 }
769
770 //
771 // Do size checking for an array type's size.
772 //
773 // Returns true if there was an error.
774 //
775 bool TParseContext::arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped* expr, int& size)
776 {
777         TIntermConstantUnion* constant = expr->getAsConstantUnion();
778
779         if (constant == 0 || !constant->isScalarInt())
780         {
781                 error(line, "array size must be a constant integer expression", "");
782                 return true;
783         }
784
785         if (constant->getBasicType() == EbtUInt)
786         {
787                 unsigned int uintSize = constant->getUConst(0);
788                 if (uintSize > static_cast<unsigned int>(std::numeric_limits<int>::max()))
789                 {
790                         error(line, "array size too large", "");
791                         size = 1;
792                         return true;
793                 }
794
795                 size = static_cast<int>(uintSize);
796         }
797         else
798         {
799                 size = constant->getIConst(0);
800
801                 if (size <= 0)
802                 {
803                         error(line, "array size must be a positive integer", "");
804                         size = 1;
805                         return true;
806                 }
807         }
808
809         return false;
810 }
811
812 //
813 // See if this qualifier can be an array.
814 //
815 // Returns true if there is an error.
816 //
817 bool TParseContext::arrayQualifierErrorCheck(const TSourceLoc &line, TPublicType type)
818 {
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());
821                 return true;
822         }
823
824         return false;
825 }
826
827 //
828 // See if this type can be an array.
829 //
830 // Returns true if there is an error.
831 //
832 bool TParseContext::arrayTypeErrorCheck(const TSourceLoc &line, TPublicType type)
833 {
834         //
835         // Can the type be an array?
836         //
837         if (type.array) {
838                 error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str());
839                 return true;
840         }
841
842         return false;
843 }
844
845 bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, const TSourceLoc &line)
846 {
847         bool builtIn = false;
848         TSymbol* symbol = symbolTable.find(node->getSymbol(), mShaderVersion, &builtIn);
849         if (symbol == 0) {
850                 error(line, " undeclared identifier", node->getSymbol().c_str());
851                 return true;
852         }
853         TVariable* variable = static_cast<TVariable*>(symbol);
854
855         type->setArrayInformationType(variable->getArrayInformationType());
856         variable->updateArrayInformationType(type);
857
858         // special casing to test index value of gl_FragData. If the accessed index is >= gl_MaxDrawBuffers
859         // its an error
860         if (node->getSymbol() == "gl_FragData") {
861                 TSymbol* fragData = symbolTable.find("gl_MaxDrawBuffers", mShaderVersion, &builtIn);
862                 ASSERT(fragData);
863
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");
867                         return true;
868                 }
869         }
870
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.
873         if (!updateFlag)
874                 return false;
875
876         size++;
877         variable->getType().setMaxArraySize(size);
878         type->setMaxArraySize(size);
879         TType* tt = type;
880
881         while(tt->getArrayInformationType() != 0) {
882                 tt = tt->getArrayInformationType();
883                 tt->setMaxArraySize(size);
884         }
885
886         return false;
887 }
888
889 //
890 // Enforce non-initializer type/qualifier rules.
891 //
892 // Returns true if there was an error.
893 //
894 bool TParseContext::nonInitConstErrorCheck(const TSourceLoc &line, TString& identifier, TPublicType& type, bool array)
895 {
896         if (type.qualifier == EvqConstExpr)
897         {
898                 // Make the qualifier make sense.
899                 type.qualifier = EvqTemporary;
900
901                 if (array)
902                 {
903                         error(line, "arrays may not be declared constant since they cannot be initialized", identifier.c_str());
904                 }
905                 else if (type.isStructureContainingArrays())
906                 {
907                         error(line, "structures containing arrays may not be declared constant since they cannot be initialized", identifier.c_str());
908                 }
909                 else
910                 {
911                         error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
912                 }
913
914                 return true;
915         }
916
917         return false;
918 }
919
920 //
921 // Do semantic checking for a variable declaration that has no initializer,
922 // and update the symbol table.
923 //
924 // Returns true if there was an error.
925 //
926 bool TParseContext::nonInitErrorCheck(const TSourceLoc &line, const TString& identifier, TPublicType& type)
927 {
928         if(type.qualifier == EvqConstExpr)
929         {
930                 // Make the qualifier make sense.
931                 type.qualifier = EvqTemporary;
932
933                 // Generate informative error messages for ESSL1.
934                 // In ESSL3 arrays and structures containing arrays can be constant.
935                 if(mShaderVersion < 300 && type.isStructureContainingArrays())
936                 {
937                         error(line,
938                                 "structures containing arrays may not be declared constant since they cannot be initialized",
939                                 identifier.c_str());
940                 }
941                 else
942                 {
943                         error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
944                 }
945
946                 return true;
947         }
948         if(type.isUnsizedArray())
949         {
950                 error(line, "implicitly sized arrays need to be initialized", identifier.c_str());
951                 return true;
952         }
953         return false;
954 }
955
956 // Do some simple checks that are shared between all variable declarations,
957 // and update the symbol table.
958 //
959 // Returns true if declaring the variable succeeded.
960 //
961 bool TParseContext::declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type,
962         TVariable **variable)
963 {
964         ASSERT((*variable) == nullptr);
965
966         // gl_LastFragData may be redeclared with a new precision qualifier
967         if(type.isArray() && identifier.compare(0, 15, "gl_LastFragData") == 0)
968         {
969                 const TVariable *maxDrawBuffers =
970                         static_cast<const TVariable *>(symbolTable.findBuiltIn("gl_MaxDrawBuffers", mShaderVersion));
971                 if(type.getArraySize() != maxDrawBuffers->getConstPointer()->getIConst())
972                 {
973                         error(line, "redeclaration of gl_LastFragData with size != gl_MaxDrawBuffers", identifier.c_str());
974                         return false;
975                 }
976         }
977
978         if(reservedErrorCheck(line, identifier))
979                 return false;
980
981         (*variable) = new TVariable(&identifier, type);
982         if(!symbolTable.declare(**variable))
983         {
984                 error(line, "redefinition", identifier.c_str());
985                 delete (*variable);
986                 (*variable) = nullptr;
987                 return false;
988         }
989
990         if(voidErrorCheck(line, identifier, type.getBasicType()))
991                 return false;
992
993         return true;
994 }
995
996 bool TParseContext::paramErrorCheck(const TSourceLoc &line, TQualifier qualifier, TQualifier paramQualifier, TType* type)
997 {
998         if (qualifier != EvqConstReadOnly && qualifier != EvqTemporary) {
999                 error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier));
1000                 return true;
1001         }
1002         if (qualifier == EvqConstReadOnly && paramQualifier != EvqIn) {
1003                 error(line, "qualifier not allowed with ", getQualifierString(qualifier), getQualifierString(paramQualifier));
1004                 return true;
1005         }
1006
1007         if (qualifier == EvqConstReadOnly)
1008                 type->setQualifier(EvqConstReadOnly);
1009         else
1010                 type->setQualifier(paramQualifier);
1011
1012         return false;
1013 }
1014
1015 bool TParseContext::extensionErrorCheck(const TSourceLoc &line, const TString& extension)
1016 {
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");
1021                 return true;
1022         }
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");
1026                 return true;
1027         }
1028         if (iter->second == EBhWarn) {
1029                 warning(line, "extension", extension.c_str(), "is being used");
1030                 return false;
1031         }
1032
1033         return false;
1034 }
1035
1036 bool TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *aggregate)
1037 {
1038         for(size_t i = 0; i < fnCandidate->getParamCount(); ++i)
1039         {
1040                 TQualifier qual = fnCandidate->getParam(i).type->getQualifier();
1041                 if(qual == EvqOut || qual == EvqInOut)
1042                 {
1043                         TIntermTyped *node = (aggregate->getSequence())[i]->getAsTyped();
1044                         if(lValueErrorCheck(node->getLine(), "assign", node))
1045                         {
1046                                 error(node->getLine(),
1047                                         "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
1048                                 recover();
1049                                 return true;
1050                         }
1051                 }
1052         }
1053         return false;
1054 }
1055
1056 void TParseContext::es3InvariantErrorCheck(const TQualifier qualifier, const TSourceLoc &invariantLocation)
1057 {
1058         switch(qualifier)
1059         {
1060         case EvqVaryingOut:
1061         case EvqSmoothOut:
1062         case EvqFlatOut:
1063         case EvqCentroidOut:
1064         case EvqVertexOut:
1065         case EvqFragmentOut:
1066                 break;
1067         default:
1068                 error(invariantLocation, "Only out variables can be invariant.", "invariant");
1069                 recover();
1070                 break;
1071         }
1072 }
1073
1074 bool TParseContext::supportsExtension(const char* extension)
1075 {
1076         const TExtensionBehavior& extbehavior = extensionBehavior();
1077         TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
1078         return (iter != extbehavior.end());
1079 }
1080
1081 void TParseContext::handleExtensionDirective(const TSourceLoc &line, const char* extName, const char* behavior)
1082 {
1083         pp::SourceLocation loc(line.first_file, line.first_line);
1084         mDirectiveHandler.handleExtension(loc, extName, behavior);
1085 }
1086
1087 void TParseContext::handlePragmaDirective(const TSourceLoc &line, const char* name, const char* value)
1088 {
1089         pp::SourceLocation loc(line.first_file, line.first_line);
1090         mDirectiveHandler.handlePragma(loc, name, value);
1091 }
1092
1093 /////////////////////////////////////////////////////////////////////////////////
1094 //
1095 // Non-Errors.
1096 //
1097 /////////////////////////////////////////////////////////////////////////////////
1098
1099 const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location,
1100         const TString *name,
1101         const TSymbol *symbol)
1102 {
1103         const TVariable *variable = nullptr;
1104
1105         if(!symbol)
1106         {
1107                 error(location, "undeclared identifier", name->c_str());
1108                 recover();
1109         }
1110         else if(!symbol->isVariable())
1111         {
1112                 error(location, "variable expected", name->c_str());
1113                 recover();
1114         }
1115         else
1116         {
1117                 variable = static_cast<const TVariable*>(symbol);
1118
1119                 if(symbolTable.findBuiltIn(variable->getName(), mShaderVersion))
1120                 {
1121                         recover();
1122                 }
1123
1124                 // Reject shaders using both gl_FragData and gl_FragColor
1125                 TQualifier qualifier = variable->getType().getQualifier();
1126                 if(qualifier == EvqFragData)
1127                 {
1128                         mUsesFragData = true;
1129                 }
1130                 else if(qualifier == EvqFragColor)
1131                 {
1132                         mUsesFragColor = true;
1133                 }
1134
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)
1140                 {
1141                         error(location, "cannot use both gl_FragData and gl_FragColor", name->c_str());
1142                         recover();
1143                 }
1144         }
1145
1146         if(!variable)
1147         {
1148                 TType type(EbtFloat, EbpUndefined);
1149                 TVariable *fakeVariable = new TVariable(name, type);
1150                 symbolTable.declare(*fakeVariable);
1151                 variable = fakeVariable;
1152         }
1153
1154         return variable;
1155 }
1156
1157 //
1158 // Look up a function name in the symbol table, and make sure it is a function.
1159 //
1160 // Return the function symbol if found, otherwise 0.
1161 //
1162 const TFunction* TParseContext::findFunction(const TSourceLoc &line, TFunction* call, bool *builtIn)
1163 {
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);
1167         if (symbol == 0) {
1168                 symbol = symbolTable.find(call->getMangledName(), mShaderVersion, builtIn);
1169         }
1170
1171         if (symbol == 0) {
1172                 error(line, "no matching overloaded function found", call->getName().c_str());
1173                 return nullptr;
1174         }
1175
1176         if (!symbol->isFunction()) {
1177                 error(line, "function name expected", call->getName().c_str());
1178                 return nullptr;
1179         }
1180
1181         return static_cast<const TFunction*>(symbol);
1182 }
1183
1184 //
1185 // Initializers show up in several places in the grammar.  Have one set of
1186 // code to handle them here.
1187 //
1188 bool TParseContext::executeInitializer(const TSourceLoc& line, const TString& identifier, const TPublicType& pType,
1189                                                                            TIntermTyped *initializer, TIntermNode **intermNode)
1190 {
1191         ASSERT(intermNode != nullptr);
1192         TType type = TType(pType);
1193
1194         if(type.isArray() && (type.getArraySize() == 0))
1195         {
1196                 type.setArraySize(initializer->getArraySize());
1197         }
1198
1199         TVariable *variable = nullptr;
1200         if(!declareVariable(line, identifier, type, &variable))
1201         {
1202                 return true;
1203         }
1204
1205         bool globalInitWarning = false;
1206         if(symbolTable.atGlobalLevel() && !ValidateGlobalInitializer(initializer, this, &globalInitWarning))
1207         {
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", "=");
1211                 return true;
1212         }
1213         if(globalInitWarning)
1214         {
1215                 warning(line, "global variable initializers should be constant expressions "
1216                         "(uniforms and globals are allowed in global initializers for legacy compatibility)", "=");
1217         }
1218
1219         //
1220         // identifier must be of type constant, a global, or a temporary
1221         //
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());
1225                 return true;
1226         }
1227         //
1228         // test for and propagate constant
1229         //
1230
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);
1238                         return true;
1239                 }
1240
1241                 if (type != initializer->getType()) {
1242                         error(line, " non-matching types for const initializer ",
1243                                 variable->getType().getQualifierString());
1244                         variable->getType().setQualifier(EvqTemporary);
1245                         return true;
1246                 }
1247
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);
1253
1254                         ConstantUnion* constArray = tVar->getConstPointer();
1255                         variable->shareConstPointer(constArray);
1256                 }
1257         }
1258
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());
1264                         return true;
1265                 }
1266         } else
1267                 *intermNode = nullptr;
1268
1269         return false;
1270 }
1271
1272 TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, bool invariant, TLayoutQualifier layoutQualifier, const TPublicType &typeSpecifier)
1273 {
1274         TPublicType returnType = typeSpecifier;
1275         returnType.qualifier = qualifier;
1276         returnType.invariant = invariant;
1277         returnType.layoutQualifier = layoutQualifier;
1278
1279         if(typeSpecifier.array)
1280         {
1281                 error(typeSpecifier.line, "not supported", "first-class array");
1282                 recover();
1283                 returnType.clearArrayness();
1284         }
1285
1286         if(mShaderVersion < 300)
1287         {
1288                 if(qualifier == EvqAttribute && (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt))
1289                 {
1290                         error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier));
1291                         recover();
1292                 }
1293
1294                 if((qualifier == EvqVaryingIn || qualifier == EvqVaryingOut) &&
1295                         (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt))
1296                 {
1297                         error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier));
1298                         recover();
1299                 }
1300         }
1301         else
1302         {
1303                 switch(qualifier)
1304                 {
1305                 case EvqSmoothIn:
1306                 case EvqSmoothOut:
1307                 case EvqVertexOut:
1308                 case EvqFragmentIn:
1309                 case EvqCentroidOut:
1310                 case EvqCentroidIn:
1311                         if(typeSpecifier.type == EbtBool)
1312                         {
1313                                 error(typeSpecifier.line, "cannot be bool", getQualifierString(qualifier));
1314                                 recover();
1315                         }
1316                         if(typeSpecifier.type == EbtInt || typeSpecifier.type == EbtUInt)
1317                         {
1318                                 error(typeSpecifier.line, "must use 'flat' interpolation here", getQualifierString(qualifier));
1319                                 recover();
1320                         }
1321                         break;
1322
1323                 case EvqVertexIn:
1324                 case EvqFragmentOut:
1325                 case EvqFlatIn:
1326                 case EvqFlatOut:
1327                         if(typeSpecifier.type == EbtBool)
1328                         {
1329                                 error(typeSpecifier.line, "cannot be bool", getQualifierString(qualifier));
1330                                 recover();
1331                         }
1332                         break;
1333
1334                 default: break;
1335                 }
1336         }
1337
1338         return returnType;
1339 }
1340
1341 TIntermAggregate *TParseContext::parseSingleDeclaration(TPublicType &publicType,
1342         const TSourceLoc &identifierOrTypeLocation,
1343         const TString &identifier)
1344 {
1345         TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierOrTypeLocation);
1346
1347         bool emptyDeclaration = (identifier == "");
1348
1349         mDeferredSingleDeclarationErrorCheck = emptyDeclaration;
1350
1351         if(emptyDeclaration)
1352         {
1353                 if(publicType.isUnsizedArray())
1354                 {
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());
1358                 }
1359         }
1360         else
1361         {
1362                 if(singleDeclarationErrorCheck(publicType, identifierOrTypeLocation))
1363                         recover();
1364
1365                 if(nonInitErrorCheck(identifierOrTypeLocation, identifier, publicType))
1366                         recover();
1367
1368                 TVariable *variable = nullptr;
1369                 if(!declareVariable(identifierOrTypeLocation, identifier, TType(publicType), &variable))
1370                         recover();
1371
1372                 if(variable && symbol)
1373                         symbol->setId(variable->getUniqueId());
1374         }
1375
1376         return intermediate.makeAggregate(symbol, identifierOrTypeLocation);
1377 }
1378
1379 TIntermAggregate *TParseContext::parseSingleArrayDeclaration(TPublicType &publicType,
1380         const TSourceLoc &identifierLocation,
1381         const TString &identifier,
1382         const TSourceLoc &indexLocation,
1383         TIntermTyped *indexExpression)
1384 {
1385         mDeferredSingleDeclarationErrorCheck = false;
1386
1387         if(singleDeclarationErrorCheck(publicType, identifierLocation))
1388                 recover();
1389
1390         if(nonInitErrorCheck(identifierLocation, identifier, publicType))
1391                 recover();
1392
1393         if(arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType))
1394         {
1395                 recover();
1396         }
1397
1398         TType arrayType(publicType);
1399
1400         int size;
1401         if(arraySizeErrorCheck(identifierLocation, indexExpression, size))
1402         {
1403                 recover();
1404         }
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);
1408
1409         TVariable *variable = nullptr;
1410         if(!declareVariable(identifierLocation, identifier, arrayType, &variable))
1411                 recover();
1412
1413         TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation);
1414         if(variable && symbol)
1415                 symbol->setId(variable->getUniqueId());
1416
1417         return intermediate.makeAggregate(symbol, identifierLocation);
1418 }
1419
1420 TIntermAggregate *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType,
1421         const TSourceLoc &identifierLocation,
1422         const TString &identifier,
1423         const TSourceLoc &initLocation,
1424         TIntermTyped *initializer)
1425 {
1426         mDeferredSingleDeclarationErrorCheck = false;
1427
1428         if(singleDeclarationErrorCheck(publicType, identifierLocation))
1429                 recover();
1430
1431         TIntermNode *intermNode = nullptr;
1432         if(!executeInitializer(identifierLocation, identifier, publicType, initializer, &intermNode))
1433         {
1434                 //
1435                 // Build intermediate representation
1436                 //
1437                 return intermNode ? intermediate.makeAggregate(intermNode, initLocation) : nullptr;
1438         }
1439         else
1440         {
1441                 recover();
1442                 return nullptr;
1443         }
1444 }
1445
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)
1453 {
1454         mDeferredSingleDeclarationErrorCheck = false;
1455
1456         if(singleDeclarationErrorCheck(publicType, identifierLocation))
1457                 recover();
1458
1459         if(arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType))
1460         {
1461                 recover();
1462         }
1463
1464         TPublicType arrayType(publicType);
1465
1466         int size = 0;
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))
1469         {
1470                 recover();
1471         }
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);
1475
1476         // initNode will correspond to the whole of "type b[n] = initializer".
1477         TIntermNode *initNode = nullptr;
1478         if(!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
1479         {
1480                 return initNode ? intermediate.makeAggregate(initNode, initLocation) : nullptr;
1481         }
1482         else
1483         {
1484                 recover();
1485                 return nullptr;
1486         }
1487 }
1488
1489 TIntermAggregate *TParseContext::parseInvariantDeclaration(const TSourceLoc &invariantLoc,
1490         const TSourceLoc &identifierLoc,
1491         const TString *identifier,
1492         const TSymbol *symbol)
1493 {
1494         // invariant declaration
1495         if(globalErrorCheck(invariantLoc, symbolTable.atGlobalLevel(), "invariant varying"))
1496         {
1497                 recover();
1498         }
1499
1500         if(!symbol)
1501         {
1502                 error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str());
1503                 recover();
1504                 return nullptr;
1505         }
1506         else
1507         {
1508                 const TString kGlFrontFacing("gl_FrontFacing");
1509                 if(*identifier == kGlFrontFacing)
1510                 {
1511                         error(identifierLoc, "identifier should not be declared as invariant", identifier->c_str());
1512                         recover();
1513                         return nullptr;
1514                 }
1515                 symbolTable.addInvariantVarying(std::string(identifier->c_str()));
1516                 const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
1517                 ASSERT(variable);
1518                 const TType &type = variable->getType();
1519                 TIntermSymbol *intermSymbol = intermediate.addSymbol(variable->getUniqueId(),
1520                         *identifier, type, identifierLoc);
1521
1522                 TIntermAggregate *aggregate = intermediate.makeAggregate(intermSymbol, identifierLoc);
1523                 aggregate->setOp(EOpInvariantDeclaration);
1524                 return aggregate;
1525         }
1526 }
1527
1528 TIntermAggregate *TParseContext::parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration,
1529         const TSourceLoc &identifierLocation, const TString &identifier)
1530 {
1531         // If the declaration starting this declarator list was empty (example: int,), some checks were not performed.
1532         if(mDeferredSingleDeclarationErrorCheck)
1533         {
1534                 if(singleDeclarationErrorCheck(publicType, identifierLocation))
1535                         recover();
1536                 mDeferredSingleDeclarationErrorCheck = false;
1537         }
1538
1539         if(locationDeclaratorListCheck(identifierLocation, publicType))
1540                 recover();
1541
1542         if(nonInitErrorCheck(identifierLocation, identifier, publicType))
1543                 recover();
1544
1545         TVariable *variable = nullptr;
1546         if(!declareVariable(identifierLocation, identifier, TType(publicType), &variable))
1547                 recover();
1548
1549         TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation);
1550         if(variable && symbol)
1551                 symbol->setId(variable->getUniqueId());
1552
1553         return intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation);
1554 }
1555
1556 TIntermAggregate *TParseContext::parseArrayDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration,
1557         const TSourceLoc &identifierLocation, const TString &identifier,
1558         const TSourceLoc &arrayLocation, TIntermTyped *indexExpression)
1559 {
1560         // If the declaration starting this declarator list was empty (example: int,), some checks were not performed.
1561         if(mDeferredSingleDeclarationErrorCheck)
1562         {
1563                 if(singleDeclarationErrorCheck(publicType, identifierLocation))
1564                         recover();
1565                 mDeferredSingleDeclarationErrorCheck = false;
1566         }
1567
1568         if(locationDeclaratorListCheck(identifierLocation, publicType))
1569                 recover();
1570
1571         if(nonInitErrorCheck(identifierLocation, identifier, publicType))
1572                 recover();
1573
1574         if(arrayTypeErrorCheck(arrayLocation, publicType) || arrayQualifierErrorCheck(arrayLocation, publicType))
1575         {
1576                 recover();
1577         }
1578         else
1579         {
1580                 TType arrayType = TType(publicType);
1581                 int size;
1582                 if(arraySizeErrorCheck(arrayLocation, indexExpression, size))
1583                 {
1584                         recover();
1585                 }
1586                 arrayType.setArraySize(size);
1587
1588                 TVariable *variable = nullptr;
1589                 if(!declareVariable(identifierLocation, identifier, arrayType, &variable))
1590                         recover();
1591
1592                 TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation);
1593                 if(variable && symbol)
1594                         symbol->setId(variable->getUniqueId());
1595
1596                 return intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation);
1597         }
1598
1599         return nullptr;
1600 }
1601
1602 TIntermAggregate *TParseContext::parseInitDeclarator(const TPublicType &publicType, TIntermAggregate *aggregateDeclaration,
1603         const TSourceLoc &identifierLocation, const TString &identifier,
1604         const TSourceLoc &initLocation, TIntermTyped *initializer)
1605 {
1606         // If the declaration starting this declarator list was empty (example: int,), some checks were not performed.
1607         if(mDeferredSingleDeclarationErrorCheck)
1608         {
1609                 if(singleDeclarationErrorCheck(publicType, identifierLocation))
1610                         recover();
1611                 mDeferredSingleDeclarationErrorCheck = false;
1612         }
1613
1614         if(locationDeclaratorListCheck(identifierLocation, publicType))
1615                 recover();
1616
1617         TIntermNode *intermNode = nullptr;
1618         if(!executeInitializer(identifierLocation, identifier, publicType, initializer, &intermNode))
1619         {
1620                 //
1621                 // build the intermediate representation
1622                 //
1623                 if(intermNode)
1624                 {
1625                         return intermediate.growAggregate(aggregateDeclaration, intermNode, initLocation);
1626                 }
1627                 else
1628                 {
1629                         return aggregateDeclaration;
1630                 }
1631         }
1632         else
1633         {
1634                 recover();
1635                 return nullptr;
1636         }
1637 }
1638
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)
1646 {
1647         // If the declaration starting this declarator list was empty (example: int,), some checks were not performed.
1648         if(mDeferredSingleDeclarationErrorCheck)
1649         {
1650                 if(singleDeclarationErrorCheck(publicType, identifierLocation))
1651                         recover();
1652                 mDeferredSingleDeclarationErrorCheck = false;
1653         }
1654
1655         if(locationDeclaratorListCheck(identifierLocation, publicType))
1656                 recover();
1657
1658         if(arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType))
1659         {
1660                 recover();
1661         }
1662
1663         TPublicType arrayType(publicType);
1664
1665         int size = 0;
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))
1668         {
1669                 recover();
1670         }
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);
1674
1675         // initNode will correspond to the whole of "b[n] = initializer".
1676         TIntermNode *initNode = nullptr;
1677         if(!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
1678         {
1679                 if(initNode)
1680                 {
1681                         return intermediate.growAggregate(aggregateDeclaration, initNode, initLocation);
1682                 }
1683                 else
1684                 {
1685                         return aggregateDeclaration;
1686                 }
1687         }
1688         else
1689         {
1690                 recover();
1691                 return nullptr;
1692         }
1693 }
1694
1695 void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier)
1696 {
1697         if(mShaderVersion < 300)
1698         {
1699                 error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 only", "layout");
1700                 recover();
1701                 return;
1702         }
1703
1704         if(typeQualifier.qualifier != EvqUniform)
1705         {
1706                 error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "global layout must be uniform");
1707                 recover();
1708                 return;
1709         }
1710
1711         const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier;
1712         ASSERT(!layoutQualifier.isEmpty());
1713
1714         if(layoutLocationErrorCheck(typeQualifier.line, typeQualifier.layoutQualifier))
1715         {
1716                 recover();
1717                 return;
1718         }
1719
1720         if(layoutQualifier.matrixPacking != EmpUnspecified)
1721         {
1722                 mDefaultMatrixPacking = layoutQualifier.matrixPacking;
1723         }
1724
1725         if(layoutQualifier.blockStorage != EbsUnspecified)
1726         {
1727                 mDefaultBlockStorage = layoutQualifier.blockStorage;
1728         }
1729 }
1730
1731 TIntermAggregate *TParseContext::addFunctionPrototypeDeclaration(const TFunction &function, const TSourceLoc &location)
1732 {
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
1735         // multiple times.
1736         TFunction *symbolTableFunction =
1737                 static_cast<TFunction *>(symbolTable.find(function.getMangledName(), getShaderVersion()));
1738         if(symbolTableFunction->hasPrototypeDeclaration() && mShaderVersion == 100)
1739         {
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");
1743                 recover();
1744         }
1745         symbolTableFunction->setHasPrototypeDeclaration();
1746
1747         TIntermAggregate *prototype = new TIntermAggregate;
1748         prototype->setType(function.getReturnType());
1749         prototype->setName(function.getMangledName());
1750
1751         for(size_t i = 0; i < function.getParamCount(); i++)
1752         {
1753                 const TParameter &param = function.getParam(i);
1754                 if(param.name != 0)
1755                 {
1756                         TVariable variable(param.name, *param.type);
1757
1758                         TIntermSymbol *paramSymbol = intermediate.addSymbol(
1759                                 variable.getUniqueId(), variable.getName(), variable.getType(), location);
1760                         prototype = intermediate.growAggregate(prototype, paramSymbol, location);
1761                 }
1762                 else
1763                 {
1764                         TIntermSymbol *paramSymbol = intermediate.addSymbol(0, "", *param.type, location);
1765                         prototype = intermediate.growAggregate(prototype, paramSymbol, location);
1766                 }
1767         }
1768
1769         prototype->setOp(EOpPrototype);
1770
1771         symbolTable.pop();
1772
1773         if(!symbolTable.atGlobalLevel())
1774         {
1775                 // ESSL 3.00.4 section 4.2.4.
1776                 error(location, "local function prototype declarations are not allowed", "function");
1777                 recover();
1778         }
1779
1780         return prototype;
1781 }
1782
1783 TIntermAggregate *TParseContext::addFunctionDefinition(const TFunction &function, TIntermAggregate *functionPrototype, TIntermAggregate *functionBody, const TSourceLoc &location)
1784 {
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)
1788         {
1789                 error(location, "function does not return a value:", "", function.getName().c_str());
1790                 recover();
1791         }
1792
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());
1797
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);
1802
1803         if(functionBody && functionBody->getAsAggregate())
1804                 aggregate->setEndLine(functionBody->getAsAggregate()->getEndLine());
1805
1806         symbolTable.pop();
1807         return aggregate;
1808 }
1809
1810 void TParseContext::parseFunctionPrototype(const TSourceLoc &location, TFunction *function, TIntermAggregate **aggregateOut)
1811 {
1812         const TSymbol *builtIn = symbolTable.findBuiltIn(function->getMangledName(), getShaderVersion());
1813
1814         if(builtIn)
1815         {
1816                 error(location, "built-in functions cannot be redefined", function->getName().c_str());
1817                 recover();
1818         }
1819
1820         TFunction *prevDec = static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion()));
1821         //
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.
1825         //
1826         if(prevDec->isDefined())
1827         {
1828                 // Then this function already has a body.
1829                 error(location, "function already has a body", function->getName().c_str());
1830                 recover();
1831         }
1832         prevDec->setDefined();
1833         //
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.
1837         //
1838         function->setUniqueId(prevDec->getUniqueId());
1839
1840         // Raise error message if main function takes any parameters or return anything other than void
1841         if(function->getName() == "main")
1842         {
1843                 if(function->getParamCount() > 0)
1844                 {
1845                         error(location, "function cannot take any parameter(s)", function->getName().c_str());
1846                         recover();
1847                 }
1848                 if(function->getReturnType().getBasicType() != EbtVoid)
1849                 {
1850                         error(location, "", function->getReturnType().getBasicString(), "main function cannot return a value");
1851                         recover();
1852                 }
1853         }
1854
1855         //
1856         // Remember the return type for later checking for RETURN statements.
1857         //
1858         mCurrentFunctionType = &(prevDec->getReturnType());
1859         mFunctionReturnsValue = false;
1860
1861         //
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).
1865         //
1866         // Also, accumulate the list of parameters into the HIL, so lower level code
1867         // knows where to find parameters.
1868         //
1869         TIntermAggregate *paramNodes = new TIntermAggregate;
1870         for(size_t i = 0; i < function->getParamCount(); i++)
1871         {
1872                 const TParameter &param = function->getParam(i);
1873                 if(param.name != 0)
1874                 {
1875                         TVariable *variable = new TVariable(param.name, *param.type);
1876                         //
1877                         // Insert the parameters with name in the symbol table.
1878                         //
1879                         if(!symbolTable.declare(*variable))
1880                         {
1881                                 error(location, "redefinition", variable->getName().c_str());
1882                                 recover();
1883                                 paramNodes = intermediate.growAggregate(
1884                                         paramNodes, intermediate.addSymbol(0, "", *param.type, location), location);
1885                                 continue;
1886                         }
1887
1888                         //
1889                         // Add the parameter to the HIL
1890                         //
1891                         TIntermSymbol *symbol = intermediate.addSymbol(
1892                                 variable->getUniqueId(), variable->getName(), variable->getType(), location);
1893
1894                         paramNodes = intermediate.growAggregate(paramNodes, symbol, location);
1895                 }
1896                 else
1897                 {
1898                         paramNodes = intermediate.growAggregate(
1899                                 paramNodes, intermediate.addSymbol(0, "", *param.type, location), location);
1900                 }
1901         }
1902         intermediate.setAggregateOperator(paramNodes, EOpParameters, location);
1903         *aggregateOut = paramNodes;
1904         setLoopNestingLevel(0);
1905 }
1906
1907 TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TFunction *function)
1908 {
1909         //
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.
1913         //
1914         // Return types and parameter qualifiers must match in all redeclarations, so those are checked
1915         // here.
1916         //
1917         TFunction *prevDec = static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion()));
1918         if(prevDec)
1919         {
1920                 if(prevDec->getReturnType() != function->getReturnType())
1921                 {
1922                         error(location, "overloaded functions must have the same return type",
1923                                 function->getReturnType().getBasicString());
1924                         recover();
1925                 }
1926                 for(size_t i = 0; i < prevDec->getParamCount(); ++i)
1927                 {
1928                         if(prevDec->getParam(i).type->getQualifier() != function->getParam(i).type->getQualifier())
1929                         {
1930                                 error(location, "overloaded functions must have the same parameter qualifiers",
1931                                         function->getParam(i).type->getQualifierString());
1932                                 recover();
1933                         }
1934                 }
1935         }
1936
1937         //
1938         // Check for previously declared variables using the same name.
1939         //
1940         TSymbol *prevSym = symbolTable.find(function->getName(), getShaderVersion());
1941         if(prevSym)
1942         {
1943                 if(!prevSym->isFunction())
1944                 {
1945                         error(location, "redefinition", function->getName().c_str(), "function");
1946                         recover();
1947                 }
1948         }
1949
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);
1953
1954         //
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.
1958         //
1959         return function;
1960 }
1961
1962 TFunction *TParseContext::addConstructorFunc(const TPublicType &publicTypeIn)
1963 {
1964         TPublicType publicType = publicTypeIn;
1965         TOperator op = EOpNull;
1966         if(publicType.userDef)
1967         {
1968                 op = EOpConstructStruct;
1969         }
1970         else
1971         {
1972                 switch(publicType.type)
1973                 {
1974                 case EbtFloat:
1975                         if(publicType.isMatrix())
1976                         {
1977                                 switch(publicType.getCols())
1978                                 {
1979                                 case 2:
1980                                         switch(publicType.getRows())
1981                                         {
1982                                         case 2: op = EOpConstructMat2;  break;
1983                                         case 3: op = EOpConstructMat2x3;  break;
1984                                         case 4: op = EOpConstructMat2x4;  break;
1985                                         }
1986                                         break;
1987                                 case 3:
1988                                         switch(publicType.getRows())
1989                                         {
1990                                         case 2: op = EOpConstructMat3x2;  break;
1991                                         case 3: op = EOpConstructMat3;  break;
1992                                         case 4: op = EOpConstructMat3x4;  break;
1993                                         }
1994                                         break;
1995                                 case 4:
1996                                         switch(publicType.getRows())
1997                                         {
1998                                         case 2: op = EOpConstructMat4x2;  break;
1999                                         case 3: op = EOpConstructMat4x3;  break;
2000                                         case 4: op = EOpConstructMat4;  break;
2001                                         }
2002                                         break;
2003                                 }
2004                         }
2005                         else
2006                         {
2007                                 switch(publicType.getNominalSize())
2008                                 {
2009                                 case 1: op = EOpConstructFloat; break;
2010                                 case 2: op = EOpConstructVec2;  break;
2011                                 case 3: op = EOpConstructVec3;  break;
2012                                 case 4: op = EOpConstructVec4;  break;
2013                                 }
2014                         }
2015                         break;
2016
2017                 case EbtInt:
2018                         switch(publicType.getNominalSize())
2019                         {
2020                         case 1: op = EOpConstructInt;   break;
2021                         case 2: op = EOpConstructIVec2; break;
2022                         case 3: op = EOpConstructIVec3; break;
2023                         case 4: op = EOpConstructIVec4; break;
2024                         }
2025                         break;
2026
2027                 case EbtUInt:
2028                         switch(publicType.getNominalSize())
2029                         {
2030                         case 1: op = EOpConstructUInt;  break;
2031                         case 2: op = EOpConstructUVec2; break;
2032                         case 3: op = EOpConstructUVec3; break;
2033                         case 4: op = EOpConstructUVec4; break;
2034                         }
2035                         break;
2036
2037                 case EbtBool:
2038                         switch(publicType.getNominalSize())
2039                         {
2040                         case 1: op = EOpConstructBool;  break;
2041                         case 2: op = EOpConstructBVec2; break;
2042                         case 3: op = EOpConstructBVec3; break;
2043                         case 4: op = EOpConstructBVec4; break;
2044                         }
2045                         break;
2046
2047                 default: break;
2048                 }
2049
2050                 if(op == EOpNull)
2051                 {
2052                         error(publicType.line, "cannot construct this type", getBasicString(publicType.type));
2053                         recover();
2054                         publicType.type = EbtFloat;
2055                         op = EOpConstructFloat;
2056                 }
2057         }
2058
2059         TString tempString;
2060         TType type(publicType);
2061         return new TFunction(&tempString, type, op);
2062 }
2063
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.
2066 //
2067 // Returns 0 for an error or the constructed node (aggregate or typed) for no error.
2068 //
2069 TIntermTyped* TParseContext::addConstructor(TIntermNode* arguments, const TType* type, TOperator op, TFunction* fnCall, const TSourceLoc &line)
2070 {
2071         TIntermAggregate *aggregateArguments = arguments->getAsAggregate();
2072
2073         if(!aggregateArguments)
2074         {
2075                 aggregateArguments = new TIntermAggregate;
2076                 aggregateArguments->getSequence().push_back(arguments);
2077         }
2078
2079         if(type->isArray())
2080         {
2081                 // GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of
2082                 // the array.
2083                 for(TIntermNode *&argNode : aggregateArguments->getSequence())
2084                 {
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))
2089                         {
2090                                 error(line, "Array constructor argument has an incorrect type", "Error");
2091                                 return nullptr;
2092                         }
2093                 }
2094         }
2095         else if(op == EOpConstructStruct)
2096         {
2097                 const TFieldList &fields = type->getStruct()->fields();
2098                 TIntermSequence &args = aggregateArguments->getSequence();
2099
2100                 for(size_t i = 0; i < fields.size(); i++)
2101                 {
2102                         if(args[i]->getAsTyped()->getType() != *fields[i]->type())
2103                         {
2104                                 error(line, "Structure constructor arguments do not match structure fields", "Error");
2105                                 recover();
2106
2107                                 return nullptr;
2108                         }
2109                 }
2110         }
2111
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)
2116         {
2117                 return constConstructor;
2118         }
2119
2120         return constructor;
2121 }
2122
2123 TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, const TType& type)
2124 {
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);
2131                 }
2132                 else {
2133                         returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type);
2134                 }
2135                 if (returnVal)
2136                         return nullptr;
2137
2138                 return intermediate.addConstantUnion(unionArray, type, aggrNode->getLine());
2139         }
2140
2141         return nullptr;
2142 }
2143
2144 //
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.
2150 //
2151 TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, const TSourceLoc &line)
2152 {
2153         TIntermTyped* typedNode;
2154         TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
2155
2156         ConstantUnion *unionArray;
2157         if (tempConstantNode) {
2158                 unionArray = tempConstantNode->getUnionArrayPointer();
2159
2160                 if (!unionArray) {
2161                         return node;
2162                 }
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");
2165                 recover();
2166
2167                 return nullptr;
2168         }
2169
2170         ConstantUnion* constArray = new ConstantUnion[fields.num];
2171
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());
2179                         recover();
2180                         fields.offsets[i] = 0;
2181                 }
2182
2183                 constArray[i] = unionArray[fields.offsets[i]];
2184
2185         }
2186         typedNode = intermediate.addConstantUnion(constArray, node->getType(), line);
2187         return typedNode;
2188 }
2189
2190 //
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)
2195 //
2196 TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, const TSourceLoc &line)
2197 {
2198         TIntermTyped* typedNode;
2199         TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
2200
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());
2206                 recover();
2207                 index = 0;
2208         }
2209
2210         if (tempConstantNode) {
2211                  ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
2212                  int size = tempConstantNode->getType().getNominalSize();
2213                  typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line);
2214         } else {
2215                 error(line, "Cannot offset into the matrix", "Error");
2216                 recover();
2217
2218                 return nullptr;
2219         }
2220
2221         return typedNode;
2222 }
2223
2224
2225 //
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)
2230 //
2231 TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc &line)
2232 {
2233         TIntermTyped* typedNode;
2234         TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
2235         TType arrayElementType = node->getType();
2236         arrayElementType.clearArrayness();
2237
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());
2243                 recover();
2244                 index = 0;
2245         }
2246
2247         size_t arrayElementSize = arrayElementType.getObjectSize();
2248
2249         if (tempConstantNode) {
2250                  ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
2251                  typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line);
2252         } else {
2253                 error(line, "Cannot offset into the array", "Error");
2254                 recover();
2255
2256                 return nullptr;
2257         }
2258
2259         return typedNode;
2260 }
2261
2262
2263 //
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.
2267 //
2268 TIntermTyped* TParseContext::addConstStruct(const TString& identifier, TIntermTyped* node, const TSourceLoc &line)
2269 {
2270         const TFieldList &fields = node->getType().getStruct()->fields();
2271         TIntermTyped *typedNode;
2272         size_t instanceSize = 0;
2273         TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
2274
2275         for(size_t index = 0; index < fields.size(); ++index) {
2276                 if (fields[index]->name() == identifier) {
2277                         break;
2278                 } else {
2279                         instanceSize += fields[index]->type()->getObjectSize();
2280                 }
2281         }
2282
2283         if (tempConstantNode) {
2284                  ConstantUnion* constArray = tempConstantNode->getUnionArrayPointer();
2285
2286                  typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function
2287         } else {
2288                 error(line, "Cannot offset into the structure", "Error");
2289                 recover();
2290
2291                 return nullptr;
2292         }
2293
2294         return typedNode;
2295 }
2296
2297 //
2298 // Interface/uniform blocks
2299 //
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)
2302 {
2303         if(reservedErrorCheck(nameLine, blockName))
2304                 recover();
2305
2306         if(typeQualifier.qualifier != EvqUniform)
2307         {
2308                 error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "interface blocks must be uniform");
2309                 recover();
2310         }
2311
2312         TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier;
2313         if(layoutLocationErrorCheck(typeQualifier.line, blockLayoutQualifier))
2314         {
2315                 recover();
2316         }
2317
2318         if(blockLayoutQualifier.matrixPacking == EmpUnspecified)
2319         {
2320                 blockLayoutQualifier.matrixPacking = mDefaultMatrixPacking;
2321         }
2322
2323         if(blockLayoutQualifier.blockStorage == EbsUnspecified)
2324         {
2325                 blockLayoutQualifier.blockStorage = mDefaultBlockStorage;
2326         }
2327
2328         TSymbol* blockNameSymbol = new TSymbol(&blockName);
2329         if(!symbolTable.declare(*blockNameSymbol)) {
2330                 error(nameLine, "redefinition", blockName.c_str(), "interface block name");
2331                 recover();
2332         }
2333
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");
2340                         recover();
2341                 }
2342
2343                 const TQualifier qualifier = fieldType->getQualifier();
2344                 switch(qualifier)
2345                 {
2346                 case EvqGlobal:
2347                 case EvqUniform:
2348                         break;
2349                 default:
2350                         error(field->line(), "invalid qualifier on interface block member", getQualifierString(qualifier));
2351                         recover();
2352                         break;
2353                 }
2354
2355                 // check layout qualifiers
2356                 TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier();
2357                 if(layoutLocationErrorCheck(field->line(), fieldLayoutQualifier))
2358                 {
2359                         recover();
2360                 }
2361
2362                 if(fieldLayoutQualifier.blockStorage != EbsUnspecified)
2363                 {
2364                         error(field->line(), "invalid layout qualifier:", getBlockStorageString(fieldLayoutQualifier.blockStorage), "cannot be used here");
2365                         recover();
2366                 }
2367
2368                 if(fieldLayoutQualifier.matrixPacking == EmpUnspecified)
2369                 {
2370                         fieldLayoutQualifier.matrixPacking = blockLayoutQualifier.matrixPacking;
2371                 }
2372                 else if(!fieldType->isMatrix())
2373                 {
2374                         error(field->line(), "invalid layout qualifier:", getMatrixPackingString(fieldLayoutQualifier.matrixPacking), "can only be used on matrix types");
2375                         recover();
2376                 }
2377
2378                 fieldType->setLayoutQualifier(fieldLayoutQualifier);
2379         }
2380
2381         // add array index
2382         int arraySize = 0;
2383         if(arrayIndex)
2384         {
2385                 if(arraySizeErrorCheck(arrayIndexLine, arrayIndex, arraySize))
2386                         recover();
2387         }
2388
2389         TInterfaceBlock* interfaceBlock = new TInterfaceBlock(&blockName, fieldList, instanceName, arraySize, blockLayoutQualifier);
2390         TType interfaceBlockType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier, arraySize);
2391
2392         TString symbolName = "";
2393         int symbolId = 0;
2394
2395         if(!instanceName)
2396         {
2397                 // define symbols for the members of the interface block
2398                 for(size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
2399                 {
2400                         TField* field = (*fieldList)[memberIndex];
2401                         TType* fieldType = field->type();
2402
2403                         // set parent pointer of the field variable
2404                         fieldType->setInterfaceBlock(interfaceBlock);
2405
2406                         TVariable* fieldVariable = new TVariable(&field->name(), *fieldType);
2407                         fieldVariable->setQualifier(typeQualifier.qualifier);
2408
2409                         if(!symbolTable.declare(*fieldVariable)) {
2410                                 error(field->line(), "redefinition", field->name().c_str(), "interface block member name");
2411                                 recover();
2412                         }
2413                 }
2414         }
2415         else
2416         {
2417                 // add a symbol for this interface block
2418                 TVariable* instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false);
2419                 instanceTypeDef->setQualifier(typeQualifier.qualifier);
2420
2421                 if(!symbolTable.declare(*instanceTypeDef)) {
2422                         error(instanceLine, "redefinition", instanceName->c_str(), "interface block instance name");
2423                         recover();
2424                 }
2425
2426                 symbolId = instanceTypeDef->getUniqueId();
2427                 symbolName = instanceTypeDef->getName();
2428         }
2429
2430         TIntermAggregate *aggregate = intermediate.makeAggregate(intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line), nameLine);
2431         aggregate->setOp(EOpDeclaration);
2432
2433         exitStructDeclaration();
2434         return aggregate;
2435 }
2436
2437 //
2438 // Parse an array index expression
2439 //
2440 TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc &location, TIntermTyped *indexExpression)
2441 {
2442         TIntermTyped *indexedExpression = nullptr;
2443
2444         if(!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector())
2445         {
2446                 if(baseExpression->getAsSymbolNode())
2447                 {
2448                         error(location, " left of '[' is not of type array, matrix, or vector ",
2449                                 baseExpression->getAsSymbolNode()->getSymbol().c_str());
2450                 }
2451                 else
2452                 {
2453                         error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
2454                 }
2455                 recover();
2456         }
2457
2458         TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion();
2459
2460         if(indexExpression->getQualifier() == EvqConstExpr && indexConstantUnion)
2461         {
2462                 int index = indexConstantUnion->getIConst(0);
2463                 if(index < 0)
2464                 {
2465                         std::stringstream infoStream;
2466                         infoStream << index;
2467                         std::string info = infoStream.str();
2468                         error(location, "negative index", info.c_str());
2469                         recover();
2470                         index = 0;
2471                 }
2472                 if(baseExpression->getType().getQualifier() == EvqConstExpr)
2473                 {
2474                         if(baseExpression->isArray())
2475                         {
2476                                 // constant folding for arrays
2477                                 indexedExpression = addConstArrayNode(index, baseExpression, location);
2478                         }
2479                         else if(baseExpression->isVector())
2480                         {
2481                                 // constant folding for vectors
2482                                 TVectorFields fields;
2483                                 fields.num = 1;
2484                                 fields.offsets[0] = index; // need to do it this way because v.xy sends fields integer array
2485                                 indexedExpression = addConstVectorNode(fields, baseExpression, location);
2486                         }
2487                         else if(baseExpression->isMatrix())
2488                         {
2489                                 // constant folding for matrices
2490                                 indexedExpression = addConstMatrixNode(index, baseExpression, location);
2491                         }
2492                 }
2493                 else
2494                 {
2495                         int safeIndex = -1;
2496
2497                         if(baseExpression->isArray())
2498                         {
2499                                 if(index >= baseExpression->getType().getArraySize())
2500                                 {
2501                                         std::stringstream extraInfoStream;
2502                                         extraInfoStream << "array index out of range '" << index << "'";
2503                                         std::string extraInfo = extraInfoStream.str();
2504                                         error(location, "", "[", extraInfo.c_str());
2505                                         recover();
2506                                         safeIndex = baseExpression->getType().getArraySize() - 1;
2507                                 }
2508                         }
2509                         else if((baseExpression->isVector() || baseExpression->isMatrix()) &&
2510                                 baseExpression->getType().getNominalSize() <= index)
2511                         {
2512                                 std::stringstream extraInfoStream;
2513                                 extraInfoStream << "field selection out of range '" << index << "'";
2514                                 std::string extraInfo = extraInfoStream.str();
2515                                 error(location, "", "[", extraInfo.c_str());
2516                                 recover();
2517                                 safeIndex = baseExpression->getType().getNominalSize() - 1;
2518                         }
2519
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.
2522                         if(safeIndex != -1)
2523                         {
2524                                 ConstantUnion *safeConstantUnion = new ConstantUnion();
2525                                 safeConstantUnion->setIConst(safeIndex);
2526                                 indexConstantUnion->replaceConstantUnion(safeConstantUnion);
2527                         }
2528
2529                         indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location);
2530                 }
2531         }
2532         else
2533         {
2534                 if(baseExpression->isInterfaceBlock())
2535                 {
2536                         error(location, "",
2537                                 "[", "array indexes for interface blocks arrays must be constant integral expressions");
2538                         recover();
2539                 }
2540                 else if(baseExpression->getQualifier() == EvqFragmentOut)
2541                 {
2542                         error(location, "", "[", "array indexes for fragment outputs must be constant integral expressions");
2543                         recover();
2544                 }
2545
2546                 indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location);
2547         }
2548
2549         if(indexedExpression == 0)
2550         {
2551                 ConstantUnion *unionArray = new ConstantUnion[1];
2552                 unionArray->setFConst(0.0f);
2553                 indexedExpression = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConstExpr), location);
2554         }
2555         else if(baseExpression->isArray())
2556         {
2557                 const TType &baseType = baseExpression->getType();
2558                 if(baseType.getStruct())
2559                 {
2560                         TType copyOfType(baseType.getStruct());
2561                         indexedExpression->setType(copyOfType);
2562                 }
2563                 else if(baseType.isInterfaceBlock())
2564                 {
2565                         TType copyOfType(baseType.getInterfaceBlock(), EvqTemporary, baseType.getLayoutQualifier(), 0);
2566                         indexedExpression->setType(copyOfType);
2567                 }
2568                 else
2569                 {
2570                         indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),
2571                                 EvqTemporary, static_cast<unsigned char>(baseExpression->getNominalSize()),
2572                                 static_cast<unsigned char>(baseExpression->getSecondarySize())));
2573                 }
2574
2575                 if(baseExpression->getType().getQualifier() == EvqConstExpr)
2576                 {
2577                         indexedExpression->getTypePointer()->setQualifier(EvqConstExpr);
2578                 }
2579         }
2580         else if(baseExpression->isMatrix())
2581         {
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())));
2585         }
2586         else if(baseExpression->isVector())
2587         {
2588                 TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConstExpr ? EvqConstExpr : EvqTemporary;
2589                 indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier));
2590         }
2591         else
2592         {
2593                 indexedExpression->setType(baseExpression->getType());
2594         }
2595
2596         return indexedExpression;
2597 }
2598
2599 TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc &dotLocation,
2600         const TString &fieldString, const TSourceLoc &fieldLocation)
2601 {
2602         TIntermTyped *indexedExpression = nullptr;
2603
2604         if(baseExpression->isArray())
2605         {
2606                 error(fieldLocation, "cannot apply dot operator to an array", ".");
2607                 recover();
2608         }
2609
2610         if(baseExpression->isVector())
2611         {
2612                 TVectorFields fields;
2613                 if(!parseVectorFields(fieldString, baseExpression->getNominalSize(), fields, fieldLocation))
2614                 {
2615                         fields.num = 1;
2616                         fields.offsets[0] = 0;
2617                         recover();
2618                 }
2619
2620                 if(baseExpression->getAsConstantUnion())
2621                 {
2622                         // constant folding for vector fields
2623                         indexedExpression = addConstVectorNode(fields, baseExpression, fieldLocation);
2624                         if(indexedExpression == 0)
2625                         {
2626                                 recover();
2627                                 indexedExpression = baseExpression;
2628                         }
2629                         else
2630                         {
2631                                 indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),
2632                                         EvqConstExpr, (unsigned char)(fieldString).size()));
2633                         }
2634                 }
2635                 else
2636                 {
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()));
2642                 }
2643         }
2644         else if(baseExpression->isMatrix())
2645         {
2646                 TMatrixFields fields;
2647                 if(!parseMatrixFields(fieldString, baseExpression->getNominalSize(), baseExpression->getSecondarySize(), fields, fieldLocation))
2648                 {
2649                         fields.wholeRow = false;
2650                         fields.wholeCol = false;
2651                         fields.row = 0;
2652                         fields.col = 0;
2653                         recover();
2654                 }
2655
2656                 if(fields.wholeRow || fields.wholeCol)
2657                 {
2658                         error(dotLocation, " non-scalar fields not implemented yet", ".");
2659                         recover();
2660                         ConstantUnion *unionArray = new ConstantUnion[1];
2661                         unionArray->setIConst(0);
2662                         TIntermTyped *index = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConstExpr),
2663                                 fieldLocation);
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())));
2668                 }
2669                 else
2670                 {
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),
2674                                 fieldLocation);
2675                         indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, index, dotLocation);
2676                         indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision()));
2677                 }
2678         }
2679         else if(baseExpression->getBasicType() == EbtStruct)
2680         {
2681                 bool fieldFound = false;
2682                 const TFieldList &fields = baseExpression->getType().getStruct()->fields();
2683                 if(fields.empty())
2684                 {
2685                         error(dotLocation, "structure has no fields", "Internal Error");
2686                         recover();
2687                         indexedExpression = baseExpression;
2688                 }
2689                 else
2690                 {
2691                         unsigned int i;
2692                         for(i = 0; i < fields.size(); ++i)
2693                         {
2694                                 if(fields[i]->name() == fieldString)
2695                                 {
2696                                         fieldFound = true;
2697                                         break;
2698                                 }
2699                         }
2700                         if(fieldFound)
2701                         {
2702                                 if(baseExpression->getType().getQualifier() == EvqConstExpr)
2703                                 {
2704                                         indexedExpression = addConstStruct(fieldString, baseExpression, dotLocation);
2705                                         if(indexedExpression == 0)
2706                                         {
2707                                                 recover();
2708                                                 indexedExpression = baseExpression;
2709                                         }
2710                                         else
2711                                         {
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);
2716                                         }
2717                                 }
2718                                 else
2719                                 {
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());
2725                                 }
2726                         }
2727                         else
2728                         {
2729                                 error(dotLocation, " no such field in structure", fieldString.c_str());
2730                                 recover();
2731                                 indexedExpression = baseExpression;
2732                         }
2733                 }
2734         }
2735         else if(baseExpression->isInterfaceBlock())
2736         {
2737                 bool fieldFound = false;
2738                 const TFieldList &fields = baseExpression->getType().getInterfaceBlock()->fields();
2739                 if(fields.empty())
2740                 {
2741                         error(dotLocation, "interface block has no fields", "Internal Error");
2742                         recover();
2743                         indexedExpression = baseExpression;
2744                 }
2745                 else
2746                 {
2747                         unsigned int i;
2748                         for(i = 0; i < fields.size(); ++i)
2749                         {
2750                                 if(fields[i]->name() == fieldString)
2751                                 {
2752                                         fieldFound = true;
2753                                         break;
2754                                 }
2755                         }
2756                         if(fieldFound)
2757                         {
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,
2762                                         dotLocation);
2763                                 indexedExpression->setType(*fields[i]->type());
2764                         }
2765                         else
2766                         {
2767                                 error(dotLocation, " no such field in interface block", fieldString.c_str());
2768                                 recover();
2769                                 indexedExpression = baseExpression;
2770                         }
2771                 }
2772         }
2773         else
2774         {
2775                 if(mShaderVersion < 300)
2776                 {
2777                         error(dotLocation, " field selection requires structure, vector, or matrix on left hand side",
2778                                 fieldString.c_str());
2779                 }
2780                 else
2781                 {
2782                         error(dotLocation,
2783                                 " field selection requires structure, vector, matrix, or interface block on left hand side",
2784                                 fieldString.c_str());
2785                 }
2786                 recover();
2787                 indexedExpression = baseExpression;
2788         }
2789
2790         return indexedExpression;
2791 }
2792
2793 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine)
2794 {
2795         TLayoutQualifier qualifier;
2796
2797         qualifier.location = -1;
2798         qualifier.matrixPacking = EmpUnspecified;
2799         qualifier.blockStorage = EbsUnspecified;
2800
2801         if(qualifierType == "shared")
2802         {
2803                 qualifier.blockStorage = EbsShared;
2804         }
2805         else if(qualifierType == "packed")
2806         {
2807                 qualifier.blockStorage = EbsPacked;
2808         }
2809         else if(qualifierType == "std140")
2810         {
2811                 qualifier.blockStorage = EbsStd140;
2812         }
2813         else if(qualifierType == "row_major")
2814         {
2815                 qualifier.matrixPacking = EmpRowMajor;
2816         }
2817         else if(qualifierType == "column_major")
2818         {
2819                 qualifier.matrixPacking = EmpColumnMajor;
2820         }
2821         else if(qualifierType == "location")
2822         {
2823                 error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "location requires an argument");
2824                 recover();
2825         }
2826         else
2827         {
2828                 error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
2829                 recover();
2830         }
2831
2832         return qualifier;
2833 }
2834
2835 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine)
2836 {
2837         TLayoutQualifier qualifier;
2838
2839         qualifier.location = -1;
2840         qualifier.matrixPacking = EmpUnspecified;
2841         qualifier.blockStorage = EbsUnspecified;
2842
2843         if (qualifierType != "location")
2844         {
2845                 error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "only location may have arguments");
2846                 recover();
2847         }
2848         else
2849         {
2850                 // must check that location is non-negative
2851                 if (intValue < 0)
2852                 {
2853                         error(intValueLine, "out of range:", intValueString.c_str(), "location must be non-negative");
2854                         recover();
2855                 }
2856                 else
2857                 {
2858                         qualifier.location = intValue;
2859                 }
2860         }
2861
2862         return qualifier;
2863 }
2864
2865 TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier)
2866 {
2867         TLayoutQualifier joinedQualifier = leftQualifier;
2868
2869         if (rightQualifier.location != -1)
2870         {
2871                 joinedQualifier.location = rightQualifier.location;
2872         }
2873         if(rightQualifier.matrixPacking != EmpUnspecified)
2874         {
2875                 joinedQualifier.matrixPacking = rightQualifier.matrixPacking;
2876         }
2877         if(rightQualifier.blockStorage != EbsUnspecified)
2878         {
2879                 joinedQualifier.blockStorage = rightQualifier.blockStorage;
2880         }
2881
2882         return joinedQualifier;
2883 }
2884
2885
2886 TPublicType TParseContext::joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier,
2887         const TSourceLoc &storageLoc, TQualifier storageQualifier)
2888 {
2889         TQualifier mergedQualifier = EvqSmoothIn;
2890
2891         if(storageQualifier == EvqFragmentIn) {
2892                 if(interpolationQualifier == EvqSmooth)
2893                         mergedQualifier = EvqSmoothIn;
2894                 else if(interpolationQualifier == EvqFlat)
2895                         mergedQualifier = EvqFlatIn;
2896                 else UNREACHABLE(interpolationQualifier);
2897         }
2898         else if(storageQualifier == EvqCentroidIn) {
2899                 if(interpolationQualifier == EvqSmooth)
2900                         mergedQualifier = EvqCentroidIn;
2901                 else if(interpolationQualifier == EvqFlat)
2902                         mergedQualifier = EvqFlatIn;
2903                 else UNREACHABLE(interpolationQualifier);
2904         }
2905         else if(storageQualifier == EvqVertexOut) {
2906                 if(interpolationQualifier == EvqSmooth)
2907                         mergedQualifier = EvqSmoothOut;
2908                 else if(interpolationQualifier == EvqFlat)
2909                         mergedQualifier = EvqFlatOut;
2910                 else UNREACHABLE(interpolationQualifier);
2911         }
2912         else if(storageQualifier == EvqCentroidOut) {
2913                 if(interpolationQualifier == EvqSmooth)
2914                         mergedQualifier = EvqCentroidOut;
2915                 else if(interpolationQualifier == EvqFlat)
2916                         mergedQualifier = EvqFlatOut;
2917                 else UNREACHABLE(interpolationQualifier);
2918         }
2919         else {
2920                 error(interpolationLoc, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getQualifierString(interpolationQualifier));
2921                 recover();
2922
2923                 mergedQualifier = storageQualifier;
2924         }
2925
2926         TPublicType type;
2927         type.setBasic(EbtVoid, mergedQualifier, storageLoc);
2928         return type;
2929 }
2930
2931 TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList)
2932 {
2933         if(voidErrorCheck(typeSpecifier.line, (*fieldList)[0]->name(), typeSpecifier.type))
2934         {
2935                 recover();
2936         }
2937
2938         for(unsigned int i = 0; i < fieldList->size(); ++i)
2939         {
2940                 //
2941                 // Careful not to replace already known aspects of type, like array-ness
2942                 //
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);
2950
2951                 // don't allow arrays of arrays
2952                 if(type->isArray())
2953                 {
2954                         if(arrayTypeErrorCheck(typeSpecifier.line, typeSpecifier))
2955                                 recover();
2956                 }
2957                 if(typeSpecifier.array)
2958                         type->setArraySize(typeSpecifier.arraySize);
2959                 if(typeSpecifier.userDef)
2960                 {
2961                         type->setStruct(typeSpecifier.userDef->getStruct());
2962                 }
2963
2964                 if(structNestingErrorCheck(typeSpecifier.line, *(*fieldList)[i]))
2965                 {
2966                         recover();
2967                 }
2968         }
2969
2970         return fieldList;
2971 }
2972
2973 TPublicType TParseContext::addStructure(const TSourceLoc &structLine, const TSourceLoc &nameLine,
2974         const TString *structName, TFieldList *fieldList)
2975 {
2976         TStructure *structure = new TStructure(structName, fieldList);
2977         TType *structureType = new TType(structure);
2978
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());
2983
2984         if(!structName->empty())
2985         {
2986                 if(reservedErrorCheck(nameLine, *structName))
2987                 {
2988                         recover();
2989                 }
2990                 TVariable *userTypeDef = new TVariable(structName, *structureType, true);
2991                 if(!symbolTable.declare(*userTypeDef))
2992                 {
2993                         error(nameLine, "redefinition", structName->c_str(), "struct");
2994                         recover();
2995                 }
2996         }
2997
2998         // ensure we do not specify any storage qualifiers on the struct members
2999         for(unsigned int typeListIndex = 0; typeListIndex < fieldList->size(); typeListIndex++)
3000         {
3001                 const TField &field = *(*fieldList)[typeListIndex];
3002                 const TQualifier qualifier = field.type()->getQualifier();
3003                 switch(qualifier)
3004                 {
3005                 case EvqGlobal:
3006                 case EvqTemporary:
3007                         break;
3008                 default:
3009                         error(field.line(), "invalid qualifier on struct member", getQualifierString(qualifier));
3010                         recover();
3011                         break;
3012                 }
3013         }
3014
3015         TPublicType publicType;
3016         publicType.setBasic(EbtStruct, EvqTemporary, structLine);
3017         publicType.userDef = structureType;
3018         exitStructDeclaration();
3019
3020         return publicType;
3021 }
3022
3023 bool TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString& identifier)
3024 {
3025         ++mStructNestingLevel;
3026
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");
3032                 return true;
3033         }
3034
3035         return false;
3036 }
3037
3038 void TParseContext::exitStructDeclaration()
3039 {
3040         --mStructNestingLevel;
3041 }
3042
3043 bool TParseContext::structNestingErrorCheck(const TSourceLoc &line, const TField &field)
3044 {
3045         static const int kWebGLMaxStructNesting = 4;
3046
3047         if(field.type()->getBasicType() != EbtStruct)
3048         {
3049                 return false;
3050         }
3051
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)
3055         {
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(), "");
3063                 return true;
3064         }
3065
3066         return false;
3067 }
3068
3069 TIntermTyped *TParseContext::createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc, const TType *funcReturnType)
3070 {
3071         if(child == nullptr)
3072         {
3073                 return nullptr;
3074         }
3075
3076         switch(op)
3077         {
3078         case EOpLogicalNot:
3079                 if(child->getBasicType() != EbtBool ||
3080                         child->isMatrix() ||
3081                         child->isArray() ||
3082                         child->isVector())
3083                 {
3084                         return nullptr;
3085                 }
3086                 break;
3087         case EOpBitwiseNot:
3088                 if((child->getBasicType() != EbtInt && child->getBasicType() != EbtUInt) ||
3089                         child->isMatrix() ||
3090                         child->isArray())
3091                 {
3092                         return nullptr;
3093                 }
3094                 break;
3095         case EOpPostIncrement:
3096         case EOpPreIncrement:
3097         case EOpPostDecrement:
3098         case EOpPreDecrement:
3099         case EOpNegative:
3100                 if(child->getBasicType() == EbtStruct ||
3101                         child->getBasicType() == EbtBool ||
3102                         child->isArray())
3103                 {
3104                         return nullptr;
3105                 }
3106                 // Operators for built-ins are already type checked against their prototype.
3107         default:
3108                 break;
3109         }
3110
3111         return intermediate.addUnaryMath(op, child, loc, funcReturnType);
3112 }
3113
3114 TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
3115 {
3116         TIntermTyped *node = createUnaryMath(op, child, loc, nullptr);
3117         if(node == nullptr)
3118         {
3119                 unaryOpError(loc, getOperatorString(op), child->getCompleteString());
3120                 recover();
3121                 return child;
3122         }
3123         return node;
3124 }
3125
3126 TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
3127 {
3128         if(lValueErrorCheck(loc, getOperatorString(op), child))
3129                 recover();
3130         return addUnaryMath(op, child, loc);
3131 }
3132
3133 bool TParseContext::binaryOpCommonCheck(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc)
3134 {
3135         if(left->isArray() || right->isArray())
3136         {
3137                 if(mShaderVersion < 300)
3138                 {
3139                         error(loc, "Invalid operation for arrays", getOperatorString(op));
3140                         return false;
3141                 }
3142
3143                 if(left->isArray() != right->isArray())
3144                 {
3145                         error(loc, "array / non-array mismatch", getOperatorString(op));
3146                         return false;
3147                 }
3148
3149                 switch(op)
3150                 {
3151                 case EOpEqual:
3152                 case EOpNotEqual:
3153                 case EOpAssign:
3154                 case EOpInitialize:
3155                         break;
3156                 default:
3157                         error(loc, "Invalid operation for arrays", getOperatorString(op));
3158                         return false;
3159                 }
3160                 // At this point, size of implicitly sized arrays should be resolved.
3161                 if(left->getArraySize() != right->getArraySize())
3162                 {
3163                         error(loc, "array size mismatch", getOperatorString(op));
3164                         return false;
3165                 }
3166         }
3167
3168         // Check ops which require integer / ivec parameters
3169         bool isBitShift = false;
3170         switch(op)
3171         {
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.
3178                 isBitShift = true;
3179                 if(!IsInteger(left->getBasicType()) || !IsInteger(right->getBasicType()))
3180                 {
3181                         return false;
3182                 }
3183                 break;
3184         case EOpBitwiseAnd:
3185         case EOpBitwiseXor:
3186         case EOpBitwiseOr:
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()))
3193                 {
3194                         return false;
3195                 }
3196                 break;
3197         default:
3198                 break;
3199         }
3200
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())
3204         {
3205                 return false;
3206         }
3207
3208         // Check that type sizes match exactly on ops that require that.
3209         // Also check restrictions for structs that contain arrays or samplers.
3210         switch(op)
3211         {
3212         case EOpAssign:
3213         case EOpInitialize:
3214         case EOpEqual:
3215         case EOpNotEqual:
3216                 // ESSL 1.00 sections 5.7, 5.8, 5.9
3217                 if(mShaderVersion < 300 && left->getType().isStructureContainingArrays())
3218                 {
3219                         error(loc, "undefined operation for structs containing arrays", getOperatorString(op));
3220                         return false;
3221                 }
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())
3227                 {
3228                         error(loc, "undefined operation for structs containing samplers", getOperatorString(op));
3229                         return false;
3230                 }
3231         case EOpLessThan:
3232         case EOpGreaterThan:
3233         case EOpLessThanEqual:
3234         case EOpGreaterThanEqual:
3235                 if((left->getNominalSize() != right->getNominalSize()) ||
3236                         (left->getSecondarySize() != right->getSecondarySize()))
3237                 {
3238                         return false;
3239                 }
3240         default:
3241                 break;
3242         }
3243
3244         return true;
3245 }
3246
3247 TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &loc)
3248 {
3249         TBasicType switchType = init->getBasicType();
3250         if((switchType != EbtInt && switchType != EbtUInt) ||
3251            init->isMatrix() ||
3252            init->isArray() ||
3253            init->isVector())
3254         {
3255                 error(init->getLine(), "init-expression in a switch statement must be a scalar integer", "switch");
3256                 recover();
3257                 return nullptr;
3258         }
3259
3260         if(statementList)
3261         {
3262                 if(!ValidateSwitch::validate(switchType, this, statementList, loc))
3263                 {
3264                         recover();
3265                         return nullptr;
3266                 }
3267         }
3268
3269         TIntermSwitch *node = intermediate.addSwitch(init, statementList, loc);
3270         if(node == nullptr)
3271         {
3272                 error(loc, "erroneous switch statement", "switch");
3273                 recover();
3274                 return nullptr;
3275         }
3276         return node;
3277 }
3278
3279 TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &loc)
3280 {
3281         if(mSwitchNestingLevel == 0)
3282         {
3283                 error(loc, "case labels need to be inside switch statements", "case");
3284                 recover();
3285                 return nullptr;
3286         }
3287         if(condition == nullptr)
3288         {
3289                 error(loc, "case label must have a condition", "case");
3290                 recover();
3291                 return nullptr;
3292         }
3293         if((condition->getBasicType() != EbtInt && condition->getBasicType() != EbtUInt) ||
3294            condition->isMatrix() ||
3295            condition->isArray() ||
3296            condition->isVector())
3297         {
3298                 error(condition->getLine(), "case label must be a scalar integer", "case");
3299                 recover();
3300         }
3301         TIntermConstantUnion *conditionConst = condition->getAsConstantUnion();
3302         if(conditionConst == nullptr)
3303         {
3304                 error(condition->getLine(), "case label must be constant", "case");
3305                 recover();
3306         }
3307         TIntermCase *node = intermediate.addCase(condition, loc);
3308         if(node == nullptr)
3309         {
3310                 error(loc, "erroneous case statement", "case");
3311                 recover();
3312                 return nullptr;
3313         }
3314         return node;
3315 }
3316
3317 TIntermCase *TParseContext::addDefault(const TSourceLoc &loc)
3318 {
3319         if(mSwitchNestingLevel == 0)
3320         {
3321                 error(loc, "default labels need to be inside switch statements", "default");
3322                 recover();
3323                 return nullptr;
3324         }
3325         TIntermCase *node = intermediate.addCase(nullptr, loc);
3326         if(node == nullptr)
3327         {
3328                 error(loc, "erroneous default statement", "default");
3329                 recover();
3330                 return nullptr;
3331         }
3332         return node;
3333 }
3334 TIntermTyped *TParseContext::createAssign(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc)
3335 {
3336         if(binaryOpCommonCheck(op, left, right, loc))
3337         {
3338                 return intermediate.addAssign(op, left, right, loc);
3339         }
3340         return nullptr;
3341 }
3342
3343 TIntermTyped *TParseContext::addAssign(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc)
3344 {
3345         TIntermTyped *node = createAssign(op, left, right, loc);
3346         if(node == nullptr)
3347         {
3348                 assignError(loc, "assign", left->getCompleteString(), right->getCompleteString());
3349                 recover();
3350                 return left;
3351         }
3352         return node;
3353 }
3354
3355 TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, TIntermTyped *left, TIntermTyped *right,
3356         const TSourceLoc &loc)
3357 {
3358         if(!binaryOpCommonCheck(op, left, right, loc))
3359                 return nullptr;
3360
3361         switch(op)
3362         {
3363         case EOpEqual:
3364         case EOpNotEqual:
3365                 break;
3366         case EOpLessThan:
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)
3373                 {
3374                         return nullptr;
3375                 }
3376                 break;
3377         case EOpLogicalOr:
3378         case EOpLogicalXor:
3379         case EOpLogicalAnd:
3380                 ASSERT(!left->isArray() && !right->isArray());
3381                 if(left->getBasicType() != EbtBool ||
3382                         left->isMatrix() || left->isVector())
3383                 {
3384                         return nullptr;
3385                 }
3386                 break;
3387         case EOpAdd:
3388         case EOpSub:
3389         case EOpDiv:
3390         case EOpMul:
3391                 ASSERT(!left->isArray() && !right->isArray());
3392                 if(left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool)
3393                 {
3394                         return nullptr;
3395                 }
3396                 break;
3397         case EOpIMod:
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)
3401                 {
3402                         return nullptr;
3403                 }
3404                 break;
3405                 // Note that for bitwise ops, type checking is done in promote() to
3406                 // share code between ops and compound assignment
3407         default:
3408                 break;
3409         }
3410
3411         return intermediate.addBinaryMath(op, left, right, loc);
3412 }
3413
3414 TIntermTyped *TParseContext::addBinaryMath(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc)
3415 {
3416         TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
3417         if(node == 0)
3418         {
3419                 binaryOpError(loc, getOperatorString(op), left->getCompleteString(), right->getCompleteString());
3420                 recover();
3421                 return left;
3422         }
3423         return node;
3424 }
3425
3426 TIntermTyped *TParseContext::addBinaryMathBooleanResult(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc)
3427 {
3428         TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
3429         if(node == 0)
3430         {
3431                 binaryOpError(loc, getOperatorString(op), left->getCompleteString(), right->getCompleteString());
3432                 recover();
3433                 ConstantUnion *unionArray = new ConstantUnion[1];
3434                 unionArray->setBConst(false);
3435                 return intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConstExpr), loc);
3436         }
3437         return node;
3438 }
3439
3440 TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc)
3441 {
3442         switch(op)
3443         {
3444         case EOpContinue:
3445                 if(mLoopNestingLevel <= 0)
3446                 {
3447                         error(loc, "continue statement only allowed in loops", "");
3448                         recover();
3449                 }
3450                 break;
3451         case EOpBreak:
3452                 if(mLoopNestingLevel <= 0 && mSwitchNestingLevel <= 0)
3453                 {
3454                         error(loc, "break statement only allowed in loops and switch statements", "");
3455                         recover();
3456                 }
3457                 break;
3458         case EOpReturn:
3459                 if(mCurrentFunctionType->getBasicType() != EbtVoid)
3460                 {
3461                         error(loc, "non-void function must return a value", "return");
3462                         recover();
3463                 }
3464                 break;
3465         default:
3466                 // No checks for discard
3467                 break;
3468         }
3469         return intermediate.addBranch(op, loc);
3470 }
3471
3472 TIntermBranch *TParseContext::addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc)
3473 {
3474         ASSERT(op == EOpReturn);
3475         mFunctionReturnsValue = true;
3476         if(mCurrentFunctionType->getBasicType() == EbtVoid)
3477         {
3478                 error(loc, "void function cannot return a value", "return");
3479                 recover();
3480         }
3481         else if(*mCurrentFunctionType != returnValue->getType())
3482         {
3483                 error(loc, "function return is not matching type:", "return");
3484                 recover();
3485         }
3486         return intermediate.addBranch(op, returnValue, loc);
3487 }
3488
3489 TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, TIntermNode *paramNode, TIntermNode *thisNode, const TSourceLoc &loc, bool *fatalError)
3490 {
3491         *fatalError = false;
3492         TOperator op = fnCall->getBuiltInOp();
3493         TIntermTyped *callNode = nullptr;
3494
3495         if(thisNode != nullptr)
3496         {
3497                 ConstantUnion *unionArray = new ConstantUnion[1];
3498                 int arraySize = 0;
3499                 TIntermTyped *typedThis = thisNode->getAsTyped();
3500                 if(fnCall->getName() != "length")
3501                 {
3502                         error(loc, "invalid method", fnCall->getName().c_str());
3503                         recover();
3504                 }
3505                 else if(paramNode != nullptr)
3506                 {
3507                         error(loc, "method takes no parameters", "length");
3508                         recover();
3509                 }
3510                 else if(typedThis == nullptr || !typedThis->isArray())
3511                 {
3512                         error(loc, "length can only be called on arrays", "length");
3513                         recover();
3514                 }
3515                 else
3516                 {
3517                         arraySize = typedThis->getArraySize();
3518                         if(typedThis->getAsSymbolNode() == nullptr)
3519                         {
3520                                 // This code path can be hit with expressions like these:
3521                                 // (a = b).length()
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");
3528                                 recover();
3529                         }
3530                 }
3531                 unionArray->setIConst(arraySize);
3532                 callNode = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConstExpr), loc);
3533         }
3534         else if(op != EOpNull)
3535         {
3536                 //
3537                 // Then this should be a constructor.
3538                 // Don't go through the symbol table for constructors.
3539                 // Their parameters will be verified algorithmically.
3540                 //
3541                 TType type(EbtVoid, EbpUndefined);  // use this to get the type back
3542                 if(!constructorErrorCheck(loc, paramNode, *fnCall, op, &type))
3543                 {
3544                         //
3545                         // It's a constructor, of type 'type'.
3546                         //
3547                         callNode = addConstructor(paramNode, &type, op, fnCall, loc);
3548                 }
3549
3550                 if(callNode == nullptr)
3551                 {
3552                         recover();
3553                         callNode = intermediate.setAggregateOperator(nullptr, op, loc);
3554                 }
3555         }
3556         else
3557         {
3558                 //
3559                 // Not a constructor.  Find it in the symbol table.
3560                 //
3561                 const TFunction *fnCandidate;
3562                 bool builtIn;
3563                 fnCandidate = findFunction(loc, fnCall, &builtIn);
3564                 if(fnCandidate)
3565                 {
3566                         //
3567                         // A declared function.
3568                         //
3569                         if(builtIn && !fnCandidate->getExtension().empty() &&
3570                                 extensionErrorCheck(loc, fnCandidate->getExtension()))
3571                         {
3572                                 recover();
3573                         }
3574                         op = fnCandidate->getBuiltInOp();
3575                         if(builtIn && op != EOpNull)
3576                         {
3577                                 //
3578                                 // A function call mapped to a built-in operation.
3579                                 //
3580                                 if(fnCandidate->getParamCount() == 1)
3581                                 {
3582                                         //
3583                                         // Treat it like a built-in unary operator.
3584                                         //
3585                                         callNode = createUnaryMath(op, paramNode->getAsTyped(), loc, &fnCandidate->getReturnType());
3586                                         if(callNode == nullptr)
3587                                         {
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());
3593                                                 *fatalError = true;
3594                                                 return nullptr;
3595                                         }
3596                                 }
3597                                 else
3598                                 {
3599                                         TIntermAggregate *aggregate = intermediate.setAggregateOperator(paramNode, op, loc);
3600                                         aggregate->setType(fnCandidate->getReturnType());
3601
3602                                         // Some built-in functions have out parameters too.
3603                                         functionCallLValueErrorCheck(fnCandidate, aggregate);
3604
3605                                         callNode = aggregate;
3606
3607                                         if(fnCandidate->getParamCount() == 2)
3608                                         {
3609                                                 TIntermSequence &parameters = paramNode->getAsAggregate()->getSequence();
3610                                                 TIntermTyped *left = parameters[0]->getAsTyped();
3611                                                 TIntermTyped *right = parameters[1]->getAsTyped();
3612
3613                                                 TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
3614                                                 TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
3615                                                 if (leftTempConstant && rightTempConstant)
3616                                                 {
3617                                                         TIntermTyped *typedReturnNode = leftTempConstant->fold(op, rightTempConstant, infoSink());
3618
3619                                                         if(typedReturnNode)
3620                                                         {
3621                                                                 callNode = typedReturnNode;
3622                                                         }
3623                                                 }
3624                                         }
3625                                 }
3626                         }
3627                         else
3628                         {
3629                                 // This is a real function call
3630
3631                                 TIntermAggregate *aggregate = intermediate.setAggregateOperator(paramNode, EOpFunctionCall, loc);
3632                                 aggregate->setType(fnCandidate->getReturnType());
3633
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
3637                                 if(!builtIn)
3638                                         aggregate->setUserDefined();
3639                                 aggregate->setName(fnCandidate->getMangledName());
3640
3641                                 callNode = aggregate;
3642
3643                                 functionCallLValueErrorCheck(fnCandidate, aggregate);
3644                         }
3645                 }
3646                 else
3647                 {
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);
3653                         recover();
3654                 }
3655         }
3656         delete fnCall;
3657         return callNode;
3658 }
3659
3660 TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &loc)
3661 {
3662         if(boolErrorCheck(loc, cond))
3663                 recover();
3664
3665         if(trueBlock->getType() != falseBlock->getType())
3666         {
3667                 binaryOpError(loc, ":", trueBlock->getCompleteString(), falseBlock->getCompleteString());
3668                 recover();
3669                 return falseBlock;
3670         }
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)
3675         {
3676                 error(loc, "ternary operator is not allowed for structures or arrays", ":");
3677                 recover();
3678                 return falseBlock;
3679         }
3680         return intermediate.addSelection(cond, trueBlock, falseBlock, loc);
3681 }
3682
3683 //
3684 // Parse an array of strings using yyparse.
3685 //
3686 // Returns 0 for success.
3687 //
3688 int PaParseStrings(int count, const char* const string[], const int length[],
3689                                    TParseContext* context) {
3690         if ((count == 0) || !string)
3691                 return 1;
3692
3693         if (glslang_initialize(context))
3694                 return 1;
3695
3696         int error = glslang_scan(count, string, length, context);
3697         if (!error)
3698                 error = glslang_parse(context);
3699
3700         glslang_finalize(context);
3701
3702         return (error == 0) && (context->numErrors() == 0) ? 0 : 1;
3703 }
3704
3705
3706