8016e2ea41230b62cf752e2515c149ca882bf638
[platform/upstream/glslang.git] / glslang / MachineIndependent / ParseHelper.cpp
1 //
2 // Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
3 // Copyright (C) 2012-2015 LunarG, Inc.
4 // Copyright (C) 2015-2016 Google, Inc.
5 //
6 // All rights reserved.
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions
10 // are met:
11 //
12 //    Redistributions of source code must retain the above copyright
13 //    notice, this list of conditions and the following disclaimer.
14 //
15 //    Redistributions in binary form must reproduce the above
16 //    copyright notice, this list of conditions and the following
17 //    disclaimer in the documentation and/or other materials provided
18 //    with the distribution.
19 //
20 //    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
21 //    contributors may be used to endorse or promote products derived
22 //    from this software without specific prior written permission.
23 //
24 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 // POSSIBILITY OF SUCH DAMAGE.
36 //
37
38 #include "ParseHelper.h"
39 #include "Scan.h"
40
41 #include "../OSDependent/osinclude.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& symbolTable, TIntermediate& interm, bool parsingBuiltins,
51                              int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language,
52                              TInfoSink& infoSink, bool forwardCompatible, EShMessages messages,
53                              const TString* entryPoint) :
54             TParseContextBase(symbolTable, interm, parsingBuiltins, version, profile, spvVersion, language,
55                               infoSink, forwardCompatible, messages, entryPoint),
56             inMain(false),
57             blockName(nullptr),
58             limits(resources.limits),
59             atomicUintOffsets(nullptr), anyIndexLimits(false)
60 {
61     // decide whether precision qualifiers should be ignored or respected
62     if (profile == EEsProfile || spvVersion.vulkan > 0) {
63         precisionManager.respectPrecisionQualifiers();
64         if (! parsingBuiltins && language == EShLangFragment && profile != EEsProfile && spvVersion.vulkan > 0)
65             precisionManager.warnAboutDefaults();
66     }
67
68     setPrecisionDefaults();
69
70     globalUniformDefaults.clear();
71     globalUniformDefaults.layoutMatrix = ElmColumnMajor;
72     globalUniformDefaults.layoutPacking = spvVersion.spv != 0 ? ElpStd140 : ElpShared;
73
74     globalBufferDefaults.clear();
75     globalBufferDefaults.layoutMatrix = ElmColumnMajor;
76     globalBufferDefaults.layoutPacking = spvVersion.spv != 0 ? ElpStd430 : ElpShared;
77
78     globalInputDefaults.clear();
79     globalOutputDefaults.clear();
80
81     // "Shaders in the transform
82     // feedback capturing mode have an initial global default of
83     //     layout(xfb_buffer = 0) out;"
84     if (language == EShLangVertex ||
85         language == EShLangTessControl ||
86         language == EShLangTessEvaluation ||
87         language == EShLangGeometry)
88         globalOutputDefaults.layoutXfbBuffer = 0;
89
90     if (language == EShLangGeometry)
91         globalOutputDefaults.layoutStream = 0;
92
93     if (entryPoint != nullptr && entryPoint->size() > 0 && *entryPoint != "main")
94         infoSink.info.message(EPrefixError, "Source entry point must be \"main\"");
95 }
96
97 TParseContext::~TParseContext()
98 {
99     delete [] atomicUintOffsets;
100 }
101
102 // Set up all default precisions as needed by the current environment.
103 // Intended just as a TParseContext constructor helper.
104 void TParseContext::setPrecisionDefaults()
105 {
106     // Set all precision defaults to EpqNone, which is correct for all types
107     // when not obeying precision qualifiers, and correct for types that don't
108     // have defaults (thus getting an error on use) when obeying precision
109     // qualifiers.
110
111     for (int type = 0; type < EbtNumTypes; ++type)
112         defaultPrecision[type] = EpqNone;
113
114     for (int type = 0; type < maxSamplerIndex; ++type)
115         defaultSamplerPrecision[type] = EpqNone;
116
117     // replace with real precision defaults for those that have them
118     if (obeyPrecisionQualifiers()) {
119         if (profile == EEsProfile) {
120             // Most don't have defaults, a few default to lowp.
121             TSampler sampler;
122             sampler.set(EbtFloat, Esd2D);
123             defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow;
124             sampler.set(EbtFloat, EsdCube);
125             defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow;
126             sampler.set(EbtFloat, Esd2D);
127             sampler.external = true;
128             defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow;
129         }
130
131         // If we are parsing built-in computational variables/functions, it is meaningful to record
132         // whether the built-in has no precision qualifier, as that ambiguity
133         // is used to resolve the precision from the supplied arguments/operands instead.
134         // So, we don't actually want to replace EpqNone with a default precision for built-ins.
135         if (! parsingBuiltins) {
136             if (profile == EEsProfile && language == EShLangFragment) {
137                 defaultPrecision[EbtInt] = EpqMedium;
138                 defaultPrecision[EbtUint] = EpqMedium;
139             } else {
140                 defaultPrecision[EbtInt] = EpqHigh;
141                 defaultPrecision[EbtUint] = EpqHigh;
142                 defaultPrecision[EbtFloat] = EpqHigh;
143             }
144
145             if (profile != EEsProfile) {
146                 // Non-ES profile
147                 // All sampler precisions default to highp.
148                 for (int type = 0; type < maxSamplerIndex; ++type)
149                     defaultSamplerPrecision[type] = EpqHigh;
150             }
151         }
152
153         defaultPrecision[EbtSampler] = EpqLow;
154         defaultPrecision[EbtAtomicUint] = EpqHigh;
155     }
156 }
157
158 void TParseContext::setLimits(const TBuiltInResource& r)
159 {
160     resources = r;
161
162     anyIndexLimits = ! limits.generalAttributeMatrixVectorIndexing ||
163                      ! limits.generalConstantMatrixVectorIndexing ||
164                      ! limits.generalSamplerIndexing ||
165                      ! limits.generalUniformIndexing ||
166                      ! limits.generalVariableIndexing ||
167                      ! limits.generalVaryingIndexing;
168
169     intermediate.setLimits(resources);
170
171     // "Each binding point tracks its own current default offset for
172     // inheritance of subsequent variables using the same binding. The initial state of compilation is that all
173     // binding points have an offset of 0."
174     atomicUintOffsets = new int[resources.maxAtomicCounterBindings];
175     for (int b = 0; b < resources.maxAtomicCounterBindings; ++b)
176         atomicUintOffsets[b] = 0;
177 }
178
179 //
180 // Parse an array of strings using yyparse, going through the
181 // preprocessor to tokenize the shader strings, then through
182 // the GLSL scanner.
183 //
184 // Returns true for successful acceptance of the shader, false if any errors.
185 //
186 bool TParseContext::parseShaderStrings(TPpContext& ppContext, TInputScanner& input, bool versionWillBeError)
187 {
188     currentScanner = &input;
189     ppContext.setInput(input, versionWillBeError);
190     yyparse(this);
191
192     finish();
193
194     return numErrors == 0;
195 }
196
197 // This is called from bison when it has a parse (syntax) error
198 // Note though that to stop cascading errors, we set EOF, which
199 // will usually cause a syntax error, so be more accurate that
200 // compilation is terminating.
201 void TParseContext::parserError(const char* s)
202 {
203     if (! getScanner()->atEndOfInput() || numErrors == 0)
204         error(getCurrentLoc(), "", "", s, "");
205     else
206         error(getCurrentLoc(), "compilation terminated", "", "");
207 }
208
209 void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>& tokens)
210 {
211     if (pragmaCallback)
212         pragmaCallback(loc.line, tokens);
213
214     if (tokens.size() == 0)
215         return;
216
217     if (tokens[0].compare("optimize") == 0) {
218         if (tokens.size() != 4) {
219             error(loc, "optimize pragma syntax is incorrect", "#pragma", "");
220             return;
221         }
222
223         if (tokens[1].compare("(") != 0) {
224             error(loc, "\"(\" expected after 'optimize' keyword", "#pragma", "");
225             return;
226         }
227
228         if (tokens[2].compare("on") == 0)
229             contextPragma.optimize = true;
230         else if (tokens[2].compare("off") == 0)
231             contextPragma.optimize = false;
232         else {
233             error(loc, "\"on\" or \"off\" expected after '(' for 'optimize' pragma", "#pragma", "");
234             return;
235         }
236
237         if (tokens[3].compare(")") != 0) {
238             error(loc, "\")\" expected to end 'optimize' pragma", "#pragma", "");
239             return;
240         }
241     } else if (tokens[0].compare("debug") == 0) {
242         if (tokens.size() != 4) {
243             error(loc, "debug pragma syntax is incorrect", "#pragma", "");
244             return;
245         }
246
247         if (tokens[1].compare("(") != 0) {
248             error(loc, "\"(\" expected after 'debug' keyword", "#pragma", "");
249             return;
250         }
251
252         if (tokens[2].compare("on") == 0)
253             contextPragma.debug = true;
254         else if (tokens[2].compare("off") == 0)
255             contextPragma.debug = false;
256         else {
257             error(loc, "\"on\" or \"off\" expected after '(' for 'debug' pragma", "#pragma", "");
258             return;
259         }
260
261         if (tokens[3].compare(")") != 0) {
262             error(loc, "\")\" expected to end 'debug' pragma", "#pragma", "");
263             return;
264         }
265     } else if (spvVersion.spv > 0 && tokens[0].compare("use_storage_buffer") == 0) {
266         if (tokens.size() != 1)
267             error(loc, "extra tokens", "#pragma", "");
268         intermediate.setUseStorageBuffer();
269     } else if (tokens[0].compare("once") == 0) {
270         warn(loc, "not implemented", "#pragma once", "");
271     }
272 }
273
274 //
275 // Handle seeing a variable identifier in the grammar.
276 //
277 TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symbol, const TString* string)
278 {
279     TIntermTyped* node = nullptr;
280
281     // Error check for requiring specific extensions present.
282     if (symbol && symbol->getNumExtensions())
283         requireExtensions(loc, symbol->getNumExtensions(), symbol->getExtensions(), symbol->getName().c_str());
284
285     if (symbol && symbol->isReadOnly()) {
286         // All shared things containing an implicitly sized array must be copied up
287         // on first use, so that all future references will share its array structure,
288         // so that editing the implicit size will effect all nodes consuming it,
289         // and so that editing the implicit size won't change the shared one.
290         //
291         // If this is a variable or a block, check it and all it contains, but if this
292         // is a member of an anonymous block, check the whole block, as the whole block
293         // will need to be copied up if it contains an implicitly-sized array.
294         if (symbol->getType().containsImplicitlySizedArray() ||
295             (symbol->getAsAnonMember() &&
296              symbol->getAsAnonMember()->getAnonContainer().getType().containsImplicitlySizedArray()))
297             makeEditable(symbol);
298     }
299
300     const TVariable* variable;
301     const TAnonMember* anon = symbol ? symbol->getAsAnonMember() : nullptr;
302     if (anon) {
303         // It was a member of an anonymous container.
304
305         // The "getNumExtensions()" mechanism above doesn't yet work for block members
306         blockMemberExtensionCheck(loc, nullptr, *string);
307
308         // Create a subtree for its dereference.
309         variable = anon->getAnonContainer().getAsVariable();
310         TIntermTyped* container = intermediate.addSymbol(*variable, loc);
311         TIntermTyped* constNode = intermediate.addConstantUnion(anon->getMemberNumber(), loc);
312         node = intermediate.addIndex(EOpIndexDirectStruct, container, constNode, loc);
313
314         node->setType(*(*variable->getType().getStruct())[anon->getMemberNumber()].type);
315         if (node->getType().hiddenMember())
316             error(loc, "member of nameless block was not redeclared", string->c_str(), "");
317     } else {
318         // Not a member of an anonymous container.
319
320         // The symbol table search was done in the lexical phase.
321         // See if it was a variable.
322         variable = symbol ? symbol->getAsVariable() : nullptr;
323         if (variable) {
324             if ((variable->getType().getBasicType() == EbtBlock ||
325                  variable->getType().getBasicType() == EbtStruct) && variable->getType().getStruct() == nullptr) {
326                 error(loc, "cannot be used (maybe an instance name is needed)", string->c_str(), "");
327                 variable = nullptr;
328             }
329         } else {
330             if (symbol)
331                 error(loc, "variable name expected", string->c_str(), "");
332         }
333
334         // Recovery, if it wasn't found or was not a variable.
335         if (! variable)
336             variable = new TVariable(string, TType(EbtVoid));
337
338         if (variable->getType().getQualifier().isFrontEndConstant())
339             node = intermediate.addConstantUnion(variable->getConstArray(), variable->getType(), loc);
340         else
341             node = intermediate.addSymbol(*variable, loc);
342     }
343
344     if (variable->getType().getQualifier().isIo())
345         intermediate.addIoAccessed(*string);
346
347     return node;
348 }
349
350 //
351 // Handle seeing a base[index] dereference in the grammar.
352 //
353 TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index)
354 {
355     TIntermTyped* result = nullptr;
356
357     int indexValue = 0;
358     if (index->getQualifier().isFrontEndConstant())
359         indexValue = index->getAsConstantUnion()->getConstArray()[0].getIConst();
360
361     variableCheck(base);
362     if (! base->isArray() && ! base->isMatrix() && ! base->isVector()) {
363         if (base->getAsSymbolNode())
364             error(loc, " left of '[' is not of type array, matrix, or vector ", base->getAsSymbolNode()->getName().c_str(), "");
365         else
366             error(loc, " left of '[' is not of type array, matrix, or vector ", "expression", "");
367     } else if (base->getType().getQualifier().isFrontEndConstant() && index->getQualifier().isFrontEndConstant()) {
368         // both base and index are front-end constants
369         checkIndex(loc, base->getType(), indexValue);
370         return intermediate.foldDereference(base, indexValue, loc);
371     } else {
372         // at least one of base and index is not a front-end constant variable...
373
374         if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
375             handleIoResizeArrayAccess(loc, base);
376
377         if (index->getQualifier().isFrontEndConstant()) {
378             if (base->getType().isImplicitlySizedArray())
379                 updateImplicitArraySize(loc, base, indexValue);
380             else
381                 checkIndex(loc, base->getType(), indexValue);
382             result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
383         } else {
384             if (base->getType().isImplicitlySizedArray()) {
385                 if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
386                     error(loc, "", "[", "array must be sized by a redeclaration or layout qualifier before being indexed with a variable");
387                 else
388                     error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable");
389             }
390             if (base->getBasicType() == EbtBlock) {
391                 if (base->getQualifier().storage == EvqBuffer)
392                     requireProfile(base->getLoc(), ~EEsProfile, "variable indexing buffer block array");
393                 else if (base->getQualifier().storage == EvqUniform)
394                     profileRequires(base->getLoc(), EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5,
395                                     "variable indexing uniform block array");
396                 else {
397                     // input/output blocks either don't exist or can be variable indexed
398                 }
399             } else if (language == EShLangFragment && base->getQualifier().isPipeOutput())
400                 requireProfile(base->getLoc(), ~EEsProfile, "variable indexing fragment shader output array");
401             else if (base->getBasicType() == EbtSampler && version >= 130) {
402                 const char* explanation = "variable indexing sampler array";
403                 requireProfile(base->getLoc(), EEsProfile | ECoreProfile | ECompatibilityProfile, explanation);
404                 profileRequires(base->getLoc(), EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, explanation);
405                 profileRequires(base->getLoc(), ECoreProfile | ECompatibilityProfile, 400, nullptr, explanation);
406             }
407
408             result = intermediate.addIndex(EOpIndexIndirect, base, index, loc);
409         }
410     }
411
412     if (result == nullptr) {
413         // Insert dummy error-recovery result
414         result = intermediate.addConstantUnion(0.0, EbtFloat, loc);
415     } else {
416         // Insert valid dereferenced result
417         TType newType(base->getType(), 0);  // dereferenced type
418         if (base->getType().getQualifier().isConstant() && index->getQualifier().isConstant()) {
419             newType.getQualifier().storage = EvqConst;
420             // If base or index is a specialization constant, the result should also be a specialization constant.
421             if (base->getType().getQualifier().isSpecConstant() || index->getQualifier().isSpecConstant()) {
422                 newType.getQualifier().makeSpecConstant();
423             }
424         } else {
425             newType.getQualifier().makePartialTemporary();
426         }
427         result->setType(newType);
428
429         if (anyIndexLimits)
430             handleIndexLimits(loc, base, index);
431     }
432
433     return result;
434 }
435
436 // for ES 2.0 (version 100) limitations for almost all index operations except vertex-shader uniforms
437 void TParseContext::handleIndexLimits(const TSourceLoc& /*loc*/, TIntermTyped* base, TIntermTyped* index)
438 {
439     if ((! limits.generalSamplerIndexing && base->getBasicType() == EbtSampler) ||
440         (! limits.generalUniformIndexing && base->getQualifier().isUniformOrBuffer() && language != EShLangVertex) ||
441         (! limits.generalAttributeMatrixVectorIndexing && base->getQualifier().isPipeInput() && language == EShLangVertex && (base->getType().isMatrix() || base->getType().isVector())) ||
442         (! limits.generalConstantMatrixVectorIndexing && base->getAsConstantUnion()) ||
443         (! limits.generalVariableIndexing && ! base->getType().getQualifier().isUniformOrBuffer() &&
444                                              ! base->getType().getQualifier().isPipeInput() &&
445                                              ! base->getType().getQualifier().isPipeOutput() &&
446                                              ! base->getType().getQualifier().isConstant()) ||
447         (! limits.generalVaryingIndexing && (base->getType().getQualifier().isPipeInput() ||
448                                                 base->getType().getQualifier().isPipeOutput()))) {
449         // it's too early to know what the inductive variables are, save it for post processing
450         needsIndexLimitationChecking.push_back(index);
451     }
452 }
453
454 // Make a shared symbol have a non-shared version that can be edited by the current
455 // compile, such that editing its type will not change the shared version and will
456 // effect all nodes sharing it.
457 void TParseContext::makeEditable(TSymbol*& symbol)
458 {
459     TParseContextBase::makeEditable(symbol);
460
461     // See if it's tied to IO resizing
462     if (isIoResizeArray(symbol->getType()))
463         ioArraySymbolResizeList.push_back(symbol);
464 }
465
466 // Return true if this is a geometry shader input array or tessellation control output array.
467 bool TParseContext::isIoResizeArray(const TType& type) const
468 {
469     return type.isArray() &&
470            ((language == EShLangGeometry    && type.getQualifier().storage == EvqVaryingIn) ||
471             (language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut && ! type.getQualifier().patch));
472 }
473
474 // If an array is not isIoResizeArray() but is an io array, make sure it has the right size
475 void TParseContext::fixIoArraySize(const TSourceLoc& loc, TType& type)
476 {
477     if (! type.isArray() || type.getQualifier().patch || symbolTable.atBuiltInLevel())
478         return;
479
480     assert(! isIoResizeArray(type));
481
482     if (type.getQualifier().storage != EvqVaryingIn || type.getQualifier().patch)
483         return;
484
485     if (language == EShLangTessControl || language == EShLangTessEvaluation) {
486         if (type.getOuterArraySize() != resources.maxPatchVertices) {
487             if (type.isExplicitlySizedArray())
488                 error(loc, "tessellation input array size must be gl_MaxPatchVertices or implicitly sized", "[]", "");
489             type.changeOuterArraySize(resources.maxPatchVertices);
490         }
491     }
492 }
493
494 // Issue any errors if the non-array object is missing arrayness WRT
495 // shader I/O that has array requirements.
496 // All arrayness checking is handled in array paths, this is for
497 void TParseContext::ioArrayCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
498 {
499     if (! type.isArray() && ! symbolTable.atBuiltInLevel()) {
500         if (type.getQualifier().isArrayedIo(language)
501 #ifdef NV_EXTENSIONS
502             && !type.getQualifier().layoutPassthrough
503 #endif
504            )
505             error(loc, "type must be an array:", type.getStorageQualifierString(), identifier.c_str());
506     }
507 }
508
509 // Handle a dereference of a geometry shader input array or tessellation control output array.
510 // See ioArraySymbolResizeList comment in ParseHelper.h.
511 //
512 void TParseContext::handleIoResizeArrayAccess(const TSourceLoc& /*loc*/, TIntermTyped* base)
513 {
514     TIntermSymbol* symbolNode = base->getAsSymbolNode();
515     assert(symbolNode);
516     if (! symbolNode)
517         return;
518
519     // fix array size, if it can be fixed and needs to be fixed (will allow variable indexing)
520     if (symbolNode->getType().isImplicitlySizedArray()) {
521         int newSize = getIoArrayImplicitSize();
522         if (newSize > 0)
523             symbolNode->getWritableType().changeOuterArraySize(newSize);
524     }
525 }
526
527 // If there has been an input primitive declaration (geometry shader) or an output
528 // number of vertices declaration(tessellation shader), make sure all input array types
529 // match it in size.  Types come either from nodes in the AST or symbols in the
530 // symbol table.
531 //
532 // Types without an array size will be given one.
533 // Types already having a size that is wrong will get an error.
534 //
535 void TParseContext::checkIoArraysConsistency(const TSourceLoc& loc, bool tailOnly)
536 {
537     int requiredSize = getIoArrayImplicitSize();
538     if (requiredSize == 0)
539         return;
540
541     const char* feature;
542     if (language == EShLangGeometry)
543         feature = TQualifier::getGeometryString(intermediate.getInputPrimitive());
544     else if (language == EShLangTessControl)
545         feature = "vertices";
546     else
547         feature = "unknown";
548
549     if (tailOnly) {
550         checkIoArrayConsistency(loc, requiredSize, feature, ioArraySymbolResizeList.back()->getWritableType(), ioArraySymbolResizeList.back()->getName());
551         return;
552     }
553
554     for (size_t i = 0; i < ioArraySymbolResizeList.size(); ++i)
555         checkIoArrayConsistency(loc, requiredSize, feature, ioArraySymbolResizeList[i]->getWritableType(), ioArraySymbolResizeList[i]->getName());
556 }
557
558 int TParseContext::getIoArrayImplicitSize() const
559 {
560     if (language == EShLangGeometry)
561         return TQualifier::mapGeometryToSize(intermediate.getInputPrimitive());
562     else if (language == EShLangTessControl)
563         return intermediate.getVertices() != TQualifier::layoutNotSet ? intermediate.getVertices() : 0;
564     else
565         return 0;
566 }
567
568 void TParseContext::checkIoArrayConsistency(const TSourceLoc& loc, int requiredSize, const char* feature, TType& type, const TString& name)
569 {
570     if (type.isImplicitlySizedArray())
571         type.changeOuterArraySize(requiredSize);
572     else if (type.getOuterArraySize() != requiredSize) {
573         if (language == EShLangGeometry)
574             error(loc, "inconsistent input primitive for array size of", feature, name.c_str());
575         else if (language == EShLangTessControl)
576             error(loc, "inconsistent output number of vertices for array size of", feature, name.c_str());
577         else
578             assert(0);
579     }
580 }
581
582 // Handle seeing a binary node with a math operation.
583 // Returns nullptr if not semantically allowed.
584 TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right)
585 {
586     rValueErrorCheck(loc, str, left->getAsTyped());
587     rValueErrorCheck(loc, str, right->getAsTyped());
588
589     bool allowed = true;
590     switch (op) {
591     // TODO: Bring more source language-specific checks up from intermediate.cpp
592     // to the specific parse helpers for that source language.
593     case EOpLessThan:
594     case EOpGreaterThan:
595     case EOpLessThanEqual:
596     case EOpGreaterThanEqual:
597         if (! left->isScalar() || ! right->isScalar())
598             allowed = false;
599         break;
600     default:
601         break;
602     }
603
604     TIntermTyped* result = nullptr;
605     if (allowed)
606         result = intermediate.addBinaryMath(op, left, right, loc);
607
608     if (result == nullptr)
609         binaryOpError(loc, str, left->getCompleteString(), right->getCompleteString());
610
611     return result;
612 }
613
614 // Handle seeing a unary node with a math operation.
615 TIntermTyped* TParseContext::handleUnaryMath(const TSourceLoc& loc, const char* str, TOperator op, TIntermTyped* childNode)
616 {
617     rValueErrorCheck(loc, str, childNode);
618
619     TIntermTyped* result = intermediate.addUnaryMath(op, childNode, loc);
620
621     if (result)
622         return result;
623     else
624         unaryOpError(loc, str, childNode->getCompleteString());
625
626     return childNode;
627 }
628
629 //
630 // Handle seeing a base.field dereference in the grammar.
631 //
632 TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TIntermTyped* base, const TString& field)
633 {
634     variableCheck(base);
635
636     //
637     // .length() can't be resolved until we later see the function-calling syntax.
638     // Save away the name in the AST for now.  Processing is completed in
639     // handleLengthMethod().
640     //
641     if (field == "length") {
642         if (base->isArray()) {
643             profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, ".length");
644             profileRequires(loc, EEsProfile, 300, nullptr, ".length");
645         } else if (base->isVector() || base->isMatrix()) {
646             const char* feature = ".length() on vectors and matrices";
647             requireProfile(loc, ~EEsProfile, feature);
648             profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, feature);
649         } else {
650             error(loc, "does not operate on this type:", field.c_str(), base->getType().getCompleteString().c_str());
651
652             return base;
653         }
654
655         return intermediate.addMethod(base, TType(EbtInt), &field, loc);
656     }
657
658     // It's not .length() if we get to here.
659
660     if (base->isArray()) {
661         error(loc, "cannot apply to an array:", ".", field.c_str());
662
663         return base;
664     }
665
666     // It's neither an array nor .length() if we get here,
667     // leaving swizzles and struct/block dereferences.
668
669     TIntermTyped* result = base;
670     if ((base->isVector() || base->isScalar()) &&
671         (base->isFloatingDomain() || base->isIntegerDomain() || base->getBasicType() == EbtBool)) {
672         if (base->isScalar()) {
673             const char* dotFeature = "scalar swizzle";
674             requireProfile(loc, ~EEsProfile, dotFeature);
675             profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, dotFeature);
676         }
677
678         TSwizzleSelectors<TVectorSelector> selectors;
679         parseSwizzleSelector(loc, field, base->getVectorSize(), selectors);
680
681         if (base->isScalar()) {
682             if (selectors.size() == 1)
683                 return result;
684             else {
685                 TType type(base->getBasicType(), EvqTemporary, selectors.size());
686                 // Swizzle operations propagate specialization-constantness
687                 if (base->getQualifier().isSpecConstant())
688                     type.getQualifier().makeSpecConstant();
689                 return addConstructor(loc, base, type);
690             }
691         }
692
693         if (base->getType().getQualifier().isFrontEndConstant())
694             result = intermediate.foldSwizzle(base, selectors, loc);
695         else {
696             if (selectors.size() == 1) {
697                 TIntermTyped* index = intermediate.addConstantUnion(selectors[0], loc);
698                 result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
699                 result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision));
700             } else {
701                 TIntermTyped* index = intermediate.addSwizzle(selectors, loc);
702                 result = intermediate.addIndex(EOpVectorSwizzle, base, index, loc);
703                 result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision, selectors.size()));
704             }
705             // Swizzle operations propagate specialization-constantness
706             if (base->getType().getQualifier().isSpecConstant())
707                 result->getWritableType().getQualifier().makeSpecConstant();
708         }
709     } else if (base->getBasicType() == EbtStruct || base->getBasicType() == EbtBlock) {
710         const TTypeList* fields = base->getType().getStruct();
711         bool fieldFound = false;
712         int member;
713         for (member = 0; member < (int)fields->size(); ++member) {
714             if ((*fields)[member].type->getFieldName() == field) {
715                 fieldFound = true;
716                 break;
717             }
718         }
719         if (fieldFound) {
720             if (base->getType().getQualifier().isFrontEndConstant())
721                 result = intermediate.foldDereference(base, member, loc);
722             else {
723                 blockMemberExtensionCheck(loc, base, field);
724                 TIntermTyped* index = intermediate.addConstantUnion(member, loc);
725                 result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc);
726                 result->setType(*(*fields)[member].type);
727             }
728         } else
729             error(loc, "no such field in structure", field.c_str(), "");
730     } else
731         error(loc, "does not apply to this type:", field.c_str(), base->getType().getCompleteString().c_str());
732
733     // Propagate noContraction up the dereference chain
734     if (base->getQualifier().noContraction)
735         result->getWritableType().getQualifier().noContraction = true;
736
737     return result;
738 }
739
740 void TParseContext::blockMemberExtensionCheck(const TSourceLoc& loc, const TIntermTyped* /*base*/, const TString& field)
741 {
742     if (profile == EEsProfile && field == "gl_PointSize") {
743         if (language == EShLangGeometry)
744             requireExtensions(loc, Num_AEP_geometry_point_size, AEP_geometry_point_size, "gl_PointSize");
745         else if (language == EShLangTessControl || language == EShLangTessEvaluation)
746             requireExtensions(loc, Num_AEP_tessellation_point_size, AEP_tessellation_point_size, "gl_PointSize");
747     }
748 }
749
750 //
751 // Handle seeing a function declarator in the grammar.  This is the precursor
752 // to recognizing a function prototype or function definition.
753 //
754 TFunction* TParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFunction& function, bool prototype)
755 {
756     // ES can't declare prototypes inside functions
757     if (! symbolTable.atGlobalLevel())
758         requireProfile(loc, ~EEsProfile, "local function declaration");
759
760     //
761     // Multiple declarations of the same function name are allowed.
762     //
763     // If this is a definition, the definition production code will check for redefinitions
764     // (we don't know at this point if it's a definition or not).
765     //
766     // Redeclarations (full signature match) are allowed.  But, return types and parameter qualifiers must also match.
767     //  - except ES 100, which only allows a single prototype
768     //
769     // ES 100 does not allow redefining, but does allow overloading of built-in functions.
770     // ES 300 does not allow redefining or overloading of built-in functions.
771     //
772     bool builtIn;
773     TSymbol* symbol = symbolTable.find(function.getMangledName(), &builtIn);
774     if (symbol && symbol->getAsFunction() && builtIn)
775         requireProfile(loc, ~EEsProfile, "redefinition of built-in function");
776     const TFunction* prevDec = symbol ? symbol->getAsFunction() : 0;
777     if (prevDec) {
778         if (prevDec->isPrototyped() && prototype)
779             profileRequires(loc, EEsProfile, 300, nullptr, "multiple prototypes for same function");
780         if (prevDec->getType() != function.getType())
781             error(loc, "overloaded functions must have the same return type", function.getName().c_str(), "");
782         for (int i = 0; i < prevDec->getParamCount(); ++i) {
783             if ((*prevDec)[i].type->getQualifier().storage != function[i].type->getQualifier().storage)
784                 error(loc, "overloaded functions must have the same parameter storage qualifiers for argument", function[i].type->getStorageQualifierString(), "%d", i+1);
785
786             if ((*prevDec)[i].type->getQualifier().precision != function[i].type->getQualifier().precision)
787                 error(loc, "overloaded functions must have the same parameter precision qualifiers for argument", function[i].type->getPrecisionQualifierString(), "%d", i+1);
788         }
789     }
790
791     arrayObjectCheck(loc, function.getType(), "array in function return type");
792
793     if (prototype) {
794         // All built-in functions are defined, even though they don't have a body.
795         // Count their prototype as a definition instead.
796         if (symbolTable.atBuiltInLevel())
797             function.setDefined();
798         else {
799             if (prevDec && ! builtIn)
800                 symbol->getAsFunction()->setPrototyped();  // need a writable one, but like having prevDec as a const
801             function.setPrototyped();
802         }
803     }
804
805     // This insert won't actually insert it if it's a duplicate signature, but it will still check for
806     // other forms of name collisions.
807     if (! symbolTable.insert(function))
808         error(loc, "function name is redeclaration of existing name", function.getName().c_str(), "");
809
810     //
811     // If this is a redeclaration, it could also be a definition,
812     // in which case, we need to use the parameter names from this one, and not the one that's
813     // being redeclared.  So, pass back this declaration, not the one in the symbol table.
814     //
815     return &function;
816 }
817
818 //
819 // Handle seeing the function prototype in front of a function definition in the grammar.
820 // The body is handled after this function returns.
821 //
822 TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc, TFunction& function)
823 {
824     currentCaller = function.getMangledName();
825     TSymbol* symbol = symbolTable.find(function.getMangledName());
826     TFunction* prevDec = symbol ? symbol->getAsFunction() : nullptr;
827
828     if (! prevDec)
829         error(loc, "can't find function", function.getName().c_str(), "");
830     // Note:  'prevDec' could be 'function' if this is the first time we've seen function
831     // as it would have just been put in the symbol table.  Otherwise, we're looking up
832     // an earlier occurrence.
833
834     if (prevDec && prevDec->isDefined()) {
835         // Then this function already has a body.
836         error(loc, "function already has a body", function.getName().c_str(), "");
837     }
838     if (prevDec && ! prevDec->isDefined()) {
839         prevDec->setDefined();
840
841         // Remember the return type for later checking for RETURN statements.
842         currentFunctionType = &(prevDec->getType());
843     } else
844         currentFunctionType = new TType(EbtVoid);
845     functionReturnsValue = false;
846
847     // Check for entry point
848     if (function.getName().compare(intermediate.getEntryPointName().c_str()) == 0) {
849         intermediate.setEntryPointMangledName(function.getMangledName().c_str());
850         intermediate.incrementEntryPointCount();
851         inMain = true;
852     } else
853         inMain = false;
854
855     //
856     // Raise error message if main function takes any parameters or returns anything other than void
857     //
858     if (inMain) {
859         if (function.getParamCount() > 0)
860             error(loc, "function cannot take any parameter(s)", function.getName().c_str(), "");
861         if (function.getType().getBasicType() != EbtVoid)
862             error(loc, "", function.getType().getBasicTypeString().c_str(), "entry point cannot return a value");
863     }
864
865     //
866     // New symbol table scope for body of function plus its arguments
867     //
868     symbolTable.push();
869
870     //
871     // Insert parameters into the symbol table.
872     // If the parameter has no name, it's not an error, just don't insert it
873     // (could be used for unused args).
874     //
875     // Also, accumulate the list of parameters into the HIL, so lower level code
876     // knows where to find parameters.
877     //
878     TIntermAggregate* paramNodes = new TIntermAggregate;
879     for (int i = 0; i < function.getParamCount(); i++) {
880         TParameter& param = function[i];
881         if (param.name != nullptr) {
882             TVariable *variable = new TVariable(param.name, *param.type);
883
884             // Insert the parameters with name in the symbol table.
885             if (! symbolTable.insert(*variable))
886                 error(loc, "redefinition", variable->getName().c_str(), "");
887             else {
888                 // Transfer ownership of name pointer to symbol table.
889                 param.name = nullptr;
890
891                 // Add the parameter to the HIL
892                 paramNodes = intermediate.growAggregate(paramNodes,
893                                                         intermediate.addSymbol(*variable, loc),
894                                                         loc);
895             }
896         } else
897             paramNodes = intermediate.growAggregate(paramNodes, intermediate.addSymbol(*param.type, loc), loc);
898     }
899     intermediate.setAggregateOperator(paramNodes, EOpParameters, TType(EbtVoid), loc);
900     loopNestingLevel = 0;
901     statementNestingLevel = 0;
902     controlFlowNestingLevel = 0;
903     postEntryPointReturn = false;
904
905     return paramNodes;
906 }
907
908 //
909 // Handle seeing function call syntax in the grammar, which could be any of
910 //  - .length() method
911 //  - constructor
912 //  - a call to a built-in function mapped to an operator
913 //  - a call to a built-in function that will remain a function call (e.g., texturing)
914 //  - user function
915 //  - subroutine call (not implemented yet)
916 //
917 TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction* function, TIntermNode* arguments)
918 {
919     TIntermTyped* result = nullptr;
920
921     if (function->getBuiltInOp() == EOpArrayLength)
922         result = handleLengthMethod(loc, function, arguments);
923     else if (function->getBuiltInOp() != EOpNull) {
924         //
925         // Then this should be a constructor.
926         // Don't go through the symbol table for constructors.
927         // Their parameters will be verified algorithmically.
928         //
929         TType type(EbtVoid);  // use this to get the type back
930         if (! constructorError(loc, arguments, *function, function->getBuiltInOp(), type)) {
931             //
932             // It's a constructor, of type 'type'.
933             //
934             result = addConstructor(loc, arguments, type);
935             if (result == nullptr)
936                 error(loc, "cannot construct with these arguments", type.getCompleteString().c_str(), "");
937         }
938     } else {
939         //
940         // Find it in the symbol table.
941         //
942         const TFunction* fnCandidate;
943         bool builtIn;
944         fnCandidate = findFunction(loc, *function, builtIn);
945         if (fnCandidate) {
946             // This is a declared function that might map to
947             //  - a built-in operator,
948             //  - a built-in function not mapped to an operator, or
949             //  - a user function.
950
951             // Error check for a function requiring specific extensions present.
952             if (builtIn && fnCandidate->getNumExtensions())
953                 requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str());
954
955             if (arguments != nullptr) {
956                 // Make sure qualifications work for these arguments.
957                 TIntermAggregate* aggregate = arguments->getAsAggregate();
958                 for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
959                     // At this early point there is a slight ambiguity between whether an aggregate 'arguments'
960                     // is the single argument itself or its children are the arguments.  Only one argument
961                     // means take 'arguments' itself as the one argument.
962                     TIntermNode* arg = fnCandidate->getParamCount() == 1 ? arguments : (aggregate ? aggregate->getSequence()[i] : arguments);
963                     TQualifier& formalQualifier = (*fnCandidate)[i].type->getQualifier();
964                     if (formalQualifier.isParamOutput()) {
965                         if (lValueErrorCheck(arguments->getLoc(), "assign", arg->getAsTyped()))
966                             error(arguments->getLoc(), "Non-L-value cannot be passed for 'out' or 'inout' parameters.", "out", "");
967                     }
968                     TQualifier& argQualifier = arg->getAsTyped()->getQualifier();
969                     if (argQualifier.isMemory()) {
970                         const char* message = "argument cannot drop memory qualifier when passed to formal parameter";
971                         if (argQualifier.volatil && ! formalQualifier.volatil)
972                             error(arguments->getLoc(), message, "volatile", "");
973                         if (argQualifier.coherent && ! formalQualifier.coherent)
974                             error(arguments->getLoc(), message, "coherent", "");
975                         if (argQualifier.readonly && ! formalQualifier.readonly)
976                             error(arguments->getLoc(), message, "readonly", "");
977                         if (argQualifier.writeonly && ! formalQualifier.writeonly)
978                             error(arguments->getLoc(), message, "writeonly", "");
979                     }
980                     // TODO 4.5 functionality:  A shader will fail to compile
981                     // if the value passed to the memargument of an atomic memory function does not correspond to a buffer or
982                     // shared variable. It is acceptable to pass an element of an array or a single component of a vector to the
983                     // memargument of an atomic memory function, as long as the underlying array or vector is a buffer or
984                     // shared variable.
985                 }
986
987                 // Convert 'in' arguments
988                 addInputArgumentConversions(*fnCandidate, arguments);  // arguments may be modified if it's just a single argument node
989             }
990
991             if (builtIn && fnCandidate->getBuiltInOp() != EOpNull) {
992                 // A function call mapped to a built-in operation.
993                 result = handleBuiltInFunctionCall(loc, arguments, *fnCandidate);
994             } else {
995                 // This is a function call not mapped to built-in operator.
996                 // It could still be a built-in function, but only if PureOperatorBuiltins == false.
997                 result = intermediate.setAggregateOperator(arguments, EOpFunctionCall, fnCandidate->getType(), loc);
998                 TIntermAggregate* call = result->getAsAggregate();
999                 call->setName(fnCandidate->getMangledName());
1000
1001                 // this is how we know whether the given function is a built-in function or a user-defined function
1002                 // if builtIn == false, it's a userDefined -> could be an overloaded built-in function also
1003                 // if builtIn == true, it's definitely a built-in function with EOpNull
1004                 if (! builtIn) {
1005                     call->setUserDefined();
1006                     if (symbolTable.atGlobalLevel()) {
1007                         requireProfile(loc, ~EEsProfile, "calling user function from global scope");
1008                         intermediate.addToCallGraph(infoSink, "main(", fnCandidate->getMangledName());
1009                     } else
1010                         intermediate.addToCallGraph(infoSink, currentCaller, fnCandidate->getMangledName());
1011                 }
1012
1013                 if (builtIn)
1014                     nonOpBuiltInCheck(loc, *fnCandidate, *call);
1015                 else
1016                     userFunctionCallCheck(loc, *call);
1017             }
1018
1019             // Convert 'out' arguments.  If it was a constant folded built-in, it won't be an aggregate anymore.
1020             // Built-ins with a single argument aren't called with an aggregate, but they also don't have an output.
1021             // Also, build the qualifier list for user function calls, which are always called with an aggregate.
1022             if (result->getAsAggregate()) {
1023                 TQualifierList& qualifierList = result->getAsAggregate()->getQualifierList();
1024                 for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
1025                     TStorageQualifier qual = (*fnCandidate)[i].type->getQualifier().storage;
1026                     qualifierList.push_back(qual);
1027                 }
1028                 result = addOutputArgumentConversions(*fnCandidate, *result->getAsAggregate());
1029             }
1030         }
1031     }
1032
1033     // generic error recovery
1034     // TODO: simplification: localize all the error recoveries that look like this, and taking type into account to reduce cascades
1035     if (result == nullptr)
1036         result = intermediate.addConstantUnion(0.0, EbtFloat, loc);
1037
1038     return result;
1039 }
1040
1041 TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNode* arguments,
1042                                                        const TFunction& function)
1043 {
1044     checkLocation(loc, function.getBuiltInOp());
1045     TIntermTyped *result = intermediate.addBuiltInFunctionCall(loc, function.getBuiltInOp(),
1046                                                                function.getParamCount() == 1,
1047                                                                arguments, function.getType());
1048     if (obeyPrecisionQualifiers())
1049         computeBuiltinPrecisions(*result, function);
1050
1051     if (result == nullptr) {
1052         if (arguments == nullptr)
1053             error(loc, " wrong operand type", "Internal Error",
1054                                       "built in unary operator function.  Type: %s", "");
1055         else
1056             error(arguments->getLoc(), " wrong operand type", "Internal Error",
1057                                       "built in unary operator function.  Type: %s",
1058                                       static_cast<TIntermTyped*>(arguments)->getCompleteString().c_str());
1059     } else if (result->getAsOperator())
1060         builtInOpCheck(loc, function, *result->getAsOperator());
1061
1062     return result;
1063 }
1064
1065 // "The operation of a built-in function can have a different precision
1066 // qualification than the precision qualification of the resulting value.
1067 // These two precision qualifications are established as follows.
1068 //
1069 // The precision qualification of the operation of a built-in function is
1070 // based on the precision qualification of its input arguments and formal
1071 // parameters:  When a formal parameter specifies a precision qualifier,
1072 // that is used, otherwise, the precision qualification of the calling
1073 // argument is used.  The highest precision of these will be the precision
1074 // qualification of the operation of the built-in function. Generally,
1075 // this is applied across all arguments to a built-in function, with the
1076 // exceptions being:
1077 //   - bitfieldExtract and bitfieldInsert ignore the 'offset' and 'bits'
1078 //     arguments.
1079 //   - interpolateAt* functions only look at the 'interpolant' argument.
1080 //
1081 // The precision qualification of the result of a built-in function is
1082 // determined in one of the following ways:
1083 //
1084 //   - For the texture sampling, image load, and image store functions,
1085 //     the precision of the return type matches the precision of the
1086 //     sampler type
1087 //
1088 //   Otherwise:
1089 //
1090 //   - For prototypes that do not specify a resulting precision qualifier,
1091 //     the precision will be the same as the precision of the operation.
1092 //
1093 //   - For prototypes that do specify a resulting precision qualifier,
1094 //     the specified precision qualifier is the precision qualification of
1095 //     the result."
1096 //
1097 void TParseContext::computeBuiltinPrecisions(TIntermTyped& node, const TFunction& function)
1098 {
1099     TPrecisionQualifier operationPrecision = EpqNone;
1100     TPrecisionQualifier resultPrecision = EpqNone;
1101
1102     TIntermOperator* opNode = node.getAsOperator();
1103     if (opNode == nullptr)
1104         return;
1105
1106     if (TIntermUnary* unaryNode = node.getAsUnaryNode()) {
1107         operationPrecision = std::max(function[0].type->getQualifier().precision,
1108                                       unaryNode->getOperand()->getType().getQualifier().precision);
1109         if (function.getType().getBasicType() != EbtBool)
1110             resultPrecision = function.getType().getQualifier().precision == EpqNone ?
1111                                         operationPrecision :
1112                                         function.getType().getQualifier().precision;
1113     } else if (TIntermAggregate* agg = node.getAsAggregate()) {
1114         TIntermSequence& sequence = agg->getSequence();
1115         unsigned int numArgs = (unsigned int)sequence.size();
1116         switch (agg->getOp()) {
1117         case EOpBitfieldExtract:
1118             numArgs = 1;
1119             break;
1120         case EOpBitfieldInsert:
1121             numArgs = 2;
1122             break;
1123         case EOpInterpolateAtCentroid:
1124         case EOpInterpolateAtOffset:
1125         case EOpInterpolateAtSample:
1126             numArgs = 1;
1127             break;
1128         default:
1129             break;
1130         }
1131         // find the maximum precision from the arguments and parameters
1132         for (unsigned int arg = 0; arg < numArgs; ++arg) {
1133             operationPrecision = std::max(operationPrecision, sequence[arg]->getAsTyped()->getQualifier().precision);
1134             operationPrecision = std::max(operationPrecision, function[arg].type->getQualifier().precision);
1135         }
1136         // compute the result precision
1137 #ifdef AMD_EXTENSIONS
1138         if (agg->isSampling() ||
1139             agg->getOp() == EOpImageLoad || agg->getOp() == EOpImageStore ||
1140             agg->getOp() == EOpImageLoadLod || agg->getOp() == EOpImageStoreLod)
1141 #else
1142         if (agg->isSampling() || agg->getOp() == EOpImageLoad || agg->getOp() == EOpImageStore)
1143 #endif
1144             resultPrecision = sequence[0]->getAsTyped()->getQualifier().precision;
1145         else if (function.getType().getBasicType() != EbtBool)
1146             resultPrecision = function.getType().getQualifier().precision == EpqNone ?
1147                                         operationPrecision :
1148                                         function.getType().getQualifier().precision;
1149     }
1150
1151     // Propagate precision through this node and its children. That algorithm stops
1152     // when a precision is found, so start by clearing this subroot precision
1153     opNode->getQualifier().precision = EpqNone;
1154     if (operationPrecision != EpqNone) {
1155         opNode->propagatePrecision(operationPrecision);
1156         opNode->setOperationPrecision(operationPrecision);
1157     }
1158     // Now, set the result precision, which might not match
1159     opNode->getQualifier().precision = resultPrecision;
1160 }
1161
1162 TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermTyped* value)
1163 {
1164     functionReturnsValue = true;
1165     if (currentFunctionType->getBasicType() == EbtVoid) {
1166         error(loc, "void function cannot return a value", "return", "");
1167         return intermediate.addBranch(EOpReturn, loc);
1168     } else if (*currentFunctionType != value->getType()) {
1169         TIntermTyped* converted = intermediate.addConversion(EOpReturn, *currentFunctionType, value);
1170         if (converted) {
1171             if (*currentFunctionType != converted->getType())
1172                 error(loc, "cannot convert return value to function return type", "return", "");
1173             if (version < 420)
1174                 warn(loc, "type conversion on return values was not explicitly allowed until version 420", "return", "");
1175             return intermediate.addBranch(EOpReturn, converted, loc);
1176         } else {
1177             error(loc, "type does not match, or is not convertible to, the function's return type", "return", "");
1178             return intermediate.addBranch(EOpReturn, value, loc);
1179         }
1180     } else
1181         return intermediate.addBranch(EOpReturn, value, loc);
1182 }
1183
1184 // See if the operation is being done in an illegal location.
1185 void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op)
1186 {
1187     switch (op) {
1188     case EOpBarrier:
1189         if (language == EShLangTessControl) {
1190             if (controlFlowNestingLevel > 0)
1191                 error(loc, "tessellation control barrier() cannot be placed within flow control", "", "");
1192             if (! inMain)
1193                 error(loc, "tessellation control barrier() must be in main()", "", "");
1194             else if (postEntryPointReturn)
1195                 error(loc, "tessellation control barrier() cannot be placed after a return from main()", "", "");
1196         }
1197         break;
1198     default:
1199         break;
1200     }
1201 }
1202
1203 // Finish processing object.length(). This started earlier in handleDotDereference(), where
1204 // the ".length" part was recognized and semantically checked, and finished here where the
1205 // function syntax "()" is recognized.
1206 //
1207 // Return resulting tree node.
1208 TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction* function, TIntermNode* intermNode)
1209 {
1210     int length = 0;
1211
1212     if (function->getParamCount() > 0)
1213         error(loc, "method does not accept any arguments", function->getName().c_str(), "");
1214     else {
1215         const TType& type = intermNode->getAsTyped()->getType();
1216         if (type.isArray()) {
1217             if (type.isRuntimeSizedArray()) {
1218                 // Create a unary op and let the back end handle it
1219                 return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt));
1220             } else if (type.isImplicitlySizedArray()) {
1221                 if (intermNode->getAsSymbolNode() && isIoResizeArray(type)) {
1222                     // We could be between a layout declaration that gives a built-in io array implicit size and
1223                     // a user redeclaration of that array, meaning we have to substitute its implicit size here
1224                     // without actually redeclaring the array.  (It is an error to use a member before the
1225                     // redeclaration, but not an error to use the array name itself.)
1226                     const TString& name = intermNode->getAsSymbolNode()->getName();
1227                     if (name == "gl_in" || name == "gl_out")
1228                         length = getIoArrayImplicitSize();
1229                 }
1230                 if (length == 0) {
1231                     if (intermNode->getAsSymbolNode() && isIoResizeArray(type))
1232                         error(loc, "", function->getName().c_str(), "array must first be sized by a redeclaration or layout qualifier");
1233                     else
1234                         error(loc, "", function->getName().c_str(), "array must be declared with a size before using this method");
1235                 }
1236             } else if (type.getOuterArrayNode()) {
1237                 // If the array's outer size is specified by an intermediate node, it means the array's length
1238                 // was specified by a specialization constant. In such a case, we should return the node of the
1239                 // specialization constants to represent the length.
1240                 return type.getOuterArrayNode();
1241             } else
1242                 length = type.getOuterArraySize();
1243         } else if (type.isMatrix())
1244             length = type.getMatrixCols();
1245         else if (type.isVector())
1246             length = type.getVectorSize();
1247         else {
1248             // we should not get here, because earlier semantic checking should have prevented this path
1249             error(loc, ".length()", "unexpected use of .length()", "");
1250         }
1251     }
1252
1253     if (length == 0)
1254         length = 1;
1255
1256     return intermediate.addConstantUnion(length, loc);
1257 }
1258
1259 //
1260 // Add any needed implicit conversions for function-call arguments to input parameters.
1261 //
1262 void TParseContext::addInputArgumentConversions(const TFunction& function, TIntermNode*& arguments) const
1263 {
1264     TIntermAggregate* aggregate = arguments->getAsAggregate();
1265
1266     // Process each argument's conversion
1267     for (int i = 0; i < function.getParamCount(); ++i) {
1268         // At this early point there is a slight ambiguity between whether an aggregate 'arguments'
1269         // is the single argument itself or its children are the arguments.  Only one argument
1270         // means take 'arguments' itself as the one argument.
1271         TIntermTyped* arg = function.getParamCount() == 1 ? arguments->getAsTyped() : (aggregate ? aggregate->getSequence()[i]->getAsTyped() : arguments->getAsTyped());
1272         if (*function[i].type != arg->getType()) {
1273             if (function[i].type->getQualifier().isParamInput()) {
1274                 // In-qualified arguments just need an extra node added above the argument to
1275                 // convert to the correct type.
1276                 arg = intermediate.addConversion(EOpFunctionCall, *function[i].type, arg);
1277                 if (arg) {
1278                     if (function.getParamCount() == 1)
1279                         arguments = arg;
1280                     else {
1281                         if (aggregate)
1282                             aggregate->getSequence()[i] = arg;
1283                         else
1284                             arguments = arg;
1285                     }
1286                 }
1287             }
1288         }
1289     }
1290 }
1291
1292 //
1293 // Add any needed implicit output conversions for function-call arguments.  This
1294 // can require a new tree topology, complicated further by whether the function
1295 // has a return value.
1296 //
1297 // Returns a node of a subtree that evaluates to the return value of the function.
1298 //
1299 TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& function, TIntermAggregate& intermNode) const
1300 {
1301     TIntermSequence& arguments = intermNode.getSequence();
1302
1303     // Will there be any output conversions?
1304     bool outputConversions = false;
1305     for (int i = 0; i < function.getParamCount(); ++i) {
1306         if (*function[i].type != arguments[i]->getAsTyped()->getType() && function[i].type->getQualifier().isParamOutput()) {
1307             outputConversions = true;
1308             break;
1309         }
1310     }
1311
1312     if (! outputConversions)
1313         return &intermNode;
1314
1315     // Setup for the new tree, if needed:
1316     //
1317     // Output conversions need a different tree topology.
1318     // Out-qualified arguments need a temporary of the correct type, with the call
1319     // followed by an assignment of the temporary to the original argument:
1320     //     void: function(arg, ...)  ->        (          function(tempArg, ...), arg = tempArg, ...)
1321     //     ret = function(arg, ...)  ->  ret = (tempRet = function(tempArg, ...), arg = tempArg, ..., tempRet)
1322     // Where the "tempArg" type needs no conversion as an argument, but will convert on assignment.
1323     TIntermTyped* conversionTree = nullptr;
1324     TVariable* tempRet = nullptr;
1325     if (intermNode.getBasicType() != EbtVoid) {
1326         // do the "tempRet = function(...), " bit from above
1327         tempRet = makeInternalVariable("tempReturn", intermNode.getType());
1328         TIntermSymbol* tempRetNode = intermediate.addSymbol(*tempRet, intermNode.getLoc());
1329         conversionTree = intermediate.addAssign(EOpAssign, tempRetNode, &intermNode, intermNode.getLoc());
1330     } else
1331         conversionTree = &intermNode;
1332
1333     conversionTree = intermediate.makeAggregate(conversionTree);
1334
1335     // Process each argument's conversion
1336     for (int i = 0; i < function.getParamCount(); ++i) {
1337         if (*function[i].type != arguments[i]->getAsTyped()->getType()) {
1338             if (function[i].type->getQualifier().isParamOutput()) {
1339                 // Out-qualified arguments need to use the topology set up above.
1340                 // do the " ...(tempArg, ...), arg = tempArg" bit from above
1341                 TVariable* tempArg = makeInternalVariable("tempArg", *function[i].type);
1342                 tempArg->getWritableType().getQualifier().makeTemporary();
1343                 TIntermSymbol* tempArgNode = intermediate.addSymbol(*tempArg, intermNode.getLoc());
1344                 TIntermTyped* tempAssign = intermediate.addAssign(EOpAssign, arguments[i]->getAsTyped(), tempArgNode, arguments[i]->getLoc());
1345                 conversionTree = intermediate.growAggregate(conversionTree, tempAssign, arguments[i]->getLoc());
1346                 // replace the argument with another node for the same tempArg variable
1347                 arguments[i] = intermediate.addSymbol(*tempArg, intermNode.getLoc());
1348             }
1349         }
1350     }
1351
1352     // Finalize the tree topology (see bigger comment above).
1353     if (tempRet) {
1354         // do the "..., tempRet" bit from above
1355         TIntermSymbol* tempRetNode = intermediate.addSymbol(*tempRet, intermNode.getLoc());
1356         conversionTree = intermediate.growAggregate(conversionTree, tempRetNode, intermNode.getLoc());
1357     }
1358     conversionTree = intermediate.setAggregateOperator(conversionTree, EOpComma, intermNode.getType(), intermNode.getLoc());
1359
1360     return conversionTree;
1361 }
1362
1363 //
1364 // Do additional checking of built-in function calls that is not caught
1365 // by normal semantic checks on argument type, extension tagging, etc.
1366 //
1367 // Assumes there has been a semantically correct match to a built-in function prototype.
1368 //
1369 void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCandidate, TIntermOperator& callNode)
1370 {
1371     // Set up convenience accessors to the argument(s).  There is almost always
1372     // multiple arguments for the cases below, but when there might be one,
1373     // check the unaryArg first.
1374     const TIntermSequence* argp = nullptr;   // confusing to use [] syntax on a pointer, so this is to help get a reference
1375     const TIntermTyped* unaryArg = nullptr;
1376     const TIntermTyped* arg0 = nullptr;
1377     if (callNode.getAsAggregate()) {
1378         argp = &callNode.getAsAggregate()->getSequence();
1379         if (argp->size() > 0)
1380             arg0 = (*argp)[0]->getAsTyped();
1381     } else {
1382         assert(callNode.getAsUnaryNode());
1383         unaryArg = callNode.getAsUnaryNode()->getOperand();
1384         arg0 = unaryArg;
1385     }
1386
1387     TString featureString;
1388     const char* feature = nullptr;
1389     switch (callNode.getOp()) {
1390     case EOpTextureGather:
1391     case EOpTextureGatherOffset:
1392     case EOpTextureGatherOffsets:
1393     {
1394         // Figure out which variants are allowed by what extensions,
1395         // and what arguments must be constant for which situations.
1396
1397         featureString = fnCandidate.getName();
1398         featureString += "(...)";
1399         feature = featureString.c_str();
1400         profileRequires(loc, EEsProfile, 310, nullptr, feature);
1401         int compArg = -1;  // track which argument, if any, is the constant component argument
1402         switch (callNode.getOp()) {
1403         case EOpTextureGather:
1404             // More than two arguments needs gpu_shader5, and rectangular or shadow needs gpu_shader5,
1405             // otherwise, need GL_ARB_texture_gather.
1406             if (fnCandidate.getParamCount() > 2 || fnCandidate[0].type->getSampler().dim == EsdRect || fnCandidate[0].type->getSampler().shadow) {
1407                 profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature);
1408                 if (! fnCandidate[0].type->getSampler().shadow)
1409                     compArg = 2;
1410             } else
1411                 profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_texture_gather, feature);
1412             break;
1413         case EOpTextureGatherOffset:
1414             // GL_ARB_texture_gather is good enough for 2D non-shadow textures with no component argument
1415             if (fnCandidate[0].type->getSampler().dim == Esd2D && ! fnCandidate[0].type->getSampler().shadow && fnCandidate.getParamCount() == 3)
1416                 profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_texture_gather, feature);
1417             else
1418                 profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature);
1419             if (! (*argp)[fnCandidate[0].type->getSampler().shadow ? 3 : 2]->getAsConstantUnion())
1420                 profileRequires(loc, EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5,
1421                                 "non-constant offset argument");
1422             if (! fnCandidate[0].type->getSampler().shadow)
1423                 compArg = 3;
1424             break;
1425         case EOpTextureGatherOffsets:
1426             profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature);
1427             if (! fnCandidate[0].type->getSampler().shadow)
1428                 compArg = 3;
1429             // check for constant offsets
1430             if (! (*argp)[fnCandidate[0].type->getSampler().shadow ? 3 : 2]->getAsConstantUnion())
1431                 error(loc, "must be a compile-time constant:", feature, "offsets argument");
1432             break;
1433         default:
1434             break;
1435         }
1436
1437         if (compArg > 0 && compArg < fnCandidate.getParamCount()) {
1438             if ((*argp)[compArg]->getAsConstantUnion()) {
1439                 int value = (*argp)[compArg]->getAsConstantUnion()->getConstArray()[0].getIConst();
1440                 if (value < 0 || value > 3)
1441                     error(loc, "must be 0, 1, 2, or 3:", feature, "component argument");
1442             } else
1443                 error(loc, "must be a compile-time constant:", feature, "component argument");
1444         }
1445
1446 #ifdef AMD_EXTENSIONS
1447         bool bias = false;
1448         if (callNode.getOp() == EOpTextureGather)
1449             bias = fnCandidate.getParamCount() > 3;
1450         else if (callNode.getOp() == EOpTextureGatherOffset ||
1451                  callNode.getOp() == EOpTextureGatherOffsets)
1452             bias = fnCandidate.getParamCount() > 4;
1453
1454         if (bias) {
1455             featureString = fnCandidate.getName();
1456             featureString += "with bias argument";
1457             feature = featureString.c_str();
1458             profileRequires(loc, ~EEsProfile, 450, nullptr, feature);
1459             requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature);
1460         }
1461 #endif
1462
1463         break;
1464     }
1465
1466 #ifdef AMD_EXTENSIONS
1467     case EOpSparseTextureGather:
1468     case EOpSparseTextureGatherOffset:
1469     case EOpSparseTextureGatherOffsets:
1470     {
1471         bool bias = false;
1472         if (callNode.getOp() == EOpSparseTextureGather)
1473             bias = fnCandidate.getParamCount() > 4;
1474         else if (callNode.getOp() == EOpSparseTextureGatherOffset ||
1475                  callNode.getOp() == EOpSparseTextureGatherOffsets)
1476             bias = fnCandidate.getParamCount() > 5;
1477
1478         if (bias) {
1479             featureString = fnCandidate.getName();
1480             featureString += "with bias argument";
1481             feature = featureString.c_str();
1482             profileRequires(loc, ~EEsProfile, 450, nullptr, feature);
1483             requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature);
1484         }
1485
1486         break;
1487     }
1488
1489     case EOpSparseTextureGatherLod:
1490     case EOpSparseTextureGatherLodOffset:
1491     case EOpSparseTextureGatherLodOffsets:
1492     {
1493         requireExtensions(loc, 1, &E_GL_ARB_sparse_texture2, fnCandidate.getName().c_str());
1494         break;
1495     }
1496 #endif
1497
1498     case EOpTextureOffset:
1499     case EOpTextureFetchOffset:
1500     case EOpTextureProjOffset:
1501     case EOpTextureLodOffset:
1502     case EOpTextureProjLodOffset:
1503     case EOpTextureGradOffset:
1504     case EOpTextureProjGradOffset:
1505     {
1506         // Handle texture-offset limits checking
1507         // Pick which argument has to hold constant offsets
1508         int arg = -1;
1509         switch (callNode.getOp()) {
1510         case EOpTextureOffset:          arg = 2;  break;
1511         case EOpTextureFetchOffset:     arg = (arg0->getType().getSampler().dim != EsdRect) ? 3 : 2; break;
1512         case EOpTextureProjOffset:      arg = 2;  break;
1513         case EOpTextureLodOffset:       arg = 3;  break;
1514         case EOpTextureProjLodOffset:   arg = 3;  break;
1515         case EOpTextureGradOffset:      arg = 4;  break;
1516         case EOpTextureProjGradOffset:  arg = 4;  break;
1517         default:
1518             assert(0);
1519             break;
1520         }
1521
1522         if (arg > 0) {
1523             if (! (*argp)[arg]->getAsConstantUnion())
1524                 error(loc, "argument must be compile-time constant", "texel offset", "");
1525             else {
1526                 const TType& type = (*argp)[arg]->getAsTyped()->getType();
1527                 for (int c = 0; c < type.getVectorSize(); ++c) {
1528                     int offset = (*argp)[arg]->getAsConstantUnion()->getConstArray()[c].getIConst();
1529                     if (offset > resources.maxProgramTexelOffset || offset < resources.minProgramTexelOffset)
1530                         error(loc, "value is out of range:", "texel offset", "[gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]");
1531                 }
1532             }
1533         }
1534
1535         break;
1536     }
1537
1538     case EOpTextureQuerySamples:
1539     case EOpImageQuerySamples:
1540         // GL_ARB_shader_texture_image_samples
1541         profileRequires(loc, ~EEsProfile, 450, E_GL_ARB_shader_texture_image_samples, "textureSamples and imageSamples");
1542         break;
1543
1544     case EOpImageAtomicAdd:
1545     case EOpImageAtomicMin:
1546     case EOpImageAtomicMax:
1547     case EOpImageAtomicAnd:
1548     case EOpImageAtomicOr:
1549     case EOpImageAtomicXor:
1550     case EOpImageAtomicExchange:
1551     case EOpImageAtomicCompSwap:
1552     {
1553         // Make sure the image types have the correct layout() format and correct argument types
1554         const TType& imageType = arg0->getType();
1555         if (imageType.getSampler().type == EbtInt || imageType.getSampler().type == EbtUint) {
1556             if (imageType.getQualifier().layoutFormat != ElfR32i && imageType.getQualifier().layoutFormat != ElfR32ui)
1557                 error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), "");
1558         } else {
1559             if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0)
1560                 error(loc, "only supported on integer images", fnCandidate.getName().c_str(), "");
1561             else if (imageType.getQualifier().layoutFormat != ElfR32f && profile == EEsProfile)
1562                 error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), "");
1563         }
1564
1565         break;
1566     }
1567
1568 #ifdef NV_EXTENSIONS
1569     case EOpAtomicAdd:
1570     case EOpAtomicMin:
1571     case EOpAtomicMax:
1572     case EOpAtomicAnd:
1573     case EOpAtomicOr:
1574     case EOpAtomicXor:
1575     case EOpAtomicExchange:
1576     case EOpAtomicCompSwap:
1577     {
1578         if (arg0->getType().getBasicType() == EbtInt64 || arg0->getType().getBasicType() == EbtUint64)
1579             requireExtensions(loc, 1, &E_GL_NV_shader_atomic_int64, fnCandidate.getName().c_str());
1580
1581         break;
1582     }
1583 #endif
1584
1585     case EOpInterpolateAtCentroid:
1586     case EOpInterpolateAtSample:
1587     case EOpInterpolateAtOffset:
1588 #ifdef AMD_EXTENSIONS
1589     case EOpInterpolateAtVertex:
1590 #endif
1591         // Make sure the first argument is an interpolant, or an array element of an interpolant
1592         if (arg0->getType().getQualifier().storage != EvqVaryingIn) {
1593             // It might still be an array element.
1594             //
1595             // We could check more, but the semantics of the first argument are already met; the
1596             // only way to turn an array into a float/vec* is array dereference and swizzle.
1597             //
1598             // ES and desktop 4.3 and earlier:  swizzles may not be used
1599             // desktop 4.4 and later: swizzles may be used
1600             bool swizzleOkay = (profile != EEsProfile) && (version >= 440);
1601             const TIntermTyped* base = TIntermediate::findLValueBase(arg0, swizzleOkay);
1602             if (base == nullptr || base->getType().getQualifier().storage != EvqVaryingIn)
1603                 error(loc, "first argument must be an interpolant, or interpolant-array element", fnCandidate.getName().c_str(), "");
1604         }
1605         break;
1606
1607     case EOpEmitStreamVertex:
1608     case EOpEndStreamPrimitive:
1609         intermediate.setMultiStream();
1610         break;
1611
1612     default:
1613         break;
1614     }
1615 }
1616
1617 extern bool PureOperatorBuiltins;
1618
1619 // Deprecated!  Use PureOperatorBuiltins == true instead, in which case this
1620 // functionality is handled in builtInOpCheck() instead of here.
1621 //
1622 // Do additional checking of built-in function calls that were not mapped
1623 // to built-in operations (e.g., texturing functions).
1624 //
1625 // Assumes there has been a semantically correct match to a built-in function.
1626 //
1627 void TParseContext::nonOpBuiltInCheck(const TSourceLoc& loc, const TFunction& fnCandidate, TIntermAggregate& callNode)
1628 {
1629     // Further maintenance of this function is deprecated, because the "correct"
1630     // future-oriented design is to not have to do string compares on function names.
1631
1632     // If PureOperatorBuiltins == true, then all built-ins should be mapped
1633     // to a TOperator, and this function would then never get called.
1634
1635     assert(PureOperatorBuiltins == false);
1636
1637     // built-in texturing functions get their return value precision from the precision of the sampler
1638     if (fnCandidate.getType().getQualifier().precision == EpqNone &&
1639         fnCandidate.getParamCount() > 0 && fnCandidate[0].type->getBasicType() == EbtSampler)
1640         callNode.getQualifier().precision = callNode.getSequence()[0]->getAsTyped()->getQualifier().precision;
1641
1642     if (fnCandidate.getName().compare(0, 7, "texture") == 0) {
1643         if (fnCandidate.getName().compare(0, 13, "textureGather") == 0) {
1644             TString featureString = fnCandidate.getName() + "(...)";
1645             const char* feature = featureString.c_str();
1646             profileRequires(loc, EEsProfile, 310, nullptr, feature);
1647
1648             int compArg = -1;  // track which argument, if any, is the constant component argument
1649             if (fnCandidate.getName().compare("textureGatherOffset") == 0) {
1650                 // GL_ARB_texture_gather is good enough for 2D non-shadow textures with no component argument
1651                 if (fnCandidate[0].type->getSampler().dim == Esd2D && ! fnCandidate[0].type->getSampler().shadow && fnCandidate.getParamCount() == 3)
1652                     profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_texture_gather, feature);
1653                 else
1654                     profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature);
1655                 int offsetArg = fnCandidate[0].type->getSampler().shadow ? 3 : 2;
1656                 if (! callNode.getSequence()[offsetArg]->getAsConstantUnion())
1657                     profileRequires(loc, EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5,
1658                                     "non-constant offset argument");
1659                 if (! fnCandidate[0].type->getSampler().shadow)
1660                     compArg = 3;
1661             } else if (fnCandidate.getName().compare("textureGatherOffsets") == 0) {
1662                 profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature);
1663                 if (! fnCandidate[0].type->getSampler().shadow)
1664                     compArg = 3;
1665                 // check for constant offsets
1666                 int offsetArg = fnCandidate[0].type->getSampler().shadow ? 3 : 2;
1667                 if (! callNode.getSequence()[offsetArg]->getAsConstantUnion())
1668                     error(loc, "must be a compile-time constant:", feature, "offsets argument");
1669             } else if (fnCandidate.getName().compare("textureGather") == 0) {
1670                 // More than two arguments needs gpu_shader5, and rectangular or shadow needs gpu_shader5,
1671                 // otherwise, need GL_ARB_texture_gather.
1672                 if (fnCandidate.getParamCount() > 2 || fnCandidate[0].type->getSampler().dim == EsdRect || fnCandidate[0].type->getSampler().shadow) {
1673                     profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature);
1674                     if (! fnCandidate[0].type->getSampler().shadow)
1675                         compArg = 2;
1676                 } else
1677                     profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_texture_gather, feature);
1678             }
1679
1680             if (compArg > 0 && compArg < fnCandidate.getParamCount()) {
1681                 if (callNode.getSequence()[compArg]->getAsConstantUnion()) {
1682                     int value = callNode.getSequence()[compArg]->getAsConstantUnion()->getConstArray()[0].getIConst();
1683                     if (value < 0 || value > 3)
1684                         error(loc, "must be 0, 1, 2, or 3:", feature, "component argument");
1685                 } else
1686                     error(loc, "must be a compile-time constant:", feature, "component argument");
1687             }
1688         } else {
1689             // this is only for functions not starting "textureGather"...
1690             if (fnCandidate.getName().find("Offset") != TString::npos) {
1691
1692                 // Handle texture-offset limits checking
1693                 int arg = -1;
1694                 if (fnCandidate.getName().compare("textureOffset") == 0)
1695                     arg = 2;
1696                 else if (fnCandidate.getName().compare("texelFetchOffset") == 0)
1697                     arg = 3;
1698                 else if (fnCandidate.getName().compare("textureProjOffset") == 0)
1699                     arg = 2;
1700                 else if (fnCandidate.getName().compare("textureLodOffset") == 0)
1701                     arg = 3;
1702                 else if (fnCandidate.getName().compare("textureProjLodOffset") == 0)
1703                     arg = 3;
1704                 else if (fnCandidate.getName().compare("textureGradOffset") == 0)
1705                     arg = 4;
1706                 else if (fnCandidate.getName().compare("textureProjGradOffset") == 0)
1707                     arg = 4;
1708
1709                 if (arg > 0) {
1710                     if (! callNode.getSequence()[arg]->getAsConstantUnion())
1711                         error(loc, "argument must be compile-time constant", "texel offset", "");
1712                     else {
1713                         const TType& type = callNode.getSequence()[arg]->getAsTyped()->getType();
1714                         for (int c = 0; c < type.getVectorSize(); ++c) {
1715                             int offset = callNode.getSequence()[arg]->getAsConstantUnion()->getConstArray()[c].getIConst();
1716                             if (offset > resources.maxProgramTexelOffset || offset < resources.minProgramTexelOffset)
1717                                 error(loc, "value is out of range:", "texel offset", "[gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]");
1718                         }
1719                     }
1720                 }
1721             }
1722         }
1723     }
1724
1725     // GL_ARB_shader_texture_image_samples
1726     if (fnCandidate.getName().compare(0, 14, "textureSamples") == 0 || fnCandidate.getName().compare(0, 12, "imageSamples") == 0)
1727         profileRequires(loc, ~EEsProfile, 450, E_GL_ARB_shader_texture_image_samples, "textureSamples and imageSamples");
1728
1729     if (fnCandidate.getName().compare(0, 11, "imageAtomic") == 0) {
1730         const TType& imageType = callNode.getSequence()[0]->getAsTyped()->getType();
1731         if (imageType.getSampler().type == EbtInt || imageType.getSampler().type == EbtUint) {
1732             if (imageType.getQualifier().layoutFormat != ElfR32i && imageType.getQualifier().layoutFormat != ElfR32ui)
1733                 error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), "");
1734         } else {
1735             if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0)
1736                 error(loc, "only supported on integer images", fnCandidate.getName().c_str(), "");
1737             else if (imageType.getQualifier().layoutFormat != ElfR32f && profile == EEsProfile)
1738                 error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), "");
1739         }
1740     }
1741 }
1742
1743 //
1744 // Do any extra checking for a user function call.
1745 //
1746 void TParseContext::userFunctionCallCheck(const TSourceLoc& loc, TIntermAggregate& callNode)
1747 {
1748     TIntermSequence& arguments = callNode.getSequence();
1749
1750     for (int i = 0; i < (int)arguments.size(); ++i)
1751         samplerConstructorLocationCheck(loc, "call argument", arguments[i]);
1752 }
1753
1754 //
1755 // Emit an error if this is a sampler constructor
1756 //
1757 void TParseContext::samplerConstructorLocationCheck(const TSourceLoc& loc, const char* token, TIntermNode* node)
1758 {
1759     if (node->getAsOperator() && node->getAsOperator()->getOp() == EOpConstructTextureSampler)
1760         error(loc, "sampler constructor must appear at point of use", token, "");
1761 }
1762
1763 //
1764 // Handle seeing a built-in constructor in a grammar production.
1765 //
1766 TFunction* TParseContext::handleConstructorCall(const TSourceLoc& loc, const TPublicType& publicType)
1767 {
1768     TType type(publicType);
1769     type.getQualifier().precision = EpqNone;
1770
1771     if (type.isArray()) {
1772         profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed constructor");
1773         profileRequires(loc, EEsProfile, 300, nullptr, "arrayed constructor");
1774     }
1775
1776     TOperator op = intermediate.mapTypeToConstructorOp(type);
1777
1778     if (op == EOpNull) {
1779         error(loc, "cannot construct this type", type.getBasicString(), "");
1780         op = EOpConstructFloat;
1781         TType errorType(EbtFloat);
1782         type.shallowCopy(errorType);
1783     }
1784
1785     TString empty("");
1786
1787     return new TFunction(&empty, type, op);
1788 }
1789
1790 // Handle seeing a precision qualifier in the grammar.
1791 void TParseContext::handlePrecisionQualifier(const TSourceLoc& /*loc*/, TQualifier& qualifier, TPrecisionQualifier precision)
1792 {
1793     if (obeyPrecisionQualifiers())
1794         qualifier.precision = precision;
1795 }
1796
1797 // Check for messages to give on seeing a precision qualifier used in a
1798 // declaration in the grammar.
1799 void TParseContext::checkPrecisionQualifier(const TSourceLoc& loc, TPrecisionQualifier)
1800 {
1801     if (precisionManager.shouldWarnAboutDefaults()) {
1802         warn(loc, "all default precisions are highp; use precision statements to quiet warning, e.g.:\n"
1803                   "         \"precision mediump int; precision highp float;\"", "", "");
1804         precisionManager.defaultWarningGiven();
1805     }
1806 }
1807
1808 //
1809 // Same error message for all places assignments don't work.
1810 //
1811 void TParseContext::assignError(const TSourceLoc& loc, const char* op, TString left, TString right)
1812 {
1813     error(loc, "", op, "cannot convert from '%s' to '%s'",
1814           right.c_str(), left.c_str());
1815 }
1816
1817 //
1818 // Same error message for all places unary operations don't work.
1819 //
1820 void TParseContext::unaryOpError(const TSourceLoc& loc, const char* op, TString operand)
1821 {
1822    error(loc, " wrong operand type", op,
1823           "no operation '%s' exists that takes an operand of type %s (or there is no acceptable conversion)",
1824           op, operand.c_str());
1825 }
1826
1827 //
1828 // Same error message for all binary operations don't work.
1829 //
1830 void TParseContext::binaryOpError(const TSourceLoc& loc, const char* op, TString left, TString right)
1831 {
1832     error(loc, " wrong operand types:", op,
1833             "no operation '%s' exists that takes a left-hand operand of type '%s' and "
1834             "a right operand of type '%s' (or there is no acceptable conversion)",
1835             op, left.c_str(), right.c_str());
1836 }
1837
1838 //
1839 // A basic type of EbtVoid is a key that the name string was seen in the source, but
1840 // it was not found as a variable in the symbol table.  If so, give the error
1841 // message and insert a dummy variable in the symbol table to prevent future errors.
1842 //
1843 void TParseContext::variableCheck(TIntermTyped*& nodePtr)
1844 {
1845     TIntermSymbol* symbol = nodePtr->getAsSymbolNode();
1846     if (! symbol)
1847         return;
1848
1849     if (symbol->getType().getBasicType() == EbtVoid) {
1850         const char *extraInfoFormat = "";
1851         if (spvVersion.vulkan != 0 && symbol->getName() == "gl_VertexID") {
1852           extraInfoFormat = "(Did you mean gl_VertexIndex?)";
1853         } else if (spvVersion.vulkan != 0 && symbol->getName() == "gl_InstanceID") {
1854           extraInfoFormat = "(Did you mean gl_InstanceIndex?)";
1855         }
1856         error(symbol->getLoc(), "undeclared identifier", symbol->getName().c_str(), extraInfoFormat);
1857
1858         // Add to symbol table to prevent future error messages on the same name
1859         if (symbol->getName().size() > 0) {
1860             TVariable* fakeVariable = new TVariable(&symbol->getName(), TType(EbtFloat));
1861             symbolTable.insert(*fakeVariable);
1862
1863             // substitute a symbol node for this new variable
1864             nodePtr = intermediate.addSymbol(*fakeVariable, symbol->getLoc());
1865         }
1866     } else {
1867         switch (symbol->getQualifier().storage) {
1868         case EvqPointCoord:
1869             profileRequires(symbol->getLoc(), ENoProfile, 120, nullptr, "gl_PointCoord");
1870             break;
1871         default: break; // some compilers want this
1872         }
1873     }
1874 }
1875
1876 //
1877 // Both test and if necessary, spit out an error, to see if the node is really
1878 // an l-value that can be operated on this way.
1879 //
1880 // Returns true if there was an error.
1881 //
1882 bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node)
1883 {
1884     TIntermBinary* binaryNode = node->getAsBinaryNode();
1885
1886     if (binaryNode) {
1887         bool errorReturn = false;
1888
1889         switch(binaryNode->getOp()) {
1890         case EOpIndexDirect:
1891         case EOpIndexIndirect:
1892             // ...  tessellation control shader ...
1893             // If a per-vertex output variable is used as an l-value, it is a
1894             // compile-time or link-time error if the expression indicating the
1895             // vertex index is not the identifier gl_InvocationID.
1896             if (language == EShLangTessControl) {
1897                 const TType& leftType = binaryNode->getLeft()->getType();
1898                 if (leftType.getQualifier().storage == EvqVaryingOut && ! leftType.getQualifier().patch && binaryNode->getLeft()->getAsSymbolNode()) {
1899                     // we have a per-vertex output
1900                     const TIntermSymbol* rightSymbol = binaryNode->getRight()->getAsSymbolNode();
1901                     if (! rightSymbol || rightSymbol->getQualifier().builtIn != EbvInvocationId)
1902                         error(loc, "tessellation-control per-vertex output l-value must be indexed with gl_InvocationID", "[]", "");
1903                 }
1904             }
1905
1906             break; // left node is checked by base class
1907         case EOpIndexDirectStruct:
1908             break; // left node is checked by base class
1909         case EOpVectorSwizzle:
1910             errorReturn = lValueErrorCheck(loc, op, binaryNode->getLeft());
1911             if (!errorReturn) {
1912                 int offset[4] = {0,0,0,0};
1913
1914                 TIntermTyped* rightNode = binaryNode->getRight();
1915                 TIntermAggregate *aggrNode = rightNode->getAsAggregate();
1916
1917                 for (TIntermSequence::iterator p = aggrNode->getSequence().begin();
1918                                                p != aggrNode->getSequence().end(); p++) {
1919                     int value = (*p)->getAsTyped()->getAsConstantUnion()->getConstArray()[0].getIConst();
1920                     offset[value]++;
1921                     if (offset[value] > 1) {
1922                         error(loc, " l-value of swizzle cannot have duplicate components", op, "", "");
1923
1924                         return true;
1925                     }
1926                 }
1927             }
1928
1929             return errorReturn;
1930         default:
1931             break;
1932         }
1933
1934         if (errorReturn) {
1935             error(loc, " l-value required", op, "", "");
1936             return true;
1937         }
1938     }
1939
1940     // Let the base class check errors
1941     if (TParseContextBase::lValueErrorCheck(loc, op, node))
1942         return true;
1943
1944     const char* symbol = nullptr;
1945     TIntermSymbol* symNode = node->getAsSymbolNode();
1946     if (symNode != nullptr)
1947         symbol = symNode->getName().c_str();
1948
1949     const char* message = nullptr;
1950     switch (node->getQualifier().storage) {
1951     case EvqVaryingIn:      message = "can't modify shader input";   break;
1952     case EvqInstanceId:     message = "can't modify gl_InstanceID";  break;
1953     case EvqVertexId:       message = "can't modify gl_VertexID";    break;
1954     case EvqFace:           message = "can't modify gl_FrontFace";   break;
1955     case EvqFragCoord:      message = "can't modify gl_FragCoord";   break;
1956     case EvqPointCoord:     message = "can't modify gl_PointCoord";  break;
1957     case EvqFragDepth:
1958         intermediate.setDepthReplacing();
1959         // "In addition, it is an error to statically write to gl_FragDepth in the fragment shader."
1960         if (profile == EEsProfile && intermediate.getEarlyFragmentTests())
1961             message = "can't modify gl_FragDepth if using early_fragment_tests";
1962         break;
1963
1964     default:
1965         break;
1966     }
1967
1968     if (message == nullptr && binaryNode == nullptr && symNode == nullptr) {
1969         error(loc, " l-value required", op, "", "");
1970
1971         return true;
1972     }
1973
1974     //
1975     // Everything else is okay, no error.
1976     //
1977     if (message == nullptr)
1978         return false;
1979
1980     //
1981     // If we get here, we have an error and a message.
1982     //
1983     if (symNode)
1984         error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message);
1985     else
1986         error(loc, " l-value required", op, "(%s)", message);
1987
1988     return true;
1989 }
1990
1991 // Test for and give an error if the node can't be read from.
1992 void TParseContext::rValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node)
1993 {
1994     // Let the base class check errors
1995     TParseContextBase::rValueErrorCheck(loc, op, node);
1996
1997 #ifdef AMD_EXTENSIONS
1998     TIntermSymbol* symNode = node->getAsSymbolNode();
1999     if (!(symNode && symNode->getQualifier().writeonly)) // base class checks
2000         if (symNode && symNode->getQualifier().explicitInterp)
2001             error(loc, "can't read from explicitly-interpolated object: ", op, symNode->getName().c_str());
2002 #endif
2003 }
2004
2005 //
2006 // Both test, and if necessary spit out an error, to see if the node is really
2007 // a constant.
2008 //
2009 void TParseContext::constantValueCheck(TIntermTyped* node, const char* token)
2010 {
2011     if (! node->getQualifier().isConstant())
2012         error(node->getLoc(), "constant expression required", token, "");
2013 }
2014
2015 //
2016 // Both test, and if necessary spit out an error, to see if the node is really
2017 // an integer.
2018 //
2019 void TParseContext::integerCheck(const TIntermTyped* node, const char* token)
2020 {
2021     if ((node->getBasicType() == EbtInt || node->getBasicType() == EbtUint) && node->isScalar())
2022         return;
2023
2024     error(node->getLoc(), "scalar integer expression required", token, "");
2025 }
2026
2027 //
2028 // Both test, and if necessary spit out an error, to see if we are currently
2029 // globally scoped.
2030 //
2031 void TParseContext::globalCheck(const TSourceLoc& loc, const char* token)
2032 {
2033     if (! symbolTable.atGlobalLevel())
2034         error(loc, "not allowed in nested scope", token, "");
2035 }
2036
2037 //
2038 // Reserved errors for GLSL.
2039 //
2040 void TParseContext::reservedErrorCheck(const TSourceLoc& loc, const TString& identifier)
2041 {
2042     // "Identifiers starting with "gl_" are reserved for use by OpenGL, and may not be
2043     // declared in a shader; this results in a compile-time error."
2044     if (! symbolTable.atBuiltInLevel()) {
2045         if (builtInName(identifier))
2046             error(loc, "identifiers starting with \"gl_\" are reserved", identifier.c_str(), "");
2047
2048         // "__" are not supposed to be an error.  ES 310 (and desktop) added the clarification:
2049         // "In addition, all identifiers containing two consecutive underscores (__) are
2050         // reserved; using such a name does not itself result in an error, but may result
2051         // in undefined behavior."
2052         // however, before that, ES tests required an error.
2053         if (identifier.find("__") != TString::npos) {
2054             if (profile == EEsProfile && version <= 300)
2055                 error(loc, "identifiers containing consecutive underscores (\"__\") are reserved, and an error if version <= 300", identifier.c_str(), "");
2056             else
2057                 warn(loc, "identifiers containing consecutive underscores (\"__\") are reserved", identifier.c_str(), "");
2058         }
2059     }
2060 }
2061
2062 //
2063 // Reserved errors for the preprocessor.
2064 //
2065 void TParseContext::reservedPpErrorCheck(const TSourceLoc& loc, const char* identifier, const char* op)
2066 {
2067     // "__" are not supposed to be an error.  ES 310 (and desktop) added the clarification:
2068     // "All macro names containing two consecutive underscores ( __ ) are reserved;
2069     // defining such a name does not itself result in an error, but may result in
2070     // undefined behavior.  All macro names prefixed with "GL_" ("GL" followed by a
2071     // single underscore) are also reserved, and defining such a name results in a
2072     // compile-time error."
2073     // however, before that, ES tests required an error.
2074     if (strncmp(identifier, "GL_", 3) == 0)
2075         ppError(loc, "names beginning with \"GL_\" can't be (un)defined:", op,  identifier);
2076     else if (strncmp(identifier, "defined", 8) == 0)
2077         ppError(loc, "\"defined\" can't be (un)defined:", op,  identifier);
2078     else if (strstr(identifier, "__") != 0) {
2079         if (profile == EEsProfile && version >= 300 &&
2080             (strcmp(identifier, "__LINE__") == 0 ||
2081              strcmp(identifier, "__FILE__") == 0 ||
2082              strcmp(identifier, "__VERSION__") == 0))
2083             ppError(loc, "predefined names can't be (un)defined:", op,  identifier);
2084         else {
2085             if (profile == EEsProfile && version <= 300)
2086                 ppError(loc, "names containing consecutive underscores are reserved, and an error if version <= 300:", op, identifier);
2087             else
2088                 ppWarn(loc, "names containing consecutive underscores are reserved:", op, identifier);
2089         }
2090     }
2091 }
2092
2093 //
2094 // See if this version/profile allows use of the line-continuation character '\'.
2095 //
2096 // Returns true if a line continuation should be done.
2097 //
2098 bool TParseContext::lineContinuationCheck(const TSourceLoc& loc, bool endOfComment)
2099 {
2100     const char* message = "line continuation";
2101
2102     bool lineContinuationAllowed = (profile == EEsProfile && version >= 300) ||
2103                                    (profile != EEsProfile && (version >= 420 || extensionTurnedOn(E_GL_ARB_shading_language_420pack)));
2104
2105     if (endOfComment) {
2106         if (lineContinuationAllowed)
2107             warn(loc, "used at end of comment; the following line is still part of the comment", message, "");
2108         else
2109             warn(loc, "used at end of comment, but this version does not provide line continuation", message, "");
2110
2111         return lineContinuationAllowed;
2112     }
2113
2114     if (relaxedErrors()) {
2115         if (! lineContinuationAllowed)
2116             warn(loc, "not allowed in this version", message, "");
2117         return true;
2118     } else {
2119         profileRequires(loc, EEsProfile, 300, nullptr, message);
2120         profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, message);
2121     }
2122
2123     return lineContinuationAllowed;
2124 }
2125
2126 bool TParseContext::builtInName(const TString& identifier)
2127 {
2128     return identifier.compare(0, 3, "gl_") == 0;
2129 }
2130
2131 //
2132 // Make sure there is enough data and not too many arguments provided to the
2133 // constructor to build something of the type of the constructor.  Also returns
2134 // the type of the constructor.
2135 //
2136 // Part of establishing type is establishing specialization-constness.
2137 // We don't yet know "top down" whether type is a specialization constant,
2138 // but a const constructor can becomes a specialization constant if any of
2139 // its children are, subject to KHR_vulkan_glsl rules:
2140 //
2141 //     - int(), uint(), and bool() constructors for type conversions
2142 //       from any of the following types to any of the following types:
2143 //         * int
2144 //         * uint
2145 //         * bool
2146 //     - vector versions of the above conversion constructors
2147 //
2148 // Returns true if there was an error in construction.
2149 //
2150 bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, TFunction& function, TOperator op, TType& type)
2151 {
2152     type.shallowCopy(function.getType());
2153
2154     bool constructingMatrix = false;
2155     switch(op) {
2156     case EOpConstructTextureSampler:
2157         return constructorTextureSamplerError(loc, function);
2158     case EOpConstructMat2x2:
2159     case EOpConstructMat2x3:
2160     case EOpConstructMat2x4:
2161     case EOpConstructMat3x2:
2162     case EOpConstructMat3x3:
2163     case EOpConstructMat3x4:
2164     case EOpConstructMat4x2:
2165     case EOpConstructMat4x3:
2166     case EOpConstructMat4x4:
2167     case EOpConstructDMat2x2:
2168     case EOpConstructDMat2x3:
2169     case EOpConstructDMat2x4:
2170     case EOpConstructDMat3x2:
2171     case EOpConstructDMat3x3:
2172     case EOpConstructDMat3x4:
2173     case EOpConstructDMat4x2:
2174     case EOpConstructDMat4x3:
2175     case EOpConstructDMat4x4:
2176 #ifdef AMD_EXTENSIONS
2177     case EOpConstructF16Mat2x2:
2178     case EOpConstructF16Mat2x3:
2179     case EOpConstructF16Mat2x4:
2180     case EOpConstructF16Mat3x2:
2181     case EOpConstructF16Mat3x3:
2182     case EOpConstructF16Mat3x4:
2183     case EOpConstructF16Mat4x2:
2184     case EOpConstructF16Mat4x3:
2185     case EOpConstructF16Mat4x4:
2186 #endif
2187         constructingMatrix = true;
2188         break;
2189     default:
2190         break;
2191     }
2192
2193     //
2194     // Walk the arguments for first-pass checks and collection of information.
2195     //
2196
2197     int size = 0;
2198     bool constType = true;
2199     bool specConstType = false;   // value is only valid if constType is true
2200     bool full = false;
2201     bool overFull = false;
2202     bool matrixInMatrix = false;
2203     bool arrayArg = false;
2204     bool floatArgument = false;
2205     for (int arg = 0; arg < function.getParamCount(); ++arg) {
2206         if (function[arg].type->isArray()) {
2207             if (! function[arg].type->isExplicitlySizedArray()) {
2208                 // Can't construct from an unsized array.
2209                 error(loc, "array argument must be sized", "constructor", "");
2210                 return true;
2211             }
2212             arrayArg = true;
2213         }
2214         if (constructingMatrix && function[arg].type->isMatrix())
2215             matrixInMatrix = true;
2216
2217         // 'full' will go to true when enough args have been seen.  If we loop
2218         // again, there is an extra argument.
2219         if (full) {
2220             // For vectors and matrices, it's okay to have too many components
2221             // available, but not okay to have unused arguments.
2222             overFull = true;
2223         }
2224
2225         size += function[arg].type->computeNumComponents();
2226         if (op != EOpConstructStruct && ! type.isArray() && size >= type.computeNumComponents())
2227             full = true;
2228
2229         if (! function[arg].type->getQualifier().isConstant())
2230             constType = false;
2231         if (function[arg].type->getQualifier().isSpecConstant())
2232             specConstType = true;
2233         if (function[arg].type->isFloatingDomain())
2234             floatArgument = true;
2235     }
2236
2237     // inherit constness from children
2238     if (constType) {
2239         bool makeSpecConst;
2240         // Finish pinning down spec-const semantics
2241         if (specConstType) {
2242             switch (op) {
2243             case EOpConstructInt:
2244             case EOpConstructUint:
2245             case EOpConstructInt64:
2246             case EOpConstructUint64:
2247 #ifdef AMD_EXTENSIONS
2248             case EOpConstructInt16:
2249             case EOpConstructUint16:
2250 #endif
2251             case EOpConstructBool:
2252             case EOpConstructBVec2:
2253             case EOpConstructBVec3:
2254             case EOpConstructBVec4:
2255             case EOpConstructIVec2:
2256             case EOpConstructIVec3:
2257             case EOpConstructIVec4:
2258             case EOpConstructUVec2:
2259             case EOpConstructUVec3:
2260             case EOpConstructUVec4:
2261             case EOpConstructI64Vec2:
2262             case EOpConstructI64Vec3:
2263             case EOpConstructI64Vec4:
2264             case EOpConstructU64Vec2:
2265             case EOpConstructU64Vec3:
2266             case EOpConstructU64Vec4:
2267 #ifdef AMD_EXTENSIONS
2268             case EOpConstructI16Vec2:
2269             case EOpConstructI16Vec3:
2270             case EOpConstructI16Vec4:
2271             case EOpConstructU16Vec2:
2272             case EOpConstructU16Vec3:
2273             case EOpConstructU16Vec4:
2274 #endif
2275                 // This was the list of valid ones, if they aren't converting from float
2276                 // and aren't making an array.
2277                 makeSpecConst = ! floatArgument && ! type.isArray();
2278                 break;
2279             default:
2280                 // anything else wasn't white-listed in the spec as a conversion
2281                 makeSpecConst = false;
2282                 break;
2283             }
2284         } else
2285             makeSpecConst = false;
2286
2287         if (makeSpecConst)
2288             type.getQualifier().makeSpecConstant();
2289         else if (specConstType)
2290             type.getQualifier().makeTemporary();
2291         else
2292             type.getQualifier().storage = EvqConst;
2293     }
2294
2295     if (type.isArray()) {
2296         if (function.getParamCount() == 0) {
2297             error(loc, "array constructor must have at least one argument", "constructor", "");
2298             return true;
2299         }
2300
2301         if (type.isImplicitlySizedArray()) {
2302             // auto adapt the constructor type to the number of arguments
2303             type.changeOuterArraySize(function.getParamCount());
2304         } else if (type.getOuterArraySize() != function.getParamCount()) {
2305             error(loc, "array constructor needs one argument per array element", "constructor", "");
2306             return true;
2307         }
2308
2309         if (type.isArrayOfArrays()) {
2310             // Types have to match, but we're still making the type.
2311             // Finish making the type, and the comparison is done later
2312             // when checking for conversion.
2313             TArraySizes& arraySizes = type.getArraySizes();
2314
2315             // At least the dimensionalities have to match.
2316             if (! function[0].type->isArray() || arraySizes.getNumDims() != function[0].type->getArraySizes().getNumDims() + 1) {
2317                 error(loc, "array constructor argument not correct type to construct array element", "constructor", "");
2318                 return true;
2319             }
2320
2321             if (arraySizes.isInnerImplicit()) {
2322                 // "Arrays of arrays ..., and the size for any dimension is optional"
2323                 // That means we need to adopt (from the first argument) the other array sizes into the type.
2324                 for (int d = 1; d < arraySizes.getNumDims(); ++d) {
2325                     if (arraySizes.getDimSize(d) == UnsizedArraySize) {
2326                         arraySizes.setDimSize(d, function[0].type->getArraySizes().getDimSize(d - 1));
2327                     }
2328                 }
2329             }
2330         }
2331     }
2332
2333     if (arrayArg && op != EOpConstructStruct && ! type.isArrayOfArrays()) {
2334         error(loc, "constructing non-array constituent from array argument", "constructor", "");
2335         return true;
2336     }
2337
2338     if (matrixInMatrix && ! type.isArray()) {
2339         profileRequires(loc, ENoProfile, 120, nullptr, "constructing matrix from matrix");
2340
2341         // "If a matrix argument is given to a matrix constructor,
2342         // it is a compile-time error to have any other arguments."
2343         if (function.getParamCount() != 1)
2344             error(loc, "matrix constructed from matrix can only have one argument", "constructor", "");
2345         return false;
2346     }
2347
2348     if (overFull) {
2349         error(loc, "too many arguments", "constructor", "");
2350         return true;
2351     }
2352
2353     if (op == EOpConstructStruct && ! type.isArray() && (int)type.getStruct()->size() != function.getParamCount()) {
2354         error(loc, "Number of constructor parameters does not match the number of structure fields", "constructor", "");
2355         return true;
2356     }
2357
2358     if ((op != EOpConstructStruct && size != 1 && size < type.computeNumComponents()) ||
2359         (op == EOpConstructStruct && size < type.computeNumComponents())) {
2360         error(loc, "not enough data provided for construction", "constructor", "");
2361         return true;
2362     }
2363
2364     TIntermTyped* typed = node->getAsTyped();
2365     if (typed == nullptr) {
2366         error(loc, "constructor argument does not have a type", "constructor", "");
2367         return true;
2368     }
2369     if (op != EOpConstructStruct && typed->getBasicType() == EbtSampler) {
2370         error(loc, "cannot convert a sampler", "constructor", "");
2371         return true;
2372     }
2373     if (op != EOpConstructStruct && typed->getBasicType() == EbtAtomicUint) {
2374         error(loc, "cannot convert an atomic_uint", "constructor", "");
2375         return true;
2376     }
2377     if (typed->getBasicType() == EbtVoid) {
2378         error(loc, "cannot convert a void", "constructor", "");
2379         return true;
2380     }
2381
2382     return false;
2383 }
2384
2385 // Verify all the correct semantics for constructing a combined texture/sampler.
2386 // Return true if the semantics are incorrect.
2387 bool TParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const TFunction& function)
2388 {
2389     TString constructorName = function.getType().getBasicTypeString();  // TODO: performance: should not be making copy; interface needs to change
2390     const char* token = constructorName.c_str();
2391
2392     // exactly two arguments needed
2393     if (function.getParamCount() != 2) {
2394         error(loc, "sampler-constructor requires two arguments", token, "");
2395         return true;
2396     }
2397
2398     // For now, not allowing arrayed constructors, the rest of this function
2399     // is set up to allow them, if this test is removed:
2400     if (function.getType().isArray()) {
2401         error(loc, "sampler-constructor cannot make an array of samplers", token, "");
2402         return true;
2403     }
2404
2405     // first argument
2406     //  * the constructor's first argument must be a texture type
2407     //  * the dimensionality (1D, 2D, 3D, Cube, Rect, Buffer, MS, and Array)
2408     //    of the texture type must match that of the constructed sampler type
2409     //    (that is, the suffixes of the type of the first argument and the
2410     //    type of the constructor will be spelled the same way)
2411     if (function[0].type->getBasicType() != EbtSampler ||
2412         ! function[0].type->getSampler().isTexture() ||
2413         function[0].type->isArray()) {
2414         error(loc, "sampler-constructor first argument must be a scalar textureXXX type", token, "");
2415         return true;
2416     }
2417     // simulate the first argument's impact on the result type, so it can be compared with the encapsulated operator!=()
2418     TSampler texture = function.getType().getSampler();
2419     texture.combined = false;
2420     texture.shadow = false;
2421     if (texture != function[0].type->getSampler()) {
2422         error(loc, "sampler-constructor first argument must match type and dimensionality of constructor type", token, "");
2423         return true;
2424     }
2425
2426     // second argument
2427     //   * the constructor's second argument must be a scalar of type
2428     //     *sampler* or *samplerShadow*
2429     //   * the presence or absence of depth comparison (Shadow) must match
2430     //     between the constructed sampler type and the type of the second argument
2431     if (  function[1].type->getBasicType() != EbtSampler ||
2432         ! function[1].type->getSampler().isPureSampler() ||
2433           function[1].type->isArray()) {
2434         error(loc, "sampler-constructor second argument must be a scalar type 'sampler'", token, "");
2435         return true;
2436     }
2437     if (function.getType().getSampler().shadow != function[1].type->getSampler().shadow) {
2438         error(loc, "sampler-constructor second argument presence of shadow must match constructor presence of shadow", token, "");
2439         return true;
2440     }
2441
2442     return false;
2443 }
2444
2445 // Checks to see if a void variable has been declared and raise an error message for such a case
2446 //
2447 // returns true in case of an error
2448 //
2449 bool TParseContext::voidErrorCheck(const TSourceLoc& loc, const TString& identifier, const TBasicType basicType)
2450 {
2451     if (basicType == EbtVoid) {
2452         error(loc, "illegal use of type 'void'", identifier.c_str(), "");
2453         return true;
2454     }
2455
2456     return false;
2457 }
2458
2459 // Checks to see if the node (for the expression) contains a scalar boolean expression or not
2460 void TParseContext::boolCheck(const TSourceLoc& loc, const TIntermTyped* type)
2461 {
2462     if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector())
2463         error(loc, "boolean expression expected", "", "");
2464 }
2465
2466 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
2467 void TParseContext::boolCheck(const TSourceLoc& loc, const TPublicType& pType)
2468 {
2469     if (pType.basicType != EbtBool || pType.arraySizes || pType.matrixCols > 1 || (pType.vectorSize > 1))
2470         error(loc, "boolean expression expected", "", "");
2471 }
2472
2473 void TParseContext::samplerCheck(const TSourceLoc& loc, const TType& type, const TString& identifier, TIntermTyped* /*initializer*/)
2474 {
2475     // Check that the appropriate extension is enabled if external sampler is used.
2476     // There are two extensions. The correct one must be used based on GLSL version.
2477     if (type.getBasicType() == EbtSampler && type.getSampler().external) {
2478         if (version < 300) {
2479             requireExtensions(loc, 1, &E_GL_OES_EGL_image_external, "samplerExternalOES");
2480         } else {
2481             requireExtensions(loc, 1, &E_GL_OES_EGL_image_external_essl3, "samplerExternalOES");
2482         }
2483     }
2484
2485     if (type.getQualifier().storage == EvqUniform)
2486         return;
2487
2488     if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtSampler))
2489         error(loc, "non-uniform struct contains a sampler or image:", type.getBasicTypeString().c_str(), identifier.c_str());
2490     else if (type.getBasicType() == EbtSampler && type.getQualifier().storage != EvqUniform) {
2491         // non-uniform sampler
2492         // not yet:  okay if it has an initializer
2493         // if (! initializer)
2494         error(loc, "sampler/image types can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str());
2495     }
2496 }
2497
2498 void TParseContext::atomicUintCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
2499 {
2500     if (type.getQualifier().storage == EvqUniform)
2501         return;
2502
2503     if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtAtomicUint))
2504         error(loc, "non-uniform struct contains an atomic_uint:", type.getBasicTypeString().c_str(), identifier.c_str());
2505     else if (type.getBasicType() == EbtAtomicUint && type.getQualifier().storage != EvqUniform)
2506         error(loc, "atomic_uints can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str());
2507 }
2508
2509 void TParseContext::transparentOpaqueCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
2510 {
2511     if (parsingBuiltins)
2512         return;
2513
2514     if (type.getQualifier().storage != EvqUniform)
2515         return;
2516
2517     if (type.containsNonOpaque()) {
2518         // Vulkan doesn't allow transparent uniforms outside of blocks
2519         if (spvVersion.vulkan > 0)
2520             vulkanRemoved(loc, "non-opaque uniforms outside a block");
2521         // OpenGL wants locations on these (unless they are getting automapped)
2522         if (spvVersion.openGl > 0 && !type.getQualifier().hasLocation() && !intermediate.getAutoMapLocations())
2523             error(loc, "non-opaque uniform variables need a layout(location=L)", identifier.c_str(), "");
2524     }
2525 }
2526
2527 //
2528 // Check/fix just a full qualifier (no variables or types yet, but qualifier is complete) at global level.
2529 //
2530 void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& qualifier)
2531 {
2532     // move from parameter/unknown qualifiers to pipeline in/out qualifiers
2533     switch (qualifier.storage) {
2534     case EvqIn:
2535         profileRequires(loc, ENoProfile, 130, nullptr, "in for stage inputs");
2536         profileRequires(loc, EEsProfile, 300, nullptr, "in for stage inputs");
2537         qualifier.storage = EvqVaryingIn;
2538         break;
2539     case EvqOut:
2540         profileRequires(loc, ENoProfile, 130, nullptr, "out for stage outputs");
2541         profileRequires(loc, EEsProfile, 300, nullptr, "out for stage outputs");
2542         qualifier.storage = EvqVaryingOut;
2543         break;
2544     case EvqInOut:
2545         qualifier.storage = EvqVaryingIn;
2546         error(loc, "cannot use 'inout' at global scope", "", "");
2547         break;
2548     default:
2549         break;
2550     }
2551
2552     invariantCheck(loc, qualifier);
2553 }
2554
2555 //
2556 // Check a full qualifier and type (no variable yet) at global level.
2557 //
2558 void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQualifier& qualifier, const TPublicType& publicType)
2559 {
2560     if (! symbolTable.atGlobalLevel())
2561         return;
2562
2563     if (qualifier.isMemory() && ! publicType.isImage() && publicType.qualifier.storage != EvqBuffer)
2564         error(loc, "memory qualifiers cannot be used on this type", "", "");
2565
2566     if (qualifier.storage == EvqBuffer && publicType.basicType != EbtBlock)
2567         error(loc, "buffers can be declared only as blocks", "buffer", "");
2568
2569     if (qualifier.storage != EvqVaryingIn && qualifier.storage != EvqVaryingOut)
2570         return;
2571
2572     if (publicType.shaderQualifiers.blendEquation)
2573         error(loc, "can only be applied to a standalone 'out'", "blend equation", "");
2574
2575     // now, knowing it is a shader in/out, do all the in/out semantic checks
2576
2577     if (publicType.basicType == EbtBool && !parsingBuiltins) {
2578         error(loc, "cannot be bool", GetStorageQualifierString(qualifier.storage), "");
2579         return;
2580     }
2581
2582     if (publicType.basicType == EbtInt   || publicType.basicType == EbtUint   ||
2583 #ifdef AMD_EXTENSIONS
2584         publicType.basicType == EbtInt16 || publicType.basicType == EbtUint16 ||
2585 #endif
2586         publicType.basicType == EbtInt64 || publicType.basicType == EbtUint64 ||
2587         publicType.basicType == EbtDouble)
2588         profileRequires(loc, EEsProfile, 300, nullptr, "shader input/output");
2589
2590 #ifdef AMD_EXTENSIONS
2591     if (! qualifier.flat && ! qualifier.explicitInterp) {
2592 #else
2593     if (!qualifier.flat) {
2594 #endif
2595         if (publicType.basicType == EbtInt    || publicType.basicType == EbtUint   ||
2596 #ifdef AMD_EXTENSIONS
2597             publicType.basicType == EbtInt16  || publicType.basicType == EbtUint16 ||
2598 #endif
2599             publicType.basicType == EbtInt64  || publicType.basicType == EbtUint64 ||
2600             publicType.basicType == EbtDouble ||
2601             (publicType.userDef && (publicType.userDef->containsBasicType(EbtInt)    ||
2602                                     publicType.userDef->containsBasicType(EbtUint)   ||
2603                                     publicType.userDef->containsBasicType(EbtInt64)  ||
2604                                     publicType.userDef->containsBasicType(EbtUint64) ||
2605                                     publicType.userDef->containsBasicType(EbtDouble)))) {
2606             if (qualifier.storage == EvqVaryingIn && language == EShLangFragment)
2607                 error(loc, "must be qualified as flat", TType::getBasicString(publicType.basicType), GetStorageQualifierString(qualifier.storage));
2608             else if (qualifier.storage == EvqVaryingOut && language == EShLangVertex && version == 300)
2609                 error(loc, "must be qualified as flat", TType::getBasicString(publicType.basicType), GetStorageQualifierString(qualifier.storage));
2610         }
2611     }
2612
2613     if (qualifier.patch && qualifier.isInterpolation())
2614         error(loc, "cannot use interpolation qualifiers with patch", "patch", "");
2615
2616     if (qualifier.storage == EvqVaryingIn) {
2617         switch (language) {
2618         case EShLangVertex:
2619             if (publicType.basicType == EbtStruct) {
2620                 error(loc, "cannot be a structure or array", GetStorageQualifierString(qualifier.storage), "");
2621                 return;
2622             }
2623             if (publicType.arraySizes) {
2624                 requireProfile(loc, ~EEsProfile, "vertex input arrays");
2625                 profileRequires(loc, ENoProfile, 150, nullptr, "vertex input arrays");
2626             }
2627             if (publicType.basicType == EbtDouble)
2628                 profileRequires(loc, ~EEsProfile, 410, nullptr, "vertex-shader `double` type input");
2629             if (qualifier.isAuxiliary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.invariant)
2630                 error(loc, "vertex input cannot be further qualified", "", "");
2631             break;
2632
2633         case EShLangTessControl:
2634             if (qualifier.patch)
2635                 error(loc, "can only use on output in tessellation-control shader", "patch", "");
2636             break;
2637
2638         case EShLangTessEvaluation:
2639             break;
2640
2641         case EShLangGeometry:
2642             break;
2643
2644         case EShLangFragment:
2645             if (publicType.userDef) {
2646                 profileRequires(loc, EEsProfile, 300, nullptr, "fragment-shader struct input");
2647                 profileRequires(loc, ~EEsProfile, 150, nullptr, "fragment-shader struct input");
2648                 if (publicType.userDef->containsStructure())
2649                     requireProfile(loc, ~EEsProfile, "fragment-shader struct input containing structure");
2650                 if (publicType.userDef->containsArray())
2651                     requireProfile(loc, ~EEsProfile, "fragment-shader struct input containing an array");
2652             }
2653             break;
2654
2655         case EShLangCompute:
2656             if (! symbolTable.atBuiltInLevel())
2657                 error(loc, "global storage input qualifier cannot be used in a compute shader", "in", "");
2658             break;
2659
2660         default:
2661             break;
2662         }
2663     } else {
2664         // qualifier.storage == EvqVaryingOut
2665         switch (language) {
2666         case EShLangVertex:
2667             if (publicType.userDef) {
2668                 profileRequires(loc, EEsProfile, 300, nullptr, "vertex-shader struct output");
2669                 profileRequires(loc, ~EEsProfile, 150, nullptr, "vertex-shader struct output");
2670                 if (publicType.userDef->containsStructure())
2671                     requireProfile(loc, ~EEsProfile, "vertex-shader struct output containing structure");
2672                 if (publicType.userDef->containsArray())
2673                     requireProfile(loc, ~EEsProfile, "vertex-shader struct output containing an array");
2674             }
2675
2676             break;
2677
2678         case EShLangTessControl:
2679             break;
2680
2681         case EShLangTessEvaluation:
2682             if (qualifier.patch)
2683                 error(loc, "can only use on input in tessellation-evaluation shader", "patch", "");
2684             break;
2685
2686         case EShLangGeometry:
2687             break;
2688
2689         case EShLangFragment:
2690             profileRequires(loc, EEsProfile, 300, nullptr, "fragment shader output");
2691             if (publicType.basicType == EbtStruct) {
2692                 error(loc, "cannot be a structure", GetStorageQualifierString(qualifier.storage), "");
2693                 return;
2694             }
2695             if (publicType.matrixRows > 0) {
2696                 error(loc, "cannot be a matrix", GetStorageQualifierString(qualifier.storage), "");
2697                 return;
2698             }
2699             if (qualifier.isAuxiliary())
2700                 error(loc, "can't use auxiliary qualifier on a fragment output", "centroid/sample/patch", "");
2701             if (qualifier.isInterpolation())
2702                 error(loc, "can't use interpolation qualifier on a fragment output", "flat/smooth/noperspective", "");
2703             if (publicType.basicType == EbtDouble)
2704                 error(loc, "cannot contain a double", GetStorageQualifierString(qualifier.storage), "");
2705         break;
2706
2707         case EShLangCompute:
2708             error(loc, "global storage output qualifier cannot be used in a compute shader", "out", "");
2709             break;
2710
2711         default:
2712             break;
2713         }
2714     }
2715 }
2716
2717 //
2718 // Merge characteristics of the 'src' qualifier into the 'dst'.
2719 // If there is duplication, issue error messages, unless 'force'
2720 // is specified, which means to just override default settings.
2721 //
2722 // Also, when force is false, it will be assumed that 'src' follows
2723 // 'dst', for the purpose of error checking order for versions
2724 // that require specific orderings of qualifiers.
2725 //
2726 void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, const TQualifier& src, bool force)
2727 {
2728     // Multiple auxiliary qualifiers (mostly done later by 'individual qualifiers')
2729     if (src.isAuxiliary() && dst.isAuxiliary())
2730         error(loc, "can only have one auxiliary qualifier (centroid, patch, and sample)", "", "");
2731
2732     // Multiple interpolation qualifiers (mostly done later by 'individual qualifiers')
2733     if (src.isInterpolation() && dst.isInterpolation())
2734 #ifdef AMD_EXTENSIONS
2735         error(loc, "can only have one interpolation qualifier (flat, smooth, noperspective, __explicitInterpAMD)", "", "");
2736 #else
2737         error(loc, "can only have one interpolation qualifier (flat, smooth, noperspective)", "", "");
2738 #endif
2739
2740     // Ordering
2741     if (! force && ((profile != EEsProfile && version < 420) ||
2742                     (profile == EEsProfile && version < 310))
2743                 && ! extensionTurnedOn(E_GL_ARB_shading_language_420pack)) {
2744         // non-function parameters
2745         if (src.noContraction && (dst.invariant || dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone))
2746             error(loc, "precise qualifier must appear first", "", "");
2747         if (src.invariant && (dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone))
2748             error(loc, "invariant qualifier must appear before interpolation, storage, and precision qualifiers ", "", "");
2749         else if (src.isInterpolation() && (dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone))
2750             error(loc, "interpolation qualifiers must appear before storage and precision qualifiers", "", "");
2751         else if (src.isAuxiliary() && (dst.storage != EvqTemporary || dst.precision != EpqNone))
2752             error(loc, "Auxiliary qualifiers (centroid, patch, and sample) must appear before storage and precision qualifiers", "", "");
2753         else if (src.storage != EvqTemporary && (dst.precision != EpqNone))
2754             error(loc, "precision qualifier must appear as last qualifier", "", "");
2755
2756         // function parameters
2757         if (src.noContraction && (dst.storage == EvqConst || dst.storage == EvqIn || dst.storage == EvqOut))
2758             error(loc, "precise qualifier must appear first", "", "");
2759         if (src.storage == EvqConst && (dst.storage == EvqIn || dst.storage == EvqOut))
2760             error(loc, "in/out must appear before const", "", "");
2761     }
2762
2763     // Storage qualification
2764     if (dst.storage == EvqTemporary || dst.storage == EvqGlobal)
2765         dst.storage = src.storage;
2766     else if ((dst.storage == EvqIn  && src.storage == EvqOut) ||
2767              (dst.storage == EvqOut && src.storage == EvqIn))
2768         dst.storage = EvqInOut;
2769     else if ((dst.storage == EvqIn    && src.storage == EvqConst) ||
2770              (dst.storage == EvqConst && src.storage == EvqIn))
2771         dst.storage = EvqConstReadOnly;
2772     else if (src.storage != EvqTemporary &&
2773              src.storage != EvqGlobal)
2774         error(loc, "too many storage qualifiers", GetStorageQualifierString(src.storage), "");
2775
2776     // Precision qualifiers
2777     if (! force && src.precision != EpqNone && dst.precision != EpqNone)
2778         error(loc, "only one precision qualifier allowed", GetPrecisionQualifierString(src.precision), "");
2779     if (dst.precision == EpqNone || (force && src.precision != EpqNone))
2780         dst.precision = src.precision;
2781
2782     // Layout qualifiers
2783     mergeObjectLayoutQualifiers(dst, src, false);
2784
2785     // individual qualifiers
2786     bool repeated = false;
2787     #define MERGE_SINGLETON(field) repeated |= dst.field && src.field; dst.field |= src.field;
2788     MERGE_SINGLETON(invariant);
2789     MERGE_SINGLETON(noContraction);
2790     MERGE_SINGLETON(centroid);
2791     MERGE_SINGLETON(smooth);
2792     MERGE_SINGLETON(flat);
2793     MERGE_SINGLETON(nopersp);
2794 #ifdef AMD_EXTENSIONS
2795     MERGE_SINGLETON(explicitInterp);
2796 #endif
2797     MERGE_SINGLETON(patch);
2798     MERGE_SINGLETON(sample);
2799     MERGE_SINGLETON(coherent);
2800     MERGE_SINGLETON(volatil);
2801     MERGE_SINGLETON(restrict);
2802     MERGE_SINGLETON(readonly);
2803     MERGE_SINGLETON(writeonly);
2804     MERGE_SINGLETON(specConstant);
2805
2806     if (repeated)
2807         error(loc, "replicated qualifiers", "", "");
2808 }
2809
2810 void TParseContext::setDefaultPrecision(const TSourceLoc& loc, TPublicType& publicType, TPrecisionQualifier qualifier)
2811 {
2812     TBasicType basicType = publicType.basicType;
2813
2814     if (basicType == EbtSampler) {
2815         defaultSamplerPrecision[computeSamplerTypeIndex(publicType.sampler)] = qualifier;
2816
2817         return;  // all is well
2818     }
2819
2820     if (basicType == EbtInt || basicType == EbtFloat) {
2821         if (publicType.isScalar()) {
2822             defaultPrecision[basicType] = qualifier;
2823             if (basicType == EbtInt) {
2824                 defaultPrecision[EbtUint] = qualifier;
2825                 precisionManager.explicitIntDefaultSeen();
2826             } else
2827                 precisionManager.explicitFloatDefaultSeen();
2828
2829             return;  // all is well
2830         }
2831     }
2832
2833     if (basicType == EbtAtomicUint) {
2834         if (qualifier != EpqHigh)
2835             error(loc, "can only apply highp to atomic_uint", "precision", "");
2836
2837         return;
2838     }
2839
2840     error(loc, "cannot apply precision statement to this type; use 'float', 'int' or a sampler type", TType::getBasicString(basicType), "");
2841 }
2842
2843 // used to flatten the sampler type space into a single dimension
2844 // correlates with the declaration of defaultSamplerPrecision[]
2845 int TParseContext::computeSamplerTypeIndex(TSampler& sampler)
2846 {
2847     int arrayIndex    = sampler.arrayed ? 1 : 0;
2848     int shadowIndex   = sampler.shadow  ? 1 : 0;
2849     int externalIndex = sampler.external? 1 : 0;
2850     int imageIndex    = sampler.image   ? 1 : 0;
2851     int msIndex       = sampler.ms      ? 1 : 0;
2852
2853     int flattened = EsdNumDims * (EbtNumTypes * (2 * (2 * (2 * (2 * arrayIndex + msIndex) + imageIndex) + shadowIndex) +
2854                                                  externalIndex) + sampler.type) + sampler.dim;
2855     assert(flattened < maxSamplerIndex);
2856
2857     return flattened;
2858 }
2859
2860 TPrecisionQualifier TParseContext::getDefaultPrecision(TPublicType& publicType)
2861 {
2862     if (publicType.basicType == EbtSampler)
2863         return defaultSamplerPrecision[computeSamplerTypeIndex(publicType.sampler)];
2864     else
2865         return defaultPrecision[publicType.basicType];
2866 }
2867
2868 void TParseContext::precisionQualifierCheck(const TSourceLoc& loc, TBasicType baseType, TQualifier& qualifier)
2869 {
2870     // Built-in symbols are allowed some ambiguous precisions, to be pinned down
2871     // later by context.
2872     if (! obeyPrecisionQualifiers() || parsingBuiltins)
2873         return;
2874
2875     if (baseType == EbtAtomicUint && qualifier.precision != EpqNone && qualifier.precision != EpqHigh)
2876         error(loc, "atomic counters can only be highp", "atomic_uint", "");
2877
2878     if (baseType == EbtFloat || baseType == EbtUint || baseType == EbtInt || baseType == EbtSampler || baseType == EbtAtomicUint) {
2879         if (qualifier.precision == EpqNone) {
2880             if (relaxedErrors())
2881                 warn(loc, "type requires declaration of default precision qualifier", TType::getBasicString(baseType), "substituting 'mediump'");
2882             else
2883                 error(loc, "type requires declaration of default precision qualifier", TType::getBasicString(baseType), "");
2884             qualifier.precision = EpqMedium;
2885             defaultPrecision[baseType] = EpqMedium;
2886         }
2887     } else if (qualifier.precision != EpqNone)
2888         error(loc, "type cannot have precision qualifier", TType::getBasicString(baseType), "");
2889 }
2890
2891 void TParseContext::parameterTypeCheck(const TSourceLoc& loc, TStorageQualifier qualifier, const TType& type)
2892 {
2893     if ((qualifier == EvqOut || qualifier == EvqInOut) && type.isOpaque())
2894         error(loc, "samplers and atomic_uints cannot be output parameters", type.getBasicTypeString().c_str(), "");
2895 }
2896
2897 bool TParseContext::containsFieldWithBasicType(const TType& type, TBasicType basicType)
2898 {
2899     if (type.getBasicType() == basicType)
2900         return true;
2901
2902     if (type.getBasicType() == EbtStruct) {
2903         const TTypeList& structure = *type.getStruct();
2904         for (unsigned int i = 0; i < structure.size(); ++i) {
2905             if (containsFieldWithBasicType(*structure[i].type, basicType))
2906                 return true;
2907         }
2908     }
2909
2910     return false;
2911 }
2912
2913 //
2914 // Do size checking for an array type's size.
2915 //
2916 void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, TArraySize& sizePair)
2917 {
2918     bool isConst = false;
2919     sizePair.node = nullptr;
2920
2921     int size = 1;
2922
2923     TIntermConstantUnion* constant = expr->getAsConstantUnion();
2924     if (constant) {
2925         // handle true (non-specialization) constant
2926         size = constant->getConstArray()[0].getIConst();
2927         isConst = true;
2928     } else {
2929         // see if it's a specialization constant instead
2930         if (expr->getQualifier().isSpecConstant()) {
2931             isConst = true;
2932             sizePair.node = expr;
2933             TIntermSymbol* symbol = expr->getAsSymbolNode();
2934             if (symbol && symbol->getConstArray().size() > 0)
2935                 size = symbol->getConstArray()[0].getIConst();
2936         }
2937     }
2938
2939     sizePair.size = size;
2940
2941     if (! isConst || (expr->getBasicType() != EbtInt && expr->getBasicType() != EbtUint)) {
2942         error(loc, "array size must be a constant integer expression", "", "");
2943         return;
2944     }
2945
2946     if (size <= 0) {
2947         error(loc, "array size must be a positive integer", "", "");
2948         return;
2949     }
2950 }
2951
2952 //
2953 // See if this qualifier can be an array.
2954 //
2955 // Returns true if there is an error.
2956 //
2957 bool TParseContext::arrayQualifierError(const TSourceLoc& loc, const TQualifier& qualifier)
2958 {
2959     if (qualifier.storage == EvqConst) {
2960         profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, "const array");
2961         profileRequires(loc, EEsProfile, 300, nullptr, "const array");
2962     }
2963
2964     if (qualifier.storage == EvqVaryingIn && language == EShLangVertex) {
2965         requireProfile(loc, ~EEsProfile, "vertex input arrays");
2966         profileRequires(loc, ENoProfile, 150, nullptr, "vertex input arrays");
2967     }
2968
2969     return false;
2970 }
2971
2972 //
2973 // See if this qualifier and type combination can be an array.
2974 // Assumes arrayQualifierError() was also called to catch the type-invariant tests.
2975 //
2976 // Returns true if there is an error.
2977 //
2978 bool TParseContext::arrayError(const TSourceLoc& loc, const TType& type)
2979 {
2980     if (type.getQualifier().storage == EvqVaryingOut && language == EShLangVertex) {
2981         if (type.isArrayOfArrays())
2982             requireProfile(loc, ~EEsProfile, "vertex-shader array-of-array output");
2983         else if (type.isStruct())
2984             requireProfile(loc, ~EEsProfile, "vertex-shader array-of-struct output");
2985     }
2986     if (type.getQualifier().storage == EvqVaryingIn && language == EShLangFragment) {
2987         if (type.isArrayOfArrays())
2988             requireProfile(loc, ~EEsProfile, "fragment-shader array-of-array input");
2989         else if (type.isStruct())
2990             requireProfile(loc, ~EEsProfile, "fragment-shader array-of-struct input");
2991     }
2992     if (type.getQualifier().storage == EvqVaryingOut && language == EShLangFragment) {
2993         if (type.isArrayOfArrays())
2994             requireProfile(loc, ~EEsProfile, "fragment-shader array-of-array output");
2995     }
2996
2997     return false;
2998 }
2999
3000 //
3001 // Require array to be completely sized
3002 //
3003 void TParseContext::arraySizeRequiredCheck(const TSourceLoc& loc, const TArraySizes& arraySizes)
3004 {
3005     if (arraySizes.isImplicit())
3006         error(loc, "array size required", "", "");
3007 }
3008
3009 void TParseContext::structArrayCheck(const TSourceLoc& /*loc*/, const TType& type)
3010 {
3011     const TTypeList& structure = *type.getStruct();
3012     for (int m = 0; m < (int)structure.size(); ++m) {
3013         const TType& member = *structure[m].type;
3014         if (member.isArray())
3015             arraySizeRequiredCheck(structure[m].loc, *member.getArraySizes());
3016     }
3017 }
3018
3019 void TParseContext::arraySizesCheck(const TSourceLoc& loc, const TQualifier& qualifier, TArraySizes* arraySizes, bool initializer, bool lastMember)
3020 {
3021     assert(arraySizes);
3022
3023     // always allow special built-in ins/outs sized to topologies
3024     if (parsingBuiltins)
3025         return;
3026
3027     // always allow an initializer to set any unknown array sizes
3028     if (initializer)
3029         return;
3030
3031     // No environment allows any non-outer-dimension to be implicitly sized
3032     if (arraySizes->isInnerImplicit()) {
3033         error(loc, "only outermost dimension of an array of arrays can be implicitly sized", "[]", "");
3034         arraySizes->clearInnerImplicit();
3035     }
3036
3037     if (arraySizes->isInnerSpecialization())
3038         error(loc, "only outermost dimension of an array of arrays can be a specialization constant", "[]", "");
3039
3040     // desktop always allows outer-dimension-unsized variable arrays,
3041     if (profile != EEsProfile)
3042         return;
3043
3044     // for ES, if size isn't coming from an initializer, it has to be explicitly declared now,
3045     // with very few exceptions
3046
3047     // last member of ssbo block exception:
3048     if (qualifier.storage == EvqBuffer && lastMember)
3049         return;
3050
3051     // implicitly-sized io exceptions:
3052     switch (language) {
3053     case EShLangGeometry:
3054         if (qualifier.storage == EvqVaryingIn)
3055             if ((profile == EEsProfile && version >= 320) ||
3056                 extensionsTurnedOn(Num_AEP_geometry_shader, AEP_geometry_shader))
3057                 return;
3058         break;
3059     case EShLangTessControl:
3060         if ( qualifier.storage == EvqVaryingIn ||
3061             (qualifier.storage == EvqVaryingOut && ! qualifier.patch))
3062             if ((profile == EEsProfile && version >= 320) ||
3063                 extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader))
3064                 return;
3065         break;
3066     case EShLangTessEvaluation:
3067         if ((qualifier.storage == EvqVaryingIn && ! qualifier.patch) ||
3068              qualifier.storage == EvqVaryingOut)
3069             if ((profile == EEsProfile && version >= 320) ||
3070                 extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader))
3071                 return;
3072         break;
3073     default:
3074         break;
3075     }
3076
3077     arraySizeRequiredCheck(loc, *arraySizes);
3078 }
3079
3080 void TParseContext::arrayOfArrayVersionCheck(const TSourceLoc& loc)
3081 {
3082     const char* feature = "arrays of arrays";
3083
3084     requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature);
3085     profileRequires(loc, EEsProfile, 310, nullptr, feature);
3086     profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, feature);
3087 }
3088
3089 void TParseContext::arrayDimCheck(const TSourceLoc& loc, const TArraySizes* sizes1, const TArraySizes* sizes2)
3090 {
3091     if ((sizes1 && sizes2) ||
3092         (sizes1 && sizes1->getNumDims() > 1) ||
3093         (sizes2 && sizes2->getNumDims() > 1))
3094         arrayOfArrayVersionCheck(loc);
3095 }
3096
3097 void TParseContext::arrayDimCheck(const TSourceLoc& loc, const TType* type, const TArraySizes* sizes2)
3098 {
3099     // skip checking for multiple dimensions on the type; it was caught earlier
3100     if ((type && type->isArray() && sizes2) ||
3101         (sizes2 && sizes2->getNumDims() > 1))
3102         arrayOfArrayVersionCheck(loc);
3103 }
3104
3105 // Merge array dimensions listed in 'sizes' onto the type's array dimensions.
3106 //
3107 // From the spec: "vec4[2] a[3]; // size-3 array of size-2 array of vec4"
3108 //
3109 // That means, the 'sizes' go in front of the 'type' as outermost sizes.
3110 // 'type' is the type part of the declaration (to the left)
3111 // 'sizes' is the arrayness tagged on the identifier (to the right)
3112 //
3113 void TParseContext::arrayDimMerge(TType& type, const TArraySizes* sizes)
3114 {
3115     if (sizes != nullptr)
3116         type.addArrayOuterSizes(*sizes);
3117 }
3118
3119 //
3120 // Do all the semantic checking for declaring or redeclaring an array, with and
3121 // without a size, and make the right changes to the symbol table.
3122 //
3123 void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifier, const TType& type, TSymbol*& symbol)
3124 {
3125     if (symbol == nullptr) {
3126         bool currentScope;
3127         symbol = symbolTable.find(identifier, nullptr, &currentScope);
3128
3129         if (symbol && builtInName(identifier) && ! symbolTable.atBuiltInLevel()) {
3130             // bad shader (errors already reported) trying to redeclare a built-in name as an array
3131             symbol = nullptr;
3132             return;
3133         }
3134         if (symbol == nullptr || ! currentScope) {
3135             //
3136             // Successfully process a new definition.
3137             // (Redeclarations have to take place at the same scope; otherwise they are hiding declarations)
3138             //
3139             symbol = new TVariable(&identifier, type);
3140             symbolTable.insert(*symbol);
3141             if (symbolTable.atGlobalLevel())
3142                 trackLinkage(*symbol);
3143
3144             if (! symbolTable.atBuiltInLevel()) {
3145                 if (isIoResizeArray(type)) {
3146                     ioArraySymbolResizeList.push_back(symbol);
3147                     checkIoArraysConsistency(loc, true);
3148                 } else
3149                     fixIoArraySize(loc, symbol->getWritableType());
3150             }
3151
3152             return;
3153         }
3154         if (symbol->getAsAnonMember()) {
3155             error(loc, "cannot redeclare a user-block member array", identifier.c_str(), "");
3156             symbol = nullptr;
3157             return;
3158         }
3159     }
3160
3161     //
3162     // Process a redeclaration.
3163     //
3164
3165     if (symbol == nullptr) {
3166         error(loc, "array variable name expected", identifier.c_str(), "");
3167         return;
3168     }
3169
3170     // redeclareBuiltinVariable() should have already done the copyUp()
3171     TType& existingType = symbol->getWritableType();
3172
3173     if (! existingType.isArray()) {
3174         error(loc, "redeclaring non-array as array", identifier.c_str(), "");
3175         return;
3176     }
3177
3178     if (! existingType.sameElementType(type)) {
3179         error(loc, "redeclaration of array with a different element type", identifier.c_str(), "");
3180         return;
3181     }
3182
3183     if (! existingType.sameInnerArrayness(type)) {
3184         error(loc, "redeclaration of array with a different array dimensions or sizes", identifier.c_str(), "");
3185         return;
3186     }
3187
3188     if (existingType.isExplicitlySizedArray()) {
3189         // be more leniant for input arrays to geometry shaders and tessellation control outputs, where the redeclaration is the same size
3190         if (! (isIoResizeArray(type) && existingType.getOuterArraySize() == type.getOuterArraySize()))
3191             error(loc, "redeclaration of array with size", identifier.c_str(), "");
3192         return;
3193     }
3194
3195     arrayLimitCheck(loc, identifier, type.getOuterArraySize());
3196
3197     existingType.updateArraySizes(type);
3198
3199     if (isIoResizeArray(type))
3200         checkIoArraysConsistency(loc);
3201 }
3202
3203 void TParseContext::updateImplicitArraySize(const TSourceLoc& loc, TIntermNode *node, int index)
3204 {
3205     // maybe there is nothing to do...
3206     TIntermTyped* typedNode = node->getAsTyped();
3207     if (typedNode->getType().getImplicitArraySize() > index)
3208         return;
3209
3210     // something to do...
3211
3212     // Figure out what symbol to lookup, as we will use its type to edit for the size change,
3213     // as that type will be shared through shallow copies for future references.
3214     TSymbol* symbol = nullptr;
3215     int blockIndex = -1;
3216     const TString* lookupName = nullptr;
3217     if (node->getAsSymbolNode())
3218         lookupName = &node->getAsSymbolNode()->getName();
3219     else if (node->getAsBinaryNode()) {
3220         const TIntermBinary* deref = node->getAsBinaryNode();
3221         // This has to be the result of a block dereference, unless it's bad shader code
3222         // If it's a uniform block, then an error will be issued elsewhere, but
3223         // return early now to avoid crashing later in this function.
3224         if (deref->getLeft()->getBasicType() != EbtBlock ||
3225             deref->getLeft()->getType().getQualifier().storage == EvqUniform ||
3226             deref->getRight()->getAsConstantUnion() == nullptr)
3227             return;
3228
3229         const TIntermTyped* left  = deref->getLeft();
3230         const TIntermTyped* right = deref->getRight();
3231
3232         if (left->getAsBinaryNode()) {
3233             left = left->getAsBinaryNode()->getLeft(); // Block array access
3234             assert(left->isArray());
3235         }
3236
3237         if (! left->getAsSymbolNode())
3238             return;
3239
3240         blockIndex = right->getAsConstantUnion()->getConstArray()[0].getIConst();
3241
3242         lookupName = &left->getAsSymbolNode()->getName();
3243         if (IsAnonymous(*lookupName))
3244             lookupName = &(*left->getType().getStruct())[blockIndex].type->getFieldName();
3245     }
3246
3247     // Lookup the symbol, should only fail if shader code is incorrect
3248     symbol = symbolTable.find(*lookupName);
3249     if (symbol == nullptr)
3250         return;
3251
3252     if (symbol->getAsFunction()) {
3253         error(loc, "array variable name expected", symbol->getName().c_str(), "");
3254         return;
3255     }
3256
3257     if (symbol->getType().isStruct() && blockIndex != -1)
3258         (*symbol->getWritableType().getStruct())[blockIndex].type->setImplicitArraySize(index + 1);
3259     else
3260         symbol->getWritableType().setImplicitArraySize(index + 1);
3261 }
3262
3263 // Returns true if the first argument to the #line directive is the line number for the next line.
3264 //
3265 // Desktop, pre-version 3.30:  "After processing this directive
3266 // (including its new-line), the implementation will behave as if it is compiling at line number line+1 and
3267 // source string number source-string-number."
3268 //
3269 // Desktop, version 3.30 and later, and ES:  "After processing this directive
3270 // (including its new-line), the implementation will behave as if it is compiling at line number line and
3271 // source string number source-string-number.
3272 bool TParseContext::lineDirectiveShouldSetNextLine() const
3273 {
3274     return profile == EEsProfile || version >= 330;
3275 }
3276
3277 //
3278 // Enforce non-initializer type/qualifier rules.
3279 //
3280 void TParseContext::nonInitConstCheck(const TSourceLoc& loc, TString& identifier, TType& type)
3281 {
3282     //
3283     // Make the qualifier make sense, given that there is not an initializer.
3284     //
3285     if (type.getQualifier().storage == EvqConst ||
3286         type.getQualifier().storage == EvqConstReadOnly) {
3287         type.getQualifier().makeTemporary();
3288         error(loc, "variables with qualifier 'const' must be initialized", identifier.c_str(), "");
3289     }
3290 }
3291
3292 //
3293 // See if the identifier is a built-in symbol that can be redeclared, and if so,
3294 // copy the symbol table's read-only built-in variable to the current
3295 // global level, where it can be modified based on the passed in type.
3296 //
3297 // Returns nullptr if no redeclaration took place; meaning a normal declaration still
3298 // needs to occur for it, not necessarily an error.
3299 //
3300 // Returns a redeclared and type-modified variable if a redeclarated occurred.
3301 //
3302 TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TString& identifier,
3303                                                  const TQualifier& qualifier, const TShaderQualifiers& publicType)
3304 {
3305     if (! builtInName(identifier) || symbolTable.atBuiltInLevel() || ! symbolTable.atGlobalLevel())
3306         return nullptr;
3307
3308     bool nonEsRedecls = (profile != EEsProfile && (version >= 130 || identifier == "gl_TexCoord"));
3309     bool    esRedecls = (profile == EEsProfile &&
3310                          (version >= 320 || extensionsTurnedOn(Num_AEP_shader_io_blocks, AEP_shader_io_blocks)));
3311     if (! esRedecls && ! nonEsRedecls)
3312         return nullptr;
3313
3314     // Special case when using GL_ARB_separate_shader_objects
3315     bool ssoPre150 = false;  // means the only reason this variable is redeclared is due to this combination
3316     if (profile != EEsProfile && version <= 140 && extensionTurnedOn(E_GL_ARB_separate_shader_objects)) {
3317         if (identifier == "gl_Position"     ||
3318             identifier == "gl_PointSize"    ||
3319             identifier == "gl_ClipVertex"   ||
3320             identifier == "gl_FogFragCoord")
3321             ssoPre150 = true;
3322     }
3323
3324     // Potentially redeclaring a built-in variable...
3325
3326     if (ssoPre150 ||
3327         (identifier == "gl_FragDepth"           && ((nonEsRedecls && version >= 420) || esRedecls)) ||
3328         (identifier == "gl_FragCoord"           && ((nonEsRedecls && version >= 150) || esRedecls)) ||
3329          identifier == "gl_ClipDistance"                                                            ||
3330          identifier == "gl_CullDistance"                                                            ||
3331          identifier == "gl_FrontColor"                                                              ||
3332          identifier == "gl_BackColor"                                                               ||
3333          identifier == "gl_FrontSecondaryColor"                                                     ||
3334          identifier == "gl_BackSecondaryColor"                                                      ||
3335          identifier == "gl_SecondaryColor"                                                          ||
3336         (identifier == "gl_Color"               && language == EShLangFragment)                     ||
3337 #ifdef NV_EXTENSIONS
3338          identifier == "gl_SampleMask"                                                              ||
3339          identifier == "gl_Layer"                                                                   ||
3340 #endif
3341          identifier == "gl_TexCoord") {
3342
3343         // Find the existing symbol, if any.
3344         bool builtIn;
3345         TSymbol* symbol = symbolTable.find(identifier, &builtIn);
3346
3347         // If the symbol was not found, this must be a version/profile/stage
3348         // that doesn't have it.
3349         if (! symbol)
3350             return nullptr;
3351
3352         // If it wasn't at a built-in level, then it's already been redeclared;
3353         // that is, this is a redeclaration of a redeclaration; reuse that initial
3354         // redeclaration.  Otherwise, make the new one.
3355         if (builtIn)
3356             makeEditable(symbol);
3357
3358         // Now, modify the type of the copy, as per the type of the current redeclaration.
3359
3360         TQualifier& symbolQualifier = symbol->getWritableType().getQualifier();
3361         if (ssoPre150) {
3362             if (intermediate.inIoAccessed(identifier))
3363                 error(loc, "cannot redeclare after use", identifier.c_str(), "");
3364             if (qualifier.hasLayout())
3365                 error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str());
3366             if (qualifier.isMemory() || qualifier.isAuxiliary() || (language == EShLangVertex   && qualifier.storage != EvqVaryingOut) ||
3367                                                                    (language == EShLangFragment && qualifier.storage != EvqVaryingIn))
3368                 error(loc, "cannot change storage, memory, or auxiliary qualification of", "redeclaration", symbol->getName().c_str());
3369             if (! qualifier.smooth)
3370                 error(loc, "cannot change interpolation qualification of", "redeclaration", symbol->getName().c_str());
3371         } else if (identifier == "gl_FrontColor"          ||
3372                    identifier == "gl_BackColor"           ||
3373                    identifier == "gl_FrontSecondaryColor" ||
3374                    identifier == "gl_BackSecondaryColor"  ||
3375                    identifier == "gl_SecondaryColor"      ||
3376                    identifier == "gl_Color") {
3377             symbolQualifier.flat = qualifier.flat;
3378             symbolQualifier.smooth = qualifier.smooth;
3379             symbolQualifier.nopersp = qualifier.nopersp;
3380             if (qualifier.hasLayout())
3381                 error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str());
3382             if (qualifier.isMemory() || qualifier.isAuxiliary() || symbol->getType().getQualifier().storage != qualifier.storage)
3383                 error(loc, "cannot change storage, memory, or auxiliary qualification of", "redeclaration", symbol->getName().c_str());
3384         } else if (identifier == "gl_TexCoord"     ||
3385                    identifier == "gl_ClipDistance" ||
3386                    identifier == "gl_CullDistance") {
3387             if (qualifier.hasLayout() || qualifier.isMemory() || qualifier.isAuxiliary() ||
3388                 qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
3389                 symbolQualifier.storage != qualifier.storage)
3390                 error(loc, "cannot change qualification of", "redeclaration", symbol->getName().c_str());
3391         } else if (identifier == "gl_FragCoord") {
3392             if (intermediate.inIoAccessed("gl_FragCoord"))
3393                 error(loc, "cannot redeclare after use", "gl_FragCoord", "");
3394             if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
3395                 qualifier.isMemory() || qualifier.isAuxiliary())
3396                 error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str());
3397             if (qualifier.storage != EvqVaryingIn)
3398                 error(loc, "cannot change input storage qualification of", "redeclaration", symbol->getName().c_str());
3399             if (! builtIn && (publicType.pixelCenterInteger != intermediate.getPixelCenterInteger() ||
3400                               publicType.originUpperLeft != intermediate.getOriginUpperLeft()))
3401                 error(loc, "cannot redeclare with different qualification:", "redeclaration", symbol->getName().c_str());
3402             if (publicType.pixelCenterInteger)
3403                 intermediate.setPixelCenterInteger();
3404             if (publicType.originUpperLeft)
3405                 intermediate.setOriginUpperLeft();
3406         } else if (identifier == "gl_FragDepth") {
3407             if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
3408                 qualifier.isMemory() || qualifier.isAuxiliary())
3409                 error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str());
3410             if (qualifier.storage != EvqVaryingOut)
3411                 error(loc, "cannot change output storage qualification of", "redeclaration", symbol->getName().c_str());
3412             if (publicType.layoutDepth != EldNone) {
3413                 if (intermediate.inIoAccessed("gl_FragDepth"))
3414                     error(loc, "cannot redeclare after use", "gl_FragDepth", "");
3415                 if (! intermediate.setDepth(publicType.layoutDepth))
3416                     error(loc, "all redeclarations must use the same depth layout on", "redeclaration", symbol->getName().c_str());
3417             }
3418         }
3419 #ifdef NV_EXTENSIONS
3420         else if (identifier == "gl_SampleMask") {
3421             if (!publicType.layoutOverrideCoverage) {
3422                 error(loc, "redeclaration only allowed for override_coverage layout", "redeclaration", symbol->getName().c_str());
3423             }
3424             intermediate.setLayoutOverrideCoverage();
3425         }
3426         else if (identifier == "gl_Layer") {
3427             if (!qualifier.layoutViewportRelative && qualifier.layoutSecondaryViewportRelativeOffset == -2048)
3428                 error(loc, "redeclaration only allowed for viewport_relative or secondary_view_offset layout", "redeclaration", symbol->getName().c_str());
3429             symbolQualifier.layoutViewportRelative = qualifier.layoutViewportRelative;
3430             symbolQualifier.layoutSecondaryViewportRelativeOffset = qualifier.layoutSecondaryViewportRelativeOffset;
3431         }
3432 #endif
3433
3434         // TODO: semantics quality: separate smooth from nothing declared, then use IsInterpolation for several tests above
3435
3436         return symbol;
3437     }
3438
3439     return nullptr;
3440 }
3441
3442 //
3443 // Either redeclare the requested block, or give an error message why it can't be done.
3444 //
3445 // TODO: functionality: explicitly sizing members of redeclared blocks is not giving them an explicit size
3446 void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newTypeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes)
3447 {
3448     const char* feature = "built-in block redeclaration";
3449     profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature);
3450     profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_separate_shader_objects, feature);
3451
3452     if (blockName != "gl_PerVertex" && blockName != "gl_PerFragment") {
3453         error(loc, "cannot redeclare block: ", "block declaration", blockName.c_str());
3454         return;
3455     }
3456
3457     // Redeclaring a built-in block...
3458
3459     if (instanceName && ! builtInName(*instanceName)) {
3460         error(loc, "cannot redeclare a built-in block with a user name", instanceName->c_str(), "");
3461         return;
3462     }
3463
3464     // Blocks with instance names are easy to find, lookup the instance name,
3465     // Anonymous blocks need to be found via a member.
3466     bool builtIn;
3467     TSymbol* block;
3468     if (instanceName)
3469         block = symbolTable.find(*instanceName, &builtIn);
3470     else
3471         block = symbolTable.find(newTypeList.front().type->getFieldName(), &builtIn);
3472
3473     // If the block was not found, this must be a version/profile/stage
3474     // that doesn't have it, or the instance name is wrong.
3475     const char* errorName = instanceName ? instanceName->c_str() : newTypeList.front().type->getFieldName().c_str();
3476     if (! block) {
3477         error(loc, "no declaration found for redeclaration", errorName, "");
3478         return;
3479     }
3480     // Built-in blocks cannot be redeclared more than once, which if happened,
3481     // we'd be finding the already redeclared one here, rather than the built in.
3482     if (! builtIn) {
3483         error(loc, "can only redeclare a built-in block once, and before any use", blockName.c_str(), "");
3484         return;
3485     }
3486
3487     // Copy the block to make a writable version, to insert into the block table after editing.
3488     block = symbolTable.copyUpDeferredInsert(block);
3489
3490     if (block->getType().getBasicType() != EbtBlock) {
3491         error(loc, "cannot redeclare a non block as a block", errorName, "");
3492         return;
3493     }
3494
3495     // Fix XFB stuff up, it applies to the order of the redeclaration, not
3496     // the order of the original members.
3497     if (currentBlockQualifier.storage == EvqVaryingOut && globalOutputDefaults.hasXfbBuffer()) {
3498         if (!currentBlockQualifier.hasXfbBuffer())
3499             currentBlockQualifier.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer;
3500         fixBlockXfbOffsets(currentBlockQualifier, newTypeList);
3501     }
3502
3503     // Edit and error check the container against the redeclaration
3504     //  - remove unused members
3505     //  - ensure remaining qualifiers/types match
3506
3507     TType& type = block->getWritableType();
3508
3509 #ifdef NV_EXTENSIONS
3510     // if gl_PerVertex is redeclared for the purpose of passing through "gl_Position"
3511     // for passthrough purpose, the redeclared block should have the same qualifers as
3512     // the current one
3513     if (currentBlockQualifier.layoutPassthrough) {
3514         type.getQualifier().layoutPassthrough = currentBlockQualifier.layoutPassthrough;
3515         type.getQualifier().storage = currentBlockQualifier.storage;
3516         type.getQualifier().layoutStream = currentBlockQualifier.layoutStream;
3517         type.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer;
3518     }
3519 #endif
3520
3521     TTypeList::iterator member = type.getWritableStruct()->begin();
3522     size_t numOriginalMembersFound = 0;
3523     while (member != type.getStruct()->end()) {
3524         // look for match
3525         bool found = false;
3526         TTypeList::const_iterator newMember;
3527         TSourceLoc memberLoc;
3528         memberLoc.init();
3529         for (newMember = newTypeList.begin(); newMember != newTypeList.end(); ++newMember) {
3530             if (member->type->getFieldName() == newMember->type->getFieldName()) {
3531                 found = true;
3532                 memberLoc = newMember->loc;
3533                 break;
3534             }
3535         }
3536
3537         if (found) {
3538             ++numOriginalMembersFound;
3539             // - ensure match between redeclared members' types
3540             // - check for things that can't be changed
3541             // - update things that can be changed
3542             TType& oldType = *member->type;
3543             const TType& newType = *newMember->type;
3544             if (! newType.sameElementType(oldType))
3545                 error(memberLoc, "cannot redeclare block member with a different type", member->type->getFieldName().c_str(), "");
3546             if (oldType.isArray() != newType.isArray())
3547                 error(memberLoc, "cannot change arrayness of redeclared block member", member->type->getFieldName().c_str(), "");
3548             else if (! oldType.sameArrayness(newType) && oldType.isExplicitlySizedArray())
3549                 error(memberLoc, "cannot change array size of redeclared block member", member->type->getFieldName().c_str(), "");
3550             else if (newType.isArray())
3551                 arrayLimitCheck(loc, member->type->getFieldName(), newType.getOuterArraySize());
3552             if (newType.getQualifier().isMemory())
3553                 error(memberLoc, "cannot add memory qualifier to redeclared block member", member->type->getFieldName().c_str(), "");
3554             if (newType.getQualifier().hasNonXfbLayout())
3555                 error(memberLoc, "cannot add non-XFB layout to redeclared block member", member->type->getFieldName().c_str(), "");
3556             if (newType.getQualifier().patch)
3557                 error(memberLoc, "cannot add patch to redeclared block member", member->type->getFieldName().c_str(), "");
3558             if (newType.getQualifier().hasXfbBuffer() &&
3559                 newType.getQualifier().layoutXfbBuffer != currentBlockQualifier.layoutXfbBuffer)
3560                 error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_buffer", "");
3561             oldType.getQualifier().centroid = newType.getQualifier().centroid;
3562             oldType.getQualifier().sample = newType.getQualifier().sample;
3563             oldType.getQualifier().invariant = newType.getQualifier().invariant;
3564             oldType.getQualifier().noContraction = newType.getQualifier().noContraction;
3565             oldType.getQualifier().smooth = newType.getQualifier().smooth;
3566             oldType.getQualifier().flat = newType.getQualifier().flat;
3567             oldType.getQualifier().nopersp = newType.getQualifier().nopersp;
3568             oldType.getQualifier().layoutXfbOffset = newType.getQualifier().layoutXfbOffset;
3569             oldType.getQualifier().layoutXfbBuffer = newType.getQualifier().layoutXfbBuffer;
3570             oldType.getQualifier().layoutXfbStride = newType.getQualifier().layoutXfbStride;
3571             if (oldType.getQualifier().layoutXfbOffset != TQualifier::layoutXfbBufferEnd) {
3572                 // if any member as an xfb_offset, then the block's xfb_buffer inherents current xfb_buffer,
3573                 // and for xfb processing, the member needs it as well, along with xfb_stride
3574                 type.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer;
3575                 oldType.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer;
3576             }
3577             if (oldType.isImplicitlySizedArray() && newType.isExplicitlySizedArray())
3578                 oldType.changeOuterArraySize(newType.getOuterArraySize());
3579
3580             //  check and process the member's type, which will include managing xfb information
3581             layoutTypeCheck(loc, oldType);
3582
3583             // go to next member
3584             ++member;
3585         } else {
3586             // For missing members of anonymous blocks that have been redeclared,
3587             // hide the original (shared) declaration.
3588             // Instance-named blocks can just have the member removed.
3589             if (instanceName)
3590                 member = type.getWritableStruct()->erase(member);
3591             else {
3592                 member->type->hideMember();
3593                 ++member;
3594             }
3595         }
3596     }
3597
3598     if (numOriginalMembersFound < newTypeList.size())
3599         error(loc, "block redeclaration has extra members", blockName.c_str(), "");
3600     if (type.isArray() != (arraySizes != nullptr))
3601         error(loc, "cannot change arrayness of redeclared block", blockName.c_str(), "");
3602     else if (type.isArray()) {
3603         if (type.isExplicitlySizedArray() && arraySizes->getOuterSize() == UnsizedArraySize)
3604             error(loc, "block already declared with size, can't redeclare as implicitly-sized", blockName.c_str(), "");
3605         else if (type.isExplicitlySizedArray() && type.getArraySizes() != *arraySizes)
3606             error(loc, "cannot change array size of redeclared block", blockName.c_str(), "");
3607         else if (type.isImplicitlySizedArray() && arraySizes->getOuterSize() != UnsizedArraySize)
3608             type.changeOuterArraySize(arraySizes->getOuterSize());
3609     }
3610
3611     symbolTable.insert(*block);
3612
3613     // Check for general layout qualifier errors
3614     layoutObjectCheck(loc, *block);
3615
3616     // Tracking for implicit sizing of array
3617     if (isIoResizeArray(block->getType())) {
3618         ioArraySymbolResizeList.push_back(block);
3619         checkIoArraysConsistency(loc, true);
3620     } else if (block->getType().isArray())
3621         fixIoArraySize(loc, block->getWritableType());
3622
3623     // Save it in the AST for linker use.
3624     trackLinkage(*block);
3625 }
3626
3627 void TParseContext::paramCheckFix(const TSourceLoc& loc, const TStorageQualifier& qualifier, TType& type)
3628 {
3629     switch (qualifier) {
3630     case EvqConst:
3631     case EvqConstReadOnly:
3632         type.getQualifier().storage = EvqConstReadOnly;
3633         break;
3634     case EvqIn:
3635     case EvqOut:
3636     case EvqInOut:
3637         type.getQualifier().storage = qualifier;
3638         break;
3639     case EvqGlobal:
3640     case EvqTemporary:
3641         type.getQualifier().storage = EvqIn;
3642         break;
3643     default:
3644         type.getQualifier().storage = EvqIn;
3645         error(loc, "storage qualifier not allowed on function parameter", GetStorageQualifierString(qualifier), "");
3646         break;
3647     }
3648 }
3649
3650 void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& qualifier, TType& type)
3651 {
3652     if (qualifier.isMemory()) {
3653         type.getQualifier().volatil   = qualifier.volatil;
3654         type.getQualifier().coherent  = qualifier.coherent;
3655         type.getQualifier().readonly  = qualifier.readonly;
3656         type.getQualifier().writeonly = qualifier.writeonly;
3657         type.getQualifier().restrict  = qualifier.restrict;
3658     }
3659
3660     if (qualifier.isAuxiliary() ||
3661         qualifier.isInterpolation())
3662         error(loc, "cannot use auxiliary or interpolation qualifiers on a function parameter", "", "");
3663     if (qualifier.hasLayout())
3664         error(loc, "cannot use layout qualifiers on a function parameter", "", "");
3665     if (qualifier.invariant)
3666         error(loc, "cannot use invariant qualifier on a function parameter", "", "");
3667     if (qualifier.noContraction) {
3668         if (qualifier.isParamOutput())
3669             type.getQualifier().noContraction = true;
3670         else
3671             warn(loc, "qualifier has no effect on non-output parameters", "precise", "");
3672     }
3673
3674     paramCheckFix(loc, qualifier.storage, type);
3675 }
3676
3677 void TParseContext::nestedBlockCheck(const TSourceLoc& loc)
3678 {
3679     if (structNestingLevel > 0)
3680         error(loc, "cannot nest a block definition inside a structure or block", "", "");
3681     ++structNestingLevel;
3682 }
3683
3684 void TParseContext::nestedStructCheck(const TSourceLoc& loc)
3685 {
3686     if (structNestingLevel > 0)
3687         error(loc, "cannot nest a structure definition inside a structure or block", "", "");
3688     ++structNestingLevel;
3689 }
3690
3691 void TParseContext::arrayObjectCheck(const TSourceLoc& loc, const TType& type, const char* op)
3692 {
3693     // Some versions don't allow comparing arrays or structures containing arrays
3694     if (type.containsArray()) {
3695         profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, op);
3696         profileRequires(loc, EEsProfile, 300, nullptr, op);
3697     }
3698 }
3699
3700 void TParseContext::opaqueCheck(const TSourceLoc& loc, const TType& type, const char* op)
3701 {
3702     if (containsFieldWithBasicType(type, EbtSampler))
3703         error(loc, "can't use with samplers or structs containing samplers", op, "");
3704 }
3705
3706 void TParseContext::specializationCheck(const TSourceLoc& loc, const TType& type, const char* op)
3707 {
3708     if (type.containsSpecializationSize())
3709         error(loc, "can't use with types containing arrays sized with a specialization constant", op, "");
3710 }
3711
3712 void TParseContext::structTypeCheck(const TSourceLoc& /*loc*/, TPublicType& publicType)
3713 {
3714     const TTypeList& typeList = *publicType.userDef->getStruct();
3715
3716     // fix and check for member storage qualifiers and types that don't belong within a structure
3717     for (unsigned int member = 0; member < typeList.size(); ++member) {
3718         TQualifier& memberQualifier = typeList[member].type->getQualifier();
3719         const TSourceLoc& memberLoc = typeList[member].loc;
3720         if (memberQualifier.isAuxiliary() ||
3721             memberQualifier.isInterpolation() ||
3722             (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal))
3723             error(memberLoc, "cannot use storage or interpolation qualifiers on structure members", typeList[member].type->getFieldName().c_str(), "");
3724         if (memberQualifier.isMemory())
3725             error(memberLoc, "cannot use memory qualifiers on structure members", typeList[member].type->getFieldName().c_str(), "");
3726         if (memberQualifier.hasLayout()) {
3727             error(memberLoc, "cannot use layout qualifiers on structure members", typeList[member].type->getFieldName().c_str(), "");
3728             memberQualifier.clearLayout();
3729         }
3730         if (memberQualifier.invariant)
3731             error(memberLoc, "cannot use invariant qualifier on structure members", typeList[member].type->getFieldName().c_str(), "");
3732     }
3733 }
3734
3735 //
3736 // See if this loop satisfies the limitations for ES 2.0 (version 100) for loops in Appendex A:
3737 //
3738 // "The loop index has type int or float.
3739 //
3740 // "The for statement has the form:
3741 //     for ( init-declaration ; condition ; expression )
3742 //     init-declaration has the form: type-specifier identifier = constant-expression
3743 //     condition has the form:  loop-index relational_operator constant-expression
3744 //         where relational_operator is one of: > >= < <= == or !=
3745 //     expression [sic] has one of the following forms:
3746 //         loop-index++
3747 //         loop-index--
3748 //         loop-index += constant-expression
3749 //         loop-index -= constant-expression
3750 //
3751 // The body is handled in an AST traversal.
3752 //
3753 void TParseContext::inductiveLoopCheck(const TSourceLoc& loc, TIntermNode* init, TIntermLoop* loop)
3754 {
3755     // loop index init must exist and be a declaration, which shows up in the AST as an aggregate of size 1 of the declaration
3756     bool badInit = false;
3757     if (! init || ! init->getAsAggregate() || init->getAsAggregate()->getSequence().size() != 1)
3758         badInit = true;
3759     TIntermBinary* binaryInit = 0;
3760     if (! badInit) {
3761         // get the declaration assignment
3762         binaryInit = init->getAsAggregate()->getSequence()[0]->getAsBinaryNode();
3763         if (! binaryInit)
3764             badInit = true;
3765     }
3766     if (badInit) {
3767         error(loc, "inductive-loop init-declaration requires the form \"type-specifier loop-index = constant-expression\"", "limitations", "");
3768         return;
3769     }
3770
3771     // loop index must be type int or float
3772     if (! binaryInit->getType().isScalar() || (binaryInit->getBasicType() != EbtInt && binaryInit->getBasicType() != EbtFloat)) {
3773         error(loc, "inductive loop requires a scalar 'int' or 'float' loop index", "limitations", "");
3774         return;
3775     }
3776
3777     // init is the form "loop-index = constant"
3778     if (binaryInit->getOp() != EOpAssign || ! binaryInit->getLeft()->getAsSymbolNode() || ! binaryInit->getRight()->getAsConstantUnion()) {
3779         error(loc, "inductive-loop init-declaration requires the form \"type-specifier loop-index = constant-expression\"", "limitations", "");
3780         return;
3781     }
3782
3783     // get the unique id of the loop index
3784     int loopIndex = binaryInit->getLeft()->getAsSymbolNode()->getId();
3785     inductiveLoopIds.insert(loopIndex);
3786
3787     // condition's form must be "loop-index relational-operator constant-expression"
3788     bool badCond = ! loop->getTest();
3789     if (! badCond) {
3790         TIntermBinary* binaryCond = loop->getTest()->getAsBinaryNode();
3791         badCond = ! binaryCond;
3792         if (! badCond) {
3793             switch (binaryCond->getOp()) {
3794             case EOpGreaterThan:
3795             case EOpGreaterThanEqual:
3796             case EOpLessThan:
3797             case EOpLessThanEqual:
3798             case EOpEqual:
3799             case EOpNotEqual:
3800                 break;
3801             default:
3802                 badCond = true;
3803             }
3804         }
3805         if (binaryCond && (! binaryCond->getLeft()->getAsSymbolNode() ||
3806                            binaryCond->getLeft()->getAsSymbolNode()->getId() != loopIndex ||
3807                            ! binaryCond->getRight()->getAsConstantUnion()))
3808             badCond = true;
3809     }
3810     if (badCond) {
3811         error(loc, "inductive-loop condition requires the form \"loop-index <comparison-op> constant-expression\"", "limitations", "");
3812         return;
3813     }
3814
3815     // loop-index++
3816     // loop-index--
3817     // loop-index += constant-expression
3818     // loop-index -= constant-expression
3819     bool badTerminal = ! loop->getTerminal();
3820     if (! badTerminal) {
3821         TIntermUnary* unaryTerminal = loop->getTerminal()->getAsUnaryNode();
3822         TIntermBinary* binaryTerminal = loop->getTerminal()->getAsBinaryNode();
3823         if (unaryTerminal || binaryTerminal) {
3824             switch(loop->getTerminal()->getAsOperator()->getOp()) {
3825             case EOpPostDecrement:
3826             case EOpPostIncrement:
3827             case EOpAddAssign:
3828             case EOpSubAssign:
3829                 break;
3830             default:
3831                 badTerminal = true;
3832             }
3833         } else
3834             badTerminal = true;
3835         if (binaryTerminal && (! binaryTerminal->getLeft()->getAsSymbolNode() ||
3836                                binaryTerminal->getLeft()->getAsSymbolNode()->getId() != loopIndex ||
3837                                ! binaryTerminal->getRight()->getAsConstantUnion()))
3838             badTerminal = true;
3839         if (unaryTerminal && (! unaryTerminal->getOperand()->getAsSymbolNode() ||
3840                               unaryTerminal->getOperand()->getAsSymbolNode()->getId() != loopIndex))
3841             badTerminal = true;
3842     }
3843     if (badTerminal) {
3844         error(loc, "inductive-loop termination requires the form \"loop-index++, loop-index--, loop-index += constant-expression, or loop-index -= constant-expression\"", "limitations", "");
3845         return;
3846     }
3847
3848     // the body
3849     inductiveLoopBodyCheck(loop->getBody(), loopIndex, symbolTable);
3850 }
3851
3852 // Do limit checks for built-in arrays.
3853 void TParseContext::arrayLimitCheck(const TSourceLoc& loc, const TString& identifier, int size)
3854 {
3855     if (identifier.compare("gl_TexCoord") == 0)
3856         limitCheck(loc, size, "gl_MaxTextureCoords", "gl_TexCoord array size");
3857     else if (identifier.compare("gl_ClipDistance") == 0)
3858         limitCheck(loc, size, "gl_MaxClipDistances", "gl_ClipDistance array size");
3859     else if (identifier.compare("gl_CullDistance") == 0)
3860         limitCheck(loc, size, "gl_MaxCullDistances", "gl_CullDistance array size");
3861 }
3862
3863 // See if the provided value is less than or equal to the symbol indicated by limit,
3864 // which should be a constant in the symbol table.
3865 void TParseContext::limitCheck(const TSourceLoc& loc, int value, const char* limit, const char* feature)
3866 {
3867     TSymbol* symbol = symbolTable.find(limit);
3868     assert(symbol->getAsVariable());
3869     const TConstUnionArray& constArray = symbol->getAsVariable()->getConstArray();
3870     assert(! constArray.empty());
3871     if (value > constArray[0].getIConst())
3872         error(loc, "must be less than or equal to", feature, "%s (%d)", limit, constArray[0].getIConst());
3873 }
3874
3875 //
3876 // Do any additional error checking, etc., once we know the parsing is done.
3877 //
3878 void TParseContext::finish()
3879 {
3880     TParseContextBase::finish();
3881
3882     if (parsingBuiltins)
3883         return;
3884
3885     // Check on array indexes for ES 2.0 (version 100) limitations.
3886     for (size_t i = 0; i < needsIndexLimitationChecking.size(); ++i)
3887         constantIndexExpressionCheck(needsIndexLimitationChecking[i]);
3888
3889     // Check for stages that are enabled by extension.
3890     // Can't do this at the beginning, it is chicken and egg to add a stage by
3891     // extension.
3892     // Stage-specific features were correctly tested for already, this is just
3893     // about the stage itself.
3894     switch (language) {
3895     case EShLangGeometry:
3896         if (profile == EEsProfile && version == 310)
3897             requireExtensions(getCurrentLoc(), Num_AEP_geometry_shader, AEP_geometry_shader, "geometry shaders");
3898         break;
3899     case EShLangTessControl:
3900     case EShLangTessEvaluation:
3901         if (profile == EEsProfile && version == 310)
3902             requireExtensions(getCurrentLoc(), Num_AEP_tessellation_shader, AEP_tessellation_shader, "tessellation shaders");
3903         else if (profile != EEsProfile && version < 400)
3904             requireExtensions(getCurrentLoc(), 1, &E_GL_ARB_tessellation_shader, "tessellation shaders");
3905         break;
3906     case EShLangCompute:
3907         if (profile != EEsProfile && version < 430)
3908             requireExtensions(getCurrentLoc(), 1, &E_GL_ARB_compute_shader, "compute shaders");
3909         break;
3910     default:
3911         break;
3912     }
3913 }
3914
3915 //
3916 // Layout qualifier stuff.
3917 //
3918
3919 // Put the id's layout qualification into the public type, for qualifiers not having a number set.
3920 // This is before we know any type information for error checking.
3921 void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publicType, TString& id)
3922 {
3923     std::transform(id.begin(), id.end(), id.begin(), ::tolower);
3924
3925     if (id == TQualifier::getLayoutMatrixString(ElmColumnMajor)) {
3926         publicType.qualifier.layoutMatrix = ElmColumnMajor;
3927         return;
3928     }
3929     if (id == TQualifier::getLayoutMatrixString(ElmRowMajor)) {
3930         publicType.qualifier.layoutMatrix = ElmRowMajor;
3931         return;
3932     }
3933     if (id == TQualifier::getLayoutPackingString(ElpPacked)) {
3934         if (spvVersion.spv != 0)
3935             spvRemoved(loc, "packed");
3936         publicType.qualifier.layoutPacking = ElpPacked;
3937         return;
3938     }
3939     if (id == TQualifier::getLayoutPackingString(ElpShared)) {
3940         if (spvVersion.spv != 0)
3941             spvRemoved(loc, "shared");
3942         publicType.qualifier.layoutPacking = ElpShared;
3943         return;
3944     }
3945     if (id == TQualifier::getLayoutPackingString(ElpStd140)) {
3946         publicType.qualifier.layoutPacking = ElpStd140;
3947         return;
3948     }
3949     if (id == TQualifier::getLayoutPackingString(ElpStd430)) {
3950         requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "std430");
3951         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, "std430");
3952         profileRequires(loc, EEsProfile, 310, nullptr, "std430");
3953         publicType.qualifier.layoutPacking = ElpStd430;
3954         return;
3955     }
3956     // TODO: compile-time performance: may need to stop doing linear searches
3957     for (TLayoutFormat format = (TLayoutFormat)(ElfNone + 1); format < ElfCount; format = (TLayoutFormat)(format + 1)) {
3958         if (id == TQualifier::getLayoutFormatString(format)) {
3959             if ((format > ElfEsFloatGuard && format < ElfFloatGuard) ||
3960                 (format > ElfEsIntGuard && format < ElfIntGuard) ||
3961                 (format > ElfEsUintGuard && format < ElfCount))
3962                 requireProfile(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, "image load-store format");
3963             profileRequires(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, 420, E_GL_ARB_shader_image_load_store, "image load store");
3964             profileRequires(loc, EEsProfile, 310, E_GL_ARB_shader_image_load_store, "image load store");
3965             publicType.qualifier.layoutFormat = format;
3966             return;
3967         }
3968     }
3969     if (id == "push_constant") {
3970         requireVulkan(loc, "push_constant");
3971         publicType.qualifier.layoutPushConstant = true;
3972         return;
3973     }
3974     if (language == EShLangGeometry || language == EShLangTessEvaluation) {
3975         if (id == TQualifier::getGeometryString(ElgTriangles)) {
3976             publicType.shaderQualifiers.geometry = ElgTriangles;
3977             return;
3978         }
3979         if (language == EShLangGeometry) {
3980             if (id == TQualifier::getGeometryString(ElgPoints)) {
3981                 publicType.shaderQualifiers.geometry = ElgPoints;
3982                 return;
3983             }
3984             if (id == TQualifier::getGeometryString(ElgLineStrip)) {
3985                 publicType.shaderQualifiers.geometry = ElgLineStrip;
3986                 return;
3987             }
3988             if (id == TQualifier::getGeometryString(ElgLines)) {
3989                 publicType.shaderQualifiers.geometry = ElgLines;
3990                 return;
3991             }
3992             if (id == TQualifier::getGeometryString(ElgLinesAdjacency)) {
3993                 publicType.shaderQualifiers.geometry = ElgLinesAdjacency;
3994                 return;
3995             }
3996             if (id == TQualifier::getGeometryString(ElgTrianglesAdjacency)) {
3997                 publicType.shaderQualifiers.geometry = ElgTrianglesAdjacency;
3998                 return;
3999             }
4000             if (id == TQualifier::getGeometryString(ElgTriangleStrip)) {
4001                 publicType.shaderQualifiers.geometry = ElgTriangleStrip;
4002                 return;
4003             }
4004 #ifdef NV_EXTENSIONS
4005             if (id == "passthrough") {
4006                requireExtensions(loc, 1, &E_SPV_NV_geometry_shader_passthrough, "geometry shader passthrough");
4007                publicType.qualifier.layoutPassthrough = true;
4008                intermediate.setGeoPassthroughEXT();
4009                return;
4010             }
4011 #endif
4012         } else {
4013             assert(language == EShLangTessEvaluation);
4014
4015             // input primitive
4016             if (id == TQualifier::getGeometryString(ElgTriangles)) {
4017                 publicType.shaderQualifiers.geometry = ElgTriangles;
4018                 return;
4019             }
4020             if (id == TQualifier::getGeometryString(ElgQuads)) {
4021                 publicType.shaderQualifiers.geometry = ElgQuads;
4022                 return;
4023             }
4024             if (id == TQualifier::getGeometryString(ElgIsolines)) {
4025                 publicType.shaderQualifiers.geometry = ElgIsolines;
4026                 return;
4027             }
4028
4029             // vertex spacing
4030             if (id == TQualifier::getVertexSpacingString(EvsEqual)) {
4031                 publicType.shaderQualifiers.spacing = EvsEqual;
4032                 return;
4033             }
4034             if (id == TQualifier::getVertexSpacingString(EvsFractionalEven)) {
4035                 publicType.shaderQualifiers.spacing = EvsFractionalEven;
4036                 return;
4037             }
4038             if (id == TQualifier::getVertexSpacingString(EvsFractionalOdd)) {
4039                 publicType.shaderQualifiers.spacing = EvsFractionalOdd;
4040                 return;
4041             }
4042
4043             // triangle order
4044             if (id == TQualifier::getVertexOrderString(EvoCw)) {
4045                 publicType.shaderQualifiers.order = EvoCw;
4046                 return;
4047             }
4048             if (id == TQualifier::getVertexOrderString(EvoCcw)) {
4049                 publicType.shaderQualifiers.order = EvoCcw;
4050                 return;
4051             }
4052
4053             // point mode
4054             if (id == "point_mode") {
4055                 publicType.shaderQualifiers.pointMode = true;
4056                 return;
4057             }
4058         }
4059     }
4060     if (language == EShLangFragment) {
4061         if (id == "origin_upper_left") {
4062             requireProfile(loc, ECoreProfile | ECompatibilityProfile, "origin_upper_left");
4063             publicType.shaderQualifiers.originUpperLeft = true;
4064             return;
4065         }
4066         if (id == "pixel_center_integer") {
4067             requireProfile(loc, ECoreProfile | ECompatibilityProfile, "pixel_center_integer");
4068             publicType.shaderQualifiers.pixelCenterInteger = true;
4069             return;
4070         }
4071         if (id == "early_fragment_tests") {
4072             profileRequires(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, 420, E_GL_ARB_shader_image_load_store, "early_fragment_tests");
4073             profileRequires(loc, EEsProfile, 310, nullptr, "early_fragment_tests");
4074             publicType.shaderQualifiers.earlyFragmentTests = true;
4075             return;
4076         }
4077         if (id == "post_depth_coverage") {
4078             requireExtensions(loc, Num_post_depth_coverageEXTs, post_depth_coverageEXTs, "post depth coverage");
4079             if (extensionTurnedOn(E_GL_ARB_post_depth_coverage)) {
4080                 publicType.shaderQualifiers.earlyFragmentTests = true;
4081             }
4082             publicType.shaderQualifiers.postDepthCoverage = true;
4083             return;
4084         }
4085         for (TLayoutDepth depth = (TLayoutDepth)(EldNone + 1); depth < EldCount; depth = (TLayoutDepth)(depth+1)) {
4086             if (id == TQualifier::getLayoutDepthString(depth)) {
4087                 requireProfile(loc, ECoreProfile | ECompatibilityProfile, "depth layout qualifier");
4088                 profileRequires(loc, ECoreProfile | ECompatibilityProfile, 420, nullptr, "depth layout qualifier");
4089                 publicType.shaderQualifiers.layoutDepth = depth;
4090                 return;
4091             }
4092         }
4093         if (id.compare(0, 13, "blend_support") == 0) {
4094             bool found = false;
4095             for (TBlendEquationShift be = (TBlendEquationShift)0; be < EBlendCount; be = (TBlendEquationShift)(be + 1)) {
4096                 if (id == TQualifier::getBlendEquationString(be)) {
4097                     profileRequires(loc, EEsProfile, 320, E_GL_KHR_blend_equation_advanced, "blend equation");
4098                     profileRequires(loc, ~EEsProfile, 0, E_GL_KHR_blend_equation_advanced, "blend equation");
4099                     intermediate.addBlendEquation(be);
4100                     publicType.shaderQualifiers.blendEquation = true;
4101                     found = true;
4102                     break;
4103                 }
4104             }
4105             if (! found)
4106                 error(loc, "unknown blend equation", "blend_support", "");
4107             return;
4108         }
4109 #ifdef NV_EXTENSIONS
4110         if (id == "override_coverage") {
4111             requireExtensions(loc, 1, &E_GL_NV_sample_mask_override_coverage, "sample mask override coverage");
4112             publicType.shaderQualifiers.layoutOverrideCoverage = true;
4113             return;
4114         }
4115     }
4116     if (language == EShLangVertex ||
4117         language == EShLangTessControl ||
4118         language == EShLangTessEvaluation ||
4119         language == EShLangGeometry ) {
4120         if (id == "viewport_relative") {
4121             requireExtensions(loc, 1, &E_GL_NV_viewport_array2, "view port array2");
4122             publicType.qualifier.layoutViewportRelative = true;
4123             return;
4124         }
4125     }
4126 #else
4127     }
4128 #endif
4129     error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), "");
4130 }
4131
4132 // Put the id's layout qualifier value into the public type, for qualifiers having a number set.
4133 // This is before we know any type information for error checking.
4134 void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publicType, TString& id, const TIntermTyped* node)
4135 {
4136     const char* feature = "layout-id value";
4137     const char* nonLiteralFeature = "non-literal layout-id value";
4138
4139     integerCheck(node, feature);
4140     const TIntermConstantUnion* constUnion = node->getAsConstantUnion();
4141     int value;
4142     if (constUnion) {
4143         value = constUnion->getConstArray()[0].getIConst();
4144         if (! constUnion->isLiteral()) {
4145             requireProfile(loc, ECoreProfile | ECompatibilityProfile, nonLiteralFeature);
4146             profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, nonLiteralFeature);
4147         }
4148     } else {
4149         // grammar should have give out the error message
4150         value = 0;
4151     }
4152
4153     if (value < 0) {
4154         error(loc, "cannot be negative", feature, "");
4155         return;
4156     }
4157
4158     std::transform(id.begin(), id.end(), id.begin(), ::tolower);
4159
4160     if (id == "offset") {
4161         // "offset" can be for either
4162         //  - uniform offsets
4163         //  - atomic_uint offsets
4164         const char* feature = "offset";
4165         if (spvVersion.spv == 0) {
4166             requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature);
4167             const char* exts[2] = { E_GL_ARB_enhanced_layouts, E_GL_ARB_shader_atomic_counters };
4168             profileRequires(loc, ECoreProfile | ECompatibilityProfile, 420, 2, exts, feature);
4169             profileRequires(loc, EEsProfile, 310, nullptr, feature);
4170         }
4171         publicType.qualifier.layoutOffset = value;
4172         return;
4173     } else if (id == "align") {
4174         const char* feature = "uniform buffer-member align";
4175         if (spvVersion.spv == 0) {
4176             requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature);
4177             profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, feature);
4178         }
4179         // "The specified alignment must be a power of 2, or a compile-time error results."
4180         if (! IsPow2(value))
4181             error(loc, "must be a power of 2", "align", "");
4182         else
4183             publicType.qualifier.layoutAlign = value;
4184         return;
4185     } else if (id == "location") {
4186         profileRequires(loc, EEsProfile, 300, nullptr, "location");
4187         const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location };
4188         profileRequires(loc, ~EEsProfile, 330, 2, exts, "location");
4189         if ((unsigned int)value >= TQualifier::layoutLocationEnd)
4190             error(loc, "location is too large", id.c_str(), "");
4191         else
4192             publicType.qualifier.layoutLocation = value;
4193         return;
4194     } else if (id == "set") {
4195         if ((unsigned int)value >= TQualifier::layoutSetEnd)
4196             error(loc, "set is too large", id.c_str(), "");
4197         else
4198             publicType.qualifier.layoutSet = value;
4199         if (value != 0)
4200             requireVulkan(loc, "descriptor set");
4201         return;
4202     } else if (id == "binding") {
4203         profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, "binding");
4204         profileRequires(loc, EEsProfile, 310, nullptr, "binding");
4205         if ((unsigned int)value >= TQualifier::layoutBindingEnd)
4206             error(loc, "binding is too large", id.c_str(), "");
4207         else
4208             publicType.qualifier.layoutBinding = value;
4209         return;
4210     } else if (id == "component") {
4211         requireProfile(loc, ECoreProfile | ECompatibilityProfile, "component");
4212         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, "component");
4213         if ((unsigned)value >= TQualifier::layoutComponentEnd)
4214             error(loc, "component is too large", id.c_str(), "");
4215         else
4216             publicType.qualifier.layoutComponent = value;
4217         return;
4218     } else if (id.compare(0, 4, "xfb_") == 0) {
4219         // "Any shader making any static use (after preprocessing) of any of these
4220         // *xfb_* qualifiers will cause the shader to be in a transform feedback
4221         // capturing mode and hence responsible for describing the transform feedback
4222         // setup."
4223         intermediate.setXfbMode();
4224         const char* feature = "transform feedback qualifier";
4225         requireStage(loc, (EShLanguageMask)(EShLangVertexMask | EShLangGeometryMask | EShLangTessControlMask | EShLangTessEvaluationMask), feature);
4226         requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature);
4227         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, feature);
4228         if (id == "xfb_buffer") {
4229             // "It is a compile-time error to specify an *xfb_buffer* that is greater than
4230             // the implementation-dependent constant gl_MaxTransformFeedbackBuffers."
4231             if (value >= resources.maxTransformFeedbackBuffers)
4232                 error(loc, "buffer is too large:", id.c_str(), "gl_MaxTransformFeedbackBuffers is %d", resources.maxTransformFeedbackBuffers);
4233             if (value >= (int)TQualifier::layoutXfbBufferEnd)
4234                 error(loc, "buffer is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbBufferEnd-1);
4235             else
4236                 publicType.qualifier.layoutXfbBuffer = value;
4237             return;
4238         } else if (id == "xfb_offset") {
4239             if (value >= (int)TQualifier::layoutXfbOffsetEnd)
4240                 error(loc, "offset is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbOffsetEnd-1);
4241             else
4242                 publicType.qualifier.layoutXfbOffset = value;
4243             return;
4244         } else if (id == "xfb_stride") {
4245             // "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
4246             // implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents."
4247             if (value > 4 * resources.maxTransformFeedbackInterleavedComponents)
4248                 error(loc, "1/4 stride is too large:", id.c_str(), "gl_MaxTransformFeedbackInterleavedComponents is %d", resources.maxTransformFeedbackInterleavedComponents);
4249             else if (value >= (int)TQualifier::layoutXfbStrideEnd)
4250                 error(loc, "stride is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbStrideEnd-1);
4251             if (value < (int)TQualifier::layoutXfbStrideEnd)
4252                 publicType.qualifier.layoutXfbStride = value;
4253             return;
4254         }
4255     }
4256
4257     if (id == "input_attachment_index") {
4258         requireVulkan(loc, "input_attachment_index");
4259         if (value >= (int)TQualifier::layoutAttachmentEnd)
4260             error(loc, "attachment index is too large", id.c_str(), "");
4261         else
4262             publicType.qualifier.layoutAttachment = value;
4263         return;
4264     }
4265     if (id == "constant_id") {
4266         requireSpv(loc, "constant_id");
4267         if (value >= (int)TQualifier::layoutSpecConstantIdEnd) {
4268             error(loc, "specialization-constant id is too large", id.c_str(), "");
4269         } else {
4270             publicType.qualifier.layoutSpecConstantId = value;
4271             publicType.qualifier.specConstant = true;
4272             if (! intermediate.addUsedConstantId(value))
4273                 error(loc, "specialization-constant id already used", id.c_str(), "");
4274         }
4275         return;
4276     }
4277     if (id == "num_views") {
4278         requireExtensions(loc, Num_OVR_multiview_EXTs, OVR_multiview_EXTs, "num_views");
4279         publicType.shaderQualifiers.numViews = value;
4280         return;
4281     }
4282
4283 #if NV_EXTENSIONS
4284     if (language == EShLangVertex ||
4285         language == EShLangTessControl ||
4286         language == EShLangTessEvaluation ||
4287         language == EShLangGeometry) {
4288         if (id == "secondary_view_offset") {
4289             requireExtensions(loc, 1, &E_GL_NV_stereo_view_rendering, "stereo view rendering");
4290             publicType.qualifier.layoutSecondaryViewportRelativeOffset = value;
4291             return;
4292         }
4293     }
4294 #endif
4295
4296     switch (language) {
4297     case EShLangVertex:
4298         break;
4299
4300     case EShLangTessControl:
4301         if (id == "vertices") {
4302             if (value == 0)
4303                 error(loc, "must be greater than 0", "vertices", "");
4304             else
4305                 publicType.shaderQualifiers.vertices = value;
4306             return;
4307         }
4308         break;
4309
4310     case EShLangTessEvaluation:
4311         break;
4312
4313     case EShLangGeometry:
4314         if (id == "invocations") {
4315             profileRequires(loc, ECompatibilityProfile | ECoreProfile, 400, nullptr, "invocations");
4316             if (value == 0)
4317                 error(loc, "must be at least 1", "invocations", "");
4318             else
4319                 publicType.shaderQualifiers.invocations = value;
4320             return;
4321         }
4322         if (id == "max_vertices") {
4323             publicType.shaderQualifiers.vertices = value;
4324             if (value > resources.maxGeometryOutputVertices)
4325                 error(loc, "too large, must be less than gl_MaxGeometryOutputVertices", "max_vertices", "");
4326             return;
4327         }
4328         if (id == "stream") {
4329             requireProfile(loc, ~EEsProfile, "selecting output stream");
4330             publicType.qualifier.layoutStream = value;
4331             if (value > 0)
4332                 intermediate.setMultiStream();
4333             return;
4334         }
4335         break;
4336
4337     case EShLangFragment:
4338         if (id == "index") {
4339             requireProfile(loc, ECompatibilityProfile | ECoreProfile, "index layout qualifier on fragment output");
4340             const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location };
4341             profileRequires(loc, ECompatibilityProfile | ECoreProfile, 330, 2, exts, "index layout qualifier on fragment output");
4342
4343             // "It is also a compile-time error if a fragment shader sets a layout index to less than 0 or greater than 1."
4344             if (value < 0 || value > 1) {
4345                 value = 0;
4346                 error(loc, "value must be 0 or 1", "index", "");
4347             }
4348
4349             publicType.qualifier.layoutIndex = value;
4350             return;
4351         }
4352         break;
4353
4354     case EShLangCompute:
4355         if (id.compare(0, 11, "local_size_") == 0) {
4356             profileRequires(loc, EEsProfile, 310, 0, "gl_WorkGroupSize");
4357             profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_compute_shader, "gl_WorkGroupSize");
4358             if (id.size() == 12 && value == 0) {
4359                 error(loc, "must be at least 1", id.c_str(), "");
4360                 return;
4361             }
4362             if (id == "local_size_x") {
4363                 publicType.shaderQualifiers.localSize[0] = value;
4364                 return;
4365             }
4366             if (id == "local_size_y") {
4367                 publicType.shaderQualifiers.localSize[1] = value;
4368                 return;
4369             }
4370             if (id == "local_size_z") {
4371                 publicType.shaderQualifiers.localSize[2] = value;
4372                 return;
4373             }
4374             if (spvVersion.spv != 0) {
4375                 if (id == "local_size_x_id") {
4376                     publicType.shaderQualifiers.localSizeSpecId[0] = value;
4377                     return;
4378                 }
4379                 if (id == "local_size_y_id") {
4380                     publicType.shaderQualifiers.localSizeSpecId[1] = value;
4381                     return;
4382                 }
4383                 if (id == "local_size_z_id") {
4384                     publicType.shaderQualifiers.localSizeSpecId[2] = value;
4385                     return;
4386                 }
4387             }
4388         }
4389         break;
4390
4391     default:
4392         break;
4393     }
4394
4395     error(loc, "there is no such layout identifier for this stage taking an assigned value", id.c_str(), "");
4396 }
4397
4398 // Merge any layout qualifier information from src into dst, leaving everything else in dst alone
4399 //
4400 // "More than one layout qualifier may appear in a single declaration.
4401 // Additionally, the same layout-qualifier-name can occur multiple times
4402 // within a layout qualifier or across multiple layout qualifiers in the
4403 // same declaration. When the same layout-qualifier-name occurs
4404 // multiple times, in a single declaration, the last occurrence overrides
4405 // the former occurrence(s).  Further, if such a layout-qualifier-name
4406 // will effect subsequent declarations or other observable behavior, it
4407 // is only the last occurrence that will have any effect, behaving as if
4408 // the earlier occurrence(s) within the declaration are not present.
4409 // This is also true for overriding layout-qualifier-names, where one
4410 // overrides the other (e.g., row_major vs. column_major); only the last
4411 // occurrence has any effect."
4412 void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifier& src, bool inheritOnly)
4413 {
4414     if (src.hasMatrix())
4415         dst.layoutMatrix = src.layoutMatrix;
4416     if (src.hasPacking())
4417         dst.layoutPacking = src.layoutPacking;
4418
4419     if (src.hasStream())
4420         dst.layoutStream = src.layoutStream;
4421
4422     if (src.hasFormat())
4423         dst.layoutFormat = src.layoutFormat;
4424
4425     if (src.hasXfbBuffer())
4426         dst.layoutXfbBuffer = src.layoutXfbBuffer;
4427
4428     if (src.hasAlign())
4429         dst.layoutAlign = src.layoutAlign;
4430
4431     if (! inheritOnly) {
4432         if (src.hasLocation())
4433             dst.layoutLocation = src.layoutLocation;
4434         if (src.hasComponent())
4435             dst.layoutComponent = src.layoutComponent;
4436         if (src.hasIndex())
4437             dst.layoutIndex = src.layoutIndex;
4438
4439         if (src.hasOffset())
4440             dst.layoutOffset = src.layoutOffset;
4441
4442         if (src.hasSet())
4443             dst.layoutSet = src.layoutSet;
4444         if (src.layoutBinding != TQualifier::layoutBindingEnd)
4445             dst.layoutBinding = src.layoutBinding;
4446
4447         if (src.hasXfbStride())
4448             dst.layoutXfbStride = src.layoutXfbStride;
4449         if (src.hasXfbOffset())
4450             dst.layoutXfbOffset = src.layoutXfbOffset;
4451         if (src.hasAttachment())
4452             dst.layoutAttachment = src.layoutAttachment;
4453         if (src.hasSpecConstantId())
4454             dst.layoutSpecConstantId = src.layoutSpecConstantId;
4455
4456         if (src.layoutPushConstant)
4457             dst.layoutPushConstant = true;
4458
4459 #ifdef NV_EXTENSIONS
4460         if (src.layoutPassthrough)
4461             dst.layoutPassthrough = true;
4462         if (src.layoutViewportRelative)
4463             dst.layoutViewportRelative = true;
4464         if (src.layoutSecondaryViewportRelativeOffset != -2048)
4465             dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset;
4466 #endif
4467     }
4468 }
4469
4470 // Do error layout error checking given a full variable/block declaration.
4471 void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symbol)
4472 {
4473     const TType& type = symbol.getType();
4474     const TQualifier& qualifier = type.getQualifier();
4475
4476     // first, cross check WRT to just the type
4477     layoutTypeCheck(loc, type);
4478
4479     // now, any remaining error checking based on the object itself
4480
4481     if (qualifier.hasAnyLocation()) {
4482         switch (qualifier.storage) {
4483         case EvqUniform:
4484         case EvqBuffer:
4485             if (symbol.getAsVariable() == nullptr)
4486                 error(loc, "can only be used on variable declaration", "location", "");
4487             break;
4488         default:
4489             break;
4490         }
4491     }
4492
4493     // user-variable location check, which are required for SPIR-V in/out:
4494     //  - variables have it directly,
4495     //  - blocks have it on each member (already enforced), so check first one
4496     if (spvVersion.spv > 0 && !parsingBuiltins && qualifier.builtIn == EbvNone &&
4497         !qualifier.hasLocation() && !intermediate.getAutoMapLocations()) {
4498
4499         switch (qualifier.storage) {
4500         case EvqVaryingIn:
4501         case EvqVaryingOut:
4502             if (type.getBasicType() != EbtBlock ||
4503                 (!(*type.getStruct())[0].type->getQualifier().hasLocation() &&
4504                   (*type.getStruct())[0].type->getQualifier().builtIn == EbvNone))
4505                 error(loc, "SPIR-V requires location for user input/output", "location", "");
4506             break;
4507         default:
4508             break;
4509         }
4510     }
4511
4512     // Check packing and matrix
4513     if (qualifier.hasUniformLayout()) {
4514         switch (qualifier.storage) {
4515         case EvqUniform:
4516         case EvqBuffer:
4517             if (type.getBasicType() != EbtBlock) {
4518                 if (qualifier.hasMatrix())
4519                     error(loc, "cannot specify matrix layout on a variable declaration", "layout", "");
4520                 if (qualifier.hasPacking())
4521                     error(loc, "cannot specify packing on a variable declaration", "layout", "");
4522                 // "The offset qualifier can only be used on block members of blocks..."
4523                 if (qualifier.hasOffset() && type.getBasicType() != EbtAtomicUint)
4524                     error(loc, "cannot specify on a variable declaration", "offset", "");
4525                 // "The align qualifier can only be used on blocks or block members..."
4526                 if (qualifier.hasAlign())
4527                     error(loc, "cannot specify on a variable declaration", "align", "");
4528                 if (qualifier.layoutPushConstant)
4529                     error(loc, "can only specify on a uniform block", "push_constant", "");
4530             }
4531             break;
4532         default:
4533             // these were already filtered by layoutTypeCheck() (or its callees)
4534             break;
4535         }
4536     }
4537 }
4538
4539 // "For some blocks declared as arrays, the location can only be applied at the block level:
4540 // When a block is declared as an array where additional locations are needed for each member
4541 // for each block array element, it is a compile-time error to specify locations on the block
4542 // members.  That is, when locations would be under specified by applying them on block members,
4543 // they are not allowed on block members.  For arrayed interfaces (those generally having an
4544 // extra level of arrayness due to interface expansion), the outer array is stripped before
4545 // applying this rule."
4546 void TParseContext::layoutMemberLocationArrayCheck(const TSourceLoc& loc, bool memberWithLocation, TArraySizes* arraySizes)
4547 {
4548     if (memberWithLocation && arraySizes != nullptr) {
4549         if (arraySizes->getNumDims() > (currentBlockQualifier.isArrayedIo(language) ? 1 : 0))
4550             error(loc, "cannot use in a block array where new locations are needed for each block element",
4551                        "location", "");
4552     }
4553 }
4554
4555 // Do layout error checking with respect to a type.
4556 void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
4557 {
4558     const TQualifier& qualifier = type.getQualifier();
4559
4560     // first, intra-layout qualifier-only error checking
4561     layoutQualifierCheck(loc, qualifier);
4562
4563     // now, error checking combining type and qualifier
4564
4565     if (qualifier.hasAnyLocation()) {
4566         if (qualifier.hasLocation()) {
4567             if (qualifier.storage == EvqVaryingOut && language == EShLangFragment) {
4568                 if (qualifier.layoutLocation >= (unsigned int)resources.maxDrawBuffers)
4569                     error(loc, "too large for fragment output", "location", "");
4570             }
4571         }
4572         if (qualifier.hasComponent()) {
4573             // "It is a compile-time error if this sequence of components gets larger than 3."
4574             if (qualifier.layoutComponent + type.getVectorSize() * (type.getBasicType() == EbtDouble ? 2 : 1) > 4)
4575                 error(loc, "type overflows the available 4 components", "component", "");
4576
4577             // "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."
4578             if (type.isMatrix() || type.getBasicType() == EbtBlock || type.getBasicType() == EbtStruct)
4579                 error(loc, "cannot apply to a matrix, structure, or block", "component", "");
4580
4581             // " It is a compile-time error to use component 1 or 3 as the beginning of a double or dvec2."
4582             if (type.getBasicType() == EbtDouble)
4583                 if (qualifier.layoutComponent & 1)
4584                     error(loc, "doubles cannot start on an odd-numbered component", "component", "");
4585         }
4586
4587         switch (qualifier.storage) {
4588         case EvqVaryingIn:
4589         case EvqVaryingOut:
4590             if (type.getBasicType() == EbtBlock)
4591                 profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, "location qualifier on in/out block");
4592             break;
4593         case EvqUniform:
4594         case EvqBuffer:
4595             if (type.getBasicType() == EbtBlock)
4596                 error(loc, "cannot apply to uniform or buffer block", "location", "");
4597             break;
4598         default:
4599             error(loc, "can only apply to uniform, buffer, in, or out storage qualifiers", "location", "");
4600             break;
4601         }
4602
4603         bool typeCollision;
4604         int repeated = intermediate.addUsedLocation(qualifier, type, typeCollision);
4605         if (repeated >= 0 && ! typeCollision)
4606             error(loc, "overlapping use of location", "location", "%d", repeated);
4607         // "fragment-shader outputs ... if two variables are placed within the same
4608         // location, they must have the same underlying type (floating-point or integer)"
4609         if (typeCollision && language == EShLangFragment && qualifier.isPipeOutput())
4610             error(loc, "fragment outputs sharing the same location must be the same basic type", "location", "%d", repeated);
4611     }
4612
4613     if (qualifier.hasXfbOffset() && qualifier.hasXfbBuffer()) {
4614         int repeated = intermediate.addXfbBufferOffset(type);
4615         if (repeated >= 0)
4616             error(loc, "overlapping offsets at", "xfb_offset", "offset %d in buffer %d", repeated, qualifier.layoutXfbBuffer);
4617
4618         // "The offset must be a multiple of the size of the first component of the first
4619         // qualified variable or block member, or a compile-time error results. Further, if applied to an aggregate
4620         // containing a double, the offset must also be a multiple of 8..."
4621         if (type.containsBasicType(EbtDouble) && ! IsMultipleOfPow2(qualifier.layoutXfbOffset, 8))
4622             error(loc, "type contains double; xfb_offset must be a multiple of 8", "xfb_offset", "");
4623 #ifdef AMD_EXTENSIONS
4624         // ..., if applied to an aggregate containing a float16_t, the offset must also be a multiple of 2..."
4625         else if (type.containsBasicType(EbtFloat16) && !IsMultipleOfPow2(qualifier.layoutXfbOffset, 2))
4626             error(loc, "type contains half float; xfb_offset must be a multiple of 2", "xfb_offset", "");
4627 #endif
4628         else if (! IsMultipleOfPow2(qualifier.layoutXfbOffset, 4))
4629             error(loc, "must be a multiple of size of first component", "xfb_offset", "");
4630     }
4631
4632     if (qualifier.hasXfbStride() && qualifier.hasXfbBuffer()) {
4633         if (! intermediate.setXfbBufferStride(qualifier.layoutXfbBuffer, qualifier.layoutXfbStride))
4634             error(loc, "all stride settings must match for xfb buffer", "xfb_stride", "%d", qualifier.layoutXfbBuffer);
4635     }
4636
4637     if (qualifier.hasBinding()) {
4638         // Binding checking, from the spec:
4639         //
4640         // "If the binding point for any uniform or shader storage block instance is less than zero, or greater than or
4641         // equal to the implementation-dependent maximum number of uniform buffer bindings, a compile-time
4642         // error will occur. When the binding identifier is used with a uniform or shader storage block instanced as
4643         // an array of size N, all elements of the array from binding through binding + N - 1 must be within this
4644         // range."
4645         //
4646         if (! type.isOpaque() && type.getBasicType() != EbtBlock)
4647             error(loc, "requires block, or sampler/image, or atomic-counter type", "binding", "");
4648         if (type.getBasicType() == EbtSampler) {
4649             int lastBinding = qualifier.layoutBinding;
4650             if (type.isArray()) {
4651                 if (type.isImplicitlySizedArray()) {
4652                     lastBinding += 1;
4653                     warn(loc, "assuming array size of one for compile-time checking of binding numbers for implicitly-sized array", "[]", "");
4654                 } else
4655                     lastBinding += type.getCumulativeArraySize();
4656             }
4657             if (spvVersion.vulkan == 0 && lastBinding >= resources.maxCombinedTextureImageUnits)
4658                 error(loc, "sampler binding not less than gl_MaxCombinedTextureImageUnits", "binding", type.isArray() ? "(using array)" : "");
4659         }
4660         if (type.getBasicType() == EbtAtomicUint) {
4661             if (qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) {
4662                 error(loc, "atomic_uint binding is too large; see gl_MaxAtomicCounterBindings", "binding", "");
4663                 return;
4664             }
4665         }
4666     }
4667
4668     // atomic_uint
4669     if (type.getBasicType() == EbtAtomicUint) {
4670         if (! type.getQualifier().hasBinding())
4671             error(loc, "layout(binding=X) is required", "atomic_uint", "");
4672     }
4673
4674     // "The offset qualifier can only be used on block members of blocks..."
4675     if (qualifier.hasOffset()) {
4676         if (type.getBasicType() == EbtBlock)
4677             error(loc, "only applies to block members, not blocks", "offset", "");
4678     }
4679
4680     // Image format
4681     if (qualifier.hasFormat()) {
4682         if (! type.isImage())
4683             error(loc, "only apply to images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), "");
4684         else {
4685             if (type.getSampler().type == EbtFloat && qualifier.layoutFormat > ElfFloatGuard)
4686                 error(loc, "does not apply to floating point images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), "");
4687             if (type.getSampler().type == EbtInt && (qualifier.layoutFormat < ElfFloatGuard || qualifier.layoutFormat > ElfIntGuard))
4688                 error(loc, "does not apply to signed integer images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), "");
4689             if (type.getSampler().type == EbtUint && qualifier.layoutFormat < ElfIntGuard)
4690                 error(loc, "does not apply to unsigned integer images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), "");
4691
4692             if (profile == EEsProfile) {
4693                 // "Except for image variables qualified with the format qualifiers r32f, r32i, and r32ui, image variables must
4694                 // specify either memory qualifier readonly or the memory qualifier writeonly."
4695                 if (! (qualifier.layoutFormat == ElfR32f || qualifier.layoutFormat == ElfR32i || qualifier.layoutFormat == ElfR32ui)) {
4696                     if (! qualifier.readonly && ! qualifier.writeonly)
4697                         error(loc, "format requires readonly or writeonly memory qualifier", TQualifier::getLayoutFormatString(qualifier.layoutFormat), "");
4698                 }
4699             }
4700         }
4701     } else if (type.isImage() && ! qualifier.writeonly) {
4702         const char *explanation = "image variables not declared 'writeonly' and without a format layout qualifier";
4703         requireProfile(loc, ECoreProfile | ECompatibilityProfile, explanation);
4704         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shader_image_load_formatted, explanation);
4705     }
4706
4707     if (qualifier.layoutPushConstant && type.getBasicType() != EbtBlock)
4708         error(loc, "can only be used with a block", "push_constant", "");
4709
4710     // input attachment
4711     if (type.isSubpass()) {
4712         if (! qualifier.hasAttachment())
4713             error(loc, "requires an input_attachment_index layout qualifier", "subpass", "");
4714     } else {
4715         if (qualifier.hasAttachment())
4716             error(loc, "can only be used with a subpass", "input_attachment_index", "");
4717     }
4718
4719     // specialization-constant id
4720     if (qualifier.hasSpecConstantId()) {
4721         if (type.getQualifier().storage != EvqConst)
4722             error(loc, "can only be applied to 'const'-qualified scalar", "constant_id", "");
4723         if (! type.isScalar())
4724             error(loc, "can only be applied to a scalar", "constant_id", "");
4725         switch (type.getBasicType())
4726         {
4727         case EbtInt:
4728         case EbtUint:
4729         case EbtInt64:
4730         case EbtUint64:
4731 #ifdef AMD_EXTENSIONS
4732         case EbtInt16:
4733         case EbtUint16:
4734 #endif
4735         case EbtBool:
4736         case EbtFloat:
4737         case EbtDouble:
4738 #ifdef AMD_EXTENSIONS
4739         case EbtFloat16:
4740 #endif
4741             break;
4742         default:
4743             error(loc, "cannot be applied to this type", "constant_id", "");
4744             break;
4745         }
4746     }
4747 }
4748
4749 // Do layout error checking that can be done within a layout qualifier proper, not needing to know
4750 // if there are blocks, atomic counters, variables, etc.
4751 void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier& qualifier)
4752 {
4753     if (qualifier.storage == EvqShared && qualifier.hasLayout())
4754         error(loc, "cannot apply layout qualifiers to a shared variable", "shared", "");
4755
4756     // "It is a compile-time error to use *component* without also specifying the location qualifier (order does not matter)."
4757     if (qualifier.hasComponent() && ! qualifier.hasLocation())
4758         error(loc, "must specify 'location' to use 'component'", "component", "");
4759
4760     if (qualifier.hasAnyLocation()) {
4761
4762         // "As with input layout qualifiers, all shaders except compute shaders
4763         // allow *location* layout qualifiers on output variable declarations,
4764         // output block declarations, and output block member declarations."
4765
4766         switch (qualifier.storage) {
4767         case EvqVaryingIn:
4768         {
4769             const char* feature = "location qualifier on input";
4770             if (profile == EEsProfile && version < 310)
4771                 requireStage(loc, EShLangVertex, feature);
4772             else
4773                 requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature);
4774             if (language == EShLangVertex) {
4775                 const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location };
4776                 profileRequires(loc, ~EEsProfile, 330, 2, exts, feature);
4777                 profileRequires(loc, EEsProfile, 300, nullptr, feature);
4778             } else {
4779                 profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_separate_shader_objects, feature);
4780                 profileRequires(loc, EEsProfile, 310, nullptr, feature);
4781             }
4782             break;
4783         }
4784         case EvqVaryingOut:
4785         {
4786             const char* feature = "location qualifier on output";
4787             if (profile == EEsProfile && version < 310)
4788                 requireStage(loc, EShLangFragment, feature);
4789             else
4790                 requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature);
4791             if (language == EShLangFragment) {
4792                 const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location };
4793                 profileRequires(loc, ~EEsProfile, 330, 2, exts, feature);
4794                 profileRequires(loc, EEsProfile, 300, nullptr, feature);
4795             } else {
4796                 profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_separate_shader_objects, feature);
4797                 profileRequires(loc, EEsProfile, 310, nullptr, feature);
4798             }
4799             break;
4800         }
4801         case EvqUniform:
4802         case EvqBuffer:
4803         {
4804             const char* feature = "location qualifier on uniform or buffer";
4805             requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature);
4806             profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, feature);
4807             profileRequires(loc, EEsProfile, 310, nullptr, feature);
4808             break;
4809         }
4810         default:
4811             break;
4812         }
4813         if (qualifier.hasIndex()) {
4814             if (qualifier.storage != EvqVaryingOut)
4815                 error(loc, "can only be used on an output", "index", "");
4816             if (! qualifier.hasLocation())
4817                 error(loc, "can only be used with an explicit location", "index", "");
4818         }
4819     }
4820
4821     if (qualifier.hasBinding()) {
4822         if (! qualifier.isUniformOrBuffer())
4823             error(loc, "requires uniform or buffer storage qualifier", "binding", "");
4824     }
4825     if (qualifier.hasStream()) {
4826         if (!qualifier.isPipeOutput())
4827             error(loc, "can only be used on an output", "stream", "");
4828     }
4829     if (qualifier.hasXfb()) {
4830         if (!qualifier.isPipeOutput())
4831             error(loc, "can only be used on an output", "xfb layout qualifier", "");
4832     }
4833     if (qualifier.hasUniformLayout()) {
4834         if (! qualifier.isUniformOrBuffer()) {
4835             if (qualifier.hasMatrix() || qualifier.hasPacking())
4836                 error(loc, "matrix or packing qualifiers can only be used on a uniform or buffer", "layout", "");
4837             if (qualifier.hasOffset() || qualifier.hasAlign())
4838                 error(loc, "offset/align can only be used on a uniform or buffer", "layout", "");
4839         }
4840     }
4841     if (qualifier.layoutPushConstant) {
4842         if (qualifier.storage != EvqUniform)
4843             error(loc, "can only be used with a uniform", "push_constant", "");
4844         if (qualifier.hasSet())
4845             error(loc, "cannot be used with push_constant", "set", "");
4846     }
4847 }
4848
4849 // For places that can't have shader-level layout qualifiers
4850 void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQualifiers& shaderQualifiers)
4851 {
4852     const char* message = "can only apply to a standalone qualifier";
4853
4854     if (shaderQualifiers.geometry != ElgNone)
4855         error(loc, message, TQualifier::getGeometryString(shaderQualifiers.geometry), "");
4856     if (shaderQualifiers.spacing != EvsNone)
4857         error(loc, message, TQualifier::getVertexSpacingString(shaderQualifiers.spacing), "");
4858     if (shaderQualifiers.order != EvoNone)
4859         error(loc, message, TQualifier::getVertexOrderString(shaderQualifiers.order), "");
4860     if (shaderQualifiers.pointMode)
4861         error(loc, message, "point_mode", "");
4862     if (shaderQualifiers.invocations != TQualifier::layoutNotSet)
4863         error(loc, message, "invocations", "");
4864     if (shaderQualifiers.earlyFragmentTests)
4865         error(loc, message, "early_fragment_tests", "");
4866     if (shaderQualifiers.postDepthCoverage)
4867         error(loc, message, "post_depth_coverage", "");
4868     for (int i = 0; i < 3; ++i) {
4869         if (shaderQualifiers.localSize[i] > 1)
4870             error(loc, message, "local_size", "");
4871         if (shaderQualifiers.localSizeSpecId[i] != TQualifier::layoutNotSet)
4872             error(loc, message, "local_size id", "");
4873     }
4874     if (shaderQualifiers.vertices != TQualifier::layoutNotSet) {
4875         if (language == EShLangGeometry)
4876             error(loc, message, "max_vertices", "");
4877         else if (language == EShLangTessControl)
4878             error(loc, message, "vertices", "");
4879         else
4880             assert(0);
4881     }
4882     if (shaderQualifiers.blendEquation)
4883         error(loc, message, "blend equation", "");
4884     if (shaderQualifiers.numViews != TQualifier::layoutNotSet)
4885         error(loc, message, "num_views", "");
4886 }
4887
4888 // Correct and/or advance an object's offset layout qualifier.
4889 void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol)
4890 {
4891     const TQualifier& qualifier = symbol.getType().getQualifier();
4892     if (symbol.getType().getBasicType() == EbtAtomicUint) {
4893         if (qualifier.hasBinding() && (int)qualifier.layoutBinding < resources.maxAtomicCounterBindings) {
4894
4895             // Set the offset
4896             int offset;
4897             if (qualifier.hasOffset())
4898                 offset = qualifier.layoutOffset;
4899             else
4900                 offset = atomicUintOffsets[qualifier.layoutBinding];
4901             symbol.getWritableType().getQualifier().layoutOffset = offset;
4902
4903             // Check for overlap
4904             int numOffsets = 4;
4905             if (symbol.getType().isArray()) {
4906                 if (symbol.getType().isExplicitlySizedArray() && ! symbol.getType().getArraySizes()->isInnerImplicit())
4907                     numOffsets *= symbol.getType().getCumulativeArraySize();
4908                 else {
4909                     // "It is a compile-time error to declare an unsized array of atomic_uint."
4910                     error(loc, "array must be explicitly sized", "atomic_uint", "");
4911                 }
4912             }
4913             int repeated = intermediate.addUsedOffsets(qualifier.layoutBinding, offset, numOffsets);
4914             if (repeated >= 0)
4915                 error(loc, "atomic counters sharing the same offset:", "offset", "%d", repeated);
4916
4917             // Bump the default offset
4918             atomicUintOffsets[qualifier.layoutBinding] = offset + numOffsets;
4919         }
4920     }
4921 }
4922
4923 //
4924 // Look up a function name in the symbol table, and make sure it is a function.
4925 //
4926 // Return the function symbol if found, otherwise nullptr.
4927 //
4928 const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
4929 {
4930     const TFunction* function = nullptr;
4931
4932     if (symbolTable.isFunctionNameVariable(call.getName())) {
4933         error(loc, "can't use function syntax on variable", call.getName().c_str(), "");
4934         return nullptr;
4935     }
4936
4937     if (profile == EEsProfile || version < 120)
4938         function = findFunctionExact(loc, call, builtIn);
4939     else if (version < 400)
4940         function = findFunction120(loc, call, builtIn);
4941     else
4942         function = findFunction400(loc, call, builtIn);
4943
4944     return function;
4945 }
4946
4947 // Function finding algorithm for ES and desktop 110.
4948 const TFunction* TParseContext::findFunctionExact(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
4949 {
4950     TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn);
4951     if (symbol == nullptr) {
4952         error(loc, "no matching overloaded function found", call.getName().c_str(), "");
4953
4954         return nullptr;
4955     }
4956
4957     return symbol->getAsFunction();
4958 }
4959
4960 // Function finding algorithm for desktop versions 120 through 330.
4961 const TFunction* TParseContext::findFunction120(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
4962 {
4963     // first, look for an exact match
4964     TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn);
4965     if (symbol)
4966         return symbol->getAsFunction();
4967
4968     // exact match not found, look through a list of overloaded functions of the same name
4969
4970     // "If no exact match is found, then [implicit conversions] will be applied to find a match. Mismatched types
4971     // on input parameters (in or inout or default) must have a conversion from the calling argument type to the
4972     // formal parameter type. Mismatched types on output parameters (out or inout) must have a conversion
4973     // from the formal parameter type to the calling argument type.  When argument conversions are used to find
4974     // a match, it is a semantic error if there are multiple ways to apply these conversions to make the call match
4975     // more than one function."
4976
4977     const TFunction* candidate = nullptr;
4978     TVector<const TFunction*> candidateList;
4979     symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
4980
4981     for (auto it = candidateList.begin(); it != candidateList.end(); ++it) {
4982         const TFunction& function = *(*it);
4983
4984         // to even be a potential match, number of arguments has to match
4985         if (call.getParamCount() != function.getParamCount())
4986             continue;
4987
4988         bool possibleMatch = true;
4989         for (int i = 0; i < function.getParamCount(); ++i) {
4990             // same types is easy
4991             if (*function[i].type == *call[i].type)
4992                 continue;
4993
4994             // We have a mismatch in type, see if it is implicitly convertible
4995
4996             if (function[i].type->isArray() || call[i].type->isArray() ||
4997                 ! function[i].type->sameElementShape(*call[i].type))
4998                 possibleMatch = false;
4999             else {
5000                 // do direction-specific checks for conversion of basic type
5001                 if (function[i].type->getQualifier().isParamInput()) {
5002                     if (! intermediate.canImplicitlyPromote(call[i].type->getBasicType(), function[i].type->getBasicType()))
5003                         possibleMatch = false;
5004                 }
5005                 if (function[i].type->getQualifier().isParamOutput()) {
5006                     if (! intermediate.canImplicitlyPromote(function[i].type->getBasicType(), call[i].type->getBasicType()))
5007                         possibleMatch = false;
5008                 }
5009             }
5010             if (! possibleMatch)
5011                 break;
5012         }
5013         if (possibleMatch) {
5014             if (candidate) {
5015                 // our second match, meaning ambiguity
5016                 error(loc, "ambiguous function signature match: multiple signatures match under implicit type conversion", call.getName().c_str(), "");
5017             } else
5018                 candidate = &function;
5019         }
5020     }
5021
5022     if (candidate == nullptr)
5023         error(loc, "no matching overloaded function found", call.getName().c_str(), "");
5024
5025     return candidate;
5026 }
5027
5028 // Function finding algorithm for desktop version 400 and above.
5029 //
5030 // "When function calls are resolved, an exact type match for all the arguments
5031 // is sought. If an exact match is found, all other functions are ignored, and
5032 // the exact match is used. If no exact match is found, then the implicit
5033 // conversions in section 4.1.10 Implicit Conversions will be applied to find
5034 // a match. Mismatched types on input parameters (in or inout or default) must
5035 // have a conversion from the calling argument type to the formal parameter type.
5036 // Mismatched types on output parameters (out or inout) must have a conversion
5037 // from the formal parameter type to the calling argument type.
5038 //
5039 // "If implicit conversions can be used to find more than one matching function,
5040 // a single best-matching function is sought. To determine a best match, the
5041 // conversions between calling argument and formal parameter types are compared
5042 // for each function argument and pair of matching functions. After these
5043 // comparisons are performed, each pair of matching functions are compared.
5044 // A function declaration A is considered a better match than function
5045 // declaration B if
5046 //
5047 //  * for at least one function argument, the conversion for that argument in A
5048 //    is better than the corresponding conversion in B; and
5049 //  * there is no function argument for which the conversion in B is better than
5050 //    the corresponding conversion in A.
5051 //
5052 // "If a single function declaration is considered a better match than every
5053 // other matching function declaration, it will be used. Otherwise, a
5054 // compile-time semantic error for an ambiguous overloaded function call occurs.
5055 //
5056 // "To determine whether the conversion for a single argument in one match is
5057 // better than that for another match, the following rules are applied, in order:
5058 //
5059 //  1. An exact match is better than a match involving any implicit conversion.
5060 //  2. A match involving an implicit conversion from float to double is better
5061 //     than a match involving any other implicit conversion.
5062 //  3. A match involving an implicit conversion from either int or uint to float
5063 //     is better than a match involving an implicit conversion from either int
5064 //     or uint to double.
5065 //
5066 // "If none of the rules above apply to a particular pair of conversions, neither
5067 // conversion is considered better than the other."
5068 //
5069 const TFunction* TParseContext::findFunction400(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
5070 {
5071     // first, look for an exact match
5072     TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn);
5073     if (symbol)
5074         return symbol->getAsFunction();
5075
5076     // no exact match, use the generic selector, parameterized by the GLSL rules
5077
5078     // create list of candidates to send
5079     TVector<const TFunction*> candidateList;
5080     symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
5081
5082     // can 'from' convert to 'to'?
5083     const auto convertible = [this](const TType& from, const TType& to, TOperator, int) -> bool {
5084         if (from == to)
5085             return true;
5086         if (from.isArray() || to.isArray() || ! from.sameElementShape(to))
5087             return false;
5088         return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType());
5089     };
5090
5091     // Is 'to2' a better conversion than 'to1'?
5092     // Ties should not be considered as better.
5093     // Assumes 'convertible' already said true.
5094     const auto better = [](const TType& from, const TType& to1, const TType& to2) -> bool {
5095         // 1. exact match
5096         if (from == to2)
5097             return from != to1;
5098         if (from == to1)
5099             return false;
5100
5101         // 2. float -> double is better
5102         if (from.getBasicType() == EbtFloat) {
5103             if (to2.getBasicType() == EbtDouble && to1.getBasicType() != EbtDouble)
5104                 return true;
5105         }
5106
5107         // 3. -> float is better than -> double
5108         return to2.getBasicType() == EbtFloat && to1.getBasicType() == EbtDouble;
5109     };
5110
5111     // for ambiguity reporting
5112     bool tie = false;
5113
5114     // send to the generic selector
5115     const TFunction* bestMatch = selectFunction(candidateList, call, convertible, better, tie);
5116
5117     if (bestMatch == nullptr)
5118         error(loc, "no matching overloaded function found", call.getName().c_str(), "");
5119     else if (tie)
5120         error(loc, "ambiguous best function under implicit type conversion", call.getName().c_str(), "");
5121
5122     return bestMatch;
5123 }
5124
5125 // When a declaration includes a type, but not a variable name, it can be
5126 // to establish defaults.
5127 void TParseContext::declareTypeDefaults(const TSourceLoc& loc, const TPublicType& publicType)
5128 {
5129     if (publicType.basicType == EbtAtomicUint && publicType.qualifier.hasBinding() && publicType.qualifier.hasOffset()) {
5130         if (publicType.qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) {
5131             error(loc, "atomic_uint binding is too large", "binding", "");
5132             return;
5133         }
5134         atomicUintOffsets[publicType.qualifier.layoutBinding] = publicType.qualifier.layoutOffset;
5135         return;
5136     }
5137
5138     if (publicType.qualifier.hasLayout())
5139         warn(loc, "useless application of layout qualifier", "layout", "");
5140 }
5141
5142 //
5143 // Do everything necessary to handle a variable (non-block) declaration.
5144 // Either redeclaring a variable, or making a new one, updating the symbol
5145 // table, and all error checking.
5146 //
5147 // Returns a subtree node that computes an initializer, if needed.
5148 // Returns nullptr if there is no code to execute for initialization.
5149 //
5150 // 'publicType' is the type part of the declaration (to the left)
5151 // 'arraySizes' is the arrayness tagged on the identifier (to the right)
5152 //
5153 TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& identifier, const TPublicType& publicType, TArraySizes* arraySizes, TIntermTyped* initializer)
5154 {
5155     TType type(publicType);  // shallow copy; 'type' shares the arrayness and structure definition with 'publicType'
5156     if (type.isImplicitlySizedArray()) {
5157         // Because "int[] a = int[2](...), b = int[3](...)" makes two arrays a and b
5158         // of different sizes, for this case sharing the shallow copy of arrayness
5159         // with the publicType oversubscribes it, so get a deep copy of the arrayness.
5160         type.newArraySizes(*publicType.arraySizes);
5161     }
5162
5163     if (voidErrorCheck(loc, identifier, type.getBasicType()))
5164         return nullptr;
5165
5166     if (initializer)
5167         rValueErrorCheck(loc, "initializer", initializer);
5168     else
5169         nonInitConstCheck(loc, identifier, type);
5170
5171     samplerCheck(loc, type, identifier, initializer);
5172     atomicUintCheck(loc, type, identifier);
5173     transparentOpaqueCheck(loc, type, identifier);
5174
5175     if (identifier != "gl_FragCoord" && (publicType.shaderQualifiers.originUpperLeft || publicType.shaderQualifiers.pixelCenterInteger))
5176         error(loc, "can only apply origin_upper_left and pixel_center_origin to gl_FragCoord", "layout qualifier", "");
5177     if (identifier != "gl_FragDepth" && publicType.shaderQualifiers.layoutDepth != EldNone)
5178         error(loc, "can only apply depth layout to gl_FragDepth", "layout qualifier", "");
5179
5180     // Check for redeclaration of built-ins and/or attempting to declare a reserved name
5181     TSymbol* symbol = redeclareBuiltinVariable(loc, identifier, type.getQualifier(), publicType.shaderQualifiers);
5182     if (symbol == nullptr)
5183         reservedErrorCheck(loc, identifier);
5184
5185     inheritGlobalDefaults(type.getQualifier());
5186
5187     // Declare the variable
5188     if (arraySizes || type.isArray()) {
5189         // Arrayness is potentially coming both from the type and from the
5190         // variable: "int[] a[];" or just one or the other.
5191         // Merge it all to the type, so all arrayness is part of the type.
5192         arrayDimCheck(loc, &type, arraySizes);
5193         arrayDimMerge(type, arraySizes);
5194
5195         // Check that implicit sizing is only where allowed.
5196         arraySizesCheck(loc, type.getQualifier(), &type.getArraySizes(), initializer != nullptr, false);
5197
5198         if (! arrayQualifierError(loc, type.getQualifier()) && ! arrayError(loc, type))
5199             declareArray(loc, identifier, type, symbol);
5200
5201         if (initializer) {
5202             profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, "initializer");
5203             profileRequires(loc, EEsProfile, 300, nullptr, "initializer");
5204         }
5205     } else {
5206         // non-array case
5207         if (symbol == nullptr)
5208             symbol = declareNonArray(loc, identifier, type);
5209         else if (type != symbol->getType())
5210             error(loc, "cannot change the type of", "redeclaration", symbol->getName().c_str());
5211     }
5212
5213     if (symbol == nullptr)
5214         return nullptr;
5215
5216     // Deal with initializer
5217     TIntermNode* initNode = nullptr;
5218     if (symbol != nullptr && initializer) {
5219         TVariable* variable = symbol->getAsVariable();
5220         if (! variable) {
5221             error(loc, "initializer requires a variable, not a member", identifier.c_str(), "");
5222             return nullptr;
5223         }
5224         initNode = executeInitializer(loc, initializer, variable);
5225     }
5226
5227     // look for errors in layout qualifier use
5228     layoutObjectCheck(loc, *symbol);
5229
5230     // fix up
5231     fixOffset(loc, *symbol);
5232
5233     return initNode;
5234 }
5235
5236 // Pick up global defaults from the provide global defaults into dst.
5237 void TParseContext::inheritGlobalDefaults(TQualifier& dst) const
5238 {
5239     if (dst.storage == EvqVaryingOut) {
5240         if (! dst.hasStream() && language == EShLangGeometry)
5241             dst.layoutStream = globalOutputDefaults.layoutStream;
5242         if (! dst.hasXfbBuffer())
5243             dst.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer;
5244     }
5245 }
5246
5247 //
5248 // Make an internal-only variable whose name is for debug purposes only
5249 // and won't be searched for.  Callers will only use the return value to use
5250 // the variable, not the name to look it up.  It is okay if the name
5251 // is the same as other names; there won't be any conflict.
5252 //
5253 TVariable* TParseContext::makeInternalVariable(const char* name, const TType& type) const
5254 {
5255     TString* nameString = NewPoolTString(name);
5256     TVariable* variable = new TVariable(nameString, type);
5257     symbolTable.makeInternalVariable(*variable);
5258
5259     return variable;
5260 }
5261
5262 //
5263 // Declare a non-array variable, the main point being there is no redeclaration
5264 // for resizing allowed.
5265 //
5266 // Return the successfully declared variable.
5267 //
5268 TVariable* TParseContext::declareNonArray(const TSourceLoc& loc, const TString& identifier, const TType& type)
5269 {
5270     // make a new variable
5271     TVariable* variable = new TVariable(&identifier, type);
5272
5273     ioArrayCheck(loc, type, identifier);
5274
5275     // add variable to symbol table
5276     if (symbolTable.insert(*variable)) {
5277         if (symbolTable.atGlobalLevel())
5278             trackLinkage(*variable);
5279         return variable;
5280     }
5281
5282     error(loc, "redefinition", variable->getName().c_str(), "");
5283     return nullptr;
5284 }
5285
5286 //
5287 // Handle all types of initializers from the grammar.
5288 //
5289 // Returning nullptr just means there is no code to execute to handle the
5290 // initializer, which will, for example, be the case for constant initializers.
5291 //
5292 TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyped* initializer, TVariable* variable)
5293 {
5294     //
5295     // Identifier must be of type constant, a global, or a temporary, and
5296     // starting at version 120, desktop allows uniforms to have initializers.
5297     //
5298     TStorageQualifier qualifier = variable->getType().getQualifier().storage;
5299     if (! (qualifier == EvqTemporary || qualifier == EvqGlobal || qualifier == EvqConst ||
5300            (qualifier == EvqUniform && profile != EEsProfile && version >= 120))) {
5301         error(loc, " cannot initialize this type of qualifier ", variable->getType().getStorageQualifierString(), "");
5302         return nullptr;
5303     }
5304     arrayObjectCheck(loc, variable->getType(), "array initializer");
5305
5306     //
5307     // If the initializer was from braces { ... }, we convert the whole subtree to a
5308     // constructor-style subtree, allowing the rest of the code to operate
5309     // identically for both kinds of initializers.
5310     //
5311     // Type can't be deduced from the initializer list, so a skeletal type to
5312     // follow has to be passed in.  Constness and specialization-constness
5313     // should be deduced bottom up, not dictated by the skeletal type.
5314     //
5315     TType skeletalType;
5316     skeletalType.shallowCopy(variable->getType());
5317     skeletalType.getQualifier().makeTemporary();
5318     initializer = convertInitializerList(loc, skeletalType, initializer);
5319     if (! initializer) {
5320         // error recovery; don't leave const without constant values
5321         if (qualifier == EvqConst)
5322             variable->getWritableType().getQualifier().makeTemporary();
5323         return nullptr;
5324     }
5325
5326     // Fix outer arrayness if variable is unsized, getting size from the initializer
5327     if (initializer->getType().isExplicitlySizedArray() &&
5328         variable->getType().isImplicitlySizedArray())
5329         variable->getWritableType().changeOuterArraySize(initializer->getType().getOuterArraySize());
5330
5331     // Inner arrayness can also get set by an initializer
5332     if (initializer->getType().isArrayOfArrays() && variable->getType().isArrayOfArrays() &&
5333         initializer->getType().getArraySizes()->getNumDims() ==
5334            variable->getType().getArraySizes()->getNumDims()) {
5335         // adopt unsized sizes from the initializer's sizes
5336         for (int d = 1; d < variable->getType().getArraySizes()->getNumDims(); ++d) {
5337             if (variable->getType().getArraySizes()->getDimSize(d) == UnsizedArraySize)
5338                 variable->getWritableType().getArraySizes().setDimSize(d, initializer->getType().getArraySizes()->getDimSize(d));
5339         }
5340     }
5341
5342     // Uniforms require a compile-time constant initializer
5343     if (qualifier == EvqUniform && ! initializer->getType().getQualifier().isFrontEndConstant()) {
5344         error(loc, "uniform initializers must be constant", "=", "'%s'", variable->getType().getCompleteString().c_str());
5345         variable->getWritableType().getQualifier().makeTemporary();
5346         return nullptr;
5347     }
5348     // Global consts require a constant initializer (specialization constant is okay)
5349     if (qualifier == EvqConst && symbolTable.atGlobalLevel() && ! initializer->getType().getQualifier().isConstant()) {
5350         error(loc, "global const initializers must be constant", "=", "'%s'", variable->getType().getCompleteString().c_str());
5351         variable->getWritableType().getQualifier().makeTemporary();
5352         return nullptr;
5353     }
5354
5355     // Const variables require a constant initializer, depending on version
5356     if (qualifier == EvqConst) {
5357         if (! initializer->getType().getQualifier().isConstant()) {
5358             const char* initFeature = "non-constant initializer";
5359             requireProfile(loc, ~EEsProfile, initFeature);
5360             profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature);
5361             variable->getWritableType().getQualifier().storage = EvqConstReadOnly;
5362             qualifier = EvqConstReadOnly;
5363         }
5364     } else {
5365         // Non-const global variables in ES need a const initializer.
5366         //
5367         // "In declarations of global variables with no storage qualifier or with a const
5368         // qualifier any initializer must be a constant expression."
5369         if (symbolTable.atGlobalLevel() && ! initializer->getType().getQualifier().isConstant()) {
5370             const char* initFeature = "non-constant global initializer (needs GL_EXT_shader_non_constant_global_initializers)";
5371             if (profile == EEsProfile) {
5372                 if (relaxedErrors() && ! extensionTurnedOn(E_GL_EXT_shader_non_constant_global_initializers))
5373                     warn(loc, "not allowed in this version", initFeature, "");
5374                 else
5375                     profileRequires(loc, EEsProfile, 0, E_GL_EXT_shader_non_constant_global_initializers, initFeature);
5376             }
5377         }
5378     }
5379
5380     if (qualifier == EvqConst || qualifier == EvqUniform) {
5381         // Compile-time tagging of the variable with its constant value...
5382
5383         initializer = intermediate.addConversion(EOpAssign, variable->getType(), initializer);
5384         if (! initializer || ! initializer->getType().getQualifier().isConstant() || variable->getType() != initializer->getType()) {
5385             error(loc, "non-matching or non-convertible constant type for const initializer",
5386                   variable->getType().getStorageQualifierString(), "");
5387             variable->getWritableType().getQualifier().makeTemporary();
5388             return nullptr;
5389         }
5390
5391         // We either have a folded constant in getAsConstantUnion, or we have to use
5392         // the initializer's subtree in the AST to represent the computation of a
5393         // specialization constant.
5394         assert(initializer->getAsConstantUnion() || initializer->getType().getQualifier().isSpecConstant());
5395         if (initializer->getAsConstantUnion())
5396             variable->setConstArray(initializer->getAsConstantUnion()->getConstArray());
5397         else {
5398             // It's a specialization constant.
5399             variable->getWritableType().getQualifier().makeSpecConstant();
5400
5401             // Keep the subtree that computes the specialization constant with the variable.
5402             // Later, a symbol node will adopt the subtree from the variable.
5403             variable->setConstSubtree(initializer);
5404         }
5405     } else {
5406         // normal assigning of a value to a variable...
5407         specializationCheck(loc, initializer->getType(), "initializer");
5408         TIntermSymbol* intermSymbol = intermediate.addSymbol(*variable, loc);
5409         TIntermTyped* initNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, loc);
5410         if (! initNode)
5411             assignError(loc, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
5412
5413         return initNode;
5414     }
5415
5416     return nullptr;
5417 }
5418
5419 //
5420 // Reprocess any initializer-list (the  "{ ... }" syntax) parts of the
5421 // initializer.
5422 //
5423 // Need to hierarchically assign correct types and implicit
5424 // conversions. Will do this mimicking the same process used for
5425 // creating a constructor-style initializer, ensuring we get the
5426 // same form.  However, it has to in parallel walk the 'type'
5427 // passed in, as type cannot be deduced from an initializer list.
5428 //
5429 TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const TType& type, TIntermTyped* initializer)
5430 {
5431     // Will operate recursively.  Once a subtree is found that is constructor style,
5432     // everything below it is already good: Only the "top part" of the initializer
5433     // can be an initializer list, where "top part" can extend for several (or all) levels.
5434
5435     // see if we have bottomed out in the tree within the initializer-list part
5436     TIntermAggregate* initList = initializer->getAsAggregate();
5437     if (! initList || initList->getOp() != EOpNull)
5438         return initializer;
5439
5440     // Of the initializer-list set of nodes, need to process bottom up,
5441     // so recurse deep, then process on the way up.
5442
5443     // Go down the tree here...
5444     if (type.isArray()) {
5445         // The type's array might be unsized, which could be okay, so base sizes on the size of the aggregate.
5446         // Later on, initializer execution code will deal with array size logic.
5447         TType arrayType;
5448         arrayType.shallowCopy(type);                     // sharing struct stuff is fine
5449         arrayType.newArraySizes(*type.getArraySizes());  // but get a fresh copy of the array information, to edit below
5450
5451         // edit array sizes to fill in unsized dimensions
5452         arrayType.changeOuterArraySize((int)initList->getSequence().size());
5453         TIntermTyped* firstInit = initList->getSequence()[0]->getAsTyped();
5454         if (arrayType.isArrayOfArrays() && firstInit->getType().isArray() &&
5455             arrayType.getArraySizes().getNumDims() == firstInit->getType().getArraySizes()->getNumDims() + 1) {
5456             for (int d = 1; d < arrayType.getArraySizes().getNumDims(); ++d) {
5457                 if (arrayType.getArraySizes().getDimSize(d) == UnsizedArraySize)
5458                     arrayType.getArraySizes().setDimSize(d, firstInit->getType().getArraySizes()->getDimSize(d - 1));
5459             }
5460         }
5461
5462         TType elementType(arrayType, 0); // dereferenced type
5463         for (size_t i = 0; i < initList->getSequence().size(); ++i) {
5464             initList->getSequence()[i] = convertInitializerList(loc, elementType, initList->getSequence()[i]->getAsTyped());
5465             if (initList->getSequence()[i] == nullptr)
5466                 return nullptr;
5467         }
5468
5469         return addConstructor(loc, initList, arrayType);
5470     } else if (type.isStruct()) {
5471         if (type.getStruct()->size() != initList->getSequence().size()) {
5472             error(loc, "wrong number of structure members", "initializer list", "");
5473             return nullptr;
5474         }
5475         for (size_t i = 0; i < type.getStruct()->size(); ++i) {
5476             initList->getSequence()[i] = convertInitializerList(loc, *(*type.getStruct())[i].type, initList->getSequence()[i]->getAsTyped());
5477             if (initList->getSequence()[i] == nullptr)
5478                 return nullptr;
5479         }
5480     } else if (type.isMatrix()) {
5481         if (type.getMatrixCols() != (int)initList->getSequence().size()) {
5482             error(loc, "wrong number of matrix columns:", "initializer list", type.getCompleteString().c_str());
5483             return nullptr;
5484         }
5485         TType vectorType(type, 0); // dereferenced type
5486         for (int i = 0; i < type.getMatrixCols(); ++i) {
5487             initList->getSequence()[i] = convertInitializerList(loc, vectorType, initList->getSequence()[i]->getAsTyped());
5488             if (initList->getSequence()[i] == nullptr)
5489                 return nullptr;
5490         }
5491     } else if (type.isVector()) {
5492         if (type.getVectorSize() != (int)initList->getSequence().size()) {
5493             error(loc, "wrong vector size (or rows in a matrix column):", "initializer list", type.getCompleteString().c_str());
5494             return nullptr;
5495         }
5496     } else {
5497         error(loc, "unexpected initializer-list type:", "initializer list", type.getCompleteString().c_str());
5498         return nullptr;
5499     }
5500
5501     // Now that the subtree is processed, process this node as if the
5502     // initializer list is a set of arguments to a constructor.
5503     TIntermNode* emulatedConstructorArguments;
5504     if (initList->getSequence().size() == 1)
5505         emulatedConstructorArguments = initList->getSequence()[0];
5506     else
5507         emulatedConstructorArguments = initList;
5508     return addConstructor(loc, emulatedConstructorArguments, type);
5509 }
5510
5511 //
5512 // Test for the correctness of the parameters passed to various constructor functions
5513 // and also convert them to the right data type, if allowed and required.
5514 //
5515 // 'node' is what to construct from.
5516 // 'type' is what type to construct.
5517 //
5518 // Returns nullptr for an error or the constructed node (aggregate or typed) for no error.
5519 //
5520 TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* node, const TType& type)
5521 {
5522     if (node == nullptr || node->getAsTyped() == nullptr)
5523         return nullptr;
5524     rValueErrorCheck(loc, "constructor", node->getAsTyped());
5525
5526     TIntermAggregate* aggrNode = node->getAsAggregate();
5527     TOperator op = intermediate.mapTypeToConstructorOp(type);
5528
5529     // Combined texture-sampler constructors are completely semantic checked
5530     // in constructorTextureSamplerError()
5531     if (op == EOpConstructTextureSampler)
5532         return intermediate.setAggregateOperator(aggrNode, op, type, loc);
5533
5534     TTypeList::const_iterator memberTypes;
5535     if (op == EOpConstructStruct)
5536         memberTypes = type.getStruct()->begin();
5537
5538     TType elementType;
5539     if (type.isArray()) {
5540         TType dereferenced(type, 0);
5541         elementType.shallowCopy(dereferenced);
5542     } else
5543         elementType.shallowCopy(type);
5544
5545     bool singleArg;
5546     if (aggrNode) {
5547         if (aggrNode->getOp() != EOpNull)
5548             singleArg = true;
5549         else
5550             singleArg = false;
5551     } else
5552         singleArg = true;
5553
5554     TIntermTyped *newNode;
5555     if (singleArg) {
5556         // If structure constructor or array constructor is being called
5557         // for only one parameter inside the structure, we need to call constructAggregate function once.
5558         if (type.isArray())
5559             newNode = constructAggregate(node, elementType, 1, node->getLoc());
5560         else if (op == EOpConstructStruct)
5561             newNode = constructAggregate(node, *(*memberTypes).type, 1, node->getLoc());
5562         else
5563             newNode = constructBuiltIn(type, op, node->getAsTyped(), node->getLoc(), false);
5564
5565         if (newNode && (type.isArray() || op == EOpConstructStruct))
5566             newNode = intermediate.setAggregateOperator(newNode, EOpConstructStruct, type, loc);
5567
5568         return newNode;
5569     }
5570
5571     //
5572     // Handle list of arguments.
5573     //
5574     TIntermSequence &sequenceVector = aggrNode->getSequence();    // Stores the information about the parameter to the constructor
5575     // if the structure constructor contains more than one parameter, then construct
5576     // each parameter
5577
5578     int paramCount = 0;  // keeps track of the constructor parameter number being checked
5579
5580     // for each parameter to the constructor call, check to see if the right type is passed or convert them
5581     // to the right type if possible (and allowed).
5582     // for structure constructors, just check if the right type is passed, no conversion is allowed.
5583     for (TIntermSequence::iterator p = sequenceVector.begin();
5584                                    p != sequenceVector.end(); p++, paramCount++) {
5585         if (type.isArray())
5586             newNode = constructAggregate(*p, elementType, paramCount+1, node->getLoc());
5587         else if (op == EOpConstructStruct)
5588             newNode = constructAggregate(*p, *(memberTypes[paramCount]).type, paramCount+1, node->getLoc());
5589         else
5590             newNode = constructBuiltIn(type, op, (*p)->getAsTyped(), node->getLoc(), true);
5591
5592         if (newNode)
5593             *p = newNode;
5594         else
5595             return nullptr;
5596     }
5597
5598     return intermediate.setAggregateOperator(aggrNode, op, type, loc);
5599 }
5600
5601 // Function for constructor implementation. Calls addUnaryMath with appropriate EOp value
5602 // for the parameter to the constructor (passed to this function). Essentially, it converts
5603 // the parameter types correctly. If a constructor expects an int (like ivec2) and is passed a
5604 // float, then float is converted to int.
5605 //
5606 // Returns nullptr for an error or the constructed node.
5607 //
5608 TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermTyped* node, const TSourceLoc& loc, bool subset)
5609 {
5610     TIntermTyped* newNode;
5611     TOperator basicOp;
5612
5613     //
5614     // First, convert types as needed.
5615     //
5616     switch (op) {
5617     case EOpConstructVec2:
5618     case EOpConstructVec3:
5619     case EOpConstructVec4:
5620     case EOpConstructMat2x2:
5621     case EOpConstructMat2x3:
5622     case EOpConstructMat2x4:
5623     case EOpConstructMat3x2:
5624     case EOpConstructMat3x3:
5625     case EOpConstructMat3x4:
5626     case EOpConstructMat4x2:
5627     case EOpConstructMat4x3:
5628     case EOpConstructMat4x4:
5629     case EOpConstructFloat:
5630         basicOp = EOpConstructFloat;
5631         break;
5632
5633     case EOpConstructDVec2:
5634     case EOpConstructDVec3:
5635     case EOpConstructDVec4:
5636     case EOpConstructDMat2x2:
5637     case EOpConstructDMat2x3:
5638     case EOpConstructDMat2x4:
5639     case EOpConstructDMat3x2:
5640     case EOpConstructDMat3x3:
5641     case EOpConstructDMat3x4:
5642     case EOpConstructDMat4x2:
5643     case EOpConstructDMat4x3:
5644     case EOpConstructDMat4x4:
5645     case EOpConstructDouble:
5646         basicOp = EOpConstructDouble;
5647         break;
5648
5649 #ifdef AMD_EXTENSIONS
5650     case EOpConstructF16Vec2:
5651     case EOpConstructF16Vec3:
5652     case EOpConstructF16Vec4:
5653     case EOpConstructF16Mat2x2:
5654     case EOpConstructF16Mat2x3:
5655     case EOpConstructF16Mat2x4:
5656     case EOpConstructF16Mat3x2:
5657     case EOpConstructF16Mat3x3:
5658     case EOpConstructF16Mat3x4:
5659     case EOpConstructF16Mat4x2:
5660     case EOpConstructF16Mat4x3:
5661     case EOpConstructF16Mat4x4:
5662     case EOpConstructFloat16:
5663         basicOp = EOpConstructFloat16;
5664         break;
5665 #endif
5666
5667     case EOpConstructIVec2:
5668     case EOpConstructIVec3:
5669     case EOpConstructIVec4:
5670     case EOpConstructInt:
5671         basicOp = EOpConstructInt;
5672         break;
5673
5674     case EOpConstructUVec2:
5675     case EOpConstructUVec3:
5676     case EOpConstructUVec4:
5677     case EOpConstructUint:
5678         basicOp = EOpConstructUint;
5679         break;
5680
5681     case EOpConstructI64Vec2:
5682     case EOpConstructI64Vec3:
5683     case EOpConstructI64Vec4:
5684     case EOpConstructInt64:
5685         basicOp = EOpConstructInt64;
5686         break;
5687
5688     case EOpConstructU64Vec2:
5689     case EOpConstructU64Vec3:
5690     case EOpConstructU64Vec4:
5691     case EOpConstructUint64:
5692         basicOp = EOpConstructUint64;
5693         break;
5694
5695 #ifdef AMD_EXTENSIONS
5696     case EOpConstructI16Vec2:
5697     case EOpConstructI16Vec3:
5698     case EOpConstructI16Vec4:
5699     case EOpConstructInt16:
5700         basicOp = EOpConstructInt16;
5701         break;
5702
5703     case EOpConstructU16Vec2:
5704     case EOpConstructU16Vec3:
5705     case EOpConstructU16Vec4:
5706     case EOpConstructUint16:
5707         basicOp = EOpConstructUint16;
5708         break;
5709 #endif
5710
5711     case EOpConstructBVec2:
5712     case EOpConstructBVec3:
5713     case EOpConstructBVec4:
5714     case EOpConstructBool:
5715         basicOp = EOpConstructBool;
5716         break;
5717
5718     default:
5719         error(loc, "unsupported construction", "", "");
5720
5721         return nullptr;
5722     }
5723     newNode = intermediate.addUnaryMath(basicOp, node, node->getLoc());
5724     if (newNode == nullptr) {
5725         error(loc, "can't convert", "constructor", "");
5726         return nullptr;
5727     }
5728
5729     //
5730     // Now, if there still isn't an operation to do the construction, and we need one, add one.
5731     //
5732
5733     // Otherwise, skip out early.
5734     if (subset || (newNode != node && newNode->getType() == type))
5735         return newNode;
5736
5737     // setAggregateOperator will insert a new node for the constructor, as needed.
5738     return intermediate.setAggregateOperator(newNode, op, type, loc);
5739 }
5740
5741 // This function tests for the type of the parameters to the structure or array constructor. Raises
5742 // an error message if the expected type does not match the parameter passed to the constructor.
5743 //
5744 // Returns nullptr for an error or the input node itself if the expected and the given parameter types match.
5745 //
5746 TIntermTyped* TParseContext::constructAggregate(TIntermNode* node, const TType& type, int paramCount, const TSourceLoc& loc)
5747 {
5748     TIntermTyped* converted = intermediate.addConversion(EOpConstructStruct, type, node->getAsTyped());
5749     if (! converted || converted->getType() != type) {
5750         error(loc, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount,
5751               node->getAsTyped()->getType().getCompleteString().c_str(), type.getCompleteString().c_str());
5752
5753         return nullptr;
5754     }
5755
5756     return converted;
5757 }
5758
5759 //
5760 // Do everything needed to add an interface block.
5761 //
5762 void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, const TString* instanceName, TArraySizes* arraySizes)
5763 {
5764     blockStageIoCheck(loc, currentBlockQualifier);
5765     blockQualifierCheck(loc, currentBlockQualifier, instanceName != nullptr);
5766     if (arraySizes) {
5767         arraySizesCheck(loc, currentBlockQualifier, arraySizes, false, false);
5768         arrayDimCheck(loc, arraySizes, 0);
5769         if (arraySizes->getNumDims() > 1)
5770             requireProfile(loc, ~EEsProfile, "array-of-array of block");
5771     }
5772
5773     // fix and check for member storage qualifiers and types that don't belong within a block
5774     for (unsigned int member = 0; member < typeList.size(); ++member) {
5775         TType& memberType = *typeList[member].type;
5776         TQualifier& memberQualifier = memberType.getQualifier();
5777         const TSourceLoc& memberLoc = typeList[member].loc;
5778         globalQualifierFixCheck(memberLoc, memberQualifier);
5779         if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal && memberQualifier.storage != currentBlockQualifier.storage)
5780             error(memberLoc, "member storage qualifier cannot contradict block storage qualifier", memberType.getFieldName().c_str(), "");
5781         memberQualifier.storage = currentBlockQualifier.storage;
5782         if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary()))
5783             error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), "");
5784         if (memberType.isArray())
5785             arraySizesCheck(memberLoc, currentBlockQualifier, &memberType.getArraySizes(), false, member == typeList.size() - 1);
5786         if (memberQualifier.hasOffset()) {
5787             if (spvVersion.spv == 0) {
5788                 requireProfile(memberLoc, ~EEsProfile, "offset on block member");
5789                 profileRequires(memberLoc, ~EEsProfile, 440, E_GL_ARB_enhanced_layouts, "offset on block member");
5790             }
5791         }
5792
5793         if (memberType.containsOpaque())
5794             error(memberLoc, "member of block cannot be or contain a sampler, image, or atomic_uint type", typeList[member].type->getFieldName().c_str(), "");
5795     }
5796
5797     // This might be a redeclaration of a built-in block.  If so, redeclareBuiltinBlock() will
5798     // do all the rest.
5799     if (! symbolTable.atBuiltInLevel() && builtInName(*blockName)) {
5800         redeclareBuiltinBlock(loc, typeList, *blockName, instanceName, arraySizes);
5801         return;
5802     }
5803
5804     // Not a redeclaration of a built-in; check that all names are user names.
5805     reservedErrorCheck(loc, *blockName);
5806     if (instanceName)
5807         reservedErrorCheck(loc, *instanceName);
5808     for (unsigned int member = 0; member < typeList.size(); ++member)
5809         reservedErrorCheck(typeList[member].loc, typeList[member].type->getFieldName());
5810
5811     // Make default block qualification, and adjust the member qualifications
5812
5813     TQualifier defaultQualification;
5814     switch (currentBlockQualifier.storage) {
5815     case EvqUniform:    defaultQualification = globalUniformDefaults;    break;
5816     case EvqBuffer:     defaultQualification = globalBufferDefaults;     break;
5817     case EvqVaryingIn:  defaultQualification = globalInputDefaults;      break;
5818     case EvqVaryingOut: defaultQualification = globalOutputDefaults;     break;
5819     default:            defaultQualification.clear();                    break;
5820     }
5821
5822     // Special case for "push_constant uniform", which has a default of std430,
5823     // contrary to normal uniform defaults, and can't have a default tracked for it.
5824     if (currentBlockQualifier.layoutPushConstant && !currentBlockQualifier.hasPacking())
5825         currentBlockQualifier.layoutPacking = ElpStd430;
5826
5827     // fix and check for member layout qualifiers
5828
5829     mergeObjectLayoutQualifiers(defaultQualification, currentBlockQualifier, true);
5830
5831     // "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
5832     if (currentBlockQualifier.hasAlign()) {
5833         if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430) {
5834             error(loc, "can only be used with std140 or std430 layout packing", "align", "");
5835             defaultQualification.layoutAlign = -1;
5836         }
5837     }
5838
5839     bool memberWithLocation = false;
5840     bool memberWithoutLocation = false;
5841     for (unsigned int member = 0; member < typeList.size(); ++member) {
5842         TQualifier& memberQualifier = typeList[member].type->getQualifier();
5843         const TSourceLoc& memberLoc = typeList[member].loc;
5844         if (memberQualifier.hasStream()) {
5845             if (defaultQualification.layoutStream != memberQualifier.layoutStream)
5846                 error(memberLoc, "member cannot contradict block", "stream", "");
5847         }
5848
5849         // "This includes a block's inheritance of the
5850         // current global default buffer, a block member's inheritance of the block's
5851         // buffer, and the requirement that any *xfb_buffer* declared on a block
5852         // member must match the buffer inherited from the block."
5853         if (memberQualifier.hasXfbBuffer()) {
5854             if (defaultQualification.layoutXfbBuffer != memberQualifier.layoutXfbBuffer)
5855                 error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_buffer", "");
5856         }
5857
5858         if (memberQualifier.hasPacking())
5859             error(memberLoc, "member of block cannot have a packing layout qualifier", typeList[member].type->getFieldName().c_str(), "");
5860         if (memberQualifier.hasLocation()) {
5861             const char* feature = "location on block member";
5862             switch (currentBlockQualifier.storage) {
5863             case EvqVaryingIn:
5864             case EvqVaryingOut:
5865                 requireProfile(memberLoc, ECoreProfile | ECompatibilityProfile | EEsProfile, feature);
5866                 profileRequires(memberLoc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, feature);
5867                 profileRequires(memberLoc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature);
5868                 memberWithLocation = true;
5869                 break;
5870             default:
5871                 error(memberLoc, "can only use in an in/out block", feature, "");
5872                 break;
5873             }
5874         } else
5875             memberWithoutLocation = true;
5876
5877         // "The offset qualifier can only be used on block members of blocks declared with std140 or std430 layouts."
5878         // "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
5879         if (memberQualifier.hasAlign() || memberQualifier.hasOffset()) {
5880             if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430)
5881                 error(memberLoc, "can only be used with std140 or std430 layout packing", "offset/align", "");
5882         }
5883
5884         TQualifier newMemberQualification = defaultQualification;
5885         mergeQualifiers(memberLoc, newMemberQualification, memberQualifier, false);
5886         memberQualifier = newMemberQualification;
5887     }
5888
5889     layoutMemberLocationArrayCheck(loc, memberWithLocation, arraySizes);
5890
5891     // Process the members
5892     fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation);
5893     fixBlockXfbOffsets(currentBlockQualifier, typeList);
5894     fixBlockUniformOffsets(currentBlockQualifier, typeList);
5895     for (unsigned int member = 0; member < typeList.size(); ++member)
5896         layoutTypeCheck(typeList[member].loc, *typeList[member].type);
5897
5898     // reverse merge, so that currentBlockQualifier now has all layout information
5899     // (can't use defaultQualification directly, it's missing other non-layout-default-class qualifiers)
5900     mergeObjectLayoutQualifiers(currentBlockQualifier, defaultQualification, true);
5901
5902     //
5903     // Build and add the interface block as a new type named 'blockName'
5904     //
5905
5906     TType blockType(&typeList, *blockName, currentBlockQualifier);
5907     if (arraySizes)
5908         blockType.newArraySizes(*arraySizes);
5909     else
5910         ioArrayCheck(loc, blockType, instanceName ? *instanceName : *blockName);
5911
5912     //
5913     // Don't make a user-defined type out of block name; that will cause an error
5914     // if the same block name gets reused in a different interface.
5915     //
5916     // "Block names have no other use within a shader
5917     // beyond interface matching; it is a compile-time error to use a block name at global scope for anything
5918     // other than as a block name (e.g., use of a block name for a global variable name or function name is
5919     // currently reserved)."
5920     //
5921     // Use the symbol table to prevent normal reuse of the block's name, as a variable entry,
5922     // whose type is EbtBlock, but without all the structure; that will come from the type
5923     // the instances point to.
5924     //
5925     TType blockNameType(EbtBlock, blockType.getQualifier().storage);
5926     TVariable* blockNameVar = new TVariable(blockName, blockNameType);
5927     if (! symbolTable.insert(*blockNameVar)) {
5928         TSymbol* existingName = symbolTable.find(*blockName);
5929         if (existingName->getType().getBasicType() == EbtBlock) {
5930             if (existingName->getType().getQualifier().storage == blockType.getQualifier().storage) {
5931                 error(loc, "Cannot reuse block name within the same interface:", blockName->c_str(), blockType.getStorageQualifierString());
5932                 return;
5933             }
5934         } else {
5935             error(loc, "block name cannot redefine a non-block name", blockName->c_str(), "");
5936             return;
5937         }
5938     }
5939
5940     // Add the variable, as anonymous or named instanceName.
5941     // Make an anonymous variable if no name was provided.
5942     if (! instanceName)
5943         instanceName = NewPoolTString("");
5944
5945     TVariable& variable = *new TVariable(instanceName, blockType);
5946     if (! symbolTable.insert(variable)) {
5947         if (*instanceName == "")
5948             error(loc, "nameless block contains a member that already has a name at global scope", blockName->c_str(), "");
5949         else
5950             error(loc, "block instance name redefinition", variable.getName().c_str(), "");
5951
5952         return;
5953     }
5954
5955     // Check for general layout qualifier errors
5956     layoutObjectCheck(loc, variable);
5957
5958     // fix up
5959     if (isIoResizeArray(blockType)) {
5960         ioArraySymbolResizeList.push_back(&variable);
5961         checkIoArraysConsistency(loc, true);
5962     } else
5963         fixIoArraySize(loc, variable.getWritableType());
5964
5965     // Save it in the AST for linker use.
5966     trackLinkage(variable);
5967 }
5968
5969 // Do all block-declaration checking regarding the combination of in/out/uniform/buffer
5970 // with a particular stage.
5971 void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& qualifier)
5972 {
5973     switch (qualifier.storage) {
5974     case EvqUniform:
5975         profileRequires(loc, EEsProfile, 300, nullptr, "uniform block");
5976         profileRequires(loc, ENoProfile, 140, nullptr, "uniform block");
5977         if (currentBlockQualifier.layoutPacking == ElpStd430 && ! currentBlockQualifier.layoutPushConstant)
5978             error(loc, "requires the 'buffer' storage qualifier", "std430", "");
5979         break;
5980     case EvqBuffer:
5981         requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "buffer block");
5982         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, "buffer block");
5983         profileRequires(loc, EEsProfile, 310, nullptr, "buffer block");
5984         break;
5985     case EvqVaryingIn:
5986         profileRequires(loc, ~EEsProfile, 150, E_GL_ARB_separate_shader_objects, "input block");
5987         // It is a compile-time error to have an input block in a vertex shader or an output block in a fragment shader
5988         // "Compute shaders do not permit user-defined input variables..."
5989         requireStage(loc, (EShLanguageMask)(EShLangTessControlMask|EShLangTessEvaluationMask|EShLangGeometryMask|EShLangFragmentMask), "input block");
5990         if (language == EShLangFragment)
5991             profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "fragment input block");
5992         break;
5993     case EvqVaryingOut:
5994         profileRequires(loc, ~EEsProfile, 150, E_GL_ARB_separate_shader_objects, "output block");
5995         requireStage(loc, (EShLanguageMask)(EShLangVertexMask|EShLangTessControlMask|EShLangTessEvaluationMask|EShLangGeometryMask), "output block");
5996         // ES 310 can have a block before shader_io is turned on, so skip this test for built-ins
5997         if (language == EShLangVertex && ! parsingBuiltins)
5998             profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "vertex output block");
5999         break;
6000     default:
6001         error(loc, "only uniform, buffer, in, or out blocks are supported", blockName->c_str(), "");
6002         break;
6003     }
6004 }
6005
6006 // Do all block-declaration checking regarding its qualifiers.
6007 void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier& qualifier, bool /*instanceName*/)
6008 {
6009     // The 4.5 specification says:
6010     //
6011     // interface-block :
6012     //    layout-qualifieropt interface-qualifier  block-name { member-list } instance-nameopt ;
6013     //
6014     // interface-qualifier :
6015     //    in
6016     //    out
6017     //    patch in
6018     //    patch out
6019     //    uniform
6020     //    buffer
6021     //
6022     // Note however memory qualifiers aren't included, yet the specification also says
6023     //
6024     // "...memory qualifiers may also be used in the declaration of shader storage blocks..."
6025
6026     if (qualifier.isInterpolation())
6027         error(loc, "cannot use interpolation qualifiers on an interface block", "flat/smooth/noperspective", "");
6028     if (qualifier.centroid)
6029         error(loc, "cannot use centroid qualifier on an interface block", "centroid", "");
6030     if (qualifier.sample)
6031         error(loc, "cannot use sample qualifier on an interface block", "sample", "");
6032     if (qualifier.invariant)
6033         error(loc, "cannot use invariant qualifier on an interface block", "invariant", "");
6034     if (qualifier.layoutPushConstant)
6035         intermediate.addPushConstantCount();
6036 }
6037
6038 //
6039 // "For a block, this process applies to the entire block, or until the first member
6040 // is reached that has a location layout qualifier. When a block member is declared with a location
6041 // qualifier, its location comes from that qualifier: The member's location qualifier overrides the block-level
6042 // declaration. Subsequent members are again assigned consecutive locations, based on the newest location,
6043 // until the next member declared with a location qualifier. The values used for locations do not have to be
6044 // declared in increasing order."
6045 void TParseContext::fixBlockLocations(const TSourceLoc& loc, TQualifier& qualifier, TTypeList& typeList, bool memberWithLocation, bool memberWithoutLocation)
6046 {
6047     // "If a block has no block-level location layout qualifier, it is required that either all or none of its members
6048     // have a location layout qualifier, or a compile-time error results."
6049     if (! qualifier.hasLocation() && memberWithLocation && memberWithoutLocation)
6050         error(loc, "either the block needs a location, or all members need a location, or no members have a location", "location", "");
6051     else {
6052         if (memberWithLocation) {
6053             // remove any block-level location and make it per *every* member
6054             int nextLocation = 0;  // by the rule above, initial value is not relevant
6055             if (qualifier.hasAnyLocation()) {
6056                 nextLocation = qualifier.layoutLocation;
6057                 qualifier.layoutLocation = TQualifier::layoutLocationEnd;
6058                 if (qualifier.hasComponent()) {
6059                     // "It is a compile-time error to apply the *component* qualifier to a ... block"
6060                     error(loc, "cannot apply to a block", "component", "");
6061                 }
6062                 if (qualifier.hasIndex()) {
6063                     error(loc, "cannot apply to a block", "index", "");
6064                 }
6065             }
6066             for (unsigned int member = 0; member < typeList.size(); ++member) {
6067                 TQualifier& memberQualifier = typeList[member].type->getQualifier();
6068                 const TSourceLoc& memberLoc = typeList[member].loc;
6069                 if (! memberQualifier.hasLocation()) {
6070                     if (nextLocation >= (int)TQualifier::layoutLocationEnd)
6071                         error(memberLoc, "location is too large", "location", "");
6072                     memberQualifier.layoutLocation = nextLocation;
6073                     memberQualifier.layoutComponent = TQualifier::layoutComponentEnd;
6074                 }
6075                 nextLocation = memberQualifier.layoutLocation + intermediate.computeTypeLocationSize(*typeList[member].type);
6076             }
6077         }
6078     }
6079 }
6080
6081 void TParseContext::fixBlockXfbOffsets(TQualifier& qualifier, TTypeList& typeList)
6082 {
6083     // "If a block is qualified with xfb_offset, all its
6084     // members are assigned transform feedback buffer offsets. If a block is not qualified with xfb_offset, any
6085     // members of that block not qualified with an xfb_offset will not be assigned transform feedback buffer
6086     // offsets."
6087
6088     if (! qualifier.hasXfbBuffer() || ! qualifier.hasXfbOffset())
6089         return;
6090
6091     int nextOffset = qualifier.layoutXfbOffset;
6092     for (unsigned int member = 0; member < typeList.size(); ++member) {
6093         TQualifier& memberQualifier = typeList[member].type->getQualifier();
6094         bool containsDouble = false;
6095         int memberSize = intermediate.computeTypeXfbSize(*typeList[member].type, containsDouble);
6096         // see if we need to auto-assign an offset to this member
6097         if (! memberQualifier.hasXfbOffset()) {
6098             // "if applied to an aggregate containing a double, the offset must also be a multiple of 8"
6099             if (containsDouble)
6100                 RoundToPow2(nextOffset, 8);
6101             memberQualifier.layoutXfbOffset = nextOffset;
6102         } else
6103             nextOffset = memberQualifier.layoutXfbOffset;
6104         nextOffset += memberSize;
6105     }
6106
6107     // The above gave all block members an offset, so we can take it off the block now,
6108     // which will avoid double counting the offset usage.
6109     qualifier.layoutXfbOffset = TQualifier::layoutXfbOffsetEnd;
6110 }
6111
6112 // Calculate and save the offset of each block member, using the recursively
6113 // defined block offset rules and the user-provided offset and align.
6114 //
6115 // Also, compute and save the total size of the block. For the block's size, arrayness
6116 // is not taken into account, as each element is backed by a separate buffer.
6117 //
6118 void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typeList)
6119 {
6120     if (! qualifier.isUniformOrBuffer())
6121         return;
6122     if (qualifier.layoutPacking != ElpStd140 && qualifier.layoutPacking != ElpStd430)
6123         return;
6124
6125     int offset = 0;
6126     int memberSize;
6127     for (unsigned int member = 0; member < typeList.size(); ++member) {
6128         TQualifier& memberQualifier = typeList[member].type->getQualifier();
6129         const TSourceLoc& memberLoc = typeList[member].loc;
6130
6131         // "When align is applied to an array, it effects only the start of the array, not the array's internal stride."
6132
6133         // modify just the children's view of matrix layout, if there is one for this member
6134         TLayoutMatrix subMatrixLayout = typeList[member].type->getQualifier().layoutMatrix;
6135         int dummyStride;
6136         int memberAlignment = intermediate.getBaseAlignment(*typeList[member].type, memberSize, dummyStride, qualifier.layoutPacking == ElpStd140,
6137                                                             subMatrixLayout != ElmNone ? subMatrixLayout == ElmRowMajor : qualifier.layoutMatrix == ElmRowMajor);
6138         if (memberQualifier.hasOffset()) {
6139             // "The specified offset must be a multiple
6140             // of the base alignment of the type of the block member it qualifies, or a compile-time error results."
6141             if (! IsMultipleOfPow2(memberQualifier.layoutOffset, memberAlignment))
6142                 error(memberLoc, "must be a multiple of the member's alignment", "offset", "");
6143
6144             // GLSL: "It is a compile-time error to specify an offset that is smaller than the offset of the previous
6145             // member in the block or that lies within the previous member of the block"
6146             if (spvVersion.spv == 0) {
6147                 if (memberQualifier.layoutOffset < offset)
6148                     error(memberLoc, "cannot lie in previous members", "offset", "");
6149
6150                 // "The offset qualifier forces the qualified member to start at or after the specified
6151                 // integral-constant expression, which will be its byte offset from the beginning of the buffer.
6152                 // "The actual offset of a member is computed as
6153                 // follows: If offset was declared, start with that offset, otherwise start with the next available offset."
6154                 offset = std::max(offset, memberQualifier.layoutOffset);
6155             } else {
6156                 // TODO: Vulkan: "It is a compile-time error to have any offset, explicit or assigned,
6157                 // that lies within another member of the block."
6158
6159                 offset = memberQualifier.layoutOffset;
6160             }
6161         }
6162
6163         // "The actual alignment of a member will be the greater of the specified align alignment and the standard
6164         // (e.g., std140) base alignment for the member's type."
6165         if (memberQualifier.hasAlign())
6166             memberAlignment = std::max(memberAlignment, memberQualifier.layoutAlign);
6167
6168         // "If the resulting offset is not a multiple of the actual alignment,
6169         // increase it to the first offset that is a multiple of
6170         // the actual alignment."
6171         RoundToPow2(offset, memberAlignment);
6172         typeList[member].type->getQualifier().layoutOffset = offset;
6173         offset += memberSize;
6174     }
6175 }
6176
6177 // For an identifier that is already declared, add more qualification to it.
6178 void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qualifier, const TString& identifier)
6179 {
6180     TSymbol* symbol = symbolTable.find(identifier);
6181     if (! symbol) {
6182         error(loc, "identifier not previously declared", identifier.c_str(), "");
6183         return;
6184     }
6185     if (symbol->getAsFunction()) {
6186         error(loc, "cannot re-qualify a function name", identifier.c_str(), "");
6187         return;
6188     }
6189
6190     if (qualifier.isAuxiliary() ||
6191         qualifier.isMemory() ||
6192         qualifier.isInterpolation() ||
6193         qualifier.hasLayout() ||
6194         qualifier.storage != EvqTemporary ||
6195         qualifier.precision != EpqNone) {
6196         error(loc, "cannot add storage, auxiliary, memory, interpolation, layout, or precision qualifier to an existing variable", identifier.c_str(), "");
6197         return;
6198     }
6199
6200     // For read-only built-ins, add a new symbol for holding the modified qualifier.
6201     // This will bring up an entire block, if a block type has to be modified (e.g., gl_Position inside a block)
6202     if (symbol->isReadOnly())
6203         symbol = symbolTable.copyUp(symbol);
6204
6205     if (qualifier.invariant) {
6206         if (intermediate.inIoAccessed(identifier))
6207             error(loc, "cannot change qualification after use", "invariant", "");
6208         symbol->getWritableType().getQualifier().invariant = true;
6209         invariantCheck(loc, symbol->getType().getQualifier());
6210     } else if (qualifier.noContraction) {
6211         if (intermediate.inIoAccessed(identifier))
6212             error(loc, "cannot change qualification after use", "precise", "");
6213         symbol->getWritableType().getQualifier().noContraction = true;
6214     } else if (qualifier.specConstant) {
6215         symbol->getWritableType().getQualifier().makeSpecConstant();
6216         if (qualifier.hasSpecConstantId())
6217             symbol->getWritableType().getQualifier().layoutSpecConstantId = qualifier.layoutSpecConstantId;
6218     } else
6219         warn(loc, "unknown requalification", "", "");
6220 }
6221
6222 void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qualifier, TIdentifierList& identifiers)
6223 {
6224     for (unsigned int i = 0; i < identifiers.size(); ++i)
6225         addQualifierToExisting(loc, qualifier, *identifiers[i]);
6226 }
6227
6228 // Make sure 'invariant' isn't being applied to a non-allowed object.
6229 void TParseContext::invariantCheck(const TSourceLoc& loc, const TQualifier& qualifier)
6230 {
6231     if (! qualifier.invariant)
6232         return;
6233
6234     bool pipeOut = qualifier.isPipeOutput();
6235     bool pipeIn = qualifier.isPipeInput();
6236     if (version >= 300 || (profile != EEsProfile && version >= 420)) {
6237         if (! pipeOut)
6238             error(loc, "can only apply to an output", "invariant", "");
6239     } else {
6240         if ((language == EShLangVertex && pipeIn) || (! pipeOut && ! pipeIn))
6241             error(loc, "can only apply to an output, or to an input in a non-vertex stage\n", "invariant", "");
6242     }
6243 }
6244
6245 //
6246 // Updating default qualifier for the case of a declaration with just a qualifier,
6247 // no type, block, or identifier.
6248 //
6249 void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, const TPublicType& publicType)
6250 {
6251     if (publicType.shaderQualifiers.vertices != TQualifier::layoutNotSet) {
6252         assert(language == EShLangTessControl || language == EShLangGeometry);
6253         const char* id = (language == EShLangTessControl) ? "vertices" : "max_vertices";
6254
6255         if (publicType.qualifier.storage != EvqVaryingOut)
6256             error(loc, "can only apply to 'out'", id, "");
6257         if (! intermediate.setVertices(publicType.shaderQualifiers.vertices))
6258             error(loc, "cannot change previously set layout value", id, "");
6259
6260         if (language == EShLangTessControl)
6261             checkIoArraysConsistency(loc);
6262     }
6263     if (publicType.shaderQualifiers.invocations != TQualifier::layoutNotSet) {
6264         if (publicType.qualifier.storage != EvqVaryingIn)
6265             error(loc, "can only apply to 'in'", "invocations", "");
6266         if (! intermediate.setInvocations(publicType.shaderQualifiers.invocations))
6267             error(loc, "cannot change previously set layout value", "invocations", "");
6268     }
6269     if (publicType.shaderQualifiers.geometry != ElgNone) {
6270         if (publicType.qualifier.storage == EvqVaryingIn) {
6271             switch (publicType.shaderQualifiers.geometry) {
6272             case ElgPoints:
6273             case ElgLines:
6274             case ElgLinesAdjacency:
6275             case ElgTriangles:
6276             case ElgTrianglesAdjacency:
6277             case ElgQuads:
6278             case ElgIsolines:
6279                 if (intermediate.setInputPrimitive(publicType.shaderQualifiers.geometry)) {
6280                     if (language == EShLangGeometry)
6281                         checkIoArraysConsistency(loc);
6282                 } else
6283                     error(loc, "cannot change previously set input primitive", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
6284                 break;
6285             default:
6286                 error(loc, "cannot apply to input", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
6287             }
6288         } else if (publicType.qualifier.storage == EvqVaryingOut) {
6289             switch (publicType.shaderQualifiers.geometry) {
6290             case ElgPoints:
6291             case ElgLineStrip:
6292             case ElgTriangleStrip:
6293                 if (! intermediate.setOutputPrimitive(publicType.shaderQualifiers.geometry))
6294                     error(loc, "cannot change previously set output primitive", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
6295                 break;
6296             default:
6297                 error(loc, "cannot apply to 'out'", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
6298             }
6299         } else
6300             error(loc, "cannot apply to:", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), GetStorageQualifierString(publicType.qualifier.storage));
6301     }
6302     if (publicType.shaderQualifiers.spacing != EvsNone) {
6303         if (publicType.qualifier.storage == EvqVaryingIn) {
6304             if (! intermediate.setVertexSpacing(publicType.shaderQualifiers.spacing))
6305                 error(loc, "cannot change previously set vertex spacing", TQualifier::getVertexSpacingString(publicType.shaderQualifiers.spacing), "");
6306         } else
6307             error(loc, "can only apply to 'in'", TQualifier::getVertexSpacingString(publicType.shaderQualifiers.spacing), "");
6308     }
6309     if (publicType.shaderQualifiers.order != EvoNone) {
6310         if (publicType.qualifier.storage == EvqVaryingIn) {
6311             if (! intermediate.setVertexOrder(publicType.shaderQualifiers.order))
6312                 error(loc, "cannot change previously set vertex order", TQualifier::getVertexOrderString(publicType.shaderQualifiers.order), "");
6313         } else
6314             error(loc, "can only apply to 'in'", TQualifier::getVertexOrderString(publicType.shaderQualifiers.order), "");
6315     }
6316     if (publicType.shaderQualifiers.pointMode) {
6317         if (publicType.qualifier.storage == EvqVaryingIn)
6318             intermediate.setPointMode();
6319         else
6320             error(loc, "can only apply to 'in'", "point_mode", "");
6321     }
6322     for (int i = 0; i < 3; ++i) {
6323         if (publicType.shaderQualifiers.localSize[i] > 1) {
6324             if (publicType.qualifier.storage == EvqVaryingIn) {
6325                 if (! intermediate.setLocalSize(i, publicType.shaderQualifiers.localSize[i]))
6326                     error(loc, "cannot change previously set size", "local_size", "");
6327                 else {
6328                     int max = 0;
6329                     switch (i) {
6330                     case 0: max = resources.maxComputeWorkGroupSizeX; break;
6331                     case 1: max = resources.maxComputeWorkGroupSizeY; break;
6332                     case 2: max = resources.maxComputeWorkGroupSizeZ; break;
6333                     default: break;
6334                     }
6335                     if (intermediate.getLocalSize(i) > (unsigned int)max)
6336                         error(loc, "too large; see gl_MaxComputeWorkGroupSize", "local_size", "");
6337
6338                     // Fix the existing constant gl_WorkGroupSize with this new information.
6339                     TVariable* workGroupSize = getEditableVariable("gl_WorkGroupSize");
6340                     if (workGroupSize != nullptr)
6341                         workGroupSize->getWritableConstArray()[i].setUConst(intermediate.getLocalSize(i));
6342                 }
6343             } else
6344                 error(loc, "can only apply to 'in'", "local_size", "");
6345         }
6346         if (publicType.shaderQualifiers.localSizeSpecId[i] != TQualifier::layoutNotSet) {
6347             if (publicType.qualifier.storage == EvqVaryingIn) {
6348                 if (! intermediate.setLocalSizeSpecId(i, publicType.shaderQualifiers.localSizeSpecId[i]))
6349                     error(loc, "cannot change previously set size", "local_size", "");
6350             } else
6351                 error(loc, "can only apply to 'in'", "local_size id", "");
6352             // Set the workgroup built-in variable as a specialization constant
6353             TVariable* workGroupSize = getEditableVariable("gl_WorkGroupSize");
6354             if (workGroupSize != nullptr)
6355                 workGroupSize->getWritableType().getQualifier().specConstant = true;
6356         }
6357     }
6358     if (publicType.shaderQualifiers.earlyFragmentTests) {
6359         if (publicType.qualifier.storage == EvqVaryingIn)
6360             intermediate.setEarlyFragmentTests();
6361         else
6362             error(loc, "can only apply to 'in'", "early_fragment_tests", "");
6363     }
6364     if (publicType.shaderQualifiers.postDepthCoverage) {
6365         if (publicType.qualifier.storage == EvqVaryingIn)
6366             intermediate.setPostDepthCoverage();
6367         else
6368             error(loc, "can only apply to 'in'", "post_coverage_coverage", "");
6369     }
6370     if (publicType.shaderQualifiers.blendEquation) {
6371         if (publicType.qualifier.storage != EvqVaryingOut)
6372             error(loc, "can only apply to 'out'", "blend equation", "");
6373     }
6374
6375     const TQualifier& qualifier = publicType.qualifier;
6376
6377     if (qualifier.isAuxiliary() ||
6378         qualifier.isMemory() ||
6379         qualifier.isInterpolation() ||
6380         qualifier.precision != EpqNone)
6381         error(loc, "cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type)", "qualifier", "");
6382     // "The offset qualifier can only be used on block members of blocks..."
6383     // "The align qualifier can only be used on blocks or block members..."
6384     if (qualifier.hasOffset() ||
6385         qualifier.hasAlign())
6386         error(loc, "cannot use offset or align qualifiers in a default qualifier declaration (declaration with no type)", "layout qualifier", "");
6387
6388     layoutQualifierCheck(loc, qualifier);
6389
6390     switch (qualifier.storage) {
6391     case EvqUniform:
6392         if (qualifier.hasMatrix())
6393             globalUniformDefaults.layoutMatrix = qualifier.layoutMatrix;
6394         if (qualifier.hasPacking())
6395             globalUniformDefaults.layoutPacking = qualifier.layoutPacking;
6396         break;
6397     case EvqBuffer:
6398         if (qualifier.hasMatrix())
6399             globalBufferDefaults.layoutMatrix = qualifier.layoutMatrix;
6400         if (qualifier.hasPacking())
6401             globalBufferDefaults.layoutPacking = qualifier.layoutPacking;
6402         break;
6403     case EvqVaryingIn:
6404         break;
6405     case EvqVaryingOut:
6406         if (qualifier.hasStream())
6407             globalOutputDefaults.layoutStream = qualifier.layoutStream;
6408         if (qualifier.hasXfbBuffer())
6409             globalOutputDefaults.layoutXfbBuffer = qualifier.layoutXfbBuffer;
6410         if (globalOutputDefaults.hasXfbBuffer() && qualifier.hasXfbStride()) {
6411             if (! intermediate.setXfbBufferStride(globalOutputDefaults.layoutXfbBuffer, qualifier.layoutXfbStride))
6412                 error(loc, "all stride settings must match for xfb buffer", "xfb_stride", "%d", qualifier.layoutXfbBuffer);
6413         }
6414         break;
6415     default:
6416         error(loc, "default qualifier requires 'uniform', 'buffer', 'in', or 'out' storage qualification", "", "");
6417         return;
6418     }
6419
6420     if (qualifier.hasBinding())
6421         error(loc, "cannot declare a default, include a type or full declaration", "binding", "");
6422     if (qualifier.hasAnyLocation())
6423         error(loc, "cannot declare a default, use a full declaration", "location/component/index", "");
6424     if (qualifier.hasXfbOffset())
6425         error(loc, "cannot declare a default, use a full declaration", "xfb_offset", "");
6426     if (qualifier.layoutPushConstant)
6427         error(loc, "cannot declare a default, can only be used on a block", "push_constant", "");
6428     if (qualifier.hasSpecConstantId())
6429         error(loc, "cannot declare a default, can only be used on a scalar", "constant_id", "");
6430 }
6431
6432 //
6433 // Take the sequence of statements that has been built up since the last case/default,
6434 // put it on the list of top-level nodes for the current (inner-most) switch statement,
6435 // and follow that by the case/default we are on now.  (See switch topology comment on
6436 // TIntermSwitch.)
6437 //
6438 void TParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode)
6439 {
6440     TIntermSequence* switchSequence = switchSequenceStack.back();
6441
6442     if (statements) {
6443         if (switchSequence->size() == 0)
6444             error(statements->getLoc(), "cannot have statements before first case/default label", "switch", "");
6445         statements->setOperator(EOpSequence);
6446         switchSequence->push_back(statements);
6447     }
6448     if (branchNode) {
6449         // check all previous cases for the same label (or both are 'default')
6450         for (unsigned int s = 0; s < switchSequence->size(); ++s) {
6451             TIntermBranch* prevBranch = (*switchSequence)[s]->getAsBranchNode();
6452             if (prevBranch) {
6453                 TIntermTyped* prevExpression = prevBranch->getExpression();
6454                 TIntermTyped* newExpression = branchNode->getAsBranchNode()->getExpression();
6455                 if (prevExpression == nullptr && newExpression == nullptr)
6456                     error(branchNode->getLoc(), "duplicate label", "default", "");
6457                 else if (prevExpression != nullptr &&
6458                           newExpression != nullptr &&
6459                          prevExpression->getAsConstantUnion() &&
6460                           newExpression->getAsConstantUnion() &&
6461                          prevExpression->getAsConstantUnion()->getConstArray()[0].getIConst() ==
6462                           newExpression->getAsConstantUnion()->getConstArray()[0].getIConst())
6463                     error(branchNode->getLoc(), "duplicated value", "case", "");
6464             }
6465         }
6466         switchSequence->push_back(branchNode);
6467     }
6468 }
6469
6470 //
6471 // Turn the top-level node sequence built up of wrapupSwitchSubsequence9)
6472 // into a switch node.
6473 //
6474 TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expression, TIntermAggregate* lastStatements)
6475 {
6476     profileRequires(loc, EEsProfile, 300, nullptr, "switch statements");
6477     profileRequires(loc, ENoProfile, 130, nullptr, "switch statements");
6478
6479     wrapupSwitchSubsequence(lastStatements, nullptr);
6480
6481     if (expression == nullptr ||
6482         (expression->getBasicType() != EbtInt && expression->getBasicType() != EbtUint) ||
6483         expression->getType().isArray() || expression->getType().isMatrix() || expression->getType().isVector())
6484             error(loc, "condition must be a scalar integer expression", "switch", "");
6485
6486     // If there is nothing to do, drop the switch but still execute the expression
6487     TIntermSequence* switchSequence = switchSequenceStack.back();
6488     if (switchSequence->size() == 0)
6489         return expression;
6490
6491     if (lastStatements == nullptr) {
6492         // This was originally an ERRROR, because early versions of the specification said
6493         // "it is an error to have no statement between a label and the end of the switch statement."
6494         // The specifications were updated to remove this (being ill-defined what a "statement" was),
6495         // so, this became a warning.  However, 3.0 tests still check for the error.
6496         if (profile == EEsProfile && version <= 300 && ! relaxedErrors())
6497             error(loc, "last case/default label not followed by statements", "switch", "");
6498         else
6499             warn(loc, "last case/default label not followed by statements", "switch", "");
6500
6501         // emulate a break for error recovery
6502         lastStatements = intermediate.makeAggregate(intermediate.addBranch(EOpBreak, loc));
6503         lastStatements->setOperator(EOpSequence);
6504         switchSequence->push_back(lastStatements);
6505     }
6506
6507     TIntermAggregate* body = new TIntermAggregate(EOpSequence);
6508     body->getSequence() = *switchSequenceStack.back();
6509     body->setLoc(loc);
6510
6511     TIntermSwitch* switchNode = new TIntermSwitch(expression, body);
6512     switchNode->setLoc(loc);
6513
6514     return switchNode;
6515 }
6516
6517 } // end namespace glslang