Update To 11.40.268.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, bool stdgl)
1008 {
1009     pp::SourceLocation srcLoc;
1010     srcLoc.file = loc.first_file;
1011     srcLoc.line = loc.first_line;
1012     directiveHandler.handlePragma(srcLoc, name, value, stdgl);
1013 }
1014
1015 /////////////////////////////////////////////////////////////////////////////////
1016 //
1017 // Non-Errors.
1018 //
1019 /////////////////////////////////////////////////////////////////////////////////
1020
1021 const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location,
1022                                                  const TString *name,
1023                                                  const TSymbol *symbol)
1024 {
1025     const TVariable *variable = NULL;
1026
1027     if (!symbol)
1028     {
1029         error(location, "undeclared identifier", name->c_str());
1030         recover();
1031     }
1032     else if (!symbol->isVariable())
1033     {
1034         error(location, "variable expected", name->c_str());
1035         recover();
1036     }
1037     else
1038     {
1039         variable = static_cast<const TVariable*>(symbol);
1040
1041         if (symbolTable.findBuiltIn(variable->getName(), shaderVersion) &&
1042             !variable->getExtension().empty() &&
1043             extensionErrorCheck(location, variable->getExtension()))
1044         {
1045             recover();
1046         }
1047     }
1048
1049     if (!variable)
1050     {
1051         TType type(EbtFloat, EbpUndefined);
1052         TVariable *fakeVariable = new TVariable(name, type);
1053         symbolTable.declare(fakeVariable);
1054         variable = fakeVariable;
1055     }
1056
1057     return variable;
1058 }
1059
1060 //
1061 // Look up a function name in the symbol table, and make sure it is a function.
1062 //
1063 // Return the function symbol if found, otherwise 0.
1064 //
1065 const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction* call, int shaderVersion, bool *builtIn)
1066 {
1067     // First find by unmangled name to check whether the function name has been
1068     // hidden by a variable name or struct typename.
1069     // If a function is found, check for one with a matching argument list.
1070     const TSymbol* symbol = symbolTable.find(call->getName(), shaderVersion, builtIn);
1071     if (symbol == 0 || symbol->isFunction()) {
1072         symbol = symbolTable.find(call->getMangledName(), shaderVersion, builtIn);
1073     }
1074
1075     if (symbol == 0) {
1076         error(line, "no matching overloaded function found", call->getName().c_str());
1077         return 0;
1078     }
1079
1080     if (!symbol->isFunction()) {
1081         error(line, "function name expected", call->getName().c_str());
1082         return 0;
1083     }
1084
1085     return static_cast<const TFunction*>(symbol);
1086 }
1087
1088 //
1089 // Initializers show up in several places in the grammar.  Have one set of
1090 // code to handle them here.
1091 //
1092 // Returns true on error, false if no error
1093 //
1094 bool TParseContext::executeInitializer(const TSourceLoc& line, const TString& identifier, TPublicType& pType, 
1095                                        TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable)
1096 {
1097     TType type = TType(pType);
1098
1099     if (variable == 0) {
1100         if (reservedErrorCheck(line, identifier))
1101             return true;
1102
1103         if (voidErrorCheck(line, identifier, pType))
1104             return true;
1105
1106         //
1107         // add variable to symbol table
1108         //
1109         variable = new TVariable(&identifier, type);
1110         if (! symbolTable.declare(variable)) {
1111             error(line, "redefinition", variable->getName().c_str());
1112             return true;
1113             // don't delete variable, it's used by error recovery, and the pool 
1114             // pop will take care of the memory
1115         }
1116     }
1117
1118     //
1119     // identifier must be of type constant, a global, or a temporary
1120     //
1121     TQualifier qualifier = variable->getType().getQualifier();
1122     if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) {
1123         error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString());
1124         return true;
1125     }
1126     //
1127     // test for and propagate constant
1128     //
1129
1130     if (qualifier == EvqConst) {
1131         if (qualifier != initializer->getType().getQualifier()) {
1132             std::stringstream extraInfoStream;
1133             extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
1134             std::string extraInfo = extraInfoStream.str();
1135             error(line, " assigning non-constant to", "=", extraInfo.c_str());
1136             variable->getType().setQualifier(EvqTemporary);
1137             return true;
1138         }
1139         if (type != initializer->getType()) {
1140             error(line, " non-matching types for const initializer ", 
1141                 variable->getType().getQualifierString());
1142             variable->getType().setQualifier(EvqTemporary);
1143             return true;
1144         }
1145         if (initializer->getAsConstantUnion()) { 
1146             variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
1147         } else if (initializer->getAsSymbolNode()) {
1148             const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), 0);
1149             const TVariable* tVar = static_cast<const TVariable*>(symbol);
1150
1151             ConstantUnion* constArray = tVar->getConstPointer();
1152             variable->shareConstPointer(constArray);
1153         } else {
1154             std::stringstream extraInfoStream;
1155             extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
1156             std::string extraInfo = extraInfoStream.str();
1157             error(line, " cannot assign to", "=", extraInfo.c_str());
1158             variable->getType().setQualifier(EvqTemporary);
1159             return true;
1160         }
1161     }
1162  
1163     if (qualifier != EvqConst) {
1164         TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
1165         intermNode = intermediate.addAssign(EOpInitialize, intermSymbol, initializer, line);
1166         if (intermNode == 0) {
1167             assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
1168             return true;
1169         }
1170     } else 
1171         intermNode = 0;
1172
1173     return false;
1174 }
1175
1176 bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
1177 {
1178     ASSERT(aggrNode != NULL);
1179     if (!aggrNode->isConstructor())
1180         return false;
1181
1182     bool allConstant = true;
1183
1184     // check if all the child nodes are constants so that they can be inserted into 
1185     // the parent node
1186     TIntermSequence *sequence = aggrNode->getSequence() ;
1187     for (TIntermSequence::iterator p = sequence->begin(); p != sequence->end(); ++p) {
1188         if (!(*p)->getAsTyped()->getAsConstantUnion())
1189             return false;
1190     }
1191
1192     return allConstant;
1193 }
1194
1195 TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, TLayoutQualifier layoutQualifier, const TPublicType& typeSpecifier)
1196 {
1197     TPublicType returnType = typeSpecifier;
1198     returnType.qualifier = qualifier;
1199     returnType.layoutQualifier = layoutQualifier;
1200
1201     if (typeSpecifier.array)
1202     {
1203         error(typeSpecifier.line, "not supported", "first-class array");
1204         recover();
1205         returnType.setArray(false);
1206     }
1207
1208     if (shaderVersion < 300)
1209     {
1210         if (qualifier == EvqAttribute && (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt))
1211         {
1212             error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier));
1213             recover();
1214         }
1215
1216         if ((qualifier == EvqVaryingIn || qualifier == EvqVaryingOut) &&
1217             (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt))
1218         {
1219             error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier));
1220             recover();
1221         }
1222     }
1223     else
1224     {
1225         switch (qualifier)
1226         {
1227           case EvqSmoothIn:
1228           case EvqSmoothOut:
1229           case EvqVertexOut:
1230           case EvqFragmentIn:
1231           case EvqCentroidOut:
1232           case EvqCentroidIn:
1233             if (typeSpecifier.type == EbtBool)
1234             {
1235                 error(typeSpecifier.line, "cannot be bool", getQualifierString(qualifier));
1236                 recover();
1237             }
1238             if (typeSpecifier.type == EbtInt || typeSpecifier.type == EbtUInt)
1239             {
1240                 error(typeSpecifier.line, "must use 'flat' interpolation here", getQualifierString(qualifier));
1241                 recover();
1242             }
1243             break;
1244
1245           case EvqVertexIn:
1246           case EvqFragmentOut:
1247           case EvqFlatIn:
1248           case EvqFlatOut:
1249             if (typeSpecifier.type == EbtBool)
1250             {
1251                 error(typeSpecifier.line, "cannot be bool", getQualifierString(qualifier));
1252                 recover();
1253             }
1254             break;
1255
1256           default: break;
1257         }
1258     }
1259
1260     return returnType;
1261 }
1262
1263 TIntermAggregate* TParseContext::parseSingleDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier)
1264 {
1265     TIntermSymbol* symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation);
1266     TIntermAggregate* aggregate = intermediate.makeAggregate(symbol, identifierLocation);
1267
1268     if (identifier != "")
1269     {
1270         if (singleDeclarationErrorCheck(publicType, identifierLocation, identifier))
1271             recover();
1272
1273         // this error check can mutate the type
1274         if (nonInitConstErrorCheck(identifierLocation, identifier, publicType, false))
1275             recover();
1276
1277         TVariable* variable = 0;
1278
1279         if (nonInitErrorCheck(identifierLocation, identifier, publicType, variable))
1280             recover();
1281
1282         if (variable && symbol)
1283         {
1284             symbol->setId(variable->getUniqueId());
1285         }
1286     }
1287
1288     return aggregate;
1289 }
1290
1291 TIntermAggregate* TParseContext::parseSingleArrayDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& indexLocation, TIntermTyped *indexExpression)
1292 {
1293     if (singleDeclarationErrorCheck(publicType, identifierLocation, identifier))
1294         recover();
1295
1296     // this error check can mutate the type
1297     if (nonInitConstErrorCheck(identifierLocation, identifier, publicType, true))
1298         recover();
1299
1300     if (arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType))
1301     {
1302         recover();
1303     }
1304
1305     TPublicType arrayType = publicType;
1306
1307     int size;
1308     if (arraySizeErrorCheck(identifierLocation, indexExpression, size))
1309     {
1310         recover();
1311     }
1312     else
1313     {
1314         arrayType.setArray(true, size);
1315     }
1316
1317     TIntermSymbol* symbol = intermediate.addSymbol(0, identifier, TType(arrayType), identifierLocation);
1318     TIntermAggregate* aggregate = intermediate.makeAggregate(symbol, identifierLocation);
1319     TVariable* variable = 0;
1320
1321     if (arrayErrorCheck(identifierLocation, identifier, arrayType, variable))
1322         recover();
1323
1324     if (variable && symbol)
1325     {
1326         symbol->setId(variable->getUniqueId());
1327     }
1328
1329     return aggregate;
1330 }
1331
1332 TIntermAggregate* TParseContext::parseSingleInitDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& initLocation, TIntermTyped *initializer)
1333 {
1334     if (singleDeclarationErrorCheck(publicType, identifierLocation, identifier))
1335         recover();
1336
1337     TIntermNode* intermNode;
1338     if (!executeInitializer(identifierLocation, identifier, publicType, initializer, intermNode))
1339     {
1340         //
1341         // Build intermediate representation
1342         //
1343         return intermNode ? intermediate.makeAggregate(intermNode, initLocation) : NULL;
1344     }
1345     else
1346     {
1347         recover();
1348         return NULL;
1349     }
1350 }
1351
1352 TIntermAggregate* TParseContext::parseInvariantDeclaration(const TSourceLoc &invariantLoc,
1353                                                            const TSourceLoc &identifierLoc,
1354                                                            const TString *identifier,
1355                                                            const TSymbol *symbol)
1356 {
1357     // invariant declaration
1358     if (globalErrorCheck(invariantLoc, symbolTable.atGlobalLevel(), "invariant varying"))
1359     {
1360         recover();
1361     }
1362
1363     if (!symbol)
1364     {
1365         error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str());
1366         recover();
1367         return NULL;
1368     }
1369     else
1370     {
1371         const TString kGlFrontFacing("gl_FrontFacing");
1372         if (*identifier == kGlFrontFacing)
1373         {
1374             error(identifierLoc, "identifier should not be declared as invariant", identifier->c_str());
1375             recover();
1376             return NULL;
1377         }
1378         symbolTable.addInvariantVarying(*identifier);
1379         const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
1380         ASSERT(variable);
1381         const TType &type = variable->getType();
1382         TIntermSymbol *intermSymbol = intermediate.addSymbol(variable->getUniqueId(),
1383                                                              *identifier, type, identifierLoc);
1384
1385         TIntermAggregate *aggregate = intermediate.makeAggregate(intermSymbol, identifierLoc);
1386         aggregate->setOp(EOpInvariantDeclaration);
1387         return aggregate;
1388     }
1389 }
1390
1391 TIntermAggregate* TParseContext::parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, TSymbol *identifierSymbol, const TSourceLoc& identifierLocation, const TString &identifier)
1392 {
1393     TIntermSymbol* symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation);
1394     TIntermAggregate* intermAggregate = intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation);
1395
1396     if (structQualifierErrorCheck(identifierLocation, publicType))
1397         recover();
1398
1399     if (locationDeclaratorListCheck(identifierLocation, publicType))
1400         recover();
1401
1402     if (nonInitConstErrorCheck(identifierLocation, identifier, publicType, false))
1403         recover();
1404
1405     TVariable* variable = 0;
1406     if (nonInitErrorCheck(identifierLocation, identifier, publicType, variable))
1407         recover();
1408     if (symbol && variable)
1409         symbol->setId(variable->getUniqueId());
1410
1411     return intermAggregate;
1412 }
1413
1414 TIntermAggregate* TParseContext::parseArrayDeclarator(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& arrayLocation, TIntermNode *declaratorList, TIntermTyped *indexExpression)
1415 {
1416     if (structQualifierErrorCheck(identifierLocation, publicType))
1417         recover();
1418
1419     if (locationDeclaratorListCheck(identifierLocation, publicType))
1420         recover();
1421
1422     if (nonInitConstErrorCheck(identifierLocation, identifier, publicType, true))
1423         recover();
1424
1425     if (arrayTypeErrorCheck(arrayLocation, publicType) || arrayQualifierErrorCheck(arrayLocation, publicType))
1426     {
1427         recover();
1428     }
1429     else if (indexExpression)
1430     {
1431         int size;
1432         if (arraySizeErrorCheck(arrayLocation, indexExpression, size))
1433             recover();
1434         TPublicType arrayType(publicType);
1435         arrayType.setArray(true, size);
1436         TVariable* variable = NULL;
1437         if (arrayErrorCheck(arrayLocation, identifier, arrayType, variable))
1438             recover();
1439         TType type = TType(arrayType);
1440         type.setArraySize(size);
1441
1442         return intermediate.growAggregate(declaratorList, intermediate.addSymbol(variable ? variable->getUniqueId() : 0, identifier, type, identifierLocation), identifierLocation);
1443     }
1444     else
1445     {
1446         TPublicType arrayType(publicType);
1447         arrayType.setArray(true);
1448         TVariable* variable = NULL;
1449         if (arrayErrorCheck(arrayLocation, identifier, arrayType, variable))
1450             recover();
1451     }
1452
1453     return NULL;
1454 }
1455
1456 TIntermAggregate* TParseContext::parseInitDeclarator(TPublicType &publicType, TIntermAggregate *declaratorList, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& initLocation, TIntermTyped *initializer)
1457 {
1458     if (structQualifierErrorCheck(identifierLocation, publicType))
1459         recover();
1460
1461     if (locationDeclaratorListCheck(identifierLocation, publicType))
1462         recover();
1463
1464     TIntermNode* intermNode;
1465     if (!executeInitializer(identifierLocation, identifier, publicType, initializer, intermNode))
1466     {
1467         //
1468         // build the intermediate representation
1469         //
1470         if (intermNode)
1471         {
1472             return intermediate.growAggregate(declaratorList, intermNode, initLocation);
1473         }
1474         else
1475         {
1476             return declaratorList;
1477         }
1478     }
1479     else
1480     {
1481         recover();
1482         return NULL;
1483     }
1484 }
1485
1486 void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier)
1487 {
1488     if (typeQualifier.qualifier != EvqUniform)
1489     {
1490         error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "global layout must be uniform");
1491         recover();
1492         return;
1493     }
1494
1495     const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier;
1496     ASSERT(!layoutQualifier.isEmpty());
1497
1498     if (shaderVersion < 300)
1499     {
1500         error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 only", "layout");
1501         recover();
1502         return;
1503     }
1504
1505     if (layoutLocationErrorCheck(typeQualifier.line, typeQualifier.layoutQualifier))
1506     {
1507         recover();
1508         return;
1509     }
1510
1511     if (layoutQualifier.matrixPacking != EmpUnspecified)
1512     {
1513         defaultMatrixPacking = layoutQualifier.matrixPacking;
1514     }
1515
1516     if (layoutQualifier.blockStorage != EbsUnspecified)
1517     {
1518         defaultBlockStorage = layoutQualifier.blockStorage;
1519     }
1520 }
1521
1522 TFunction *TParseContext::addConstructorFunc(TPublicType publicType)
1523 {
1524     TOperator op = EOpNull;
1525     if (publicType.userDef)
1526     {
1527         op = EOpConstructStruct;
1528     }
1529     else
1530     {
1531         switch (publicType.type)
1532         {
1533           case EbtFloat:
1534             if (publicType.isMatrix())
1535             {
1536                 // TODO: non-square matrices
1537                 switch(publicType.getCols())
1538                 {
1539                   case 2: op = EOpConstructMat2;  break;
1540                   case 3: op = EOpConstructMat3;  break;
1541                   case 4: op = EOpConstructMat4;  break;
1542                 }
1543             }
1544             else
1545             {
1546                 switch(publicType.getNominalSize())
1547                 {
1548                   case 1: op = EOpConstructFloat; break;
1549                   case 2: op = EOpConstructVec2;  break;
1550                   case 3: op = EOpConstructVec3;  break;
1551                   case 4: op = EOpConstructVec4;  break;
1552                 }
1553             }
1554             break;
1555
1556           case EbtInt:
1557             switch(publicType.getNominalSize())
1558             {
1559               case 1: op = EOpConstructInt;   break;
1560               case 2: op = EOpConstructIVec2; break;
1561               case 3: op = EOpConstructIVec3; break;
1562               case 4: op = EOpConstructIVec4; break;
1563             }
1564             break;
1565
1566           case EbtUInt:
1567             switch(publicType.getNominalSize())
1568             {
1569               case 1: op = EOpConstructUInt;  break;
1570               case 2: op = EOpConstructUVec2; break;
1571               case 3: op = EOpConstructUVec3; break;
1572               case 4: op = EOpConstructUVec4; break;
1573             }
1574             break;
1575
1576           case EbtBool:
1577             switch(publicType.getNominalSize())
1578             {
1579                 case 1: op = EOpConstructBool;  break;
1580                 case 2: op = EOpConstructBVec2; break;
1581                 case 3: op = EOpConstructBVec3; break;
1582                 case 4: op = EOpConstructBVec4; break;
1583             }
1584             break;
1585
1586           default: break;
1587         }
1588
1589         if (op == EOpNull)
1590         {
1591             error(publicType.line, "cannot construct this type", getBasicString(publicType.type));
1592             recover();
1593             publicType.type = EbtFloat;
1594             op = EOpConstructFloat;
1595         }
1596     }
1597
1598     TString tempString;
1599     TType type(publicType);
1600     return new TFunction(&tempString, type, op);
1601 }
1602
1603 // This function is used to test for the correctness of the parameters passed to various constructor functions
1604 // and also convert them to the right datatype if it is allowed and required. 
1605 //
1606 // Returns 0 for an error or the constructed node (aggregate or typed) for no error.
1607 //
1608 TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, const TType *type, TOperator op, TFunction *fnCall, const TSourceLoc &line)
1609 {
1610     TIntermAggregate *aggregateArguments = arguments->getAsAggregate();
1611
1612     if (!aggregateArguments)
1613     {
1614         aggregateArguments = new TIntermAggregate;
1615         aggregateArguments->getSequence()->push_back(arguments);
1616     }
1617
1618     if (op == EOpConstructStruct)
1619     {
1620         const TFieldList &fields = type->getStruct()->fields();
1621         TIntermSequence *args = aggregateArguments->getSequence();
1622
1623         for (size_t i = 0; i < fields.size(); i++)
1624         {
1625             if (i >= args->size() || (*args)[i]->getAsTyped()->getType() != *fields[i]->type())
1626             {
1627                 error(line, "Structure constructor arguments do not match structure fields", "Error");
1628                 recover();
1629
1630                 return 0;
1631             }
1632         }
1633     }
1634
1635     // Turn the argument list itself into a constructor
1636     TIntermTyped *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
1637     TIntermTyped *constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type);
1638     if (constConstructor)
1639     {
1640         return constConstructor;
1641     }
1642
1643     return constructor;
1644 }
1645
1646 TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, const TType& type)
1647 {
1648     bool canBeFolded = areAllChildConst(aggrNode);
1649     aggrNode->setType(type);
1650     if (canBeFolded) {
1651         bool returnVal = false;
1652         ConstantUnion* unionArray = new ConstantUnion[type.getObjectSize()];
1653         if (aggrNode->getSequence()->size() == 1)  {
1654             returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type, true);
1655         }
1656         else {
1657             returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type);
1658         }
1659         if (returnVal)
1660             return 0;
1661
1662         return intermediate.addConstantUnion(unionArray, type, aggrNode->getLine());
1663     }
1664
1665     return 0;
1666 }
1667
1668 //
1669 // This function returns the tree representation for the vector field(s) being accessed from contant vector.
1670 // If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a contant node is
1671 // returned, else an aggregate node is returned (for v.xy). The input to this function could either be the symbol
1672 // node or it could be the intermediate tree representation of accessing fields in a constant structure or column of 
1673 // a constant matrix.
1674 //
1675 TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, const TSourceLoc& line)
1676 {
1677     TIntermTyped* typedNode;
1678     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
1679
1680     ConstantUnion *unionArray;
1681     if (tempConstantNode) {
1682         unionArray = tempConstantNode->getUnionArrayPointer();
1683
1684         if (!unionArray) {
1685             return node;
1686         }
1687     } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
1688         error(line, "Cannot offset into the vector", "Error");
1689         recover();
1690
1691         return 0;
1692     }
1693
1694     ConstantUnion* constArray = new ConstantUnion[fields.num];
1695
1696     for (int i = 0; i < fields.num; i++) {
1697         if (fields.offsets[i] >= node->getType().getNominalSize()) {
1698             std::stringstream extraInfoStream;
1699             extraInfoStream << "vector field selection out of range '" << fields.offsets[i] << "'";
1700             std::string extraInfo = extraInfoStream.str();
1701             error(line, "", "[", extraInfo.c_str());
1702             recover();
1703             fields.offsets[i] = 0;
1704         }
1705         
1706         constArray[i] = unionArray[fields.offsets[i]];
1707
1708     } 
1709     typedNode = intermediate.addConstantUnion(constArray, node->getType(), line);
1710     return typedNode;
1711 }
1712
1713 //
1714 // This function returns the column being accessed from a constant matrix. The values are retrieved from
1715 // the symbol table and parse-tree is built for a vector (each column of a matrix is a vector). The input 
1716 // to the function could either be a symbol node (m[0] where m is a constant matrix)that represents a 
1717 // constant matrix or it could be the tree representation of the constant matrix (s.m1[0] where s is a constant structure)
1718 //
1719 TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, const TSourceLoc& line)
1720 {
1721     TIntermTyped* typedNode;
1722     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
1723
1724     if (index >= node->getType().getCols()) {
1725         std::stringstream extraInfoStream;
1726         extraInfoStream << "matrix field selection out of range '" << index << "'";
1727         std::string extraInfo = extraInfoStream.str();
1728         error(line, "", "[", extraInfo.c_str());
1729         recover();
1730         index = 0;
1731     }
1732
1733     if (tempConstantNode) {
1734          ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
1735          int size = tempConstantNode->getType().getCols();
1736          typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line);
1737     } else {
1738         error(line, "Cannot offset into the matrix", "Error");
1739         recover();
1740
1741         return 0;
1742     }
1743
1744     return typedNode;
1745 }
1746
1747
1748 //
1749 // This function returns an element of an array accessed from a constant array. The values are retrieved from
1750 // the symbol table and parse-tree is built for the type of the element. The input 
1751 // to the function could either be a symbol node (a[0] where a is a constant array)that represents a 
1752 // constant array or it could be the tree representation of the constant array (s.a1[0] where s is a constant structure)
1753 //
1754 TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc& line)
1755 {
1756     TIntermTyped* typedNode;
1757     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
1758     TType arrayElementType = node->getType();
1759     arrayElementType.clearArrayness();
1760
1761     if (index >= node->getType().getArraySize()) {
1762         std::stringstream extraInfoStream;
1763         extraInfoStream << "array field selection out of range '" << index << "'";
1764         std::string extraInfo = extraInfoStream.str();
1765         error(line, "", "[", extraInfo.c_str());
1766         recover();
1767         index = 0;
1768     }
1769
1770     if (tempConstantNode) {
1771         size_t arrayElementSize = arrayElementType.getObjectSize();
1772         ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
1773         typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line);
1774     } else {
1775         error(line, "Cannot offset into the array", "Error");
1776         recover();
1777
1778         return 0;
1779     }
1780
1781     return typedNode;
1782 }
1783
1784
1785 //
1786 // This function returns the value of a particular field inside a constant structure from the symbol table. 
1787 // If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr
1788 // function and returns the parse-tree with the values of the embedded/nested struct.
1789 //
1790 TIntermTyped* TParseContext::addConstStruct(const TString &identifier, TIntermTyped *node, const TSourceLoc& line)
1791 {
1792     const TFieldList& fields = node->getType().getStruct()->fields();
1793     size_t instanceSize = 0;
1794
1795     for (size_t index = 0; index < fields.size(); ++index) {
1796         if (fields[index]->name() == identifier) {
1797             break;
1798         } else {
1799             instanceSize += fields[index]->type()->getObjectSize();
1800         }
1801     }
1802
1803     TIntermTyped *typedNode;
1804     TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
1805     if (tempConstantNode) {
1806          ConstantUnion* constArray = tempConstantNode->getUnionArrayPointer();
1807
1808          typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function
1809     } else {
1810         error(line, "Cannot offset into the structure", "Error");
1811         recover();
1812
1813         return 0;
1814     }
1815
1816     return typedNode;
1817 }
1818
1819 //
1820 // Interface/uniform blocks
1821 //
1822 TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TFieldList* fieldList, 
1823                                                    const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine)
1824 {
1825     if (reservedErrorCheck(nameLine, blockName))
1826         recover();
1827
1828     if (typeQualifier.qualifier != EvqUniform)
1829     {
1830         error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "interface blocks must be uniform");
1831         recover();
1832     }
1833
1834     TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier;
1835     if (layoutLocationErrorCheck(typeQualifier.line, blockLayoutQualifier))
1836     {
1837         recover();
1838     }
1839
1840     if (blockLayoutQualifier.matrixPacking == EmpUnspecified)
1841     {
1842         blockLayoutQualifier.matrixPacking = defaultMatrixPacking;
1843     }
1844
1845     if (blockLayoutQualifier.blockStorage == EbsUnspecified)
1846     {
1847         blockLayoutQualifier.blockStorage = defaultBlockStorage;
1848     }
1849
1850     TSymbol* blockNameSymbol = new TInterfaceBlockName(&blockName);
1851     if (!symbolTable.declare(blockNameSymbol)) {
1852         error(nameLine, "redefinition", blockName.c_str(), "interface block name");
1853         recover();
1854     }
1855
1856     // check for sampler types and apply layout qualifiers
1857     for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex) {
1858         TField* field = (*fieldList)[memberIndex];
1859         TType* fieldType = field->type();
1860         if (IsSampler(fieldType->getBasicType())) {
1861             error(field->line(), "unsupported type", fieldType->getBasicString(), "sampler types are not allowed in interface blocks");
1862             recover();
1863         }
1864
1865         const TQualifier qualifier = fieldType->getQualifier();
1866         switch (qualifier)
1867         {
1868           case EvqGlobal:
1869           case EvqUniform:
1870             break;
1871           default:
1872             error(field->line(), "invalid qualifier on interface block member", getQualifierString(qualifier));
1873             recover();
1874             break;
1875         }
1876
1877         // check layout qualifiers
1878         TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier();
1879         if (layoutLocationErrorCheck(field->line(), fieldLayoutQualifier))
1880         {
1881             recover();
1882         }
1883
1884         if (fieldLayoutQualifier.blockStorage != EbsUnspecified)
1885         {
1886             error(field->line(), "invalid layout qualifier:", getBlockStorageString(fieldLayoutQualifier.blockStorage), "cannot be used here");
1887             recover();
1888         }
1889
1890         if (fieldLayoutQualifier.matrixPacking == EmpUnspecified)
1891         {
1892             fieldLayoutQualifier.matrixPacking = blockLayoutQualifier.matrixPacking;
1893         }
1894         else if (!fieldType->isMatrix())
1895         {
1896             error(field->line(), "invalid layout qualifier:", getMatrixPackingString(fieldLayoutQualifier.matrixPacking), "can only be used on matrix types");
1897             recover();
1898         }
1899
1900         fieldType->setLayoutQualifier(fieldLayoutQualifier);
1901     }
1902
1903     // add array index
1904     int arraySize = 0;
1905     if (arrayIndex != NULL)
1906     {
1907         if (arraySizeErrorCheck(arrayIndexLine, arrayIndex, arraySize))
1908             recover();
1909     }
1910
1911     TInterfaceBlock* interfaceBlock = new TInterfaceBlock(&blockName, fieldList, instanceName, arraySize, blockLayoutQualifier);
1912     TType interfaceBlockType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier, arraySize);
1913
1914     TString symbolName = "";
1915     int symbolId = 0;
1916
1917     if (!instanceName)
1918     {
1919         // define symbols for the members of the interface block
1920         for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
1921         {
1922             TField* field = (*fieldList)[memberIndex];
1923             TType* fieldType = field->type();
1924
1925             // set parent pointer of the field variable
1926             fieldType->setInterfaceBlock(interfaceBlock);
1927
1928             TVariable* fieldVariable = new TVariable(&field->name(), *fieldType);
1929             fieldVariable->setQualifier(typeQualifier.qualifier);
1930
1931             if (!symbolTable.declare(fieldVariable)) {
1932                 error(field->line(), "redefinition", field->name().c_str(), "interface block member name");
1933                 recover();
1934             }
1935         }
1936     }
1937     else
1938     {
1939         // add a symbol for this interface block
1940         TVariable* instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false);
1941         instanceTypeDef->setQualifier(typeQualifier.qualifier);
1942
1943         if (!symbolTable.declare(instanceTypeDef)) {
1944             error(instanceLine, "redefinition", instanceName->c_str(), "interface block instance name");
1945             recover();
1946         }
1947
1948         symbolId = instanceTypeDef->getUniqueId();
1949         symbolName = instanceTypeDef->getName();
1950     }
1951
1952     TIntermAggregate *aggregate = intermediate.makeAggregate(intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line), nameLine);
1953     aggregate->setOp(EOpDeclaration);
1954
1955     exitStructDeclaration();
1956     return aggregate;
1957 }
1958
1959 bool TParseContext::enterStructDeclaration(const TSourceLoc& line, const TString& identifier)
1960 {
1961     ++structNestingLevel;
1962
1963     // Embedded structure definitions are not supported per GLSL ES spec.
1964     // They aren't allowed in GLSL either, but we need to detect this here
1965     // so we don't rely on the GLSL compiler to catch it.
1966     if (structNestingLevel > 1) {
1967         error(line, "", "Embedded struct definitions are not allowed");
1968         return true;
1969     }
1970
1971     return false;
1972 }
1973
1974 void TParseContext::exitStructDeclaration()
1975 {
1976     --structNestingLevel;
1977 }
1978
1979 namespace {
1980
1981 const int kWebGLMaxStructNesting = 4;
1982
1983 }  // namespace
1984
1985 bool TParseContext::structNestingErrorCheck(const TSourceLoc& line, const TField& field)
1986 {
1987     if (!IsWebGLBasedSpec(shaderSpec)) {
1988         return false;
1989     }
1990
1991     if (field.type()->getBasicType() != EbtStruct) {
1992         return false;
1993     }
1994
1995     // We're already inside a structure definition at this point, so add
1996     // one to the field's struct nesting.
1997     if (1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting) {
1998         std::stringstream reasonStream;
1999         reasonStream << "Reference of struct type "
2000                      << field.type()->getStruct()->name().c_str()
2001                      << " exceeds maximum allowed nesting level of "
2002                      << kWebGLMaxStructNesting;
2003         std::string reason = reasonStream.str();
2004         error(line, reason.c_str(), field.name().c_str(), "");
2005         return true;
2006     }
2007
2008     return false;
2009 }
2010
2011 //
2012 // Parse an array index expression
2013 //
2014 TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression)
2015 {
2016     TIntermTyped *indexedExpression = NULL;
2017
2018     if (!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector())
2019     {
2020         if (baseExpression->getAsSymbolNode())
2021         {
2022             error(location, " left of '[' is not of type array, matrix, or vector ", baseExpression->getAsSymbolNode()->getSymbol().c_str());
2023         }
2024         else
2025         {
2026             error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
2027         }
2028         recover();
2029     }
2030
2031     if (indexExpression->getQualifier() == EvqConst)
2032     {
2033         int index = indexExpression->getAsConstantUnion()->getIConst(0);
2034         if (index < 0)
2035         {
2036             std::stringstream infoStream;
2037             infoStream << index;
2038             std::string info = infoStream.str();
2039             error(location, "negative index", info.c_str());
2040             recover();
2041             index = 0;
2042         }
2043         if (baseExpression->getType().getQualifier() == EvqConst)
2044         {
2045             if (baseExpression->isArray())
2046             {
2047                 // constant folding for arrays
2048                 indexedExpression = addConstArrayNode(index, baseExpression, location);
2049             }
2050             else if (baseExpression->isVector())
2051             {
2052                 // constant folding for vectors
2053                 TVectorFields fields;
2054                 fields.num = 1;
2055                 fields.offsets[0] = index; // need to do it this way because v.xy sends fields integer array
2056                 indexedExpression = addConstVectorNode(fields, baseExpression, location);
2057             }
2058             else if (baseExpression->isMatrix())
2059             {
2060                 // constant folding for matrices
2061                 indexedExpression = addConstMatrixNode(index, baseExpression, location);
2062             }
2063         }
2064         else
2065         {
2066             if (baseExpression->isArray())
2067             {
2068                 if (index >= baseExpression->getType().getArraySize())
2069                 {
2070                     std::stringstream extraInfoStream;
2071                     extraInfoStream << "array index out of range '" << index << "'";
2072                     std::string extraInfo = extraInfoStream.str();
2073                     error(location, "", "[", extraInfo.c_str());
2074                     recover();
2075                     index = baseExpression->getType().getArraySize() - 1;
2076                 }
2077                 else if (baseExpression->getQualifier() == EvqFragData && index > 0 && !isExtensionEnabled("GL_EXT_draw_buffers"))
2078                 {
2079                     error(location, "", "[", "array indexes for gl_FragData must be zero when GL_EXT_draw_buffers is disabled");
2080                     recover();
2081                     index = 0;
2082                 }
2083             }
2084             else if ((baseExpression->isVector() || baseExpression->isMatrix()) && baseExpression->getType().getNominalSize() <= index)
2085             {
2086                 std::stringstream extraInfoStream;
2087                 extraInfoStream << "field selection out of range '" << index << "'";
2088                 std::string extraInfo = extraInfoStream.str();
2089                 error(location, "", "[", extraInfo.c_str());
2090                 recover();
2091                 index = baseExpression->getType().getNominalSize() - 1;
2092             }
2093
2094             indexExpression->getAsConstantUnion()->getUnionArrayPointer()->setIConst(index);
2095             indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location);
2096         }
2097     }
2098     else
2099     {
2100         if (baseExpression->isInterfaceBlock())
2101         {
2102             error(location, "", "[", "array indexes for interface blocks arrays must be constant integral expressions");
2103             recover();
2104         }
2105         else if (baseExpression->getQualifier() == EvqFragmentOut)
2106         {
2107             error(location, "", "[", "array indexes for fragment outputs must be constant integral expressions");
2108             recover();
2109         }
2110
2111         indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location);
2112     }
2113
2114     if (indexedExpression == 0)
2115     {
2116         ConstantUnion *unionArray = new ConstantUnion[1];
2117         unionArray->setFConst(0.0f);
2118         indexedExpression = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), location);
2119     }
2120     else if (baseExpression->isArray())
2121     {
2122         const TType &baseType = baseExpression->getType();
2123         if (baseType.getStruct())
2124         {
2125             TType copyOfType(baseType.getStruct());
2126             indexedExpression->setType(copyOfType);
2127         }
2128         else if (baseType.isInterfaceBlock())
2129         {
2130             TType copyOfType(baseType.getInterfaceBlock(), baseType.getQualifier(), baseType.getLayoutQualifier(), 0);
2131             indexedExpression->setType(copyOfType);
2132         }
2133         else
2134         {
2135             indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary, baseExpression->getNominalSize(), baseExpression->getSecondarySize()));
2136         }
2137
2138         if (baseExpression->getType().getQualifier() == EvqConst)
2139         {
2140             indexedExpression->getTypePointer()->setQualifier(EvqConst);
2141         }
2142     }
2143     else if (baseExpression->isMatrix())
2144     {
2145         TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary;
2146         indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier, baseExpression->getRows()));
2147     }
2148     else if (baseExpression->isVector())
2149     {
2150         TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary;
2151         indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier));
2152     }
2153     else
2154     {
2155         indexedExpression->setType(baseExpression->getType());
2156     }
2157
2158     return indexedExpression;
2159 }
2160
2161 TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc& dotLocation, const TString &fieldString, const TSourceLoc& fieldLocation)
2162 {
2163     TIntermTyped *indexedExpression = NULL;
2164
2165     if (baseExpression->isArray())
2166     {
2167         error(fieldLocation, "cannot apply dot operator to an array", ".");
2168         recover();
2169     }
2170
2171     if (baseExpression->isVector())
2172     {
2173         TVectorFields fields;
2174         if (!parseVectorFields(fieldString, baseExpression->getNominalSize(), fields, fieldLocation))
2175         {
2176             fields.num = 1;
2177             fields.offsets[0] = 0;
2178             recover();
2179         }
2180
2181         if (baseExpression->getType().getQualifier() == EvqConst)
2182         {
2183             // constant folding for vector fields
2184             indexedExpression = addConstVectorNode(fields, baseExpression, fieldLocation);
2185             if (indexedExpression == 0)
2186             {
2187                 recover();
2188                 indexedExpression = baseExpression;
2189             }
2190             else
2191             {
2192                 indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqConst, (int) (fieldString).size()));
2193             }
2194         }
2195         else
2196         {
2197             TString vectorString = fieldString;
2198             TIntermTyped* index = intermediate.addSwizzle(fields, fieldLocation);
2199             indexedExpression = intermediate.addIndex(EOpVectorSwizzle, baseExpression, index, dotLocation);
2200             indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary, (int) vectorString.size()));
2201         }
2202     }
2203     else if (baseExpression->isMatrix())
2204     {
2205         TMatrixFields fields;
2206         if (!parseMatrixFields(fieldString, baseExpression->getCols(), baseExpression->getRows(), fields, fieldLocation))
2207         {
2208             fields.wholeRow = false;
2209             fields.wholeCol = false;
2210             fields.row = 0;
2211             fields.col = 0;
2212             recover();
2213         }
2214
2215         if (fields.wholeRow || fields.wholeCol)
2216         {
2217             error(dotLocation, " non-scalar fields not implemented yet", ".");
2218             recover();
2219             ConstantUnion *unionArray = new ConstantUnion[1];
2220             unionArray->setIConst(0);
2221             TIntermTyped* index = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), fieldLocation);
2222             indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, index, dotLocation);
2223             indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),EvqTemporary, baseExpression->getCols(), baseExpression->getRows()));
2224         }
2225         else
2226         {
2227             ConstantUnion *unionArray = new ConstantUnion[1];
2228             unionArray->setIConst(fields.col * baseExpression->getRows() + fields.row);
2229             TIntermTyped* index = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), fieldLocation);
2230             indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, index, dotLocation);
2231             indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision()));
2232         }
2233     }
2234     else if (baseExpression->getBasicType() == EbtStruct)
2235     {
2236         bool fieldFound = false;
2237         const TFieldList& fields = baseExpression->getType().getStruct()->fields();
2238         if (fields.empty())
2239         {
2240             error(dotLocation, "structure has no fields", "Internal Error");
2241             recover();
2242             indexedExpression = baseExpression;
2243         }
2244         else
2245         {
2246             unsigned int i;
2247             for (i = 0; i < fields.size(); ++i)
2248             {
2249                 if (fields[i]->name() == fieldString)
2250                 {
2251                     fieldFound = true;
2252                     break;
2253                 }
2254             }
2255             if (fieldFound)
2256             {
2257                 if (baseExpression->getType().getQualifier() == EvqConst)
2258                 {
2259                     indexedExpression = addConstStruct(fieldString, baseExpression, dotLocation);
2260                     if (indexedExpression == 0)
2261                     {
2262                         recover();
2263                         indexedExpression = baseExpression;
2264                     }
2265                     else
2266                     {
2267                         indexedExpression->setType(*fields[i]->type());
2268                         // change the qualifier of the return type, not of the structure field
2269                         // as the structure definition is shared between various structures.
2270                         indexedExpression->getTypePointer()->setQualifier(EvqConst);
2271                     }
2272                 }
2273                 else
2274                 {
2275                     ConstantUnion *unionArray = new ConstantUnion[1];
2276                     unionArray->setIConst(i);
2277                     TIntermTyped* index = intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation);
2278                     indexedExpression = intermediate.addIndex(EOpIndexDirectStruct, baseExpression, index, dotLocation);
2279                     indexedExpression->setType(*fields[i]->type());
2280                 }
2281             }
2282             else
2283             {
2284                 error(dotLocation, " no such field in structure", fieldString.c_str());
2285                 recover();
2286                 indexedExpression = baseExpression;
2287             }
2288         }
2289     }
2290     else if (baseExpression->isInterfaceBlock())
2291     {
2292         bool fieldFound = false;
2293         const TFieldList& fields = baseExpression->getType().getInterfaceBlock()->fields();
2294         if (fields.empty())
2295         {
2296             error(dotLocation, "interface block has no fields", "Internal Error");
2297             recover();
2298             indexedExpression = baseExpression;
2299         }
2300         else
2301         {
2302             unsigned int i;
2303             for (i = 0; i < fields.size(); ++i)
2304             {
2305                 if (fields[i]->name() == fieldString)
2306                 {
2307                     fieldFound = true;
2308                     break;
2309                 }
2310             }
2311             if (fieldFound)
2312             {
2313                 ConstantUnion *unionArray = new ConstantUnion[1];
2314                 unionArray->setIConst(i);
2315                 TIntermTyped* index = intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation);
2316                 indexedExpression = intermediate.addIndex(EOpIndexDirectInterfaceBlock, baseExpression, index, dotLocation);
2317                 indexedExpression->setType(*fields[i]->type());
2318             }
2319             else
2320             {
2321                 error(dotLocation, " no such field in interface block", fieldString.c_str());
2322                 recover();
2323                 indexedExpression = baseExpression;
2324             }
2325         }
2326     }
2327     else
2328     {
2329         if (shaderVersion < 300)
2330         {
2331             error(dotLocation, " field selection requires structure, vector, or matrix on left hand side", fieldString.c_str());
2332         }
2333         else
2334         {
2335             error(dotLocation, " field selection requires structure, vector, matrix, or interface block on left hand side", fieldString.c_str());
2336         }
2337         recover();
2338         indexedExpression = baseExpression;
2339     }
2340
2341     return indexedExpression;
2342 }
2343
2344 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine)
2345 {
2346     TLayoutQualifier qualifier;
2347
2348     qualifier.location = -1;
2349     qualifier.matrixPacking = EmpUnspecified;
2350     qualifier.blockStorage = EbsUnspecified;
2351
2352     if (qualifierType == "shared")
2353     {
2354         qualifier.blockStorage = EbsShared;
2355     }
2356     else if (qualifierType == "packed")
2357     {
2358         qualifier.blockStorage = EbsPacked;
2359     }
2360     else if (qualifierType == "std140")
2361     {
2362         qualifier.blockStorage = EbsStd140;
2363     }
2364     else if (qualifierType == "row_major")
2365     {
2366         qualifier.matrixPacking = EmpRowMajor;
2367     }
2368     else if (qualifierType == "column_major")
2369     {
2370         qualifier.matrixPacking = EmpColumnMajor;
2371     }
2372     else if (qualifierType == "location")
2373     {
2374         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "location requires an argument");
2375         recover();
2376     }
2377     else
2378     {
2379         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
2380         recover();
2381     }
2382
2383     return qualifier;
2384 }
2385
2386 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine)
2387 {
2388     TLayoutQualifier qualifier;
2389
2390     qualifier.location = -1;
2391     qualifier.matrixPacking = EmpUnspecified;
2392     qualifier.blockStorage = EbsUnspecified;
2393
2394     if (qualifierType != "location")
2395     {
2396         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "only location may have arguments");
2397         recover();
2398     }
2399     else
2400     {
2401         // must check that location is non-negative
2402         if (intValue < 0)
2403         {
2404             error(intValueLine, "out of range:", intValueString.c_str(), "location must be non-negative");
2405             recover();
2406         }
2407         else
2408         {
2409             qualifier.location = intValue;
2410         }
2411     }
2412
2413     return qualifier;
2414 }
2415
2416 TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier)
2417 {
2418     TLayoutQualifier joinedQualifier = leftQualifier;
2419
2420     if (rightQualifier.location != -1)
2421     {
2422         joinedQualifier.location = rightQualifier.location;
2423     }
2424     if (rightQualifier.matrixPacking != EmpUnspecified)
2425     {
2426         joinedQualifier.matrixPacking = rightQualifier.matrixPacking;
2427     }
2428     if (rightQualifier.blockStorage != EbsUnspecified)
2429     {
2430         joinedQualifier.blockStorage = rightQualifier.blockStorage;
2431     }
2432
2433     return joinedQualifier;
2434 }
2435
2436 TPublicType TParseContext::joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier,
2437                                                        const TSourceLoc &storageLoc, TQualifier storageQualifier)
2438 {
2439     TQualifier mergedQualifier = EvqSmoothIn;
2440
2441     if (storageQualifier == EvqFragmentIn) {
2442         if (interpolationQualifier == EvqSmooth)
2443             mergedQualifier = EvqSmoothIn;
2444         else if (interpolationQualifier == EvqFlat)
2445             mergedQualifier = EvqFlatIn;
2446         else UNREACHABLE();
2447     }
2448     else if (storageQualifier == EvqCentroidIn) {
2449         if (interpolationQualifier == EvqSmooth)
2450             mergedQualifier = EvqCentroidIn;
2451         else if (interpolationQualifier == EvqFlat)
2452             mergedQualifier = EvqFlatIn;
2453         else UNREACHABLE();
2454     }
2455     else if (storageQualifier == EvqVertexOut) {
2456         if (interpolationQualifier == EvqSmooth)
2457             mergedQualifier = EvqSmoothOut;
2458         else if (interpolationQualifier == EvqFlat)
2459             mergedQualifier = EvqFlatOut;
2460         else UNREACHABLE();
2461     }
2462     else if (storageQualifier == EvqCentroidOut) {
2463         if (interpolationQualifier == EvqSmooth)
2464             mergedQualifier = EvqCentroidOut;
2465         else if (interpolationQualifier == EvqFlat)
2466             mergedQualifier = EvqFlatOut;
2467         else UNREACHABLE();
2468     }
2469     else {
2470         error(interpolationLoc, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getInterpolationString(interpolationQualifier));
2471         recover();
2472
2473         mergedQualifier = storageQualifier;
2474     }
2475
2476     TPublicType type;
2477     type.setBasic(EbtVoid, mergedQualifier, storageLoc);
2478     return type;
2479 }
2480
2481 TFieldList *TParseContext::addStructDeclaratorList(const TPublicType& typeSpecifier, TFieldList *fieldList)
2482 {
2483     if (voidErrorCheck(typeSpecifier.line, (*fieldList)[0]->name(), typeSpecifier)) {
2484         recover();
2485     }
2486
2487     for (unsigned int i = 0; i < fieldList->size(); ++i) {
2488         //
2489         // Careful not to replace already known aspects of type, like array-ness
2490         //
2491         TType* type = (*fieldList)[i]->type();
2492         type->setBasicType(typeSpecifier.type);
2493         type->setPrimarySize(typeSpecifier.primarySize);
2494         type->setSecondarySize(typeSpecifier.secondarySize);
2495         type->setPrecision(typeSpecifier.precision);
2496         type->setQualifier(typeSpecifier.qualifier);
2497         type->setLayoutQualifier(typeSpecifier.layoutQualifier);
2498
2499         // don't allow arrays of arrays
2500         if (type->isArray()) {
2501             if (arrayTypeErrorCheck(typeSpecifier.line, typeSpecifier))
2502                 recover();
2503         }
2504         if (typeSpecifier.array)
2505             type->setArraySize(typeSpecifier.arraySize);
2506         if (typeSpecifier.userDef) {
2507             type->setStruct(typeSpecifier.userDef->getStruct());
2508         }
2509
2510         if (structNestingErrorCheck(typeSpecifier.line, *(*fieldList)[i])) {
2511             recover();
2512         }
2513     }
2514
2515     return fieldList;
2516 }
2517
2518 TPublicType TParseContext::addStructure(const TSourceLoc& structLine, const TSourceLoc& nameLine, const TString *structName, TFieldList* fieldList)
2519 {
2520     TStructure* structure = new TStructure(structName, fieldList);
2521     TType* structureType = new TType(structure);
2522
2523     structure->setUniqueId(TSymbolTable::nextUniqueId());
2524
2525     if (!structName->empty())
2526     {
2527         if (reservedErrorCheck(nameLine, *structName))
2528         {
2529             recover();
2530         }
2531         TVariable* userTypeDef = new TVariable(structName, *structureType, true);
2532         if (!symbolTable.declare(userTypeDef)) {
2533             error(nameLine, "redefinition", structName->c_str(), "struct");
2534             recover();
2535         }
2536     }
2537
2538     // ensure we do not specify any storage qualifiers on the struct members
2539     for (unsigned int typeListIndex = 0; typeListIndex < fieldList->size(); typeListIndex++)
2540     {
2541         const TField &field = *(*fieldList)[typeListIndex];
2542         const TQualifier qualifier = field.type()->getQualifier();
2543         switch (qualifier)
2544         {
2545           case EvqGlobal:
2546           case EvqTemporary:
2547             break;
2548           default:
2549             error(field.line(), "invalid qualifier on struct member", getQualifierString(qualifier));
2550             recover();
2551             break;
2552         }
2553     }
2554
2555     TPublicType publicType;
2556     publicType.setBasic(EbtStruct, EvqTemporary, structLine);
2557     publicType.userDef = structureType;
2558     exitStructDeclaration();
2559
2560     return publicType;
2561 }
2562
2563 //
2564 // Parse an array of strings using yyparse.
2565 //
2566 // Returns 0 for success.
2567 //
2568 int PaParseStrings(size_t count, const char* const string[], const int length[],
2569                    TParseContext* context) {
2570     if ((count == 0) || (string == NULL))
2571         return 1;
2572
2573     if (glslang_initialize(context))
2574         return 1;
2575
2576     int error = glslang_scan(count, string, length, context);
2577     if (!error)
2578         error = glslang_parse(context);
2579
2580     glslang_finalize(context);
2581
2582     return (error == 0) && (context->numErrors() == 0) ? 0 : 1;
2583 }
2584
2585
2586