OSDN Git Service

Rename the GLES2 folder to OpenGL.
[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 "compiler/ParseHelper.h"
8
9 #include <stdarg.h>
10 #include <stdio.h>
11
12 #include "compiler/glslang.h"
13 #include "compiler/preprocessor/SourceLocation.h"
14
15 ///////////////////////////////////////////////////////////////////////
16 //
17 // Sub- vector and matrix fields
18 //
19 ////////////////////////////////////////////////////////////////////////
20
21 //
22 // Look at a '.' field selector string and change it into offsets
23 // for a vector.
24 //
25 bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, 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()->getUnionArrayPointer()->getIConst();
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 (shaderSpec == SH_WEBGL_SPEC) {
436             if (identifier.compare(0, 6, "webgl_") == 0) {
437                 error(line, reservedErrMsg, "webgl_");
438                 return true;
439             }
440             if (identifier.compare(0, 7, "_webgl_") == 0) {
441                 error(line, reservedErrMsg, "_webgl_");
442                 return true;
443             }
444         }
445         if (identifier.find("__") != TString::npos) {
446             error(line, "identifiers containing two consecutive underscores (__) are reserved as possible future keywords", identifier.c_str());
447             return true;
448         }
449     }
450
451     return false;
452 }
453
454 //
455 // Make sure there is enough data provided to the constructor to build
456 // something of the type of the constructor.  Also returns the type of
457 // the constructor.
458 //
459 // Returns true if there was an error in construction.
460 //
461 bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction& function, TOperator op, TType* type)
462 {
463     *type = function.getReturnType();
464
465     bool constructingMatrix = false;
466     switch(op) {
467     case EOpConstructMat2:
468     case EOpConstructMat3:
469     case EOpConstructMat4:
470         constructingMatrix = true;
471         break;
472     default:
473         break;
474     }
475
476     //
477     // Note: It's okay to have too many components available, but not okay to have unused
478     // arguments.  'full' will go to true when enough args have been seen.  If we loop
479     // again, there is an extra argument, so 'overfull' will become true.
480     //
481
482     int size = 0;
483     bool constType = true;
484     bool full = false;
485     bool overFull = false;
486     bool matrixInMatrix = false;
487     bool arrayArg = false;
488     for (int i = 0; i < function.getParamCount(); ++i) {
489         const TParameter& param = function.getParam(i);
490         size += param.type->getObjectSize();
491
492         if (constructingMatrix && param.type->isMatrix())
493             matrixInMatrix = true;
494         if (full)
495             overFull = true;
496         if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize())
497             full = true;
498         if (param.type->getQualifier() != EvqConst)
499             constType = false;
500         if (param.type->isArray())
501             arrayArg = true;
502     }
503
504     if (constType)
505         type->setQualifier(EvqConst);
506
507     if (type->isArray() && type->getArraySize() != function.getParamCount()) {
508         error(line, "array constructor needs one argument per array element", "constructor");
509         return true;
510     }
511
512     if (arrayArg && op != EOpConstructStruct) {
513         error(line, "constructing from a non-dereferenced array", "constructor");
514         return true;
515     }
516
517     if (matrixInMatrix && !type->isArray()) {
518         if (function.getParamCount() != 1) {
519           error(line, "constructing matrix from matrix can only take one argument", "constructor");
520           return true;
521         }
522     }
523
524     if (overFull) {
525         error(line, "too many arguments", "constructor");
526         return true;
527     }
528
529     if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->size()) != function.getParamCount()) {
530         error(line, "Number of constructor parameters does not match the number of structure fields", "constructor");
531         return true;
532     }
533
534     if (!type->isMatrix() || !matrixInMatrix) {
535         if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) ||
536             (op == EOpConstructStruct && size < type->getObjectSize())) {
537             error(line, "not enough data provided for construction", "constructor");
538             return true;
539         }
540     }
541
542     TIntermTyped *typed = node ? node->getAsTyped() : 0;
543     if (typed == 0) {
544         error(line, "constructor argument does not have a type", "constructor");
545         return true;
546     }
547     if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) {
548         error(line, "cannot convert a sampler", "constructor");
549         return true;
550     }
551     if (typed->getBasicType() == EbtVoid) {
552         error(line, "cannot convert a void", "constructor");
553         return true;
554     }
555
556     return false;
557 }
558
559 // This function checks to see if a void variable has been declared and raise an error message for such a case
560 //
561 // returns true in case of an error
562 //
563 bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TPublicType& pubType)
564 {
565     if (pubType.type == EbtVoid) {
566         error(line, "illegal use of type 'void'", identifier.c_str());
567         return true;
568     }
569
570     return false;
571 }
572
573 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
574 //
575 // returns true in case of an error
576 //
577 bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type)
578 {
579     if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) {
580         error(line, "boolean expression expected", "");
581         return true;
582     }
583
584     return false;
585 }
586
587 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
588 //
589 // returns true in case of an error
590 //
591 bool TParseContext::boolErrorCheck(int line, const TPublicType& pType)
592 {
593     if (pType.type != EbtBool || pType.array || pType.matrix || (pType.size > 1)) {
594         error(line, "boolean expression expected", "");
595         return true;
596     }
597
598     return false;
599 }
600
601 bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const char* reason)
602 {
603     if (pType.type == EbtStruct) {
604         if (containsSampler(*pType.userDef)) {
605             error(line, reason, getBasicString(pType.type), "(structure contains a sampler)");
606
607             return true;
608         }
609
610         return false;
611     } else if (IsSampler(pType.type)) {
612         error(line, reason, getBasicString(pType.type));
613
614         return true;
615     }
616
617     return false;
618 }
619
620 bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType)
621 {
622     if ((pType.qualifier == EvqVaryingIn || pType.qualifier == EvqVaryingOut || pType.qualifier == EvqAttribute) &&
623         pType.type == EbtStruct) {
624         error(line, "cannot be used with a structure", getQualifierString(pType.qualifier));
625
626         return true;
627     }
628
629     if (pType.qualifier != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform"))
630         return true;
631
632     return false;
633 }
634
635 bool TParseContext::parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type)
636 {
637     if ((qualifier == EvqOut || qualifier == EvqInOut) &&
638              type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
639         error(line, "samplers cannot be output parameters", type.getBasicString());
640         return true;
641     }
642
643     return false;
644 }
645
646 bool TParseContext::containsSampler(TType& type)
647 {
648     if (IsSampler(type.getBasicType()))
649         return true;
650
651     if (type.getBasicType() == EbtStruct) {
652         TTypeList& structure = *type.getStruct();
653         for (unsigned int i = 0; i < structure.size(); ++i) {
654             if (containsSampler(*structure[i].type))
655                 return true;
656         }
657     }
658
659     return false;
660 }
661
662 //
663 // Do size checking for an array type's size.
664 //
665 // Returns true if there was an error.
666 //
667 bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
668 {
669     TIntermConstantUnion* constant = expr->getAsConstantUnion();
670     if (constant == 0 || constant->getBasicType() != EbtInt) {
671         error(line, "array size must be a constant integer expression", "");
672         return true;
673     }
674
675     size = constant->getUnionArrayPointer()->getIConst();
676
677     if (size <= 0) {
678         error(line, "array size must be a positive integer", "");
679         size = 1;
680         return true;
681     }
682
683     return false;
684 }
685
686 //
687 // See if this qualifier can be an array.
688 //
689 // Returns true if there is an error.
690 //
691 bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type)
692 {
693     if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqConst)) {
694         error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str());
695         return true;
696     }
697
698     return false;
699 }
700
701 //
702 // See if this type can be an array.
703 //
704 // Returns true if there is an error.
705 //
706 bool TParseContext::arrayTypeErrorCheck(int line, TPublicType type)
707 {
708     //
709     // Can the type be an array?
710     //
711     if (type.array) {
712         error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str());
713         return true;
714     }
715
716     return false;
717 }
718
719 //
720 // Do all the semantic checking for declaring an array, with and
721 // without a size, and make the right changes to the symbol table.
722 //
723 // size == 0 means no specified size.
724 //
725 // Returns true if there was an error.
726 //
727 bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable)
728 {
729     //
730     // Don't check for reserved word use until after we know it's not in the symbol table,
731     // because reserved arrays can be redeclared.
732     //
733
734     bool builtIn = false;
735     bool sameScope = false;
736     TSymbol* symbol = symbolTable.find(identifier, &builtIn, &sameScope);
737     if (symbol == 0 || !sameScope) {
738         if (reservedErrorCheck(line, identifier))
739             return true;
740
741         variable = new TVariable(&identifier, TType(type));
742
743         if (type.arraySize)
744             variable->getType().setArraySize(type.arraySize);
745
746         if (! symbolTable.insert(*variable)) {
747             delete variable;
748             error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str());
749             return true;
750         }
751     } else {
752         if (! symbol->isVariable()) {
753             error(line, "variable expected", identifier.c_str());
754             return true;
755         }
756
757         variable = static_cast<TVariable*>(symbol);
758         if (! variable->getType().isArray()) {
759             error(line, "redeclaring non-array as array", identifier.c_str());
760             return true;
761         }
762         if (variable->getType().getArraySize() > 0) {
763             error(line, "redeclaration of array with size", identifier.c_str());
764             return true;
765         }
766
767         if (! variable->getType().sameElementType(TType(type))) {
768             error(line, "redeclaration of array with a different type", identifier.c_str());
769             return true;
770         }
771
772         TType* t = variable->getArrayInformationType();
773         while (t != 0) {
774             if (t->getMaxArraySize() > type.arraySize) {
775                 error(line, "higher index value already used for the array", identifier.c_str());
776                 return true;
777             }
778             t->setArraySize(type.arraySize);
779             t = t->getArrayInformationType();
780         }
781
782         if (type.arraySize)
783             variable->getType().setArraySize(type.arraySize);
784     }
785
786     if (voidErrorCheck(line, identifier, type))
787         return true;
788
789     return false;
790 }
791
792 bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, TSourceLoc line)
793 {
794     bool builtIn = false;
795     TSymbol* symbol = symbolTable.find(node->getSymbol(), &builtIn);
796     if (symbol == 0) {
797         error(line, " undeclared identifier", node->getSymbol().c_str());
798         return true;
799     }
800     TVariable* variable = static_cast<TVariable*>(symbol);
801
802     type->setArrayInformationType(variable->getArrayInformationType());
803     variable->updateArrayInformationType(type);
804
805     // special casing to test index value of gl_FragData. If the accessed index is >= gl_MaxDrawBuffers
806     // its an error
807     if (node->getSymbol() == "gl_FragData") {
808         TSymbol* fragData = symbolTable.find("gl_MaxDrawBuffers", &builtIn);
809         ASSERT(fragData);
810
811         int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst();
812         if (fragDataValue <= size) {
813             error(line, "", "[", "gl_FragData can only have a max array size of up to gl_MaxDrawBuffers");
814             return true;
815         }
816     }
817
818     // we dont want to update the maxArraySize when this flag is not set, we just want to include this
819     // node type in the chain of node types so that its updated when a higher maxArraySize comes in.
820     if (!updateFlag)
821         return false;
822
823     size++;
824     variable->getType().setMaxArraySize(size);
825     type->setMaxArraySize(size);
826     TType* tt = type;
827
828     while(tt->getArrayInformationType() != 0) {
829         tt = tt->getArrayInformationType();
830         tt->setMaxArraySize(size);
831     }
832
833     return false;
834 }
835
836 //
837 // Enforce non-initializer type/qualifier rules.
838 //
839 // Returns true if there was an error.
840 //
841 bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type, bool array)
842 {
843     if (type.qualifier == EvqConst)
844     {
845         // Make the qualifier make sense.
846         type.qualifier = EvqTemporary;
847
848         if (array)
849         {
850             error(line, "arrays may not be declared constant since they cannot be initialized", identifier.c_str());
851         }
852         else if (type.isStructureContainingArrays())
853         {
854             error(line, "structures containing arrays may not be declared constant since they cannot be initialized", identifier.c_str());
855         }
856         else
857         {
858             error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
859         }
860
861         return true;
862     }
863
864     return false;
865 }
866
867 //
868 // Do semantic checking for a variable declaration that has no initializer,
869 // and update the symbol table.
870 //
871 // Returns true if there was an error.
872 //
873 bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType& type, TVariable*& variable)
874 {
875     if (reservedErrorCheck(line, identifier))
876         recover();
877
878     variable = new TVariable(&identifier, TType(type));
879
880     if (! symbolTable.insert(*variable)) {
881         error(line, "redefinition", variable->getName().c_str());
882         delete variable;
883         variable = 0;
884         return true;
885     }
886
887     if (voidErrorCheck(line, identifier, type))
888         return true;
889
890     return false;
891 }
892
893 bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type)
894 {
895     if (qualifier != EvqConst && qualifier != EvqTemporary) {
896         error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier));
897         return true;
898     }
899     if (qualifier == EvqConst && paramQualifier != EvqIn) {
900         error(line, "qualifier not allowed with ", getQualifierString(qualifier), getQualifierString(paramQualifier));
901         return true;
902     }
903
904     if (qualifier == EvqConst)
905         type->setQualifier(EvqConstReadOnly);
906     else
907         type->setQualifier(paramQualifier);
908
909     return false;
910 }
911
912 bool TParseContext::extensionErrorCheck(int line, const TString& extension)
913 {
914     const TExtensionBehavior& extBehavior = extensionBehavior();
915     TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str());
916     if (iter == extBehavior.end()) {
917         error(line, "extension", extension.c_str(), "is not supported");
918         return true;
919     }
920     // In GLSL ES, an extension's default behavior is "disable".
921     if (iter->second == EBhDisable || iter->second == EBhUndefined) {
922         error(line, "extension", extension.c_str(), "is disabled");
923         return true;
924     }
925     if (iter->second == EBhWarn) {
926         warning(line, "extension", extension.c_str(), "is being used");
927         return false;
928     }
929
930     return false;
931 }
932
933 bool TParseContext::supportsExtension(const char* extension)
934 {
935     const TExtensionBehavior& extbehavior = extensionBehavior();
936     TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
937     return (iter != extbehavior.end());
938 }
939
940 void TParseContext::handleExtensionDirective(int line, const char* extName, const char* behavior)
941 {
942     pp::SourceLocation loc;
943     DecodeSourceLoc(line, &loc.file, &loc.line);
944     directiveHandler.handleExtension(loc, extName, behavior);
945 }
946
947 void TParseContext::handlePragmaDirective(int line, const char* name, const char* value)
948 {
949     pp::SourceLocation loc;
950     DecodeSourceLoc(line, &loc.file, &loc.line);
951     directiveHandler.handlePragma(loc, name, value);
952 }
953
954 /////////////////////////////////////////////////////////////////////////////////
955 //
956 // Non-Errors.
957 //
958 /////////////////////////////////////////////////////////////////////////////////
959
960 //
961 // Look up a function name in the symbol table, and make sure it is a function.
962 //
963 // Return the function symbol if found, otherwise 0.
964 //
965 const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *builtIn)
966 {
967     // First find by unmangled name to check whether the function name has been
968     // hidden by a variable name or struct typename.
969     const TSymbol* symbol = symbolTable.find(call->getName(), builtIn);
970     if (symbol == 0) {
971         symbol = symbolTable.find(call->getMangledName(), builtIn);
972     }
973
974     if (symbol == 0) {
975         error(line, "no matching overloaded function found", call->getName().c_str());
976         return 0;
977     }
978
979     if (!symbol->isFunction()) {
980         error(line, "function name expected", call->getName().c_str());
981         return 0;
982     }
983
984     return static_cast<const TFunction*>(symbol);
985 }
986
987 //
988 // Initializers show up in several places in the grammar.  Have one set of
989 // code to handle them here.
990 //
991 bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
992                                        TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable)
993 {
994     TType type = TType(pType);
995
996     if (variable == 0) {
997         if (reservedErrorCheck(line, identifier))
998             return true;
999
1000         if (voidErrorCheck(line, identifier, pType))
1001             return true;
1002
1003         //
1004         // add variable to symbol table
1005         //
1006         variable = new TVariable(&identifier, type);
1007         if (! symbolTable.insert(*variable)) {
1008             error(line, "redefinition", variable->getName().c_str());
1009             return true;
1010             // don't delete variable, it's used by error recovery, and the pool
1011             // pop will take care of the memory
1012         }
1013     }
1014
1015     //
1016     // identifier must be of type constant, a global, or a temporary
1017     //
1018     TQualifier qualifier = variable->getType().getQualifier();
1019     if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) {
1020         error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString());
1021         return true;
1022     }
1023     //
1024     // test for and propagate constant
1025     //
1026
1027     if (qualifier == EvqConst) {
1028         if (qualifier != initializer->getType().getQualifier()) {
1029             std::stringstream extraInfoStream;
1030             extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
1031             std::string extraInfo = extraInfoStream.str();
1032             error(line, " assigning non-constant to", "=", extraInfo.c_str());
1033             variable->getType().setQualifier(EvqTemporary);
1034             return true;
1035         }
1036         if (type != initializer->getType()) {
1037             error(line, " non-matching types for const initializer ",
1038                 variable->getType().getQualifierString());
1039             variable->getType().setQualifier(EvqTemporary);
1040             return true;
1041         }
1042         if (initializer->getAsConstantUnion()) {
1043             ConstantUnion* unionArray = variable->getConstPointer();
1044
1045             if (type.getObjectSize() == 1 && type.getBasicType() != EbtStruct) {
1046                 *unionArray = (initializer->getAsConstantUnion()->getUnionArrayPointer())[0];
1047             } else {
1048                 variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
1049             }
1050         } else if (initializer->getAsSymbolNode()) {
1051             const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol());
1052             const TVariable* tVar = static_cast<const TVariable*>(symbol);
1053
1054             ConstantUnion* constArray = tVar->getConstPointer();
1055             variable->shareConstPointer(constArray);
1056         } else {
1057             std::stringstream extraInfoStream;
1058             extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
1059             std::string extraInfo = extraInfoStream.str();
1060             error(line, " cannot assign to", "=", extraInfo.c_str());
1061             variable->getType().setQualifier(EvqTemporary);
1062             return true;
1063         }
1064     }
1065
1066     if (qualifier != EvqConst) {
1067         TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
1068         intermNode = intermediate.addAssign(EOpInitialize, intermSymbol, initializer, line);
1069         if (intermNode == 0) {
1070             assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
1071             return true;
1072         }
1073     } else
1074         intermNode = 0;
1075
1076     return false;
1077 }
1078
1079 bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
1080 {
1081     ASSERT(aggrNode != NULL);
1082     if (!aggrNode->isConstructor())
1083         return false;
1084
1085     bool allConstant = true;
1086
1087     // check if all the child nodes are constants so that they can be inserted into
1088     // the parent node
1089     TIntermSequence &sequence = aggrNode->getSequence() ;
1090     for (TIntermSequence::iterator p = sequence.begin(); p != sequence.end(); ++p) {
1091         if (!(*p)->getAsTyped()->getAsConstantUnion())
1092             return false;
1093     }
1094
1095     return allConstant;
1096 }
1097
1098 // This function is used to test for the correctness of the parameters passed to various constructor functions
1099 // and also convert them to the right datatype if it is allowed and required.
1100 //
1101 // Returns 0 for an error or the constructed node (aggregate or typed) for no error.
1102 //
1103 TIntermTyped* TParseContext::addConstructor(TIntermNode* arguments, const TType* type, TOperator op, TFunction* fnCall, TSourceLoc line)
1104 {
1105     TIntermAggregate *aggregateArguments = arguments->getAsAggregate();
1106
1107     if(!aggregateArguments)
1108     {
1109         aggregateArguments = new TIntermAggregate;
1110         aggregateArguments->getSequence().push_back(arguments);
1111     }
1112
1113     if(op == EOpConstructStruct)
1114     {
1115         TTypeList &fields = *type->getStruct();
1116         TIntermSequence &args = aggregateArguments->getSequence();
1117
1118         for(size_t i = 0; i < fields.size(); i++)
1119         {
1120             if(args[i]->getAsTyped()->getType() != *fields[i].type)
1121             {
1122                 error(line, "Structure constructor arguments do not match structure fields", "Error");
1123                 recover();
1124
1125                 return 0;
1126             }
1127         }
1128     }
1129
1130     // Turn the argument list itself into a constructor
1131     TIntermTyped *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
1132     TIntermTyped *constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type);
1133     if(constConstructor)
1134     {
1135         return constConstructor;
1136     }
1137
1138     return constructor;
1139 }
1140
1141 TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, const TType& type)
1142 {
1143     bool canBeFolded = areAllChildConst(aggrNode);
1144     aggrNode->setType(type);
1145     if (canBeFolded) {
1146         bool returnVal = false;
1147         ConstantUnion* unionArray = new ConstantUnion[type.getObjectSize()];
1148         if (aggrNode->getSequence().size() == 1)  {
1149             returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type, true);
1150         }
1151         else {
1152             returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type);
1153         }
1154         if (returnVal)
1155             return 0;
1156
1157         return intermediate.addConstantUnion(unionArray, type, aggrNode->getLine());
1158     }
1159
1160     return 0;
1161 }
1162
1163 //
1164 // This function returns the tree representation for the vector field(s) being accessed from contant vector.
1165 // If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a contant node is
1166 // returned, else an aggregate node is returned (for v.xy). The input to this function could either be the symbol
1167 // node or it could be the intermediate tree representation of accessing fields in a constant structure or column of 
1168 // a constant matrix.
1169 //
1170 TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, TSourceLoc line)
1171 {
1172     TIntermTyped* typedNode;
1173     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
1174
1175     ConstantUnion *unionArray;
1176     if (tempConstantNode) {
1177         unionArray = tempConstantNode->getUnionArrayPointer();
1178         ASSERT(unionArray);
1179
1180         if (!unionArray) {
1181             return node;
1182         }
1183     } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
1184         error(line, "Cannot offset into the vector", "Error");
1185         recover();
1186
1187         return 0;
1188     }
1189
1190     ConstantUnion* constArray = new ConstantUnion[fields.num];
1191
1192     for (int i = 0; i < fields.num; i++) {
1193         if (fields.offsets[i] >= node->getType().getObjectSize()) {
1194             std::stringstream extraInfoStream;
1195             extraInfoStream << "vector field selection out of range '" << fields.offsets[i] << "'";
1196             std::string extraInfo = extraInfoStream.str();
1197             error(line, "", "[", extraInfo.c_str());
1198             recover();
1199             fields.offsets[i] = 0;
1200         }
1201
1202         constArray[i] = unionArray[fields.offsets[i]];
1203
1204     }
1205     typedNode = intermediate.addConstantUnion(constArray, node->getType(), line);
1206     return typedNode;
1207 }
1208
1209 //
1210 // This function returns the column being accessed from a constant matrix. The values are retrieved from
1211 // the symbol table and parse-tree is built for a vector (each column of a matrix is a vector). The input
1212 // to the function could either be a symbol node (m[0] where m is a constant matrix)that represents a
1213 // constant matrix or it could be the tree representation of the constant matrix (s.m1[0] where s is a constant structure)
1214 //
1215 TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, TSourceLoc line)
1216 {
1217     TIntermTyped* typedNode;
1218     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
1219
1220     if (index >= node->getType().getNominalSize()) {
1221         std::stringstream extraInfoStream;
1222         extraInfoStream << "matrix field selection out of range '" << index << "'";
1223         std::string extraInfo = extraInfoStream.str();
1224         error(line, "", "[", extraInfo.c_str());
1225         recover();
1226         index = 0;
1227     }
1228
1229     if (tempConstantNode) {
1230          ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
1231          int size = tempConstantNode->getType().getNominalSize();
1232          typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line);
1233     } else {
1234         error(line, "Cannot offset into the matrix", "Error");
1235         recover();
1236
1237         return 0;
1238     }
1239
1240     return typedNode;
1241 }
1242
1243
1244 //
1245 // This function returns an element of an array accessed from a constant array. The values are retrieved from
1246 // the symbol table and parse-tree is built for the type of the element. The input
1247 // to the function could either be a symbol node (a[0] where a is a constant array)that represents a
1248 // constant array or it could be the tree representation of the constant array (s.a1[0] where s is a constant structure)
1249 //
1250 TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line)
1251 {
1252     TIntermTyped* typedNode;
1253     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
1254     TType arrayElementType = node->getType();
1255     arrayElementType.clearArrayness();
1256
1257     if (index >= node->getType().getArraySize()) {
1258         std::stringstream extraInfoStream;
1259         extraInfoStream << "array field selection out of range '" << index << "'";
1260         std::string extraInfo = extraInfoStream.str();
1261         error(line, "", "[", extraInfo.c_str());
1262         recover();
1263         index = 0;
1264     }
1265
1266     int arrayElementSize = arrayElementType.getObjectSize();
1267
1268     if (tempConstantNode) {
1269          ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
1270          typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line);
1271     } else {
1272         error(line, "Cannot offset into the array", "Error");
1273         recover();
1274
1275         return 0;
1276     }
1277
1278     return typedNode;
1279 }
1280
1281
1282 //
1283 // This function returns the value of a particular field inside a constant structure from the symbol table.
1284 // If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr
1285 // function and returns the parse-tree with the values of the embedded/nested struct.
1286 //
1287 TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc line)
1288 {
1289     const TTypeList* fields = node->getType().getStruct();
1290     TIntermTyped *typedNode;
1291     int instanceSize = 0;
1292     unsigned int index = 0;
1293     TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
1294
1295     for ( index = 0; index < fields->size(); ++index) {
1296         if ((*fields)[index].type->getFieldName() == identifier) {
1297             break;
1298         } else {
1299             instanceSize += (*fields)[index].type->getObjectSize();
1300         }
1301     }
1302
1303     if (tempConstantNode) {
1304          ConstantUnion* constArray = tempConstantNode->getUnionArrayPointer();
1305
1306          typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function
1307     } else {
1308         error(line, "Cannot offset into the structure", "Error");
1309         recover();
1310
1311         return 0;
1312     }
1313
1314     return typedNode;
1315 }
1316
1317 bool TParseContext::enterStructDeclaration(int line, const TString& identifier)
1318 {
1319     ++structNestingLevel;
1320
1321     // Embedded structure definitions are not supported per GLSL ES spec.
1322     // They aren't allowed in GLSL either, but we need to detect this here
1323     // so we don't rely on the GLSL compiler to catch it.
1324     if (structNestingLevel > 1) {
1325         error(line, "", "Embedded struct definitions are not allowed");
1326         return true;
1327     }
1328
1329     return false;
1330 }
1331
1332 void TParseContext::exitStructDeclaration()
1333 {
1334     --structNestingLevel;
1335 }
1336
1337 namespace {
1338
1339 const int kWebGLMaxStructNesting = 4;
1340
1341 }  // namespace
1342
1343 bool TParseContext::structNestingErrorCheck(TSourceLoc line, const TType& fieldType)
1344 {
1345     if (shaderSpec != SH_WEBGL_SPEC) {
1346         return false;
1347     }
1348
1349     if (fieldType.getBasicType() != EbtStruct) {
1350         return false;
1351     }
1352
1353     // We're already inside a structure definition at this point, so add
1354     // one to the field's struct nesting.
1355     if (1 + fieldType.getDeepestStructNesting() > kWebGLMaxStructNesting) {
1356         std::stringstream extraInfoStream;
1357         extraInfoStream << "Reference of struct type " << fieldType.getTypeName()
1358                         << " exceeds maximum struct nesting of " << kWebGLMaxStructNesting;
1359         std::string extraInfo = extraInfoStream.str();
1360         error(line, "", "", extraInfo.c_str());
1361         return true;
1362     }
1363
1364     return false;
1365 }
1366
1367 //
1368 // Parse an array of strings using yyparse.
1369 //
1370 // Returns 0 for success.
1371 //
1372 int PaParseStrings(int count, const char* const string[], const int length[],
1373                    TParseContext* context) {
1374     if ((count == 0) || (string == NULL))
1375         return 1;
1376
1377     if (glslang_initialize(context))
1378         return 1;
1379
1380     int error = glslang_scan(count, string, length, context);
1381     if (!error)
1382         error = glslang_parse(context);
1383
1384     glslang_finalize(context);
1385
1386     return (error == 0) && (context->numErrors() == 0) ? 0 : 1;
1387 }
1388
1389
1390