OSDN Git Service

Eliminate compiling for the WebGL spec.
[android-x86/external-swiftshader.git] / src / OpenGL / compiler / ParseHelper.cpp
1 //
2 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 #include "ParseHelper.h"
8
9 #include <stdarg.h>
10 #include <stdio.h>
11
12 #include "glslang.h"
13 #include "preprocessor/SourceLocation.h"
14
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, int 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         case 'w':
78             fields.offsets[i] = 3;
79             fieldSet[i] = exyzw;
80             break;
81         case 'a':
82             fields.offsets[i] = 3;
83             fieldSet[i] = ergba;
84             break;
85         case 'q':
86             fields.offsets[i] = 3;
87             fieldSet[i] = estpq;
88             break;
89         default:
90             error(line, "illegal vector field selection", compString.c_str());
91             return false;
92         }
93     }
94
95     for (int i = 0; i < fields.num; ++i) {
96         if (fields.offsets[i] >= vecSize) {
97             error(line, "vector field selection out of range",  compString.c_str());
98             return false;
99         }
100
101         if (i > 0) {
102             if (fieldSet[i] != fieldSet[i-1]) {
103                 error(line, "illegal - vector component fields not from the same set", compString.c_str());
104                 return false;
105             }
106         }
107     }
108
109     return true;
110 }
111
112
113 //
114 // Look at a '.' field selector string and change it into offsets
115 // for a matrix.
116 //
117 bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TMatrixFields& fields, int line)
118 {
119     fields.wholeRow = false;
120     fields.wholeCol = false;
121     fields.row = -1;
122     fields.col = -1;
123
124     if (compString.size() != 2) {
125         error(line, "illegal length of matrix field selection", compString.c_str());
126         return false;
127     }
128
129     if (compString[0] == '_') {
130         if (compString[1] < '0' || compString[1] > '3') {
131             error(line, "illegal matrix field selection", compString.c_str());
132             return false;
133         }
134         fields.wholeCol = true;
135         fields.col = compString[1] - '0';
136     } else if (compString[1] == '_') {
137         if (compString[0] < '0' || compString[0] > '3') {
138             error(line, "illegal matrix field selection", compString.c_str());
139             return false;
140         }
141         fields.wholeRow = true;
142         fields.row = compString[0] - '0';
143     } else {
144         if (compString[0] < '0' || compString[0] > '3' ||
145             compString[1] < '0' || compString[1] > '3') {
146             error(line, "illegal matrix field selection", compString.c_str());
147             return false;
148         }
149         fields.row = compString[0] - '0';
150         fields.col = compString[1] - '0';
151     }
152
153     if (fields.row >= matSize || fields.col >= matSize) {
154         error(line, "matrix field selection out of range", compString.c_str());
155         return false;
156     }
157
158     return true;
159 }
160
161 ///////////////////////////////////////////////////////////////////////
162 //
163 // Errors
164 //
165 ////////////////////////////////////////////////////////////////////////
166
167 //
168 // Track whether errors have occurred.
169 //
170 void TParseContext::recover()
171 {
172 }
173
174 //
175 // Used by flex/bison to output all syntax and parsing errors.
176 //
177 void TParseContext::error(TSourceLoc loc,
178                           const char* reason, const char* token,
179                           const char* extraInfo)
180 {
181     pp::SourceLocation srcLoc;
182     DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line);
183     diagnostics.writeInfo(pp::Diagnostics::PP_ERROR,
184                           srcLoc, reason, token, extraInfo);
185
186 }
187
188 void TParseContext::warning(TSourceLoc loc,
189                             const char* reason, const char* token,
190                             const char* extraInfo) {
191     pp::SourceLocation srcLoc;
192     DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line);
193     diagnostics.writeInfo(pp::Diagnostics::PP_WARNING,
194                           srcLoc, reason, token, extraInfo);
195 }
196
197 void TParseContext::trace(const char* str)
198 {
199     diagnostics.writeDebug(str);
200 }
201
202 //
203 // Same error message for all places assignments don't work.
204 //
205 void TParseContext::assignError(int line, const char* op, TString left, TString right)
206 {
207     std::stringstream extraInfoStream;
208     extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'";
209     std::string extraInfo = extraInfoStream.str();
210     error(line, "", op, extraInfo.c_str());
211 }
212
213 //
214 // Same error message for all places unary operations don't work.
215 //
216 void TParseContext::unaryOpError(int line, const char* op, TString operand)
217 {
218     std::stringstream extraInfoStream;
219     extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " << operand
220                     << " (or there is no acceptable conversion)";
221     std::string extraInfo = extraInfoStream.str();
222     error(line, " wrong operand type", op, extraInfo.c_str());
223 }
224
225 //
226 // Same error message for all binary operations don't work.
227 //
228 void TParseContext::binaryOpError(int line, const char* op, TString left, TString right)
229 {
230     std::stringstream extraInfoStream;
231     extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" << left 
232                     << "' and a right operand of type '" << right << "' (or there is no acceptable conversion)";
233     std::string extraInfo = extraInfoStream.str();
234     error(line, " wrong operand types ", op, extraInfo.c_str());
235 }
236
237 bool TParseContext::precisionErrorCheck(int line, TPrecision precision, TBasicType type){
238     if (!checksPrecisionErrors)
239         return false;
240     switch( type ){
241     case EbtFloat:
242         if( precision == EbpUndefined ){
243             error( line, "No precision specified for (float)", "" );
244             return true;
245         }
246         break;
247     case EbtInt:
248         if( precision == EbpUndefined ){
249             error( line, "No precision specified (int)", "" );
250             return true;
251         }
252         break;
253     default:
254         return false;
255     }
256     return false;
257 }
258
259 //
260 // Both test and if necessary, spit out an error, to see if the node is really
261 // an l-value that can be operated on this way.
262 //
263 // Returns true if the was an error.
264 //
265 bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* node)
266 {
267     TIntermSymbol* symNode = node->getAsSymbolNode();
268     TIntermBinary* binaryNode = node->getAsBinaryNode();
269
270     if (binaryNode) {
271         bool errorReturn;
272
273         switch(binaryNode->getOp()) {
274         case EOpIndexDirect:
275         case EOpIndexIndirect:
276         case EOpIndexDirectStruct:
277             return lValueErrorCheck(line, op, binaryNode->getLeft());
278         case EOpVectorSwizzle:
279             errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft());
280             if (!errorReturn) {
281                 int offset[4] = {0,0,0,0};
282
283                 TIntermTyped* rightNode = binaryNode->getRight();
284                 TIntermAggregate *aggrNode = rightNode->getAsAggregate();
285
286                 for (TIntermSequence::iterator p = aggrNode->getSequence().begin();
287                                                p != aggrNode->getSequence().end(); p++) {
288                     int value = (*p)->getAsTyped()->getAsConstantUnion()->getIConst(0);
289                     offset[value]++;
290                     if (offset[value] > 1) {
291                         error(line, " l-value of swizzle cannot have duplicate components", op);
292
293                         return true;
294                     }
295                 }
296             }
297
298             return errorReturn;
299         default:
300             break;
301         }
302         error(line, " l-value required", op);
303
304         return true;
305     }
306
307
308     const char* symbol = 0;
309     if (symNode != 0)
310         symbol = symNode->getSymbol().c_str();
311
312     const char* message = 0;
313     switch (node->getQualifier()) {
314     case EvqConst:          message = "can't modify a const";        break;
315     case EvqConstReadOnly:  message = "can't modify a const";        break;
316     case EvqAttribute:      message = "can't modify an attribute";   break;
317     case EvqUniform:        message = "can't modify a uniform";      break;
318     case EvqVaryingIn:      message = "can't modify a varying";      break;
319     case EvqInput:          message = "can't modify an input";       break;
320     case EvqFragCoord:      message = "can't modify gl_FragCoord";   break;
321     case EvqFrontFacing:    message = "can't modify gl_FrontFacing"; break;
322     case EvqPointCoord:     message = "can't modify gl_PointCoord";  break;
323     default:
324
325         //
326         // Type that can't be written to?
327         //
328         if(IsSampler(node->getBasicType()))
329         {
330             message = "can't modify a sampler";
331         }
332         else if(node->getBasicType() == EbtVoid)
333         {
334             message = "can't modify void";
335         }
336     }
337
338     if (message == 0 && binaryNode == 0 && symNode == 0) {
339         error(line, " l-value required", op);
340
341         return true;
342     }
343
344
345     //
346     // Everything else is okay, no error.
347     //
348     if (message == 0)
349         return false;
350
351     //
352     // If we get here, we have an error and a message.
353     //
354     if (symNode) {
355         std::stringstream extraInfoStream;
356         extraInfoStream << "\"" << symbol << "\" (" << message << ")";
357         std::string extraInfo = extraInfoStream.str();
358         error(line, " l-value required", op, extraInfo.c_str());
359     }
360     else {
361         std::stringstream extraInfoStream;
362         extraInfoStream << "(" << message << ")";
363         std::string extraInfo = extraInfoStream.str();
364         error(line, " l-value required", op, extraInfo.c_str());
365     }
366
367     return true;
368 }
369
370 //
371 // Both test, and if necessary spit out an error, to see if the node is really
372 // a constant.
373 //
374 // Returns true if the was an error.
375 //
376 bool TParseContext::constErrorCheck(TIntermTyped* node)
377 {
378     if (node->getQualifier() == EvqConst)
379         return false;
380
381     error(node->getLine(), "constant expression required", "");
382
383     return true;
384 }
385
386 //
387 // Both test, and if necessary spit out an error, to see if the node is really
388 // an integer.
389 //
390 // Returns true if the was an error.
391 //
392 bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token)
393 {
394     if (node->getBasicType() == EbtInt && node->getNominalSize() == 1)
395         return false;
396
397     error(node->getLine(), "integer expression required", token);
398
399     return true;
400 }
401
402 //
403 // Both test, and if necessary spit out an error, to see if we are currently
404 // globally scoped.
405 //
406 // Returns true if the was an error.
407 //
408 bool TParseContext::globalErrorCheck(int line, bool global, const char* token)
409 {
410     if (global)
411         return false;
412
413     error(line, "only allowed at global scope", token);
414
415     return true;
416 }
417
418 //
419 // For now, keep it simple:  if it starts "gl_", it's reserved, independent
420 // of scope.  Except, if the symbol table is at the built-in push-level,
421 // which is when we are parsing built-ins.
422 // Also checks for "webgl_" and "_webgl_" reserved identifiers if parsing a
423 // webgl shader.
424 //
425 // Returns true if there was an error.
426 //
427 bool TParseContext::reservedErrorCheck(int line, const TString& identifier)
428 {
429     static const char* reservedErrMsg = "reserved built-in name";
430     if (!symbolTable.atBuiltInLevel()) {
431         if (identifier.compare(0, 3, "gl_") == 0) {
432             error(line, reservedErrMsg, "gl_");
433             return true;
434         }
435         if (identifier.find("__") != TString::npos) {
436             error(line, "identifiers containing two consecutive underscores (__) are reserved as possible future keywords", identifier.c_str());
437             return true;
438         }
439     }
440
441     return false;
442 }
443
444 //
445 // Make sure there is enough data provided to the constructor to build
446 // something of the type of the constructor.  Also returns the type of
447 // the constructor.
448 //
449 // Returns true if there was an error in construction.
450 //
451 bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction& function, TOperator op, TType* type)
452 {
453     *type = function.getReturnType();
454
455     bool constructingMatrix = false;
456     switch(op) {
457     case EOpConstructMat2:
458     case EOpConstructMat3:
459     case EOpConstructMat4:
460         constructingMatrix = true;
461         break;
462     default:
463         break;
464     }
465
466     //
467     // Note: It's okay to have too many components available, but not okay to have unused
468     // arguments.  'full' will go to true when enough args have been seen.  If we loop
469     // again, there is an extra argument, so 'overfull' will become true.
470     //
471
472     int size = 0;
473     bool constType = true;
474     bool full = false;
475     bool overFull = false;
476     bool matrixInMatrix = false;
477     bool arrayArg = false;
478     for (int i = 0; i < function.getParamCount(); ++i) {
479         const TParameter& param = function.getParam(i);
480         size += param.type->getObjectSize();
481
482         if (constructingMatrix && param.type->isMatrix())
483             matrixInMatrix = true;
484         if (full)
485             overFull = true;
486         if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize())
487             full = true;
488         if (param.type->getQualifier() != EvqConst)
489             constType = false;
490         if (param.type->isArray())
491             arrayArg = true;
492     }
493
494     if (constType)
495         type->setQualifier(EvqConst);
496
497     if (type->isArray() && type->getArraySize() != function.getParamCount()) {
498         error(line, "array constructor needs one argument per array element", "constructor");
499         return true;
500     }
501
502     if (arrayArg && op != EOpConstructStruct) {
503         error(line, "constructing from a non-dereferenced array", "constructor");
504         return true;
505     }
506
507     if (matrixInMatrix && !type->isArray()) {
508         if (function.getParamCount() != 1) {
509           error(line, "constructing matrix from matrix can only take one argument", "constructor");
510           return true;
511         }
512     }
513
514     if (overFull) {
515         error(line, "too many arguments", "constructor");
516         return true;
517     }
518
519     if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->size()) != function.getParamCount()) {
520         error(line, "Number of constructor parameters does not match the number of structure fields", "constructor");
521         return true;
522     }
523
524     if (!type->isMatrix() || !matrixInMatrix) {
525         if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) ||
526             (op == EOpConstructStruct && size < type->getObjectSize())) {
527             error(line, "not enough data provided for construction", "constructor");
528             return true;
529         }
530     }
531
532     TIntermTyped *typed = node ? node->getAsTyped() : 0;
533     if (typed == 0) {
534         error(line, "constructor argument does not have a type", "constructor");
535         return true;
536     }
537     if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) {
538         error(line, "cannot convert a sampler", "constructor");
539         return true;
540     }
541     if (typed->getBasicType() == EbtVoid) {
542         error(line, "cannot convert a void", "constructor");
543         return true;
544     }
545
546     return false;
547 }
548
549 // This function checks to see if a void variable has been declared and raise an error message for such a case
550 //
551 // returns true in case of an error
552 //
553 bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TPublicType& pubType)
554 {
555     if (pubType.type == EbtVoid) {
556         error(line, "illegal use of type 'void'", identifier.c_str());
557         return true;
558     }
559
560     return false;
561 }
562
563 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
564 //
565 // returns true in case of an error
566 //
567 bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type)
568 {
569     if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) {
570         error(line, "boolean expression expected", "");
571         return true;
572     }
573
574     return false;
575 }
576
577 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
578 //
579 // returns true in case of an error
580 //
581 bool TParseContext::boolErrorCheck(int line, const TPublicType& pType)
582 {
583     if (pType.type != EbtBool || pType.array || pType.matrix || (pType.size > 1)) {
584         error(line, "boolean expression expected", "");
585         return true;
586     }
587
588     return false;
589 }
590
591 bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const char* reason)
592 {
593     if (pType.type == EbtStruct) {
594         if (containsSampler(*pType.userDef)) {
595             error(line, reason, getBasicString(pType.type), "(structure contains a sampler)");
596
597             return true;
598         }
599
600         return false;
601     } else if (IsSampler(pType.type)) {
602         error(line, reason, getBasicString(pType.type));
603
604         return true;
605     }
606
607     return false;
608 }
609
610 bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType)
611 {
612     if ((pType.qualifier == EvqVaryingIn || pType.qualifier == EvqVaryingOut || pType.qualifier == EvqAttribute) &&
613         pType.type == EbtStruct) {
614         error(line, "cannot be used with a structure", getQualifierString(pType.qualifier));
615
616         return true;
617     }
618
619     if (pType.qualifier != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform"))
620         return true;
621
622     return false;
623 }
624
625 bool TParseContext::parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type)
626 {
627     if ((qualifier == EvqOut || qualifier == EvqInOut) &&
628              type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
629         error(line, "samplers cannot be output parameters", type.getBasicString());
630         return true;
631     }
632
633     return false;
634 }
635
636 bool TParseContext::containsSampler(TType& type)
637 {
638     if (IsSampler(type.getBasicType()))
639         return true;
640
641     if (type.getBasicType() == EbtStruct) {
642         TTypeList& structure = *type.getStruct();
643         for (unsigned int i = 0; i < structure.size(); ++i) {
644             if (containsSampler(*structure[i].type))
645                 return true;
646         }
647     }
648
649     return false;
650 }
651
652 //
653 // Do size checking for an array type's size.
654 //
655 // Returns true if there was an error.
656 //
657 bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
658 {
659     TIntermConstantUnion* constant = expr->getAsConstantUnion();
660     if (constant == 0 || constant->getBasicType() != EbtInt) {
661         error(line, "array size must be a constant integer expression", "");
662         return true;
663     }
664
665     size = constant->getIConst(0);
666
667     if (size <= 0) {
668         error(line, "array size must be a positive integer", "");
669         size = 1;
670         return true;
671     }
672
673     return false;
674 }
675
676 //
677 // See if this qualifier can be an array.
678 //
679 // Returns true if there is an error.
680 //
681 bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type)
682 {
683     if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqConst)) {
684         error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str());
685         return true;
686     }
687
688     return false;
689 }
690
691 //
692 // See if this type can be an array.
693 //
694 // Returns true if there is an error.
695 //
696 bool TParseContext::arrayTypeErrorCheck(int line, TPublicType type)
697 {
698     //
699     // Can the type be an array?
700     //
701     if (type.array) {
702         error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str());
703         return true;
704     }
705
706     return false;
707 }
708
709 //
710 // Do all the semantic checking for declaring an array, with and
711 // without a size, and make the right changes to the symbol table.
712 //
713 // size == 0 means no specified size.
714 //
715 // Returns true if there was an error.
716 //
717 bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable)
718 {
719     //
720     // Don't check for reserved word use until after we know it's not in the symbol table,
721     // because reserved arrays can be redeclared.
722     //
723
724     bool builtIn = false;
725     bool sameScope = false;
726     TSymbol* symbol = symbolTable.find(identifier, &builtIn, &sameScope);
727     if (symbol == 0 || !sameScope) {
728         if (reservedErrorCheck(line, identifier))
729             return true;
730
731         variable = new TVariable(&identifier, TType(type));
732
733         if (type.arraySize)
734             variable->getType().setArraySize(type.arraySize);
735
736         if (! symbolTable.insert(*variable)) {
737             delete variable;
738             error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str());
739             return true;
740         }
741     } else {
742         if (! symbol->isVariable()) {
743             error(line, "variable expected", identifier.c_str());
744             return true;
745         }
746
747         variable = static_cast<TVariable*>(symbol);
748         if (! variable->getType().isArray()) {
749             error(line, "redeclaring non-array as array", identifier.c_str());
750             return true;
751         }
752         if (variable->getType().getArraySize() > 0) {
753             error(line, "redeclaration of array with size", identifier.c_str());
754             return true;
755         }
756
757         if (! variable->getType().sameElementType(TType(type))) {
758             error(line, "redeclaration of array with a different type", identifier.c_str());
759             return true;
760         }
761
762         TType* t = variable->getArrayInformationType();
763         while (t != 0) {
764             if (t->getMaxArraySize() > type.arraySize) {
765                 error(line, "higher index value already used for the array", identifier.c_str());
766                 return true;
767             }
768             t->setArraySize(type.arraySize);
769             t = t->getArrayInformationType();
770         }
771
772         if (type.arraySize)
773             variable->getType().setArraySize(type.arraySize);
774     }
775
776     if (voidErrorCheck(line, identifier, type))
777         return true;
778
779     return false;
780 }
781
782 bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, TSourceLoc line)
783 {
784     bool builtIn = false;
785     TSymbol* symbol = symbolTable.find(node->getSymbol(), &builtIn);
786     if (symbol == 0) {
787         error(line, " undeclared identifier", node->getSymbol().c_str());
788         return true;
789     }
790     TVariable* variable = static_cast<TVariable*>(symbol);
791
792     type->setArrayInformationType(variable->getArrayInformationType());
793     variable->updateArrayInformationType(type);
794
795     // special casing to test index value of gl_FragData. If the accessed index is >= gl_MaxDrawBuffers
796     // its an error
797     if (node->getSymbol() == "gl_FragData") {
798         TSymbol* fragData = symbolTable.find("gl_MaxDrawBuffers", &builtIn);
799         ASSERT(fragData);
800
801         int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst();
802         if (fragDataValue <= size) {
803             error(line, "", "[", "gl_FragData can only have a max array size of up to gl_MaxDrawBuffers");
804             return true;
805         }
806     }
807
808     // we dont want to update the maxArraySize when this flag is not set, we just want to include this
809     // node type in the chain of node types so that its updated when a higher maxArraySize comes in.
810     if (!updateFlag)
811         return false;
812
813     size++;
814     variable->getType().setMaxArraySize(size);
815     type->setMaxArraySize(size);
816     TType* tt = type;
817
818     while(tt->getArrayInformationType() != 0) {
819         tt = tt->getArrayInformationType();
820         tt->setMaxArraySize(size);
821     }
822
823     return false;
824 }
825
826 //
827 // Enforce non-initializer type/qualifier rules.
828 //
829 // Returns true if there was an error.
830 //
831 bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type, bool array)
832 {
833     if (type.qualifier == EvqConst)
834     {
835         // Make the qualifier make sense.
836         type.qualifier = EvqTemporary;
837
838         if (array)
839         {
840             error(line, "arrays may not be declared constant since they cannot be initialized", identifier.c_str());
841         }
842         else if (type.isStructureContainingArrays())
843         {
844             error(line, "structures containing arrays may not be declared constant since they cannot be initialized", identifier.c_str());
845         }
846         else
847         {
848             error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
849         }
850
851         return true;
852     }
853
854     return false;
855 }
856
857 //
858 // Do semantic checking for a variable declaration that has no initializer,
859 // and update the symbol table.
860 //
861 // Returns true if there was an error.
862 //
863 bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType& type, TVariable*& variable)
864 {
865     if (reservedErrorCheck(line, identifier))
866         recover();
867
868     variable = new TVariable(&identifier, TType(type));
869
870     if (! symbolTable.insert(*variable)) {
871         error(line, "redefinition", variable->getName().c_str());
872         delete variable;
873         variable = 0;
874         return true;
875     }
876
877     if (voidErrorCheck(line, identifier, type))
878         return true;
879
880     return false;
881 }
882
883 bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type)
884 {
885     if (qualifier != EvqConst && qualifier != EvqTemporary) {
886         error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier));
887         return true;
888     }
889     if (qualifier == EvqConst && paramQualifier != EvqIn) {
890         error(line, "qualifier not allowed with ", getQualifierString(qualifier), getQualifierString(paramQualifier));
891         return true;
892     }
893
894     if (qualifier == EvqConst)
895         type->setQualifier(EvqConstReadOnly);
896     else
897         type->setQualifier(paramQualifier);
898
899     return false;
900 }
901
902 bool TParseContext::extensionErrorCheck(int line, const TString& extension)
903 {
904     const TExtensionBehavior& extBehavior = extensionBehavior();
905     TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str());
906     if (iter == extBehavior.end()) {
907         error(line, "extension", extension.c_str(), "is not supported");
908         return true;
909     }
910     // In GLSL ES, an extension's default behavior is "disable".
911     if (iter->second == EBhDisable || iter->second == EBhUndefined) {
912         error(line, "extension", extension.c_str(), "is disabled");
913         return true;
914     }
915     if (iter->second == EBhWarn) {
916         warning(line, "extension", extension.c_str(), "is being used");
917         return false;
918     }
919
920     return false;
921 }
922
923 bool TParseContext::supportsExtension(const char* extension)
924 {
925     const TExtensionBehavior& extbehavior = extensionBehavior();
926     TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
927     return (iter != extbehavior.end());
928 }
929
930 void TParseContext::handleExtensionDirective(int line, const char* extName, const char* behavior)
931 {
932     pp::SourceLocation loc;
933     DecodeSourceLoc(line, &loc.file, &loc.line);
934     directiveHandler.handleExtension(loc, extName, behavior);
935 }
936
937 void TParseContext::handlePragmaDirective(int line, const char* name, const char* value)
938 {
939     pp::SourceLocation loc;
940     DecodeSourceLoc(line, &loc.file, &loc.line);
941     directiveHandler.handlePragma(loc, name, value);
942 }
943
944 /////////////////////////////////////////////////////////////////////////////////
945 //
946 // Non-Errors.
947 //
948 /////////////////////////////////////////////////////////////////////////////////
949
950 //
951 // Look up a function name in the symbol table, and make sure it is a function.
952 //
953 // Return the function symbol if found, otherwise 0.
954 //
955 const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *builtIn)
956 {
957     // First find by unmangled name to check whether the function name has been
958     // hidden by a variable name or struct typename.
959     const TSymbol* symbol = symbolTable.find(call->getName(), builtIn);
960     if (symbol == 0) {
961         symbol = symbolTable.find(call->getMangledName(), builtIn);
962     }
963
964     if (symbol == 0) {
965         error(line, "no matching overloaded function found", call->getName().c_str());
966         return 0;
967     }
968
969     if (!symbol->isFunction()) {
970         error(line, "function name expected", call->getName().c_str());
971         return 0;
972     }
973
974     return static_cast<const TFunction*>(symbol);
975 }
976
977 //
978 // Initializers show up in several places in the grammar.  Have one set of
979 // code to handle them here.
980 //
981 bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
982                                        TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable)
983 {
984     TType type = TType(pType);
985
986     if (variable == 0) {
987         if (reservedErrorCheck(line, identifier))
988             return true;
989
990         if (voidErrorCheck(line, identifier, pType))
991             return true;
992
993         //
994         // add variable to symbol table
995         //
996         variable = new TVariable(&identifier, type);
997         if (! symbolTable.insert(*variable)) {
998             error(line, "redefinition", variable->getName().c_str());
999             return true;
1000             // don't delete variable, it's used by error recovery, and the pool
1001             // pop will take care of the memory
1002         }
1003     }
1004
1005     //
1006     // identifier must be of type constant, a global, or a temporary
1007     //
1008     TQualifier qualifier = variable->getType().getQualifier();
1009     if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) {
1010         error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString());
1011         return true;
1012     }
1013     //
1014     // test for and propagate constant
1015     //
1016
1017     if (qualifier == EvqConst) {
1018         if (qualifier != initializer->getType().getQualifier()) {
1019             std::stringstream extraInfoStream;
1020             extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
1021             std::string extraInfo = extraInfoStream.str();
1022             error(line, " assigning non-constant to", "=", extraInfo.c_str());
1023             variable->getType().setQualifier(EvqTemporary);
1024             return true;
1025         }
1026         if (type != initializer->getType()) {
1027             error(line, " non-matching types for const initializer ",
1028                 variable->getType().getQualifierString());
1029             variable->getType().setQualifier(EvqTemporary);
1030             return true;
1031         }
1032         if (initializer->getAsConstantUnion()) {
1033             ConstantUnion* unionArray = variable->getConstPointer();
1034
1035             if (type.getObjectSize() == 1 && type.getBasicType() != EbtStruct) {
1036                 *unionArray = (initializer->getAsConstantUnion()->getUnionArrayPointer())[0];
1037             } else {
1038                 variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
1039             }
1040         } else if (initializer->getAsSymbolNode()) {
1041             const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol());
1042             const TVariable* tVar = static_cast<const TVariable*>(symbol);
1043
1044             ConstantUnion* constArray = tVar->getConstPointer();
1045             variable->shareConstPointer(constArray);
1046         } else {
1047             std::stringstream extraInfoStream;
1048             extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
1049             std::string extraInfo = extraInfoStream.str();
1050             error(line, " cannot assign to", "=", extraInfo.c_str());
1051             variable->getType().setQualifier(EvqTemporary);
1052             return true;
1053         }
1054     }
1055
1056     if (qualifier != EvqConst) {
1057         TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
1058         intermNode = intermediate.addAssign(EOpInitialize, intermSymbol, initializer, line);
1059         if (intermNode == 0) {
1060             assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
1061             return true;
1062         }
1063     } else
1064         intermNode = 0;
1065
1066     return false;
1067 }
1068
1069 bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
1070 {
1071     ASSERT(aggrNode != NULL);
1072     if (!aggrNode->isConstructor())
1073         return false;
1074
1075     bool allConstant = true;
1076
1077     // check if all the child nodes are constants so that they can be inserted into
1078     // the parent node
1079     TIntermSequence &sequence = aggrNode->getSequence() ;
1080     for (TIntermSequence::iterator p = sequence.begin(); p != sequence.end(); ++p) {
1081         if (!(*p)->getAsTyped()->getAsConstantUnion())
1082             return false;
1083     }
1084
1085     return allConstant;
1086 }
1087
1088 // This function is used to test for the correctness of the parameters passed to various constructor functions
1089 // and also convert them to the right datatype if it is allowed and required.
1090 //
1091 // Returns 0 for an error or the constructed node (aggregate or typed) for no error.
1092 //
1093 TIntermTyped* TParseContext::addConstructor(TIntermNode* arguments, const TType* type, TOperator op, TFunction* fnCall, TSourceLoc line)
1094 {
1095     TIntermAggregate *aggregateArguments = arguments->getAsAggregate();
1096
1097     if(!aggregateArguments)
1098     {
1099         aggregateArguments = new TIntermAggregate;
1100         aggregateArguments->getSequence().push_back(arguments);
1101     }
1102
1103     if(op == EOpConstructStruct)
1104     {
1105         TTypeList &fields = *type->getStruct();
1106         TIntermSequence &args = aggregateArguments->getSequence();
1107
1108         for(size_t i = 0; i < fields.size(); i++)
1109         {
1110             if(args[i]->getAsTyped()->getType() != *fields[i].type)
1111             {
1112                 error(line, "Structure constructor arguments do not match structure fields", "Error");
1113                 recover();
1114
1115                 return 0;
1116             }
1117         }
1118     }
1119
1120     // Turn the argument list itself into a constructor
1121     TIntermTyped *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
1122     TIntermTyped *constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type);
1123     if(constConstructor)
1124     {
1125         return constConstructor;
1126     }
1127
1128     return constructor;
1129 }
1130
1131 TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, const TType& type)
1132 {
1133     bool canBeFolded = areAllChildConst(aggrNode);
1134     aggrNode->setType(type);
1135     if (canBeFolded) {
1136         bool returnVal = false;
1137         ConstantUnion* unionArray = new ConstantUnion[type.getObjectSize()];
1138         if (aggrNode->getSequence().size() == 1)  {
1139             returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type, true);
1140         }
1141         else {
1142             returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type);
1143         }
1144         if (returnVal)
1145             return 0;
1146
1147         return intermediate.addConstantUnion(unionArray, type, aggrNode->getLine());
1148     }
1149
1150     return 0;
1151 }
1152
1153 //
1154 // This function returns the tree representation for the vector field(s) being accessed from contant vector.
1155 // If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a contant node is
1156 // returned, else an aggregate node is returned (for v.xy). The input to this function could either be the symbol
1157 // node or it could be the intermediate tree representation of accessing fields in a constant structure or column of 
1158 // a constant matrix.
1159 //
1160 TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, TSourceLoc line)
1161 {
1162     TIntermTyped* typedNode;
1163     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
1164
1165     ConstantUnion *unionArray;
1166     if (tempConstantNode) {
1167         unionArray = tempConstantNode->getUnionArrayPointer();
1168
1169         if (!unionArray) {
1170             return node;
1171         }
1172     } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
1173         error(line, "Cannot offset into the vector", "Error");
1174         recover();
1175
1176         return 0;
1177     }
1178
1179     ConstantUnion* constArray = new ConstantUnion[fields.num];
1180
1181     for (int i = 0; i < fields.num; i++) {
1182         if (fields.offsets[i] >= node->getType().getObjectSize()) {
1183             std::stringstream extraInfoStream;
1184             extraInfoStream << "vector field selection out of range '" << fields.offsets[i] << "'";
1185             std::string extraInfo = extraInfoStream.str();
1186             error(line, "", "[", extraInfo.c_str());
1187             recover();
1188             fields.offsets[i] = 0;
1189         }
1190
1191         constArray[i] = unionArray[fields.offsets[i]];
1192
1193     }
1194     typedNode = intermediate.addConstantUnion(constArray, node->getType(), line);
1195     return typedNode;
1196 }
1197
1198 //
1199 // This function returns the column being accessed from a constant matrix. The values are retrieved from
1200 // the symbol table and parse-tree is built for a vector (each column of a matrix is a vector). The input
1201 // to the function could either be a symbol node (m[0] where m is a constant matrix)that represents a
1202 // constant matrix or it could be the tree representation of the constant matrix (s.m1[0] where s is a constant structure)
1203 //
1204 TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, TSourceLoc line)
1205 {
1206     TIntermTyped* typedNode;
1207     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
1208
1209     if (index >= node->getType().getNominalSize()) {
1210         std::stringstream extraInfoStream;
1211         extraInfoStream << "matrix field selection out of range '" << index << "'";
1212         std::string extraInfo = extraInfoStream.str();
1213         error(line, "", "[", extraInfo.c_str());
1214         recover();
1215         index = 0;
1216     }
1217
1218     if (tempConstantNode) {
1219          ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
1220          int size = tempConstantNode->getType().getNominalSize();
1221          typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line);
1222     } else {
1223         error(line, "Cannot offset into the matrix", "Error");
1224         recover();
1225
1226         return 0;
1227     }
1228
1229     return typedNode;
1230 }
1231
1232
1233 //
1234 // This function returns an element of an array accessed from a constant array. The values are retrieved from
1235 // the symbol table and parse-tree is built for the type of the element. The input
1236 // to the function could either be a symbol node (a[0] where a is a constant array)that represents a
1237 // constant array or it could be the tree representation of the constant array (s.a1[0] where s is a constant structure)
1238 //
1239 TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line)
1240 {
1241     TIntermTyped* typedNode;
1242     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
1243     TType arrayElementType = node->getType();
1244     arrayElementType.clearArrayness();
1245
1246     if (index >= node->getType().getArraySize()) {
1247         std::stringstream extraInfoStream;
1248         extraInfoStream << "array field selection out of range '" << index << "'";
1249         std::string extraInfo = extraInfoStream.str();
1250         error(line, "", "[", extraInfo.c_str());
1251         recover();
1252         index = 0;
1253     }
1254
1255     int arrayElementSize = arrayElementType.getObjectSize();
1256
1257     if (tempConstantNode) {
1258          ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
1259          typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line);
1260     } else {
1261         error(line, "Cannot offset into the array", "Error");
1262         recover();
1263
1264         return 0;
1265     }
1266
1267     return typedNode;
1268 }
1269
1270
1271 //
1272 // This function returns the value of a particular field inside a constant structure from the symbol table.
1273 // If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr
1274 // function and returns the parse-tree with the values of the embedded/nested struct.
1275 //
1276 TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc line)
1277 {
1278     const TTypeList* fields = node->getType().getStruct();
1279     TIntermTyped *typedNode;
1280     int instanceSize = 0;
1281     unsigned int index = 0;
1282     TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
1283
1284     for ( index = 0; index < fields->size(); ++index) {
1285         if ((*fields)[index].type->getFieldName() == identifier) {
1286             break;
1287         } else {
1288             instanceSize += (*fields)[index].type->getObjectSize();
1289         }
1290     }
1291
1292     if (tempConstantNode) {
1293          ConstantUnion* constArray = tempConstantNode->getUnionArrayPointer();
1294
1295          typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function
1296     } else {
1297         error(line, "Cannot offset into the structure", "Error");
1298         recover();
1299
1300         return 0;
1301     }
1302
1303     return typedNode;
1304 }
1305
1306 bool TParseContext::enterStructDeclaration(int line, const TString& identifier)
1307 {
1308     ++structNestingLevel;
1309
1310     // Embedded structure definitions are not supported per GLSL ES spec.
1311     // They aren't allowed in GLSL either, but we need to detect this here
1312     // so we don't rely on the GLSL compiler to catch it.
1313     if (structNestingLevel > 1) {
1314         error(line, "", "Embedded struct definitions are not allowed");
1315         return true;
1316     }
1317
1318     return false;
1319 }
1320
1321 void TParseContext::exitStructDeclaration()
1322 {
1323     --structNestingLevel;
1324 }
1325
1326 //
1327 // Parse an array of strings using yyparse.
1328 //
1329 // Returns 0 for success.
1330 //
1331 int PaParseStrings(int count, const char* const string[], const int length[],
1332                    TParseContext* context) {
1333     if ((count == 0) || (string == NULL))
1334         return 1;
1335
1336     if (glslang_initialize(context))
1337         return 1;
1338
1339     int error = glslang_scan(count, string, length, context);
1340     if (!error)
1341         error = glslang_parse(context);
1342
1343     glslang_finalize(context);
1344
1345     return (error == 0) && (context->numErrors() == 0) ? 0 : 1;
1346 }
1347
1348
1349