OSDN Git Service

Replacing int by TSourceLoc for lines
[android-x86/external-swiftshader.git] / src / OpenGL / compiler / ParseHelper.cpp
1 //
2 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 #include "ParseHelper.h"
8
9 #include <stdarg.h>
10 #include <stdio.h>
11
12 #include "glslang.h"
13 #include "preprocessor/SourceLocation.h"
14 #include "ValidateSwitch.h"
15
16 ///////////////////////////////////////////////////////////////////////
17 //
18 // Sub- vector and matrix fields
19 //
20 ////////////////////////////////////////////////////////////////////////
21
22 //
23 // Look at a '.' field selector string and change it into offsets
24 // for a vector.
25 //
26 bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, const TSourceLoc &line)
27 {
28     fields.num = (int) compString.size();
29     if (fields.num > 4) {
30         error(line, "illegal vector field selection", compString.c_str());
31         return false;
32     }
33
34     enum {
35         exyzw,
36         ergba,
37         estpq
38     } fieldSet[4];
39
40     for (int i = 0; i < fields.num; ++i) {
41         switch (compString[i])  {
42         case 'x':
43             fields.offsets[i] = 0;
44             fieldSet[i] = exyzw;
45             break;
46         case 'r':
47             fields.offsets[i] = 0;
48             fieldSet[i] = ergba;
49             break;
50         case 's':
51             fields.offsets[i] = 0;
52             fieldSet[i] = estpq;
53             break;
54         case 'y':
55             fields.offsets[i] = 1;
56             fieldSet[i] = exyzw;
57             break;
58         case 'g':
59             fields.offsets[i] = 1;
60             fieldSet[i] = ergba;
61             break;
62         case 't':
63             fields.offsets[i] = 1;
64             fieldSet[i] = estpq;
65             break;
66         case 'z':
67             fields.offsets[i] = 2;
68             fieldSet[i] = exyzw;
69             break;
70         case 'b':
71             fields.offsets[i] = 2;
72             fieldSet[i] = ergba;
73             break;
74         case 'p':
75             fields.offsets[i] = 2;
76             fieldSet[i] = estpq;
77             break;
78         case 'w':
79             fields.offsets[i] = 3;
80             fieldSet[i] = exyzw;
81             break;
82         case 'a':
83             fields.offsets[i] = 3;
84             fieldSet[i] = ergba;
85             break;
86         case 'q':
87             fields.offsets[i] = 3;
88             fieldSet[i] = estpq;
89             break;
90         default:
91             error(line, "illegal vector field selection", compString.c_str());
92             return false;
93         }
94     }
95
96     for (int i = 0; i < fields.num; ++i) {
97         if (fields.offsets[i] >= vecSize) {
98             error(line, "vector field selection out of range",  compString.c_str());
99             return false;
100         }
101
102         if (i > 0) {
103             if (fieldSet[i] != fieldSet[i-1]) {
104                 error(line, "illegal - vector component fields not from the same set", compString.c_str());
105                 return false;
106             }
107         }
108     }
109
110     return true;
111 }
112
113
114 //
115 // Look at a '.' field selector string and change it into offsets
116 // for a matrix.
117 //
118 bool TParseContext::parseMatrixFields(const TString& compString, int matCols, int matRows, TMatrixFields& fields, const TSourceLoc &line)
119 {
120     fields.wholeRow = false;
121     fields.wholeCol = false;
122     fields.row = -1;
123     fields.col = -1;
124
125     if (compString.size() != 2) {
126         error(line, "illegal length of matrix field selection", compString.c_str());
127         return false;
128     }
129
130     if (compString[0] == '_') {
131         if (compString[1] < '0' || compString[1] > '3') {
132             error(line, "illegal matrix field selection", compString.c_str());
133             return false;
134         }
135         fields.wholeCol = true;
136         fields.col = compString[1] - '0';
137     } else if (compString[1] == '_') {
138         if (compString[0] < '0' || compString[0] > '3') {
139             error(line, "illegal matrix field selection", compString.c_str());
140             return false;
141         }
142         fields.wholeRow = true;
143         fields.row = compString[0] - '0';
144     } else {
145         if (compString[0] < '0' || compString[0] > '3' ||
146             compString[1] < '0' || compString[1] > '3') {
147             error(line, "illegal matrix field selection", compString.c_str());
148             return false;
149         }
150         fields.row = compString[0] - '0';
151         fields.col = compString[1] - '0';
152     }
153
154     if (fields.row >= matRows || fields.col >= matCols) {
155         error(line, "matrix field selection out of range", compString.c_str());
156         return false;
157     }
158
159     return true;
160 }
161
162 ///////////////////////////////////////////////////////////////////////
163 //
164 // Errors
165 //
166 ////////////////////////////////////////////////////////////////////////
167
168 //
169 // Track whether errors have occurred.
170 //
171 void TParseContext::recover()
172 {
173 }
174
175 //
176 // Used by flex/bison to output all syntax and parsing errors.
177 //
178 void TParseContext::error(const TSourceLoc& loc,
179                           const char* reason, const char* token,
180                           const char* extraInfo)
181 {
182     pp::SourceLocation srcLoc;
183     DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line);
184     diagnostics.writeInfo(pp::Diagnostics::PP_ERROR,
185                           srcLoc, reason, token, extraInfo);
186
187 }
188
189 void TParseContext::warning(const TSourceLoc& loc,
190                             const char* reason, const char* token,
191                             const char* extraInfo) {
192     pp::SourceLocation srcLoc;
193     DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line);
194     diagnostics.writeInfo(pp::Diagnostics::PP_WARNING,
195                           srcLoc, reason, token, extraInfo);
196 }
197
198 void TParseContext::trace(const char* str)
199 {
200     diagnostics.writeDebug(str);
201 }
202
203 //
204 // Same error message for all places assignments don't work.
205 //
206 void TParseContext::assignError(const TSourceLoc &line, const char* op, TString left, TString right)
207 {
208     std::stringstream extraInfoStream;
209     extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'";
210     std::string extraInfo = extraInfoStream.str();
211     error(line, "", op, extraInfo.c_str());
212 }
213
214 //
215 // Same error message for all places unary operations don't work.
216 //
217 void TParseContext::unaryOpError(const TSourceLoc &line, const char* op, TString operand)
218 {
219     std::stringstream extraInfoStream;
220     extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " << operand
221                     << " (or there is no acceptable conversion)";
222     std::string extraInfo = extraInfoStream.str();
223     error(line, " wrong operand type", op, extraInfo.c_str());
224 }
225
226 //
227 // Same error message for all binary operations don't work.
228 //
229 void TParseContext::binaryOpError(const TSourceLoc &line, const char* op, TString left, TString right)
230 {
231     std::stringstream extraInfoStream;
232     extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" << left 
233                     << "' and a right operand of type '" << right << "' (or there is no acceptable conversion)";
234     std::string extraInfo = extraInfoStream.str();
235     error(line, " wrong operand types ", op, extraInfo.c_str());
236 }
237
238 bool TParseContext::precisionErrorCheck(const TSourceLoc &line, TPrecision precision, TBasicType type){
239     if (!checksPrecisionErrors)
240         return false;
241     switch( type ){
242     case EbtFloat:
243         if( precision == EbpUndefined ){
244             error( line, "No precision specified for (float)", "" );
245             return true;
246         }
247         break;
248     case EbtInt:
249         if( precision == EbpUndefined ){
250             error( line, "No precision specified (int)", "" );
251             return true;
252         }
253         break;
254     default:
255         return false;
256     }
257     return false;
258 }
259
260 //
261 // Both test and if necessary, spit out an error, to see if the node is really
262 // an l-value that can be operated on this way.
263 //
264 // Returns true if the was an error.
265 //
266 bool TParseContext::lValueErrorCheck(const TSourceLoc &line, const char* op, TIntermTyped* node)
267 {
268     TIntermSymbol* symNode = node->getAsSymbolNode();
269     TIntermBinary* binaryNode = node->getAsBinaryNode();
270
271     if (binaryNode) {
272         bool errorReturn;
273
274         switch(binaryNode->getOp()) {
275         case EOpIndexDirect:
276         case EOpIndexIndirect:
277         case EOpIndexDirectStruct:
278             return lValueErrorCheck(line, op, binaryNode->getLeft());
279         case EOpVectorSwizzle:
280             errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft());
281             if (!errorReturn) {
282                 int offset[4] = {0,0,0,0};
283
284                 TIntermTyped* rightNode = binaryNode->getRight();
285                 TIntermAggregate *aggrNode = rightNode->getAsAggregate();
286
287                 for (TIntermSequence::iterator p = aggrNode->getSequence().begin();
288                                                p != aggrNode->getSequence().end(); p++) {
289                     int value = (*p)->getAsTyped()->getAsConstantUnion()->getIConst(0);
290                     offset[value]++;
291                     if (offset[value] > 1) {
292                         error(line, " l-value of swizzle cannot have duplicate components", op);
293
294                         return true;
295                     }
296                 }
297             }
298
299             return errorReturn;
300         default:
301             break;
302         }
303         error(line, " l-value required", op);
304
305         return true;
306     }
307
308
309     const char* symbol = 0;
310     if (symNode != 0)
311         symbol = symNode->getSymbol().c_str();
312
313     const char* message = 0;
314     switch (node->getQualifier()) {
315     case EvqConstExpr:      message = "can't modify a const";        break;
316     case EvqConstReadOnly:  message = "can't modify a const";        break;
317     case EvqAttribute:      message = "can't modify an attribute";   break;
318     case EvqFragmentIn:     message = "can't modify an input";       break;
319     case EvqVertexIn:       message = "can't modify an input";       break;
320     case EvqUniform:        message = "can't modify a uniform";      break;
321     case EvqSmoothIn:
322     case EvqFlatIn:
323     case EvqCentroidIn:
324     case EvqVaryingIn:      message = "can't modify a varying";      break;
325     case EvqInput:          message = "can't modify an input";       break;
326     case EvqFragCoord:      message = "can't modify gl_FragCoord";   break;
327     case EvqFrontFacing:    message = "can't modify gl_FrontFacing"; break;
328     case EvqPointCoord:     message = "can't modify gl_PointCoord";  break;
329     case EvqInstanceID:     message = "can't modify gl_InstanceID";  break;
330     default:
331
332         //
333         // Type that can't be written to?
334         //
335         if(IsSampler(node->getBasicType()))
336         {
337             message = "can't modify a sampler";
338         }
339         else if(node->getBasicType() == EbtVoid)
340         {
341             message = "can't modify void";
342         }
343     }
344
345     if (message == 0 && binaryNode == 0 && symNode == 0) {
346         error(line, " l-value required", op);
347
348         return true;
349     }
350
351
352     //
353     // Everything else is okay, no error.
354     //
355     if (message == 0)
356         return false;
357
358     //
359     // If we get here, we have an error and a message.
360     //
361     if (symNode) {
362         std::stringstream extraInfoStream;
363         extraInfoStream << "\"" << symbol << "\" (" << message << ")";
364         std::string extraInfo = extraInfoStream.str();
365         error(line, " l-value required", op, extraInfo.c_str());
366     }
367     else {
368         std::stringstream extraInfoStream;
369         extraInfoStream << "(" << message << ")";
370         std::string extraInfo = extraInfoStream.str();
371         error(line, " l-value required", op, extraInfo.c_str());
372     }
373
374     return true;
375 }
376
377 //
378 // Both test, and if necessary spit out an error, to see if the node is really
379 // a constant.
380 //
381 // Returns true if the was an error.
382 //
383 bool TParseContext::constErrorCheck(TIntermTyped* node)
384 {
385     if (node->getQualifier() == EvqConstExpr)
386         return false;
387
388     error(node->getLine(), "constant expression required", "");
389
390     return true;
391 }
392
393 //
394 // Both test, and if necessary spit out an error, to see if the node is really
395 // an integer.
396 //
397 // Returns true if the was an error.
398 //
399 bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token)
400 {
401     if (node->isScalarInt())
402         return false;
403
404     error(node->getLine(), "integer expression required", token);
405
406     return true;
407 }
408
409 //
410 // Both test, and if necessary spit out an error, to see if we are currently
411 // globally scoped.
412 //
413 // Returns true if the was an error.
414 //
415 bool TParseContext::globalErrorCheck(const TSourceLoc &line, bool global, const char* token)
416 {
417     if (global)
418         return false;
419
420     error(line, "only allowed at global scope", token);
421
422     return true;
423 }
424
425 //
426 // For now, keep it simple:  if it starts "gl_", it's reserved, independent
427 // of scope.  Except, if the symbol table is at the built-in push-level,
428 // which is when we are parsing built-ins.
429 // Also checks for "webgl_" and "_webgl_" reserved identifiers if parsing a
430 // webgl shader.
431 //
432 // Returns true if there was an error.
433 //
434 bool TParseContext::reservedErrorCheck(const TSourceLoc &line, const TString& identifier)
435 {
436     static const char* reservedErrMsg = "reserved built-in name";
437     if (!symbolTable.atBuiltInLevel()) {
438         if (identifier.compare(0, 3, "gl_") == 0) {
439             error(line, reservedErrMsg, "gl_");
440             return true;
441         }
442         if (identifier.find("__") != TString::npos) {
443             error(line, "identifiers containing two consecutive underscores (__) are reserved as possible future keywords", identifier.c_str());
444             return true;
445         }
446     }
447
448     return false;
449 }
450
451 //
452 // Make sure there is enough data provided to the constructor to build
453 // something of the type of the constructor.  Also returns the type of
454 // the constructor.
455 //
456 // Returns true if there was an error in construction.
457 //
458 bool TParseContext::constructorErrorCheck(const TSourceLoc &line, TIntermNode* node, TFunction& function, TOperator op, TType* type)
459 {
460     *type = function.getReturnType();
461
462     bool constructingMatrix = false;
463     switch(op) {
464     case EOpConstructMat2:
465     case EOpConstructMat3:
466     case EOpConstructMat4:
467         constructingMatrix = true;
468         break;
469     default:
470         break;
471     }
472
473     //
474     // Note: It's okay to have too many components available, but not okay to have unused
475     // arguments.  'full' will go to true when enough args have been seen.  If we loop
476     // again, there is an extra argument, so 'overfull' will become true.
477     //
478
479     int size = 0;
480     bool constType = true;
481     bool full = false;
482     bool overFull = false;
483     bool matrixInMatrix = false;
484     bool arrayArg = false;
485     for (size_t i = 0; i < function.getParamCount(); ++i) {
486         const TParameter& param = function.getParam(i);
487         size += param.type->getObjectSize();
488
489         if (constructingMatrix && param.type->isMatrix())
490             matrixInMatrix = true;
491         if (full)
492             overFull = true;
493         if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize())
494             full = true;
495         if (param.type->getQualifier() != EvqConstExpr)
496             constType = false;
497         if (param.type->isArray())
498             arrayArg = true;
499     }
500
501     if (constType)
502         type->setQualifier(EvqConstExpr);
503
504     if (type->isArray() && type->getArraySize() != function.getParamCount()) {
505         error(line, "array constructor needs one argument per array element", "constructor");
506         return true;
507     }
508
509     if (arrayArg && op != EOpConstructStruct) {
510         error(line, "constructing from a non-dereferenced array", "constructor");
511         return true;
512     }
513
514     if (matrixInMatrix && !type->isArray()) {
515         if (function.getParamCount() != 1) {
516           error(line, "constructing matrix from matrix can only take one argument", "constructor");
517           return true;
518         }
519     }
520
521     if (overFull) {
522         error(line, "too many arguments", "constructor");
523         return true;
524     }
525
526     if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->fields().size()) != function.getParamCount()) {
527         error(line, "Number of constructor parameters does not match the number of structure fields", "constructor");
528         return true;
529     }
530
531     if (!type->isMatrix() || !matrixInMatrix) {
532         if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) ||
533             (op == EOpConstructStruct && size < type->getObjectSize())) {
534             error(line, "not enough data provided for construction", "constructor");
535             return true;
536         }
537     }
538
539     TIntermTyped *typed = node ? node->getAsTyped() : 0;
540     if (typed == 0) {
541         error(line, "constructor argument does not have a type", "constructor");
542         return true;
543     }
544     if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) {
545         error(line, "cannot convert a sampler", "constructor");
546         return true;
547     }
548     if (typed->getBasicType() == EbtVoid) {
549         error(line, "cannot convert a void", "constructor");
550         return true;
551     }
552
553     return false;
554 }
555
556 // This function checks to see if a void variable has been declared and raise an error message for such a case
557 //
558 // returns true in case of an error
559 //
560 bool TParseContext::voidErrorCheck(const TSourceLoc &line, const TString& identifier, const TBasicType& type)
561 {
562     if(type == EbtVoid) {
563         error(line, "illegal use of type 'void'", identifier.c_str());
564         return true;
565     }
566
567     return false;
568 }
569
570 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
571 //
572 // returns true in case of an error
573 //
574 bool TParseContext::boolErrorCheck(const TSourceLoc &line, const TIntermTyped* type)
575 {
576     if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) {
577         error(line, "boolean expression expected", "");
578         return true;
579     }
580
581     return false;
582 }
583
584 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
585 //
586 // returns true in case of an error
587 //
588 bool TParseContext::boolErrorCheck(const TSourceLoc &line, const TPublicType& pType)
589 {
590     if (pType.type != EbtBool || pType.array || (pType.primarySize > 1) || (pType.secondarySize > 1)) {
591         error(line, "boolean expression expected", "");
592         return true;
593     }
594
595     return false;
596 }
597
598 bool TParseContext::samplerErrorCheck(const TSourceLoc &line, const TPublicType& pType, const char* reason)
599 {
600     if (pType.type == EbtStruct) {
601         if (containsSampler(*pType.userDef)) {
602             error(line, reason, getBasicString(pType.type), "(structure contains a sampler)");
603
604             return true;
605         }
606
607         return false;
608     } else if (IsSampler(pType.type)) {
609         error(line, reason, getBasicString(pType.type));
610
611         return true;
612     }
613
614     return false;
615 }
616
617 bool TParseContext::structQualifierErrorCheck(const TSourceLoc &line, const TPublicType& pType)
618 {
619         switch(pType.qualifier)
620         {
621         case EvqVaryingOut:
622         case EvqSmooth:
623         case EvqFlat:
624         case EvqCentroidOut:
625         case EvqVaryingIn:
626         case EvqSmoothIn:
627         case EvqFlatIn:
628         case EvqCentroidIn:
629         case EvqAttribute:
630         case EvqVertexIn:
631         case EvqFragmentOut:
632                 if(pType.type == EbtStruct)
633                 {
634                         error(line, "cannot be used with a structure", getQualifierString(pType.qualifier));
635
636                         return true;
637                 }
638                 break;
639         default:
640                 break;
641         }
642
643     if (pType.qualifier != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform"))
644         return true;
645
646         // check for layout qualifier issues
647         const TLayoutQualifier layoutQualifier = pType.layoutQualifier;
648
649         if (pType.qualifier != EvqVertexIn && pType.qualifier != EvqFragmentOut &&
650             layoutLocationErrorCheck(line, pType.layoutQualifier))
651         {
652                 return true;
653         }
654
655     return false;
656 }
657
658 // These checks are common for all declarations starting a declarator list, and declarators that follow an empty
659 // declaration.
660 //
661 bool TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &identifierLocation)
662 {
663         switch(publicType.qualifier)
664         {
665         case EvqVaryingIn:
666         case EvqVaryingOut:
667         case EvqAttribute:
668         case EvqVertexIn:
669         case EvqFragmentOut:
670                 if(publicType.type == EbtStruct)
671                 {
672                         error(identifierLocation, "cannot be used with a structure",
673                                 getQualifierString(publicType.qualifier));
674                         return true;
675                 }
676
677         default: break;
678         }
679
680         if(publicType.qualifier != EvqUniform && samplerErrorCheck(identifierLocation, publicType,
681                 "samplers must be uniform"))
682         {
683                 return true;
684         }
685
686         // check for layout qualifier issues
687         const TLayoutQualifier layoutQualifier = publicType.layoutQualifier;
688
689         if(layoutQualifier.matrixPacking != EmpUnspecified)
690         {
691                 error(identifierLocation, "layout qualifier", getMatrixPackingString(layoutQualifier.matrixPacking),
692                         "only valid for interface blocks");
693                 return true;
694         }
695
696         if(layoutQualifier.blockStorage != EbsUnspecified)
697         {
698                 error(identifierLocation, "layout qualifier", getBlockStorageString(layoutQualifier.blockStorage),
699                         "only valid for interface blocks");
700                 return true;
701         }
702
703         if(publicType.qualifier != EvqVertexIn && publicType.qualifier != EvqFragmentOut &&
704                 layoutLocationErrorCheck(identifierLocation, publicType.layoutQualifier))
705         {
706                 return true;
707         }
708
709         return false;
710 }
711
712 bool TParseContext::layoutLocationErrorCheck(const TSourceLoc &location, const TLayoutQualifier &layoutQualifier)\r
713 {\r
714         if(layoutQualifier.location != -1)\r
715         {\r
716                 error(location, "invalid layout qualifier:", "location", "only valid on program inputs and outputs");\r
717                 return true;\r
718         }\r
719 \r
720         return false;\r
721 }\r
722
723 bool TParseContext::locationDeclaratorListCheck(const TSourceLoc& line, const TPublicType &pType)
724 {
725         if(pType.layoutQualifier.location != -1)
726         {
727                 error(line, "location must only be specified for a single input or output variable", "location");
728                 return true;
729         }
730
731         return false;
732 }
733
734 bool TParseContext::parameterSamplerErrorCheck(const TSourceLoc &line, TQualifier qualifier, const TType& type)
735 {
736     if ((qualifier == EvqOut || qualifier == EvqInOut) &&
737              type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
738         error(line, "samplers cannot be output parameters", type.getBasicString());
739         return true;
740     }
741
742     return false;
743 }
744
745 bool TParseContext::containsSampler(TType& type)
746 {
747     if (IsSampler(type.getBasicType()))
748         return true;
749
750     if (type.getBasicType() == EbtStruct) {
751         const TFieldList& fields = type.getStruct()->fields();
752         for(unsigned int i = 0; i < fields.size(); ++i) {
753             if (containsSampler(*fields[i]->type()))
754                 return true;
755         }
756     }
757
758     return false;
759 }
760
761 //
762 // Do size checking for an array type's size.
763 //
764 // Returns true if there was an error.
765 //
766 bool TParseContext::arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped* expr, int& size)
767 {
768     TIntermConstantUnion* constant = expr->getAsConstantUnion();
769
770     if (constant == 0 || !constant->isScalarInt())
771     {
772         error(line, "array size must be a constant integer expression", "");
773         return true;
774     }
775
776     if (constant->getBasicType() == EbtUInt)
777     {
778         unsigned int uintSize = constant->getUConst(0);
779         if (uintSize > static_cast<unsigned int>(std::numeric_limits<int>::max()))
780         {
781             error(line, "array size too large", "");
782             size = 1;
783             return true;
784         }
785
786         size = static_cast<int>(uintSize);
787     }
788     else
789     {
790         size = constant->getIConst(0);
791
792         if (size <= 0)
793         {
794             error(line, "array size must be a positive integer", "");
795             size = 1;
796             return true;
797         }
798     }
799
800     return false;
801 }
802
803 //
804 // See if this qualifier can be an array.
805 //
806 // Returns true if there is an error.
807 //
808 bool TParseContext::arrayQualifierErrorCheck(const TSourceLoc &line, TPublicType type)
809 {
810     if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqVertexIn) || (type.qualifier == EvqConstExpr)) {
811         error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str());
812         return true;
813     }
814
815     return false;
816 }
817
818 //
819 // See if this type can be an array.
820 //
821 // Returns true if there is an error.
822 //
823 bool TParseContext::arrayTypeErrorCheck(const TSourceLoc &line, TPublicType type)
824 {
825     //
826     // Can the type be an array?
827     //
828     if (type.array) {
829         error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str());
830         return true;
831     }
832
833     return false;
834 }
835
836 //
837 // Do all the semantic checking for declaring an array, with and
838 // without a size, and make the right changes to the symbol table.
839 //
840 // size == 0 means no specified size.
841 //
842 // Returns true if there was an error.
843 //
844 bool TParseContext::arrayErrorCheck(const TSourceLoc &line, TString& identifier, TPublicType type, TVariable*& variable)
845 {
846     //
847     // Don't check for reserved word use until after we know it's not in the symbol table,
848     // because reserved arrays can be redeclared.
849     //
850
851     bool builtIn = false;
852     bool sameScope = false;
853     TSymbol* symbol = symbolTable.find(identifier, shaderVersion, &builtIn, &sameScope);
854     if (symbol == 0 || !sameScope) {
855         if (reservedErrorCheck(line, identifier))
856             return true;
857
858         variable = new TVariable(&identifier, TType(type));
859
860         if (type.arraySize)
861             variable->getType().setArraySize(type.arraySize);
862
863         if (! symbolTable.declare(*variable)) {
864             delete variable;
865             error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str());
866             return true;
867         }
868     } else {
869         if (! symbol->isVariable()) {
870             error(line, "variable expected", identifier.c_str());
871             return true;
872         }
873
874         variable = static_cast<TVariable*>(symbol);
875         if (! variable->getType().isArray()) {
876             error(line, "redeclaring non-array as array", identifier.c_str());
877             return true;
878         }
879         if (variable->getType().getArraySize() > 0) {
880             error(line, "redeclaration of array with size", identifier.c_str());
881             return true;
882         }
883
884         if (! variable->getType().sameElementType(TType(type))) {
885             error(line, "redeclaration of array with a different type", identifier.c_str());
886             return true;
887         }
888
889         TType* t = variable->getArrayInformationType();
890         while (t != 0) {
891             if (t->getMaxArraySize() > type.arraySize) {
892                 error(line, "higher index value already used for the array", identifier.c_str());
893                 return true;
894             }
895             t->setArraySize(type.arraySize);
896             t = t->getArrayInformationType();
897         }
898
899         if (type.arraySize)
900             variable->getType().setArraySize(type.arraySize);
901     }
902
903     if (voidErrorCheck(line, identifier, type.type))
904         return true;
905
906     return false;
907 }
908
909 bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, const TSourceLoc &line)
910 {
911     bool builtIn = false;
912     TSymbol* symbol = symbolTable.find(node->getSymbol(), shaderVersion, &builtIn);
913     if (symbol == 0) {
914         error(line, " undeclared identifier", node->getSymbol().c_str());
915         return true;
916     }
917     TVariable* variable = static_cast<TVariable*>(symbol);
918
919     type->setArrayInformationType(variable->getArrayInformationType());
920     variable->updateArrayInformationType(type);
921
922     // special casing to test index value of gl_FragData. If the accessed index is >= gl_MaxDrawBuffers
923     // its an error
924     if (node->getSymbol() == "gl_FragData") {
925         TSymbol* fragData = symbolTable.find("gl_MaxDrawBuffers", shaderVersion, &builtIn);
926         ASSERT(fragData);
927
928         int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst();
929         if (fragDataValue <= size) {
930             error(line, "", "[", "gl_FragData can only have a max array size of up to gl_MaxDrawBuffers");
931             return true;
932         }
933     }
934
935     // we dont want to update the maxArraySize when this flag is not set, we just want to include this
936     // node type in the chain of node types so that its updated when a higher maxArraySize comes in.
937     if (!updateFlag)
938         return false;
939
940     size++;
941     variable->getType().setMaxArraySize(size);
942     type->setMaxArraySize(size);
943     TType* tt = type;
944
945     while(tt->getArrayInformationType() != 0) {
946         tt = tt->getArrayInformationType();
947         tt->setMaxArraySize(size);
948     }
949
950     return false;
951 }
952
953 //
954 // Enforce non-initializer type/qualifier rules.
955 //
956 // Returns true if there was an error.
957 //
958 bool TParseContext::nonInitConstErrorCheck(const TSourceLoc &line, TString& identifier, TPublicType& type, bool array)
959 {
960     if (type.qualifier == EvqConstExpr)
961     {
962         // Make the qualifier make sense.
963         type.qualifier = EvqTemporary;
964
965         if (array)
966         {
967             error(line, "arrays may not be declared constant since they cannot be initialized", identifier.c_str());
968         }
969         else if (type.isStructureContainingArrays())
970         {
971             error(line, "structures containing arrays may not be declared constant since they cannot be initialized", identifier.c_str());
972         }
973         else
974         {
975             error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
976         }
977
978         return true;
979     }
980
981     return false;
982 }
983
984 //
985 // Do semantic checking for a variable declaration that has no initializer,
986 // and update the symbol table.
987 //
988 // Returns true if there was an error.
989 //
990 bool TParseContext::nonInitErrorCheck(const TSourceLoc &line, const TString& identifier, TPublicType& type)
991 {
992         if(type.qualifier == EvqConstExpr)
993         {
994                 // Make the qualifier make sense.
995                 type.qualifier = EvqTemporary;
996
997                 // Generate informative error messages for ESSL1.
998                 // In ESSL3 arrays and structures containing arrays can be constant.
999                 if(shaderVersion < 300 && type.isStructureContainingArrays())
1000                 {
1001                         error(line,
1002                                 "structures containing arrays may not be declared constant since they cannot be initialized",
1003                                 identifier.c_str());
1004                 }
1005                 else
1006                 {
1007                         error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
1008                 }
1009
1010                 return true;
1011         }
1012         if(type.isUnsizedArray())
1013         {
1014                 error(line, "implicitly sized arrays need to be initialized", identifier.c_str());
1015                 return true;
1016         }
1017         return false;
1018 }
1019
1020 // Do some simple checks that are shared between all variable declarations,
1021 // and update the symbol table.
1022 //
1023 // Returns true if declaring the variable succeeded.
1024 //
1025 bool TParseContext::declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type,
1026         TVariable **variable)
1027 {
1028         ASSERT((*variable) == nullptr);
1029
1030         // gl_LastFragData may be redeclared with a new precision qualifier
1031         if(type.isArray() && identifier.compare(0, 15, "gl_LastFragData") == 0)
1032         {
1033                 const TVariable *maxDrawBuffers =
1034                         static_cast<const TVariable *>(symbolTable.findBuiltIn("gl_MaxDrawBuffers", shaderVersion));
1035                 if(type.getArraySize() != maxDrawBuffers->getConstPointer()->getIConst())
1036                 {
1037                         error(line, "redeclaration of gl_LastFragData with size != gl_MaxDrawBuffers", identifier.c_str());
1038                         return false;
1039                 }
1040         }
1041
1042         if(reservedErrorCheck(line, identifier))
1043                 return false;
1044
1045         (*variable) = new TVariable(&identifier, type);
1046         if(!symbolTable.declare(**variable))
1047         {
1048                 error(line, "redefinition", identifier.c_str());
1049                 delete (*variable);
1050                 (*variable) = nullptr;
1051                 return false;
1052         }
1053
1054         if(voidErrorCheck(line, identifier, type.getBasicType()))
1055                 return false;
1056
1057         return true;
1058 }
1059
1060 bool TParseContext::paramErrorCheck(const TSourceLoc &line, TQualifier qualifier, TQualifier paramQualifier, TType* type)
1061 {
1062     if (qualifier != EvqConstReadOnly && qualifier != EvqTemporary) {
1063         error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier));
1064         return true;
1065     }
1066     if (qualifier == EvqConstReadOnly && paramQualifier != EvqIn) {
1067         error(line, "qualifier not allowed with ", getQualifierString(qualifier), getQualifierString(paramQualifier));
1068         return true;
1069     }
1070
1071     if (qualifier == EvqConstReadOnly)
1072         type->setQualifier(EvqConstReadOnly);
1073     else
1074         type->setQualifier(paramQualifier);
1075
1076     return false;
1077 }
1078
1079 bool TParseContext::extensionErrorCheck(const TSourceLoc &line, const TString& extension)
1080 {
1081     const TExtensionBehavior& extBehavior = extensionBehavior();
1082     TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str());
1083     if (iter == extBehavior.end()) {
1084         error(line, "extension", extension.c_str(), "is not supported");
1085         return true;
1086     }
1087     // In GLSL ES, an extension's default behavior is "disable".
1088     if (iter->second == EBhDisable || iter->second == EBhUndefined) {
1089         error(line, "extension", extension.c_str(), "is disabled");
1090         return true;
1091     }
1092     if (iter->second == EBhWarn) {
1093         warning(line, "extension", extension.c_str(), "is being used");
1094         return false;
1095     }
1096
1097     return false;
1098 }
1099
1100 bool TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *aggregate)
1101 {
1102         for(size_t i = 0; i < fnCandidate->getParamCount(); ++i)
1103         {
1104                 TQualifier qual = fnCandidate->getParam(i).type->getQualifier();
1105                 if(qual == EvqOut || qual == EvqInOut)
1106                 {
1107                         TIntermTyped *node = (aggregate->getSequence())[i]->getAsTyped();
1108                         if(lValueErrorCheck(node->getLine(), "assign", node))
1109                         {
1110                                 error(node->getLine(),
1111                                         "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
1112                                 recover();
1113                                 return true;
1114                         }
1115                 }
1116         }
1117         return false;
1118 }
1119
1120 bool TParseContext::supportsExtension(const char* extension)
1121 {
1122     const TExtensionBehavior& extbehavior = extensionBehavior();
1123     TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
1124     return (iter != extbehavior.end());
1125 }
1126
1127 void TParseContext::handleExtensionDirective(const TSourceLoc &line, const char* extName, const char* behavior)
1128 {
1129     pp::SourceLocation loc;
1130     DecodeSourceLoc(line, &loc.file, &loc.line);
1131     directiveHandler.handleExtension(loc, extName, behavior);
1132 }
1133
1134 void TParseContext::handlePragmaDirective(const TSourceLoc &line, const char* name, const char* value)
1135 {
1136     pp::SourceLocation loc;
1137     DecodeSourceLoc(line, &loc.file, &loc.line);
1138     directiveHandler.handlePragma(loc, name, value);
1139 }
1140
1141 /////////////////////////////////////////////////////////////////////////////////
1142 //
1143 // Non-Errors.
1144 //
1145 /////////////////////////////////////////////////////////////////////////////////
1146
1147 const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location,
1148         const TString *name,
1149         const TSymbol *symbol)
1150 {
1151         const TVariable *variable = NULL;
1152
1153         if(!symbol)
1154         {
1155                 error(location, "undeclared identifier", name->c_str());
1156                 recover();
1157         }
1158         else if(!symbol->isVariable())
1159         {
1160                 error(location, "variable expected", name->c_str());
1161                 recover();
1162         }
1163         else
1164         {
1165                 variable = static_cast<const TVariable*>(symbol);
1166
1167                 if(symbolTable.findBuiltIn(variable->getName(), shaderVersion))
1168                 {
1169                         recover();
1170                 }
1171
1172                 // Reject shaders using both gl_FragData and gl_FragColor
1173                 TQualifier qualifier = variable->getType().getQualifier();
1174                 if(qualifier == EvqFragData)
1175                 {
1176                         mUsesFragData = true;
1177                 }
1178                 else if(qualifier == EvqFragColor)
1179                 {
1180                         mUsesFragColor = true;
1181                 }
1182
1183                 // This validation is not quite correct - it's only an error to write to
1184                 // both FragData and FragColor. For simplicity, and because users shouldn't
1185                 // be rewarded for reading from undefined varaibles, return an error
1186                 // if they are both referenced, rather than assigned.
1187                 if(mUsesFragData && mUsesFragColor)
1188                 {
1189                         error(location, "cannot use both gl_FragData and gl_FragColor", name->c_str());
1190                         recover();
1191                 }
1192         }
1193
1194         if(!variable)
1195         {
1196                 TType type(EbtFloat, EbpUndefined);
1197                 TVariable *fakeVariable = new TVariable(name, type);
1198                 symbolTable.declare(*fakeVariable);
1199                 variable = fakeVariable;
1200         }
1201
1202         return variable;
1203 }
1204
1205 //
1206 // Look up a function name in the symbol table, and make sure it is a function.
1207 //
1208 // Return the function symbol if found, otherwise 0.
1209 //
1210 const TFunction* TParseContext::findFunction(const TSourceLoc &line, TFunction* call, bool *builtIn)
1211 {
1212     // First find by unmangled name to check whether the function name has been
1213     // hidden by a variable name or struct typename.
1214     const TSymbol* symbol = symbolTable.find(call->getName(), shaderVersion, builtIn);
1215     if (symbol == 0) {
1216         symbol = symbolTable.find(call->getMangledName(), shaderVersion, builtIn);
1217     }
1218
1219     if (symbol == 0) {
1220         error(line, "no matching overloaded function found", call->getName().c_str());
1221         return 0;
1222     }
1223
1224     if (!symbol->isFunction()) {
1225         error(line, "function name expected", call->getName().c_str());
1226         return 0;
1227     }
1228
1229     return static_cast<const TFunction*>(symbol);
1230 }
1231
1232 //
1233 // Initializers show up in several places in the grammar.  Have one set of
1234 // code to handle them here.
1235 //
1236 bool TParseContext::executeInitializer(const TSourceLoc& line, const TString& identifier, const TPublicType& pType,
1237                                        TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable)
1238 {
1239     TType type = TType(pType);
1240
1241     if (variable == 0) {
1242         if (reservedErrorCheck(line, identifier))
1243             return true;
1244
1245         if (voidErrorCheck(line, identifier, pType.type))
1246             return true;
1247
1248         //
1249         // add variable to symbol table
1250         //
1251         variable = new TVariable(&identifier, type);
1252         if (! symbolTable.declare(*variable)) {
1253             error(line, "redefinition", variable->getName().c_str());
1254             return true;
1255             // don't delete variable, it's used by error recovery, and the pool
1256             // pop will take care of the memory
1257         }
1258     }
1259
1260     //
1261     // identifier must be of type constant, a global, or a temporary
1262     //
1263     TQualifier qualifier = variable->getType().getQualifier();
1264     if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConstExpr)) {
1265         error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString());
1266         return true;
1267     }
1268     //
1269     // test for and propagate constant
1270     //
1271
1272     if (qualifier == EvqConstExpr) {
1273         if (qualifier != initializer->getType().getQualifier()) {
1274             std::stringstream extraInfoStream;
1275             extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
1276             std::string extraInfo = extraInfoStream.str();
1277             error(line, " assigning non-constant to", "=", extraInfo.c_str());
1278             variable->getType().setQualifier(EvqTemporary);
1279             return true;
1280         }
1281         if (type != initializer->getType()) {
1282             error(line, " non-matching types for const initializer ",
1283                 variable->getType().getQualifierString());
1284             variable->getType().setQualifier(EvqTemporary);
1285             return true;
1286         }
1287         if (initializer->getAsConstantUnion()) {
1288             ConstantUnion* unionArray = variable->getConstPointer();
1289
1290             if (type.getObjectSize() == 1 && type.getBasicType() != EbtStruct) {
1291                 *unionArray = (initializer->getAsConstantUnion()->getUnionArrayPointer())[0];
1292             } else {
1293                 variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
1294             }
1295         } else if (initializer->getAsSymbolNode()) {
1296             const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), shaderVersion);
1297             const TVariable* tVar = static_cast<const TVariable*>(symbol);
1298
1299             ConstantUnion* constArray = tVar->getConstPointer();
1300             variable->shareConstPointer(constArray);
1301         } else {
1302             std::stringstream extraInfoStream;
1303             extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
1304             std::string extraInfo = extraInfoStream.str();
1305             error(line, " cannot assign to", "=", extraInfo.c_str());
1306             variable->getType().setQualifier(EvqTemporary);
1307             return true;
1308         }
1309     }
1310
1311     if (qualifier != EvqConstExpr) {
1312         TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
1313         intermNode = intermediate.addAssign(EOpInitialize, intermSymbol, initializer, line);
1314         if (intermNode == 0) {
1315             assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
1316             return true;
1317         }
1318     } else
1319         intermNode = 0;
1320
1321     return false;
1322 }
1323
1324 bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
1325 {
1326     ASSERT(aggrNode != NULL);
1327     if (!aggrNode->isConstructor())
1328         return false;
1329
1330     bool allConstant = true;
1331
1332     // check if all the child nodes are constants so that they can be inserted into
1333     // the parent node
1334     TIntermSequence &sequence = aggrNode->getSequence() ;
1335     for (TIntermSequence::iterator p = sequence.begin(); p != sequence.end(); ++p) {
1336         if (!(*p)->getAsTyped()->getAsConstantUnion())
1337             return false;
1338     }
1339
1340     return allConstant;
1341 }
1342
1343 TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, bool invariant, TLayoutQualifier layoutQualifier, const TPublicType &typeSpecifier)
1344 {
1345         TPublicType returnType = typeSpecifier;
1346         returnType.qualifier = qualifier;
1347         returnType.invariant = invariant;
1348         returnType.layoutQualifier = layoutQualifier;
1349
1350         if(typeSpecifier.array)
1351         {
1352                 error(typeSpecifier.line, "not supported", "first-class array");
1353                 recover();
1354                 returnType.clearArrayness();
1355         }
1356
1357         if(shaderVersion < 300)
1358         {
1359                 if(qualifier == EvqAttribute && (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt))
1360                 {
1361                         error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier));
1362                         recover();
1363                 }
1364
1365                 if((qualifier == EvqVaryingIn || qualifier == EvqVaryingOut) &&
1366                         (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt))
1367                 {
1368                         error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier));
1369                         recover();
1370                 }
1371         }
1372         else
1373         {
1374                 switch(qualifier)
1375                 {
1376                 case EvqSmoothIn:
1377                 case EvqSmoothOut:
1378                 case EvqVertexOut:
1379                 case EvqFragmentIn:
1380                 case EvqCentroidOut:
1381                 case EvqCentroidIn:
1382                         if(typeSpecifier.type == EbtBool)
1383                         {
1384                                 error(typeSpecifier.line, "cannot be bool", getQualifierString(qualifier));
1385                                 recover();
1386                         }
1387                         if(typeSpecifier.type == EbtInt || typeSpecifier.type == EbtUInt)
1388                         {
1389                                 error(typeSpecifier.line, "must use 'flat' interpolation here", getQualifierString(qualifier));
1390                                 recover();
1391                         }
1392                         break;
1393
1394                 case EvqVertexIn:
1395                 case EvqFragmentOut:
1396                 case EvqFlatIn:
1397                 case EvqFlatOut:
1398                         if(typeSpecifier.type == EbtBool)
1399                         {
1400                                 error(typeSpecifier.line, "cannot be bool", getQualifierString(qualifier));
1401                                 recover();
1402                         }
1403                         break;
1404
1405                 default: break;
1406                 }
1407         }
1408
1409         return returnType;
1410 }
1411
1412 TIntermAggregate *TParseContext::parseSingleDeclaration(TPublicType &publicType,
1413         const TSourceLoc &identifierOrTypeLocation,
1414         const TString &identifier)
1415 {
1416         TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierOrTypeLocation);
1417
1418         bool emptyDeclaration = (identifier == "");
1419
1420         mDeferredSingleDeclarationErrorCheck = emptyDeclaration;
1421
1422         if(emptyDeclaration)
1423         {
1424                 if(publicType.isUnsizedArray())
1425                 {
1426                         // ESSL3 spec section 4.1.9: Array declaration which leaves the size unspecified is an error.
1427                         // It is assumed that this applies to empty declarations as well.
1428                         error(identifierOrTypeLocation, "empty array declaration needs to specify a size", identifier.c_str());
1429                 }
1430         }
1431         else
1432         {
1433                 if(singleDeclarationErrorCheck(publicType, identifierOrTypeLocation))
1434                         recover();
1435
1436                 if(nonInitErrorCheck(identifierOrTypeLocation, identifier, publicType))
1437                         recover();
1438
1439                 TVariable *variable = nullptr;
1440                 if(!declareVariable(identifierOrTypeLocation, identifier, TType(publicType), &variable))
1441                         recover();
1442
1443                 if(variable && symbol)
1444                         symbol->setId(variable->getUniqueId());
1445         }
1446
1447         return intermediate.makeAggregate(symbol, identifierOrTypeLocation);
1448 }
1449
1450 TIntermAggregate *TParseContext::parseSingleArrayDeclaration(TPublicType &publicType,
1451         const TSourceLoc &identifierLocation,
1452         const TString &identifier,
1453         const TSourceLoc &indexLocation,
1454         TIntermTyped *indexExpression)
1455 {
1456         mDeferredSingleDeclarationErrorCheck = false;
1457
1458         if(singleDeclarationErrorCheck(publicType, identifierLocation))
1459                 recover();
1460
1461         if(nonInitErrorCheck(identifierLocation, identifier, publicType))
1462                 recover();
1463
1464         if(arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType))
1465         {
1466                 recover();
1467         }
1468
1469         TType arrayType(publicType);
1470
1471         int size;
1472         if(arraySizeErrorCheck(identifierLocation, indexExpression, size))
1473         {
1474                 recover();
1475         }
1476         // Make the type an array even if size check failed.
1477         // This ensures useless error messages regarding the variable's non-arrayness won't follow.
1478         arrayType.setArraySize(size);
1479
1480         TVariable *variable = nullptr;
1481         if(!declareVariable(identifierLocation, identifier, arrayType, &variable))
1482                 recover();
1483
1484         TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation);
1485         if(variable && symbol)
1486                 symbol->setId(variable->getUniqueId());
1487
1488         return intermediate.makeAggregate(symbol, identifierLocation);
1489 }
1490
1491 TIntermAggregate *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType,
1492         const TSourceLoc &identifierLocation,
1493         const TString &identifier,
1494         const TSourceLoc &initLocation,
1495         TIntermTyped *initializer)
1496 {
1497         mDeferredSingleDeclarationErrorCheck = false;
1498
1499         if(singleDeclarationErrorCheck(publicType, identifierLocation))
1500                 recover();
1501
1502         TIntermNode *intermNode = nullptr;
1503         if(!executeInitializer(identifierLocation, identifier, publicType, initializer, intermNode))
1504         {
1505                 //
1506                 // Build intermediate representation
1507                 //
1508                 return intermNode ? intermediate.makeAggregate(intermNode, initLocation) : nullptr;
1509         }
1510         else
1511         {
1512                 recover();
1513                 return nullptr;
1514         }
1515 }
1516
1517 TIntermAggregate *TParseContext::parseSingleArrayInitDeclaration(TPublicType &publicType,
1518         const TSourceLoc &identifierLocation,
1519         const TString &identifier,
1520         const TSourceLoc &indexLocation,
1521         TIntermTyped *indexExpression,
1522         const TSourceLoc &initLocation,
1523         TIntermTyped *initializer)
1524 {
1525         mDeferredSingleDeclarationErrorCheck = false;
1526
1527         if(singleDeclarationErrorCheck(publicType, identifierLocation))
1528                 recover();
1529
1530         if(arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType))
1531         {
1532                 recover();
1533         }
1534
1535         TPublicType arrayType(publicType);
1536
1537         int size = 0;
1538         // If indexExpression is nullptr, then the array will eventually get its size implicitly from the initializer.
1539         if(indexExpression != nullptr && arraySizeErrorCheck(identifierLocation, indexExpression, size))
1540         {
1541                 recover();
1542         }
1543         // Make the type an array even if size check failed.
1544         // This ensures useless error messages regarding the variable's non-arrayness won't follow.
1545         arrayType.setArray(true, size);
1546
1547         // initNode will correspond to the whole of "type b[n] = initializer".
1548         TIntermNode *initNode = nullptr;
1549         if(!executeInitializer(identifierLocation, identifier, arrayType, initializer, initNode))
1550         {
1551                 return initNode ? intermediate.makeAggregate(initNode, initLocation) : nullptr;
1552         }
1553         else
1554         {
1555                 recover();
1556                 return nullptr;
1557         }
1558 }
1559
1560 TIntermAggregate *TParseContext::parseInvariantDeclaration(const TSourceLoc &invariantLoc,
1561         const TSourceLoc &identifierLoc,
1562         const TString *identifier,
1563         const TSymbol *symbol)
1564 {
1565         // invariant declaration
1566         if(globalErrorCheck(invariantLoc, symbolTable.atGlobalLevel(), "invariant varying"))
1567         {
1568                 recover();
1569         }
1570
1571         if(!symbol)
1572         {
1573                 error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str());
1574                 recover();
1575                 return nullptr;
1576         }
1577         else
1578         {
1579                 const TString kGlFrontFacing("gl_FrontFacing");
1580                 if(*identifier == kGlFrontFacing)
1581                 {
1582                         error(identifierLoc, "identifier should not be declared as invariant", identifier->c_str());
1583                         recover();
1584                         return nullptr;
1585                 }
1586                 symbolTable.addInvariantVarying(std::string(identifier->c_str()));
1587                 const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
1588                 ASSERT(variable);
1589                 const TType &type = variable->getType();
1590                 TIntermSymbol *intermSymbol = intermediate.addSymbol(variable->getUniqueId(),
1591                         *identifier, type, identifierLoc);
1592
1593                 TIntermAggregate *aggregate = intermediate.makeAggregate(intermSymbol, identifierLoc);
1594                 aggregate->setOp(EOpInvariantDeclaration);
1595                 return aggregate;
1596         }
1597 }
1598
1599 TIntermAggregate *TParseContext::parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration,
1600         const TSourceLoc &identifierLocation, const TString &identifier)
1601 {
1602         // If the declaration starting this declarator list was empty (example: int,), some checks were not performed.
1603         if(mDeferredSingleDeclarationErrorCheck)
1604         {
1605                 if(singleDeclarationErrorCheck(publicType, identifierLocation))
1606                         recover();
1607                 mDeferredSingleDeclarationErrorCheck = false;
1608         }
1609
1610         if(locationDeclaratorListCheck(identifierLocation, publicType))
1611                 recover();
1612
1613         if(nonInitErrorCheck(identifierLocation, identifier, publicType))
1614                 recover();
1615
1616         TVariable *variable = nullptr;
1617         if(!declareVariable(identifierLocation, identifier, TType(publicType), &variable))
1618                 recover();
1619
1620         TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation);
1621         if(variable && symbol)
1622                 symbol->setId(variable->getUniqueId());
1623
1624         return intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation);
1625 }
1626
1627 TIntermAggregate *TParseContext::parseArrayDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration,
1628         const TSourceLoc &identifierLocation, const TString &identifier,
1629         const TSourceLoc &arrayLocation, TIntermTyped *indexExpression)
1630 {
1631         // If the declaration starting this declarator list was empty (example: int,), some checks were not performed.
1632         if(mDeferredSingleDeclarationErrorCheck)
1633         {
1634                 if(singleDeclarationErrorCheck(publicType, identifierLocation))
1635                         recover();
1636                 mDeferredSingleDeclarationErrorCheck = false;
1637         }
1638
1639         if(locationDeclaratorListCheck(identifierLocation, publicType))
1640                 recover();
1641
1642         if(nonInitErrorCheck(identifierLocation, identifier, publicType))
1643                 recover();
1644
1645         if(arrayTypeErrorCheck(arrayLocation, publicType) || arrayQualifierErrorCheck(arrayLocation, publicType))
1646         {
1647                 recover();
1648         }
1649         else
1650         {
1651                 TType arrayType = TType(publicType);
1652                 int size;
1653                 if(arraySizeErrorCheck(arrayLocation, indexExpression, size))
1654                 {
1655                         recover();
1656                 }
1657                 arrayType.setArraySize(size);
1658
1659                 TVariable *variable = nullptr;
1660                 if(!declareVariable(identifierLocation, identifier, arrayType, &variable))
1661                         recover();
1662
1663                 TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation);
1664                 if(variable && symbol)
1665                         symbol->setId(variable->getUniqueId());
1666
1667                 return intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation);
1668         }
1669
1670         return nullptr;
1671 }
1672
1673 TIntermAggregate *TParseContext::parseInitDeclarator(const TPublicType &publicType, TIntermAggregate *aggregateDeclaration,
1674         const TSourceLoc &identifierLocation, const TString &identifier,
1675         const TSourceLoc &initLocation, TIntermTyped *initializer)
1676 {
1677         // If the declaration starting this declarator list was empty (example: int,), some checks were not performed.
1678         if(mDeferredSingleDeclarationErrorCheck)
1679         {
1680                 if(singleDeclarationErrorCheck(publicType, identifierLocation))
1681                         recover();
1682                 mDeferredSingleDeclarationErrorCheck = false;
1683         }
1684
1685         if(locationDeclaratorListCheck(identifierLocation, publicType))
1686                 recover();
1687
1688         TIntermNode *intermNode = nullptr;
1689         if(!executeInitializer(identifierLocation, identifier, publicType, initializer, intermNode))
1690         {
1691                 //
1692                 // build the intermediate representation
1693                 //
1694                 if(intermNode)
1695                 {
1696                         return intermediate.growAggregate(aggregateDeclaration, intermNode, initLocation);
1697                 }
1698                 else
1699                 {
1700                         return aggregateDeclaration;
1701                 }
1702         }
1703         else
1704         {
1705                 recover();
1706                 return nullptr;
1707         }
1708 }
1709
1710 TIntermAggregate *TParseContext::parseArrayInitDeclarator(const TPublicType &publicType,
1711         TIntermAggregate *aggregateDeclaration,
1712         const TSourceLoc &identifierLocation,
1713         const TString &identifier,
1714         const TSourceLoc &indexLocation,
1715         TIntermTyped *indexExpression,
1716         const TSourceLoc &initLocation, TIntermTyped *initializer)
1717 {
1718         // If the declaration starting this declarator list was empty (example: int,), some checks were not performed.
1719         if(mDeferredSingleDeclarationErrorCheck)
1720         {
1721                 if(singleDeclarationErrorCheck(publicType, identifierLocation))
1722                         recover();
1723                 mDeferredSingleDeclarationErrorCheck = false;
1724         }
1725
1726         if(locationDeclaratorListCheck(identifierLocation, publicType))
1727                 recover();
1728
1729         if(arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType))
1730         {
1731                 recover();
1732         }
1733
1734         TPublicType arrayType(publicType);
1735
1736         int size = 0;
1737         // If indexExpression is nullptr, then the array will eventually get its size implicitly from the initializer.
1738         if(indexExpression != nullptr && arraySizeErrorCheck(identifierLocation, indexExpression, size))
1739         {
1740                 recover();
1741         }
1742         // Make the type an array even if size check failed.
1743         // This ensures useless error messages regarding the variable's non-arrayness won't follow.
1744         arrayType.setArray(true, size);
1745
1746         // initNode will correspond to the whole of "b[n] = initializer".
1747         TIntermNode *initNode = nullptr;
1748         if(!executeInitializer(identifierLocation, identifier, arrayType, initializer, initNode))
1749         {
1750                 if(initNode)
1751                 {
1752                         return intermediate.growAggregate(aggregateDeclaration, initNode, initLocation);
1753                 }
1754                 else
1755                 {
1756                         return aggregateDeclaration;
1757                 }
1758         }
1759         else
1760         {
1761                 recover();
1762                 return nullptr;
1763         }
1764 }
1765
1766 void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier)
1767 {
1768         if(shaderVersion < 300)
1769         {
1770                 error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 only", "layout");
1771                 recover();
1772                 return;
1773         }
1774
1775         if(typeQualifier.qualifier != EvqUniform)
1776         {
1777                 error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "global layout must be uniform");
1778                 recover();
1779                 return;
1780         }
1781
1782         const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier;
1783         ASSERT(!layoutQualifier.isEmpty());
1784
1785         if(layoutLocationErrorCheck(typeQualifier.line, typeQualifier.layoutQualifier))
1786         {
1787                 recover();
1788                 return;
1789         }
1790
1791         if(layoutQualifier.matrixPacking != EmpUnspecified)
1792         {
1793                 defaultMatrixPacking = layoutQualifier.matrixPacking;
1794         }
1795
1796         if(layoutQualifier.blockStorage != EbsUnspecified)
1797         {
1798                 defaultBlockStorage = layoutQualifier.blockStorage;
1799         }
1800 }
1801
1802 // This function is used to test for the correctness of the parameters passed to various constructor functions
1803 // and also convert them to the right datatype if it is allowed and required.
1804 //
1805 // Returns 0 for an error or the constructed node (aggregate or typed) for no error.
1806 //
1807 TIntermTyped* TParseContext::addConstructor(TIntermNode* arguments, const TType* type, TOperator op, TFunction* fnCall, const TSourceLoc &line)
1808 {
1809     TIntermAggregate *aggregateArguments = arguments->getAsAggregate();
1810
1811     if(!aggregateArguments)
1812     {
1813         aggregateArguments = new TIntermAggregate;
1814         aggregateArguments->getSequence().push_back(arguments);
1815     }
1816
1817     if(op == EOpConstructStruct)
1818     {
1819         const TFieldList &fields = type->getStruct()->fields();
1820         TIntermSequence &args = aggregateArguments->getSequence();
1821
1822         for(size_t i = 0; i < fields.size(); i++)
1823         {
1824             if(args[i]->getAsTyped()->getType() != *fields[i]->type())
1825             {
1826                 error(line, "Structure constructor arguments do not match structure fields", "Error");
1827                 recover();
1828
1829                 return 0;
1830             }
1831         }
1832     }
1833
1834     // Turn the argument list itself into a constructor
1835     TIntermTyped *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
1836     TIntermTyped *constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type);
1837     if(constConstructor)
1838     {
1839         return constConstructor;
1840     }
1841
1842     return constructor;
1843 }
1844
1845 TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, const TType& type)
1846 {
1847     bool canBeFolded = areAllChildConst(aggrNode);
1848     aggrNode->setType(type);
1849     if (canBeFolded) {
1850         bool returnVal = false;
1851         ConstantUnion* unionArray = new ConstantUnion[type.getObjectSize()];
1852         if (aggrNode->getSequence().size() == 1)  {
1853             returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type, true);
1854         }
1855         else {
1856             returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type);
1857         }
1858         if (returnVal)
1859             return 0;
1860
1861         return intermediate.addConstantUnion(unionArray, type, aggrNode->getLine());
1862     }
1863
1864     return 0;
1865 }
1866
1867 //
1868 // This function returns the tree representation for the vector field(s) being accessed from contant vector.
1869 // If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a contant node is
1870 // returned, else an aggregate node is returned (for v.xy). The input to this function could either be the symbol
1871 // node or it could be the intermediate tree representation of accessing fields in a constant structure or column of 
1872 // a constant matrix.
1873 //
1874 TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, const TSourceLoc &line)
1875 {
1876     TIntermTyped* typedNode;
1877     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
1878
1879     ConstantUnion *unionArray;
1880     if (tempConstantNode) {
1881         unionArray = tempConstantNode->getUnionArrayPointer();
1882
1883         if (!unionArray) {
1884             return node;
1885         }
1886     } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
1887         error(line, "Cannot offset into the vector", "Error");
1888         recover();
1889
1890         return 0;
1891     }
1892
1893     ConstantUnion* constArray = new ConstantUnion[fields.num];
1894
1895     for (int i = 0; i < fields.num; i++) {
1896         if (fields.offsets[i] >= node->getType().getObjectSize()) {
1897             std::stringstream extraInfoStream;
1898             extraInfoStream << "vector field selection out of range '" << fields.offsets[i] << "'";
1899             std::string extraInfo = extraInfoStream.str();
1900             error(line, "", "[", extraInfo.c_str());
1901             recover();
1902             fields.offsets[i] = 0;
1903         }
1904
1905         constArray[i] = unionArray[fields.offsets[i]];
1906
1907     }
1908     typedNode = intermediate.addConstantUnion(constArray, node->getType(), line);
1909     return typedNode;
1910 }
1911
1912 //
1913 // This function returns the column being accessed from a constant matrix. The values are retrieved from
1914 // the symbol table and parse-tree is built for a vector (each column of a matrix is a vector). The input
1915 // to the function could either be a symbol node (m[0] where m is a constant matrix)that represents a
1916 // constant matrix or it could be the tree representation of the constant matrix (s.m1[0] where s is a constant structure)
1917 //
1918 TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, const TSourceLoc &line)
1919 {
1920     TIntermTyped* typedNode;
1921     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
1922
1923     if (index >= node->getType().getNominalSize()) {
1924         std::stringstream extraInfoStream;
1925         extraInfoStream << "matrix field selection out of range '" << index << "'";
1926         std::string extraInfo = extraInfoStream.str();
1927         error(line, "", "[", extraInfo.c_str());
1928         recover();
1929         index = 0;
1930     }
1931
1932     if (tempConstantNode) {
1933          ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
1934          int size = tempConstantNode->getType().getNominalSize();
1935          typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line);
1936     } else {
1937         error(line, "Cannot offset into the matrix", "Error");
1938         recover();
1939
1940         return 0;
1941     }
1942
1943     return typedNode;
1944 }
1945
1946
1947 //
1948 // This function returns an element of an array accessed from a constant array. The values are retrieved from
1949 // the symbol table and parse-tree is built for the type of the element. The input
1950 // to the function could either be a symbol node (a[0] where a is a constant array)that represents a
1951 // constant array or it could be the tree representation of the constant array (s.a1[0] where s is a constant structure)
1952 //
1953 TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc &line)
1954 {
1955     TIntermTyped* typedNode;
1956     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
1957     TType arrayElementType = node->getType();
1958     arrayElementType.clearArrayness();
1959
1960     if (index >= node->getType().getArraySize()) {
1961         std::stringstream extraInfoStream;
1962         extraInfoStream << "array field selection out of range '" << index << "'";
1963         std::string extraInfo = extraInfoStream.str();
1964         error(line, "", "[", extraInfo.c_str());
1965         recover();
1966         index = 0;
1967     }
1968
1969     int arrayElementSize = arrayElementType.getObjectSize();
1970
1971     if (tempConstantNode) {
1972          ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
1973          typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line);
1974     } else {
1975         error(line, "Cannot offset into the array", "Error");
1976         recover();
1977
1978         return 0;
1979     }
1980
1981     return typedNode;
1982 }
1983
1984
1985 //
1986 // This function returns the value of a particular field inside a constant structure from the symbol table.
1987 // If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr
1988 // function and returns the parse-tree with the values of the embedded/nested struct.
1989 //
1990 TIntermTyped* TParseContext::addConstStruct(const TString& identifier, TIntermTyped* node, const TSourceLoc &line)
1991 {
1992     const TFieldList &fields = node->getType().getStruct()->fields();
1993     TIntermTyped *typedNode;
1994     int instanceSize = 0;
1995     unsigned int index = 0;
1996     TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
1997
1998     for ( index = 0; index < fields.size(); ++index) {
1999         if (fields[index]->name() == identifier) {
2000             break;
2001         } else {
2002             instanceSize += fields[index]->type()->getObjectSize();
2003         }
2004     }
2005
2006     if (tempConstantNode) {
2007          ConstantUnion* constArray = tempConstantNode->getUnionArrayPointer();
2008
2009          typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function
2010     } else {
2011         error(line, "Cannot offset into the structure", "Error");
2012         recover();
2013
2014         return 0;
2015     }
2016
2017     return typedNode;
2018 }
2019
2020 //
2021 // Interface/uniform blocks
2022 //
2023 TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TFieldList* fieldList,
2024                                                    const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine)
2025 {
2026         if(reservedErrorCheck(nameLine, blockName))
2027                 recover();
2028
2029         if(typeQualifier.qualifier != EvqUniform)
2030         {
2031                 error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "interface blocks must be uniform");
2032                 recover();
2033         }
2034
2035         TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier;
2036         if(layoutLocationErrorCheck(typeQualifier.line, blockLayoutQualifier))
2037         {
2038                 recover();
2039         }
2040
2041         if(blockLayoutQualifier.matrixPacking == EmpUnspecified)
2042         {
2043                 blockLayoutQualifier.matrixPacking = defaultMatrixPacking;
2044         }
2045
2046         if(blockLayoutQualifier.blockStorage == EbsUnspecified)
2047         {
2048                 blockLayoutQualifier.blockStorage = defaultBlockStorage;
2049         }
2050
2051         TSymbol* blockNameSymbol = new TSymbol(&blockName);
2052         if(!symbolTable.declare(*blockNameSymbol)) {
2053                 error(nameLine, "redefinition", blockName.c_str(), "interface block name");
2054                 recover();
2055         }
2056
2057         // check for sampler types and apply layout qualifiers
2058         for(size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex) {
2059                 TField* field = (*fieldList)[memberIndex];
2060                 TType* fieldType = field->type();
2061                 if(IsSampler(fieldType->getBasicType())) {
2062                         error(field->line(), "unsupported type", fieldType->getBasicString(), "sampler types are not allowed in interface blocks");
2063                         recover();
2064                 }
2065
2066                 const TQualifier qualifier = fieldType->getQualifier();
2067                 switch(qualifier)
2068                 {
2069                 case EvqGlobal:
2070                 case EvqUniform:
2071                         break;
2072                 default:
2073                         error(field->line(), "invalid qualifier on interface block member", getQualifierString(qualifier));
2074                         recover();
2075                         break;
2076                 }
2077
2078                 // check layout qualifiers
2079                 TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier();
2080                 if(layoutLocationErrorCheck(field->line(), fieldLayoutQualifier))
2081                 {
2082                         recover();
2083                 }
2084
2085                 if(fieldLayoutQualifier.blockStorage != EbsUnspecified)
2086                 {
2087                         error(field->line(), "invalid layout qualifier:", getBlockStorageString(fieldLayoutQualifier.blockStorage), "cannot be used here");
2088                         recover();
2089                 }
2090
2091                 if(fieldLayoutQualifier.matrixPacking == EmpUnspecified)
2092                 {
2093                         fieldLayoutQualifier.matrixPacking = blockLayoutQualifier.matrixPacking;
2094                 }
2095                 else if(!fieldType->isMatrix())
2096                 {
2097                         error(field->line(), "invalid layout qualifier:", getMatrixPackingString(fieldLayoutQualifier.matrixPacking), "can only be used on matrix types");
2098                         recover();
2099                 }
2100
2101                 fieldType->setLayoutQualifier(fieldLayoutQualifier);
2102         }
2103
2104         // add array index
2105         int arraySize = 0;
2106         if(arrayIndex != NULL)
2107         {
2108                 if(arraySizeErrorCheck(arrayIndexLine, arrayIndex, arraySize))
2109                         recover();
2110         }
2111
2112         TInterfaceBlock* interfaceBlock = new TInterfaceBlock(&blockName, fieldList, instanceName, arraySize, blockLayoutQualifier);
2113         TType interfaceBlockType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier, arraySize);
2114
2115         TString symbolName = "";
2116         int symbolId = 0;
2117
2118         if(!instanceName)
2119         {
2120                 // define symbols for the members of the interface block
2121                 for(size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
2122                 {
2123                         TField* field = (*fieldList)[memberIndex];
2124                         TType* fieldType = field->type();
2125
2126                         // set parent pointer of the field variable
2127                         fieldType->setInterfaceBlock(interfaceBlock);
2128
2129                         TVariable* fieldVariable = new TVariable(&field->name(), *fieldType);
2130                         fieldVariable->setQualifier(typeQualifier.qualifier);
2131
2132                         if(!symbolTable.declare(*fieldVariable)) {
2133                                 error(field->line(), "redefinition", field->name().c_str(), "interface block member name");
2134                                 recover();
2135                         }
2136                 }
2137         }
2138         else
2139         {
2140                 // add a symbol for this interface block
2141                 TVariable* instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false);
2142                 instanceTypeDef->setQualifier(typeQualifier.qualifier);
2143
2144                 if(!symbolTable.declare(*instanceTypeDef)) {
2145                         error(instanceLine, "redefinition", instanceName->c_str(), "interface block instance name");
2146                         recover();
2147                 }
2148
2149                 symbolId = instanceTypeDef->getUniqueId();
2150                 symbolName = instanceTypeDef->getName();
2151         }
2152
2153         TIntermAggregate *aggregate = intermediate.makeAggregate(intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line), nameLine);
2154         aggregate->setOp(EOpDeclaration);
2155
2156         exitStructDeclaration();
2157         return aggregate;
2158 }
2159
2160 //
2161 // Parse an array index expression
2162 //
2163 TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc &location, TIntermTyped *indexExpression)
2164 {
2165         TIntermTyped *indexedExpression = NULL;
2166
2167         if(!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector())
2168         {
2169                 if(baseExpression->getAsSymbolNode())
2170                 {
2171                         error(location, " left of '[' is not of type array, matrix, or vector ",
2172                                 baseExpression->getAsSymbolNode()->getSymbol().c_str());
2173                 }
2174                 else
2175                 {
2176                         error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
2177                 }
2178                 recover();
2179         }
2180
2181         TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion();
2182
2183         if(indexExpression->getQualifier() == EvqConstExpr && indexConstantUnion)
2184         {
2185                 int index = indexConstantUnion->getIConst(0);
2186                 if(index < 0)
2187                 {
2188                         std::stringstream infoStream;
2189                         infoStream << index;
2190                         std::string info = infoStream.str();
2191                         error(location, "negative index", info.c_str());
2192                         recover();
2193                         index = 0;
2194                 }
2195                 if(baseExpression->getType().getQualifier() == EvqConstExpr)
2196                 {
2197                         if(baseExpression->isArray())
2198                         {
2199                                 // constant folding for arrays
2200                                 indexedExpression = addConstArrayNode(index, baseExpression, location);
2201                         }
2202                         else if(baseExpression->isVector())
2203                         {
2204                                 // constant folding for vectors
2205                                 TVectorFields fields;
2206                                 fields.num = 1;
2207                                 fields.offsets[0] = index; // need to do it this way because v.xy sends fields integer array
2208                                 indexedExpression = addConstVectorNode(fields, baseExpression, location);
2209                         }
2210                         else if(baseExpression->isMatrix())
2211                         {
2212                                 // constant folding for matrices
2213                                 indexedExpression = addConstMatrixNode(index, baseExpression, location);
2214                         }
2215                 }
2216                 else
2217                 {
2218                         int safeIndex = -1;
2219
2220                         if(baseExpression->isArray())
2221                         {
2222                                 if(index >= baseExpression->getType().getArraySize())
2223                                 {
2224                                         std::stringstream extraInfoStream;
2225                                         extraInfoStream << "array index out of range '" << index << "'";
2226                                         std::string extraInfo = extraInfoStream.str();
2227                                         error(location, "", "[", extraInfo.c_str());
2228                                         recover();
2229                                         safeIndex = baseExpression->getType().getArraySize() - 1;
2230                                 }
2231                         }
2232                         else if((baseExpression->isVector() || baseExpression->isMatrix()) &&
2233                                 baseExpression->getType().getNominalSize() <= index)
2234                         {
2235                                 std::stringstream extraInfoStream;
2236                                 extraInfoStream << "field selection out of range '" << index << "'";
2237                                 std::string extraInfo = extraInfoStream.str();
2238                                 error(location, "", "[", extraInfo.c_str());
2239                                 recover();
2240                                 safeIndex = baseExpression->getType().getNominalSize() - 1;
2241                         }
2242
2243                         // Don't modify the data of the previous constant union, because it can point
2244                         // to builtins, like gl_MaxDrawBuffers. Instead use a new sanitized object.
2245                         if(safeIndex != -1)
2246                         {
2247                                 ConstantUnion *safeConstantUnion = new ConstantUnion();
2248                                 safeConstantUnion->setIConst(safeIndex);
2249                                 indexConstantUnion->replaceConstantUnion(safeConstantUnion);
2250                         }
2251
2252                         indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location);
2253                 }
2254         }
2255         else
2256         {
2257                 if(baseExpression->isInterfaceBlock())
2258                 {
2259                         error(location, "",
2260                                 "[", "array indexes for interface blocks arrays must be constant integral expressions");
2261                         recover();
2262                 }
2263                 else if(baseExpression->getQualifier() == EvqFragmentOut)
2264                 {
2265                         error(location, "", "[", "array indexes for fragment outputs must be constant integral expressions");
2266                         recover();
2267                 }
2268
2269                 indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location);
2270         }
2271
2272         if(indexedExpression == 0)
2273         {
2274                 ConstantUnion *unionArray = new ConstantUnion[1];
2275                 unionArray->setFConst(0.0f);
2276                 indexedExpression = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConstExpr), location);
2277         }
2278         else if(baseExpression->isArray())
2279         {
2280                 const TType &baseType = baseExpression->getType();
2281                 if(baseType.getStruct())
2282                 {
2283                         TType copyOfType(baseType.getStruct());
2284                         indexedExpression->setType(copyOfType);
2285                 }
2286                 else if(baseType.isInterfaceBlock())
2287                 {
2288                         TType copyOfType(baseType.getInterfaceBlock(), baseType.getQualifier(), baseType.getLayoutQualifier(), 0);
2289                         indexedExpression->setType(copyOfType);
2290                 }
2291                 else
2292                 {
2293                         indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),
2294                                 EvqTemporary, static_cast<unsigned char>(baseExpression->getNominalSize()),
2295                                 static_cast<unsigned char>(baseExpression->getSecondarySize())));
2296                 }
2297
2298                 if(baseExpression->getType().getQualifier() == EvqConstExpr)
2299                 {
2300                         indexedExpression->getTypePointer()->setQualifier(EvqConstExpr);
2301                 }
2302         }
2303         else if(baseExpression->isMatrix())
2304         {
2305                 TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConstExpr ? EvqConstExpr : EvqTemporary;
2306                 indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),
2307                         qualifier, static_cast<unsigned char>(baseExpression->getSecondarySize())));
2308         }
2309         else if(baseExpression->isVector())
2310         {
2311                 TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConstExpr ? EvqConstExpr : EvqTemporary;
2312                 indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier));
2313         }
2314         else
2315         {
2316                 indexedExpression->setType(baseExpression->getType());
2317         }
2318
2319         return indexedExpression;
2320 }
2321
2322 TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc &dotLocation,
2323         const TString &fieldString, const TSourceLoc &fieldLocation)
2324 {
2325         TIntermTyped *indexedExpression = NULL;
2326
2327         if(baseExpression->isArray())
2328         {
2329                 error(fieldLocation, "cannot apply dot operator to an array", ".");
2330                 recover();
2331         }
2332
2333         if(baseExpression->isVector())
2334         {
2335                 TVectorFields fields;
2336                 if(!parseVectorFields(fieldString, baseExpression->getNominalSize(), fields, fieldLocation))
2337                 {
2338                         fields.num = 1;
2339                         fields.offsets[0] = 0;
2340                         recover();
2341                 }
2342
2343                 if(baseExpression->getType().getQualifier() == EvqConstExpr)
2344                 {
2345                         // constant folding for vector fields
2346                         indexedExpression = addConstVectorNode(fields, baseExpression, fieldLocation);
2347                         if(indexedExpression == 0)
2348                         {
2349                                 recover();
2350                                 indexedExpression = baseExpression;
2351                         }
2352                         else
2353                         {
2354                                 indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),
2355                                         EvqConstExpr, (unsigned char)(fieldString).size()));
2356                         }
2357                 }
2358                 else
2359                 {
2360                         TString vectorString = fieldString;
2361                         TIntermTyped *index = intermediate.addSwizzle(fields, fieldLocation);
2362                         indexedExpression = intermediate.addIndex(EOpVectorSwizzle, baseExpression, index, dotLocation);
2363                         indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),
2364                                 EvqTemporary, (unsigned char)vectorString.size()));
2365                 }
2366         }
2367         else if(baseExpression->isMatrix())
2368         {
2369                 TMatrixFields fields;
2370                 if(!parseMatrixFields(fieldString, baseExpression->getNominalSize(), baseExpression->getSecondarySize(), fields, fieldLocation))
2371                 {
2372                         fields.wholeRow = false;
2373                         fields.wholeCol = false;
2374                         fields.row = 0;
2375                         fields.col = 0;
2376                         recover();
2377                 }
2378
2379                 if(fields.wholeRow || fields.wholeCol)
2380                 {
2381                         error(dotLocation, " non-scalar fields not implemented yet", ".");
2382                         recover();
2383                         ConstantUnion *unionArray = new ConstantUnion[1];
2384                         unionArray->setIConst(0);
2385                         TIntermTyped *index = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConstExpr),
2386                                 fieldLocation);
2387                         indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, index, dotLocation);
2388                         indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),
2389                                 EvqTemporary, static_cast<unsigned char>(baseExpression->getNominalSize()),
2390                                 static_cast<unsigned char>(baseExpression->getSecondarySize())));
2391                 }
2392                 else
2393                 {
2394                         ConstantUnion *unionArray = new ConstantUnion[1];
2395                         unionArray->setIConst(fields.col * baseExpression->getSecondarySize() + fields.row);
2396                         TIntermTyped *index = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConstExpr),
2397                                 fieldLocation);
2398                         indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, index, dotLocation);
2399                         indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision()));
2400                 }
2401         }
2402         else if(baseExpression->getBasicType() == EbtStruct)
2403         {
2404                 bool fieldFound = false;
2405                 const TFieldList &fields = baseExpression->getType().getStruct()->fields();
2406                 if(fields.empty())
2407                 {
2408                         error(dotLocation, "structure has no fields", "Internal Error");
2409                         recover();
2410                         indexedExpression = baseExpression;
2411                 }
2412                 else
2413                 {
2414                         unsigned int i;
2415                         for(i = 0; i < fields.size(); ++i)
2416                         {
2417                                 if(fields[i]->name() == fieldString)
2418                                 {
2419                                         fieldFound = true;
2420                                         break;
2421                                 }
2422                         }
2423                         if(fieldFound)
2424                         {
2425                                 if(baseExpression->getType().getQualifier() == EvqConstExpr)
2426                                 {
2427                                         indexedExpression = addConstStruct(fieldString, baseExpression, dotLocation);
2428                                         if(indexedExpression == 0)
2429                                         {
2430                                                 recover();
2431                                                 indexedExpression = baseExpression;
2432                                         }
2433                                         else
2434                                         {
2435                                                 indexedExpression->setType(*fields[i]->type());
2436                                                 // change the qualifier of the return type, not of the structure field
2437                                                 // as the structure definition is shared between various structures.
2438                                                 indexedExpression->getTypePointer()->setQualifier(EvqConstExpr);
2439                                         }
2440                                 }
2441                                 else
2442                                 {
2443                                         ConstantUnion *unionArray = new ConstantUnion[1];
2444                                         unionArray->setIConst(i);
2445                                         TIntermTyped *index = intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation);
2446                                         indexedExpression = intermediate.addIndex(EOpIndexDirectStruct, baseExpression, index, dotLocation);
2447                                         indexedExpression->setType(*fields[i]->type());
2448                                 }
2449                         }
2450                         else
2451                         {
2452                                 error(dotLocation, " no such field in structure", fieldString.c_str());
2453                                 recover();
2454                                 indexedExpression = baseExpression;
2455                         }
2456                 }
2457         }
2458         else if(baseExpression->isInterfaceBlock())
2459         {
2460                 bool fieldFound = false;
2461                 const TFieldList &fields = baseExpression->getType().getInterfaceBlock()->fields();
2462                 if(fields.empty())
2463                 {
2464                         error(dotLocation, "interface block has no fields", "Internal Error");
2465                         recover();
2466                         indexedExpression = baseExpression;
2467                 }
2468                 else
2469                 {
2470                         unsigned int i;
2471                         for(i = 0; i < fields.size(); ++i)
2472                         {
2473                                 if(fields[i]->name() == fieldString)
2474                                 {
2475                                         fieldFound = true;
2476                                         break;
2477                                 }
2478                         }
2479                         if(fieldFound)
2480                         {
2481                                 ConstantUnion *unionArray = new ConstantUnion[1];
2482                                 unionArray->setIConst(i);
2483                                 TIntermTyped *index = intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation);
2484                                 indexedExpression = intermediate.addIndex(EOpIndexDirectInterfaceBlock, baseExpression, index,
2485                                         dotLocation);
2486                                 indexedExpression->setType(*fields[i]->type());
2487                         }
2488                         else
2489                         {
2490                                 error(dotLocation, " no such field in interface block", fieldString.c_str());
2491                                 recover();
2492                                 indexedExpression = baseExpression;
2493                         }
2494                 }
2495         }
2496         else
2497         {
2498                 if(shaderVersion < 300)
2499                 {
2500                         error(dotLocation, " field selection requires structure, vector, or matrix on left hand side",
2501                                 fieldString.c_str());
2502                 }
2503                 else
2504                 {
2505                         error(dotLocation,
2506                                 " field selection requires structure, vector, matrix, or interface block on left hand side",
2507                                 fieldString.c_str());
2508                 }
2509                 recover();
2510                 indexedExpression = baseExpression;
2511         }
2512
2513         return indexedExpression;
2514 }
2515
2516 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine)
2517 {
2518     TLayoutQualifier qualifier;
2519
2520     qualifier.location = -1;
2521         qualifier.matrixPacking = EmpUnspecified;
2522         qualifier.blockStorage = EbsUnspecified;
2523
2524         if(qualifierType == "shared")
2525         {
2526                 qualifier.blockStorage = EbsShared;
2527         }
2528         else if(qualifierType == "packed")
2529         {
2530                 qualifier.blockStorage = EbsPacked;
2531         }
2532         else if(qualifierType == "std140")
2533         {
2534                 qualifier.blockStorage = EbsStd140;
2535         }
2536         else if(qualifierType == "row_major")
2537         {
2538                 qualifier.matrixPacking = EmpRowMajor;
2539         }
2540         else if(qualifierType == "column_major")
2541         {
2542                 qualifier.matrixPacking = EmpColumnMajor;
2543         }
2544         else if(qualifierType == "location")
2545     {
2546         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "location requires an argument");
2547         recover();
2548     }
2549     else
2550     {
2551         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
2552         recover();
2553     }
2554
2555     return qualifier;
2556 }
2557
2558 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine)
2559 {
2560     TLayoutQualifier qualifier;
2561
2562     qualifier.location = -1;
2563     qualifier.matrixPacking = EmpUnspecified;
2564     qualifier.blockStorage = EbsUnspecified;
2565
2566     if (qualifierType != "location")
2567     {
2568         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "only location may have arguments");
2569         recover();
2570     }
2571     else
2572     {
2573         // must check that location is non-negative
2574         if (intValue < 0)
2575         {
2576             error(intValueLine, "out of range:", intValueString.c_str(), "location must be non-negative");
2577             recover();
2578         }
2579         else
2580         {
2581             qualifier.location = intValue;
2582         }
2583     }
2584
2585     return qualifier;
2586 }
2587
2588 TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier)
2589 {
2590     TLayoutQualifier joinedQualifier = leftQualifier;
2591
2592     if (rightQualifier.location != -1)
2593     {
2594         joinedQualifier.location = rightQualifier.location;
2595     }
2596         if(rightQualifier.matrixPacking != EmpUnspecified)
2597         {
2598                 joinedQualifier.matrixPacking = rightQualifier.matrixPacking;
2599         }
2600         if(rightQualifier.blockStorage != EbsUnspecified)
2601         {
2602                 joinedQualifier.blockStorage = rightQualifier.blockStorage;
2603         }
2604
2605     return joinedQualifier;
2606 }
2607
2608
2609 TPublicType TParseContext::joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier,
2610         const TSourceLoc &storageLoc, TQualifier storageQualifier)
2611 {
2612         TQualifier mergedQualifier = EvqSmoothIn;
2613
2614         if(storageQualifier == EvqFragmentIn) {
2615                 if(interpolationQualifier == EvqSmooth)
2616                         mergedQualifier = EvqSmoothIn;
2617                 else if(interpolationQualifier == EvqFlat)
2618                         mergedQualifier = EvqFlatIn;
2619                 else UNREACHABLE();
2620         }
2621         else if(storageQualifier == EvqCentroidIn) {
2622                 if(interpolationQualifier == EvqSmooth)
2623                         mergedQualifier = EvqCentroidIn;
2624                 else if(interpolationQualifier == EvqFlat)
2625                         mergedQualifier = EvqFlatIn;
2626                 else UNREACHABLE();
2627         }
2628         else if(storageQualifier == EvqVertexOut) {
2629                 if(interpolationQualifier == EvqSmooth)
2630                         mergedQualifier = EvqSmoothOut;
2631                 else if(interpolationQualifier == EvqFlat)
2632                         mergedQualifier = EvqFlatOut;
2633                 else UNREACHABLE();
2634         }
2635         else if(storageQualifier == EvqCentroidOut) {
2636                 if(interpolationQualifier == EvqSmooth)
2637                         mergedQualifier = EvqCentroidOut;
2638                 else if(interpolationQualifier == EvqFlat)
2639                         mergedQualifier = EvqFlatOut;
2640                 else UNREACHABLE();
2641         }
2642         else {
2643                 error(interpolationLoc, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getQualifierString(interpolationQualifier));
2644                 recover();
2645
2646                 mergedQualifier = storageQualifier;
2647         }
2648
2649         TPublicType type;
2650         type.setBasic(EbtVoid, mergedQualifier, storageLoc);
2651         return type;
2652 }
2653
2654 TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList)
2655 {
2656         if(voidErrorCheck(typeSpecifier.line, (*fieldList)[0]->name(), typeSpecifier.type))
2657         {
2658                 recover();
2659         }
2660
2661         for(unsigned int i = 0; i < fieldList->size(); ++i)
2662         {
2663                 //
2664                 // Careful not to replace already known aspects of type, like array-ness
2665                 //
2666                 TType *type = (*fieldList)[i]->type();
2667                 type->setBasicType(typeSpecifier.type);
2668                 type->setNominalSize(typeSpecifier.primarySize);
2669                 type->setSecondarySize(typeSpecifier.secondarySize);
2670                 type->setPrecision(typeSpecifier.precision);
2671                 type->setQualifier(typeSpecifier.qualifier);
2672                 type->setLayoutQualifier(typeSpecifier.layoutQualifier);
2673
2674                 // don't allow arrays of arrays
2675                 if(type->isArray())
2676                 {
2677                         if(arrayTypeErrorCheck(typeSpecifier.line, typeSpecifier))
2678                                 recover();
2679                 }
2680                 if(typeSpecifier.array)
2681                         type->setArraySize(typeSpecifier.arraySize);
2682                 if(typeSpecifier.userDef)
2683                 {
2684                         type->setStruct(typeSpecifier.userDef->getStruct());
2685                 }
2686
2687                 if(structNestingErrorCheck(typeSpecifier.line, *(*fieldList)[i]))
2688                 {
2689                         recover();
2690                 }
2691         }
2692
2693         return fieldList;
2694 }
2695
2696 TPublicType TParseContext::addStructure(const TSourceLoc &structLine, const TSourceLoc &nameLine,
2697         const TString *structName, TFieldList *fieldList)
2698 {
2699         TStructure *structure = new TStructure(structName, fieldList);
2700         TType *structureType = new TType(structure);
2701
2702         // Store a bool in the struct if we're at global scope, to allow us to
2703         // skip the local struct scoping workaround in HLSL.
2704         structure->setUniqueId(TSymbolTableLevel::nextUniqueId());
2705         structure->setAtGlobalScope(symbolTable.atGlobalLevel());
2706
2707         if(!structName->empty())
2708         {
2709                 if(reservedErrorCheck(nameLine, *structName))
2710                 {
2711                         recover();
2712                 }
2713                 TVariable *userTypeDef = new TVariable(structName, *structureType, true);
2714                 if(!symbolTable.declare(*userTypeDef))
2715                 {
2716                         error(nameLine, "redefinition", structName->c_str(), "struct");
2717                         recover();
2718                 }
2719         }
2720
2721         // ensure we do not specify any storage qualifiers on the struct members
2722         for(unsigned int typeListIndex = 0; typeListIndex < fieldList->size(); typeListIndex++)
2723         {
2724                 const TField &field = *(*fieldList)[typeListIndex];
2725                 const TQualifier qualifier = field.type()->getQualifier();
2726                 switch(qualifier)
2727                 {
2728                 case EvqGlobal:
2729                 case EvqTemporary:
2730                         break;
2731                 default:
2732                         error(field.line(), "invalid qualifier on struct member", getQualifierString(qualifier));
2733                         recover();
2734                         break;
2735                 }
2736         }
2737
2738         TPublicType publicType;
2739         publicType.setBasic(EbtStruct, EvqTemporary, structLine);
2740         publicType.userDef = structureType;
2741         exitStructDeclaration();
2742
2743         return publicType;
2744 }
2745
2746 bool TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString& identifier)
2747 {
2748     ++structNestingLevel;
2749
2750     // Embedded structure definitions are not supported per GLSL ES spec.
2751     // They aren't allowed in GLSL either, but we need to detect this here
2752     // so we don't rely on the GLSL compiler to catch it.
2753     if (structNestingLevel > 1) {
2754         error(line, "", "Embedded struct definitions are not allowed");
2755         return true;
2756     }
2757
2758     return false;
2759 }
2760
2761 void TParseContext::exitStructDeclaration()
2762 {
2763     --structNestingLevel;
2764 }
2765
2766 bool TParseContext::structNestingErrorCheck(const TSourceLoc &line, const TField &field)
2767 {
2768         static const int kWebGLMaxStructNesting = 4;
2769
2770         if(field.type()->getBasicType() != EbtStruct)
2771         {
2772                 return false;
2773         }
2774
2775         // We're already inside a structure definition at this point, so add
2776         // one to the field's struct nesting.
2777         if(1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting)
2778         {
2779                 std::stringstream reasonStream;
2780                 reasonStream << "Reference of struct type "
2781                         << field.type()->getStruct()->name().c_str()
2782                         << " exceeds maximum allowed nesting level of "
2783                         << kWebGLMaxStructNesting;
2784                 std::string reason = reasonStream.str();
2785                 error(line, reason.c_str(), field.name().c_str(), "");
2786                 return true;
2787         }
2788
2789         return false;
2790 }
2791
2792 TIntermTyped *TParseContext::createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc, const TType *funcReturnType)
2793 {
2794         if(child == nullptr)
2795         {
2796                 return nullptr;
2797         }
2798
2799         switch(op)
2800         {
2801         case EOpLogicalNot:
2802                 if(child->getBasicType() != EbtBool ||
2803                         child->isMatrix() ||
2804                         child->isArray() ||
2805                         child->isVector())
2806                 {
2807                         return nullptr;
2808                 }
2809                 break;
2810         case EOpBitwiseNot:
2811                 if((child->getBasicType() != EbtInt && child->getBasicType() != EbtUInt) ||
2812                         child->isMatrix() ||
2813                         child->isArray())
2814                 {
2815                         return nullptr;
2816                 }
2817                 break;
2818         case EOpPostIncrement:
2819         case EOpPreIncrement:
2820         case EOpPostDecrement:
2821         case EOpPreDecrement:
2822         case EOpNegative:
2823                 if(child->getBasicType() == EbtStruct ||
2824                         child->getBasicType() == EbtBool ||
2825                         child->isArray())
2826                 {
2827                         return nullptr;
2828                 }
2829                 // Operators for built-ins are already type checked against their prototype.
2830         default:
2831                 break;
2832         }
2833
2834         return intermediate.addUnaryMath(op, child, loc); // FIXME , funcReturnType);
2835 }
2836
2837 TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
2838 {
2839         TIntermTyped *node = createUnaryMath(op, child, loc, nullptr);
2840         if(node == nullptr)
2841         {
2842                 unaryOpError(loc, getOperatorString(op), child->getCompleteString());
2843                 recover();
2844                 return child;
2845         }
2846         return node;
2847 }
2848
2849 TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
2850 {
2851         if(lValueErrorCheck(loc, getOperatorString(op), child))
2852                 recover();
2853         return addUnaryMath(op, child, loc);
2854 }
2855
2856 bool TParseContext::binaryOpCommonCheck(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc)
2857 {
2858         if(left->isArray() || right->isArray())
2859         {
2860                 if(shaderVersion < 300)
2861                 {
2862                         error(loc, "Invalid operation for arrays", getOperatorString(op));
2863                         return false;
2864                 }
2865
2866                 if(left->isArray() != right->isArray())
2867                 {
2868                         error(loc, "array / non-array mismatch", getOperatorString(op));
2869                         return false;
2870                 }
2871
2872                 switch(op)
2873                 {
2874                 case EOpEqual:
2875                 case EOpNotEqual:
2876                 case EOpAssign:
2877                 case EOpInitialize:
2878                         break;
2879                 default:
2880                         error(loc, "Invalid operation for arrays", getOperatorString(op));
2881                         return false;
2882                 }
2883                 // At this point, size of implicitly sized arrays should be resolved.
2884                 if(left->getArraySize() != right->getArraySize())
2885                 {
2886                         error(loc, "array size mismatch", getOperatorString(op));
2887                         return false;
2888                 }
2889         }
2890
2891         // Check ops which require integer / ivec parameters
2892         bool isBitShift = false;
2893         switch(op)
2894         {
2895         case EOpBitShiftLeft:
2896         case EOpBitShiftRight:
2897         case EOpBitShiftLeftAssign:
2898         case EOpBitShiftRightAssign:
2899                 // Unsigned can be bit-shifted by signed and vice versa, but we need to
2900                 // check that the basic type is an integer type.
2901                 isBitShift = true;
2902                 if(!IsInteger(left->getBasicType()) || !IsInteger(right->getBasicType()))
2903                 {
2904                         return false;
2905                 }
2906                 break;
2907         case EOpBitwiseAnd:
2908         case EOpBitwiseXor:
2909         case EOpBitwiseOr:
2910         case EOpBitwiseAndAssign:
2911         case EOpBitwiseXorAssign:
2912         case EOpBitwiseOrAssign:
2913                 // It is enough to check the type of only one operand, since later it
2914                 // is checked that the operand types match.
2915                 if(!IsInteger(left->getBasicType()))
2916                 {
2917                         return false;
2918                 }
2919                 break;
2920         default:
2921                 break;
2922         }
2923
2924         // GLSL ES 1.00 and 3.00 do not support implicit type casting.
2925         // So the basic type should usually match.
2926         if(!isBitShift && left->getBasicType() != right->getBasicType())
2927         {
2928                 return false;
2929         }
2930
2931         // Check that type sizes match exactly on ops that require that.
2932         // Also check restrictions for structs that contain arrays or samplers.
2933         switch(op)
2934         {
2935         case EOpAssign:
2936         case EOpInitialize:
2937         case EOpEqual:
2938         case EOpNotEqual:
2939                 // ESSL 1.00 sections 5.7, 5.8, 5.9
2940                 if(shaderVersion < 300 && left->getType().isStructureContainingArrays())
2941                 {
2942                         error(loc, "undefined operation for structs containing arrays", getOperatorString(op));
2943                         return false;
2944                 }
2945                 // Samplers as l-values are disallowed also in ESSL 3.00, see section 4.1.7,
2946                 // we interpret the spec so that this extends to structs containing samplers,
2947                 // similarly to ESSL 1.00 spec.
2948                 if((shaderVersion < 300 || op == EOpAssign || op == EOpInitialize) &&
2949                         left->getType().isStructureContainingSamplers())
2950                 {
2951                         error(loc, "undefined operation for structs containing samplers", getOperatorString(op));
2952                         return false;
2953                 }
2954         case EOpLessThan:
2955         case EOpGreaterThan:
2956         case EOpLessThanEqual:
2957         case EOpGreaterThanEqual:
2958                 if((left->getNominalSize() != right->getNominalSize()) ||
2959                         (left->getSecondarySize() != right->getSecondarySize()))
2960                 {
2961                         return false;
2962                 }
2963         default:
2964                 break;
2965         }
2966
2967         return true;
2968 }
2969
2970 TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &loc)
2971 {
2972         TBasicType switchType = init->getBasicType();
2973         if((switchType != EbtInt && switchType != EbtUInt) ||
2974            init->isMatrix() ||
2975            init->isArray() ||
2976            init->isVector())
2977         {
2978                 error(init->getLine(), "init-expression in a switch statement must be a scalar integer", "switch");
2979                 recover();
2980                 return nullptr;
2981         }
2982
2983         if(statementList)
2984         {
2985                 if(!ValidateSwitch::validate(switchType, this, statementList, loc))
2986                 {
2987                         recover();
2988                         return nullptr;
2989                 }
2990         }
2991
2992         TIntermSwitch *node = intermediate.addSwitch(init, statementList, loc);
2993         if(node == nullptr)
2994         {
2995                 error(loc, "erroneous switch statement", "switch");
2996                 recover();
2997                 return nullptr;
2998         }
2999         return node;
3000 }
3001
3002 TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &loc)
3003 {
3004         if(switchNestingLevel == 0)
3005         {
3006                 error(loc, "case labels need to be inside switch statements", "case");
3007                 recover();
3008                 return nullptr;
3009         }
3010         if(condition == nullptr)
3011         {
3012                 error(loc, "case label must have a condition", "case");
3013                 recover();
3014                 return nullptr;
3015         }
3016         if((condition->getBasicType() != EbtInt && condition->getBasicType() != EbtUInt) ||
3017            condition->isMatrix() ||
3018            condition->isArray() ||
3019            condition->isVector())
3020         {
3021                 error(condition->getLine(), "case label must be a scalar integer", "case");
3022                 recover();
3023         }
3024         TIntermConstantUnion *conditionConst = condition->getAsConstantUnion();
3025         if(conditionConst == nullptr)
3026         {
3027                 error(condition->getLine(), "case label must be constant", "case");
3028                 recover();
3029         }
3030         TIntermCase *node = intermediate.addCase(condition, loc);
3031         if(node == nullptr)
3032         {
3033                 error(loc, "erroneous case statement", "case");
3034                 recover();
3035                 return nullptr;
3036         }
3037         return node;
3038 }
3039
3040 TIntermCase *TParseContext::addDefault(const TSourceLoc &loc)
3041 {
3042         if(switchNestingLevel == 0)
3043         {
3044                 error(loc, "default labels need to be inside switch statements", "default");
3045                 recover();
3046                 return nullptr;
3047         }
3048         TIntermCase *node = intermediate.addCase(nullptr, loc);
3049         if(node == nullptr)
3050         {
3051                 error(loc, "erroneous default statement", "default");
3052                 recover();
3053                 return nullptr;
3054         }
3055         return node;
3056 }
3057
3058 TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc)
3059 {
3060         switch(op)
3061         {
3062         case EOpContinue:
3063                 if(loopNestingLevel <= 0)
3064                 {
3065                         error(loc, "continue statement only allowed in loops", "");
3066                         recover();
3067                 }
3068                 break;
3069         case EOpBreak:
3070                 if(loopNestingLevel <= 0 && switchNestingLevel <= 0)
3071                 {
3072                         error(loc, "break statement only allowed in loops and switch statements", "");
3073                         recover();
3074                 }
3075                 break;
3076         case EOpReturn:
3077                 if(currentFunctionType->getBasicType() != EbtVoid)
3078                 {
3079                         error(loc, "non-void function must return a value", "return");
3080                         recover();
3081                 }
3082                 break;
3083         default:
3084                 // No checks for discard
3085                 break;
3086         }
3087         return intermediate.addBranch(op, loc);
3088 }
3089
3090 TIntermBranch *TParseContext::addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc)
3091 {
3092         ASSERT(op == EOpReturn);
3093         functionReturnsValue = true;
3094         if(currentFunctionType->getBasicType() == EbtVoid)
3095         {
3096                 error(loc, "void function cannot return a value", "return");
3097                 recover();
3098         }
3099         else if(*currentFunctionType != returnValue->getType())
3100         {
3101                 error(loc, "function return is not matching type:", "return");
3102                 recover();
3103         }
3104         return intermediate.addBranch(op, returnValue, loc);
3105 }
3106
3107 //
3108 // Parse an array of strings using yyparse.
3109 //
3110 // Returns 0 for success.
3111 //
3112 int PaParseStrings(int count, const char* const string[], const int length[],
3113                    TParseContext* context) {
3114     if ((count == 0) || (string == NULL))
3115         return 1;
3116
3117     if (glslang_initialize(context))
3118         return 1;
3119
3120     int error = glslang_scan(count, string, length, context);
3121     if (!error)
3122         error = glslang_parse(context);
3123
3124     glslang_finalize(context);
3125
3126     return (error == 0) && (context->numErrors() == 0) ? 0 : 1;
3127 }
3128
3129
3130