glslang: Fix over 100 warnings from MSVC warning level 4.
[platform/upstream/glslang.git] / glslang / MachineIndependent / ParseHelper.cpp
1 //
2 //Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
3 //Copyright (C) 2012-2013 LunarG, Inc.
4 //
5 //All rights reserved.
6 //
7 //Redistribution and use in source and binary forms, with or without
8 //modification, are permitted provided that the following conditions
9 //are met:
10 //
11 //    Redistributions of source code must retain the above copyright
12 //    notice, this list of conditions and the following disclaimer.
13 //
14 //    Redistributions in binary form must reproduce the above
15 //    copyright notice, this list of conditions and the following
16 //    disclaimer in the documentation and/or other materials provided
17 //    with the distribution.
18 //
19 //    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
20 //    contributors may be used to endorse or promote products derived
21 //    from this software without specific prior written permission.
22 //
23 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 //"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 //FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 //COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 //INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 //CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 //LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 //ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 //POSSIBILITY OF SUCH DAMAGE.
35 //
36
37 #include "ParseHelper.h"
38 #include "Scan.h"
39
40 #include "osinclude.h"
41 #include <stdarg.h>
42 #include <algorithm>
43
44 #include "preprocessor/PpContext.h"
45
46 extern int yyparse(glslang::TParseContext*);
47
48 namespace glslang {
49
50 TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb, int v, EProfile p, EShLanguage L, TInfoSink& is,
51                              bool fc, EShMessages m) :
52             intermediate(interm), symbolTable(symt), infoSink(is), language(L),
53             version(v), profile(p), forwardCompatible(fc), messages(m),
54             contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), statementNestingLevel(0),
55             postMainReturn(false),
56             tokensBeforeEOF(false), limits(resources.limits), currentScanner(0),
57             numErrors(0), parsingBuiltins(pb), afterEOF(false),
58             atomicUintOffsets(0), anyIndexLimits(false)
59 {
60     // ensure we always have a linkage node, even if empty, to simplify tree topology algorithms
61     linkage = new TIntermAggregate;
62
63     // set all precision defaults to EpqNone, which is correct for all desktop types
64     // and for ES types that don't have defaults (thus getting an error on use)
65     for (int type = 0; type < EbtNumTypes; ++type)
66         defaultPrecision[type] = EpqNone;
67
68     for (int type = 0; type < maxSamplerIndex; ++type)
69         defaultSamplerPrecision[type] = EpqNone;
70
71     // replace with real defaults for those that have them
72     if (profile == EEsProfile) {
73         TSampler sampler;
74         sampler.set(EbtFloat, Esd2D);
75         defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow;
76         sampler.set(EbtFloat, EsdCube);
77         defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow;
78         sampler.set(EbtFloat, Esd2D);
79         sampler.external = true;
80         defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow;
81
82         switch (language) {
83         case EShLangFragment:
84             defaultPrecision[EbtInt] = EpqMedium;
85             defaultPrecision[EbtUint] = EpqMedium;
86             break;
87         default:
88             defaultPrecision[EbtInt] = EpqHigh;
89             defaultPrecision[EbtUint] = EpqHigh;
90             defaultPrecision[EbtFloat] = EpqHigh;
91             break;
92         }
93
94         defaultPrecision[EbtSampler] = EpqLow;
95         defaultPrecision[EbtAtomicUint] = EpqHigh;
96     }
97
98     globalUniformDefaults.clear();
99     globalUniformDefaults.layoutMatrix = ElmColumnMajor;
100     globalUniformDefaults.layoutPacking = ElpShared;
101
102     globalBufferDefaults.clear();
103     globalBufferDefaults.layoutMatrix = ElmColumnMajor;
104     globalBufferDefaults.layoutPacking = ElpShared;
105
106     globalInputDefaults.clear();
107     globalOutputDefaults.clear();
108
109     // "Shaders in the transform 
110     // feedback capturing mode have an initial global default of
111     //     layout(xfb_buffer = 0) out;"
112     if (language == EShLangVertex ||
113         language == EShLangTessControl ||
114         language == EShLangTessEvaluation ||
115         language == EShLangGeometry)
116         globalOutputDefaults.layoutXfbBuffer = 0;
117
118     if (language == EShLangGeometry)
119         globalOutputDefaults.layoutStream = 0;
120 }
121
122 TParseContext::~TParseContext()
123 {
124     delete [] atomicUintOffsets;
125 }
126
127 void TParseContext::setLimits(const TBuiltInResource& r)
128 {
129     resources = r;
130
131     anyIndexLimits = ! limits.generalAttributeMatrixVectorIndexing ||
132                      ! limits.generalConstantMatrixVectorIndexing ||
133                      ! limits.generalSamplerIndexing ||
134                      ! limits.generalUniformIndexing ||
135                      ! limits.generalVariableIndexing ||
136                      ! limits.generalVaryingIndexing;
137
138     intermediate.setLimits(resources);
139
140     // "Each binding point tracks its own current default offset for
141     // inheritance of subsequent variables using the same binding. The initial state of compilation is that all
142     // binding points have an offset of 0."
143     atomicUintOffsets = new int[resources.maxAtomicCounterBindings];
144     for (int b = 0; b < resources.maxAtomicCounterBindings; ++b)
145         atomicUintOffsets[b] = 0;
146 }
147
148 //
149 // Parse an array of strings using yyparse, going through the
150 // preprocessor to tokenize the shader strings, then through
151 // the GLSL scanner.
152 //
153 // Returns true for successful acceptance of the shader, false if any errors.
154 //
155 bool TParseContext::parseShaderStrings(TPpContext& ppContext, TInputScanner& input, bool versionWillBeError)
156 {
157     currentScanner = &input;
158     ppContext.setInput(input, versionWillBeError);
159     yyparse(this);
160     finalErrorCheck();
161
162     return numErrors == 0;
163 }
164
165 // This is called from bison when it has a parse (syntax) error
166 void TParseContext::parserError(const char* s)
167 {
168     if (afterEOF) {
169         if (tokensBeforeEOF == 1)
170             error(getCurrentLoc(), "", "pre-mature EOF", s, "");
171     } else
172         error(getCurrentLoc(), "", "", s, "");
173 }
174
175 void TParseContext::handlePragma(TSourceLoc loc, const TVector<TString>& tokens)
176 {
177     if (tokens.size() == 0)
178         return;
179
180     if (tokens[0].compare("optimize") == 0) {
181         if (tokens.size() != 4) {
182             error(loc, "optimize pragma syntax is incorrect", "#pragma", "");
183             return;
184         }
185
186         if (tokens[1].compare("(") != 0) {
187             error(loc, "\"(\" expected after 'optimize' keyword", "#pragma", "");
188             return;
189         }
190
191         if (tokens[2].compare("on") == 0)
192             contextPragma.optimize = true;
193         else if (tokens[2].compare("off") == 0)
194             contextPragma.optimize = false;
195         else {
196             error(loc, "\"on\" or \"off\" expected after '(' for 'optimize' pragma", "#pragma", "");
197             return;
198         }
199
200         if (tokens[3].compare(")") != 0) {
201             error(loc, "\")\" expected to end 'optimize' pragma", "#pragma", "");
202             return;
203         }
204     } else if (tokens[0].compare("debug") == 0) {
205         if (tokens.size() != 4) {
206             error(loc, "debug pragma syntax is incorrect", "#pragma", "");
207             return;
208         }
209
210         if (tokens[1].compare("(") != 0) {
211             error(loc, "\"(\" expected after 'debug' keyword", "#pragma", "");
212             return;
213         }
214
215         if (tokens[2].compare("on") == 0)
216             contextPragma.debug = true;
217         else if (tokens[2].compare("off") == 0)
218             contextPragma.debug = false;
219         else {
220             error(loc, "\"on\" or \"off\" expected after '(' for 'debug' pragma", "#pragma", "");
221             return;
222         }
223
224         if (tokens[3].compare(")") != 0) {
225             error(loc, "\")\" expected to end 'debug' pragma", "#pragma", "");
226             return;
227         }
228     }
229 }
230
231 ///////////////////////////////////////////////////////////////////////
232 //
233 // Sub- vector and matrix fields
234 //
235 ////////////////////////////////////////////////////////////////////////
236
237 //
238 // Look at a '.' field selector string and change it into offsets
239 // for a vector or scalar
240 //
241 // Returns true if there is no error.
242 //
243 bool TParseContext::parseVectorFields(TSourceLoc loc, const TString& compString, int vecSize, TVectorFields& fields)
244 {
245     fields.num = (int) compString.size();
246     if (fields.num > 4) {
247         error(loc, "illegal vector field selection", compString.c_str(), "");
248         return false;
249     }
250
251     enum {
252         exyzw,
253         ergba,
254         estpq,
255     } fieldSet[4];
256
257     for (int i = 0; i < fields.num; ++i) {
258         switch (compString[i])  {
259         case 'x':
260             fields.offsets[i] = 0;
261             fieldSet[i] = exyzw;
262             break;
263         case 'r':
264             fields.offsets[i] = 0;
265             fieldSet[i] = ergba;
266             break;
267         case 's':
268             fields.offsets[i] = 0;
269             fieldSet[i] = estpq;
270             break;
271         case 'y':
272             fields.offsets[i] = 1;
273             fieldSet[i] = exyzw;
274             break;
275         case 'g':
276             fields.offsets[i] = 1;
277             fieldSet[i] = ergba;
278             break;
279         case 't':
280             fields.offsets[i] = 1;
281             fieldSet[i] = estpq;
282             break;
283         case 'z':
284             fields.offsets[i] = 2;
285             fieldSet[i] = exyzw;
286             break;
287         case 'b':
288             fields.offsets[i] = 2;
289             fieldSet[i] = ergba;
290             break;
291         case 'p':
292             fields.offsets[i] = 2;
293             fieldSet[i] = estpq;
294             break;
295
296         case 'w':
297             fields.offsets[i] = 3;
298             fieldSet[i] = exyzw;
299             break;
300         case 'a':
301             fields.offsets[i] = 3;
302             fieldSet[i] = ergba;
303             break;
304         case 'q':
305             fields.offsets[i] = 3;
306             fieldSet[i] = estpq;
307             break;
308         default:
309             error(loc, "illegal vector field selection", compString.c_str(), "");
310             return false;
311         }
312     }
313
314     for (int i = 0; i < fields.num; ++i) {
315         if (fields.offsets[i] >= vecSize) {
316             error(loc, "vector field selection out of range",  compString.c_str(), "");
317             return false;
318         }
319
320         if (i > 0) {
321             if (fieldSet[i] != fieldSet[i-1]) {
322                 error(loc, "illegal - vector component fields not from the same set", compString.c_str(), "");
323                 return false;
324             }
325         }
326     }
327
328     return true;
329 }
330
331 ///////////////////////////////////////////////////////////////////////
332 //
333 // Errors
334 //
335 ////////////////////////////////////////////////////////////////////////
336
337 //
338 // Used to output syntax, parsing, and semantic errors.
339 //
340 void C_DECL TParseContext::error(TSourceLoc loc, const char* szReason, const char* szToken,
341                                  const char* szExtraInfoFormat, ...)
342 {
343     const int maxSize = GlslangMaxTokenLength + 200;
344     char szExtraInfo[maxSize];
345     va_list marker;
346
347     va_start(marker, szExtraInfoFormat);
348
349     safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, marker);
350
351     infoSink.info.prefix(EPrefixError);
352     infoSink.info.location(loc);
353     infoSink.info << "'" << szToken <<  "' : " << szReason << " " << szExtraInfo << "\n";
354
355     va_end(marker);
356
357     ++numErrors;
358 }
359
360 void C_DECL TParseContext::warn(TSourceLoc loc, const char* szReason, const char* szToken,
361                                  const char* szExtraInfoFormat, ...)
362 {
363     if (messages & EShMsgSuppressWarnings)
364         return;
365
366     const int maxSize = GlslangMaxTokenLength + 200;
367     char szExtraInfo[maxSize];
368     va_list marker;
369
370     va_start(marker, szExtraInfoFormat);
371
372     safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, marker);
373
374     infoSink.info.prefix(EPrefixWarning);
375     infoSink.info.location(loc);
376     infoSink.info << "'" << szToken <<  "' : " << szReason << " " << szExtraInfo << "\n";
377
378     va_end(marker);
379 }
380
381 //
382 // Handle seeing a variable identifier in the grammar.
383 //
384 TIntermTyped* TParseContext::handleVariable(TSourceLoc loc, TSymbol* symbol, TString* string)
385 {
386     TIntermTyped* node = 0;
387
388     // Error check for function requiring specific extensions present.
389     if (symbol && symbol->getNumExtensions())
390         requireExtensions(loc, symbol->getNumExtensions(), symbol->getExtensions(), symbol->getName().c_str());
391
392     if (symbol && symbol->isReadOnly()) {
393         // All shared things containing an implicitly sized array must be copied up 
394         // on first use, so that all future references will share its array structure,
395         // so that editing the implicit size will effect all nodes consuming it,
396         // and so that editing the implicit size won't change the shared one.
397         //
398         // If this is a variable or a block, check it and all it contains, but if this 
399         // is a member of an anonymous block, check the whole block, as the whole block
400         // will need to be copied up if it contains an implicitly-sized array.
401         if (symbol->getType().containsImplicitlySizedArray() || (symbol->getAsAnonMember() && symbol->getAsAnonMember()->getAnonContainer().getType().containsImplicitlySizedArray()))
402             makeEditable(symbol);
403     }
404
405     const TVariable* variable;
406     const TAnonMember* anon = symbol ? symbol->getAsAnonMember() : 0;
407     if (anon) {
408         // It was a member of an anonymous container.
409
410         // Create a subtree for its dereference.
411         variable = anon->getAnonContainer().getAsVariable();
412         TIntermTyped* container = intermediate.addSymbol(*variable, loc);
413         TIntermTyped* constNode = intermediate.addConstantUnion(anon->getMemberNumber(), loc);
414         node = intermediate.addIndex(EOpIndexDirectStruct, container, constNode, loc);
415
416         node->setType(*(*variable->getType().getStruct())[anon->getMemberNumber()].type);
417         if (node->getType().hiddenMember())
418             error(loc, "member of nameless block was not redeclared", string->c_str(), "");
419     } else {
420         // Not a member of an anonymous container.
421
422         // The symbol table search was done in the lexical phase.
423         // See if it was a variable.
424         variable = symbol ? symbol->getAsVariable() : 0;
425         if (symbol && ! variable)
426             error(loc, "variable name expected", string->c_str(), "");
427
428         // Recovery, if it wasn't found or was not a variable.
429         if (! variable)
430             variable = new TVariable(string, TType(EbtVoid));
431
432         if (variable->getType().getQualifier().storage == EvqConst)
433             node = intermediate.addConstantUnion(variable->getConstArray(), variable->getType(), loc);
434         else
435             node = intermediate.addSymbol(*variable, loc);
436     }
437
438     if (variable->getType().getQualifier().isIo())
439         intermediate.addIoAccessed(*string);
440
441     return node;
442 }
443
444 //
445 // Handle seeing a base[index] dereference in the grammar.
446 //
447 TIntermTyped* TParseContext::handleBracketDereference(TSourceLoc loc, TIntermTyped* base, TIntermTyped* index)
448 {
449     TIntermTyped* result = 0;
450
451     int indexValue = 0;
452     if (index->getQualifier().storage == EvqConst) {
453         indexValue = index->getAsConstantUnion()->getConstArray()[0].getIConst();
454         checkIndex(loc, base->getType(), indexValue);
455     }
456
457     variableCheck(base);
458     if (! base->isArray() && ! base->isMatrix() && ! base->isVector()) {
459         if (base->getAsSymbolNode())
460             error(loc, " left of '[' is not of type array, matrix, or vector ", base->getAsSymbolNode()->getName().c_str(), "");
461         else
462             error(loc, " left of '[' is not of type array, matrix, or vector ", "expression", "");
463     } else if (base->getType().getQualifier().storage == EvqConst && index->getQualifier().storage == EvqConst)
464         return intermediate.foldDereference(base, indexValue, loc);
465     else {
466         // at least one of base and index is variable...
467
468         if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
469             handleIoResizeArrayAccess(loc, base);
470
471         if (index->getQualifier().storage == EvqConst) {
472             if (base->getType().isImplicitlySizedArray())
473                 updateImplicitArraySize(loc, base, indexValue);
474             result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
475         } else {
476             if (base->getType().isImplicitlySizedArray()) {
477                 if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
478                     error(loc, "", "[", "array must be sized by a redeclaration or layout qualifier before being indexed with a variable");
479                 else
480                     error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable");
481             }
482             if (base->getBasicType() == EbtBlock)
483                 requireProfile(base->getLoc(), ~EEsProfile, "variable indexing block array");
484             else if (language == EShLangFragment && base->getQualifier().isPipeOutput())
485                 requireProfile(base->getLoc(), ~EEsProfile, "variable indexing fragment shader ouput array");
486             else if (base->getBasicType() == EbtSampler && version >= 130) {
487                 const char* explanation = "variable indexing sampler array";
488                 requireProfile(base->getLoc(), ECoreProfile | ECompatibilityProfile, explanation);
489                 profileRequires(base->getLoc(), ECoreProfile | ECompatibilityProfile, 400, 0, explanation);
490             }
491
492             result = intermediate.addIndex(EOpIndexIndirect, base, index, loc);
493         }
494     }
495
496     if (result == 0) {
497         // Insert dummy error-recovery result
498         result = intermediate.addConstantUnion(0.0, EbtFloat, loc);
499     } else {
500         // Insert valid dereferenced result
501         TType newType(base->getType(), 0);  // dereferenced type
502         if (base->getType().getQualifier().storage == EvqConst && index->getQualifier().storage == EvqConst)
503             newType.getQualifier().storage = EvqConst;
504         else
505             newType.getQualifier().storage = EvqTemporary;
506         result->setType(newType);
507
508         if (anyIndexLimits)
509             handleIndexLimits(loc, base, index);
510     }
511
512     return result;
513 }
514
515 void TParseContext::checkIndex(TSourceLoc loc, const TType& type, int& index)
516 {
517     if (index < 0) {
518         error(loc, "", "[", "index out of range '%d'", index);
519         index = 0;
520     } else if (type.isArray()) {
521         if (type.isExplicitlySizedArray() && index >= type.getArraySize()) {
522             error(loc, "", "[", "array index out of range '%d'", index);
523             index = type.getArraySize() - 1;
524         }
525     } else if (type.isVector()) {
526         if (index >= type.getVectorSize()) {
527             error(loc, "", "[", "vector index out of range '%d'", index);
528             index = type.getVectorSize() - 1;
529         }
530     } else if (type.isMatrix()) {
531         if (index >= type.getMatrixCols()) {
532             error(loc, "", "[", "matrix index out of range '%d'", index);
533             index = type.getMatrixCols() - 1;
534         }
535     }           
536 }
537
538 // for ES 2.0 (version 100) limitations for almost all index operations except vertex-shader uniforms
539 void TParseContext::handleIndexLimits(TSourceLoc /*loc*/, TIntermTyped* base, TIntermTyped* index)
540 {
541     if ((! limits.generalSamplerIndexing && base->getBasicType() == EbtSampler) ||
542         (! limits.generalUniformIndexing && base->getQualifier().isUniformOrBuffer() && language != EShLangVertex) ||
543         (! limits.generalAttributeMatrixVectorIndexing && base->getQualifier().isPipeInput() && language == EShLangVertex && (base->getType().isMatrix() || base->getType().isVector())) ||
544         (! limits.generalConstantMatrixVectorIndexing && base->getAsConstantUnion()) ||
545         (! limits.generalVariableIndexing && ! base->getType().getQualifier().isUniformOrBuffer() &&
546                                              ! base->getType().getQualifier().isPipeInput() &&
547                                              ! base->getType().getQualifier().isPipeOutput() &&
548                                                base->getType().getQualifier().storage != EvqConst) ||
549         (! limits.generalVaryingIndexing && (base->getType().getQualifier().isPipeInput() ||
550                                                 base->getType().getQualifier().isPipeOutput()))) {
551         // it's too early to know what the inductive variables are, save it for post processing
552         needsIndexLimitationChecking.push_back(index);
553     }
554 }
555
556 // Make a shared symbol have a non-shared version that can be edited by the current 
557 // compile, such that editing its type will not change the shared version and will
558 // effect all nodes sharing it.
559 void TParseContext::makeEditable(TSymbol*& symbol)
560 {
561     // copyUp() does a deep copy of the type.
562     symbol = symbolTable.copyUp(symbol);
563
564     // Also, see if it's tied to IO resizing
565     if (isIoResizeArray(symbol->getType()))
566         ioArraySymbolResizeList.push_back(symbol);
567
568     // Also, save it in the AST for linker use.
569     intermediate.addSymbolLinkageNode(linkage, *symbol);
570 }
571
572 // Return true if this is a geometry shader input array or tessellation control output array.
573 bool TParseContext::isIoResizeArray(const TType& type) const
574 {
575     return type.isArray() &&
576            ((language == EShLangGeometry    && type.getQualifier().storage == EvqVaryingIn) ||
577             (language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut && ! type.getQualifier().patch));
578 }
579
580 // If an array is not isIoResizeArray() but is an io array, make sure it has the right size
581 void TParseContext::fixIoArraySize(TSourceLoc loc, TType& type)
582 {
583     if (! type.isArray() || type.getQualifier().patch || symbolTable.atBuiltInLevel())
584         return;
585
586     assert(! isIoResizeArray(type));
587
588     if (type.getQualifier().storage != EvqVaryingIn || type.getQualifier().patch)
589         return;
590
591     if (language == EShLangTessControl || language == EShLangTessEvaluation) {
592         if (type.getArraySize() != resources.maxPatchVertices) {
593             if (type.isExplicitlySizedArray())
594                 error(loc, "tessellation input array size must be gl_MaxPatchVertices or implicitly sized", "[]", "");
595             type.changeArraySize(resources.maxPatchVertices);
596         }
597     }
598 }
599
600 // Issue any errors if the non-array object is missing arrayness WRT
601 // shader I/O that has array requirements.
602 // All arrayness checking is handled in array paths, this is for 
603 void TParseContext::ioArrayCheck(TSourceLoc loc, const TType& type, const TString& identifier)
604 {
605     if (! type.isArray() && ! symbolTable.atBuiltInLevel()) {
606         if (type.getQualifier().isArrayedIo(language))
607             error(loc, "type must be an array:", type.getStorageQualifierString(), identifier.c_str());
608     }
609 }
610
611 // Handle a dereference of a geometry shader input array or tessellation control output array.
612 // See ioArraySymbolResizeList comment in ParseHelper.h.
613 //
614 void TParseContext::handleIoResizeArrayAccess(TSourceLoc /*loc*/, TIntermTyped* base)
615 {
616     TIntermSymbol* symbolNode = base->getAsSymbolNode();
617     assert(symbolNode);
618     if (! symbolNode)
619         return;
620
621     // fix array size, if it can be fixed and needs to be fixed (will allow variable indexing)
622     if (symbolNode->getType().isImplicitlySizedArray()) {
623         int newSize = getIoArrayImplicitSize();
624         if (newSize)
625             symbolNode->getWritableType().changeArraySize(newSize);
626     }
627 }
628
629 // If there has been an input primitive declaration (geometry shader) or an output
630 // number of vertices declaration(tessellation shader), make sure all input array types
631 // match it in size.  Types come either from nodes in the AST or symbols in the 
632 // symbol table.
633 //
634 // Types without an array size will be given one.
635 // Types already having a size that is wrong will get an error.
636 //
637 void TParseContext::checkIoArraysConsistency(TSourceLoc loc, bool tailOnly)
638 {
639     int requiredSize = getIoArrayImplicitSize();
640     if (requiredSize == 0)
641         return;
642
643     const char* feature;
644     if (language == EShLangGeometry)
645         feature = TQualifier::getGeometryString(intermediate.getInputPrimitive());
646     else if (language == EShLangTessControl)
647         feature = "vertices";
648     else
649         feature = "unknown";
650
651     if (tailOnly) {
652         checkIoArrayConsistency(loc, requiredSize, feature, ioArraySymbolResizeList.back()->getWritableType(), ioArraySymbolResizeList.back()->getName());
653         return;
654     }
655
656     for (size_t i = 0; i < ioArraySymbolResizeList.size(); ++i)
657         checkIoArrayConsistency(loc, requiredSize, feature, ioArraySymbolResizeList[i]->getWritableType(), ioArraySymbolResizeList[i]->getName());
658 }
659
660 int TParseContext::getIoArrayImplicitSize() const
661 {
662     if (language == EShLangGeometry)
663         return TQualifier::mapGeometryToSize(intermediate.getInputPrimitive());
664     else if (language == EShLangTessControl)
665         return intermediate.getVertices();
666     else
667         return 0;
668 }
669
670 void TParseContext::checkIoArrayConsistency(TSourceLoc loc, int requiredSize, const char* feature, TType& type, const TString& name)
671 {
672     if (type.isImplicitlySizedArray())
673         type.changeArraySize(requiredSize);
674     else if (type.getArraySize() != requiredSize) {
675         if (language == EShLangGeometry)
676             error(loc, "inconsistent input primitive for array size of", feature, name.c_str());
677         else if (language == EShLangTessControl)
678             error(loc, "inconsistent output number of vertices for array size of", feature, name.c_str());
679         else
680             assert(0);
681     }
682 }
683
684 // Handle seeing a binary node with a math operation.
685 TIntermTyped* TParseContext::handleBinaryMath(TSourceLoc loc, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right)
686 {
687     rValueErrorCheck(loc, str, left->getAsTyped());
688     rValueErrorCheck(loc, str, right->getAsTyped());
689
690     TIntermTyped* result = intermediate.addBinaryMath(op, left, right, loc);
691     if (! result)
692         binaryOpError(loc, str, left->getCompleteString(), right->getCompleteString());
693
694     return result;
695 }
696
697 // Handle seeing a unary node with a math operation.
698 TIntermTyped* TParseContext::handleUnaryMath(TSourceLoc loc, const char* str, TOperator op, TIntermTyped* childNode)
699 {
700     rValueErrorCheck(loc, str, childNode);
701
702     TIntermTyped* result = intermediate.addUnaryMath(op, childNode, loc);
703
704     if (result)
705         return result;
706     else
707         unaryOpError(loc, str, childNode->getCompleteString());
708         
709     return childNode;
710 }
711
712 //
713 // Handle seeing a base.field dereference in the grammar.
714 //
715 TIntermTyped* TParseContext::handleDotDereference(TSourceLoc loc, TIntermTyped* base, TString& field)
716 {
717     variableCheck(base);
718
719     //
720     // .length() can't be resolved until we later see the function-calling syntax.
721     // Save away the name in the AST for now.  Processing is compeleted in 
722     // handleLengthMethod().
723     //
724     if (field == "length") {
725         if (base->isArray()) {
726             profileRequires(loc, ENoProfile, 120, GL_3DL_array_objects, ".length");
727             profileRequires(loc, EEsProfile, 300, 0, ".length");
728         } else if (base->isVector() || base->isMatrix()) {
729             const char* feature = ".length() on vectors and matrices";
730             requireProfile(loc, ~EEsProfile, feature);
731             profileRequires(loc, ~EEsProfile, 420, GL_ARB_shading_language_420pack, feature);
732         } else {
733             error(loc, "does not operate on this type:", field.c_str(), base->getType().getCompleteString().c_str());
734
735             return base;
736         }
737
738         return intermediate.addMethod(base, TType(EbtInt), &field, loc);
739     }
740
741     // It's not .length() if we get to here.
742
743     if (base->isArray()) {
744         error(loc, "cannot apply to an array:", ".", field.c_str());
745
746         return base;
747     }
748
749     // It's neither an array nor .length() if we get here,
750     // leaving swizzles and struct/block dereferences.
751
752     TIntermTyped* result = base;
753     if (base->isVector() || base->isScalar()) {
754         if (base->isScalar()) {
755             const char* dotFeature = "scalar swizzle";
756             requireProfile(loc, ~EEsProfile, dotFeature);
757             profileRequires(loc, ~EEsProfile, 420, GL_ARB_shading_language_420pack, dotFeature);
758         }
759
760         TVectorFields fields;
761         if (! parseVectorFields(loc, field, base->getVectorSize(), fields)) {
762             fields.num = 1;
763             fields.offsets[0] = 0;
764         }
765
766         if (base->isScalar()) {
767             if (fields.num == 1)
768                 return result;
769             else {
770                 TType type(base->getBasicType(), EvqTemporary, fields.num);
771                 return addConstructor(loc, base, type, mapTypeToConstructorOp(type));
772             }
773         }
774
775         if (base->getType().getQualifier().storage == EvqConst)
776             result = intermediate.foldSwizzle(base, fields, loc);
777         else {
778             if (fields.num == 1) {
779                 TIntermTyped* index = intermediate.addConstantUnion(fields.offsets[0], loc);
780                 result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
781                 result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision));
782             } else {
783                 TString vectorString = field;
784                 TIntermTyped* index = intermediate.addSwizzle(fields, loc);
785                 result = intermediate.addIndex(EOpVectorSwizzle, base, index, loc);
786                 result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision, (int) vectorString.size()));
787             }
788         }
789     } else if (base->getBasicType() == EbtStruct || base->getBasicType() == EbtBlock) {
790         const TTypeList* fields = base->getType().getStruct();
791         bool fieldFound = false;
792         int member;
793         for (member = 0; member < (int)fields->size(); ++member) {
794             if ((*fields)[member].type->getFieldName() == field) {
795                 fieldFound = true;
796                 break;
797             }
798         }
799         if (fieldFound) {
800             if (base->getType().getQualifier().storage == EvqConst)
801                 result = intermediate.foldDereference(base, member, loc);
802             else {
803                 TIntermTyped* index = intermediate.addConstantUnion(member, loc);
804                 result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc);
805                 result->setType(*(*fields)[member].type);
806             }
807         } else
808             error(loc, "no such field in structure", field.c_str(), "");
809     } else
810         error(loc, "does not apply to this type:", field.c_str(), base->getType().getCompleteString().c_str());
811
812     return result;
813 }
814
815 //
816 // Handle seeing a function declarator in the grammar.  This is the precursor
817 // to recognizing a function prototype or function definition.
818 //
819 TFunction* TParseContext::handleFunctionDeclarator(TSourceLoc loc, TFunction& function, bool prototype)
820 {
821     // ES can't declare prototypes inside functions
822     if (! symbolTable.atGlobalLevel())
823         requireProfile(loc, ~EEsProfile, "local function declaration");
824
825     //
826     // Multiple declarations of the same function name are allowed.
827     //
828     // If this is a definition, the definition production code will check for redefinitions
829     // (we don't know at this point if it's a definition or not).
830     //
831     // Redeclarations (full signature match) are allowed.  But, return types and parameter qualifiers must also match.
832     //  - except ES 100, which only allows a single prototype
833     //
834     // ES 100 does not allow redefining, but does allow overloading of built-in functions.
835     // ES 300 does not allow redefining or overloading of built-in functions.
836     //
837     bool builtIn;
838     TSymbol* symbol = symbolTable.find(function.getMangledName(), &builtIn);
839     if (symbol && symbol->getAsFunction() && builtIn)
840         requireProfile(loc, ~EEsProfile, "redefinition of built-in function");
841     const TFunction* prevDec = symbol ? symbol->getAsFunction() : 0;
842     if (prevDec) {
843         if (prevDec->isPrototyped() && prototype)
844             profileRequires(loc, EEsProfile, 300, 0, "multiple prototypes for same function");
845         if (prevDec->getType() != function.getType())
846             error(loc, "overloaded functions must have the same return type", function.getType().getBasicTypeString().c_str(), "");
847         for (int i = 0; i < prevDec->getParamCount(); ++i) {
848             if ((*prevDec)[i].type->getQualifier().storage != function[i].type->getQualifier().storage)
849                 error(loc, "overloaded functions must have the same parameter storage qualifiers for argument", function[i].type->getStorageQualifierString(), "%d", i+1);
850
851             if ((*prevDec)[i].type->getQualifier().precision != function[i].type->getQualifier().precision)
852                 error(loc, "overloaded functions must have the same parameter precision qualifiers for argument", function[i].type->getPrecisionQualifierString(), "%d", i+1);
853         }
854     }
855
856     arrayObjectCheck(loc, function.getType(), "array in function return type");
857
858     if (prototype) {
859         // All built-in functions are defined, even though they don't have a body.
860         // Count their prototype as a definition instead.
861         if (symbolTable.atBuiltInLevel())
862             function.setDefined();
863         else {
864             if (prevDec && ! builtIn)                
865                 symbol->getAsFunction()->setPrototyped();  // need a writable one, but like having prevDec as a const
866             function.setPrototyped();
867         }
868     }
869
870     // This insert won't actually insert it if it's a duplicate signature, but it will still check for
871     // other forms of name collisions.
872     if (! symbolTable.insert(function))
873         error(loc, "function name is redeclaration of existing name", function.getName().c_str(), "");
874
875     //
876     // If this is a redeclaration, it could also be a definition,
877     // in which case, we need to use the parameter names from this one, and not the one that's
878     // being redeclared.  So, pass back this declaration, not the one in the symbol table.
879     //
880     return &function;
881 }
882
883 //
884 // Handle seeing the function prototype in front of a function definition in the grammar.  
885 // The body is handled after this function returns.
886 //
887 TIntermAggregate* TParseContext::handleFunctionDefinition(TSourceLoc loc, TFunction& function)
888 {
889     currentCaller = function.getMangledName();
890     TSymbol* symbol = symbolTable.find(function.getMangledName());
891     TFunction* prevDec = symbol ? symbol->getAsFunction() : 0;
892
893     if (! prevDec)
894         error(loc, "can't find function", function.getName().c_str(), "");
895     // Note:  'prevDec' could be 'function' if this is the first time we've seen function
896     // as it would have just been put in the symbol table.  Otherwise, we're looking up
897     // an earlier occurance.
898
899     if (prevDec && prevDec->isDefined()) {
900         // Then this function already has a body.
901         error(loc, "function already has a body", function.getName().c_str(), "");
902     }
903     if (prevDec && ! prevDec->isDefined()) {
904         prevDec->setDefined();
905
906         // Remember the return type for later checking for RETURN statements.
907         currentFunctionType = &(prevDec->getType());
908     } else
909         currentFunctionType = new TType(EbtVoid);
910     functionReturnsValue = false;
911
912     //
913     // Raise error message if main function takes any parameters or returns anything other than void
914     //
915     if (function.getName() == "main") {
916         if (function.getParamCount() > 0)
917             error(loc, "function cannot take any parameter(s)", function.getName().c_str(), "");
918         if (function.getType().getBasicType() != EbtVoid)
919             error(loc, "", function.getType().getBasicTypeString().c_str(), "main function cannot return a value");
920         intermediate.addMainCount();
921         inMain = true;
922     } else
923         inMain = false;
924
925     //
926     // New symbol table scope for body of function plus its arguments
927     //
928     symbolTable.push();
929
930     //
931     // Insert parameters into the symbol table.
932     // If the parameter has no name, it's not an error, just don't insert it
933     // (could be used for unused args).
934     //
935     // Also, accumulate the list of parameters into the HIL, so lower level code
936     // knows where to find parameters.
937     //
938     TIntermAggregate* paramNodes = new TIntermAggregate;
939     for (int i = 0; i < function.getParamCount(); i++) {
940         TParameter& param = function[i];
941         if (param.name != 0) {
942             TVariable *variable = new TVariable(param.name, *param.type);
943
944             // Insert the parameters with name in the symbol table.
945             if (! symbolTable.insert(*variable))
946                 error(loc, "redefinition", variable->getName().c_str(), "");
947             else {
948                 // Transfer ownership of name pointer to symbol table.
949                 param.name = 0;
950
951                 // Add the parameter to the HIL
952                 paramNodes = intermediate.growAggregate(paramNodes,
953                                                         intermediate.addSymbol(*variable, loc),
954                                                         loc);
955             }
956         } else
957             paramNodes = intermediate.growAggregate(paramNodes, intermediate.addSymbol(0, "", *param.type, loc), loc);
958     }
959     intermediate.setAggregateOperator(paramNodes, EOpParameters, TType(EbtVoid), loc);
960     loopNestingLevel = 0;
961     statementNestingLevel = 0;
962     controlFlowNestingLevel = 0;
963     postMainReturn = false;
964
965     return paramNodes;
966 }
967
968 //
969 // Handle seeing function call syntax in the grammar, which could be any of
970 //  - .length() method
971 //  - constructor
972 //  - a call to a built-in function mapped to an operator
973 //  - a call to a built-in function that will remain a function call (e.g., texturing)
974 //  - user function
975 //  - subroutine call (not implemented yet)
976 //
977 TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* function, TIntermNode* arguments)
978 {
979     TIntermTyped* result = 0;
980
981     TOperator op = function->getBuiltInOp();
982     if (op == EOpArrayLength)
983         result = handleLengthMethod(loc, function, arguments);
984     else if (op != EOpNull) {
985         //
986         // Then this should be a constructor.
987         // Don't go through the symbol table for constructors.
988         // Their parameters will be verified algorithmically.
989         //
990         TType type(EbtVoid);  // use this to get the type back
991         if (! constructorError(loc, arguments, *function, op, type)) {
992             //
993             // It's a constructor, of type 'type'.
994             //
995             result = addConstructor(loc, arguments, type, op);
996             if (result == 0)
997                 error(loc, "cannot construct with these arguments", type.getCompleteString().c_str(), "");
998         }
999     } else {
1000         //
1001         // Find it in the symbol table.
1002         //
1003         const TFunction* fnCandidate;
1004         bool builtIn;
1005         fnCandidate = findFunction(loc, *function, builtIn);
1006         if (fnCandidate) {
1007             // This is a declared function that might map to
1008             //  - a built-in operator,
1009             //  - a built-in function not mapped to an operator, or
1010             //  - a user function.
1011
1012             // Error check for a function requiring specific extensions present.
1013             if (builtIn && fnCandidate->getNumExtensions())
1014                 requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str());
1015
1016             if (arguments) {
1017                 // Make sure qualifications work for these arguments.
1018                 TIntermAggregate* aggregate = arguments->getAsAggregate();
1019                 for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
1020                     // At this early point there is a slight ambiguity between whether an aggregate 'arguments'
1021                     // is the single argument itself or its children are the arguments.  Only one argument
1022                     // means take 'arguments' itself as the one argument.
1023                     TIntermNode* arg = fnCandidate->getParamCount() == 1 ? arguments : (aggregate ? aggregate->getSequence()[i] : arguments);
1024                     TQualifier& formalQualifier = (*fnCandidate)[i].type->getQualifier();
1025                     if (formalQualifier.storage == EvqOut || formalQualifier.storage == EvqInOut) {
1026                         if (lValueErrorCheck(arguments->getLoc(), "assign", arg->getAsTyped()))
1027                             error(arguments->getLoc(), "Non-L-value cannot be passed for 'out' or 'inout' parameters.", "out", "");
1028                     }
1029                     TQualifier& argQualifier = arg->getAsTyped()->getQualifier();
1030                     if (argQualifier.isMemory()) {
1031                         const char* message = "argument cannot drop memory qualifier when passed to formal parameter";
1032                         if (argQualifier.volatil && ! formalQualifier.volatil)
1033                             error(arguments->getLoc(), message, "volatile", "");
1034                         if (argQualifier.coherent && ! formalQualifier.coherent)
1035                             error(arguments->getLoc(), message, "coherent", "");
1036                         if (argQualifier.readonly && ! formalQualifier.readonly)
1037                             error(arguments->getLoc(), message, "readonly", "");
1038                         if (argQualifier.writeonly && ! formalQualifier.writeonly)
1039                             error(arguments->getLoc(), message, "writeonly", "");
1040                     }
1041                     // TODO 4.5 functionality:  A shader will fail to compile 
1042                     // if the value passed to the memargument of an atomic memory function does not correspond to a buffer or
1043                     // shared variable. It is acceptable to pass an element of an array or a single component of a vector to the 
1044                     // memargument of an atomic memory function, as long as the underlying array or vector is a buffer or 
1045                     // shared variable.
1046                 }
1047
1048                 // Convert 'in' arguments
1049                 addInputArgumentConversions(*fnCandidate, arguments);  // arguments may be modified if it's just a single argument node
1050             }
1051
1052             op = fnCandidate->getBuiltInOp();
1053             if (builtIn && op != EOpNull) {
1054                 // A function call mapped to a built-in operation.
1055                 checkLocation(loc, op);
1056                 result = intermediate.addBuiltInFunctionCall(loc, op, fnCandidate->getParamCount() == 1, arguments, fnCandidate->getType());
1057                 if (result == 0)  {
1058                     error(arguments->getLoc(), " wrong operand type", "Internal Error",
1059                                         "built in unary operator function.  Type: %s",
1060                                         static_cast<TIntermTyped*>(arguments)->getCompleteString().c_str());
1061                 }
1062             } else {
1063                 // This is a function call not mapped to built-in operator, but it could still be a built-in function
1064                 result = intermediate.setAggregateOperator(arguments, EOpFunctionCall, fnCandidate->getType(), loc);
1065                 TIntermAggregate* call = result->getAsAggregate();
1066                 call->setName(fnCandidate->getMangledName());
1067
1068                 // this is how we know whether the given function is a built-in function or a user-defined function
1069                 // if builtIn == false, it's a userDefined -> could be an overloaded built-in function also
1070                 // if builtIn == true, it's definitely a built-in function with EOpNull
1071                 if (! builtIn) {
1072                     call->setUserDefined();
1073                     intermediate.addToCallGraph(infoSink, currentCaller, fnCandidate->getMangledName());
1074                 }
1075
1076                 if (builtIn)
1077                     nonOpBuiltInCheck(loc, *fnCandidate, *call);
1078             }
1079
1080             // Convert 'out' arguments.  If it was a constant folded built-in, it won't be an aggregate anymore.
1081             // Built-ins with a single argument aren't called with an aggregate, but they also don't have an output.
1082             // Also, build the qualifier list for user function calls, which are always called with an aggregate.
1083             if (result->getAsAggregate()) {
1084                 TQualifierList& qualifierList = result->getAsAggregate()->getQualifierList();
1085                 for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
1086                     TStorageQualifier qual = (*fnCandidate)[i].type->getQualifier().storage;
1087                     qualifierList.push_back(qual);
1088                 }
1089                 result = addOutputArgumentConversions(*fnCandidate, *result->getAsAggregate());
1090             }
1091         }
1092     }
1093
1094     // generic error recovery
1095     // TODO: simplification: localize all the error recoveries that look like this, and taking type into account to reduce cascades
1096     if (result == 0)
1097         result = intermediate.addConstantUnion(0.0, EbtFloat, loc);
1098
1099     return result;
1100 }
1101
1102 // See if the operation is being done in an illegal location.
1103 void TParseContext::checkLocation(TSourceLoc loc, TOperator op)
1104 {
1105     switch (op) {
1106     case EOpBarrier:
1107         if (language == EShLangTessControl) {
1108             if (controlFlowNestingLevel > 0)
1109                 error(loc, "tessellation control barrier() cannot be placed within flow control", "", "");
1110             if (! inMain)
1111                 error(loc, "tessellation control barrier() must be in main()", "", "");
1112             else if (postMainReturn)
1113                 error(loc, "tessellation control barrier() cannot be placed after a return from main()", "", "");
1114         }
1115         break;
1116     default:
1117         break;
1118     }
1119 }
1120
1121 // Finish processing object.length(). This started earlier in handleDotDereference(), where
1122 // the ".length" part was recognized and semantically checked, and finished here where the 
1123 // function syntax "()" is recognized.
1124 //
1125 // Return resulting tree node.
1126 TIntermTyped* TParseContext::handleLengthMethod(TSourceLoc loc, TFunction* function, TIntermNode* intermNode)
1127 {
1128     int length = 0;
1129
1130     if (function->getParamCount() > 0)
1131         error(loc, "method does not accept any arguments", function->getName().c_str(), "");
1132     else {
1133         const TType& type = intermNode->getAsTyped()->getType();
1134         if (type.isArray()) {
1135             if (type.isRuntimeSizedArray()) {
1136                 // Create a unary op and let the back end handle it
1137                 return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt));
1138             } else if (type.isImplicitlySizedArray()) {
1139                 if (intermNode->getAsSymbolNode() && isIoResizeArray(type)) {
1140                     // We could be between a layout declaration that gives a built-in io array implicit size and 
1141                     // a user redeclaration of that array, meaning we have to substitute its implicit size here 
1142                     // without actually redeclaring the array.  (It is an error to use a member before the
1143                     // redeclaration, but not an error to use the array name itself.)
1144                     const TString& name = intermNode->getAsSymbolNode()->getName();
1145                     if (name == "gl_in" || name == "gl_out")
1146                         length = getIoArrayImplicitSize();
1147                 }
1148                 if (length == 0) {
1149                     if (intermNode->getAsSymbolNode() && isIoResizeArray(type))
1150                         error(loc, "", function->getName().c_str(), "array must first be sized by a redeclaration or layout qualifier");
1151                     else
1152                         error(loc, "", function->getName().c_str(), "array must be declared with a size before using this method");
1153                 }
1154             } else
1155                 length = type.getArraySize();
1156         } else if (type.isMatrix())
1157             length = type.getMatrixCols();
1158         else if (type.isVector())
1159             length = type.getVectorSize();
1160         else {
1161             // we should not get here, because earlier semantic checking should have prevented this path
1162             error(loc, ".length()", "unexpected use of .length()", "");
1163         }
1164     }
1165
1166     if (length == 0)
1167         length = 1;
1168
1169     return intermediate.addConstantUnion(length, loc);
1170 }
1171
1172 //
1173 // Add any needed implicit conversions for function-call arguments to input parameters.
1174 //
1175 void TParseContext::addInputArgumentConversions(const TFunction& function, TIntermNode*& arguments) const
1176 {
1177     TIntermAggregate* aggregate = arguments->getAsAggregate();
1178
1179     // Process each argument's conversion
1180     for (int i = 0; i < function.getParamCount(); ++i) {
1181         // At this early point there is a slight ambiguity between whether an aggregate 'arguments'
1182         // is the single argument itself or its children are the arguments.  Only one argument
1183         // means take 'arguments' itself as the one argument.
1184         TIntermTyped* arg = function.getParamCount() == 1 ? arguments->getAsTyped() : (aggregate ? aggregate->getSequence()[i]->getAsTyped() : arguments->getAsTyped());
1185         if (*function[i].type != arg->getType()) {
1186             if (function[i].type->getQualifier().isParamInput()) {
1187                 // In-qualified arguments just need an extra node added above the argument to
1188                 // convert to the correct type.
1189                 arg = intermediate.addConversion(EOpFunctionCall, *function[i].type, arg);
1190                 if (arg) {
1191                     if (aggregate)
1192                         aggregate->getSequence()[i] = arg;
1193                     else
1194                         arguments = arg;
1195                 }
1196             }
1197         }
1198     }
1199 }
1200
1201 //
1202 // Add any needed implicit output conversions for function-call arguments.  This
1203 // can require a new tree topology, complicated further by whether the function
1204 // has a return value.
1205 //
1206 // Returns a node of a subtree that evaluates to the return value of the function.
1207 //
1208 TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& function, TIntermAggregate& intermNode) const
1209 {
1210     TIntermSequence& arguments = intermNode.getSequence();
1211
1212     // Will there be any output conversions?
1213     bool outputConversions = false;
1214     for (int i = 0; i < function.getParamCount(); ++i) {
1215         if (*function[i].type != arguments[i]->getAsTyped()->getType() && function[i].type->getQualifier().storage == EvqOut) {
1216             outputConversions = true;
1217             break;
1218         }
1219     }
1220
1221     if (! outputConversions)
1222         return &intermNode;
1223
1224     // Setup for the new tree, if needed:
1225     //
1226     // Output conversions need a different tree topology.
1227     // Out-qualified arguments need a temporary of the correct type, with the call
1228     // followed by an assignment of the temporary to the original argument:
1229     //     void: function(arg, ...)  ->        (          function(tempArg, ...), arg = tempArg, ...)
1230     //     ret = function(arg, ...)  ->  ret = (tempRet = function(tempArg, ...), arg = tempArg, ..., tempRet)
1231     // Where the "tempArg" type needs no conversion as an argument, but will convert on assignment.
1232     TIntermTyped* conversionTree = 0;
1233     TVariable* tempRet = 0;
1234     if (intermNode.getBasicType() != EbtVoid) {
1235         // do the "tempRet = function(...), " bit from above
1236         tempRet = makeInternalVariable("tempReturn", intermNode.getType());
1237         TIntermSymbol* tempRetNode = intermediate.addSymbol(*tempRet, intermNode.getLoc());
1238         conversionTree = intermediate.addAssign(EOpAssign, tempRetNode, &intermNode, intermNode.getLoc());
1239     } else
1240         conversionTree = &intermNode;
1241
1242     conversionTree = intermediate.makeAggregate(conversionTree);
1243
1244     // Process each argument's conversion
1245     for (int i = 0; i < function.getParamCount(); ++i) {
1246         if (*function[i].type != arguments[i]->getAsTyped()->getType()) {
1247             if (function[i].type->getQualifier().isParamOutput()) {
1248                 // Out-qualified arguments need to use the topology set up above.
1249                 // do the " ...(tempArg, ...), arg = tempArg" bit from above
1250                 TVariable* tempArg = makeInternalVariable("tempArg", *function[i].type);
1251                 tempArg->getWritableType().getQualifier().makeTemporary();
1252                 TIntermSymbol* tempArgNode = intermediate.addSymbol(*tempArg, intermNode.getLoc());
1253                 TIntermTyped* tempAssign = intermediate.addAssign(EOpAssign, arguments[i]->getAsTyped(), tempArgNode, arguments[i]->getLoc());
1254                 conversionTree = intermediate.growAggregate(conversionTree, tempAssign, arguments[i]->getLoc());
1255                 // replace the argument with another node for the same tempArg variable
1256                 arguments[i] = intermediate.addSymbol(*tempArg, intermNode.getLoc());
1257             }
1258         }
1259     }
1260
1261     // Finalize the tree topology (see bigger comment above).
1262     if (tempRet) {
1263         // do the "..., tempRet" bit from above
1264         TIntermSymbol* tempRetNode = intermediate.addSymbol(*tempRet, intermNode.getLoc());
1265         conversionTree = intermediate.growAggregate(conversionTree, tempRetNode, intermNode.getLoc());
1266     }
1267     conversionTree = intermediate.setAggregateOperator(conversionTree, EOpComma, intermNode.getType(), intermNode.getLoc());
1268
1269     return conversionTree;
1270 }
1271
1272 //
1273 // Do additional checking of built-in function calls that were not mapped
1274 // to built-in operations (e.g., texturing functions).
1275 //
1276 // Assumes there has been a semantically correct match to a built-in function.
1277 //
1278 void TParseContext::nonOpBuiltInCheck(TSourceLoc loc, const TFunction& fnCandidate, TIntermAggregate& callNode)
1279 {
1280     // built-in texturing functions get their return value precision from the precision of the sampler
1281     if (fnCandidate.getType().getQualifier().precision == EpqNone &&
1282         fnCandidate.getParamCount() > 0 && fnCandidate[0].type->getBasicType() == EbtSampler)
1283         callNode.getQualifier().precision = callNode.getAsAggregate()->getSequence()[0]->getAsTyped()->getQualifier().precision;
1284
1285     if (fnCandidate.getName().compare(0, 7, "texture") == 0) {
1286         if (fnCandidate.getName().compare(0, 13, "textureGather") == 0) {
1287             TString featureString = fnCandidate.getName() + "(...)";
1288             const char* feature = featureString.c_str();
1289             profileRequires(loc, EEsProfile, 310, 0, feature);
1290
1291             int compArg = -1;  // track which argument, if any, is the constant component argument
1292             if (fnCandidate.getName().compare("textureGatherOffset") == 0) {
1293                 // GL_ARB_texture_gather is good enough for 2D non-shadow textures with no component argument
1294                 if (fnCandidate[0].type->getSampler().dim == Esd2D && ! fnCandidate[0].type->getSampler().shadow && fnCandidate.getParamCount() == 3)
1295                     profileRequires(loc, ~EEsProfile, 400, GL_ARB_texture_gather, feature);
1296                 else
1297                     profileRequires(loc, ~EEsProfile, 400, GL_ARB_gpu_shader5, feature);
1298                 if (! fnCandidate[0].type->getSampler().shadow)
1299                     compArg = 3;
1300             } else if (fnCandidate.getName().compare("textureGatherOffsets") == 0) {
1301                 profileRequires(loc, ~EEsProfile, 400, GL_ARB_gpu_shader5, feature);
1302                 if (! fnCandidate[0].type->getSampler().shadow)
1303                     compArg = 3;
1304                 // check for constant offsets
1305                 int offsetArg = fnCandidate[0].type->getSampler().shadow ? 3 : 2;
1306                 if (! callNode.getSequence()[offsetArg]->getAsConstantUnion())
1307                     error(loc, "must be a compile-time constant:", feature, "offsets argument");
1308             } else if (fnCandidate.getName().compare("textureGather") == 0) {
1309                 // More than two arguments needs gpu_shader5, and rectangular or shadow needs gpu_shader5,
1310                 // otherwise, need GL_ARB_texture_gather.
1311                 if (fnCandidate.getParamCount() > 2 || fnCandidate[0].type->getSampler().dim == EsdRect || fnCandidate[0].type->getSampler().shadow) {
1312                     profileRequires(loc, ~EEsProfile, 400, GL_ARB_gpu_shader5, feature);
1313                     if (! fnCandidate[0].type->getSampler().shadow)
1314                         compArg = 2;
1315                 } else
1316                     profileRequires(loc, ~EEsProfile, 400, GL_ARB_texture_gather, feature);
1317             }
1318
1319             if (compArg > 0 && compArg < fnCandidate.getParamCount()) {
1320                 if (callNode.getSequence()[compArg]->getAsConstantUnion()) {
1321                     int value = callNode.getSequence()[compArg]->getAsConstantUnion()->getConstArray()[0].getIConst();
1322                     if (value < 0 || value > 3)
1323                         error(loc, "must be 0, 1, 2, or 3:", feature, "component argument");
1324                 } else
1325                     error(loc, "must be a compile-time constant:", feature, "component argument");
1326             }
1327         } else {
1328             // this is only for functions not starting "textureGather"...
1329             if (fnCandidate.getName().find("Offset") != TString::npos) {
1330
1331                 // Handle texture-offset limits checking
1332                 int arg = -1;
1333                 if (fnCandidate.getName().compare("textureOffset") == 0)
1334                     arg = 2;
1335                 else if (fnCandidate.getName().compare("texelFetchOffset") == 0)
1336                     arg = 3;
1337                 else if (fnCandidate.getName().compare("textureProjOffset") == 0)
1338                     arg = 2;
1339                 else if (fnCandidate.getName().compare("textureLodOffset") == 0)
1340                     arg = 3;
1341                 else if (fnCandidate.getName().compare("textureProjLodOffset") == 0)
1342                     arg = 3;
1343                 else if (fnCandidate.getName().compare("textureGradOffset") == 0)
1344                     arg = 4;
1345                 else if (fnCandidate.getName().compare("textureProjGradOffset") == 0)
1346                     arg = 4;
1347
1348                 if (arg > 0) {
1349                     if (! callNode.getSequence()[arg]->getAsConstantUnion())
1350                         error(loc, "argument must be compile-time constant", "texel offset", "");
1351                     else {
1352                         const TType& type = callNode.getSequence()[arg]->getAsTyped()->getType();
1353                         for (int c = 0; c < type.getVectorSize(); ++c) {
1354                             int offset = callNode.getSequence()[arg]->getAsConstantUnion()->getConstArray()[c].getIConst();
1355                             if (offset > resources.maxProgramTexelOffset || offset < resources.minProgramTexelOffset)
1356                                 error(loc, "value is out of range:", "texel offset", "[gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]");
1357                         }
1358                     }
1359                 }
1360             }
1361         }
1362     }
1363
1364     // GL_ARB_shader_texture_image_samples
1365     if (fnCandidate.getName().compare(0, 14, "textureSamples") == 0 || fnCandidate.getName().compare(0, 12, "imageSamples") == 0)
1366         profileRequires(loc, ~EEsProfile, 450, GL_ARB_shader_texture_image_samples, "textureSamples and imageSamples");
1367
1368     if (fnCandidate.getName().compare(0, 11, "imageAtomic") == 0) {
1369         const TType& imageType = callNode.getSequence()[0]->getAsTyped()->getType();
1370         if (imageType.getSampler().type == EbtInt || imageType.getSampler().type == EbtUint) {
1371             if (imageType.getQualifier().layoutFormat != ElfR32i && imageType.getQualifier().layoutFormat != ElfR32ui)
1372                 error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), "");
1373         } else if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0) 
1374             error(loc, "only supported on integer images", fnCandidate.getName().c_str(), "");
1375     }
1376 }
1377
1378 //
1379 // Handle seeing a built-in constructor in a grammar production.
1380 //
1381 TFunction* TParseContext::handleConstructorCall(TSourceLoc loc, const TPublicType& publicType)
1382 {
1383     TType type(publicType);
1384     type.getQualifier().precision = EpqNone;
1385
1386     if (type.isArray()) {
1387         profileRequires(loc, ENoProfile, 120, GL_3DL_array_objects, "arrayed constructor");
1388         profileRequires(loc, EEsProfile, 300, 0, "arrayed constructor");
1389     }
1390
1391     TOperator op = mapTypeToConstructorOp(type);
1392
1393     if (op == EOpNull) {
1394         error(loc, "cannot construct this type", type.getBasicString(), "");
1395         op = EOpConstructFloat;
1396         TType errorType(EbtFloat);
1397         type.shallowCopy(errorType);
1398     }
1399
1400     TString empty("");
1401
1402     return new TFunction(&empty, type, op);
1403 }
1404
1405 //
1406 // Given a type, find what operation would fully construct it.
1407 //
1408 TOperator TParseContext::mapTypeToConstructorOp(const TType& type) const
1409 {
1410     if (type.isStruct())
1411         return EOpConstructStruct;
1412
1413     TOperator op = EOpNull;
1414     switch (type.getBasicType()) {
1415     case EbtFloat:
1416         if (type.isMatrix()) {
1417             switch (type.getMatrixCols()) {
1418             case 2:
1419                 switch (type.getMatrixRows()) {
1420                 case 2: op = EOpConstructMat2x2; break;
1421                 case 3: op = EOpConstructMat2x3; break;
1422                 case 4: op = EOpConstructMat2x4; break;
1423                 default: break; // some compilers want this
1424                 }
1425                 break;
1426             case 3:
1427                 switch (type.getMatrixRows()) {
1428                 case 2: op = EOpConstructMat3x2; break;
1429                 case 3: op = EOpConstructMat3x3; break;
1430                 case 4: op = EOpConstructMat3x4; break;
1431                 default: break; // some compilers want this
1432                 }
1433                 break;
1434             case 4:
1435                 switch (type.getMatrixRows()) {
1436                 case 2: op = EOpConstructMat4x2; break;
1437                 case 3: op = EOpConstructMat4x3; break;
1438                 case 4: op = EOpConstructMat4x4; break;
1439                 default: break; // some compilers want this
1440                 }
1441                 break;
1442             default: break; // some compilers want this
1443             }
1444         } else {
1445             switch(type.getVectorSize()) {
1446             case 1: op = EOpConstructFloat; break;
1447             case 2: op = EOpConstructVec2;  break;
1448             case 3: op = EOpConstructVec3;  break;
1449             case 4: op = EOpConstructVec4;  break;
1450             default: break; // some compilers want this
1451             }
1452         }
1453         break;
1454     case EbtDouble:
1455         if (type.getMatrixCols()) {
1456             switch (type.getMatrixCols()) {
1457             case 2:
1458                 switch (type.getMatrixRows()) {
1459                 case 2: op = EOpConstructDMat2x2; break;
1460                 case 3: op = EOpConstructDMat2x3; break;
1461                 case 4: op = EOpConstructDMat2x4; break;
1462                 default: break; // some compilers want this
1463                 }
1464                 break;
1465             case 3:
1466                 switch (type.getMatrixRows()) {
1467                 case 2: op = EOpConstructDMat3x2; break;
1468                 case 3: op = EOpConstructDMat3x3; break;
1469                 case 4: op = EOpConstructDMat3x4; break;
1470                 default: break; // some compilers want this
1471                 }
1472                 break;
1473             case 4:
1474                 switch (type.getMatrixRows()) {
1475                 case 2: op = EOpConstructDMat4x2; break;
1476                 case 3: op = EOpConstructDMat4x3; break;
1477                 case 4: op = EOpConstructDMat4x4; break;
1478                 default: break; // some compilers want this
1479                 }
1480                 break;
1481             }
1482         } else {
1483             switch(type.getVectorSize()) {
1484             case 1: op = EOpConstructDouble; break;
1485             case 2: op = EOpConstructDVec2;  break;
1486             case 3: op = EOpConstructDVec3;  break;
1487             case 4: op = EOpConstructDVec4;  break;
1488             default: break; // some compilers want this
1489             }
1490         }
1491         break;
1492     case EbtInt:
1493         switch(type.getVectorSize()) {
1494         case 1: op = EOpConstructInt;   break;
1495         case 2: op = EOpConstructIVec2; break;
1496         case 3: op = EOpConstructIVec3; break;
1497         case 4: op = EOpConstructIVec4; break;
1498         default: break; // some compilers want this
1499         }
1500         break;
1501     case EbtUint:
1502         switch(type.getVectorSize()) {
1503         case 1: op = EOpConstructUint;  break;
1504         case 2: op = EOpConstructUVec2; break;
1505         case 3: op = EOpConstructUVec3; break;
1506         case 4: op = EOpConstructUVec4; break;
1507         default: break; // some compilers want this
1508         }
1509         break;
1510     case EbtBool:
1511         switch(type.getVectorSize()) {
1512         case 1:  op = EOpConstructBool;  break;
1513         case 2:  op = EOpConstructBVec2; break;
1514         case 3:  op = EOpConstructBVec3; break;
1515         case 4:  op = EOpConstructBVec4; break;
1516         default: break; // some compilers want this
1517         }
1518         break;
1519     default:
1520         break;
1521     }
1522
1523     return op;
1524 }
1525
1526 //
1527 // Same error message for all places assignments don't work.
1528 //
1529 void TParseContext::assignError(TSourceLoc loc, const char* op, TString left, TString right)
1530 {
1531     error(loc, "", op, "cannot convert from '%s' to '%s'",
1532           right.c_str(), left.c_str());
1533 }
1534
1535 //
1536 // Same error message for all places unary operations don't work.
1537 //
1538 void TParseContext::unaryOpError(TSourceLoc loc, const char* op, TString operand)
1539 {
1540    error(loc, " wrong operand type", op,
1541           "no operation '%s' exists that takes an operand of type %s (or there is no acceptable conversion)",
1542           op, operand.c_str());
1543 }
1544
1545 //
1546 // Same error message for all binary operations don't work.
1547 //
1548 void TParseContext::binaryOpError(TSourceLoc loc, const char* op, TString left, TString right)
1549 {
1550     error(loc, " wrong operand types:", op,
1551             "no operation '%s' exists that takes a left-hand operand of type '%s' and "
1552             "a right operand of type '%s' (or there is no acceptable conversion)",
1553             op, left.c_str(), right.c_str());
1554 }
1555
1556 //
1557 // A basic type of EbtVoid is a key that the name string was seen in the source, but
1558 // it was not found as a variable in the symbol table.  If so, give the error
1559 // message and insert a dummy variable in the symbol table to prevent future errors.
1560 //
1561 void TParseContext::variableCheck(TIntermTyped*& nodePtr)
1562 {
1563     TIntermSymbol* symbol = nodePtr->getAsSymbolNode();
1564     if (! symbol)
1565         return;
1566
1567     if (symbol->getType().getBasicType() == EbtVoid) {
1568         error(symbol->getLoc(), "undeclared identifier", symbol->getName().c_str(), "");
1569
1570         // Add to symbol table to prevent future error messages on the same name
1571
1572         TVariable* fakeVariable = new TVariable(&symbol->getName(), TType(EbtFloat));
1573         symbolTable.insert(*fakeVariable);
1574
1575         // substitute a symbol node for this new variable
1576         nodePtr = intermediate.addSymbol(*fakeVariable, symbol->getLoc());
1577     } else {
1578         switch (symbol->getQualifier().storage) {
1579         case EvqPointCoord:
1580             profileRequires(symbol->getLoc(), ENoProfile, 120, 0, "gl_PointCoord");
1581             break;
1582         default: break; // some compilers want this
1583         }
1584     }
1585 }
1586
1587 //
1588 // Both test and if necessary, spit out an error, to see if the node is really
1589 // an l-value that can be operated on this way.
1590 //
1591 // Returns true if the was an error.
1592 //
1593 bool TParseContext::lValueErrorCheck(TSourceLoc loc, const char* op, TIntermTyped* node)
1594 {
1595     TIntermBinary* binaryNode = node->getAsBinaryNode();
1596
1597     if (binaryNode) {
1598         bool errorReturn;
1599
1600         switch(binaryNode->getOp()) {
1601         case EOpIndexDirect:
1602         case EOpIndexIndirect:
1603         case EOpIndexDirectStruct:
1604             return lValueErrorCheck(loc, op, binaryNode->getLeft());
1605         case EOpVectorSwizzle:
1606             errorReturn = lValueErrorCheck(loc, op, binaryNode->getLeft());
1607             if (!errorReturn) {
1608                 int offset[4] = {0,0,0,0};
1609
1610                 TIntermTyped* rightNode = binaryNode->getRight();
1611                 TIntermAggregate *aggrNode = rightNode->getAsAggregate();
1612
1613                 for (TIntermSequence::iterator p = aggrNode->getSequence().begin();
1614                                                p != aggrNode->getSequence().end(); p++) {
1615                     int value = (*p)->getAsTyped()->getAsConstantUnion()->getConstArray()[0].getIConst();
1616                     offset[value]++;
1617                     if (offset[value] > 1) {
1618                         error(loc, " l-value of swizzle cannot have duplicate components", op, "", "");
1619
1620                         return true;
1621                     }
1622                 }
1623             }
1624
1625             return errorReturn;
1626         default:
1627             break;
1628         }
1629         error(loc, " l-value required", op, "", "");
1630
1631         return true;
1632     }
1633
1634
1635     const char* symbol = 0;
1636     TIntermSymbol* symNode = node->getAsSymbolNode();
1637     if (symNode != 0)
1638         symbol = symNode->getName().c_str();
1639
1640     const char* message = 0;
1641     switch (node->getQualifier().storage) {
1642     case EvqConst:          message = "can't modify a const";        break;
1643     case EvqConstReadOnly:  message = "can't modify a const";        break;
1644     case EvqVaryingIn:      message = "can't modify shader input";   break;
1645     case EvqInstanceId:     message = "can't modify gl_InstanceID";  break;
1646     case EvqVertexId:       message = "can't modify gl_VertexID";    break;
1647     case EvqFace:           message = "can't modify gl_FrontFace";   break;
1648     case EvqFragCoord:      message = "can't modify gl_FragCoord";   break;
1649     case EvqPointCoord:     message = "can't modify gl_PointCoord";  break;
1650     case EvqUniform:        message = "can't modify a uniform";      break;
1651     case EvqBuffer:
1652         if (node->getQualifier().readonly)
1653             message = "can't modify a readonly buffer";
1654         break;
1655     default:
1656
1657         //
1658         // Type that can't be written to?
1659         //
1660         switch (node->getBasicType()) {
1661         case EbtSampler:
1662             message = "can't modify a sampler";
1663             break;
1664         case EbtAtomicUint:
1665             message = "can't modify an atomic_uint";
1666             break;
1667         case EbtVoid:
1668             message = "can't modify void";
1669             break;
1670         default:
1671             break;
1672         }
1673     }
1674
1675     if (message == 0 && binaryNode == 0 && symNode == 0) {
1676         error(loc, " l-value required", op, "", "");
1677
1678         return true;
1679     }
1680
1681
1682     //
1683     // Everything else is okay, no error.
1684     //
1685     if (message == 0)
1686         return false;
1687
1688     //
1689     // If we get here, we have an error and a message.
1690     //
1691     if (symNode)
1692         error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message);
1693     else
1694         error(loc, " l-value required", op, "(%s)", message);
1695
1696     return true;
1697 }
1698
1699 // Test for and give an error if the node can't be read from.
1700 void TParseContext::rValueErrorCheck(TSourceLoc loc, const char* op, TIntermTyped* node)
1701 {
1702     if (! node)
1703         return;
1704
1705     TIntermBinary* binaryNode = node->getAsBinaryNode();
1706     if (binaryNode) {
1707         switch(binaryNode->getOp()) {
1708         case EOpIndexDirect:
1709         case EOpIndexIndirect:
1710         case EOpIndexDirectStruct:
1711         case EOpVectorSwizzle:
1712             rValueErrorCheck(loc, op, binaryNode->getLeft());
1713         default:
1714             break;
1715         }
1716
1717         return;
1718     }
1719
1720     TIntermSymbol* symNode = node->getAsSymbolNode();
1721     if (symNode && symNode->getQualifier().writeonly)
1722         error(loc, "can't read from writeonly object: ", op, symNode->getName().c_str());
1723 }
1724
1725 //
1726 // Both test, and if necessary spit out an error, to see if the node is really
1727 // a constant.
1728 //
1729 void TParseContext::constantValueCheck(TIntermTyped* node, const char* token)
1730 {
1731     if (node->getQualifier().storage != EvqConst)
1732         error(node->getLoc(), "constant expression required", token, "");
1733 }
1734
1735 //
1736 // Both test, and if necessary spit out an error, to see if the node is really
1737 // an integer.
1738 //
1739 void TParseContext::integerCheck(const TIntermTyped* node, const char* token)
1740 {
1741     if ((node->getBasicType() == EbtInt || node->getBasicType() == EbtUint) && node->isScalar())
1742         return;
1743
1744     error(node->getLoc(), "scalar integer expression required", token, "");
1745 }
1746
1747 //
1748 // Both test, and if necessary spit out an error, to see if we are currently
1749 // globally scoped.
1750 //
1751 void TParseContext::globalCheck(TSourceLoc loc, const char* token)
1752 {
1753     if (! symbolTable.atGlobalLevel())
1754         error(loc, "not allowed in nested scope", token, "");
1755 }
1756
1757 //
1758 // Reserved errors for GLSL.
1759 //
1760 void TParseContext::reservedErrorCheck(TSourceLoc loc, const TString& identifier)
1761 {
1762     // "Identifiers starting with "gl_" are reserved for use by OpenGL, and may not be
1763     // declared in a shader; this results in a compile-time error."
1764     if (! symbolTable.atBuiltInLevel()) {
1765         if (builtInName(identifier))
1766             error(loc, "identifiers starting with \"gl_\" are reserved", identifier.c_str(), "");
1767
1768         // "In addition, all identifiers containing two consecutive underscores (__) are
1769         // reserved; using such a name does not itself result in an error, but may result
1770         // in undefined behavior."
1771         if (identifier.find("__") != TString::npos)
1772             warn(loc, "identifiers containing consecutive underscores (\"__\") are reserved", identifier.c_str(), "");
1773     }
1774 }
1775
1776 //
1777 // Reserved errors for the preprocessor.
1778 //
1779 void TParseContext::reservedPpErrorCheck(TSourceLoc loc, const char* identifier, const char* op)
1780 {
1781     // "All macro names containing two consecutive underscores ( __ ) are reserved;
1782     // defining such a name does not itself result in an error, but may result in
1783     // undefined behavior.  All macro names prefixed with "GL_" ("GL" followed by a
1784     // single underscore) are also reserved, and defining such a name results in a
1785     // compile-time error."
1786     if (strncmp(identifier, "GL_", 3) == 0)
1787         error(loc, "names beginning with \"GL_\" can't be (un)defined:", op,  identifier);
1788     else if (strstr(identifier, "__") != 0) {
1789         if (profile == EEsProfile && version >= 300 &&
1790             (strcmp(identifier, "__LINE__") == 0 ||
1791              strcmp(identifier, "__FILE__") == 0 ||
1792              strcmp(identifier, "__VERSION__") == 0))
1793             error(loc, "predefined names can't be (un)defined:", op,  identifier);
1794         else
1795             warn(loc, "names containing consecutive underscores are reserved:", op, identifier);
1796     }
1797 }
1798
1799 //
1800 // See if this version/profile allows use of the line-continuation character '\'.
1801 //
1802 // Returns true if a line continuation should be done.
1803 //
1804 bool TParseContext::lineContinuationCheck(TSourceLoc loc, bool endOfComment)
1805 {
1806     const char* message = "line continuation";
1807
1808     bool lineContinuationAllowed = (profile == EEsProfile && version >= 300) ||
1809                                    (profile != EEsProfile && (version >= 420 || extensionsTurnedOn(1, &GL_ARB_shading_language_420pack)));
1810
1811     if (endOfComment) {
1812         if (lineContinuationAllowed)
1813             warn(loc, "used at end of comment; the following line is still part of the comment", message, "");
1814         else
1815             warn(loc, "used at end of comment, but this version does not provide line continuation", message, "");
1816
1817         return lineContinuationAllowed;
1818     }
1819
1820     if (messages & EShMsgRelaxedErrors) {
1821         if (! lineContinuationAllowed)
1822             warn(loc, "not allowed in this version", message, "");
1823         return true;
1824     } else {
1825         profileRequires(loc, EEsProfile, 300, 0, message);
1826         profileRequires(loc, ~EEsProfile, 420, GL_ARB_shading_language_420pack, message);
1827     }
1828
1829     return lineContinuationAllowed;
1830 }
1831
1832 bool TParseContext::builtInName(const TString& identifier)
1833 {
1834     return identifier.compare(0, 3, "gl_") == 0;
1835 }
1836
1837 //
1838 // Make sure there is enough data and not too many arguments provided to the
1839 // constructor to build something of the type of the constructor.  Also returns
1840 // the type of the constructor.
1841 //
1842 // Returns true if there was an error in construction.
1843 //
1844 bool TParseContext::constructorError(TSourceLoc loc, TIntermNode* node, TFunction& function, TOperator op, TType& type)
1845 {
1846     type.shallowCopy(function.getType());
1847
1848     bool constructingMatrix = false;
1849     switch(op) {
1850     case EOpConstructMat2x2:
1851     case EOpConstructMat2x3:
1852     case EOpConstructMat2x4:
1853     case EOpConstructMat3x2:
1854     case EOpConstructMat3x3:
1855     case EOpConstructMat3x4:
1856     case EOpConstructMat4x2:
1857     case EOpConstructMat4x3:
1858     case EOpConstructMat4x4:
1859     case EOpConstructDMat2x2:
1860     case EOpConstructDMat2x3:
1861     case EOpConstructDMat2x4:
1862     case EOpConstructDMat3x2:
1863     case EOpConstructDMat3x3:
1864     case EOpConstructDMat3x4:
1865     case EOpConstructDMat4x2:
1866     case EOpConstructDMat4x3:
1867     case EOpConstructDMat4x4:
1868         constructingMatrix = true;
1869         break;
1870     default:
1871         break;
1872     }
1873
1874     //
1875     // Note: It's okay to have too many components available, but not okay to have unused
1876     // arguments.  'full' will go to true when enough args have been seen.  If we loop
1877     // again, there is an extra argument, so 'overfull' will become true.
1878     //
1879
1880     int size = 0;
1881     bool constType = true;
1882     bool full = false;
1883     bool overFull = false;
1884     bool matrixInMatrix = false;
1885     bool arrayArg = false;
1886     for (int i = 0; i < function.getParamCount(); ++i) {
1887         size += function[i].type->computeNumComponents();
1888
1889         if (constructingMatrix && function[i].type->isMatrix())
1890             matrixInMatrix = true;
1891         if (full)
1892             overFull = true;
1893         if (op != EOpConstructStruct && ! type.isArray() && size >= type.computeNumComponents())
1894             full = true;
1895         if (function[i].type->getQualifier().storage != EvqConst)
1896             constType = false;
1897         if (function[i].type->isArray())
1898             arrayArg = true;
1899     }
1900
1901     if (constType)
1902         type.getQualifier().storage = EvqConst;
1903
1904     if (type.isArray()) {
1905         if (type.isImplicitlySizedArray()) {
1906             // auto adapt the constructor type to the number of arguments
1907             type.changeArraySize(function.getParamCount());
1908         } else if (type.getArraySize() != function.getParamCount()) {
1909             error(loc, "array constructor needs one argument per array element", "constructor", "");
1910             return true;
1911         }
1912     }
1913
1914     if (arrayArg && op != EOpConstructStruct) {
1915         error(loc, "constructing from a non-dereferenced array", "constructor", "");
1916         return true;
1917     }
1918
1919     if (matrixInMatrix && ! type.isArray()) {
1920         profileRequires(loc, ENoProfile, 120, 0, "constructing matrix from matrix");
1921
1922         // "If a matrix argument is given to a matrix constructor,
1923         // it is a compile-time error to have any other arguments."
1924         if (function.getParamCount() > 1)
1925             error(loc, "matrix constructed from matrix can only have one argument", "constructor", "");
1926         return false;
1927     }
1928
1929     if (overFull) {
1930         error(loc, "too many arguments", "constructor", "");
1931         return true;
1932     }
1933
1934     if (op == EOpConstructStruct && ! type.isArray() && (int)type.getStruct()->size() != function.getParamCount()) {
1935         error(loc, "Number of constructor parameters does not match the number of structure fields", "constructor", "");
1936         return true;
1937     }
1938
1939     if ((op != EOpConstructStruct && size != 1 && size < type.computeNumComponents()) ||
1940         (op == EOpConstructStruct && size < type.computeNumComponents())) {
1941         error(loc, "not enough data provided for construction", "constructor", "");
1942         return true;
1943     }
1944
1945     TIntermTyped* typed = node->getAsTyped();
1946     if (typed == 0) {
1947         error(loc, "constructor argument does not have a type", "constructor", "");
1948         return true;
1949     }
1950     if (op != EOpConstructStruct && typed->getBasicType() == EbtSampler) {
1951         error(loc, "cannot convert a sampler", "constructor", "");
1952         return true;
1953     }
1954     if (op != EOpConstructStruct && typed->getBasicType() == EbtAtomicUint) {
1955         error(loc, "cannot convert an atomic_uint", "constructor", "");
1956         return true;
1957     }
1958     if (typed->getBasicType() == EbtVoid) {
1959         error(loc, "cannot convert a void", "constructor", "");
1960         return true;
1961     }
1962
1963     return false;
1964 }
1965
1966 // Checks to see if a void variable has been declared and raise an error message for such a case
1967 //
1968 // returns true in case of an error
1969 //
1970 bool TParseContext::voidErrorCheck(TSourceLoc loc, const TString& identifier, const TBasicType basicType)
1971 {
1972     if (basicType == EbtVoid) {
1973         error(loc, "illegal use of type 'void'", identifier.c_str(), "");
1974         return true;
1975     }
1976
1977     return false;
1978 }
1979
1980 // Checks to see if the node (for the expression) contains a scalar boolean expression or not
1981 void TParseContext::boolCheck(TSourceLoc loc, const TIntermTyped* type)
1982 {
1983     if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector())
1984         error(loc, "boolean expression expected", "", "");
1985 }
1986
1987 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
1988 void TParseContext::boolCheck(TSourceLoc loc, const TPublicType& pType)
1989 {
1990     if (pType.basicType != EbtBool || pType.arraySizes || pType.matrixCols > 1 || (pType.vectorSize > 1))
1991         error(loc, "boolean expression expected", "", "");
1992 }
1993
1994 void TParseContext::samplerCheck(TSourceLoc loc, const TType& type, const TString& identifier)
1995 {
1996     if (type.getQualifier().storage == EvqUniform)
1997         return;
1998
1999     if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtSampler))
2000         error(loc, "non-uniform struct contains a sampler or image:", type.getBasicTypeString().c_str(), identifier.c_str());
2001     else if (type.getBasicType() == EbtSampler && type.getQualifier().storage != EvqUniform)
2002         error(loc, "sampler/image types can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str());
2003 }
2004
2005 void TParseContext::atomicUintCheck(TSourceLoc loc, const TType& type, const TString& identifier)
2006 {
2007     if (type.getQualifier().storage == EvqUniform)
2008         return;
2009
2010     if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtAtomicUint))
2011         error(loc, "non-uniform struct contains an atomic_uint:", type.getBasicTypeString().c_str(), identifier.c_str());
2012     else if (type.getBasicType() == EbtAtomicUint && type.getQualifier().storage != EvqUniform)
2013         error(loc, "atomic_uints can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str());
2014 }
2015
2016 //
2017 // Check/fix just a full qualifier (no variables or types yet, but qualifier is complete) at global level.
2018 //
2019 void TParseContext::globalQualifierFixCheck(TSourceLoc loc, TQualifier& qualifier)
2020 {
2021     // move from parameter/unknown qualifiers to pipeline in/out qualifiers
2022     switch (qualifier.storage) {
2023     case EvqIn:
2024         profileRequires(loc, ENoProfile, 130, 0, "in for stage inputs");
2025         profileRequires(loc, EEsProfile, 300, 0, "in for stage inputs");
2026         qualifier.storage = EvqVaryingIn;
2027         break;
2028     case EvqOut:
2029         profileRequires(loc, ENoProfile, 130, 0, "out for stage outputs");
2030         profileRequires(loc, EEsProfile, 300, 0, "out for stage outputs");
2031         qualifier.storage = EvqVaryingOut;
2032         break;
2033     case EvqInOut:
2034         qualifier.storage = EvqVaryingIn;
2035         error(loc, "cannot use 'inout' at global scope", "", "");
2036         break;
2037     default:
2038         break;
2039     }
2040
2041     invariantCheck(loc, qualifier);
2042 }
2043
2044 //
2045 // Check a full qualifier and type (no variable yet) at global level.
2046 //
2047 void TParseContext::globalQualifierTypeCheck(TSourceLoc loc, const TQualifier& qualifier, const TPublicType& publicType)
2048 {
2049     if (! symbolTable.atGlobalLevel())
2050         return;
2051
2052     if (qualifier.isMemory() && ! publicType.isImage() && publicType.qualifier.storage != EvqBuffer)
2053         error(loc, "memory qualifiers cannot be used on this type", "", "");
2054
2055     if (qualifier.storage == EvqBuffer && publicType.basicType != EbtBlock)
2056         error(loc, "buffers can be declared only as blocks", "buffer", "");
2057
2058     if (qualifier.storage != EvqVaryingIn && qualifier.storage != EvqVaryingOut)
2059         return;
2060
2061     // now, knowing it is a shader in/out, do all the in/out semantic checks
2062
2063     if (publicType.basicType == EbtBool) {
2064         error(loc, "cannot be bool", GetStorageQualifierString(qualifier.storage), "");
2065         return;
2066     }
2067
2068     if (publicType.basicType == EbtInt || publicType.basicType == EbtUint || publicType.basicType == EbtDouble) {
2069         profileRequires(loc, EEsProfile, 300, 0, "shader input/output");
2070         if (! qualifier.flat) {
2071             if (qualifier.storage == EvqVaryingIn && language == EShLangFragment)
2072                 error(loc, "must be qualified as flat", TType::getBasicString(publicType.basicType), GetStorageQualifierString(qualifier.storage));
2073             else if (qualifier.storage == EvqVaryingOut && language == EShLangVertex && version == 300)
2074                 error(loc, "must be qualified as flat", TType::getBasicString(publicType.basicType), GetStorageQualifierString(qualifier.storage));
2075         }
2076     }
2077
2078     if (qualifier.patch && qualifier.isInterpolation())
2079         error(loc, "cannot use interpolation qualifiers with patch", "patch", "");
2080
2081     if (qualifier.storage == EvqVaryingIn) {
2082         switch (language) {
2083         case EShLangVertex:
2084             if (publicType.basicType == EbtStruct) {
2085                 error(loc, "cannot be a structure or array", GetStorageQualifierString(qualifier.storage), "");
2086                 return;
2087             }
2088             if (publicType.arraySizes) {
2089                 requireProfile(loc, ~EEsProfile, "vertex input arrays");
2090                 profileRequires(loc, ENoProfile, 150, 0, "vertex input arrays");
2091             }
2092             if (qualifier.isAuxiliary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.invariant)
2093                 error(loc, "vertex input cannot be further qualified", "", "");
2094             break;
2095
2096         case EShLangTessControl:
2097             if (qualifier.patch)
2098                 error(loc, "can only use on output in tessellation-control shader", "patch", "");
2099             break;
2100
2101         case EShLangTessEvaluation:
2102             break;
2103
2104         case EShLangGeometry:
2105             break;
2106
2107         case EShLangFragment:
2108             if (publicType.userDef) {
2109                 profileRequires(loc, EEsProfile, 300, 0, "fragment-shader struct input");
2110                 profileRequires(loc, ~EEsProfile, 150, 0, "fragment-shader struct input");
2111                 if (publicType.userDef->containsStructure())
2112                     requireProfile(loc, ~EEsProfile, "fragment-shader struct input containing structure");
2113                 if (publicType.userDef->containsArray())
2114                     requireProfile(loc, ~EEsProfile, "fragment-shader struct input containing an array");
2115             }
2116             break;
2117
2118         case EShLangCompute:
2119             if (! symbolTable.atBuiltInLevel())
2120                 error(loc, "global storage input qualifier cannot be used in a compute shader", "in", "");
2121             break;
2122
2123         default:
2124             break;
2125         }
2126     } else {
2127         // qualifier.storage == EvqVaryingOut
2128         switch (language) {
2129         case EShLangVertex:
2130             if (publicType.userDef) {
2131                 profileRequires(loc, EEsProfile, 300, 0, "vertex-shader struct output");
2132                 profileRequires(loc, ~EEsProfile, 150, 0, "vertex-shader struct output");
2133                 if (publicType.userDef->containsStructure())
2134                     requireProfile(loc, ~EEsProfile, "vertex-shader struct output containing structure");
2135                 if (publicType.userDef->containsArray())
2136                     requireProfile(loc, ~EEsProfile, "vertex-shader struct output containing an array");
2137             }
2138
2139             break;
2140
2141         case EShLangTessControl:
2142             break;
2143
2144         case EShLangTessEvaluation:
2145             if (qualifier.patch)
2146                 error(loc, "can only use on input in tessellation-evaluation shader", "patch", "");
2147             break;
2148
2149         case EShLangGeometry:
2150             break;
2151
2152         case EShLangFragment:
2153             profileRequires(loc, EEsProfile, 300, 0, "fragment shader output");
2154             if (publicType.basicType == EbtStruct) {
2155                 error(loc, "cannot be a structure", GetStorageQualifierString(qualifier.storage), "");
2156                 return;
2157             }
2158             if (publicType.matrixRows > 0) {
2159                 error(loc, "cannot be a matrix", GetStorageQualifierString(qualifier.storage), "");
2160                 return;
2161             }
2162         break;
2163
2164         case EShLangCompute:
2165             error(loc, "global storage output qualifier cannot be used in a compute shader", "out", "");
2166             break;
2167
2168         default:
2169             break;
2170         }
2171     }
2172 }
2173
2174 //
2175 // Merge characteristics of the 'src' qualifier into the 'dst'.
2176 // If there is duplication, issue error messages, unless 'force'
2177 // is specified, which means to just override default settings.
2178 //
2179 // Also, when force is false, it will be assumed that 'src' follows
2180 // 'dst', for the purpose of error checking order for versions
2181 // that require specific orderings of qualifiers.
2182 //
2183 void TParseContext::mergeQualifiers(TSourceLoc loc, TQualifier& dst, const TQualifier& src, bool force)
2184 {
2185     // Multiple auxiliary qualifiers (mostly done later by 'individual qualifiers')
2186     if (src.isAuxiliary() && dst.isAuxiliary())
2187         error(loc, "can only have one auxiliary qualifier (centroid, patch, and sample)", "", "");
2188
2189     // Multiple interpolation qualifiers (mostly done later by 'individual qualifiers')
2190     if (src.isInterpolation() && dst.isInterpolation())
2191         error(loc, "can only have one interpolation qualifier (flat, smooth, noperspective)", "", "");
2192
2193     // Ordering
2194     if (! force && ((profile != EEsProfile && version < 420) || 
2195                      profile == EEsProfile && version < 310)
2196                 && ! extensionsTurnedOn(1, &GL_ARB_shading_language_420pack)) {
2197         // non-function parameters
2198         if (src.invariant && (dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone))
2199             error(loc, "invariant qualifier must appear first", "", "");
2200         else if (src.isInterpolation() && (dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone))
2201             error(loc, "interpolation qualifiers must appear before storage and precision qualifiers", "", "");
2202         else if (src.isAuxiliary() && (dst.storage != EvqTemporary || dst.precision != EpqNone))
2203             error(loc, "Auxiliary qualifiers (centroid, patch, and sample) must appear before storage and precision qualifiers", "", "");
2204         else if (src.storage != EvqTemporary && (dst.precision != EpqNone))
2205             error(loc, "precision qualifier must appear as last qualifier", "", "");
2206
2207         // function parameters
2208         if (src.storage == EvqConst && (dst.storage == EvqIn || dst.storage == EvqOut))
2209             error(loc, "in/out must appear before const", "", "");
2210     }
2211
2212     // Storage qualification
2213     if (dst.storage == EvqTemporary || dst.storage == EvqGlobal)
2214         dst.storage = src.storage;
2215     else if ((dst.storage == EvqIn  && src.storage == EvqOut) ||
2216              (dst.storage == EvqOut && src.storage == EvqIn))
2217         dst.storage = EvqInOut;
2218     else if ((dst.storage == EvqIn    && src.storage == EvqConst) ||
2219              (dst.storage == EvqConst && src.storage == EvqIn))
2220         dst.storage = EvqConstReadOnly;
2221     else if (src.storage != EvqTemporary &&
2222              src.storage != EvqGlobal)
2223         error(loc, "too many storage qualifiers", GetStorageQualifierString(src.storage), "");
2224
2225     // Precision qualifiers
2226     if (! force && src.precision != EpqNone && dst.precision != EpqNone)
2227         error(loc, "only one precision qualifier allowed", GetPrecisionQualifierString(src.precision), "");
2228     if (dst.precision == EpqNone || (force && src.precision != EpqNone))
2229         dst.precision = src.precision;
2230
2231     // Layout qualifiers
2232     mergeObjectLayoutQualifiers(dst, src, false);
2233
2234     // individual qualifiers
2235     bool repeated = false;
2236     #define MERGE_SINGLETON(field) repeated |= dst.field && src.field; dst.field |= src.field;
2237     MERGE_SINGLETON(invariant);
2238     MERGE_SINGLETON(centroid);
2239     MERGE_SINGLETON(smooth);
2240     MERGE_SINGLETON(flat);
2241     MERGE_SINGLETON(nopersp);
2242     MERGE_SINGLETON(patch);
2243     MERGE_SINGLETON(sample);
2244     MERGE_SINGLETON(coherent);
2245     MERGE_SINGLETON(volatil);
2246     MERGE_SINGLETON(restrict);
2247     MERGE_SINGLETON(readonly);
2248     MERGE_SINGLETON(writeonly);
2249
2250     if (repeated)
2251         error(loc, "replicated qualifiers", "", "");
2252 }
2253
2254 void TParseContext::setDefaultPrecision(TSourceLoc loc, TPublicType& publicType, TPrecisionQualifier qualifier)
2255 {
2256     TBasicType basicType = publicType.basicType;
2257
2258     if (basicType == EbtSampler) {
2259         defaultSamplerPrecision[computeSamplerTypeIndex(publicType.sampler)] = qualifier;
2260
2261         return;  // all is well
2262     }
2263
2264     if (basicType == EbtInt || basicType == EbtFloat) {
2265         if (publicType.isScalar()) {
2266             defaultPrecision[basicType] = qualifier;
2267             if (basicType == EbtInt)
2268                 defaultPrecision[EbtUint] = qualifier;
2269
2270             return;  // all is well
2271         }
2272     }
2273
2274     if (basicType == EbtAtomicUint) {
2275         if (qualifier != EpqHigh)
2276             error(loc, "can only apply highp to atomic_uint", "precision", "");
2277
2278         return;
2279     }
2280
2281     error(loc, "cannot apply precision statement to this type; use 'float', 'int' or a sampler type", TType::getBasicString(basicType), "");
2282 }
2283
2284 // used to flatten the sampler type space into a single dimension
2285 // correlates with the declaration of defaultSamplerPrecision[]
2286 int TParseContext::computeSamplerTypeIndex(TSampler& sampler)
2287 {
2288     int arrayIndex   = sampler.arrayed   ? 1 : 0;
2289     int shadowIndex   = sampler.shadow   ? 1 : 0;
2290     int externalIndex = sampler.external ? 1 : 0;
2291
2292     return EsdNumDims * (EbtNumTypes * (2 * (2 * arrayIndex + shadowIndex) + externalIndex) + sampler.type) + sampler.dim;
2293 }
2294
2295 TPrecisionQualifier TParseContext::getDefaultPrecision(TPublicType& publicType)
2296 {
2297     if (publicType.basicType == EbtSampler)
2298         return defaultSamplerPrecision[computeSamplerTypeIndex(publicType.sampler)];
2299     else
2300         return defaultPrecision[publicType.basicType];
2301 }
2302
2303 void TParseContext::precisionQualifierCheck(TSourceLoc loc, TBasicType baseType, TQualifier& qualifier)
2304 {
2305     // Built-in symbols are allowed some ambiguous precisions, to be pinned down
2306     // later by context.
2307     if (profile != EEsProfile || parsingBuiltins)
2308         return;
2309
2310     if (baseType == EbtAtomicUint && qualifier.precision != EpqNone && qualifier.precision != EpqHigh)
2311         error(loc, "atomic counters can only be highp", "atomic_uint", "");
2312
2313     if (baseType == EbtFloat || baseType == EbtUint || baseType == EbtInt || baseType == EbtSampler || baseType == EbtAtomicUint) {
2314         if (qualifier.precision == EpqNone) {
2315             if (messages & EShMsgRelaxedErrors)
2316                 warn(loc, "type requires declaration of default precision qualifier", TType::getBasicString(baseType), "substituting 'mediump'");
2317             else
2318                 error(loc, "type requires declaration of default precision qualifier", TType::getBasicString(baseType), "");
2319             qualifier.precision = EpqMedium;
2320             defaultPrecision[baseType] = EpqMedium;
2321         }
2322     } else if (qualifier.precision != EpqNone)
2323         error(loc, "type cannot have precision qualifier", TType::getBasicString(baseType), "");
2324 }
2325
2326 void TParseContext::parameterTypeCheck(TSourceLoc loc, TStorageQualifier qualifier, const TType& type)
2327 {
2328     if ((qualifier == EvqOut || qualifier == EvqInOut) && (type.getBasicType() == EbtSampler || type.getBasicType() == EbtAtomicUint))
2329         error(loc, "samplers and atomic_uints cannot be output parameters", type.getBasicTypeString().c_str(), "");
2330 }
2331
2332 bool TParseContext::containsFieldWithBasicType(const TType& type, TBasicType basicType)
2333 {
2334     if (type.getBasicType() == basicType)
2335         return true;
2336
2337     if (type.getBasicType() == EbtStruct) {
2338         const TTypeList& structure = *type.getStruct();
2339         for (unsigned int i = 0; i < structure.size(); ++i) {
2340             if (containsFieldWithBasicType(*structure[i].type, basicType))
2341                 return true;
2342         }
2343     }
2344
2345     return false;
2346 }
2347
2348 //
2349 // Do size checking for an array type's size.
2350 //
2351 void TParseContext::arraySizeCheck(TSourceLoc loc, TIntermTyped* expr, int& size)
2352 {
2353     TIntermConstantUnion* constant = expr->getAsConstantUnion();
2354     if (constant == 0 || (constant->getBasicType() != EbtInt && constant->getBasicType() != EbtUint)) {
2355         error(loc, "array size must be a constant integer expression", "", "");
2356         size = 1;
2357
2358         return;
2359     }
2360
2361     size = constant->getConstArray()[0].getIConst();
2362
2363     if (size <= 0) {
2364         error(loc, "array size must be a positive integer", "", "");
2365         size = 1;
2366
2367         return;
2368     }
2369 }
2370
2371 //
2372 // See if this qualifier can be an array.
2373 //
2374 // Returns true if there is an error.
2375 //
2376 bool TParseContext::arrayQualifierError(TSourceLoc loc, const TQualifier& qualifier)
2377 {
2378     if (qualifier.storage == EvqConst) {
2379         profileRequires(loc, ENoProfile, 120, GL_3DL_array_objects, "const array");
2380         profileRequires(loc, EEsProfile, 300, 0, "const array");
2381     }
2382
2383     if (qualifier.storage == EvqVaryingIn && language == EShLangVertex) {
2384         requireProfile(loc, ~EEsProfile, "vertex input arrays");
2385         profileRequires(loc, ENoProfile, 150, 0, "vertex input arrays");
2386     }
2387
2388     return false;
2389 }
2390
2391 //
2392 // See if this qualifier and type combination can be an array.
2393 // Assumes arrayQualifierError() was also called to catch the type-invariant tests.
2394 //
2395 // Returns true if there is an error.
2396 //
2397 bool TParseContext::arrayError(TSourceLoc loc, const TType& type)
2398 {
2399     if (type.getQualifier().storage == EvqVaryingOut && language == EShLangVertex) {
2400         if (type.isArrayOfArrays())
2401             requireProfile(loc, ~EEsProfile, "vertex-shader array-of-array output");
2402         else if (type.getArraySize() && type.isStruct())
2403             requireProfile(loc, ~EEsProfile, "vertex-shader array-of-struct output");
2404     }
2405     if (type.getQualifier().storage == EvqVaryingIn && language == EShLangFragment) {
2406         if (type.isArrayOfArrays())
2407             requireProfile(loc, ~EEsProfile, "fragment-shader array-of-array input");
2408         else if (type.getArraySize() && type.isStruct())
2409             requireProfile(loc, ~EEsProfile, "fragment-shader array-of-struct input");
2410     }
2411
2412     return false;
2413 }
2414
2415 //
2416 // Require array to have size
2417 //
2418 void TParseContext::arraySizeRequiredCheck(TSourceLoc loc, int size)
2419 {
2420     if (size == 0) {
2421         error(loc, "array size required", "", "");
2422         size = 1;
2423     }
2424 }
2425
2426 void TParseContext::structArrayCheck(TSourceLoc /*loc*/, TType* type)
2427 {
2428     const TTypeList& structure = *type->getStruct();
2429     for (int m = 0; m < (int)structure.size(); ++m) {
2430         const TType& member = *structure[m].type;
2431         if (member.isArray() && ! member.isExplicitlySizedArray())
2432             arraySizeRequiredCheck(structure[m].loc, 0);
2433     }
2434 }
2435
2436 void TParseContext::arrayDimError(TSourceLoc loc)
2437 {
2438     requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "arrays of arrays");
2439     profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, 0, "arrays of arrays");
2440     profileRequires(loc, EEsProfile, 310, 0, "arrays of arrays");
2441 }
2442
2443 void TParseContext::arrayDimCheck(TSourceLoc loc, TArraySizes* sizes1, TArraySizes* sizes2)
2444 {
2445     if ((sizes1 && sizes2) ||
2446         (sizes1 && sizes1->isArrayOfArrays()) ||
2447         (sizes2 && sizes2->isArrayOfArrays()))
2448         arrayDimError(loc);
2449 }
2450
2451 void TParseContext::arrayDimCheck(TSourceLoc loc, const TType* type, TArraySizes* sizes2)
2452 {
2453     if ((type && type->isArray() && sizes2) ||
2454         (sizes2 && sizes2->isArrayOfArrays()))
2455         arrayDimError(loc);
2456 }
2457
2458 //
2459 // Do all the semantic checking for declaring or redeclaring an array, with and
2460 // without a size, and make the right changes to the symbol table.
2461 //
2462 // size == 0 means no specified size.
2463 //
2464 void TParseContext::declareArray(TSourceLoc loc, TString& identifier, const TType& type, TSymbol*& symbol, bool& newDeclaration)
2465 {
2466     if (! symbol) {
2467         bool currentScope;
2468         symbol = symbolTable.find(identifier, 0, &currentScope);
2469
2470         if (symbol && builtInName(identifier) && ! symbolTable.atBuiltInLevel()) {
2471             // bad shader (errors already reported) trying to redeclare a built-in name as an array
2472             return;
2473         }
2474         if (symbol == 0 || ! currentScope) {
2475             //
2476             // Successfully process a new definition.
2477             // (Redeclarations have to take place at the same scope; otherwise they are hiding declarations)
2478             //
2479             symbol = new TVariable(&identifier, type);
2480             symbolTable.insert(*symbol);
2481             newDeclaration = true;
2482
2483             if (! symbolTable.atBuiltInLevel()) {
2484                 if (isIoResizeArray(type)) {
2485                     ioArraySymbolResizeList.push_back(symbol);
2486                     checkIoArraysConsistency(loc, true);
2487                 } else
2488                     fixIoArraySize(loc, symbol->getWritableType());
2489             }
2490
2491             return;
2492         }
2493         if (symbol->getAsAnonMember()) {
2494             error(loc, "cannot redeclare a user-block member array", identifier.c_str(), "");
2495             symbol = 0;
2496             return;
2497         }
2498     }
2499
2500     //
2501     // Process a redeclaration.
2502     //
2503
2504     if (! symbol) {
2505         error(loc, "array variable name expected", identifier.c_str(), "");
2506         return;
2507     }
2508
2509     // redeclareBuiltinVariable() should have already done the copyUp()
2510     TType& existingType = symbol->getWritableType();
2511
2512     if (! existingType.isArray()) {
2513         error(loc, "redeclaring non-array as array", identifier.c_str(), "");
2514         return;
2515     }
2516     if (existingType.isExplicitlySizedArray()) {
2517         // be more leniant for input arrays to geometry shaders and tessellation control outputs, where the redeclaration is the same size
2518         if (! (isIoResizeArray(type) && existingType.getArraySize() == type.getArraySize()))
2519             error(loc, "redeclaration of array with size", identifier.c_str(), "");
2520         return;
2521     }
2522
2523     if (! existingType.sameElementType(type)) {
2524         error(loc, "redeclaration of array with a different type", identifier.c_str(), "");
2525         return;
2526     }
2527
2528     arrayLimitCheck(loc, identifier, type.getArraySize());
2529
2530     existingType.updateArraySizes(type);
2531
2532     if (isIoResizeArray(type))
2533         checkIoArraysConsistency(loc);
2534 }
2535
2536 void TParseContext::updateImplicitArraySize(TSourceLoc loc, TIntermNode *node, int index)
2537 {
2538     // maybe there is nothing to do...
2539     TIntermTyped* typedNode = node->getAsTyped();
2540     if (typedNode->getType().getImplicitArraySize() > index)
2541         return;
2542
2543     // something to do...
2544
2545     // Figure out what symbol to lookup, as we will use its type to edit for the size change,
2546     // as that type will be shared through shallow copies for future references.
2547     TSymbol* symbol = 0;
2548     int blockIndex = -1;
2549     const TString* lookupName = 0;
2550     if (node->getAsSymbolNode())
2551         lookupName = &node->getAsSymbolNode()->getName();
2552     else if (node->getAsBinaryNode()) {
2553         const TIntermBinary* deref = node->getAsBinaryNode();
2554         // This has to be the result of a block dereference, unless it's bad shader code
2555         // If it's a uniform block, then an error will be issued elsewhere, but
2556         // return early now to avoid crashing later in this function.
2557         if (! deref->getLeft()->getAsSymbolNode() || deref->getLeft()->getBasicType() != EbtBlock ||
2558             deref->getLeft()->getType().getQualifier().storage == EvqUniform ||
2559             deref->getRight()->getAsConstantUnion() == 0)
2560             return;
2561
2562         blockIndex = deref->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
2563
2564         lookupName = &deref->getLeft()->getAsSymbolNode()->getName();
2565         if (IsAnonymous(*lookupName))
2566             lookupName = &(*deref->getLeft()->getType().getStruct())[blockIndex].type->getFieldName();
2567     }
2568
2569     // Lookup the symbol, should only fail if shader code is incorrect
2570     symbol = symbolTable.find(*lookupName);
2571     if (symbol == 0)
2572         return;
2573
2574     if (symbol->getAsFunction()) {
2575         error(loc, "array variable name expected", symbol->getName().c_str(), "");
2576         return;
2577     }
2578
2579     symbol->getWritableType().setImplicitArraySize(index + 1);
2580 }
2581
2582 //
2583 // Enforce non-initializer type/qualifier rules.
2584 //
2585 void TParseContext::nonInitConstCheck(TSourceLoc loc, TString& identifier, TType& type)
2586 {
2587     //
2588     // Make the qualifier make sense, given that there is an initializer.
2589     //
2590     if (type.getQualifier().storage == EvqConst ||
2591         type.getQualifier().storage == EvqConstReadOnly) {
2592         type.getQualifier().storage = EvqTemporary;
2593         error(loc, "variables with qualifier 'const' must be initialized", identifier.c_str(), "");
2594     }
2595 }
2596
2597 //
2598 // See if the identifier is a built-in symbol that can be redeclared, and if so,
2599 // copy the symbol table's read-only built-in variable to the current
2600 // global level, where it can be modified based on the passed in type.
2601 //
2602 // Returns 0 if no redeclaration took place; meaning a normal declaration still
2603 // needs to occur for it, not necessarily an error.
2604 //
2605 // Returns a redeclared and type-modified variable if a redeclarated occurred.
2606 //
2607 TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString& identifier, const TQualifier& qualifier, const TShaderQualifiers& publicType, bool& newDeclaration)
2608 {
2609     if (profile == EEsProfile || ! builtInName(identifier) || symbolTable.atBuiltInLevel() || ! symbolTable.atGlobalLevel())
2610         return 0;
2611
2612     // Special case when using GL_ARB_separate_shader_objects
2613     bool ssoPre150 = false;  // means the only reason this variable is redeclared is due to this combination
2614     if (version <= 140 && extensionsTurnedOn(1, &GL_ARB_separate_shader_objects)) {
2615         if (identifier == "gl_Position"     ||
2616             identifier == "gl_PointSize"    ||
2617             identifier == "gl_ClipVertex"   ||
2618             identifier == "gl_FogFragCoord")
2619             ssoPre150 = true;
2620     }
2621
2622     // Potentially redeclaring a built-in variable...
2623
2624     if (ssoPre150 ||
2625         (identifier == "gl_FragDepth"           && version >= 420) ||
2626         (identifier == "gl_FragCoord"           && version >= 150) ||
2627         (identifier == "gl_ClipDistance"        && version >= 130) ||
2628         (identifier == "gl_FrontColor"          && version >= 130) ||
2629         (identifier == "gl_BackColor"           && version >= 130) ||
2630         (identifier == "gl_FrontSecondaryColor" && version >= 130) ||
2631         (identifier == "gl_BackSecondaryColor"  && version >= 130) ||
2632         (identifier == "gl_SecondaryColor"      && version >= 130) ||
2633         (identifier == "gl_Color"               && version >= 130 && language == EShLangFragment) ||
2634          identifier == "gl_TexCoord") {
2635
2636         // Find the existing symbol, if any.
2637         bool builtIn;
2638         TSymbol* symbol = symbolTable.find(identifier, &builtIn);
2639
2640         // If the symbol was not found, this must be a version/profile/stage
2641         // that doesn't have it.
2642         if (! symbol)
2643             return 0;
2644
2645         // If it wasn't at a built-in level, then it's already been redeclared;
2646         // that is, this is a redeclaration of a redeclaration; reuse that initial
2647         // redeclaration.  Otherwise, make the new one.
2648         if (builtIn) {
2649             // Copy the symbol up to make a writable version
2650             makeEditable(symbol);
2651             newDeclaration = true;
2652         }
2653
2654         // Now, modify the type of the copy, as per the type of the current redeclaration.
2655
2656         TQualifier& symbolQualifier = symbol->getWritableType().getQualifier();
2657         if (ssoPre150) {            
2658             if (intermediate.inIoAccessed(identifier))
2659                 error(loc, "cannot redeclare after use", identifier.c_str(), "");
2660             if (qualifier.hasLayout())
2661                 error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str());
2662             if (qualifier.isMemory() || qualifier.isAuxiliary() || (language == EShLangVertex   && qualifier.storage != EvqVaryingOut) ||
2663                                                                    (language == EShLangFragment && qualifier.storage != EvqVaryingIn))
2664                 error(loc, "cannot change storage, memory, or auxiliary qualification of", "redeclaration", symbol->getName().c_str());
2665             if (! qualifier.smooth)
2666                 error(loc, "cannot change interpolation qualification of", "redeclaration", symbol->getName().c_str());
2667         } else if (identifier == "gl_FrontColor"          ||
2668                    identifier == "gl_BackColor"           ||
2669                    identifier == "gl_FrontSecondaryColor" ||
2670                    identifier == "gl_BackSecondaryColor"  ||
2671                    identifier == "gl_SecondaryColor"      ||
2672                    identifier == "gl_Color") {
2673             symbolQualifier.flat = qualifier.flat;
2674             symbolQualifier.smooth = qualifier.smooth;
2675             symbolQualifier.nopersp = qualifier.nopersp;
2676             if (qualifier.hasLayout())
2677                 error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str());
2678             if (qualifier.isMemory() || qualifier.isAuxiliary() || symbol->getType().getQualifier().storage != qualifier.storage)
2679                 error(loc, "cannot change storage, memory, or auxiliary qualification of", "redeclaration", symbol->getName().c_str());
2680         } else if (identifier == "gl_TexCoord" ||
2681                    identifier == "gl_ClipDistance") {
2682             if (qualifier.hasLayout() || qualifier.isMemory() || qualifier.isAuxiliary() ||
2683                 qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
2684                 symbolQualifier.storage != qualifier.storage)
2685                 error(loc, "cannot change qualification of", "redeclaration", symbol->getName().c_str());
2686         } else if (identifier == "gl_FragCoord") {
2687             if (intermediate.inIoAccessed("gl_FragCoord"))
2688                 error(loc, "cannot redeclare after use", "gl_FragCoord", "");
2689             if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
2690                 qualifier.isMemory() || qualifier.isAuxiliary())
2691                 error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str());
2692             if (identifier == "gl_FragCoord" && qualifier.storage != EvqVaryingIn)
2693                 error(loc, "cannot change input storage qualification of", "redeclaration", symbol->getName().c_str());
2694             if (! builtIn && (publicType.pixelCenterInteger != intermediate.getPixelCenterInteger() || 
2695                               publicType.originUpperLeft != intermediate.getOriginUpperLeft()))
2696                 error(loc, "cannot redeclare with different qualification:", "redeclaration", symbol->getName().c_str());
2697             if (publicType.pixelCenterInteger)
2698                 intermediate.setPixelCenterInteger();
2699             if (publicType.originUpperLeft)
2700                 intermediate.setOriginUpperLeft();
2701         } else if (identifier == "gl_FragDepth") {
2702             if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
2703                 qualifier.isMemory() || qualifier.isAuxiliary())
2704                 error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str());
2705             if (qualifier.storage != EvqVaryingOut)
2706                 error(loc, "cannot change output storage qualification of", "redeclaration", symbol->getName().c_str());
2707             if (publicType.layoutDepth != EldNone) {
2708                 if (intermediate.inIoAccessed("gl_FragDepth"))
2709                     error(loc, "cannot redeclare after use", "gl_FragDepth", "");
2710                 if (! intermediate.setDepth(publicType.layoutDepth))
2711                     error(loc, "all redeclarations must use the same depth layout on", "redeclaration", symbol->getName().c_str());
2712             }
2713
2714         }
2715         // TODO: semantics quality: separate smooth from nothing declared, then use IsInterpolation for several tests above
2716
2717         return symbol;
2718     }
2719
2720     return 0;
2721 }
2722
2723 //
2724 // Either redeclare the requested block, or give an error message why it can't be done.
2725 //
2726 // TODO: functionality: explicitly sizing members of redeclared blocks is not giving them an explicit size
2727 void TParseContext::redeclareBuiltinBlock(TSourceLoc loc, TTypeList& newTypeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes)
2728 {
2729     const char* feature = "built-in block redeclaration";
2730     requireProfile(loc, ~EEsProfile, feature);
2731     profileRequires(loc, ~EEsProfile, 410, GL_ARB_separate_shader_objects, feature);
2732
2733     if (blockName != "gl_PerVertex" && blockName != "gl_PerFragment") {
2734         error(loc, "cannot redeclare block: ", "block declaration", blockName.c_str());
2735         return;
2736     }
2737
2738     // Redeclaring a built-in block...
2739
2740     if (instanceName && ! builtInName(*instanceName)) {
2741         error(loc, "cannot redeclare a built-in block with a user name", instanceName->c_str(), "");
2742         return;
2743     }
2744
2745     // Blocks with instance names are easy to find, lookup the instance name,
2746     // Anonymous blocks need to be found via a member.
2747     bool builtIn;
2748     TSymbol* block;
2749     if (instanceName)
2750         block = symbolTable.find(*instanceName, &builtIn);
2751     else
2752         block = symbolTable.find(newTypeList.front().type->getFieldName(), &builtIn);
2753
2754     // If the block was not found, this must be a version/profile/stage
2755     // that doesn't have it, or the instance name is wrong.
2756     const char* errorName = instanceName ? instanceName->c_str() : newTypeList.front().type->getFieldName().c_str();
2757     if (! block) {
2758         error(loc, "no declaration found for redeclaration", errorName, "");
2759         return;
2760     }
2761     // Built-in blocks cannot be redeclared more than once, which if happened,
2762     // we'd be finding the already redeclared one here, rather than the built in.
2763     if (! builtIn) {
2764         error(loc, "can only redeclare a built-in block once, and before any use", blockName.c_str(), "");
2765         return;
2766     }
2767
2768     // Copy the block to make a writable version, to insert into the block table after editing.
2769     block = symbolTable.copyUpDeferredInsert(block);
2770
2771     if (block->getType().getBasicType() != EbtBlock) {
2772         error(loc, "cannot redeclare a non block as a block", errorName, "");
2773         return;
2774     }
2775
2776     // Edit and error check the container against the redeclaration
2777     //  - remove unused members
2778     //  - ensure remaining qualifiers/types match
2779     TType& type = block->getWritableType();
2780     TTypeList::iterator member = type.getWritableStruct()->begin();
2781     size_t numOriginalMembersFound = 0;
2782     while (member != type.getStruct()->end()) {
2783         // look for match
2784         bool found = false;
2785         TTypeList::const_iterator newMember;
2786         TSourceLoc memberLoc = {};
2787         for (newMember = newTypeList.begin(); newMember != newTypeList.end(); ++newMember) {
2788             if (member->type->getFieldName() == newMember->type->getFieldName()) {
2789                 found = true;
2790                 memberLoc = newMember->loc;
2791                 break;
2792             }
2793         }
2794
2795         if (found) {
2796             ++numOriginalMembersFound;
2797             // - ensure match between redeclared members' types
2798             // - check for things that can't be changed
2799             // - update things that can be changed
2800             TType& oldType = *member->type;
2801             const TType& newType = *newMember->type;
2802             if (! newType.sameElementType(oldType))
2803                 error(memberLoc, "cannot redeclare block member with a different type", member->type->getFieldName().c_str(), "");
2804             if (oldType.isArray() != newType.isArray())
2805                 error(memberLoc, "cannot change arrayness of redeclared block member", member->type->getFieldName().c_str(), "");
2806             else if (! oldType.sameArrayness(newType) && oldType.isExplicitlySizedArray())
2807                 error(memberLoc, "cannot change array size of redeclared block member", member->type->getFieldName().c_str(), "");
2808             else if (newType.isArray())
2809                 arrayLimitCheck(loc, member->type->getFieldName(), newType.getArraySize());
2810             if (newType.getQualifier().isMemory())
2811                 error(memberLoc, "cannot add memory qualifier to redeclared block member", member->type->getFieldName().c_str(), "");
2812             if (newType.getQualifier().hasLayout())
2813                 error(memberLoc, "cannot add layout to redeclared block member", member->type->getFieldName().c_str(), "");
2814             if (newType.getQualifier().patch)
2815                 error(memberLoc, "cannot add patch to redeclared block member", member->type->getFieldName().c_str(), "");
2816             oldType.getQualifier().centroid = newType.getQualifier().centroid;
2817             oldType.getQualifier().sample = newType.getQualifier().sample;
2818             oldType.getQualifier().invariant = newType.getQualifier().invariant;
2819             oldType.getQualifier().smooth = newType.getQualifier().smooth;
2820             oldType.getQualifier().flat = newType.getQualifier().flat;
2821             oldType.getQualifier().nopersp = newType.getQualifier().nopersp;
2822
2823             // go to next member
2824             ++member;
2825         } else {    
2826             // For missing members of anonymous blocks that have been redeclared,
2827             // hide the original (shared) declaration.
2828             // Instance-named blocks can just have the member removed.
2829             if (instanceName)
2830                 member = type.getWritableStruct()->erase(member);
2831             else {
2832                 member->type->hideMember();
2833                 ++member;
2834             }
2835         }
2836     }
2837
2838     if (numOriginalMembersFound < newTypeList.size())
2839         error(loc, "block redeclaration has extra members", blockName.c_str(), "");
2840     if (type.isArray() != (arraySizes != 0))
2841         error(loc, "cannot change arrayness of redeclared block", blockName.c_str(), "");
2842     else if (type.isArray()) {
2843         if (type.isExplicitlySizedArray() && arraySizes->getSize() == 0)
2844             error(loc, "block already declared with size, can't redeclare as implicitly-sized", blockName.c_str(), "");
2845         else if (type.isExplicitlySizedArray() && type.getArraySize() != arraySizes->getSize())
2846             error(loc, "cannot change array size of redeclared block", blockName.c_str(), "");
2847         else if (type.isImplicitlySizedArray() && arraySizes->getSize() > 0)
2848             type.changeArraySize(arraySizes->getSize());
2849     }
2850
2851     symbolTable.insert(*block);
2852
2853     // Check for general layout qualifier errors
2854     layoutObjectCheck(loc, *block);
2855
2856     // Tracking for implicit sizing of array
2857     if (isIoResizeArray(block->getType())) {
2858         ioArraySymbolResizeList.push_back(block);
2859         checkIoArraysConsistency(loc, true);
2860     } else if (block->getType().isArray())
2861         fixIoArraySize(loc, block->getWritableType());
2862
2863     // Save it in the AST for linker use.
2864     intermediate.addSymbolLinkageNode(linkage, *block);
2865 }
2866
2867 void TParseContext::paramCheckFix(TSourceLoc loc, const TStorageQualifier& qualifier, TType& type)
2868 {
2869     switch (qualifier) {
2870     case EvqConst:
2871     case EvqConstReadOnly:
2872         type.getQualifier().storage = EvqConstReadOnly;
2873         break;
2874     case EvqIn:
2875     case EvqOut:
2876     case EvqInOut:
2877         type.getQualifier().storage = qualifier;
2878         break;
2879     case EvqGlobal:
2880     case EvqTemporary:
2881         type.getQualifier().storage = EvqIn;
2882         break;
2883     default:
2884         type.getQualifier().storage = EvqIn;
2885         error(loc, "storage qualifier not allowed on function parameter", GetStorageQualifierString(qualifier), "");
2886         break;
2887     }
2888 }
2889
2890 void TParseContext::paramCheckFix(TSourceLoc loc, const TQualifier& qualifier, TType& type)
2891 {
2892     if (qualifier.isMemory()) {
2893         type.getQualifier().volatil   = qualifier.volatil;
2894         type.getQualifier().coherent  = qualifier.coherent;
2895         type.getQualifier().readonly  = qualifier.readonly;
2896         type.getQualifier().writeonly = qualifier.writeonly;
2897         type.getQualifier().restrict  = qualifier.restrict;
2898     }
2899     if (qualifier.isAuxiliary() ||
2900         qualifier.isInterpolation())
2901         error(loc, "cannot use auxiliary or interpolation qualifiers on a function parameter", "", "");
2902     if (qualifier.hasLayout())
2903         error(loc, "cannot use layout qualifiers on a function parameter", "", "");
2904     if (qualifier.invariant)
2905         error(loc, "cannot use invariant qualifier on a function parameter", "", "");    
2906
2907     paramCheckFix(loc, qualifier.storage, type);
2908 }
2909
2910 void TParseContext::nestedBlockCheck(TSourceLoc loc)
2911 {
2912     if (structNestingLevel > 0)
2913         error(loc, "cannot nest a block definition inside a structure or block", "", "");
2914     ++structNestingLevel;
2915 }
2916
2917 void TParseContext::nestedStructCheck(TSourceLoc loc)
2918 {
2919     if (structNestingLevel > 0)
2920         error(loc, "cannot nest a structure definition inside a structure or block", "", "");
2921     ++structNestingLevel;
2922 }
2923
2924 void TParseContext::arrayObjectCheck(TSourceLoc loc, const TType& type, const char* op)
2925 {
2926     // Some versions don't allow comparing arrays or structures containing arrays
2927     if (type.containsArray()) {
2928         profileRequires(loc, ENoProfile, 120, GL_3DL_array_objects, op);
2929         profileRequires(loc, EEsProfile, 300, 0, op);
2930     }
2931 }
2932
2933 void TParseContext::opaqueCheck(TSourceLoc loc, const TType& type, const char* op)
2934 {
2935     if (containsFieldWithBasicType(type, EbtSampler))
2936         error(loc, "can't use with samplers or structs containing samplers", op, "");
2937 }
2938
2939 void TParseContext::structTypeCheck(TSourceLoc /*loc*/, TPublicType& publicType)
2940 {
2941     const TTypeList& typeList = *publicType.userDef->getStruct();
2942
2943     // fix and check for member storage qualifiers and types that don't belong within a structure
2944     for (unsigned int member = 0; member < typeList.size(); ++member) {
2945         TQualifier& memberQualifier = typeList[member].type->getQualifier();        
2946         TSourceLoc memberLoc = typeList[member].loc;
2947         if (memberQualifier.isAuxiliary() ||
2948             memberQualifier.isInterpolation() ||
2949             (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal))
2950             error(memberLoc, "cannot use storage or interpolation qualifiers on structure members", typeList[member].type->getFieldName().c_str(), "");
2951         if (memberQualifier.isMemory())
2952             error(memberLoc, "cannot use memory qualifiers on structure members", typeList[member].type->getFieldName().c_str(), "");
2953         if (memberQualifier.hasLayout()) {
2954             error(memberLoc, "cannot use layout qualifiers on structure members", typeList[member].type->getFieldName().c_str(), "");
2955             memberQualifier.clearLayout();
2956         }
2957         if (memberQualifier.invariant)
2958             error(memberLoc, "cannot use invariant qualifier on structure members", typeList[member].type->getFieldName().c_str(), "");
2959     }
2960 }
2961
2962 //
2963 // See if this loop satisfies the limitations for ES 2.0 (version 100) for loops in Appendex A:
2964 //
2965 // "The loop index has type int or float.
2966 //
2967 // "The for statement has the form:
2968 //     for ( init-declaration ; condition ; expression )
2969 //     init-declaration has the form: type-specifier identifier = constant-expression
2970 //     condition has the form:  loop-index relational_operator constant-expression
2971 //         where relational_operator is one of: > >= < <= == or !=
2972 //     expression [sic] has one of the following forms:
2973 //         loop-index++
2974 //         loop-index--
2975 //         loop-index += constant-expression
2976 //         loop-index -= constant-expression
2977 //
2978 // The body is handled in an AST traversal.
2979 //
2980 void TParseContext::inductiveLoopCheck(TSourceLoc loc, TIntermNode* init, TIntermLoop* loop)
2981 {
2982     // loop index init must exist and be a declaration, which shows up in the AST as an aggregate of size 1 of the declaration
2983     bool badInit = false;
2984     if (! init || ! init->getAsAggregate() || init->getAsAggregate()->getSequence().size() != 1)
2985         badInit = true;
2986     TIntermBinary* binaryInit = 0;
2987     if (! badInit) {
2988         // get the declaration assignment
2989         binaryInit = init->getAsAggregate()->getSequence()[0]->getAsBinaryNode();
2990         if (! binaryInit)
2991             badInit = true;
2992     }
2993     if (badInit) {
2994         error(loc, "inductive-loop init-declaration requires the form \"type-specifier loop-index = constant-expression\"", "limitations", "");
2995         return;
2996     }
2997
2998     // loop index must be type int or float
2999     if (! binaryInit->getType().isScalar() || (binaryInit->getBasicType() != EbtInt && binaryInit->getBasicType() != EbtFloat)) {
3000         error(loc, "inductive loop requires a scalar 'int' or 'float' loop index", "limitations", "");
3001         return;
3002     }
3003
3004     // init is the form "loop-index = constant"
3005     if (binaryInit->getOp() != EOpAssign || ! binaryInit->getLeft()->getAsSymbolNode() || ! binaryInit->getRight()->getAsConstantUnion()) {
3006         error(loc, "inductive-loop init-declaration requires the form \"type-specifier loop-index = constant-expression\"", "limitations", "");
3007         return;
3008     }
3009
3010     // get the unique id of the loop index
3011     int loopIndex = binaryInit->getLeft()->getAsSymbolNode()->getId();
3012     inductiveLoopIds.insert(loopIndex);
3013
3014     // condition's form must be "loop-index relational-operator constant-expression"
3015     bool badCond = ! loop->getTest();
3016     if (! badCond) {
3017         TIntermBinary* binaryCond = loop->getTest()->getAsBinaryNode();
3018         badCond = ! binaryCond;
3019         if (! badCond) {
3020             switch (binaryCond->getOp()) {
3021             case EOpGreaterThan:
3022             case EOpGreaterThanEqual:
3023             case EOpLessThan:
3024             case EOpLessThanEqual:
3025             case EOpEqual:
3026             case EOpNotEqual:
3027                 break;
3028             default:
3029                 badCond = true;
3030             }
3031         }
3032         if (binaryCond && (! binaryCond->getLeft()->getAsSymbolNode() ||
3033                            binaryCond->getLeft()->getAsSymbolNode()->getId() != loopIndex ||
3034                            ! binaryCond->getRight()->getAsConstantUnion()))
3035             badCond = true;
3036     }
3037     if (badCond) {
3038         error(loc, "inductive-loop condition requires the form \"loop-index <comparison-op> constant-expression\"", "limitations", "");
3039         return;
3040     }
3041
3042     // loop-index++
3043     // loop-index--
3044     // loop-index += constant-expression
3045     // loop-index -= constant-expression
3046     bool badTerminal = ! loop->getTerminal();
3047     if (! badTerminal) {
3048         TIntermUnary* unaryTerminal = loop->getTerminal()->getAsUnaryNode();
3049         TIntermBinary* binaryTerminal = loop->getTerminal()->getAsBinaryNode();
3050         if (unaryTerminal || binaryTerminal) {
3051             switch(loop->getTerminal()->getAsOperator()->getOp()) {
3052             case EOpPostDecrement:
3053             case EOpPostIncrement:
3054             case EOpAddAssign:
3055             case EOpSubAssign:
3056                 break;
3057             default:
3058                 badTerminal = true;
3059             }
3060         } else
3061             badTerminal = true;
3062         if (binaryTerminal && (! binaryTerminal->getLeft()->getAsSymbolNode() ||
3063                                binaryTerminal->getLeft()->getAsSymbolNode()->getId() != loopIndex ||
3064                                ! binaryTerminal->getRight()->getAsConstantUnion()))
3065             badTerminal = true;
3066         if (unaryTerminal && (! unaryTerminal->getOperand()->getAsSymbolNode() ||
3067                               unaryTerminal->getOperand()->getAsSymbolNode()->getId() != loopIndex))
3068             badTerminal = true;
3069     }
3070     if (badTerminal) {
3071         error(loc, "inductive-loop termination requires the form \"loop-index++, loop-index--, loop-index += constant-expression, or loop-index -= constant-expression\"", "limitations", "");
3072         return;
3073     }
3074
3075     // the body
3076     inductiveLoopBodyCheck(loop->getBody(), loopIndex, symbolTable);
3077 }
3078
3079 // Do limit checks against for all built-in arrays.
3080 void TParseContext::arrayLimitCheck(TSourceLoc loc, const TString& identifier, int size)
3081 {
3082     if (identifier.compare("gl_TexCoord") == 0)
3083         limitCheck(loc, size, "gl_MaxTextureCoords", "gl_TexCoord array size");
3084     else if (identifier.compare("gl_ClipDistance") == 0)
3085         limitCheck(loc, size, "gl_MaxClipDistances", "gl_ClipDistance array size");
3086 }
3087
3088 // See if the provide value is less than the symbol indicated by limit,
3089 // which should be a constant in the symbol table.
3090 void TParseContext::limitCheck(TSourceLoc loc, int value, const char* limit, const char* feature)
3091 {
3092     TSymbol* symbol = symbolTable.find(limit);
3093     assert(symbol->getAsVariable());
3094     const TConstUnionArray& constArray = symbol->getAsVariable()->getConstArray();
3095     assert(! constArray.empty());
3096     if (value >= constArray[0].getIConst())
3097         error(loc, "must be less than", feature, "%s (%d)", limit, constArray[0].getIConst());
3098 }
3099
3100 //
3101 // Do any additional error checking, etc., once we know the parsing is done.
3102 //
3103 void TParseContext::finalErrorCheck()
3104 {
3105     // Check on array indexes for ES 2.0 (version 100) limitations.
3106     for (size_t i = 0; i < needsIndexLimitationChecking.size(); ++i)
3107         constantIndexExpressionCheck(needsIndexLimitationChecking[i]);
3108 }
3109
3110 //
3111 // Layout qualifier stuff.
3112 //
3113
3114 // Put the id's layout qualification into the public type, for qualifiers not having a number set.
3115 // This is before we know any type information for error checking.
3116 void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id)
3117 {
3118     std::transform(id.begin(), id.end(), id.begin(), ::tolower);
3119
3120     if (id == TQualifier::getLayoutMatrixString(ElmColumnMajor)) {
3121         publicType.qualifier.layoutMatrix = ElmColumnMajor;
3122         return;
3123     }
3124     if (id == TQualifier::getLayoutMatrixString(ElmRowMajor)) {
3125         publicType.qualifier.layoutMatrix = ElmRowMajor;
3126         return;
3127     }
3128     if (id == TQualifier::getLayoutPackingString(ElpPacked)) {
3129         publicType.qualifier.layoutPacking = ElpPacked;
3130         return;
3131     }
3132     if (id == TQualifier::getLayoutPackingString(ElpShared)) {
3133         publicType.qualifier.layoutPacking = ElpShared;
3134         return;
3135     }
3136     if (id == TQualifier::getLayoutPackingString(ElpStd140)) {
3137         publicType.qualifier.layoutPacking = ElpStd140;
3138         return;
3139     }
3140     if (id == TQualifier::getLayoutPackingString(ElpStd430)) {
3141         requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "std430");
3142         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, 0, "std430");
3143         profileRequires(loc, EEsProfile, 310, 0, "std430");
3144         publicType.qualifier.layoutPacking = ElpStd430;
3145         return;
3146     }
3147     for (TLayoutFormat format = (TLayoutFormat)(ElfNone + 1); format < ElfCount; format = (TLayoutFormat)(format + 1)) {
3148         if (id == TQualifier::getLayoutFormatString(format)) {
3149             if ((format > ElfEsFloatGuard && format < ElfFloatGuard) ||
3150                 (format > ElfEsIntGuard && format < ElfIntGuard) ||
3151                 (format > ElfEsUintGuard && format < ElfCount))
3152                 requireProfile(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, "image load-store format");
3153             profileRequires(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, 420, GL_ARB_shader_image_load_store, "image load store");
3154             profileRequires(loc, EEsProfile, 310, GL_ARB_shader_image_load_store, "image load store");
3155             publicType.qualifier.layoutFormat = format;
3156             return;
3157         }
3158     }
3159     if (language == EShLangGeometry || language == EShLangTessEvaluation) {
3160         if (id == TQualifier::getGeometryString(ElgTriangles)) {
3161             publicType.shaderQualifiers.geometry = ElgTriangles;
3162             return;
3163         }
3164         if (language == EShLangGeometry) {
3165             if (id == TQualifier::getGeometryString(ElgPoints)) {
3166                 publicType.shaderQualifiers.geometry = ElgPoints;
3167                 return;
3168             }
3169             if (id == TQualifier::getGeometryString(ElgLineStrip)) {
3170                 publicType.shaderQualifiers.geometry = ElgLineStrip;
3171                 return;
3172             }
3173             if (id == TQualifier::getGeometryString(ElgLines)) {
3174                 publicType.shaderQualifiers.geometry = ElgLines;
3175                 return;
3176             }
3177             if (id == TQualifier::getGeometryString(ElgLinesAdjacency)) {
3178                 publicType.shaderQualifiers.geometry = ElgLinesAdjacency;
3179                 return;
3180             }
3181             if (id == TQualifier::getGeometryString(ElgTrianglesAdjacency)) {
3182                 publicType.shaderQualifiers.geometry = ElgTrianglesAdjacency;
3183                 return;
3184             }
3185             if (id == TQualifier::getGeometryString(ElgTriangleStrip)) {
3186                 publicType.shaderQualifiers.geometry = ElgTriangleStrip;
3187                 return;
3188             }
3189         } else {
3190             assert(language == EShLangTessEvaluation);
3191
3192             // input primitive
3193             if (id == TQualifier::getGeometryString(ElgTriangles)) {
3194                 publicType.shaderQualifiers.geometry = ElgTriangles;
3195                 return;
3196             }
3197             if (id == TQualifier::getGeometryString(ElgQuads)) {
3198                 publicType.shaderQualifiers.geometry = ElgQuads;
3199                 return;
3200             }
3201             if (id == TQualifier::getGeometryString(ElgIsolines)) {
3202                 publicType.shaderQualifiers.geometry = ElgIsolines;
3203                 return;
3204             }
3205
3206             // vertex spacing
3207             if (id == TQualifier::getVertexSpacingString(EvsEqual)) {
3208                 publicType.shaderQualifiers.spacing = EvsEqual;
3209                 return;
3210             }
3211             if (id == TQualifier::getVertexSpacingString(EvsFractionalEven)) {
3212                 publicType.shaderQualifiers.spacing = EvsFractionalEven;
3213                 return;
3214             }
3215             if (id == TQualifier::getVertexSpacingString(EvsFractionalOdd)) {
3216                 publicType.shaderQualifiers.spacing = EvsFractionalOdd;
3217                 return;
3218             }
3219
3220             // triangle order
3221             if (id == TQualifier::getVertexOrderString(EvoCw)) {
3222                 publicType.shaderQualifiers.order = EvoCw;
3223                 return;
3224             }
3225             if (id == TQualifier::getVertexOrderString(EvoCcw)) {
3226                 publicType.shaderQualifiers.order = EvoCcw;
3227                 return;
3228             }
3229
3230             // point mode
3231             if (id == "point_mode") {
3232                 publicType.shaderQualifiers.pointMode = true;
3233                 return;
3234             }
3235         }
3236     }
3237     if (language == EShLangFragment) {
3238         if (id == "origin_upper_left") {
3239             requireProfile(loc, ECoreProfile | ECompatibilityProfile, "origin_upper_left");
3240             publicType.shaderQualifiers.originUpperLeft = true;
3241             return;
3242         }
3243         if (id == "pixel_center_integer") {
3244             requireProfile(loc, ECoreProfile | ECompatibilityProfile, "pixel_center_integer");
3245             publicType.shaderQualifiers.pixelCenterInteger = true;
3246             return;
3247         }
3248         if (id == "early_fragment_tests") {
3249             profileRequires(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, 420, GL_ARB_shader_image_load_store, "early_fragment_tests");
3250             profileRequires(loc, EEsProfile, 310, 0, "early_fragment_tests");
3251             publicType.shaderQualifiers.earlyFragmentTests = true;
3252             return;
3253         }
3254         for (TLayoutDepth depth = (TLayoutDepth)(EldNone + 1); depth < EldCount; depth = (TLayoutDepth)(depth+1)) {
3255             if (id == TQualifier::getLayoutDepthString(depth)) {
3256                 requireProfile(loc, ECoreProfile | ECompatibilityProfile, "depth layout qualifier");
3257                 profileRequires(loc, ECoreProfile | ECompatibilityProfile, 420, 0, "depth layout qualifier");
3258                 publicType.shaderQualifiers.layoutDepth = depth;
3259                 return;
3260             }
3261         }
3262     }
3263     error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), "");
3264 }
3265
3266 // Put the id's layout qualifier value into the public type, for qualifiers having a number set.
3267 // This is before we know any type information for error checking.
3268 void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id, const TIntermTyped* node)
3269 {
3270     const char* feature = "layout-id value";
3271     const char* nonLiteralFeature = "non-literal layout-id value";
3272
3273     integerCheck(node, feature);
3274     const TIntermConstantUnion* constUnion = node->getAsConstantUnion();
3275     int value;
3276     if (constUnion) {
3277         value = constUnion->getConstArray()[0].getIConst();
3278         if (! constUnion->isLiteral()) {
3279             requireProfile(loc, ECoreProfile | ECompatibilityProfile, nonLiteralFeature);
3280             profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, GL_ARB_enhanced_layouts, nonLiteralFeature);
3281         }
3282     } else {
3283         // grammar should have give out the error message
3284         value = 0;
3285     }
3286
3287     if (value < 0) {
3288         error(loc, "cannot be negative", feature, "");
3289         return;
3290     }
3291
3292     std::transform(id.begin(), id.end(), id.begin(), ::tolower);
3293     
3294     if (id == "offset") {
3295         const char* feature = "uniform offset";
3296         requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature);
3297         const char* exts[2] = { GL_ARB_enhanced_layouts, GL_ARB_shader_atomic_counters };
3298         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 420, 2, exts, feature);
3299         profileRequires(loc, EEsProfile, 310, 0, feature);
3300         publicType.qualifier.layoutOffset = value;
3301         return;
3302     } else if (id == "align") {
3303         const char* feature = "uniform buffer-member align";
3304         requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature);
3305         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, GL_ARB_enhanced_layouts, feature);
3306         // "The specified alignment must be a power of 2, or a compile-time error results."
3307         if (! IsPow2(value))
3308             error(loc, "must be a power of 2", "align", "");
3309         else
3310             publicType.qualifier.layoutAlign = value;
3311         return;
3312     } else if (id == "location") {
3313         profileRequires(loc, EEsProfile, 300, 0, "location");
3314         const char* exts[2] = { GL_ARB_separate_shader_objects, GL_ARB_explicit_attrib_location };
3315         profileRequires(loc, ~EEsProfile, 330, 2, exts, "location");
3316         if ((unsigned int)value >= TQualifier::layoutLocationEnd)
3317             error(loc, "location is too large", id.c_str(), "");
3318         else
3319             publicType.qualifier.layoutLocation = value;
3320         return;
3321     } else if (id == "set") {
3322         if ((unsigned int)value >= TQualifier::layoutSetEnd)
3323             error(loc, "set is too large", id.c_str(), "");
3324         else
3325             publicType.qualifier.layoutSet = value;
3326         return;
3327     } else if (id == "binding") {
3328         profileRequires(loc, ~EEsProfile, 420, GL_ARB_shading_language_420pack, "binding");
3329         profileRequires(loc, EEsProfile, 310, 0, "binding");
3330         if ((unsigned int)value >= TQualifier::layoutBindingEnd)
3331             error(loc, "binding is too large", id.c_str(), "");
3332         else
3333             publicType.qualifier.layoutBinding = value;
3334         return;
3335     } else if (id == "component") {
3336         requireProfile(loc, ECoreProfile | ECompatibilityProfile, "component");
3337         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, GL_ARB_enhanced_layouts, "component");
3338         if ((unsigned)value >= TQualifier::layoutComponentEnd)
3339             error(loc, "component is too large", id.c_str(), "");
3340         else
3341             publicType.qualifier.layoutComponent = value;
3342         return;
3343     } else if (id.compare(0, 4, "xfb_") == 0) {
3344         // "Any shader making any static use (after preprocessing) of any of these 
3345         // *xfb_* qualifiers will cause the shader to be in a transform feedback 
3346         // capturing mode and hence responsible for describing the transform feedback 
3347         // setup."
3348         intermediate.setXfbMode();
3349         const char* feature = "transform feedback qualifier";
3350         requireStage(loc, (EShLanguageMask)(EShLangVertexMask | EShLangGeometryMask | EShLangTessControlMask | EShLangTessEvaluationMask), feature);
3351         requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature);
3352         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, GL_ARB_enhanced_layouts, feature);
3353         if (id == "xfb_buffer") {
3354             // "It is a compile-time error to specify an *xfb_buffer* that is greater than
3355             // the implementation-dependent constant gl_MaxTransformFeedbackBuffers."
3356             if (value >= resources.maxTransformFeedbackBuffers)
3357                 error(loc, "buffer is too large:", id.c_str(), "gl_MaxTransformFeedbackBuffers is %d", resources.maxTransformFeedbackBuffers);                
3358             if (value >= TQualifier::layoutXfbBufferEnd)
3359                 error(loc, "buffer is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbBufferEnd-1);
3360             else
3361                 publicType.qualifier.layoutXfbBuffer = value;
3362             return;
3363         } else if (id == "xfb_offset") {
3364             if (value >= TQualifier::layoutXfbOffsetEnd)
3365                 error(loc, "offset is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbOffsetEnd-1);
3366             else
3367                 publicType.qualifier.layoutXfbOffset = value;
3368             return;
3369         } else if (id == "xfb_stride") {
3370             // "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the 
3371             // implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents."
3372             if (value > 4 * resources.maxTransformFeedbackInterleavedComponents)
3373                 error(loc, "1/4 stride is too large:", id.c_str(), "gl_MaxTransformFeedbackInterleavedComponents is %d", resources.maxTransformFeedbackInterleavedComponents);
3374             else if (value >= TQualifier::layoutXfbStrideEnd)
3375                 error(loc, "stride is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbStrideEnd-1);
3376             if (value < TQualifier::layoutXfbStrideEnd)
3377                 publicType.qualifier.layoutXfbStride = value;
3378             return;
3379         }
3380     }
3381
3382     switch (language) {
3383     case EShLangVertex:
3384         break;
3385
3386     case EShLangTessControl:
3387         if (id == "vertices") {
3388             publicType.shaderQualifiers.vertices = value;
3389             return;
3390         }
3391         break;
3392
3393     case EShLangTessEvaluation:
3394         break;
3395
3396     case EShLangGeometry:
3397         if (id == "invocations") {
3398             profileRequires(loc, ECompatibilityProfile | ECoreProfile, 400, 0, "invocations");
3399             publicType.shaderQualifiers.invocations = value;
3400             return;
3401         }
3402         if (id == "max_vertices") {
3403             publicType.shaderQualifiers.vertices = value;
3404             if (value > resources.maxGeometryOutputVertices)
3405                 error(loc, "too large, must be less than gl_MaxGeometryOutputVertices", "max_vertices", "");
3406             return;
3407         }
3408         if (id == "stream") {
3409             publicType.qualifier.layoutStream = value;
3410             return;
3411         }
3412         break;
3413
3414     case EShLangFragment:
3415         if (id == "index") {
3416             requireProfile(loc, ECompatibilityProfile | ECoreProfile, "index layout qualifier on fragment output");
3417             const char* exts[2] = { GL_ARB_separate_shader_objects, GL_ARB_explicit_attrib_location };
3418             profileRequires(loc, ECompatibilityProfile | ECoreProfile, 330, 2, exts, "index layout qualifier on fragment output");
3419             publicType.qualifier.layoutIndex = value;
3420             return;
3421         }
3422         break;
3423
3424     case EShLangCompute:
3425         if (id == "local_size_x") {
3426             publicType.shaderQualifiers.localSize[0] = value;
3427             return;
3428         }
3429         if (id == "local_size_y") {
3430             publicType.shaderQualifiers.localSize[1] = value;
3431             return;
3432         }
3433         if (id == "local_size_z") {
3434             publicType.shaderQualifiers.localSize[2] = value;
3435             return;
3436         }
3437         break;
3438
3439     default:
3440         break;
3441     }
3442
3443     error(loc, "there is no such layout identifier for this stage taking an assigned value", id.c_str(), "");
3444 }
3445
3446 // Merge any layout qualifier information from src into dst, leaving everything else in dst alone
3447 //
3448 // "More than one layout qualifier may appear in a single declaration.
3449 // Additionally, the same layout-qualifier-name can occur multiple times 
3450 // within a layout qualifier or across multiple layout qualifiers in the 
3451 // same declaration. When the same layout-qualifier-name occurs 
3452 // multiple times, in a single declaration, the last occurrence overrides 
3453 // the former occurrence(s).  Further, if such a layout-qualifier-name 
3454 // will effect subsequent declarations or other observable behavior, it 
3455 // is only the last occurrence that will have any effect, behaving as if 
3456 // the earlier occurrence(s) within the declaration are not present.  
3457 // This is also true for overriding layout-qualifier-names, where one 
3458 // overrides the other (e.g., row_major vs. column_major); only the last 
3459 // occurrence has any effect."    
3460 //
3461 void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifier& src, bool inheritOnly)
3462 {
3463     if (src.hasMatrix())
3464         dst.layoutMatrix = src.layoutMatrix;
3465     if (src.hasPacking())
3466         dst.layoutPacking = src.layoutPacking;
3467
3468     if (src.hasStream())
3469         dst.layoutStream = src.layoutStream;
3470
3471     if (src.hasFormat())
3472         dst.layoutFormat = src.layoutFormat;
3473
3474     if (src.hasXfbBuffer())
3475         dst.layoutXfbBuffer = src.layoutXfbBuffer;
3476
3477     if (src.hasAlign())
3478         dst.layoutAlign = src.layoutAlign;
3479
3480     if (! inheritOnly) {
3481         if (src.hasLocation())
3482             dst.layoutLocation = src.layoutLocation;
3483         if (src.hasComponent())
3484             dst.layoutComponent = src.layoutComponent;
3485         if (src.hasIndex())
3486             dst.layoutIndex = src.layoutIndex;
3487
3488         if (src.hasOffset())
3489             dst.layoutOffset = src.layoutOffset;
3490
3491         if (src.hasSet())
3492             dst.layoutSet = src.layoutSet;
3493         if (src.layoutBinding != TQualifier::layoutBindingEnd)
3494             dst.layoutBinding = src.layoutBinding;
3495
3496         if (src.hasXfbStride())
3497             dst.layoutXfbStride = src.layoutXfbStride;
3498         if (src.hasXfbOffset())
3499             dst.layoutXfbOffset = src.layoutXfbOffset;
3500     }
3501 }
3502
3503 // Do error layout error checking given a full variable/block declaration.
3504 void TParseContext::layoutObjectCheck(TSourceLoc loc, const TSymbol& symbol)
3505 {
3506     const TType& type = symbol.getType();
3507     const TQualifier& qualifier = type.getQualifier();
3508
3509     // first, cross check WRT to just the type
3510     layoutTypeCheck(loc, type);
3511
3512     // now, any remaining error checking based on the object itself
3513
3514     if (qualifier.hasAnyLocation()) {
3515         switch (qualifier.storage) {
3516         case EvqUniform:
3517         case EvqBuffer:
3518             if (symbol.getAsVariable() == 0)
3519                 error(loc, "can only be used on variable declaration", "location", "");
3520             break;
3521         default:
3522             break;
3523         }
3524     }
3525
3526     // Check packing and matrix 
3527     if (qualifier.hasUniformLayout()) {
3528         switch (qualifier.storage) {
3529         case EvqUniform:
3530         case EvqBuffer:
3531             if (type.getBasicType() != EbtBlock) {
3532                 if (qualifier.hasMatrix())
3533                     error(loc, "cannot specify matrix layout on a variable declaration", "layout", "");
3534                 if (qualifier.hasPacking())
3535                     error(loc, "cannot specify packing on a variable declaration", "layout", "");
3536                 // "The offset qualifier can only be used on block members of blocks..."
3537                 if (qualifier.hasOffset() && type.getBasicType() != EbtAtomicUint)
3538                     error(loc, "cannot specify on a variable declaration", "offset", "");
3539                 // "The align qualifier can only be used on blocks or block members..."
3540                 if (qualifier.hasAlign())
3541                     error(loc, "cannot specify on a variable declaration", "align", "");
3542             }
3543             break;
3544         default:
3545             // these were already filtered by layoutTypeCheck() (or its callees)
3546             break;
3547         }
3548     }
3549 }
3550
3551 // Do layout error checking with respect to a type.
3552 void TParseContext::layoutTypeCheck(TSourceLoc loc, const TType& type)
3553 {
3554     const TQualifier& qualifier = type.getQualifier();
3555
3556     // first, intra layout qualifier-only error checking
3557     layoutQualifierCheck(loc, qualifier);
3558
3559     // now, error checking combining type and qualifier
3560
3561     if (qualifier.hasAnyLocation()) {
3562         if (qualifier.hasLocation()) {
3563             if (qualifier.storage == EvqVaryingOut && language == EShLangFragment) {
3564                 if (qualifier.layoutLocation >= (unsigned int)resources.maxDrawBuffers)
3565                     error(loc, "too large for fragment output", "location", "");
3566             }
3567         }
3568         if (qualifier.hasComponent()) {
3569             // "It is a compile-time error if this sequence of components gets larger than 3."
3570             if (qualifier.layoutComponent + type.getVectorSize() > 4)
3571                 error(loc, "type overflows the available 4 components", "component", "");
3572
3573             // "It is a compile-time error to apply the component qualifier to a matrix, a structure, a block, or an array containing any of these."
3574             if (type.isMatrix() || type.getBasicType() == EbtBlock || type.getBasicType() == EbtStruct)
3575                 error(loc, "cannot apply to a matrix, structure, or block", "component", "");
3576         }
3577
3578         switch (qualifier.storage) {
3579         case EvqVaryingIn:
3580         case EvqVaryingOut:
3581             if (type.getBasicType() == EbtBlock)
3582                 profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, GL_ARB_enhanced_layouts, "location qualifier on in/out block");
3583             break;
3584         case EvqUniform:
3585         case EvqBuffer:
3586             break;
3587         default:
3588             error(loc, "can only appy to uniform, buffer, in, or out storage qualifiers", "location", "");
3589             break;
3590         }
3591
3592         bool typeCollision;
3593         int repeated = intermediate.addUsedLocation(qualifier, type, typeCollision);
3594         if (repeated >= 0 && ! typeCollision)
3595             error(loc, "overlapping use of location", "location", "%d", repeated);
3596         // "fragment-shader outputs ... if two variables are placed within the same
3597         // location, they must have the same underlying type (floating-point or integer)"
3598         if (typeCollision && language == EShLangFragment && qualifier.isPipeOutput())
3599             error(loc, "fragment outputs sharing the same location must be the same basic type", "location", "%d", repeated);
3600     }
3601
3602     if (qualifier.hasXfbOffset() && qualifier.hasXfbBuffer()) {
3603         int repeated = intermediate.addXfbBufferOffset(type);
3604         if (repeated >= 0)
3605             error(loc, "overlapping offsets at", "xfb_offset", "offset %d in buffer %d", repeated, qualifier.layoutXfbBuffer);
3606
3607         // "The offset must be a multiple of the size of the first component of the first 
3608         // qualified variable or block member, or a compile-time error results. Further, if applied to an aggregate 
3609         // containing a double, the offset must also be a multiple of 8..."
3610         if (type.containsBasicType(EbtDouble) && ! IsMultipleOfPow2(qualifier.layoutXfbOffset, 8))
3611             error(loc, "type contains double; xfb_offset must be a multiple of 8", "xfb_offset", "");
3612         else if (! IsMultipleOfPow2(qualifier.layoutXfbOffset, 4))
3613             error(loc, "must be a multiple of size of first component", "xfb_offset", "");
3614     }
3615
3616     if (qualifier.hasXfbStride() && qualifier.hasXfbBuffer()) {
3617         if (! intermediate.setXfbBufferStride(qualifier.layoutXfbBuffer, qualifier.layoutXfbStride))
3618             error(loc, "all stride settings must match for xfb buffer", "xfb_stride", "%d", qualifier.layoutXfbBuffer);
3619     }
3620
3621     if (qualifier.hasBinding()) {
3622         // Binding checking, from the spec:
3623         //
3624         // "If the binding point for any uniform or shader storage block instance is less than zero, or greater than or
3625         // equal to the implementation-dependent maximum number of uniform buffer bindings, a compile-time
3626         // error will occur. When the binding identifier is used with a uniform or shader storage block instanced as
3627         // an array of size N, all elements of the array from binding through binding + N \96 1 must be within this
3628         // range."
3629         //
3630         if (type.getBasicType() != EbtSampler && type.getBasicType() != EbtBlock && type.getBasicType() != EbtAtomicUint)
3631             error(loc, "requires block, or sampler/image, or atomic-counter type", "binding", "");
3632         if (type.getBasicType() == EbtSampler) {
3633             int lastBinding = qualifier.layoutBinding;
3634             if (type.isArray())
3635                 lastBinding += type.getArraySize();
3636             if (lastBinding >= resources.maxCombinedTextureImageUnits)
3637                 error(loc, "sampler binding not less than gl_MaxCombinedTextureImageUnits", "binding", type.isArray() ? "(using array)" : "");
3638         }
3639         if (type.getBasicType() == EbtAtomicUint) {
3640             if (qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) {
3641                 error(loc, "atomic_uint binding is too large; see gl_MaxAtomicCounterBindings", "binding", "");
3642                 return;
3643             }
3644         }
3645     }
3646
3647     // atomic_uint
3648     if (type.getBasicType() == EbtAtomicUint) {
3649         if (! type.getQualifier().hasBinding())
3650             error(loc, "layout(binding=X) is required", "atomic_uint", "");
3651     }
3652
3653     // "The offset qualifier can only be used on block members of blocks..."
3654     if (qualifier.hasOffset()) {
3655         if (type.getBasicType() == EbtBlock)
3656             error(loc, "only applies to block members, not blocks", "offset", "");
3657     }
3658
3659     // Image format
3660     if (qualifier.hasFormat()) {
3661         if (! type.isImage())
3662             error(loc, "only apply to images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), "");
3663         else {
3664             if (type.getSampler().type == EbtFloat && qualifier.layoutFormat > ElfFloatGuard)
3665                 error(loc, "does not apply to floating point images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), "");
3666             if (type.getSampler().type == EbtInt && (qualifier.layoutFormat < ElfFloatGuard || qualifier.layoutFormat > ElfIntGuard))
3667                 error(loc, "does not apply to signed integer images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), "");
3668             if (type.getSampler().type == EbtUint && qualifier.layoutFormat < ElfIntGuard)
3669                 error(loc, "does not apply to unsigned integer images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), "");
3670
3671             if (profile == EEsProfile) {
3672                 // "Except for image variables qualified with the format qualifiers r32f, r32i, and r32ui, image variables must 
3673                 // specify either memory qualifier readonly or the memory qualifier writeonly."
3674                 if (! (qualifier.layoutFormat == ElfR32f || qualifier.layoutFormat == ElfR32i || qualifier.layoutFormat == ElfR32ui)) {
3675                     if (! qualifier.readonly && ! qualifier.writeonly)
3676                         error(loc, "format requires readonly or writeonly memory qualifier", TQualifier::getLayoutFormatString(qualifier.layoutFormat), "");
3677                 }
3678             }
3679         }
3680     } else if (type.isImage() && ! qualifier.writeonly)
3681         error(loc, "image variables not declared 'writeonly' must have a format layout qualifier", "", "");
3682 }
3683
3684 // Do layout error checking that can be done within a layout qualifier proper, not needing to know
3685 // if there are blocks, atomic counters, variables, etc.
3686 void TParseContext::layoutQualifierCheck(TSourceLoc loc, const TQualifier& qualifier)
3687 {
3688     if (qualifier.storage == EvqShared && qualifier.hasLayout())
3689         error(loc, "cannot apply layout qualifiers to a shared variable", "shared", "");
3690
3691     // "It is a compile-time error to use *component* without also specifying the location qualifier (order does not matter)."
3692     if (qualifier.hasComponent() && ! qualifier.hasLocation())
3693         error(loc, "must specify 'location' to use 'component'", "component", "");
3694
3695     if (qualifier.hasAnyLocation()) {
3696
3697         // "As with input layout qualifiers, all shaders except compute shaders 
3698         // allow *location* layout qualifiers on output variable declarations, 
3699         // output block declarations, and output block member declarations."
3700
3701         switch (qualifier.storage) {
3702         case EvqVaryingIn:
3703         {
3704             const char* feature = "location qualifier on input";
3705             if (profile == EEsProfile && version < 310)
3706                 requireStage(loc, EShLangVertex, feature);
3707             else
3708                 requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature);
3709             if (language == EShLangVertex) {
3710                 const char* exts[2] = { GL_ARB_separate_shader_objects, GL_ARB_explicit_attrib_location };
3711                 profileRequires(loc, ~EEsProfile, 330, 2, exts, feature);
3712                 profileRequires(loc, EEsProfile, 300, 0, feature);
3713             } else {
3714                 profileRequires(loc, ~EEsProfile, 410, GL_ARB_separate_shader_objects, feature);
3715                 profileRequires(loc, EEsProfile, 310, 0, feature);
3716             }
3717             break;
3718         }
3719         case EvqVaryingOut:
3720         {
3721             const char* feature = "location qualifier on output";
3722             if (profile == EEsProfile && version < 310)
3723                 requireStage(loc, EShLangFragment, feature);
3724             else
3725                 requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature);
3726             if (language == EShLangFragment) {
3727                 const char* exts[2] = { GL_ARB_separate_shader_objects, GL_ARB_explicit_attrib_location };
3728                 profileRequires(loc, ~EEsProfile, 330, 2, exts, feature);
3729                 profileRequires(loc, EEsProfile, 300, 0, feature);
3730             } else {
3731                 profileRequires(loc, ~EEsProfile, 410, GL_ARB_separate_shader_objects, feature);
3732                 profileRequires(loc, EEsProfile, 310, 0, feature);
3733             }
3734             break;
3735         }
3736         case EvqUniform:
3737         case EvqBuffer:
3738         {
3739             const char* feature = "location qualifier on uniform or buffer";
3740             requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature);
3741             profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, 0, feature);
3742             profileRequires(loc, EEsProfile, 310, 0, feature);
3743             break;
3744         }
3745         default:
3746             break;
3747         }
3748         if (qualifier.hasIndex()) {
3749             if (qualifier.storage != EvqVaryingOut)
3750                 error(loc, "can only be used on an output", "index", "");
3751             if (! qualifier.hasLocation())
3752                 error(loc, "can only be used with an explicit location", "index", "");
3753         }
3754     }
3755
3756     if (qualifier.hasBinding()) {
3757         if (! qualifier.isUniformOrBuffer())
3758             error(loc, "requires uniform or buffer storage qualifier", "binding", "");
3759     }
3760     if (qualifier.hasStream()) {
3761         if (qualifier.storage != EvqVaryingOut)
3762             error(loc, "can only be used on an output", "stream", "");
3763     }
3764     if (qualifier.hasXfb()) {
3765         if (qualifier.storage != EvqVaryingOut)
3766             error(loc, "can only be used on an output", "xfb layout qualifier", "");
3767     }
3768     if (qualifier.hasUniformLayout()) {
3769         if (! qualifier.isUniformOrBuffer()) {
3770             if (qualifier.hasMatrix() || qualifier.hasPacking())
3771                 error(loc, "matrix or packing qualifiers can only be used on a uniform or buffer", "layout", "");
3772             if (qualifier.hasOffset() || qualifier.hasAlign())
3773                 error(loc, "offset/align can only be used on a uniform or buffer", "layout", "");
3774         }
3775     }
3776 }
3777
3778 // For places that can't have shader-level layout qualifiers
3779 void TParseContext::checkNoShaderLayouts(TSourceLoc loc, const TShaderQualifiers& shaderQualifiers)
3780 {
3781     const char* message = "can only apply to a standalone qualifier";
3782
3783     if (shaderQualifiers.geometry != ElgNone)
3784         error(loc, message, TQualifier::getGeometryString(shaderQualifiers.geometry), "");
3785     if (shaderQualifiers.invocations > 0)
3786         error(loc, message, "invocations", "");
3787     if (shaderQualifiers.vertices > 0) {
3788         if (language == EShLangGeometry)
3789             error(loc, message, "max_vertices", "");
3790         else if (language == EShLangTessControl)
3791             error(loc, message, "vertices", "");
3792         else
3793             assert(0);
3794     }
3795     for (int i = 0; i < 3; ++i) {
3796         if (shaderQualifiers.localSize[i] > 1)
3797             error(loc, message, "local_size", "");
3798     }
3799 }
3800
3801 // Correct and/or advance an object's offset layout qualifier.
3802 void TParseContext::fixOffset(TSourceLoc loc, TSymbol& symbol)
3803 {
3804     const TQualifier& qualifier = symbol.getType().getQualifier();
3805     if (symbol.getType().getBasicType() == EbtAtomicUint) {
3806         if (qualifier.hasBinding() && (int)qualifier.layoutBinding < resources.maxAtomicCounterBindings) {
3807
3808             // Set the offset
3809             int offset;
3810             if (qualifier.hasOffset())
3811                 offset = qualifier.layoutOffset;
3812             else
3813                 offset = atomicUintOffsets[qualifier.layoutBinding];
3814             symbol.getWritableType().getQualifier().layoutOffset = offset;
3815
3816             // Check for overlap
3817             int numOffsets = 4;
3818             if (symbol.getType().isArray())
3819                 numOffsets *= symbol.getType().getArraySize();
3820             int repeated = intermediate.addUsedOffsets(qualifier.layoutBinding, offset, numOffsets);
3821             if (repeated >= 0)
3822                 error(loc, "atomic counters sharing the same offset:", "offset", "%d", repeated);
3823
3824             // Bump the default offset
3825             atomicUintOffsets[qualifier.layoutBinding] = offset + numOffsets;
3826         }
3827     }
3828 }
3829
3830 //
3831 // Look up a function name in the symbol table, and make sure it is a function.
3832 //
3833 // Return the function symbol if found, otherwise 0.
3834 //
3835 const TFunction* TParseContext::findFunction(TSourceLoc loc, const TFunction& call, bool& builtIn)
3836 {
3837     const TFunction* function = 0;
3838
3839     if (symbolTable.isFunctionNameVariable(call.getName())) {
3840         error(loc, "can't use function syntax on variable", call.getName().c_str(), "");
3841         return 0;
3842     }
3843
3844     if (profile == EEsProfile || version < 120)
3845         function = findFunctionExact(loc, call, builtIn);
3846     else if (version < 400)
3847         function = findFunction120(loc, call, builtIn);
3848     else
3849         function = findFunction400(loc, call, builtIn);
3850
3851     return function;
3852 }
3853
3854 // Function finding algorithm for ES and desktop 110.
3855 const TFunction* TParseContext::findFunctionExact(TSourceLoc loc, const TFunction& call, bool& builtIn)
3856 {
3857     TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn);
3858     if (symbol == 0) {
3859         error(loc, "no matching overloaded function found", call.getName().c_str(), "");
3860
3861         return 0;
3862     }
3863
3864     return symbol->getAsFunction();
3865 }
3866
3867 // Function finding algorithm for desktop versions 120 through 330.
3868 const TFunction* TParseContext::findFunction120(TSourceLoc loc, const TFunction& call, bool& builtIn)
3869 {
3870     // first, look for an exact match
3871     TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn);
3872     if (symbol)
3873         return symbol->getAsFunction();
3874
3875     // exact match not found, look through a list of overloaded functions of the same name
3876
3877     // "If no exact match is found, then [implicit conversions] will be applied to find a match. Mismatched types
3878     // on input parameters (in or inout or default) must have a conversion from the calling argument type to the
3879     // formal parameter type. Mismatched types on output parameters (out or inout) must have a conversion
3880     // from the formal parameter type to the calling argument type.  When argument conversions are used to find
3881     // a match, it is a semantic error if there are multiple ways to apply these conversions to make the call match
3882     // more than one function."
3883
3884     const TFunction* candidate = 0;
3885     TVector<TFunction*> candidateList;
3886     symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
3887
3888     for (TVector<TFunction*>::const_iterator it = candidateList.begin(); it != candidateList.end(); ++it) {
3889         const TFunction& function = *(*it);
3890
3891         // to even be a potential match, number of arguments has to match
3892         if (call.getParamCount() != function.getParamCount())
3893             continue;
3894
3895         bool possibleMatch = true;
3896         for (int i = 0; i < function.getParamCount(); ++i) {
3897             // same types is easy
3898             if (*function[i].type == *call[i].type)
3899                 continue;
3900
3901             // We have a mismatch in type, see if it is implicitly convertible
3902
3903             if (function[i].type->isArray() || call[i].type->isArray() ||
3904                 ! function[i].type->sameElementShape(*call[i].type))
3905                 possibleMatch = false;
3906             else {
3907                 // do direction-specific checks for conversion of basic type
3908                 if (function[i].type->getQualifier().isParamInput()) {
3909                     if (! intermediate.canImplicitlyPromote(call[i].type->getBasicType(), function[i].type->getBasicType()))
3910                         possibleMatch = false;
3911                 }
3912                 if (function[i].type->getQualifier().isParamOutput()) {
3913                     if (! intermediate.canImplicitlyPromote(function[i].type->getBasicType(), call[i].type->getBasicType()))
3914                         possibleMatch = false;
3915                 }
3916             }
3917             if (! possibleMatch)
3918                 break;
3919         }
3920         if (possibleMatch) {
3921             if (candidate) {
3922                 // our second match, meaning ambiguity
3923                 error(loc, "ambiguous function signature match: multiple signatures match under implicit type conversion", call.getName().c_str(), "");
3924             } else
3925                 candidate = &function;
3926         }
3927     }
3928
3929     if (candidate == 0)
3930         error(loc, "no matching overloaded function found", call.getName().c_str(), "");
3931
3932     return candidate;
3933 }
3934
3935 // Function finding algorithm for desktop version 400 and above.
3936 const TFunction* TParseContext::findFunction400(TSourceLoc loc, const TFunction& call, bool& builtIn)
3937 {
3938     // TODO: 4.00 functionality: findFunction400()
3939     return findFunction120(loc, call, builtIn);
3940 }
3941
3942 // When a declaration includes a type, but not a variable name, it can be 
3943 // to establish defaults.
3944 void TParseContext::declareTypeDefaults(TSourceLoc loc, const TPublicType& publicType)
3945 {
3946     if (publicType.basicType == EbtAtomicUint && publicType.qualifier.hasBinding() && publicType.qualifier.hasOffset()) {
3947         if (publicType.qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) {
3948             error(loc, "atomic_uint binding is too large", "binding", "");
3949             return;
3950         }
3951         atomicUintOffsets[publicType.qualifier.layoutBinding] = publicType.qualifier.layoutOffset;
3952         return;
3953     }
3954
3955     if (publicType.qualifier.hasLayout())
3956         warn(loc, "useless application of layout qualifier", "layout", "");
3957 }
3958
3959 //
3960 // Do everything necessary to handle a variable (non-block) declaration.
3961 // Either redeclaring a variable, or making a new one, updating the symbol
3962 // table, and all error checking.
3963 //
3964 // Returns a subtree node that computes an initializer, if needed.
3965 // Returns 0 if there is no code to execute for initialization.
3966 //
3967 TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier, const TPublicType& publicType, TArraySizes* arraySizes, TIntermTyped* initializer)
3968 {
3969     TType type(publicType);
3970
3971     if (voidErrorCheck(loc, identifier, type.getBasicType()))
3972         return 0;
3973
3974     if (initializer)        
3975         rValueErrorCheck(loc, "initializer", initializer);
3976     else
3977         nonInitConstCheck(loc, identifier, type);
3978
3979     samplerCheck(loc, type, identifier);
3980     atomicUintCheck(loc, type, identifier);
3981
3982     if (identifier != "gl_FragCoord" && (publicType.shaderQualifiers.originUpperLeft || publicType.shaderQualifiers.pixelCenterInteger))
3983         error(loc, "can only apply origin_upper_left and pixel_center_origin to gl_FragCoord", "layout qualifier", "");
3984     if (identifier != "gl_FragDepth" && publicType.shaderQualifiers.layoutDepth != EldNone)
3985         error(loc, "can only apply depth layout to gl_FragDepth", "layout qualifier", "");
3986
3987     // Check for redeclaration of built-ins and/or attempting to declare a reserved name
3988     bool newDeclaration = false;    // true if a new entry gets added to the symbol table
3989     TSymbol* symbol = redeclareBuiltinVariable(loc, identifier, type.getQualifier(), publicType.shaderQualifiers, newDeclaration);
3990     if (! symbol)
3991         reservedErrorCheck(loc, identifier);
3992
3993     inheritGlobalDefaults(type.getQualifier());
3994
3995     // Declare the variable
3996     if (arraySizes || type.isArray()) {
3997         // Arrayness is potentially coming both from the type and from the 
3998         // variable: "int[] a[];" or just one or the other.
3999         // For now, arrays of arrays aren't supported, so it's just one or the
4000         // other.  Move it to the type, so all arrayness is part of the type.
4001         arrayDimCheck(loc, &type, arraySizes);
4002         if (arraySizes)
4003             type.setArraySizes(arraySizes);
4004
4005         // for ES, if size isn't coming from an initializer, it has to be explicitly declared now
4006         if (profile == EEsProfile && ! initializer)
4007             arraySizeRequiredCheck(loc, type.getArraySize());
4008
4009         if (! arrayQualifierError(loc, type.getQualifier()) && ! arrayError(loc, type))
4010             declareArray(loc, identifier, type, symbol, newDeclaration);
4011
4012         if (initializer) {
4013             profileRequires(loc, ENoProfile, 120, GL_3DL_array_objects, "initializer");
4014             profileRequires(loc, EEsProfile, 300, 0, "initializer");
4015         }
4016     } else {
4017         // non-array case
4018         if (! symbol)
4019             symbol = declareNonArray(loc, identifier, type, newDeclaration);
4020         else if (type != symbol->getType())
4021             error(loc, "cannot change the type of", "redeclaration", symbol->getName().c_str());
4022     }
4023
4024     if (! symbol)
4025         return 0;
4026
4027     // Deal with initializer
4028     TIntermNode* initNode = 0;
4029     if (symbol && initializer) {
4030         TVariable* variable = symbol->getAsVariable();
4031         if (! variable) {
4032             error(loc, "initializer requires a variable, not a member", identifier.c_str(), "");
4033             return 0;
4034         }
4035         initNode = executeInitializer(loc, initializer, variable);
4036     }
4037
4038     // look for errors in layout qualifier use
4039     layoutObjectCheck(loc, *symbol);
4040     fixOffset(loc, *symbol);
4041
4042     // see if it's a linker-level object to track
4043     if (newDeclaration && symbolTable.atGlobalLevel())
4044         intermediate.addSymbolLinkageNode(linkage, *symbol);
4045
4046     return initNode;
4047 }
4048
4049 // Pick up global defaults from the provide global defaults into dst.
4050 void TParseContext::inheritGlobalDefaults(TQualifier& dst) const
4051 {
4052     if (dst.storage == EvqVaryingOut) {
4053         if (! dst.hasStream() && language == EShLangGeometry)
4054             dst.layoutStream = globalOutputDefaults.layoutStream;
4055         if (! dst.hasXfbBuffer())
4056             dst.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer;
4057     }
4058 }
4059
4060 //
4061 // Make an internal-only variable whose name is for debug purposes only
4062 // and won't be searched for.  Callers will only use the return value to use
4063 // the variable, not the name to look it up.  It is okay if the name
4064 // is the same as other names; there won't be any conflict.
4065 //
4066 TVariable* TParseContext::makeInternalVariable(const char* name, const TType& type) const
4067 {
4068     TString* nameString = new TString(name);
4069     TVariable* variable = new TVariable(nameString, type);
4070     symbolTable.makeInternalVariable(*variable);
4071
4072     return variable;
4073 }
4074
4075 //
4076 // Declare a non-array variable, the main point being there is no redeclaration
4077 // for resizing allowed.
4078 //
4079 // Return the successfully declared variable.
4080 //
4081 TVariable* TParseContext::declareNonArray(TSourceLoc loc, TString& identifier, TType& type, bool& newDeclaration)
4082 {
4083     // make a new variable
4084     TVariable* variable = new TVariable(&identifier, type);
4085
4086     ioArrayCheck(loc, type, identifier);
4087     // add variable to symbol table
4088     if (! symbolTable.insert(*variable)) {
4089         error(loc, "redefinition", variable->getName().c_str(), "");
4090         return 0;
4091     } else {
4092         newDeclaration = true;
4093         return variable;
4094     }
4095 }
4096
4097 //
4098 // Handle all types of initializers from the grammar.
4099 //
4100 // Returning 0 just means there is no code to execute to handle the
4101 // initializer, which will, for example, be the case for constant initializers.
4102 //
4103 TIntermNode* TParseContext::executeInitializer(TSourceLoc loc, TIntermTyped* initializer, TVariable* variable)
4104 {
4105     //
4106     // Identifier must be of type constant, a global, or a temporary, and
4107     // starting at version 120, desktop allows uniforms to have initializers.
4108     //
4109     TStorageQualifier qualifier = variable->getType().getQualifier().storage;
4110     if (! (qualifier == EvqTemporary || qualifier == EvqGlobal || qualifier == EvqConst ||
4111            (qualifier == EvqUniform && profile != EEsProfile && version >= 120))) {
4112         error(loc, " cannot initialize this type of qualifier ", variable->getType().getStorageQualifierString(), "");
4113         return 0;
4114     }
4115     arrayObjectCheck(loc, variable->getType(), "array initializer");
4116
4117     //
4118     // If the initializer was from braces { ... }, we convert the whole subtree to a
4119     // constructor-style subtree, allowing the rest of the code to operate
4120     // identically for both kinds of initializers.
4121     //
4122     initializer = convertInitializerList(loc, variable->getType(), initializer);
4123     if (! initializer) {
4124         // error recovery; don't leave const without constant values
4125         if (qualifier == EvqConst)
4126             variable->getWritableType().getQualifier().storage = EvqTemporary;
4127         return 0;
4128     }
4129
4130     // Fix arrayness if variable is unsized, getting size from the initializer
4131     if (initializer->getType().isArray() && initializer->getType().isExplicitlySizedArray() &&
4132         variable->getType().isImplicitlySizedArray())
4133         variable->getWritableType().changeArraySize(initializer->getType().getArraySize());
4134
4135     // Uniform and global consts require a constant initializer
4136     if (qualifier == EvqUniform && initializer->getType().getQualifier().storage != EvqConst) {
4137         error(loc, "uniform initializers must be constant", "=", "'%s'", variable->getType().getCompleteString().c_str());
4138         variable->getWritableType().getQualifier().storage = EvqTemporary;
4139         return 0;
4140     }
4141     if (qualifier == EvqConst && symbolTable.atGlobalLevel() && initializer->getType().getQualifier().storage != EvqConst) {
4142         error(loc, "global const initializers must be constant", "=", "'%s'", variable->getType().getCompleteString().c_str());
4143         variable->getWritableType().getQualifier().storage = EvqTemporary;
4144         return 0;
4145     }
4146
4147     // Const variables require a constant initializer, depending on version
4148     if (qualifier == EvqConst) {
4149         if (initializer->getType().getQualifier().storage != EvqConst) {
4150             const char* initFeature = "non-constant initializer";
4151             requireProfile(loc, ~EEsProfile, initFeature);
4152             profileRequires(loc, ~EEsProfile, 420, GL_ARB_shading_language_420pack, initFeature);
4153             variable->getWritableType().getQualifier().storage = EvqConstReadOnly;
4154             qualifier = EvqConstReadOnly;
4155         }
4156     } else {
4157         // Non-const global variables in ES need a const initializer.
4158         //
4159         // "In declarations of global variables with no storage qualifier or with a const
4160         // qualifier any initializer must be a constant expression."
4161         if (symbolTable.atGlobalLevel() && initializer->getType().getQualifier().storage != EvqConst) {
4162             const char* initFeature = "non-constant global initializer";
4163             requireProfile(loc, ~EEsProfile, initFeature);
4164         }
4165     }
4166
4167     if (qualifier == EvqConst || qualifier == EvqUniform) {
4168         // Compile-time tagging of the variable with it's constant value...
4169
4170         initializer = intermediate.addConversion(EOpAssign, variable->getType(), initializer);
4171         if (! initializer || ! initializer->getAsConstantUnion() || variable->getType() != initializer->getType()) {
4172             error(loc, "non-matching or non-convertible constant type for const initializer",
4173                   variable->getType().getStorageQualifierString(), "");
4174             variable->getWritableType().getQualifier().storage = EvqTemporary;
4175             return 0;
4176         }
4177
4178         variable->setConstArray(initializer->getAsConstantUnion()->getConstArray());
4179     } else {
4180         // normal assigning of a value to a variable...
4181         TIntermSymbol* intermSymbol = intermediate.addSymbol(*variable, loc);
4182         TIntermNode* initNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, loc);
4183         if (! initNode)
4184             assignError(loc, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
4185
4186         return initNode;
4187     }
4188
4189     return 0;
4190 }
4191
4192 //
4193 // Reprocess any initializer-list { ... } parts of the initializer.
4194 // Need to heirarchically assign correct types and implicit
4195 // conversions. Will do this mimicking the same process used for
4196 // creating a constructor-style initializer, ensuring we get the
4197 // same form.
4198 //
4199 TIntermTyped* TParseContext::convertInitializerList(TSourceLoc loc, const TType& type, TIntermTyped* initializer)
4200 {
4201     // Will operate recursively.  Once a subtree is found that is constructor style,
4202     // everything below it is already good: Only the "top part" of the initializer
4203     // can be an initializer list, where "top part" can extend for several (or all) levels.
4204
4205     // see if we have bottomed out in the tree within the initializer-list part
4206     TIntermAggregate* initList = initializer->getAsAggregate();
4207     if (! initList || initList->getOp() != EOpNull)
4208         return initializer;
4209
4210     // Of the initializer-list set of nodes, need to process bottom up,
4211     // so recurse deep, then process on the way up.
4212
4213     // Go down the tree here...
4214     if (type.isArray()) {
4215         // The type's array might be unsized, which could be okay, so base sizes on the size of the aggregate.
4216         // Later on, initializer execution code will deal with array size logic.
4217         TType arrayType;
4218         arrayType.shallowCopy(type);
4219         arrayType.setArraySizes(type);
4220         arrayType.changeArraySize((int)initList->getSequence().size());
4221         TType elementType(arrayType, 0); // dereferenced type
4222         for (size_t i = 0; i < initList->getSequence().size(); ++i) {
4223             initList->getSequence()[i] = convertInitializerList(loc, elementType, initList->getSequence()[i]->getAsTyped());
4224             if (initList->getSequence()[i] == 0)
4225                 return 0;
4226         }
4227
4228         return addConstructor(loc, initList, arrayType, mapTypeToConstructorOp(arrayType));
4229     } else if (type.isStruct()) {
4230         if (type.getStruct()->size() != initList->getSequence().size()) {
4231             error(loc, "wrong number of structure members", "initializer list", "");
4232             return 0;
4233         }
4234         for (size_t i = 0; i < type.getStruct()->size(); ++i) {
4235             initList->getSequence()[i] = convertInitializerList(loc, *(*type.getStruct())[i].type, initList->getSequence()[i]->getAsTyped());
4236             if (initList->getSequence()[i] == 0)
4237                 return 0;
4238         }
4239     } else if (type.isMatrix()) {
4240         if (type.getMatrixCols() != (int)initList->getSequence().size()) {
4241             error(loc, "wrong number of matrix columns:", "initializer list", type.getCompleteString().c_str());
4242             return 0;
4243         }
4244         TType vectorType(type, 0); // dereferenced type
4245         for (int i = 0; i < type.getMatrixCols(); ++i) {
4246             initList->getSequence()[i] = convertInitializerList(loc, vectorType, initList->getSequence()[i]->getAsTyped());
4247             if (initList->getSequence()[i] == 0)
4248                 return 0;
4249         }
4250     } else if (type.isVector()) {
4251         if (type.getVectorSize() != (int)initList->getSequence().size()) {
4252             error(loc, "wrong vector size (or rows in a matrix column):", "initializer list", type.getCompleteString().c_str());
4253             return 0;
4254         }
4255     } else {
4256         error(loc, "unexpected initializer-list type:", "initializer list", type.getCompleteString().c_str());
4257         return 0;
4258     }
4259
4260     // now that the subtree is processed, process this node
4261     return addConstructor(loc, initList, type, mapTypeToConstructorOp(type));
4262 }
4263
4264 //
4265 // Test for the correctness of the parameters passed to various constructor functions
4266 // and also convert them to the right data type, if allowed and required.
4267 //
4268 // Returns 0 for an error or the constructed node (aggregate or typed) for no error.
4269 //
4270 TIntermTyped* TParseContext::addConstructor(TSourceLoc loc, TIntermNode* node, const TType& type, TOperator op)
4271 {
4272     if (node == 0 || node->getAsTyped() == 0)
4273         return 0;
4274     rValueErrorCheck(loc, "constructor", node->getAsTyped());
4275
4276     TIntermAggregate* aggrNode = node->getAsAggregate();
4277
4278     TTypeList::const_iterator memberTypes;
4279     if (op == EOpConstructStruct)
4280         memberTypes = type.getStruct()->begin();
4281
4282     TType elementType;
4283     elementType.shallowCopy(type);
4284     if (type.isArray())
4285         elementType.dereference();
4286
4287     bool singleArg;
4288     if (aggrNode) {
4289         if (aggrNode->getOp() != EOpNull || aggrNode->getSequence().size() == 1)
4290             singleArg = true;
4291         else
4292             singleArg = false;
4293     } else
4294         singleArg = true;
4295
4296     TIntermTyped *newNode;
4297     if (singleArg) {
4298         // If structure constructor or array constructor is being called
4299         // for only one parameter inside the structure, we need to call constructStruct function once.
4300         if (type.isArray())
4301             newNode = constructStruct(node, elementType, 1, node->getLoc());
4302         else if (op == EOpConstructStruct)
4303             newNode = constructStruct(node, *(*memberTypes).type, 1, node->getLoc());
4304         else
4305             newNode = constructBuiltIn(type, op, node->getAsTyped(), node->getLoc(), false);
4306
4307         if (newNode && (type.isArray() || op == EOpConstructStruct))
4308             newNode = intermediate.setAggregateOperator(newNode, EOpConstructStruct, type, loc);
4309
4310         return newNode;
4311     }
4312
4313     //
4314     // Handle list of arguments.
4315     //
4316     TIntermSequence &sequenceVector = aggrNode->getSequence();    // Stores the information about the parameter to the constructor
4317     // if the structure constructor contains more than one parameter, then construct
4318     // each parameter
4319
4320     int paramCount = 0;  // keeps a track of the constructor parameter number being checked
4321
4322     // for each parameter to the constructor call, check to see if the right type is passed or convert them
4323     // to the right type if possible (and allowed).
4324     // for structure constructors, just check if the right type is passed, no conversion is allowed.
4325
4326     for (TIntermSequence::iterator p = sequenceVector.begin();
4327                                    p != sequenceVector.end(); p++, paramCount++) {
4328         if (type.isArray())
4329             newNode = constructStruct(*p, elementType, paramCount+1, node->getLoc());
4330         else if (op == EOpConstructStruct)
4331             newNode = constructStruct(*p, *(memberTypes[paramCount]).type, paramCount+1, node->getLoc());
4332         else
4333             newNode = constructBuiltIn(type, op, (*p)->getAsTyped(), node->getLoc(), true);
4334
4335         if (newNode)
4336             *p = newNode;
4337         else
4338             return 0;
4339     }
4340
4341     TIntermTyped* constructor = intermediate.setAggregateOperator(aggrNode, op, type, loc);
4342
4343     return constructor;
4344 }
4345
4346 // Function for constructor implementation. Calls addUnaryMath with appropriate EOp value
4347 // for the parameter to the constructor (passed to this function). Essentially, it converts
4348 // the parameter types correctly. If a constructor expects an int (like ivec2) and is passed a
4349 // float, then float is converted to int.
4350 //
4351 // Returns 0 for an error or the constructed node.
4352 //
4353 TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermTyped* node, TSourceLoc loc, bool subset)
4354 {
4355     TIntermTyped* newNode;
4356     TOperator basicOp;
4357
4358     //
4359     // First, convert types as needed.
4360     //
4361     switch (op) {
4362     case EOpConstructVec2:
4363     case EOpConstructVec3:
4364     case EOpConstructVec4:
4365     case EOpConstructMat2x2:
4366     case EOpConstructMat2x3:
4367     case EOpConstructMat2x4:
4368     case EOpConstructMat3x2:
4369     case EOpConstructMat3x3:
4370     case EOpConstructMat3x4:
4371     case EOpConstructMat4x2:
4372     case EOpConstructMat4x3:
4373     case EOpConstructMat4x4:
4374     case EOpConstructFloat:
4375         basicOp = EOpConstructFloat;
4376         break;
4377
4378     case EOpConstructDVec2:
4379     case EOpConstructDVec3:
4380     case EOpConstructDVec4:
4381     case EOpConstructDMat2x2:
4382     case EOpConstructDMat2x3:
4383     case EOpConstructDMat2x4:
4384     case EOpConstructDMat3x2:
4385     case EOpConstructDMat3x3:
4386     case EOpConstructDMat3x4:
4387     case EOpConstructDMat4x2:
4388     case EOpConstructDMat4x3:
4389     case EOpConstructDMat4x4:
4390     case EOpConstructDouble:
4391         basicOp = EOpConstructDouble;
4392         break;
4393
4394     case EOpConstructIVec2:
4395     case EOpConstructIVec3:
4396     case EOpConstructIVec4:
4397     case EOpConstructInt:
4398         basicOp = EOpConstructInt;
4399         break;
4400
4401     case EOpConstructUVec2:
4402     case EOpConstructUVec3:
4403     case EOpConstructUVec4:
4404     case EOpConstructUint:
4405         basicOp = EOpConstructUint;
4406         break;
4407
4408     case EOpConstructBVec2:
4409     case EOpConstructBVec3:
4410     case EOpConstructBVec4:
4411     case EOpConstructBool:
4412         basicOp = EOpConstructBool;
4413         break;
4414
4415     default:
4416         error(loc, "unsupported construction", "", "");
4417
4418         return 0;
4419     }
4420     newNode = intermediate.addUnaryMath(basicOp, node, node->getLoc());
4421     if (newNode == 0) {
4422         error(loc, "can't convert", "constructor", "");
4423         return 0;
4424     }
4425
4426     //
4427     // Now, if there still isn't an operation to do the construction, and we need one, add one.
4428     //
4429
4430     // Otherwise, skip out early.
4431     if (subset || (newNode != node && newNode->getType() == type))
4432         return newNode;
4433
4434     // setAggregateOperator will insert a new node for the constructor, as needed.
4435     return intermediate.setAggregateOperator(newNode, op, type, loc);
4436 }
4437
4438 // This function tests for the type of the parameters to the structures constructors. Raises
4439 // an error message if the expected type does not match the parameter passed to the constructor.
4440 //
4441 // Returns 0 for an error or the input node itself if the expected and the given parameter types match.
4442 //
4443 TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& type, int paramCount, TSourceLoc loc)
4444 {
4445     TIntermTyped* converted = intermediate.addConversion(EOpConstructStruct, type, node->getAsTyped());
4446     if (! converted || converted->getType() != type) {
4447         error(loc, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount,
4448               node->getAsTyped()->getType().getCompleteString().c_str(), type.getCompleteString().c_str());
4449
4450         return 0;
4451     }
4452
4453     return converted;
4454 }
4455
4456 //
4457 // Do everything needed to add an interface block.
4458 //
4459 void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TString* instanceName, TArraySizes* arraySizes)
4460 {
4461     if (profile == EEsProfile && arraySizes)
4462         arraySizeRequiredCheck(loc, arraySizes->getSize());
4463
4464     switch (currentBlockQualifier.storage) {
4465     case EvqUniform:
4466         profileRequires(loc, EEsProfile, 300, 0, "uniform block");
4467         profileRequires(loc, ENoProfile, 140, 0, "uniform block");
4468         break;
4469     case EvqBuffer:
4470         requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "buffer block");
4471         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, 0, "buffer block");
4472         profileRequires(loc, EEsProfile, 310, 0, "buffer block");
4473         break;
4474     case EvqVaryingIn:
4475         requireProfile(loc, ~EEsProfile, "input block");
4476         profileRequires(loc, ~EEsProfile, 150, GL_ARB_separate_shader_objects, "input block");
4477         if (language == EShLangVertex)
4478             error(loc, "cannot declare an input block in a vertex shader", "in", "");
4479         break;
4480     case EvqVaryingOut:
4481         requireProfile(loc, ~EEsProfile, "output block");
4482         profileRequires(loc, ~EEsProfile, 150, GL_ARB_separate_shader_objects, "output block");
4483         if (language == EShLangFragment)
4484             error(loc, "cannot declare an output block in a fragment shader", "out", "");
4485         break;
4486     default:
4487         error(loc, "only uniform, buffer, in, or out blocks are supported", blockName->c_str(), "");
4488         return;
4489     }
4490
4491     arrayDimCheck(loc, arraySizes, 0);
4492
4493     // fix and check for member storage qualifiers and types that don't belong within a block
4494     for (unsigned int member = 0; member < typeList.size(); ++member) {
4495         TType& memberType = *typeList[member].type;
4496         TQualifier& memberQualifier = memberType.getQualifier();
4497         TSourceLoc memberLoc = typeList[member].loc;
4498         globalQualifierFixCheck(memberLoc, memberQualifier);
4499         if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal && memberQualifier.storage != currentBlockQualifier.storage)
4500             error(memberLoc, "member storage qualifier cannot contradict block storage qualifier", memberType.getFieldName().c_str(), "");
4501         memberQualifier.storage = currentBlockQualifier.storage;
4502         if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary()))
4503             error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), "");
4504         if (memberType.isRuntimeSizedArray() && member < typeList.size() - 1)
4505             error(memberLoc, "only the last member of a buffer block can be run-time sized", memberType.getFieldName().c_str(), "");
4506         if (memberType.isImplicitlySizedArray())
4507             requireProfile(memberLoc, ~EEsProfile, "implicitly-sized array in a block");
4508         if (memberQualifier.hasOffset()) {
4509             requireProfile(memberLoc, ~EEsProfile, "offset on block member");
4510             profileRequires(memberLoc, ~EEsProfile, 440, GL_ARB_enhanced_layouts, "offset on block member");
4511         }
4512
4513         TBasicType basicType = memberType.getBasicType();
4514         if (basicType == EbtSampler)
4515             error(memberLoc, "member of block cannot be a sampler type", typeList[member].type->getFieldName().c_str(), "");
4516     }
4517
4518     // This might be a redeclaration of a built-in block.  If so, redeclareBuiltinBlock() will
4519     // do all the rest.
4520     if (! symbolTable.atBuiltInLevel() && builtInName(*blockName)) {
4521         redeclareBuiltinBlock(loc, typeList, *blockName, instanceName, arraySizes);
4522         return;
4523     }
4524
4525     // Not a redeclaration of a built-in; check that all names are user names.
4526     reservedErrorCheck(loc, *blockName);
4527     if (instanceName)
4528         reservedErrorCheck(loc, *instanceName);
4529     for (unsigned int member = 0; member < typeList.size(); ++member)
4530         reservedErrorCheck(typeList[member].loc, typeList[member].type->getFieldName());
4531
4532     // Make default block qualification, and adjust the member qualifications
4533
4534     TQualifier defaultQualification;
4535     switch (currentBlockQualifier.storage) {
4536     case EvqUniform:    defaultQualification = globalUniformDefaults;    break;
4537     case EvqBuffer:     defaultQualification = globalBufferDefaults;     break;
4538     case EvqVaryingIn:  defaultQualification = globalInputDefaults;      break;
4539     case EvqVaryingOut: defaultQualification = globalOutputDefaults;     break;
4540     default:            defaultQualification.clear();                    break;
4541     }
4542
4543     // fix and check for member layout qualifiers
4544
4545     mergeObjectLayoutQualifiers(defaultQualification, currentBlockQualifier, true);
4546
4547     // "The offset qualifier can only be used on block members of blocks declared with std140 or std430 layouts."
4548     // "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
4549     if (currentBlockQualifier.hasAlign() || currentBlockQualifier.hasAlign()) {
4550         if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430) {
4551             error(loc, "can only be used with std140 or std430 layout packing", "offset/align", "");
4552             defaultQualification.layoutAlign = -1;
4553         }
4554     }
4555
4556     bool memberWithLocation = false;
4557     bool memberWithoutLocation = false;
4558     for (unsigned int member = 0; member < typeList.size(); ++member) {
4559         TQualifier& memberQualifier = typeList[member].type->getQualifier();
4560         TSourceLoc memberLoc = typeList[member].loc;
4561         if (memberQualifier.hasStream()) {
4562             if (defaultQualification.layoutStream != memberQualifier.layoutStream)
4563                 error(memberLoc, "member cannot contradict block", "stream", "");
4564         }
4565
4566         // "This includes a block's inheritance of the 
4567         // current global default buffer, a block member's inheritance of the block's 
4568         // buffer, and the requirement that any *xfb_buffer* declared on a block 
4569         // member must match the buffer inherited from the block."
4570         if (memberQualifier.hasXfbBuffer()) {
4571             if (defaultQualification.layoutXfbBuffer != memberQualifier.layoutXfbBuffer)
4572                 error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_buffer", "");
4573         }
4574
4575         if (memberQualifier.hasPacking())
4576             error(memberLoc, "member of block cannot have a packing layout qualifier", typeList[member].type->getFieldName().c_str(), "");
4577         if (memberQualifier.hasLocation()) {
4578             const char* feature = "location on block member";
4579             switch (currentBlockQualifier.storage) {
4580             case EvqVaryingIn:
4581             case EvqVaryingOut:
4582                 requireProfile(memberLoc, ECoreProfile | ECompatibilityProfile, feature);
4583                 profileRequires(memberLoc, ECoreProfile | ECompatibilityProfile, 440, GL_ARB_enhanced_layouts, feature);
4584                 memberWithLocation = true;
4585                 break;
4586             default:
4587                 error(memberLoc, "can only use in an in/out block", feature, "");
4588                 break;
4589             }
4590         } else
4591             memberWithoutLocation = true;
4592         if (memberQualifier.hasAlign()) {
4593             if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430)
4594                 error(memberLoc, "can only be used with std140 or std430 layout packing", "align", "");
4595         }
4596
4597         TQualifier newMemberQualification = defaultQualification;
4598         mergeQualifiers(memberLoc, newMemberQualification, memberQualifier, false);
4599         memberQualifier = newMemberQualification;
4600     }
4601
4602     // Process the members
4603     fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation);
4604     fixBlockXfbOffsets(currentBlockQualifier, typeList);
4605     fixBlockUniformOffsets(currentBlockQualifier, typeList);
4606     for (unsigned int member = 0; member < typeList.size(); ++member)
4607         layoutTypeCheck(typeList[member].loc, *typeList[member].type);
4608
4609     // reverse merge, so that currentBlockQualifier now has all layout information
4610     // (can't use defaultQualification directly, it's missing other non-layout-default-class qualifiers)
4611     mergeObjectLayoutQualifiers(currentBlockQualifier, defaultQualification, true);
4612
4613     //
4614     // Build and add the interface block as a new type named 'blockName'
4615     //
4616
4617     TType blockType(&typeList, *blockName, currentBlockQualifier);
4618     if (arraySizes)
4619         blockType.setArraySizes(arraySizes);
4620     else
4621         ioArrayCheck(loc, blockType, instanceName ? *instanceName : *blockName);
4622
4623     //
4624     // Don't make a user-defined type out of block name; that will cause an error
4625     // if the same block name gets reused in a different interface.
4626     //
4627     // "Block names have no other use within a shader
4628     // beyond interface matching; it is a compile-time error to use a block name at global scope for anything
4629     // other than as a block name (e.g., use of a block name for a global variable name or function name is
4630     // currently reserved)."
4631     //
4632     // Use the symbol table to prevent normal reuse of the block's name, as a variable entry,
4633     // whose type is EbtBlock, but without all the structure; that will come from the type
4634     // the instances point to.
4635     //
4636     TType blockNameType(EbtBlock, blockType.getQualifier().storage);
4637     TVariable* blockNameVar = new TVariable(blockName, blockNameType);
4638     if (! symbolTable.insert(*blockNameVar)) {
4639         TSymbol* existingName = symbolTable.find(*blockName);
4640         if (existingName->getType().getBasicType() == EbtBlock) {
4641             if (existingName->getType().getQualifier().storage == blockType.getQualifier().storage) {
4642                 error(loc, "Cannot reuse block name within the same interface:", blockName->c_str(), blockType.getStorageQualifierString());
4643                 return;
4644             }
4645         } else {
4646             error(loc, "block name cannot redefine a non-block name", blockName->c_str(), "");
4647             return;
4648         }
4649     }
4650
4651     // Add the variable, as anonymous or named instanceName.
4652     // Make an anonymous variable if no name was provided.
4653     if (! instanceName)
4654         instanceName = NewPoolTString("");
4655
4656     TVariable& variable = *new TVariable(instanceName, blockType);
4657     if (! symbolTable.insert(variable)) {
4658         if (*instanceName == "")
4659             error(loc, "nameless block contains a member that already has a name at global scope", blockName->c_str(), "");
4660         else
4661             error(loc, "block instance name redefinition", variable.getName().c_str(), "");
4662
4663         return;
4664     }
4665
4666     // Check for general layout qualifier errors
4667     layoutObjectCheck(loc, variable);
4668
4669     if (isIoResizeArray(blockType)) {
4670         ioArraySymbolResizeList.push_back(&variable);
4671         checkIoArraysConsistency(loc, true);
4672     } else
4673         fixIoArraySize(loc, variable.getWritableType());
4674
4675     // Save it in the AST for linker use.
4676     intermediate.addSymbolLinkageNode(linkage, variable);
4677 }
4678
4679 //
4680 // "For a block, this process applies to the entire block, or until the first member 
4681 // is reached that has a location layout qualifier. When a block member is declared with a location 
4682 // qualifier, its location comes from that qualifier: The member's location qualifier overrides the block-level
4683 // declaration. Subsequent members are again assigned consecutive locations, based on the newest location, 
4684 // until the next member declared with a location qualifier. The values used for locations do not have to be 
4685 // declared in increasing order."
4686 void TParseContext::fixBlockLocations(TSourceLoc loc, TQualifier& qualifier, TTypeList& typeList, bool memberWithLocation, bool memberWithoutLocation)
4687 {
4688     // "If a block has no block-level location layout qualifier, it is required that either all or none of its members 
4689     // have a location layout qualifier, or a compile-time error results."
4690     if (! qualifier.hasLocation() && memberWithLocation && memberWithoutLocation)
4691         error(loc, "either the block needs a location, or all members need a location, or no members have a location", "location", "");
4692     else {
4693         if (memberWithLocation) {
4694             // remove any block-level location and make it per *every* member
4695             int nextLocation = 0;  // by the rule above, initial value is not relevant
4696             if (qualifier.hasAnyLocation()) {
4697                 nextLocation = qualifier.layoutLocation;
4698                 qualifier.layoutLocation = TQualifier::layoutLocationEnd;
4699                 if (qualifier.hasComponent()) {
4700                     // "It is a compile-time error to apply the *component* qualifier to a ... block"
4701                     error(loc, "cannot apply to a block", "component", "");
4702                 }
4703                 if (qualifier.hasIndex()) {
4704                     error(loc, "cannot apply to a block", "index", "");
4705                 }
4706             }
4707             for (unsigned int member = 0; member < typeList.size(); ++member) {
4708                 TQualifier& memberQualifier = typeList[member].type->getQualifier();
4709                 TSourceLoc memberLoc = typeList[member].loc;
4710                 if (! memberQualifier.hasLocation()) {
4711                     if (nextLocation >= TQualifier::layoutLocationEnd)
4712                         error(memberLoc, "location is too large", "location", "");
4713                     memberQualifier.layoutLocation = nextLocation;
4714                     memberQualifier.layoutComponent = 0;
4715                 }
4716                 nextLocation = memberQualifier.layoutLocation + intermediate.computeTypeLocationSize(*typeList[member].type);
4717             }
4718         }
4719     }
4720 }
4721
4722 void TParseContext::fixBlockXfbOffsets(TQualifier& qualifier, TTypeList& typeList)
4723 {
4724     // "If a block is qualified with xfb_offset, all its 
4725     // members are assigned transform feedback buffer offsets. If a block is not qualified with xfb_offset, any 
4726     // members of that block not qualified with an xfb_offset will not be assigned transform feedback buffer 
4727     // offsets."
4728
4729     if (! qualifier.hasXfbBuffer() || ! qualifier.hasXfbOffset())
4730         return;
4731
4732     int nextOffset = qualifier.layoutXfbOffset;
4733     for (unsigned int member = 0; member < typeList.size(); ++member) {
4734         TQualifier& memberQualifier = typeList[member].type->getQualifier();
4735         bool containsDouble = false;
4736         int memberSize = intermediate.computeTypeXfbSize(*typeList[member].type, containsDouble);
4737         // see if we need to auto-assign an offset to this member
4738         if (! memberQualifier.hasXfbOffset()) {
4739             // "if applied to an aggregate containing a double, the offset must also be a multiple of 8"
4740             if (containsDouble)
4741                 RoundToPow2(nextOffset, 8);
4742             memberQualifier.layoutXfbOffset = nextOffset;
4743         } else
4744             nextOffset = memberQualifier.layoutXfbOffset;
4745         nextOffset += memberSize;
4746     }
4747
4748     // The above gave all block members an offset, so we can take it off the block now,
4749     // which will avoid double counting the offset usage.
4750     qualifier.layoutXfbOffset = TQualifier::layoutXfbOffsetEnd;
4751 }
4752
4753 // Calculate and save the offset of each block member, using the recursively 
4754 // defined block offset rules and the user-provided offset and align.
4755 //
4756 // Also, compute and save the total size of the block. For the block's size, arrayness 
4757 // is not taken into account, as each element is backed by a separate buffer.
4758 //
4759 void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typeList)
4760 {
4761     if (! qualifier.isUniformOrBuffer())
4762         return;
4763     if (qualifier.layoutPacking != ElpStd140 && qualifier.layoutPacking != ElpStd430)
4764         return;
4765
4766     int offset = 0;
4767     int memberSize;
4768     for (unsigned int member = 0; member < typeList.size(); ++member) {
4769         TQualifier& memberQualifier = typeList[member].type->getQualifier();
4770         TSourceLoc memberLoc = typeList[member].loc;
4771
4772         // "When align is applied to an array, it effects only the start of the array, not the array's internal stride."
4773         
4774         int memberAlignment = intermediate.getBaseAlignment(*typeList[member].type, memberSize, qualifier.layoutPacking == ElpStd140);
4775         if (memberQualifier.hasOffset()) {
4776             // "The specified offset must be a multiple 
4777             // of the base alignment of the type of the block member it qualifies, or a compile-time error results."
4778             if (! IsMultipleOfPow2(memberQualifier.layoutOffset, memberAlignment))
4779                 error(memberLoc, "must be a multiple of the member's alignment", "offset", "");
4780
4781             // "It is a compile-time error to specify an offset that is smaller than the offset of the previous 
4782             // member in the block or that lies within the previous member of the block"
4783             if (memberQualifier.layoutOffset < offset)
4784                 error(memberLoc, "cannot lie in previous members", "offset", "");
4785
4786             // "The offset qualifier forces the qualified member to start at or after the specified 
4787             // integral-constant expression, which will be its byte offset from the beginning of the buffer. 
4788             // "The actual offset of a member is computed as 
4789             // follows: If offset was declared, start with that offset, otherwise start with the next available offset."
4790             offset = std::max(offset, memberQualifier.layoutOffset);
4791         }
4792
4793         // "The actual alignment of a member will be the greater of the specified align alignment and the standard 
4794         // (e.g., std140) base alignment for the member's type."
4795         if (memberQualifier.hasAlign())
4796             memberAlignment = std::max(memberAlignment, memberQualifier.layoutAlign);
4797
4798         // "If the resulting offset is not a multiple of the actual alignment,
4799         // increase it to the first offset that is a multiple of 
4800         // the actual alignment."
4801         RoundToPow2(offset, memberAlignment);
4802         typeList[member].type->getQualifier().layoutOffset = offset;
4803         offset += memberSize;
4804     }
4805 }
4806
4807 // For an identifier that is already declared, add more qualification to it.
4808 void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier, const TString& identifier)
4809 {
4810     TSymbol* symbol = symbolTable.find(identifier);
4811     if (! symbol) {
4812         error(loc, "identifier not previously declared", identifier.c_str(), "");
4813         return;
4814     }
4815     if (symbol->getAsFunction()) {
4816         error(loc, "cannot re-qualify a function name", identifier.c_str(), "");
4817         return;
4818     }
4819
4820     if (qualifier.isAuxiliary() ||
4821         qualifier.isMemory() ||
4822         qualifier.isInterpolation() ||
4823         qualifier.hasLayout() ||
4824         qualifier.storage != EvqTemporary ||
4825         qualifier.precision != EpqNone) {
4826         error(loc, "cannot add storage, auxiliary, memory, interpolation, layout, or precision qualifier to an existing variable", identifier.c_str(), "");
4827         return;
4828     }
4829
4830     // For read-only built-ins, add a new symbol for holding the modified qualifier.
4831     // This will bring up an entire block, if a block type has to be modified (e.g., gl_Position inside a block)
4832     if (symbol->isReadOnly())
4833         symbol = symbolTable.copyUp(symbol);
4834
4835     if (qualifier.invariant) {
4836         if (intermediate.inIoAccessed(identifier))
4837             error(loc, "cannot change qualification after use", "invariant", "");
4838         symbol->getWritableType().getQualifier().invariant = true;
4839         invariantCheck(loc, symbol->getType().getQualifier());
4840     } else
4841         warn(loc, "unknown requalification", "", "");
4842 }
4843
4844 void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier, TIdentifierList& identifiers)
4845 {
4846     for (unsigned int i = 0; i < identifiers.size(); ++i)
4847         addQualifierToExisting(loc, qualifier, *identifiers[i]);
4848 }
4849
4850 void TParseContext::invariantCheck(TSourceLoc loc, const TQualifier& qualifier)
4851 {
4852     if (! qualifier.invariant)
4853         return;
4854
4855     bool pipeOut = qualifier.isPipeOutput();
4856     bool pipeIn = qualifier.isPipeInput();
4857     if (version >= 300 || profile != EEsProfile && version >= 420) {
4858         if (! pipeOut)
4859             error(loc, "can only apply to an output", "invariant", "");
4860     } else {
4861         if ((language == EShLangVertex && pipeIn) || (! pipeOut && ! pipeIn))
4862             error(loc, "can only apply to an output, or to an input in a non-vertex stage\n", "invariant", "");
4863     }
4864 }
4865
4866 //
4867 // Updating default qualifier for the case of a declaration with just a qualifier,
4868 // no type, block, or identifier.
4869 //
4870 void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPublicType& publicType)
4871 {
4872     if (publicType.shaderQualifiers.vertices) {
4873         assert(language == EShLangTessControl || language == EShLangGeometry);
4874         const char* id = (language == EShLangTessControl) ? "vertices" : "max_vertices";
4875
4876         if (publicType.qualifier.storage != EvqVaryingOut)
4877             error(loc, "can only apply to 'out'", id, "");
4878         if (! intermediate.setVertices(publicType.shaderQualifiers.vertices))
4879             error(loc, "cannot change previously set layout value", id, "");
4880         
4881         if (language == EShLangTessControl)
4882             checkIoArraysConsistency(loc);
4883     }
4884     if (publicType.shaderQualifiers.invocations) {
4885         if (publicType.qualifier.storage != EvqVaryingIn)
4886             error(loc, "can only apply to 'in'", "invocations", "");
4887         if (! intermediate.setInvocations(publicType.shaderQualifiers.invocations))
4888             error(loc, "cannot change previously set layout value", "invocations", "");
4889     }
4890     if (publicType.shaderQualifiers.geometry != ElgNone) {
4891         if (publicType.qualifier.storage == EvqVaryingIn) {
4892             switch (publicType.shaderQualifiers.geometry) {
4893             case ElgPoints:
4894             case ElgLines:
4895             case ElgLinesAdjacency:
4896             case ElgTriangles:
4897             case ElgTrianglesAdjacency:
4898             case ElgQuads:
4899             case ElgIsolines:
4900                 if (intermediate.setInputPrimitive(publicType.shaderQualifiers.geometry)) {
4901                     if (language == EShLangGeometry)
4902                         checkIoArraysConsistency(loc);
4903                 } else
4904                     error(loc, "cannot change previously set input primitive", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
4905                 break;
4906             default:
4907                 error(loc, "cannot apply to input", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
4908             }
4909         } else if (publicType.qualifier.storage == EvqVaryingOut) {
4910             switch (publicType.shaderQualifiers.geometry) {
4911             case ElgPoints:
4912             case ElgLineStrip:
4913             case ElgTriangleStrip:
4914                 if (! intermediate.setOutputPrimitive(publicType.shaderQualifiers.geometry))
4915                     error(loc, "cannot change previously set output primitive", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
4916                 break;
4917             default:
4918                 error(loc, "cannot apply to 'out'", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
4919             }
4920         } else
4921             error(loc, "cannot apply to:", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), GetStorageQualifierString(publicType.qualifier.storage));
4922     }
4923     if (publicType.shaderQualifiers.spacing != EvsNone) {
4924         if (publicType.qualifier.storage == EvqVaryingIn) {
4925             if (! intermediate.setVertexSpacing(publicType.shaderQualifiers.spacing))
4926                 error(loc, "cannot change previously set vertex spacing", TQualifier::getVertexSpacingString(publicType.shaderQualifiers.spacing), "");
4927         } else
4928             error(loc, "can only apply to 'in'", TQualifier::getVertexSpacingString(publicType.shaderQualifiers.spacing), "");
4929     }
4930     if (publicType.shaderQualifiers.order != EvoNone) {
4931         if (publicType.qualifier.storage == EvqVaryingIn) {
4932             if (! intermediate.setVertexOrder(publicType.shaderQualifiers.order))
4933                 error(loc, "cannot change previously set vertex order", TQualifier::getVertexOrderString(publicType.shaderQualifiers.order), "");
4934         } else
4935             error(loc, "can only apply to 'in'", TQualifier::getVertexOrderString(publicType.shaderQualifiers.order), "");
4936     }
4937     if (publicType.shaderQualifiers.pointMode) {
4938         if (publicType.qualifier.storage == EvqVaryingIn)
4939             intermediate.setPointMode();
4940         else
4941             error(loc, "can only apply to 'in'", "point_mode", "");
4942     }
4943     for (int i = 0; i < 3; ++i) {
4944         if (publicType.shaderQualifiers.localSize[i] > 1) {
4945             if (publicType.qualifier.storage == EvqVaryingIn) {
4946                 if (! intermediate.setLocalSize(i, publicType.shaderQualifiers.localSize[i]))
4947                     error(loc, "cannot change previously set size", "local_size", "");
4948                 else {
4949                     int max = 0;
4950                     switch (i) {
4951                     case 0: max = resources.maxComputeWorkGroupSizeX; break;
4952                     case 1: max = resources.maxComputeWorkGroupSizeY; break;
4953                     case 2: max = resources.maxComputeWorkGroupSizeZ; break;
4954                     default: break;
4955                     }
4956                     if (intermediate.getLocalSize(i) > (unsigned int)max)
4957                         error(loc, "too large; see gl_MaxComputeWorkGroupSize", "local_size", "");
4958
4959                     // Fix the existing constant gl_WorkGroupSize with this new information.
4960                     bool builtIn;
4961                     TSymbol* symbol = symbolTable.find("gl_WorkGroupSize", &builtIn);
4962                     if (builtIn)
4963                         makeEditable(symbol);
4964                     TVariable* workGroupSize = symbol->getAsVariable();
4965                     workGroupSize->getWritableConstArray()[i].setUConst(intermediate.getLocalSize(i));
4966                 }
4967             } else
4968                 error(loc, "can only apply to 'in'", "local_size", "");
4969         }
4970     }
4971     if (publicType.shaderQualifiers.earlyFragmentTests) {
4972         if (publicType.qualifier.storage == EvqVaryingIn)
4973             intermediate.setEarlyFragmentTests();
4974         else
4975             error(loc, "can only apply to 'in'", "early_fragment_tests", "");
4976     }
4977
4978     const TQualifier& qualifier = publicType.qualifier;
4979
4980     if (qualifier.isAuxiliary() ||
4981         qualifier.isMemory() ||
4982         qualifier.isInterpolation() ||
4983         qualifier.precision != EpqNone)
4984         error(loc, "cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type)", "qualifier", "");
4985     // "The offset qualifier can only be used on block members of blocks..."
4986     // "The align qualifier can only be used on blocks or block members..."
4987     if (qualifier.hasOffset() ||
4988         qualifier.hasAlign())
4989         error(loc, "cannot use offset or align qualifiers in a default qualifier declaration (declaration with no type)", "layout qualifier", "");
4990
4991     layoutQualifierCheck(loc, qualifier);
4992
4993     switch (qualifier.storage) {
4994     case EvqUniform:
4995         if (qualifier.hasMatrix())
4996             globalUniformDefaults.layoutMatrix = qualifier.layoutMatrix;
4997         if (qualifier.hasPacking())
4998             globalUniformDefaults.layoutPacking = qualifier.layoutPacking;
4999         break;
5000     case EvqBuffer:
5001         if (qualifier.hasMatrix())
5002             globalBufferDefaults.layoutMatrix = qualifier.layoutMatrix;
5003         if (qualifier.hasPacking())
5004             globalBufferDefaults.layoutPacking = qualifier.layoutPacking;
5005         break;
5006     case EvqVaryingIn:
5007         break;
5008     case EvqVaryingOut:
5009         if (qualifier.hasStream())
5010             globalOutputDefaults.layoutStream = qualifier.layoutStream;
5011         if (qualifier.hasXfbBuffer())
5012             globalOutputDefaults.layoutXfbBuffer = qualifier.layoutXfbBuffer;
5013         if (globalOutputDefaults.hasXfbBuffer() && qualifier.hasXfbStride()) {
5014             if (! intermediate.setXfbBufferStride(globalOutputDefaults.layoutXfbBuffer, qualifier.layoutXfbStride))
5015                 error(loc, "all stride settings must match for xfb buffer", "xfb_stride", "%d", qualifier.layoutXfbBuffer);
5016         }
5017         break;
5018     default:
5019         error(loc, "default qualifier requires 'uniform', 'buffer', 'in', or 'out' storage qualification", "", "");
5020         return;
5021     }
5022
5023     if (qualifier.hasBinding())
5024         error(loc, "cannot declare a default, include a type or full declaration", "binding", "");
5025     if (qualifier.hasAnyLocation())
5026         error(loc, "cannot declare a default, use a full declaration", "location/component/index", "");
5027     if (qualifier.hasXfbOffset())
5028         error(loc, "cannot declare a default, use a full declaration", "xfb_offset", "");
5029 }
5030
5031 //
5032 // Take the sequence of statements that has been built up since the last case/default,
5033 // put it on the list of top-level nodes for the current (inner-most) switch statement,
5034 // and follow that by the case/default we are on now.  (See switch topology comment on
5035 // TIntermSwitch.)
5036 //
5037 void TParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode)
5038 {
5039     TIntermSequence* switchSequence = switchSequenceStack.back();
5040
5041     if (statements) {
5042         if (switchSequence->size() == 0)
5043             error(statements->getLoc(), "cannot have statements before first case/default label", "switch", "");
5044         statements->setOperator(EOpSequence);
5045         switchSequence->push_back(statements);
5046     }
5047     if (branchNode) {
5048         // check all previous cases for the same label (or both are 'default')
5049         for (unsigned int s = 0; s < switchSequence->size(); ++s) {
5050             TIntermBranch* prevBranch = (*switchSequence)[s]->getAsBranchNode();
5051             if (prevBranch) {
5052                 TIntermTyped* prevExpression = prevBranch->getExpression();
5053                 TIntermTyped* newExpression = branchNode->getAsBranchNode()->getExpression();
5054                 if (prevExpression == 0 && newExpression == 0)
5055                     error(branchNode->getLoc(), "duplicate label", "default", "");
5056                 else if (prevExpression != 0 &&
5057                           newExpression != 0 &&
5058                          prevExpression->getAsConstantUnion() &&
5059                           newExpression->getAsConstantUnion() &&
5060                          prevExpression->getAsConstantUnion()->getConstArray()[0].getIConst() ==
5061                           newExpression->getAsConstantUnion()->getConstArray()[0].getIConst())
5062                     error(branchNode->getLoc(), "duplicated value", "case", "");
5063             }
5064         }
5065         switchSequence->push_back(branchNode);
5066     }
5067 }
5068
5069 //
5070 // Turn the top-level node sequence built up of wrapupSwitchSubsequence9)
5071 // into a switch node.
5072 //
5073 TIntermNode* TParseContext::addSwitch(TSourceLoc loc, TIntermTyped* expression, TIntermAggregate* lastStatements)
5074 {
5075     profileRequires(loc, EEsProfile, 300, 0, "switch statements");
5076     profileRequires(loc, ENoProfile, 130, 0, "switch statements");
5077
5078     wrapupSwitchSubsequence(lastStatements, 0);
5079
5080     if (expression == 0 ||
5081         (expression->getBasicType() != EbtInt && expression->getBasicType() != EbtUint) ||
5082         expression->getType().isArray() || expression->getType().isMatrix() || expression->getType().isVector())
5083             error(loc, "condition must be a scalar integer expression", "switch", "");
5084
5085     // If there is nothing to do, drop the switch but still execute the expression
5086     TIntermSequence* switchSequence = switchSequenceStack.back();
5087     if (switchSequence->size() == 0)
5088         return expression;
5089
5090     if (lastStatements == 0)
5091         warn(loc, "last case/default label not followed by statements", "switch", "");
5092
5093     TIntermAggregate* body = new TIntermAggregate(EOpSequence);
5094     body->getSequence() = *switchSequenceStack.back();
5095     body->setLoc(loc);
5096
5097     TIntermSwitch* switchNode = new TIntermSwitch(expression, body);
5098     switchNode->setLoc(loc);
5099
5100     return switchNode;
5101 }
5102
5103 } // end namespace glslang