OSDN Git Service

Completing GLES 3.0 language parser
[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 EvqConstExpr:      message = "can't modify a const";        break;
315     case EvqConstReadOnly:  message = "can't modify a const";        break;
316     case EvqAttribute:      message = "can't modify an attribute";   break;
317     case 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() == EvqConstExpr)
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->isScalarInt())
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() != EvqConstExpr)
489             constType = false;
490         if (param.type->isArray())
491             arrayArg = true;
492     }
493
494     if (constType)
495         type->setQualifier(EvqConstExpr);
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.primarySize > 1) || (pType.secondarySize > 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
661     if (constant == 0 || !constant->isScalarInt())
662     {
663         error(line, "array size must be a constant integer expression", "");
664         return true;
665     }
666
667     if (constant->getBasicType() == EbtUInt)
668     {
669         unsigned int uintSize = constant->getUConst(0);
670         if (uintSize > static_cast<unsigned int>(std::numeric_limits<int>::max()))
671         {
672             error(line, "array size too large", "");
673             size = 1;
674             return true;
675         }
676
677         size = static_cast<int>(uintSize);
678     }
679     else
680     {
681         size = constant->getIConst(0);
682
683         if (size <= 0)
684         {
685             error(line, "array size must be a positive integer", "");
686             size = 1;
687             return true;
688         }
689     }
690
691     return false;
692 }
693
694 //
695 // See if this qualifier can be an array.
696 //
697 // Returns true if there is an error.
698 //
699 bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type)
700 {
701     if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqConstExpr)) {
702         error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str());
703         return true;
704     }
705
706     return false;
707 }
708
709 //
710 // See if this type can be an array.
711 //
712 // Returns true if there is an error.
713 //
714 bool TParseContext::arrayTypeErrorCheck(int line, TPublicType type)
715 {
716     //
717     // Can the type be an array?
718     //
719     if (type.array) {
720         error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str());
721         return true;
722     }
723
724     return false;
725 }
726
727 //
728 // Do all the semantic checking for declaring an array, with and
729 // without a size, and make the right changes to the symbol table.
730 //
731 // size == 0 means no specified size.
732 //
733 // Returns true if there was an error.
734 //
735 bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable)
736 {
737     //
738     // Don't check for reserved word use until after we know it's not in the symbol table,
739     // because reserved arrays can be redeclared.
740     //
741
742     bool builtIn = false;
743     bool sameScope = false;
744     TSymbol* symbol = symbolTable.find(identifier, shaderVersion, &builtIn, &sameScope);
745     if (symbol == 0 || !sameScope) {
746         if (reservedErrorCheck(line, identifier))
747             return true;
748
749         variable = new TVariable(&identifier, TType(type));
750
751         if (type.arraySize)
752             variable->getType().setArraySize(type.arraySize);
753
754         if (! symbolTable.declare(*variable)) {
755             delete variable;
756             error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str());
757             return true;
758         }
759     } else {
760         if (! symbol->isVariable()) {
761             error(line, "variable expected", identifier.c_str());
762             return true;
763         }
764
765         variable = static_cast<TVariable*>(symbol);
766         if (! variable->getType().isArray()) {
767             error(line, "redeclaring non-array as array", identifier.c_str());
768             return true;
769         }
770         if (variable->getType().getArraySize() > 0) {
771             error(line, "redeclaration of array with size", identifier.c_str());
772             return true;
773         }
774
775         if (! variable->getType().sameElementType(TType(type))) {
776             error(line, "redeclaration of array with a different type", identifier.c_str());
777             return true;
778         }
779
780         TType* t = variable->getArrayInformationType();
781         while (t != 0) {
782             if (t->getMaxArraySize() > type.arraySize) {
783                 error(line, "higher index value already used for the array", identifier.c_str());
784                 return true;
785             }
786             t->setArraySize(type.arraySize);
787             t = t->getArrayInformationType();
788         }
789
790         if (type.arraySize)
791             variable->getType().setArraySize(type.arraySize);
792     }
793
794     if (voidErrorCheck(line, identifier, type))
795         return true;
796
797     return false;
798 }
799
800 bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, TSourceLoc line)
801 {
802     bool builtIn = false;
803     TSymbol* symbol = symbolTable.find(node->getSymbol(), shaderVersion, &builtIn);
804     if (symbol == 0) {
805         error(line, " undeclared identifier", node->getSymbol().c_str());
806         return true;
807     }
808     TVariable* variable = static_cast<TVariable*>(symbol);
809
810     type->setArrayInformationType(variable->getArrayInformationType());
811     variable->updateArrayInformationType(type);
812
813     // special casing to test index value of gl_FragData. If the accessed index is >= gl_MaxDrawBuffers
814     // its an error
815     if (node->getSymbol() == "gl_FragData") {
816         TSymbol* fragData = symbolTable.find("gl_MaxDrawBuffers", shaderVersion, &builtIn);
817         ASSERT(fragData);
818
819         int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst();
820         if (fragDataValue <= size) {
821             error(line, "", "[", "gl_FragData can only have a max array size of up to gl_MaxDrawBuffers");
822             return true;
823         }
824     }
825
826     // we dont want to update the maxArraySize when this flag is not set, we just want to include this
827     // node type in the chain of node types so that its updated when a higher maxArraySize comes in.
828     if (!updateFlag)
829         return false;
830
831     size++;
832     variable->getType().setMaxArraySize(size);
833     type->setMaxArraySize(size);
834     TType* tt = type;
835
836     while(tt->getArrayInformationType() != 0) {
837         tt = tt->getArrayInformationType();
838         tt->setMaxArraySize(size);
839     }
840
841     return false;
842 }
843
844 //
845 // Enforce non-initializer type/qualifier rules.
846 //
847 // Returns true if there was an error.
848 //
849 bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type, bool array)
850 {
851     if (type.qualifier == EvqConstExpr)
852     {
853         // Make the qualifier make sense.
854         type.qualifier = EvqTemporary;
855
856         if (array)
857         {
858             error(line, "arrays may not be declared constant since they cannot be initialized", identifier.c_str());
859         }
860         else if (type.isStructureContainingArrays())
861         {
862             error(line, "structures containing arrays may not be declared constant since they cannot be initialized", identifier.c_str());
863         }
864         else
865         {
866             error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
867         }
868
869         return true;
870     }
871
872     return false;
873 }
874
875 //
876 // Do semantic checking for a variable declaration that has no initializer,
877 // and update the symbol table.
878 //
879 // Returns true if there was an error.
880 //
881 bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType& type, TVariable*& variable)
882 {
883     if (reservedErrorCheck(line, identifier))
884         recover();
885
886     variable = new TVariable(&identifier, TType(type));
887
888     if (! symbolTable.declare(*variable)) {
889         error(line, "redefinition", variable->getName().c_str());
890         delete variable;
891         variable = 0;
892         return true;
893     }
894
895     if (voidErrorCheck(line, identifier, type))
896         return true;
897
898     return false;
899 }
900
901 bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type)
902 {
903     if (qualifier != EvqConstReadOnly && qualifier != EvqTemporary) {
904         error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier));
905         return true;
906     }
907     if (qualifier == EvqConstReadOnly && paramQualifier != EvqIn) {
908         error(line, "qualifier not allowed with ", getQualifierString(qualifier), getQualifierString(paramQualifier));
909         return true;
910     }
911
912     if (qualifier == EvqConstReadOnly)
913         type->setQualifier(EvqConstReadOnly);
914     else
915         type->setQualifier(paramQualifier);
916
917     return false;
918 }
919
920 bool TParseContext::extensionErrorCheck(int line, const TString& extension)
921 {
922     const TExtensionBehavior& extBehavior = extensionBehavior();
923     TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str());
924     if (iter == extBehavior.end()) {
925         error(line, "extension", extension.c_str(), "is not supported");
926         return true;
927     }
928     // In GLSL ES, an extension's default behavior is "disable".
929     if (iter->second == EBhDisable || iter->second == EBhUndefined) {
930         error(line, "extension", extension.c_str(), "is disabled");
931         return true;
932     }
933     if (iter->second == EBhWarn) {
934         warning(line, "extension", extension.c_str(), "is being used");
935         return false;
936     }
937
938     return false;
939 }
940
941 bool TParseContext::supportsExtension(const char* extension)
942 {
943     const TExtensionBehavior& extbehavior = extensionBehavior();
944     TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
945     return (iter != extbehavior.end());
946 }
947
948 void TParseContext::handleExtensionDirective(int line, const char* extName, const char* behavior)
949 {
950     pp::SourceLocation loc;
951     DecodeSourceLoc(line, &loc.file, &loc.line);
952     directiveHandler.handleExtension(loc, extName, behavior);
953 }
954
955 void TParseContext::handlePragmaDirective(int line, const char* name, const char* value)
956 {
957     pp::SourceLocation loc;
958     DecodeSourceLoc(line, &loc.file, &loc.line);
959     directiveHandler.handlePragma(loc, name, value);
960 }
961
962 /////////////////////////////////////////////////////////////////////////////////
963 //
964 // Non-Errors.
965 //
966 /////////////////////////////////////////////////////////////////////////////////
967
968 //
969 // Look up a function name in the symbol table, and make sure it is a function.
970 //
971 // Return the function symbol if found, otherwise 0.
972 //
973 const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *builtIn)
974 {
975     // First find by unmangled name to check whether the function name has been
976     // hidden by a variable name or struct typename.
977     const TSymbol* symbol = symbolTable.find(call->getName(), shaderVersion, builtIn);
978     if (symbol == 0) {
979         symbol = symbolTable.find(call->getMangledName(), shaderVersion, builtIn);
980     }
981
982     if (symbol == 0) {
983         error(line, "no matching overloaded function found", call->getName().c_str());
984         return 0;
985     }
986
987     if (!symbol->isFunction()) {
988         error(line, "function name expected", call->getName().c_str());
989         return 0;
990     }
991
992     return static_cast<const TFunction*>(symbol);
993 }
994
995 //
996 // Initializers show up in several places in the grammar.  Have one set of
997 // code to handle them here.
998 //
999 bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
1000                                        TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable)
1001 {
1002     TType type = TType(pType);
1003
1004     if (variable == 0) {
1005         if (reservedErrorCheck(line, identifier))
1006             return true;
1007
1008         if (voidErrorCheck(line, identifier, pType))
1009             return true;
1010
1011         //
1012         // add variable to symbol table
1013         //
1014         variable = new TVariable(&identifier, type);
1015         if (! symbolTable.declare(*variable)) {
1016             error(line, "redefinition", variable->getName().c_str());
1017             return true;
1018             // don't delete variable, it's used by error recovery, and the pool
1019             // pop will take care of the memory
1020         }
1021     }
1022
1023     //
1024     // identifier must be of type constant, a global, or a temporary
1025     //
1026     TQualifier qualifier = variable->getType().getQualifier();
1027     if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConstExpr)) {
1028         error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString());
1029         return true;
1030     }
1031     //
1032     // test for and propagate constant
1033     //
1034
1035     if (qualifier == EvqConstExpr) {
1036         if (qualifier != initializer->getType().getQualifier()) {
1037             std::stringstream extraInfoStream;
1038             extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
1039             std::string extraInfo = extraInfoStream.str();
1040             error(line, " assigning non-constant to", "=", extraInfo.c_str());
1041             variable->getType().setQualifier(EvqTemporary);
1042             return true;
1043         }
1044         if (type != initializer->getType()) {
1045             error(line, " non-matching types for const initializer ",
1046                 variable->getType().getQualifierString());
1047             variable->getType().setQualifier(EvqTemporary);
1048             return true;
1049         }
1050         if (initializer->getAsConstantUnion()) {
1051             ConstantUnion* unionArray = variable->getConstPointer();
1052
1053             if (type.getObjectSize() == 1 && type.getBasicType() != EbtStruct) {
1054                 *unionArray = (initializer->getAsConstantUnion()->getUnionArrayPointer())[0];
1055             } else {
1056                 variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
1057             }
1058         } else if (initializer->getAsSymbolNode()) {
1059             const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), shaderVersion);
1060             const TVariable* tVar = static_cast<const TVariable*>(symbol);
1061
1062             ConstantUnion* constArray = tVar->getConstPointer();
1063             variable->shareConstPointer(constArray);
1064         } else {
1065             std::stringstream extraInfoStream;
1066             extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
1067             std::string extraInfo = extraInfoStream.str();
1068             error(line, " cannot assign to", "=", extraInfo.c_str());
1069             variable->getType().setQualifier(EvqTemporary);
1070             return true;
1071         }
1072     }
1073
1074     if (qualifier != EvqConstExpr) {
1075         TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
1076         intermNode = intermediate.addAssign(EOpInitialize, intermSymbol, initializer, line);
1077         if (intermNode == 0) {
1078             assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
1079             return true;
1080         }
1081     } else
1082         intermNode = 0;
1083
1084     return false;
1085 }
1086
1087 bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
1088 {
1089     ASSERT(aggrNode != NULL);
1090     if (!aggrNode->isConstructor())
1091         return false;
1092
1093     bool allConstant = true;
1094
1095     // check if all the child nodes are constants so that they can be inserted into
1096     // the parent node
1097     TIntermSequence &sequence = aggrNode->getSequence() ;
1098     for (TIntermSequence::iterator p = sequence.begin(); p != sequence.end(); ++p) {
1099         if (!(*p)->getAsTyped()->getAsConstantUnion())
1100             return false;
1101     }
1102
1103     return allConstant;
1104 }
1105
1106 // This function is used to test for the correctness of the parameters passed to various constructor functions
1107 // and also convert them to the right datatype if it is allowed and required.
1108 //
1109 // Returns 0 for an error or the constructed node (aggregate or typed) for no error.
1110 //
1111 TIntermTyped* TParseContext::addConstructor(TIntermNode* arguments, const TType* type, TOperator op, TFunction* fnCall, TSourceLoc line)
1112 {
1113     TIntermAggregate *aggregateArguments = arguments->getAsAggregate();
1114
1115     if(!aggregateArguments)
1116     {
1117         aggregateArguments = new TIntermAggregate;
1118         aggregateArguments->getSequence().push_back(arguments);
1119     }
1120
1121     if(op == EOpConstructStruct)
1122     {
1123         TTypeList &fields = *type->getStruct();
1124         TIntermSequence &args = aggregateArguments->getSequence();
1125
1126         for(size_t i = 0; i < fields.size(); i++)
1127         {
1128             if(args[i]->getAsTyped()->getType() != *fields[i].type)
1129             {
1130                 error(line, "Structure constructor arguments do not match structure fields", "Error");
1131                 recover();
1132
1133                 return 0;
1134             }
1135         }
1136     }
1137
1138     // Turn the argument list itself into a constructor
1139     TIntermTyped *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
1140     TIntermTyped *constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type);
1141     if(constConstructor)
1142     {
1143         return constConstructor;
1144     }
1145
1146     return constructor;
1147 }
1148
1149 TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, const TType& type)
1150 {
1151     bool canBeFolded = areAllChildConst(aggrNode);
1152     aggrNode->setType(type);
1153     if (canBeFolded) {
1154         bool returnVal = false;
1155         ConstantUnion* unionArray = new ConstantUnion[type.getObjectSize()];
1156         if (aggrNode->getSequence().size() == 1)  {
1157             returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type, true);
1158         }
1159         else {
1160             returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type);
1161         }
1162         if (returnVal)
1163             return 0;
1164
1165         return intermediate.addConstantUnion(unionArray, type, aggrNode->getLine());
1166     }
1167
1168     return 0;
1169 }
1170
1171 //
1172 // This function returns the tree representation for the vector field(s) being accessed from contant vector.
1173 // If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a contant node is
1174 // returned, else an aggregate node is returned (for v.xy). The input to this function could either be the symbol
1175 // node or it could be the intermediate tree representation of accessing fields in a constant structure or column of 
1176 // a constant matrix.
1177 //
1178 TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, TSourceLoc line)
1179 {
1180     TIntermTyped* typedNode;
1181     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
1182
1183     ConstantUnion *unionArray;
1184     if (tempConstantNode) {
1185         unionArray = tempConstantNode->getUnionArrayPointer();
1186
1187         if (!unionArray) {
1188             return node;
1189         }
1190     } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
1191         error(line, "Cannot offset into the vector", "Error");
1192         recover();
1193
1194         return 0;
1195     }
1196
1197     ConstantUnion* constArray = new ConstantUnion[fields.num];
1198
1199     for (int i = 0; i < fields.num; i++) {
1200         if (fields.offsets[i] >= node->getType().getObjectSize()) {
1201             std::stringstream extraInfoStream;
1202             extraInfoStream << "vector field selection out of range '" << fields.offsets[i] << "'";
1203             std::string extraInfo = extraInfoStream.str();
1204             error(line, "", "[", extraInfo.c_str());
1205             recover();
1206             fields.offsets[i] = 0;
1207         }
1208
1209         constArray[i] = unionArray[fields.offsets[i]];
1210
1211     }
1212     typedNode = intermediate.addConstantUnion(constArray, node->getType(), line);
1213     return typedNode;
1214 }
1215
1216 //
1217 // This function returns the column being accessed from a constant matrix. The values are retrieved from
1218 // the symbol table and parse-tree is built for a vector (each column of a matrix is a vector). The input
1219 // to the function could either be a symbol node (m[0] where m is a constant matrix)that represents a
1220 // constant matrix or it could be the tree representation of the constant matrix (s.m1[0] where s is a constant structure)
1221 //
1222 TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, TSourceLoc line)
1223 {
1224     TIntermTyped* typedNode;
1225     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
1226
1227     if (index >= node->getType().getNominalSize()) {
1228         std::stringstream extraInfoStream;
1229         extraInfoStream << "matrix field selection out of range '" << index << "'";
1230         std::string extraInfo = extraInfoStream.str();
1231         error(line, "", "[", extraInfo.c_str());
1232         recover();
1233         index = 0;
1234     }
1235
1236     if (tempConstantNode) {
1237          ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
1238          int size = tempConstantNode->getType().getNominalSize();
1239          typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line);
1240     } else {
1241         error(line, "Cannot offset into the matrix", "Error");
1242         recover();
1243
1244         return 0;
1245     }
1246
1247     return typedNode;
1248 }
1249
1250
1251 //
1252 // This function returns an element of an array accessed from a constant array. The values are retrieved from
1253 // the symbol table and parse-tree is built for the type of the element. The input
1254 // to the function could either be a symbol node (a[0] where a is a constant array)that represents a
1255 // constant array or it could be the tree representation of the constant array (s.a1[0] where s is a constant structure)
1256 //
1257 TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line)
1258 {
1259     TIntermTyped* typedNode;
1260     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
1261     TType arrayElementType = node->getType();
1262     arrayElementType.clearArrayness();
1263
1264     if (index >= node->getType().getArraySize()) {
1265         std::stringstream extraInfoStream;
1266         extraInfoStream << "array field selection out of range '" << index << "'";
1267         std::string extraInfo = extraInfoStream.str();
1268         error(line, "", "[", extraInfo.c_str());
1269         recover();
1270         index = 0;
1271     }
1272
1273     int arrayElementSize = arrayElementType.getObjectSize();
1274
1275     if (tempConstantNode) {
1276          ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
1277          typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line);
1278     } else {
1279         error(line, "Cannot offset into the array", "Error");
1280         recover();
1281
1282         return 0;
1283     }
1284
1285     return typedNode;
1286 }
1287
1288
1289 //
1290 // This function returns the value of a particular field inside a constant structure from the symbol table.
1291 // If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr
1292 // function and returns the parse-tree with the values of the embedded/nested struct.
1293 //
1294 TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc line)
1295 {
1296     const TTypeList* fields = node->getType().getStruct();
1297     TIntermTyped *typedNode;
1298     int instanceSize = 0;
1299     unsigned int index = 0;
1300     TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
1301
1302     for ( index = 0; index < fields->size(); ++index) {
1303         if ((*fields)[index].type->getFieldName() == identifier) {
1304             break;
1305         } else {
1306             instanceSize += (*fields)[index].type->getObjectSize();
1307         }
1308     }
1309
1310     if (tempConstantNode) {
1311          ConstantUnion* constArray = tempConstantNode->getUnionArrayPointer();
1312
1313          typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function
1314     } else {
1315         error(line, "Cannot offset into the structure", "Error");
1316         recover();
1317
1318         return 0;
1319     }
1320
1321     return typedNode;
1322 }
1323
1324 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine)
1325 {
1326     TLayoutQualifier qualifier;
1327
1328     qualifier.location = -1;
1329
1330     if (qualifierType == "location")
1331     {
1332         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "location requires an argument");
1333         recover();
1334     }
1335     else
1336     {
1337         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
1338         recover();
1339     }
1340
1341     return qualifier;
1342 }
1343
1344 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine)
1345 {
1346     TLayoutQualifier qualifier;
1347
1348     qualifier.location = -1;
1349
1350     if (qualifierType != "location")
1351     {
1352         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "only location may have arguments");
1353         recover();
1354     }
1355     else
1356     {
1357         // must check that location is non-negative
1358         if (intValue < 0)
1359         {
1360             error(intValueLine, "out of range:", intValueString.c_str(), "location must be non-negative");
1361             recover();
1362         }
1363         else
1364         {
1365             qualifier.location = intValue;
1366         }
1367     }
1368
1369     return qualifier;
1370 }
1371
1372 TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier)
1373 {
1374     TLayoutQualifier joinedQualifier = leftQualifier;
1375
1376     if (rightQualifier.location != -1)
1377     {
1378         joinedQualifier.location = rightQualifier.location;
1379     }
1380
1381     return joinedQualifier;
1382 }
1383
1384 bool TParseContext::enterStructDeclaration(int line, const TString& identifier)
1385 {
1386     ++structNestingLevel;
1387
1388     // Embedded structure definitions are not supported per GLSL ES spec.
1389     // They aren't allowed in GLSL either, but we need to detect this here
1390     // so we don't rely on the GLSL compiler to catch it.
1391     if (structNestingLevel > 1) {
1392         error(line, "", "Embedded struct definitions are not allowed");
1393         return true;
1394     }
1395
1396     return false;
1397 }
1398
1399 void TParseContext::exitStructDeclaration()
1400 {
1401     --structNestingLevel;
1402 }
1403
1404 //
1405 // Parse an array of strings using yyparse.
1406 //
1407 // Returns 0 for success.
1408 //
1409 int PaParseStrings(int count, const char* const string[], const int length[],
1410                    TParseContext* context) {
1411     if ((count == 0) || (string == NULL))
1412         return 1;
1413
1414     if (glslang_initialize(context))
1415         return 1;
1416
1417     int error = glslang_scan(count, string, length, context);
1418     if (!error)
1419         error = glslang_parse(context);
1420
1421     glslang_finalize(context);
1422
1423     return (error == 0) && (context->numErrors() == 0) ? 0 : 1;
1424 }
1425
1426
1427