Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / compiler / translator / ParseContext.cpp
1 //
2 // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 #include "compiler/translator/ParseContext.h"
8
9 #include <stdarg.h>
10 #include <stdio.h>
11
12 #include "compiler/translator/glslang.h"
13 #include "compiler/preprocessor/SourceLocation.h"
14
15 ///////////////////////////////////////////////////////////////////////
16 //
17 // Sub- vector and matrix fields
18 //
19 ////////////////////////////////////////////////////////////////////////
20
21 //
22 // Look at a '.' field selector string and change it into offsets
23 // for a vector.
24 //
25 bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, const TSourceLoc& line)
26 {
27     fields.num = (int) compString.size();
28     if (fields.num > 4) {
29         error(line, "illegal vector field selection", compString.c_str());
30         return false;
31     }
32
33     enum {
34         exyzw,
35         ergba,
36         estpq
37     } fieldSet[4];
38
39     for (int i = 0; i < fields.num; ++i) {
40         switch (compString[i])  {
41         case 'x': 
42             fields.offsets[i] = 0;
43             fieldSet[i] = exyzw;
44             break;
45         case 'r': 
46             fields.offsets[i] = 0;
47             fieldSet[i] = ergba;
48             break;
49         case 's':
50             fields.offsets[i] = 0;
51             fieldSet[i] = estpq;
52             break;
53         case 'y': 
54             fields.offsets[i] = 1;
55             fieldSet[i] = exyzw;
56             break;
57         case 'g': 
58             fields.offsets[i] = 1;
59             fieldSet[i] = ergba;
60             break;
61         case 't':
62             fields.offsets[i] = 1;
63             fieldSet[i] = estpq;
64             break;
65         case 'z': 
66             fields.offsets[i] = 2;
67             fieldSet[i] = exyzw;
68             break;
69         case 'b': 
70             fields.offsets[i] = 2;
71             fieldSet[i] = ergba;
72             break;
73         case 'p':
74             fields.offsets[i] = 2;
75             fieldSet[i] = estpq;
76             break;
77         
78         case 'w': 
79             fields.offsets[i] = 3;
80             fieldSet[i] = exyzw;
81             break;
82         case 'a': 
83             fields.offsets[i] = 3;
84             fieldSet[i] = ergba;
85             break;
86         case 'q':
87             fields.offsets[i] = 3;
88             fieldSet[i] = estpq;
89             break;
90         default:
91             error(line, "illegal vector field selection", compString.c_str());
92             return false;
93         }
94     }
95
96     for (int i = 0; i < fields.num; ++i) {
97         if (fields.offsets[i] >= vecSize) {
98             error(line, "vector field selection out of range",  compString.c_str());
99             return false;
100         }
101
102         if (i > 0) {
103             if (fieldSet[i] != fieldSet[i-1]) {
104                 error(line, "illegal - vector component fields not from the same set", compString.c_str());
105                 return false;
106             }
107         }
108     }
109
110     return true;
111 }
112
113
114 //
115 // Look at a '.' field selector string and change it into offsets
116 // for a matrix.
117 //
118 bool TParseContext::parseMatrixFields(const TString& compString, int matCols, int matRows, TMatrixFields& fields, const TSourceLoc& line)
119 {
120     fields.wholeRow = false;
121     fields.wholeCol = false;
122     fields.row = -1;
123     fields.col = -1;
124
125     if (compString.size() != 2) {
126         error(line, "illegal length of matrix field selection", compString.c_str());
127         return false;
128     }
129
130     if (compString[0] == '_') {
131         if (compString[1] < '0' || compString[1] > '3') {
132             error(line, "illegal matrix field selection", compString.c_str());
133             return false;
134         }
135         fields.wholeCol = true;
136         fields.col = compString[1] - '0';
137     } else if (compString[1] == '_') {
138         if (compString[0] < '0' || compString[0] > '3') {
139             error(line, "illegal matrix field selection", compString.c_str());
140             return false;
141         }
142         fields.wholeRow = true;
143         fields.row = compString[0] - '0';
144     } else {
145         if (compString[0] < '0' || compString[0] > '3' ||
146             compString[1] < '0' || compString[1] > '3') {
147             error(line, "illegal matrix field selection", compString.c_str());
148             return false;
149         }
150         fields.row = compString[0] - '0';
151         fields.col = compString[1] - '0';
152     }
153
154     if (fields.row >= matRows || fields.col >= matCols) {
155         error(line, "matrix field selection out of range", compString.c_str());
156         return false;
157     }
158
159     return true;
160 }
161
162 ///////////////////////////////////////////////////////////////////////
163 //
164 // Errors
165 //
166 ////////////////////////////////////////////////////////////////////////
167
168 //
169 // Track whether errors have occurred.
170 //
171 void TParseContext::recover()
172 {
173 }
174
175 //
176 // Used by flex/bison to output all syntax and parsing errors.
177 //
178 void TParseContext::error(const TSourceLoc& loc,
179                           const char* reason, const char* token, 
180                           const char* extraInfo)
181 {
182     pp::SourceLocation srcLoc;
183     srcLoc.file = loc.first_file;
184     srcLoc.line = loc.first_line;
185     diagnostics.writeInfo(pp::Diagnostics::PP_ERROR,
186                           srcLoc, reason, token, extraInfo);
187
188 }
189
190 void TParseContext::warning(const TSourceLoc& loc,
191                             const char* reason, const char* token,
192                             const char* extraInfo) {
193     pp::SourceLocation srcLoc;
194     srcLoc.file = loc.first_file;
195     srcLoc.line = loc.first_line;
196     diagnostics.writeInfo(pp::Diagnostics::PP_WARNING,
197                           srcLoc, reason, token, extraInfo);
198 }
199
200 void TParseContext::trace(const char* str)
201 {
202     diagnostics.writeDebug(str);
203 }
204
205 //
206 // Same error message for all places assignments don't work.
207 //
208 void TParseContext::assignError(const TSourceLoc& line, const char* op, TString left, TString right)
209 {
210     std::stringstream extraInfoStream;
211     extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'";
212     std::string extraInfo = extraInfoStream.str();
213     error(line, "", op, extraInfo.c_str());
214 }
215
216 //
217 // Same error message for all places unary operations don't work.
218 //
219 void TParseContext::unaryOpError(const TSourceLoc& line, const char* op, TString operand)
220 {
221     std::stringstream extraInfoStream;
222     extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " << operand 
223                     << " (or there is no acceptable conversion)";
224     std::string extraInfo = extraInfoStream.str();
225     error(line, " wrong operand type", op, extraInfo.c_str());
226 }
227
228 //
229 // Same error message for all binary operations don't work.
230 //
231 void TParseContext::binaryOpError(const TSourceLoc& line, const char* op, TString left, TString right)
232 {
233     std::stringstream extraInfoStream;
234     extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" << left 
235                     << "' and a right operand of type '" << right << "' (or there is no acceptable conversion)";
236     std::string extraInfo = extraInfoStream.str();
237     error(line, " wrong operand types ", op, extraInfo.c_str()); 
238 }
239
240 bool TParseContext::precisionErrorCheck(const TSourceLoc& line, TPrecision precision, TBasicType type){
241     if (!checksPrecisionErrors)
242         return false;
243     switch( type ){
244     case EbtFloat:
245         if( precision == EbpUndefined ){
246             error( line, "No precision specified for (float)", "" );
247             return true;
248         }
249         break;
250     case EbtInt:
251         if( precision == EbpUndefined ){
252             error( line, "No precision specified (int)", "" );
253             return true;
254         }
255         break;
256     default:
257         return false;
258     }
259     return false;
260 }
261
262 //
263 // Both test and if necessary, spit out an error, to see if the node is really
264 // an l-value that can be operated on this way.
265 //
266 // Returns true if the was an error.
267 //
268 bool TParseContext::lValueErrorCheck(const TSourceLoc& line, const char* op, TIntermTyped* node)
269 {
270     TIntermSymbol* symNode = node->getAsSymbolNode();
271     TIntermBinary* binaryNode = node->getAsBinaryNode();
272
273     if (binaryNode) {
274         bool errorReturn;
275
276         switch(binaryNode->getOp()) {
277         case EOpIndexDirect:
278         case EOpIndexIndirect:
279         case EOpIndexDirectStruct:
280         case EOpIndexDirectInterfaceBlock:
281             return lValueErrorCheck(line, op, binaryNode->getLeft());
282         case EOpVectorSwizzle:
283             errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft());
284             if (!errorReturn) {
285                 int offset[4] = {0,0,0,0};
286
287                 TIntermTyped* rightNode = binaryNode->getRight();
288                 TIntermAggregate *aggrNode = rightNode->getAsAggregate();
289
290                 for (TIntermSequence::iterator p = aggrNode->getSequence()->begin();
291                                                p != aggrNode->getSequence()->end(); p++) {
292                     int value = (*p)->getAsTyped()->getAsConstantUnion()->getIConst(0);
293                     offset[value]++;
294                     if (offset[value] > 1) {
295                         error(line, " l-value of swizzle cannot have duplicate components", op);
296
297                         return true;
298                     }
299                 }
300             }
301
302             return errorReturn;
303         default:
304             break;
305         }
306         error(line, " l-value required", op);
307
308         return true;
309     }
310
311
312     const char* symbol = 0;
313     if (symNode != 0)
314         symbol = symNode->getSymbol().c_str();
315
316     const char* message = 0;
317     switch (node->getQualifier()) {
318     case EvqConst:          message = "can't modify a const";        break;
319     case EvqConstReadOnly:  message = "can't modify a const";        break;
320     case EvqAttribute:      message = "can't modify an attribute";   break;
321     case EvqFragmentIn:     message = "can't modify an input";       break;
322     case EvqVertexIn:       message = "can't modify an input";       break;
323     case EvqUniform:        message = "can't modify a uniform";      break;
324     case EvqVaryingIn:      message = "can't modify a varying";      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     default:
329
330         //
331         // Type that can't be written to?
332         //
333         if (node->getBasicType() == EbtVoid) {
334             message = "can't modify void";
335         }
336         if (IsSampler(node->getBasicType())) {
337             message = "can't modify a sampler";
338         }
339     }
340
341     if (message == 0 && binaryNode == 0 && symNode == 0) {
342         error(line, " l-value required", op);
343
344         return true;
345     }
346
347
348     //
349     // Everything else is okay, no error.
350     //
351     if (message == 0)
352         return false;
353
354     //
355     // If we get here, we have an error and a message.
356     //
357     if (symNode) {
358         std::stringstream extraInfoStream;
359         extraInfoStream << "\"" << symbol << "\" (" << message << ")";
360         std::string extraInfo = extraInfoStream.str();
361         error(line, " l-value required", op, extraInfo.c_str());
362     }
363     else {
364         std::stringstream extraInfoStream;
365         extraInfoStream << "(" << message << ")";
366         std::string extraInfo = extraInfoStream.str();
367         error(line, " l-value required", op, extraInfo.c_str());
368     }
369
370     return true;
371 }
372
373 //
374 // Both test, and if necessary spit out an error, to see if the node is really
375 // a constant.
376 //
377 // Returns true if the was an error.
378 //
379 bool TParseContext::constErrorCheck(TIntermTyped* node)
380 {
381     if (node->getQualifier() == EvqConst)
382         return false;
383
384     error(node->getLine(), "constant expression required", "");
385
386     return true;
387 }
388
389 //
390 // Both test, and if necessary spit out an error, to see if the node is really
391 // an integer.
392 //
393 // Returns true if the was an error.
394 //
395 bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token)
396 {
397     if (node->isScalarInt())
398         return false;
399
400     error(node->getLine(), "integer expression required", token);
401
402     return true;
403 }
404
405 //
406 // Both test, and if necessary spit out an error, to see if we are currently
407 // globally scoped.
408 //
409 // Returns true if the was an error.
410 //
411 bool TParseContext::globalErrorCheck(const TSourceLoc& line, bool global, const char* token)
412 {
413     if (global)
414         return false;
415
416     error(line, "only allowed at global scope", token);
417
418     return true;
419 }
420
421 //
422 // For now, keep it simple:  if it starts "gl_", it's reserved, independent
423 // of scope.  Except, if the symbol table is at the built-in push-level,
424 // which is when we are parsing built-ins.
425 // Also checks for "webgl_" and "_webgl_" reserved identifiers if parsing a
426 // webgl shader.
427 //
428 // Returns true if there was an error.
429 //
430 bool TParseContext::reservedErrorCheck(const TSourceLoc& line, const TString& identifier)
431 {
432     static const char* reservedErrMsg = "reserved built-in name";
433     if (!symbolTable.atBuiltInLevel()) {
434         if (identifier.compare(0, 3, "gl_") == 0) {
435             error(line, reservedErrMsg, "gl_");
436             return true;
437         }
438         if (IsWebGLBasedSpec(shaderSpec)) {
439             if (identifier.compare(0, 6, "webgl_") == 0) {
440                 error(line, reservedErrMsg, "webgl_");
441                 return true;
442             }
443             if (identifier.compare(0, 7, "_webgl_") == 0) {
444                 error(line, reservedErrMsg, "_webgl_");
445                 return true;
446             }
447             if (shaderSpec == SH_CSS_SHADERS_SPEC && identifier.compare(0, 4, "css_") == 0) {
448                 error(line, reservedErrMsg, "css_");
449                 return true;
450             }
451         }
452         if (identifier.find("__") != TString::npos) {
453             error(line, "identifiers containing two consecutive underscores (__) are reserved as possible future keywords", identifier.c_str());
454             return true;
455         }
456     }
457
458     return false;
459 }
460
461 //
462 // Make sure there is enough data provided to the constructor to build
463 // something of the type of the constructor.  Also returns the type of
464 // the constructor.
465 //
466 // Returns true if there was an error in construction.
467 //
468 bool TParseContext::constructorErrorCheck(const TSourceLoc& line, TIntermNode* node, TFunction& function, TOperator op, TType* type)
469 {
470     *type = function.getReturnType();
471
472     bool constructingMatrix = false;
473     switch(op) {
474     case EOpConstructMat2:
475     case EOpConstructMat3:
476     case EOpConstructMat4:
477         constructingMatrix = true;
478         break;
479     default: 
480         break;
481     }
482
483     //
484     // Note: It's okay to have too many components available, but not okay to have unused
485     // arguments.  'full' will go to true when enough args have been seen.  If we loop
486     // again, there is an extra argument, so 'overfull' will become true.
487     //
488
489     size_t size = 0;
490     bool constType = true;
491     bool full = false;
492     bool overFull = false;
493     bool matrixInMatrix = false;
494     bool arrayArg = false;
495     for (size_t i = 0; i < function.getParamCount(); ++i) {
496         const TParameter& param = function.getParam(i);
497         size += param.type->getObjectSize();
498         
499         if (constructingMatrix && param.type->isMatrix())
500             matrixInMatrix = true;
501         if (full)
502             overFull = true;
503         if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize())
504             full = true;
505         if (param.type->getQualifier() != EvqConst)
506             constType = false;
507         if (param.type->isArray())
508             arrayArg = true;
509     }
510     
511     if (constType)
512         type->setQualifier(EvqConst);
513
514     if (type->isArray() && static_cast<size_t>(type->getArraySize()) != function.getParamCount()) {
515         error(line, "array constructor needs one argument per array element", "constructor");
516         return true;
517     }
518
519     if (arrayArg && op != EOpConstructStruct) {
520         error(line, "constructing from a non-dereferenced array", "constructor");
521         return true;
522     }
523
524     if (matrixInMatrix && !type->isArray()) {
525         if (function.getParamCount() != 1) {
526           error(line, "constructing matrix from matrix can only take one argument", "constructor");
527           return true;
528         }
529     }
530
531     if (overFull) {
532         error(line, "too many arguments", "constructor");
533         return true;
534     }
535     
536     if (op == EOpConstructStruct && !type->isArray() && type->getStruct()->fields().size() != function.getParamCount()) {
537         error(line, "Number of constructor parameters does not match the number of structure fields", "constructor");
538         return true;
539     }
540
541     if (!type->isMatrix() || !matrixInMatrix) {
542         if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) ||
543             (op == EOpConstructStruct && size < type->getObjectSize())) {
544             error(line, "not enough data provided for construction", "constructor");
545             return true;
546         }
547     }
548
549     TIntermTyped *typed = node ? node->getAsTyped() : 0;
550     if (typed == 0) {
551         error(line, "constructor argument does not have a type", "constructor");
552         return true;
553     }
554     if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) {
555         error(line, "cannot convert a sampler", "constructor");
556         return true;
557     }
558     if (typed->getBasicType() == EbtVoid) {
559         error(line, "cannot convert a void", "constructor");
560         return true;
561     }
562
563     return false;
564 }
565
566 // This function checks to see if a void variable has been declared and raise an error message for such a case
567 //
568 // returns true in case of an error
569 //
570 bool TParseContext::voidErrorCheck(const TSourceLoc& line, const TString& identifier, const TPublicType& pubType)
571 {
572     if (pubType.type == EbtVoid) {
573         error(line, "illegal use of type 'void'", identifier.c_str());
574         return true;
575     } 
576
577     return false;
578 }
579
580 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
581 //
582 // returns true in case of an error
583 //
584 bool TParseContext::boolErrorCheck(const TSourceLoc& line, const TIntermTyped* type)
585 {
586     if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) {
587         error(line, "boolean expression expected", "");
588         return true;
589     } 
590
591     return false;
592 }
593
594 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
595 //
596 // returns true in case of an error
597 //
598 bool TParseContext::boolErrorCheck(const TSourceLoc& line, const TPublicType& pType)
599 {
600     if (pType.type != EbtBool || pType.isAggregate()) {
601         error(line, "boolean expression expected", "");
602         return true;
603     } 
604
605     return false;
606 }
607
608 bool TParseContext::samplerErrorCheck(const TSourceLoc& line, const TPublicType& pType, const char* reason)
609 {
610     if (pType.type == EbtStruct) {
611         if (containsSampler(*pType.userDef)) {
612             error(line, reason, getBasicString(pType.type), "(structure contains a sampler)");
613         
614             return true;
615         }
616         
617         return false;
618     } else if (IsSampler(pType.type)) {
619         error(line, reason, getBasicString(pType.type));
620
621         return true;
622     }
623
624     return false;
625 }
626
627 bool TParseContext::structQualifierErrorCheck(const TSourceLoc& line, const TPublicType& pType)
628 {
629     switch (pType.qualifier)
630     {
631       case EvqVaryingIn:
632       case EvqVaryingOut:
633       case EvqAttribute:
634       case EvqVertexIn:
635       case EvqFragmentOut:
636         if (pType.type == EbtStruct)
637         {
638             error(line, "cannot be used with a structure", getQualifierString(pType.qualifier));
639             return true;
640         }
641
642       default: break;
643     }
644
645     if (pType.qualifier != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform"))
646         return true;
647
648     return false;
649 }
650
651 bool TParseContext::locationDeclaratorListCheck(const TSourceLoc& line, const TPublicType &pType)
652 {
653     if (pType.layoutQualifier.location != -1)
654     {
655         error(line, "location must only be specified for a single input or output variable", "location");
656         return true;
657     }
658
659     return false;
660 }
661
662 bool TParseContext::parameterSamplerErrorCheck(const TSourceLoc& line, TQualifier qualifier, const TType& type)
663 {
664     if ((qualifier == EvqOut || qualifier == EvqInOut) && 
665              type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
666         error(line, "samplers cannot be output parameters", type.getBasicString());
667         return true;
668     }
669
670     return false;
671 }
672
673 bool TParseContext::containsSampler(TType& type)
674 {
675     if (IsSampler(type.getBasicType()))
676         return true;
677
678     if (type.getBasicType() == EbtStruct || type.isInterfaceBlock()) {
679         const TFieldList& fields = type.getStruct()->fields();
680         for (unsigned int i = 0; i < fields.size(); ++i) {
681             if (containsSampler(*fields[i]->type()))
682                 return true;
683         }
684     }
685
686     return false;
687 }
688
689 //
690 // Do size checking for an array type's size.
691 //
692 // Returns true if there was an error.
693 //
694 bool TParseContext::arraySizeErrorCheck(const TSourceLoc& line, TIntermTyped* expr, int& size)
695 {
696     TIntermConstantUnion* constant = expr->getAsConstantUnion();
697
698     if (constant == 0 || !constant->isScalarInt())
699     {
700         error(line, "array size must be a constant integer expression", "");
701         return true;
702     }
703
704     unsigned int unsignedSize = 0;
705
706     if (constant->getBasicType() == EbtUInt)
707     {
708         unsignedSize = constant->getUConst(0);
709         size = static_cast<int>(unsignedSize);
710     }
711     else
712     {
713         size = constant->getIConst(0);
714
715         if (size < 0)
716         {
717             error(line, "array size must be non-negative", "");
718             size = 1;
719             return true;
720         }
721
722         unsignedSize = static_cast<unsigned int>(size);
723     }
724
725     if (size == 0)
726     {
727         error(line, "array size must be greater than zero", "");
728         size = 1;
729         return true;
730     }
731
732     // The size of arrays is restricted here to prevent issues further down the
733     // compiler/translator/driver stack. Shader Model 5 generation hardware is limited to
734     // 4096 registers so this should be reasonable even for aggressively optimizable code.
735     const unsigned int sizeLimit = 65536;
736
737     if (unsignedSize > sizeLimit)
738     {
739         error(line, "array size too large", "");
740         size = 1;
741         return true;
742     }
743
744     return false;
745 }
746
747 //
748 // See if this qualifier can be an array.
749 //
750 // Returns true if there is an error.
751 //
752 bool TParseContext::arrayQualifierErrorCheck(const TSourceLoc& line, TPublicType type)
753 {
754     if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqVertexIn) || (type.qualifier == EvqConst)) {
755         error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str());
756         return true;
757     }
758
759     return false;
760 }
761
762 //
763 // See if this type can be an array.
764 //
765 // Returns true if there is an error.
766 //
767 bool TParseContext::arrayTypeErrorCheck(const TSourceLoc& line, TPublicType type)
768 {
769     //
770     // Can the type be an array?
771     //
772     if (type.array) {
773         error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str());
774         return true;
775     }
776
777     return false;
778 }
779
780 //
781 // Do all the semantic checking for declaring an array, with and 
782 // without a size, and make the right changes to the symbol table.
783 //
784 // size == 0 means no specified size.
785 //
786 // Returns true if there was an error.
787 //
788 bool TParseContext::arrayErrorCheck(const TSourceLoc& line, const TString& identifier, const TPublicType &type, TVariable*& variable)
789 {
790     //
791     // Don't check for reserved word use until after we know it's not in the symbol table,
792     // because reserved arrays can be redeclared.
793     //
794
795     bool builtIn = false; 
796     bool sameScope = false;
797     TSymbol* symbol = symbolTable.find(identifier, 0, &builtIn, &sameScope);
798     if (symbol == 0 || !sameScope) {
799         if (reservedErrorCheck(line, identifier))
800             return true;
801         
802         variable = new TVariable(&identifier, TType(type));
803
804         if (type.arraySize)
805             variable->getType().setArraySize(type.arraySize);
806
807         if (! symbolTable.declare(variable)) {
808             delete variable;
809             error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str());
810             return true;
811         }
812     } else {
813         if (! symbol->isVariable()) {
814             error(line, "variable expected", identifier.c_str());
815             return true;
816         }
817
818         variable = static_cast<TVariable*>(symbol);
819         if (! variable->getType().isArray()) {
820             error(line, "redeclaring non-array as array", identifier.c_str());
821             return true;
822         }
823         if (variable->getType().getArraySize() > 0) {
824             error(line, "redeclaration of array with size", identifier.c_str());
825             return true;
826         }
827         
828         if (! variable->getType().sameElementType(TType(type))) {
829             error(line, "redeclaration of array with a different type", identifier.c_str());
830             return true;
831         }
832
833         if (type.arraySize)
834             variable->getType().setArraySize(type.arraySize);
835     } 
836
837     if (voidErrorCheck(line, identifier, type))
838         return true;
839
840     return false;
841 }
842
843 //
844 // Enforce non-initializer type/qualifier rules.
845 //
846 // Returns true if there was an error.
847 //
848 bool TParseContext::nonInitConstErrorCheck(const TSourceLoc& line, const TString& identifier, TPublicType& type, bool array)
849 {
850     if (type.qualifier == EvqConst)
851     {
852         // Make the qualifier make sense.
853         type.qualifier = EvqTemporary;
854         
855         if (array)
856         {
857             error(line, "arrays may not be declared constant since they cannot be initialized", identifier.c_str());
858         }
859         else if (type.isStructureContainingArrays())
860         {
861             error(line, "structures containing arrays may not be declared constant since they cannot be initialized", identifier.c_str());
862         }
863         else
864         {
865             error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
866         }
867
868         return true;
869     }
870
871     return false;
872 }
873
874 //
875 // Do semantic checking for a variable declaration that has no initializer,
876 // and update the symbol table.
877 //
878 // Returns true if there was an error.
879 //
880 bool TParseContext::nonInitErrorCheck(const TSourceLoc& line, const TString& identifier, const TPublicType& type, TVariable*& variable)
881 {
882     if (reservedErrorCheck(line, identifier))
883         recover();
884
885     variable = new TVariable(&identifier, TType(type));
886
887     if (! symbolTable.declare(variable)) {
888         error(line, "redefinition", variable->getName().c_str());
889         delete variable;
890         variable = 0;
891         return true;
892     }
893
894     if (voidErrorCheck(line, identifier, type))
895         return true;
896
897     return false;
898 }
899
900 bool TParseContext::paramErrorCheck(const TSourceLoc& line, TQualifier qualifier, TQualifier paramQualifier, TType* type)
901 {    
902     if (qualifier != EvqConst && qualifier != EvqTemporary) {
903         error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier));
904         return true;
905     }
906     if (qualifier == EvqConst && paramQualifier != EvqIn) {
907         error(line, "qualifier not allowed with ", getQualifierString(qualifier), getQualifierString(paramQualifier));
908         return true;
909     }
910
911     if (qualifier == EvqConst)
912         type->setQualifier(EvqConstReadOnly);
913     else
914         type->setQualifier(paramQualifier);
915
916     return false;
917 }
918
919 bool TParseContext::extensionErrorCheck(const TSourceLoc& line, const TString& extension)
920 {
921     const TExtensionBehavior& extBehavior = extensionBehavior();
922     TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str());
923     if (iter == extBehavior.end()) {
924         error(line, "extension", extension.c_str(), "is not supported");
925         return true;
926     }
927     // In GLSL ES, an extension's default behavior is "disable".
928     if (iter->second == EBhDisable || iter->second == EBhUndefined) {
929         error(line, "extension", extension.c_str(), "is disabled");
930         return true;
931     }
932     if (iter->second == EBhWarn) {
933         warning(line, "extension", extension.c_str(), "is being used");
934         return false;
935     }
936
937     return false;
938 }
939
940 bool TParseContext::singleDeclarationErrorCheck(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier)
941 {
942     if (structQualifierErrorCheck(identifierLocation, publicType))
943         return true;
944
945     // check for layout qualifier issues
946     const TLayoutQualifier layoutQualifier = publicType.layoutQualifier;
947
948     if (layoutQualifier.matrixPacking != EmpUnspecified)
949     {
950         error(identifierLocation, "layout qualifier", getMatrixPackingString(layoutQualifier.matrixPacking), "only valid for interface blocks");
951         return true;
952     }
953
954     if (layoutQualifier.blockStorage != EbsUnspecified)
955     {
956         error(identifierLocation, "layout qualifier", getBlockStorageString(layoutQualifier.blockStorage), "only valid for interface blocks");
957         return true;
958     }
959
960     if (publicType.qualifier != EvqVertexIn && publicType.qualifier != EvqFragmentOut && layoutLocationErrorCheck(identifierLocation, publicType.layoutQualifier))
961     {
962         return true;
963     }
964
965     return false;
966 }
967
968 bool TParseContext::layoutLocationErrorCheck(const TSourceLoc& location, const TLayoutQualifier &layoutQualifier)
969 {
970     if (layoutQualifier.location != -1)
971     {
972         error(location, "invalid layout qualifier:", "location", "only valid on program inputs and outputs");
973         return true;
974     }
975
976     return false;
977 }
978
979 bool TParseContext::supportsExtension(const char* extension)
980 {
981     const TExtensionBehavior& extbehavior = extensionBehavior();
982     TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
983     return (iter != extbehavior.end());
984 }
985
986 bool TParseContext::isExtensionEnabled(const char* extension) const
987 {
988     const TExtensionBehavior& extbehavior = extensionBehavior();
989     TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
990
991     if (iter == extbehavior.end())
992     {
993         return false;
994     }
995
996     return (iter->second == EBhEnable || iter->second == EBhRequire);
997 }
998
999 void TParseContext::handleExtensionDirective(const TSourceLoc& loc, const char* extName, const char* behavior)
1000 {
1001     pp::SourceLocation srcLoc;
1002     srcLoc.file = loc.first_file;
1003     srcLoc.line = loc.first_line;
1004     directiveHandler.handleExtension(srcLoc, extName, behavior);
1005 }
1006
1007 void TParseContext::handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value)
1008 {
1009     pp::SourceLocation srcLoc;
1010     srcLoc.file = loc.first_file;
1011     srcLoc.line = loc.first_line;
1012     directiveHandler.handlePragma(srcLoc, name, value);
1013 }
1014
1015 /////////////////////////////////////////////////////////////////////////////////
1016 //
1017 // Non-Errors.
1018 //
1019 /////////////////////////////////////////////////////////////////////////////////
1020
1021 //
1022 // Look up a function name in the symbol table, and make sure it is a function.
1023 //
1024 // Return the function symbol if found, otherwise 0.
1025 //
1026 const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction* call, int shaderVersion, bool *builtIn)
1027 {
1028     // First find by unmangled name to check whether the function name has been
1029     // hidden by a variable name or struct typename.
1030     // If a function is found, check for one with a matching argument list.
1031     const TSymbol* symbol = symbolTable.find(call->getName(), shaderVersion, builtIn);
1032     if (symbol == 0 || symbol->isFunction()) {
1033         symbol = symbolTable.find(call->getMangledName(), shaderVersion, builtIn);
1034     }
1035
1036     if (symbol == 0) {
1037         error(line, "no matching overloaded function found", call->getName().c_str());
1038         return 0;
1039     }
1040
1041     if (!symbol->isFunction()) {
1042         error(line, "function name expected", call->getName().c_str());
1043         return 0;
1044     }
1045
1046     return static_cast<const TFunction*>(symbol);
1047 }
1048
1049 //
1050 // Initializers show up in several places in the grammar.  Have one set of
1051 // code to handle them here.
1052 //
1053 bool TParseContext::executeInitializer(const TSourceLoc& line, const TString& identifier, TPublicType& pType, 
1054                                        TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable)
1055 {
1056     TType type = TType(pType);
1057
1058     if (variable == 0) {
1059         if (reservedErrorCheck(line, identifier))
1060             return true;
1061
1062         if (voidErrorCheck(line, identifier, pType))
1063             return true;
1064
1065         //
1066         // add variable to symbol table
1067         //
1068         variable = new TVariable(&identifier, type);
1069         if (! symbolTable.declare(variable)) {
1070             error(line, "redefinition", variable->getName().c_str());
1071             return true;
1072             // don't delete variable, it's used by error recovery, and the pool 
1073             // pop will take care of the memory
1074         }
1075     }
1076
1077     //
1078     // identifier must be of type constant, a global, or a temporary
1079     //
1080     TQualifier qualifier = variable->getType().getQualifier();
1081     if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) {
1082         error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString());
1083         return true;
1084     }
1085     //
1086     // test for and propagate constant
1087     //
1088
1089     if (qualifier == EvqConst) {
1090         if (qualifier != initializer->getType().getQualifier()) {
1091             std::stringstream extraInfoStream;
1092             extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
1093             std::string extraInfo = extraInfoStream.str();
1094             error(line, " assigning non-constant to", "=", extraInfo.c_str());
1095             variable->getType().setQualifier(EvqTemporary);
1096             return true;
1097         }
1098         if (type != initializer->getType()) {
1099             error(line, " non-matching types for const initializer ", 
1100                 variable->getType().getQualifierString());
1101             variable->getType().setQualifier(EvqTemporary);
1102             return true;
1103         }
1104         if (initializer->getAsConstantUnion()) { 
1105             variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
1106         } else if (initializer->getAsSymbolNode()) {
1107             const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), 0);
1108             const TVariable* tVar = static_cast<const TVariable*>(symbol);
1109
1110             ConstantUnion* constArray = tVar->getConstPointer();
1111             variable->shareConstPointer(constArray);
1112         } else {
1113             std::stringstream extraInfoStream;
1114             extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
1115             std::string extraInfo = extraInfoStream.str();
1116             error(line, " cannot assign to", "=", extraInfo.c_str());
1117             variable->getType().setQualifier(EvqTemporary);
1118             return true;
1119         }
1120     }
1121  
1122     if (qualifier != EvqConst) {
1123         TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
1124         intermNode = intermediate.addAssign(EOpInitialize, intermSymbol, initializer, line);
1125         if (intermNode == 0) {
1126             assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
1127             return true;
1128         }
1129     } else 
1130         intermNode = 0;
1131
1132     return false;
1133 }
1134
1135 bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
1136 {
1137     ASSERT(aggrNode != NULL);
1138     if (!aggrNode->isConstructor())
1139         return false;
1140
1141     bool allConstant = true;
1142
1143     // check if all the child nodes are constants so that they can be inserted into 
1144     // the parent node
1145     TIntermSequence *sequence = aggrNode->getSequence() ;
1146     for (TIntermSequence::iterator p = sequence->begin(); p != sequence->end(); ++p) {
1147         if (!(*p)->getAsTyped()->getAsConstantUnion())
1148             return false;
1149     }
1150
1151     return allConstant;
1152 }
1153
1154 TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, TLayoutQualifier layoutQualifier, const TPublicType& typeSpecifier)
1155 {
1156     TPublicType returnType = typeSpecifier;
1157     returnType.qualifier = qualifier;
1158     returnType.layoutQualifier = layoutQualifier;
1159
1160     if (typeSpecifier.array)
1161     {
1162         error(typeSpecifier.line, "not supported", "first-class array");
1163         recover();
1164         returnType.setArray(false);
1165     }
1166
1167     if (shaderVersion < 300)
1168     {
1169         if (qualifier == EvqAttribute && (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt))
1170         {
1171             error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier));
1172             recover();
1173         }
1174
1175         if ((qualifier == EvqVaryingIn || qualifier == EvqVaryingOut) &&
1176             (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt))
1177         {
1178             error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier));
1179             recover();
1180         }
1181     }
1182     else
1183     {
1184         switch (qualifier)
1185         {
1186           case EvqSmoothIn:
1187           case EvqSmoothOut:
1188           case EvqVertexOut:
1189           case EvqFragmentIn:
1190           case EvqCentroidOut:
1191           case EvqCentroidIn:
1192             if (typeSpecifier.type == EbtBool)
1193             {
1194                 error(typeSpecifier.line, "cannot be bool", getQualifierString(qualifier));
1195                 recover();
1196             }
1197             if (typeSpecifier.type == EbtInt || typeSpecifier.type == EbtUInt)
1198             {
1199                 error(typeSpecifier.line, "must use 'flat' interpolation here", getQualifierString(qualifier));
1200                 recover();
1201             }
1202             break;
1203
1204           case EvqVertexIn:
1205           case EvqFragmentOut:
1206           case EvqFlatIn:
1207           case EvqFlatOut:
1208             if (typeSpecifier.type == EbtBool)
1209             {
1210                 error(typeSpecifier.line, "cannot be bool", getQualifierString(qualifier));
1211                 recover();
1212             }
1213             break;
1214
1215           default: break;
1216         }
1217     }
1218
1219     return returnType;
1220 }
1221
1222 TIntermAggregate* TParseContext::parseSingleDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier)
1223 {
1224     TIntermSymbol* symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation);
1225     TIntermAggregate* aggregate = intermediate.makeAggregate(symbol, identifierLocation);
1226
1227     if (identifier != "")
1228     {
1229         if (singleDeclarationErrorCheck(publicType, identifierLocation, identifier))
1230             recover();
1231
1232         // this error check can mutate the type
1233         if (nonInitConstErrorCheck(identifierLocation, identifier, publicType, false))
1234             recover();
1235
1236         TVariable* variable = 0;
1237
1238         if (nonInitErrorCheck(identifierLocation, identifier, publicType, variable))
1239             recover();
1240
1241         if (variable && symbol)
1242         {
1243             symbol->setId(variable->getUniqueId());
1244         }
1245     }
1246
1247     return aggregate;
1248 }
1249
1250 TIntermAggregate* TParseContext::parseSingleArrayDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& indexLocation, TIntermTyped *indexExpression)
1251 {
1252     if (singleDeclarationErrorCheck(publicType, identifierLocation, identifier))
1253         recover();
1254
1255     // this error check can mutate the type
1256     if (nonInitConstErrorCheck(identifierLocation, identifier, publicType, true))
1257         recover();
1258
1259     if (arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType))
1260     {
1261         recover();
1262     }
1263
1264     TPublicType arrayType = publicType;
1265
1266     int size;
1267     if (arraySizeErrorCheck(identifierLocation, indexExpression, size))
1268     {
1269         recover();
1270     }
1271     else
1272     {
1273         arrayType.setArray(true, size);
1274     }
1275
1276     TIntermSymbol* symbol = intermediate.addSymbol(0, identifier, TType(arrayType), identifierLocation);
1277     TIntermAggregate* aggregate = intermediate.makeAggregate(symbol, identifierLocation);
1278     TVariable* variable = 0;
1279
1280     if (arrayErrorCheck(identifierLocation, identifier, arrayType, variable))
1281         recover();
1282
1283     if (variable && symbol)
1284     {
1285         symbol->setId(variable->getUniqueId());
1286     }
1287
1288     return aggregate;
1289 }
1290
1291 TIntermAggregate* TParseContext::parseSingleInitDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& initLocation, TIntermTyped *initializer)
1292 {
1293     if (singleDeclarationErrorCheck(publicType, identifierLocation, identifier))
1294         recover();
1295
1296     TIntermNode* intermNode;
1297     if (!executeInitializer(identifierLocation, identifier, publicType, initializer, intermNode))
1298     {
1299         //
1300         // Build intermediate representation
1301         //
1302         return intermNode ? intermediate.makeAggregate(intermNode, initLocation) : NULL;
1303     }
1304     else
1305     {
1306         recover();
1307         return NULL;
1308     }
1309 }
1310
1311 TIntermAggregate* TParseContext::parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, TSymbol *identifierSymbol, const TSourceLoc& identifierLocation, const TString &identifier)
1312 {
1313     if (publicType.type == EbtInvariant && !identifierSymbol)
1314     {
1315         error(identifierLocation, "undeclared identifier declared as invariant", identifier.c_str());
1316         recover();
1317     }
1318
1319     TIntermSymbol* symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation);
1320     TIntermAggregate* intermAggregate = intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation);
1321
1322     if (structQualifierErrorCheck(identifierLocation, publicType))
1323         recover();
1324
1325     if (locationDeclaratorListCheck(identifierLocation, publicType))
1326         recover();
1327
1328     if (nonInitConstErrorCheck(identifierLocation, identifier, publicType, false))
1329         recover();
1330
1331     TVariable* variable = 0;
1332     if (nonInitErrorCheck(identifierLocation, identifier, publicType, variable))
1333         recover();
1334     if (symbol && variable)
1335         symbol->setId(variable->getUniqueId());
1336
1337     return intermAggregate;
1338 }
1339
1340 TIntermAggregate* TParseContext::parseArrayDeclarator(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& arrayLocation, TIntermNode *declaratorList, TIntermTyped *indexExpression)
1341 {
1342     if (structQualifierErrorCheck(identifierLocation, publicType))
1343         recover();
1344
1345     if (locationDeclaratorListCheck(identifierLocation, publicType))
1346         recover();
1347
1348     if (nonInitConstErrorCheck(identifierLocation, identifier, publicType, true))
1349         recover();
1350
1351     if (arrayTypeErrorCheck(arrayLocation, publicType) || arrayQualifierErrorCheck(arrayLocation, publicType))
1352     {
1353         recover();
1354     }
1355     else if (indexExpression)
1356     {
1357         int size;
1358         if (arraySizeErrorCheck(arrayLocation, indexExpression, size))
1359             recover();
1360         TPublicType arrayType(publicType);
1361         arrayType.setArray(true, size);
1362         TVariable* variable = NULL;
1363         if (arrayErrorCheck(arrayLocation, identifier, arrayType, variable))
1364             recover();
1365         TType type = TType(arrayType);
1366         type.setArraySize(size);
1367
1368         return intermediate.growAggregate(declaratorList, intermediate.addSymbol(variable ? variable->getUniqueId() : 0, identifier, type, identifierLocation), identifierLocation);
1369     }
1370     else
1371     {
1372         TPublicType arrayType(publicType);
1373         arrayType.setArray(true);
1374         TVariable* variable = NULL;
1375         if (arrayErrorCheck(arrayLocation, identifier, arrayType, variable))
1376             recover();
1377     }
1378
1379     return NULL;
1380 }
1381
1382 TIntermAggregate* TParseContext::parseInitDeclarator(TPublicType &publicType, TIntermAggregate *declaratorList, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& initLocation, TIntermTyped *initializer)
1383 {
1384     if (structQualifierErrorCheck(identifierLocation, publicType))
1385         recover();
1386
1387     if (locationDeclaratorListCheck(identifierLocation, publicType))
1388         recover();
1389
1390     TIntermNode* intermNode;
1391     if (!executeInitializer(identifierLocation, identifier, publicType, initializer, intermNode))
1392     {
1393         //
1394         // build the intermediate representation
1395         //
1396         if (intermNode)
1397         {
1398             return intermediate.growAggregate(declaratorList, intermNode, initLocation);
1399         }
1400         else
1401         {
1402             return declaratorList;
1403         }
1404     }
1405     else
1406     {
1407         recover();
1408         return NULL;
1409     }
1410 }
1411
1412 void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier)
1413 {
1414     if (typeQualifier.qualifier != EvqUniform)
1415     {
1416         error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "global layout must be uniform");
1417         recover();
1418         return;
1419     }
1420
1421     const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier;
1422     ASSERT(!layoutQualifier.isEmpty());
1423
1424     if (shaderVersion < 300)
1425     {
1426         error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 only", "layout");
1427         recover();
1428         return;
1429     }
1430
1431     if (layoutLocationErrorCheck(typeQualifier.line, typeQualifier.layoutQualifier))
1432     {
1433         recover();
1434         return;
1435     }
1436
1437     if (layoutQualifier.matrixPacking != EmpUnspecified)
1438     {
1439         defaultMatrixPacking = layoutQualifier.matrixPacking;
1440     }
1441
1442     if (layoutQualifier.blockStorage != EbsUnspecified)
1443     {
1444         defaultBlockStorage = layoutQualifier.blockStorage;
1445     }
1446 }
1447
1448 TFunction *TParseContext::addConstructorFunc(TPublicType publicType)
1449 {
1450     TOperator op = EOpNull;
1451     if (publicType.userDef)
1452     {
1453         op = EOpConstructStruct;
1454     }
1455     else
1456     {
1457         switch (publicType.type)
1458         {
1459           case EbtFloat:
1460             if (publicType.isMatrix())
1461             {
1462                 // TODO: non-square matrices
1463                 switch(publicType.getCols())
1464                 {
1465                   case 2: op = EOpConstructMat2;  break;
1466                   case 3: op = EOpConstructMat3;  break;
1467                   case 4: op = EOpConstructMat4;  break;
1468                 }
1469             }
1470             else
1471             {
1472                 switch(publicType.getNominalSize())
1473                 {
1474                   case 1: op = EOpConstructFloat; break;
1475                   case 2: op = EOpConstructVec2;  break;
1476                   case 3: op = EOpConstructVec3;  break;
1477                   case 4: op = EOpConstructVec4;  break;
1478                 }
1479             }
1480             break;
1481
1482           case EbtInt:
1483             switch(publicType.getNominalSize())
1484             {
1485               case 1: op = EOpConstructInt;   break;
1486               case 2: op = EOpConstructIVec2; break;
1487               case 3: op = EOpConstructIVec3; break;
1488               case 4: op = EOpConstructIVec4; break;
1489             }
1490             break;
1491
1492           case EbtUInt:
1493             switch(publicType.getNominalSize())
1494             {
1495               case 1: op = EOpConstructUInt;  break;
1496               case 2: op = EOpConstructUVec2; break;
1497               case 3: op = EOpConstructUVec3; break;
1498               case 4: op = EOpConstructUVec4; break;
1499             }
1500             break;
1501
1502           case EbtBool:
1503             switch(publicType.getNominalSize())
1504             {
1505                 case 1: op = EOpConstructBool;  break;
1506                 case 2: op = EOpConstructBVec2; break;
1507                 case 3: op = EOpConstructBVec3; break;
1508                 case 4: op = EOpConstructBVec4; break;
1509             }
1510             break;
1511
1512           default: break;
1513         }
1514
1515         if (op == EOpNull)
1516         {
1517             error(publicType.line, "cannot construct this type", getBasicString(publicType.type));
1518             recover();
1519             publicType.type = EbtFloat;
1520             op = EOpConstructFloat;
1521         }
1522     }
1523
1524     TString tempString;
1525     TType type(publicType);
1526     return new TFunction(&tempString, type, op);
1527 }
1528
1529 // This function is used to test for the correctness of the parameters passed to various constructor functions
1530 // and also convert them to the right datatype if it is allowed and required. 
1531 //
1532 // Returns 0 for an error or the constructed node (aggregate or typed) for no error.
1533 //
1534 TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, const TType *type, TOperator op, TFunction *fnCall, const TSourceLoc &line)
1535 {
1536     TIntermAggregate *aggregateArguments = arguments->getAsAggregate();
1537
1538     if (!aggregateArguments)
1539     {
1540         aggregateArguments = new TIntermAggregate;
1541         aggregateArguments->getSequence()->push_back(arguments);
1542     }
1543
1544     if (op == EOpConstructStruct)
1545     {
1546         const TFieldList &fields = type->getStruct()->fields();
1547         TIntermSequence *args = aggregateArguments->getSequence();
1548
1549         for (size_t i = 0; i < fields.size(); i++)
1550         {
1551             if ((*args)[i]->getAsTyped()->getType() != *fields[i]->type())
1552             {
1553                 error(line, "Structure constructor arguments do not match structure fields", "Error");
1554                 recover();
1555
1556                 return 0;
1557             }
1558         }
1559     }
1560
1561     // Turn the argument list itself into a constructor
1562     TIntermTyped *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
1563     TIntermTyped *constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type);
1564     if (constConstructor)
1565     {
1566         return constConstructor;
1567     }
1568
1569     return constructor;
1570 }
1571
1572 TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, const TType& type)
1573 {
1574     bool canBeFolded = areAllChildConst(aggrNode);
1575     aggrNode->setType(type);
1576     if (canBeFolded) {
1577         bool returnVal = false;
1578         ConstantUnion* unionArray = new ConstantUnion[type.getObjectSize()];
1579         if (aggrNode->getSequence()->size() == 1)  {
1580             returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type, true);
1581         }
1582         else {
1583             returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type);
1584         }
1585         if (returnVal)
1586             return 0;
1587
1588         return intermediate.addConstantUnion(unionArray, type, aggrNode->getLine());
1589     }
1590
1591     return 0;
1592 }
1593
1594 //
1595 // This function returns the tree representation for the vector field(s) being accessed from contant vector.
1596 // If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a contant node is
1597 // returned, else an aggregate node is returned (for v.xy). The input to this function could either be the symbol
1598 // node or it could be the intermediate tree representation of accessing fields in a constant structure or column of 
1599 // a constant matrix.
1600 //
1601 TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, const TSourceLoc& line)
1602 {
1603     TIntermTyped* typedNode;
1604     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
1605
1606     ConstantUnion *unionArray;
1607     if (tempConstantNode) {
1608         unionArray = tempConstantNode->getUnionArrayPointer();
1609
1610         if (!unionArray) {
1611             return node;
1612         }
1613     } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
1614         error(line, "Cannot offset into the vector", "Error");
1615         recover();
1616
1617         return 0;
1618     }
1619
1620     ConstantUnion* constArray = new ConstantUnion[fields.num];
1621
1622     for (int i = 0; i < fields.num; i++) {
1623         if (fields.offsets[i] >= node->getType().getNominalSize()) {
1624             std::stringstream extraInfoStream;
1625             extraInfoStream << "vector field selection out of range '" << fields.offsets[i] << "'";
1626             std::string extraInfo = extraInfoStream.str();
1627             error(line, "", "[", extraInfo.c_str());
1628             recover();
1629             fields.offsets[i] = 0;
1630         }
1631         
1632         constArray[i] = unionArray[fields.offsets[i]];
1633
1634     } 
1635     typedNode = intermediate.addConstantUnion(constArray, node->getType(), line);
1636     return typedNode;
1637 }
1638
1639 //
1640 // This function returns the column being accessed from a constant matrix. The values are retrieved from
1641 // the symbol table and parse-tree is built for a vector (each column of a matrix is a vector). The input 
1642 // to the function could either be a symbol node (m[0] where m is a constant matrix)that represents a 
1643 // constant matrix or it could be the tree representation of the constant matrix (s.m1[0] where s is a constant structure)
1644 //
1645 TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, const TSourceLoc& line)
1646 {
1647     TIntermTyped* typedNode;
1648     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
1649
1650     if (index >= node->getType().getCols()) {
1651         std::stringstream extraInfoStream;
1652         extraInfoStream << "matrix field selection out of range '" << index << "'";
1653         std::string extraInfo = extraInfoStream.str();
1654         error(line, "", "[", extraInfo.c_str());
1655         recover();
1656         index = 0;
1657     }
1658
1659     if (tempConstantNode) {
1660          ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
1661          int size = tempConstantNode->getType().getCols();
1662          typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line);
1663     } else {
1664         error(line, "Cannot offset into the matrix", "Error");
1665         recover();
1666
1667         return 0;
1668     }
1669
1670     return typedNode;
1671 }
1672
1673
1674 //
1675 // This function returns an element of an array accessed from a constant array. The values are retrieved from
1676 // the symbol table and parse-tree is built for the type of the element. The input 
1677 // to the function could either be a symbol node (a[0] where a is a constant array)that represents a 
1678 // constant array or it could be the tree representation of the constant array (s.a1[0] where s is a constant structure)
1679 //
1680 TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc& line)
1681 {
1682     TIntermTyped* typedNode;
1683     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
1684     TType arrayElementType = node->getType();
1685     arrayElementType.clearArrayness();
1686
1687     if (index >= node->getType().getArraySize()) {
1688         std::stringstream extraInfoStream;
1689         extraInfoStream << "array field selection out of range '" << index << "'";
1690         std::string extraInfo = extraInfoStream.str();
1691         error(line, "", "[", extraInfo.c_str());
1692         recover();
1693         index = 0;
1694     }
1695
1696     if (tempConstantNode) {
1697         size_t arrayElementSize = arrayElementType.getObjectSize();
1698         ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
1699         typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line);
1700     } else {
1701         error(line, "Cannot offset into the array", "Error");
1702         recover();
1703
1704         return 0;
1705     }
1706
1707     return typedNode;
1708 }
1709
1710
1711 //
1712 // This function returns the value of a particular field inside a constant structure from the symbol table. 
1713 // If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr
1714 // function and returns the parse-tree with the values of the embedded/nested struct.
1715 //
1716 TIntermTyped* TParseContext::addConstStruct(const TString &identifier, TIntermTyped *node, const TSourceLoc& line)
1717 {
1718     const TFieldList& fields = node->getType().getStruct()->fields();
1719     size_t instanceSize = 0;
1720
1721     for (size_t index = 0; index < fields.size(); ++index) {
1722         if (fields[index]->name() == identifier) {
1723             break;
1724         } else {
1725             instanceSize += fields[index]->type()->getObjectSize();
1726         }
1727     }
1728
1729     TIntermTyped *typedNode;
1730     TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
1731     if (tempConstantNode) {
1732          ConstantUnion* constArray = tempConstantNode->getUnionArrayPointer();
1733
1734          typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function
1735     } else {
1736         error(line, "Cannot offset into the structure", "Error");
1737         recover();
1738
1739         return 0;
1740     }
1741
1742     return typedNode;
1743 }
1744
1745 //
1746 // Interface/uniform blocks
1747 //
1748 TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TFieldList* fieldList, 
1749                                                    const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine)
1750 {
1751     if (reservedErrorCheck(nameLine, blockName))
1752         recover();
1753
1754     if (typeQualifier.qualifier != EvqUniform)
1755     {
1756         error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "interface blocks must be uniform");
1757         recover();
1758     }
1759
1760     TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier;
1761     if (layoutLocationErrorCheck(typeQualifier.line, blockLayoutQualifier))
1762     {
1763         recover();
1764     }
1765
1766     if (blockLayoutQualifier.matrixPacking == EmpUnspecified)
1767     {
1768         blockLayoutQualifier.matrixPacking = defaultMatrixPacking;
1769     }
1770
1771     if (blockLayoutQualifier.blockStorage == EbsUnspecified)
1772     {
1773         blockLayoutQualifier.blockStorage = defaultBlockStorage;
1774     }
1775
1776     TSymbol* blockNameSymbol = new TInterfaceBlockName(&blockName);
1777     if (!symbolTable.declare(blockNameSymbol)) {
1778         error(nameLine, "redefinition", blockName.c_str(), "interface block name");
1779         recover();
1780     }
1781
1782     // check for sampler types and apply layout qualifiers
1783     for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex) {
1784         TField* field = (*fieldList)[memberIndex];
1785         TType* fieldType = field->type();
1786         if (IsSampler(fieldType->getBasicType())) {
1787             error(field->line(), "unsupported type", fieldType->getBasicString(), "sampler types are not allowed in interface blocks");
1788             recover();
1789         }
1790
1791         const TQualifier qualifier = fieldType->getQualifier();
1792         switch (qualifier)
1793         {
1794           case EvqGlobal:
1795           case EvqUniform:
1796             break;
1797           default:
1798             error(field->line(), "invalid qualifier on interface block member", getQualifierString(qualifier));
1799             recover();
1800             break;
1801         }
1802
1803         // check layout qualifiers
1804         TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier();
1805         if (layoutLocationErrorCheck(field->line(), fieldLayoutQualifier))
1806         {
1807             recover();
1808         }
1809
1810         if (fieldLayoutQualifier.blockStorage != EbsUnspecified)
1811         {
1812             error(field->line(), "invalid layout qualifier:", getBlockStorageString(fieldLayoutQualifier.blockStorage), "cannot be used here");
1813             recover();
1814         }
1815
1816         if (fieldLayoutQualifier.matrixPacking == EmpUnspecified)
1817         {
1818             fieldLayoutQualifier.matrixPacking = blockLayoutQualifier.matrixPacking;
1819         }
1820         else if (!fieldType->isMatrix())
1821         {
1822             error(field->line(), "invalid layout qualifier:", getMatrixPackingString(fieldLayoutQualifier.matrixPacking), "can only be used on matrix types");
1823             recover();
1824         }
1825
1826         fieldType->setLayoutQualifier(fieldLayoutQualifier);
1827     }
1828
1829     // add array index
1830     int arraySize = 0;
1831     if (arrayIndex != NULL)
1832     {
1833         if (arraySizeErrorCheck(arrayIndexLine, arrayIndex, arraySize))
1834             recover();
1835     }
1836
1837     TInterfaceBlock* interfaceBlock = new TInterfaceBlock(&blockName, fieldList, instanceName, arraySize, blockLayoutQualifier);
1838     TType interfaceBlockType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier, arraySize);
1839
1840     TString symbolName = "";
1841     int symbolId = 0;
1842
1843     if (!instanceName)
1844     {
1845         // define symbols for the members of the interface block
1846         for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
1847         {
1848             TField* field = (*fieldList)[memberIndex];
1849             TType* fieldType = field->type();
1850
1851             // set parent pointer of the field variable
1852             fieldType->setInterfaceBlock(interfaceBlock);
1853
1854             TVariable* fieldVariable = new TVariable(&field->name(), *fieldType);
1855             fieldVariable->setQualifier(typeQualifier.qualifier);
1856
1857             if (!symbolTable.declare(fieldVariable)) {
1858                 error(field->line(), "redefinition", field->name().c_str(), "interface block member name");
1859                 recover();
1860             }
1861         }
1862     }
1863     else
1864     {
1865         // add a symbol for this interface block
1866         TVariable* instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false);
1867         instanceTypeDef->setQualifier(typeQualifier.qualifier);
1868
1869         if (!symbolTable.declare(instanceTypeDef)) {
1870             error(instanceLine, "redefinition", instanceName->c_str(), "interface block instance name");
1871             recover();
1872         }
1873
1874         symbolId = instanceTypeDef->getUniqueId();
1875         symbolName = instanceTypeDef->getName();
1876     }
1877
1878     TIntermAggregate *aggregate = intermediate.makeAggregate(intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line), nameLine);
1879     aggregate->setOp(EOpDeclaration);
1880
1881     exitStructDeclaration();
1882     return aggregate;
1883 }
1884
1885 bool TParseContext::enterStructDeclaration(const TSourceLoc& line, const TString& identifier)
1886 {
1887     ++structNestingLevel;
1888
1889     // Embedded structure definitions are not supported per GLSL ES spec.
1890     // They aren't allowed in GLSL either, but we need to detect this here
1891     // so we don't rely on the GLSL compiler to catch it.
1892     if (structNestingLevel > 1) {
1893         error(line, "", "Embedded struct definitions are not allowed");
1894         return true;
1895     }
1896
1897     return false;
1898 }
1899
1900 void TParseContext::exitStructDeclaration()
1901 {
1902     --structNestingLevel;
1903 }
1904
1905 namespace {
1906
1907 const int kWebGLMaxStructNesting = 4;
1908
1909 }  // namespace
1910
1911 bool TParseContext::structNestingErrorCheck(const TSourceLoc& line, const TField& field)
1912 {
1913     if (!IsWebGLBasedSpec(shaderSpec)) {
1914         return false;
1915     }
1916
1917     if (field.type()->getBasicType() != EbtStruct) {
1918         return false;
1919     }
1920
1921     // We're already inside a structure definition at this point, so add
1922     // one to the field's struct nesting.
1923     if (1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting) {
1924         std::stringstream reasonStream;
1925         reasonStream << "Reference of struct type "
1926                      << field.type()->getStruct()->name().c_str()
1927                      << " exceeds maximum allowed nesting level of "
1928                      << kWebGLMaxStructNesting;
1929         std::string reason = reasonStream.str();
1930         error(line, reason.c_str(), field.name().c_str(), "");
1931         return true;
1932     }
1933
1934     return false;
1935 }
1936
1937 //
1938 // Parse an array index expression
1939 //
1940 TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression)
1941 {
1942     TIntermTyped *indexedExpression = NULL;
1943
1944     if (!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector())
1945     {
1946         if (baseExpression->getAsSymbolNode())
1947         {
1948             error(location, " left of '[' is not of type array, matrix, or vector ", baseExpression->getAsSymbolNode()->getSymbol().c_str());
1949         }
1950         else
1951         {
1952             error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
1953         }
1954         recover();
1955     }
1956
1957     if (indexExpression->getQualifier() == EvqConst)
1958     {
1959         int index = indexExpression->getAsConstantUnion()->getIConst(0);
1960         if (index < 0)
1961         {
1962             std::stringstream infoStream;
1963             infoStream << index;
1964             std::string info = infoStream.str();
1965             error(location, "negative index", info.c_str());
1966             recover();
1967             index = 0;
1968         }
1969         if (baseExpression->getType().getQualifier() == EvqConst)
1970         {
1971             if (baseExpression->isArray())
1972             {
1973                 // constant folding for arrays
1974                 indexedExpression = addConstArrayNode(index, baseExpression, location);
1975             }
1976             else if (baseExpression->isVector())
1977             {
1978                 // constant folding for vectors
1979                 TVectorFields fields;
1980                 fields.num = 1;
1981                 fields.offsets[0] = index; // need to do it this way because v.xy sends fields integer array
1982                 indexedExpression = addConstVectorNode(fields, baseExpression, location);
1983             }
1984             else if (baseExpression->isMatrix())
1985             {
1986                 // constant folding for matrices
1987                 indexedExpression = addConstMatrixNode(index, baseExpression, location);
1988             }
1989         }
1990         else
1991         {
1992             if (baseExpression->isArray())
1993             {
1994                 if (index >= baseExpression->getType().getArraySize())
1995                 {
1996                     std::stringstream extraInfoStream;
1997                     extraInfoStream << "array index out of range '" << index << "'";
1998                     std::string extraInfo = extraInfoStream.str();
1999                     error(location, "", "[", extraInfo.c_str());
2000                     recover();
2001                     index = baseExpression->getType().getArraySize() - 1;
2002                 }
2003                 else if (baseExpression->getQualifier() == EvqFragData && index > 0 && !isExtensionEnabled("GL_EXT_draw_buffers"))
2004                 {
2005                     error(location, "", "[", "array indexes for gl_FragData must be zero when GL_EXT_draw_buffers is disabled");
2006                     recover();
2007                     index = 0;
2008                 }
2009             }
2010             else if ((baseExpression->isVector() || baseExpression->isMatrix()) && baseExpression->getType().getNominalSize() <= index)
2011             {
2012                 std::stringstream extraInfoStream;
2013                 extraInfoStream << "field selection out of range '" << index << "'";
2014                 std::string extraInfo = extraInfoStream.str();
2015                 error(location, "", "[", extraInfo.c_str());
2016                 recover();
2017                 index = baseExpression->getType().getNominalSize() - 1;
2018             }
2019
2020             indexExpression->getAsConstantUnion()->getUnionArrayPointer()->setIConst(index);
2021             indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location);
2022         }
2023     }
2024     else
2025     {
2026         if (baseExpression->isInterfaceBlock())
2027         {
2028             error(location, "", "[", "array indexes for interface blocks arrays must be constant integral expressions");
2029             recover();
2030         }
2031         else if (baseExpression->getQualifier() == EvqFragmentOut)
2032         {
2033             error(location, "", "[", "array indexes for fragment outputs must be constant integral expressions");
2034             recover();
2035         }
2036
2037         indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location);
2038     }
2039
2040     if (indexedExpression == 0)
2041     {
2042         ConstantUnion *unionArray = new ConstantUnion[1];
2043         unionArray->setFConst(0.0f);
2044         indexedExpression = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), location);
2045     }
2046     else if (baseExpression->isArray())
2047     {
2048         const TType &baseType = baseExpression->getType();
2049         if (baseType.getStruct())
2050         {
2051             TType copyOfType(baseType.getStruct());
2052             indexedExpression->setType(copyOfType);
2053         }
2054         else if (baseType.isInterfaceBlock())
2055         {
2056             TType copyOfType(baseType.getInterfaceBlock(), baseType.getQualifier(), baseType.getLayoutQualifier(), 0);
2057             indexedExpression->setType(copyOfType);
2058         }
2059         else
2060         {
2061             indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary, baseExpression->getNominalSize(), baseExpression->getSecondarySize()));
2062         }
2063
2064         if (baseExpression->getType().getQualifier() == EvqConst)
2065         {
2066             indexedExpression->getTypePointer()->setQualifier(EvqConst);
2067         }
2068     }
2069     else if (baseExpression->isMatrix())
2070     {
2071         TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary;
2072         indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier, baseExpression->getRows()));
2073     }
2074     else if (baseExpression->isVector())
2075     {
2076         TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary;
2077         indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier));
2078     }
2079     else
2080     {
2081         indexedExpression->setType(baseExpression->getType());
2082     }
2083
2084     return indexedExpression;
2085 }
2086
2087 TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc& dotLocation, const TString &fieldString, const TSourceLoc& fieldLocation)
2088 {
2089     TIntermTyped *indexedExpression = NULL;
2090
2091     if (baseExpression->isArray())
2092     {
2093         error(fieldLocation, "cannot apply dot operator to an array", ".");
2094         recover();
2095     }
2096
2097     if (baseExpression->isVector())
2098     {
2099         TVectorFields fields;
2100         if (!parseVectorFields(fieldString, baseExpression->getNominalSize(), fields, fieldLocation))
2101         {
2102             fields.num = 1;
2103             fields.offsets[0] = 0;
2104             recover();
2105         }
2106
2107         if (baseExpression->getType().getQualifier() == EvqConst)
2108         {
2109             // constant folding for vector fields
2110             indexedExpression = addConstVectorNode(fields, baseExpression, fieldLocation);
2111             if (indexedExpression == 0)
2112             {
2113                 recover();
2114                 indexedExpression = baseExpression;
2115             }
2116             else
2117             {
2118                 indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqConst, (int) (fieldString).size()));
2119             }
2120         }
2121         else
2122         {
2123             TString vectorString = fieldString;
2124             TIntermTyped* index = intermediate.addSwizzle(fields, fieldLocation);
2125             indexedExpression = intermediate.addIndex(EOpVectorSwizzle, baseExpression, index, dotLocation);
2126             indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary, (int) vectorString.size()));
2127         }
2128     }
2129     else if (baseExpression->isMatrix())
2130     {
2131         TMatrixFields fields;
2132         if (!parseMatrixFields(fieldString, baseExpression->getCols(), baseExpression->getRows(), fields, fieldLocation))
2133         {
2134             fields.wholeRow = false;
2135             fields.wholeCol = false;
2136             fields.row = 0;
2137             fields.col = 0;
2138             recover();
2139         }
2140
2141         if (fields.wholeRow || fields.wholeCol)
2142         {
2143             error(dotLocation, " non-scalar fields not implemented yet", ".");
2144             recover();
2145             ConstantUnion *unionArray = new ConstantUnion[1];
2146             unionArray->setIConst(0);
2147             TIntermTyped* index = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), fieldLocation);
2148             indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, index, dotLocation);
2149             indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),EvqTemporary, baseExpression->getCols(), baseExpression->getRows()));
2150         }
2151         else
2152         {
2153             ConstantUnion *unionArray = new ConstantUnion[1];
2154             unionArray->setIConst(fields.col * baseExpression->getRows() + fields.row);
2155             TIntermTyped* index = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), fieldLocation);
2156             indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, index, dotLocation);
2157             indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision()));
2158         }
2159     }
2160     else if (baseExpression->getBasicType() == EbtStruct)
2161     {
2162         bool fieldFound = false;
2163         const TFieldList& fields = baseExpression->getType().getStruct()->fields();
2164         if (fields.empty())
2165         {
2166             error(dotLocation, "structure has no fields", "Internal Error");
2167             recover();
2168             indexedExpression = baseExpression;
2169         }
2170         else
2171         {
2172             unsigned int i;
2173             for (i = 0; i < fields.size(); ++i)
2174             {
2175                 if (fields[i]->name() == fieldString)
2176                 {
2177                     fieldFound = true;
2178                     break;
2179                 }
2180             }
2181             if (fieldFound)
2182             {
2183                 if (baseExpression->getType().getQualifier() == EvqConst)
2184                 {
2185                     indexedExpression = addConstStruct(fieldString, baseExpression, dotLocation);
2186                     if (indexedExpression == 0)
2187                     {
2188                         recover();
2189                         indexedExpression = baseExpression;
2190                     }
2191                     else
2192                     {
2193                         indexedExpression->setType(*fields[i]->type());
2194                         // change the qualifier of the return type, not of the structure field
2195                         // as the structure definition is shared between various structures.
2196                         indexedExpression->getTypePointer()->setQualifier(EvqConst);
2197                     }
2198                 }
2199                 else
2200                 {
2201                     ConstantUnion *unionArray = new ConstantUnion[1];
2202                     unionArray->setIConst(i);
2203                     TIntermTyped* index = intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation);
2204                     indexedExpression = intermediate.addIndex(EOpIndexDirectStruct, baseExpression, index, dotLocation);
2205                     indexedExpression->setType(*fields[i]->type());
2206                 }
2207             }
2208             else
2209             {
2210                 error(dotLocation, " no such field in structure", fieldString.c_str());
2211                 recover();
2212                 indexedExpression = baseExpression;
2213             }
2214         }
2215     }
2216     else if (baseExpression->isInterfaceBlock())
2217     {
2218         bool fieldFound = false;
2219         const TFieldList& fields = baseExpression->getType().getInterfaceBlock()->fields();
2220         if (fields.empty())
2221         {
2222             error(dotLocation, "interface block has no fields", "Internal Error");
2223             recover();
2224             indexedExpression = baseExpression;
2225         }
2226         else
2227         {
2228             unsigned int i;
2229             for (i = 0; i < fields.size(); ++i)
2230             {
2231                 if (fields[i]->name() == fieldString)
2232                 {
2233                     fieldFound = true;
2234                     break;
2235                 }
2236             }
2237             if (fieldFound)
2238             {
2239                 ConstantUnion *unionArray = new ConstantUnion[1];
2240                 unionArray->setIConst(i);
2241                 TIntermTyped* index = intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation);
2242                 indexedExpression = intermediate.addIndex(EOpIndexDirectInterfaceBlock, baseExpression, index, dotLocation);
2243                 indexedExpression->setType(*fields[i]->type());
2244             }
2245             else
2246             {
2247                 error(dotLocation, " no such field in interface block", fieldString.c_str());
2248                 recover();
2249                 indexedExpression = baseExpression;
2250             }
2251         }
2252     }
2253     else
2254     {
2255         if (shaderVersion < 300)
2256         {
2257             error(dotLocation, " field selection requires structure, vector, or matrix on left hand side", fieldString.c_str());
2258         }
2259         else
2260         {
2261             error(dotLocation, " field selection requires structure, vector, matrix, or interface block on left hand side", fieldString.c_str());
2262         }
2263         recover();
2264         indexedExpression = baseExpression;
2265     }
2266
2267     return indexedExpression;
2268 }
2269
2270 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine)
2271 {
2272     TLayoutQualifier qualifier;
2273
2274     qualifier.location = -1;
2275     qualifier.matrixPacking = EmpUnspecified;
2276     qualifier.blockStorage = EbsUnspecified;
2277
2278     if (qualifierType == "shared")
2279     {
2280         qualifier.blockStorage = EbsShared;
2281     }
2282     else if (qualifierType == "packed")
2283     {
2284         qualifier.blockStorage = EbsPacked;
2285     }
2286     else if (qualifierType == "std140")
2287     {
2288         qualifier.blockStorage = EbsStd140;
2289     }
2290     else if (qualifierType == "row_major")
2291     {
2292         qualifier.matrixPacking = EmpRowMajor;
2293     }
2294     else if (qualifierType == "column_major")
2295     {
2296         qualifier.matrixPacking = EmpColumnMajor;
2297     }
2298     else if (qualifierType == "location")
2299     {
2300         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "location requires an argument");
2301         recover();
2302     }
2303     else
2304     {
2305         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
2306         recover();
2307     }
2308
2309     return qualifier;
2310 }
2311
2312 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine)
2313 {
2314     TLayoutQualifier qualifier;
2315
2316     qualifier.location = -1;
2317     qualifier.matrixPacking = EmpUnspecified;
2318     qualifier.blockStorage = EbsUnspecified;
2319
2320     if (qualifierType != "location")
2321     {
2322         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "only location may have arguments");
2323         recover();
2324     }
2325     else
2326     {
2327         // must check that location is non-negative
2328         if (intValue < 0)
2329         {
2330             error(intValueLine, "out of range:", intValueString.c_str(), "location must be non-negative");
2331             recover();
2332         }
2333         else
2334         {
2335             qualifier.location = intValue;
2336         }
2337     }
2338
2339     return qualifier;
2340 }
2341
2342 TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier)
2343 {
2344     TLayoutQualifier joinedQualifier = leftQualifier;
2345
2346     if (rightQualifier.location != -1)
2347     {
2348         joinedQualifier.location = rightQualifier.location;
2349     }
2350     if (rightQualifier.matrixPacking != EmpUnspecified)
2351     {
2352         joinedQualifier.matrixPacking = rightQualifier.matrixPacking;
2353     }
2354     if (rightQualifier.blockStorage != EbsUnspecified)
2355     {
2356         joinedQualifier.blockStorage = rightQualifier.blockStorage;
2357     }
2358
2359     return joinedQualifier;
2360 }
2361
2362 TPublicType TParseContext::joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier,
2363                                                        const TSourceLoc &storageLoc, TQualifier storageQualifier)
2364 {
2365     TQualifier mergedQualifier = EvqSmoothIn;
2366
2367     if (storageQualifier == EvqFragmentIn) {
2368         if (interpolationQualifier == EvqSmooth)
2369             mergedQualifier = EvqSmoothIn;
2370         else if (interpolationQualifier == EvqFlat)
2371             mergedQualifier = EvqFlatIn;
2372         else UNREACHABLE();
2373     }
2374     else if (storageQualifier == EvqCentroidIn) {
2375         if (interpolationQualifier == EvqSmooth)
2376             mergedQualifier = EvqCentroidIn;
2377         else if (interpolationQualifier == EvqFlat)
2378             mergedQualifier = EvqFlatIn;
2379         else UNREACHABLE();
2380     }
2381     else if (storageQualifier == EvqVertexOut) {
2382         if (interpolationQualifier == EvqSmooth)
2383             mergedQualifier = EvqSmoothOut;
2384         else if (interpolationQualifier == EvqFlat)
2385             mergedQualifier = EvqFlatOut;
2386         else UNREACHABLE();
2387     }
2388     else if (storageQualifier == EvqCentroidOut) {
2389         if (interpolationQualifier == EvqSmooth)
2390             mergedQualifier = EvqCentroidOut;
2391         else if (interpolationQualifier == EvqFlat)
2392             mergedQualifier = EvqFlatOut;
2393         else UNREACHABLE();
2394     }
2395     else {
2396         error(interpolationLoc, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getInterpolationString(interpolationQualifier));
2397         recover();
2398
2399         mergedQualifier = storageQualifier;
2400     }
2401
2402     TPublicType type;
2403     type.setBasic(EbtVoid, mergedQualifier, storageLoc);
2404     return type;
2405 }
2406
2407 TFieldList *TParseContext::addStructDeclaratorList(const TPublicType& typeSpecifier, TFieldList *fieldList)
2408 {
2409     if (voidErrorCheck(typeSpecifier.line, (*fieldList)[0]->name(), typeSpecifier)) {
2410         recover();
2411     }
2412
2413     for (unsigned int i = 0; i < fieldList->size(); ++i) {
2414         //
2415         // Careful not to replace already known aspects of type, like array-ness
2416         //
2417         TType* type = (*fieldList)[i]->type();
2418         type->setBasicType(typeSpecifier.type);
2419         type->setPrimarySize(typeSpecifier.primarySize);
2420         type->setSecondarySize(typeSpecifier.secondarySize);
2421         type->setPrecision(typeSpecifier.precision);
2422         type->setQualifier(typeSpecifier.qualifier);
2423         type->setLayoutQualifier(typeSpecifier.layoutQualifier);
2424
2425         // don't allow arrays of arrays
2426         if (type->isArray()) {
2427             if (arrayTypeErrorCheck(typeSpecifier.line, typeSpecifier))
2428                 recover();
2429         }
2430         if (typeSpecifier.array)
2431             type->setArraySize(typeSpecifier.arraySize);
2432         if (typeSpecifier.userDef) {
2433             type->setStruct(typeSpecifier.userDef->getStruct());
2434         }
2435
2436         if (structNestingErrorCheck(typeSpecifier.line, *(*fieldList)[i])) {
2437             recover();
2438         }
2439     }
2440
2441     return fieldList;
2442 }
2443
2444 TPublicType TParseContext::addStructure(const TSourceLoc& structLine, const TSourceLoc& nameLine, const TString *structName, TFieldList* fieldList)
2445 {
2446     TStructure* structure = new TStructure(structName, fieldList);
2447     TType* structureType = new TType(structure);
2448
2449     structure->setUniqueId(TSymbolTable::nextUniqueId());
2450
2451     if (!structName->empty())
2452     {
2453         if (reservedErrorCheck(nameLine, *structName))
2454         {
2455             recover();
2456         }
2457         TVariable* userTypeDef = new TVariable(structName, *structureType, true);
2458         if (!symbolTable.declare(userTypeDef)) {
2459             error(nameLine, "redefinition", structName->c_str(), "struct");
2460             recover();
2461         }
2462     }
2463
2464     // ensure we do not specify any storage qualifiers on the struct members
2465     for (unsigned int typeListIndex = 0; typeListIndex < fieldList->size(); typeListIndex++)
2466     {
2467         const TField &field = *(*fieldList)[typeListIndex];
2468         const TQualifier qualifier = field.type()->getQualifier();
2469         switch (qualifier)
2470         {
2471           case EvqGlobal:
2472           case EvqTemporary:
2473             break;
2474           default:
2475             error(field.line(), "invalid qualifier on struct member", getQualifierString(qualifier));
2476             recover();
2477             break;
2478         }
2479     }
2480
2481     TPublicType publicType;
2482     publicType.setBasic(EbtStruct, EvqTemporary, structLine);
2483     publicType.userDef = structureType;
2484     exitStructDeclaration();
2485
2486     return publicType;
2487 }
2488
2489 //
2490 // Parse an array of strings using yyparse.
2491 //
2492 // Returns 0 for success.
2493 //
2494 int PaParseStrings(size_t count, const char* const string[], const int length[],
2495                    TParseContext* context) {
2496     if ((count == 0) || (string == NULL))
2497         return 1;
2498
2499     if (glslang_initialize(context))
2500         return 1;
2501
2502     int error = glslang_scan(count, string, length, context);
2503     if (!error)
2504         error = glslang_parse(context);
2505
2506     glslang_finalize(context);
2507
2508     return (error == 0) && (context->numErrors() == 0) ? 0 : 1;
2509 }
2510
2511
2512