OSDN Git Service

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