d338a7dddbd928b06a53a985aa0821599bec617b
[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-2018 Google, Inc.
5 // Copyright (C) 2017, 2019 ARM Limited.
6 //
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions
11 // are met:
12 //
13 //    Redistributions of source code must retain the above copyright
14 //    notice, this list of conditions and the following disclaimer.
15 //
16 //    Redistributions in binary form must reproduce the above
17 //    copyright notice, this list of conditions and the following
18 //    disclaimer in the documentation and/or other materials provided
19 //    with the distribution.
20 //
21 //    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
22 //    contributors may be used to endorse or promote products derived
23 //    from this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 // POSSIBILITY OF SUCH DAMAGE.
37 //
38
39 #include "ParseHelper.h"
40 #include "Scan.h"
41
42 #include "../OSDependent/osinclude.h"
43 #include <algorithm>
44
45 #include "preprocessor/PpContext.h"
46
47 extern int yyparse(glslang::TParseContext*);
48
49 namespace glslang {
50
51 TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, bool parsingBuiltins,
52                              int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language,
53                              TInfoSink& infoSink, bool forwardCompatible, EShMessages messages,
54                              const TString* entryPoint) :
55             TParseContextBase(symbolTable, interm, parsingBuiltins, version, profile, spvVersion, language,
56                               infoSink, forwardCompatible, messages, entryPoint),
57             inMain(false),
58             blockName(nullptr),
59             limits(resources.limits)
60 #ifndef GLSLANG_WEB
61             ,
62             atomicUintOffsets(nullptr), anyIndexLimits(false)
63 #endif
64 {
65     // decide whether precision qualifiers should be ignored or respected
66     if (isEsProfile() || spvVersion.vulkan > 0) {
67         precisionManager.respectPrecisionQualifiers();
68         if (! parsingBuiltins && language == EShLangFragment && !isEsProfile() && spvVersion.vulkan > 0)
69             precisionManager.warnAboutDefaults();
70     }
71
72     setPrecisionDefaults();
73
74     globalUniformDefaults.clear();
75     globalUniformDefaults.layoutMatrix = ElmColumnMajor;
76     globalUniformDefaults.layoutPacking = spvVersion.spv != 0 ? ElpStd140 : ElpShared;
77
78     globalBufferDefaults.clear();
79     globalBufferDefaults.layoutMatrix = ElmColumnMajor;
80     globalBufferDefaults.layoutPacking = spvVersion.spv != 0 ? ElpStd430 : ElpShared;
81
82     // use storage buffer on SPIR-V 1.3 and up
83     if (spvVersion.spv >= EShTargetSpv_1_3)
84         intermediate.setUseStorageBuffer();
85
86     globalInputDefaults.clear();
87     globalOutputDefaults.clear();
88
89 #ifndef GLSLANG_WEB
90     // "Shaders in the transform
91     // feedback capturing mode have an initial global default of
92     //     layout(xfb_buffer = 0) out;"
93     if (language == EShLangVertex ||
94         language == EShLangTessControl ||
95         language == EShLangTessEvaluation ||
96         language == EShLangGeometry)
97         globalOutputDefaults.layoutXfbBuffer = 0;
98
99     if (language == EShLangGeometry)
100         globalOutputDefaults.layoutStream = 0;
101 #endif
102
103     if (entryPoint != nullptr && entryPoint->size() > 0 && *entryPoint != "main")
104         infoSink.info.message(EPrefixError, "Source entry point must be \"main\"");
105 }
106
107 TParseContext::~TParseContext()
108 {
109 #ifndef GLSLANG_WEB
110     delete [] atomicUintOffsets;
111 #endif
112 }
113
114 // Set up all default precisions as needed by the current environment.
115 // Intended just as a TParseContext constructor helper.
116 void TParseContext::setPrecisionDefaults()
117 {
118     // Set all precision defaults to EpqNone, which is correct for all types
119     // when not obeying precision qualifiers, and correct for types that don't
120     // have defaults (thus getting an error on use) when obeying precision
121     // qualifiers.
122
123     for (int type = 0; type < EbtNumTypes; ++type)
124         defaultPrecision[type] = EpqNone;
125
126     for (int type = 0; type < maxSamplerIndex; ++type)
127         defaultSamplerPrecision[type] = EpqNone;
128
129     // replace with real precision defaults for those that have them
130     if (obeyPrecisionQualifiers()) {
131         if (isEsProfile()) {
132             // Most don't have defaults, a few default to lowp.
133             TSampler sampler;
134             sampler.set(EbtFloat, Esd2D);
135             defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow;
136             sampler.set(EbtFloat, EsdCube);
137             defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow;
138             sampler.set(EbtFloat, Esd2D);
139             sampler.setExternal(true);
140             defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow;
141         }
142
143         // If we are parsing built-in computational variables/functions, it is meaningful to record
144         // whether the built-in has no precision qualifier, as that ambiguity
145         // is used to resolve the precision from the supplied arguments/operands instead.
146         // So, we don't actually want to replace EpqNone with a default precision for built-ins.
147         if (! parsingBuiltins) {
148             if (isEsProfile() && language == EShLangFragment) {
149                 defaultPrecision[EbtInt] = EpqMedium;
150                 defaultPrecision[EbtUint] = EpqMedium;
151             } else {
152                 defaultPrecision[EbtInt] = EpqHigh;
153                 defaultPrecision[EbtUint] = EpqHigh;
154                 defaultPrecision[EbtFloat] = EpqHigh;
155             }
156
157             if (!isEsProfile()) {
158                 // Non-ES profile
159                 // All sampler precisions default to highp.
160                 for (int type = 0; type < maxSamplerIndex; ++type)
161                     defaultSamplerPrecision[type] = EpqHigh;
162             }
163         }
164
165         defaultPrecision[EbtSampler] = EpqLow;
166         defaultPrecision[EbtAtomicUint] = EpqHigh;
167     }
168 }
169
170 void TParseContext::setLimits(const TBuiltInResource& r)
171 {
172     resources = r;
173     intermediate.setLimits(r);
174
175 #ifndef GLSLANG_WEB
176     anyIndexLimits = ! limits.generalAttributeMatrixVectorIndexing ||
177                      ! limits.generalConstantMatrixVectorIndexing ||
178                      ! limits.generalSamplerIndexing ||
179                      ! limits.generalUniformIndexing ||
180                      ! limits.generalVariableIndexing ||
181                      ! limits.generalVaryingIndexing;
182
183
184     // "Each binding point tracks its own current default offset for
185     // inheritance of subsequent variables using the same binding. The initial state of compilation is that all
186     // binding points have an offset of 0."
187     atomicUintOffsets = new int[resources.maxAtomicCounterBindings];
188     for (int b = 0; b < resources.maxAtomicCounterBindings; ++b)
189         atomicUintOffsets[b] = 0;
190 #endif
191 }
192
193 //
194 // Parse an array of strings using yyparse, going through the
195 // preprocessor to tokenize the shader strings, then through
196 // the GLSL scanner.
197 //
198 // Returns true for successful acceptance of the shader, false if any errors.
199 //
200 bool TParseContext::parseShaderStrings(TPpContext& ppContext, TInputScanner& input, bool versionWillBeError)
201 {
202     currentScanner = &input;
203     ppContext.setInput(input, versionWillBeError);
204     yyparse(this);
205
206     finish();
207
208     return numErrors == 0;
209 }
210
211 // This is called from bison when it has a parse (syntax) error
212 // Note though that to stop cascading errors, we set EOF, which
213 // will usually cause a syntax error, so be more accurate that
214 // compilation is terminating.
215 void TParseContext::parserError(const char* s)
216 {
217     if (! getScanner()->atEndOfInput() || numErrors == 0)
218         error(getCurrentLoc(), "", "", s, "");
219     else
220         error(getCurrentLoc(), "compilation terminated", "", "");
221 }
222
223 void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>& tokens)
224 {
225 #ifndef GLSLANG_WEB
226     if (pragmaCallback)
227         pragmaCallback(loc.line, tokens);
228
229     if (tokens.size() == 0)
230         return;
231
232     if (tokens[0].compare("optimize") == 0) {
233         if (tokens.size() != 4) {
234             error(loc, "optimize pragma syntax is incorrect", "#pragma", "");
235             return;
236         }
237
238         if (tokens[1].compare("(") != 0) {
239             error(loc, "\"(\" expected after 'optimize' keyword", "#pragma", "");
240             return;
241         }
242
243         if (tokens[2].compare("on") == 0)
244             contextPragma.optimize = true;
245         else if (tokens[2].compare("off") == 0)
246             contextPragma.optimize = false;
247         else {
248             error(loc, "\"on\" or \"off\" expected after '(' for 'optimize' pragma", "#pragma", "");
249             return;
250         }
251
252         if (tokens[3].compare(")") != 0) {
253             error(loc, "\")\" expected to end 'optimize' pragma", "#pragma", "");
254             return;
255         }
256     } else if (tokens[0].compare("debug") == 0) {
257         if (tokens.size() != 4) {
258             error(loc, "debug pragma syntax is incorrect", "#pragma", "");
259             return;
260         }
261
262         if (tokens[1].compare("(") != 0) {
263             error(loc, "\"(\" expected after 'debug' keyword", "#pragma", "");
264             return;
265         }
266
267         if (tokens[2].compare("on") == 0)
268             contextPragma.debug = true;
269         else if (tokens[2].compare("off") == 0)
270             contextPragma.debug = false;
271         else {
272             error(loc, "\"on\" or \"off\" expected after '(' for 'debug' pragma", "#pragma", "");
273             return;
274         }
275
276         if (tokens[3].compare(")") != 0) {
277             error(loc, "\")\" expected to end 'debug' pragma", "#pragma", "");
278             return;
279         }
280     } else if (spvVersion.spv > 0 && tokens[0].compare("use_storage_buffer") == 0) {
281         if (tokens.size() != 1)
282             error(loc, "extra tokens", "#pragma", "");
283         intermediate.setUseStorageBuffer();
284     } else if (spvVersion.spv > 0 && tokens[0].compare("use_vulkan_memory_model") == 0) {
285         if (tokens.size() != 1)
286             error(loc, "extra tokens", "#pragma", "");
287         intermediate.setUseVulkanMemoryModel();
288     } else if (spvVersion.spv > 0 && tokens[0].compare("use_variable_pointers") == 0) {
289         if (tokens.size() != 1)
290             error(loc, "extra tokens", "#pragma", "");
291         if (spvVersion.spv < glslang::EShTargetSpv_1_3)
292             error(loc, "requires SPIR-V 1.3", "#pragma use_variable_pointers", "");
293         intermediate.setUseVariablePointers();
294     } else if (tokens[0].compare("once") == 0) {
295         warn(loc, "not implemented", "#pragma once", "");
296     } else if (tokens[0].compare("glslang_binary_double_output") == 0)
297         intermediate.setBinaryDoubleOutput();
298 #endif
299 }
300
301 //
302 // Handle seeing a variable identifier in the grammar.
303 //
304 TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symbol, const TString* string)
305 {
306     TIntermTyped* node = nullptr;
307
308     // Error check for requiring specific extensions present.
309     if (symbol && symbol->getNumExtensions())
310         requireExtensions(loc, symbol->getNumExtensions(), symbol->getExtensions(), symbol->getName().c_str());
311
312 #ifndef GLSLANG_WEB
313     if (symbol && symbol->isReadOnly()) {
314         // All shared things containing an unsized array must be copied up
315         // on first use, so that all future references will share its array structure,
316         // so that editing the implicit size will effect all nodes consuming it,
317         // and so that editing the implicit size won't change the shared one.
318         //
319         // If this is a variable or a block, check it and all it contains, but if this
320         // is a member of an anonymous block, check the whole block, as the whole block
321         // will need to be copied up if it contains an unsized array.
322         //
323         // This check is being done before the block-name check further down, so guard
324         // for that too.
325         if (!symbol->getType().isUnusableName()) {
326             if (symbol->getType().containsUnsizedArray() ||
327                 (symbol->getAsAnonMember() &&
328                  symbol->getAsAnonMember()->getAnonContainer().getType().containsUnsizedArray()))
329                 makeEditable(symbol);
330         }
331     }
332 #endif
333
334     const TVariable* variable;
335     const TAnonMember* anon = symbol ? symbol->getAsAnonMember() : nullptr;
336     if (anon) {
337         // It was a member of an anonymous container.
338
339         // Create a subtree for its dereference.
340         variable = anon->getAnonContainer().getAsVariable();
341         TIntermTyped* container = intermediate.addSymbol(*variable, loc);
342         TIntermTyped* constNode = intermediate.addConstantUnion(anon->getMemberNumber(), loc);
343         node = intermediate.addIndex(EOpIndexDirectStruct, container, constNode, loc);
344
345         node->setType(*(*variable->getType().getStruct())[anon->getMemberNumber()].type);
346         if (node->getType().hiddenMember())
347             error(loc, "member of nameless block was not redeclared", string->c_str(), "");
348     } else {
349         // Not a member of an anonymous container.
350
351         // The symbol table search was done in the lexical phase.
352         // See if it was a variable.
353         variable = symbol ? symbol->getAsVariable() : nullptr;
354         if (variable) {
355             if (variable->getType().isUnusableName()) {
356                 error(loc, "cannot be used (maybe an instance name is needed)", string->c_str(), "");
357                 variable = nullptr;
358             }
359         } else {
360             if (symbol)
361                 error(loc, "variable name expected", string->c_str(), "");
362         }
363
364         // Recovery, if it wasn't found or was not a variable.
365         if (! variable)
366             variable = new TVariable(string, TType(EbtVoid));
367
368         if (variable->getType().getQualifier().isFrontEndConstant())
369             node = intermediate.addConstantUnion(variable->getConstArray(), variable->getType(), loc);
370         else
371             node = intermediate.addSymbol(*variable, loc);
372     }
373
374     if (variable->getType().getQualifier().isIo())
375         intermediate.addIoAccessed(*string);
376
377     if (variable->getType().isReference() &&
378         variable->getType().getQualifier().bufferReferenceNeedsVulkanMemoryModel()) {
379         intermediate.setUseVulkanMemoryModel();
380     }
381
382     return node;
383 }
384
385 //
386 // Handle seeing a base[index] dereference in the grammar.
387 //
388 TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index)
389 {
390     int indexValue = 0;
391     if (index->getQualifier().isFrontEndConstant())
392         indexValue = index->getAsConstantUnion()->getConstArray()[0].getIConst();
393
394     // basic type checks...
395     variableCheck(base);
396
397     if (! base->isArray() && ! base->isMatrix() && ! base->isVector() && ! base->getType().isCoopMat() &&
398         ! base->isReference()) {
399         if (base->getAsSymbolNode())
400             error(loc, " left of '[' is not of type array, matrix, or vector ", base->getAsSymbolNode()->getName().c_str(), "");
401         else
402             error(loc, " left of '[' is not of type array, matrix, or vector ", "expression", "");
403
404         // Insert dummy error-recovery result
405         return intermediate.addConstantUnion(0.0, EbtFloat, loc);
406     }
407
408     if (!base->isArray() && base->isVector()) {
409         if (base->getType().contains16BitFloat())
410             requireFloat16Arithmetic(loc, "[", "does not operate on types containing float16");
411         if (base->getType().contains16BitInt())
412             requireInt16Arithmetic(loc, "[", "does not operate on types containing (u)int16");
413         if (base->getType().contains8BitInt())
414             requireInt8Arithmetic(loc, "[", "does not operate on types containing (u)int8");
415     }
416
417     // check for constant folding
418     if (base->getType().getQualifier().isFrontEndConstant() && index->getQualifier().isFrontEndConstant()) {
419         // both base and index are front-end constants
420         checkIndex(loc, base->getType(), indexValue);
421         return intermediate.foldDereference(base, indexValue, loc);
422     }
423
424     // at least one of base and index is not a front-end constant variable...
425     TIntermTyped* result = nullptr;
426
427 #ifndef GLSLANG_WEB
428     if (base->isReference() && ! base->isArray()) {
429         requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "buffer reference indexing");
430         result = intermediate.addBinaryMath(EOpAdd, base, index, loc);
431         result->setType(base->getType());
432         return result;
433     }
434     if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
435         handleIoResizeArrayAccess(loc, base);
436 #endif
437
438     if (index->getQualifier().isFrontEndConstant())
439         checkIndex(loc, base->getType(), indexValue);
440
441     if (index->getQualifier().isFrontEndConstant()) {
442 #ifndef GLSLANG_WEB
443         if (base->getType().isUnsizedArray()) {
444             base->getWritableType().updateImplicitArraySize(indexValue + 1);
445             // For 2D per-view builtin arrays, update the inner dimension size in parent type
446             if (base->getQualifier().isPerView() && base->getQualifier().builtIn != EbvNone) {
447                 TIntermBinary* binaryNode = base->getAsBinaryNode();
448                 if (binaryNode) {
449                     TType& leftType = binaryNode->getLeft()->getWritableType();
450                     TArraySizes& arraySizes = *leftType.getArraySizes();
451                     assert(arraySizes.getNumDims() == 2);
452                     arraySizes.setDimSize(1, std::max(arraySizes.getDimSize(1), indexValue + 1));
453                 }
454             }
455         } else
456 #endif
457             checkIndex(loc, base->getType(), indexValue);
458         result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
459     } else {
460 #ifndef GLSLANG_WEB
461         if (base->getType().isUnsizedArray()) {
462             // we have a variable index into an unsized array, which is okay,
463             // depending on the situation
464             if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
465                 error(loc, "", "[", "array must be sized by a redeclaration or layout qualifier before being indexed with a variable");
466             else {
467                 // it is okay for a run-time sized array
468                 checkRuntimeSizable(loc, *base);
469             }
470             base->getWritableType().setArrayVariablyIndexed();
471         }
472 #endif
473         if (base->getBasicType() == EbtBlock) {
474             if (base->getQualifier().storage == EvqBuffer)
475                 requireProfile(base->getLoc(), ~EEsProfile, "variable indexing buffer block array");
476             else if (base->getQualifier().storage == EvqUniform)
477                 profileRequires(base->getLoc(), EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5,
478                                 "variable indexing uniform block array");
479             else {
480                 // input/output blocks either don't exist or can't be variably indexed
481             }
482         } else if (language == EShLangFragment && base->getQualifier().isPipeOutput())
483             requireProfile(base->getLoc(), ~EEsProfile, "variable indexing fragment shader output array");
484         else if (base->getBasicType() == EbtSampler && version >= 130) {
485             const char* explanation = "variable indexing sampler array";
486             requireProfile(base->getLoc(), EEsProfile | ECoreProfile | ECompatibilityProfile, explanation);
487             profileRequires(base->getLoc(), EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, explanation);
488             profileRequires(base->getLoc(), ECoreProfile | ECompatibilityProfile, 400, nullptr, explanation);
489         }
490
491         result = intermediate.addIndex(EOpIndexIndirect, base, index, loc);
492     }
493
494     // Insert valid dereferenced result type
495     TType newType(base->getType(), 0);
496     if (base->getType().getQualifier().isConstant() && index->getQualifier().isConstant()) {
497         newType.getQualifier().storage = EvqConst;
498         // If base or index is a specialization constant, the result should also be a specialization constant.
499         if (base->getType().getQualifier().isSpecConstant() || index->getQualifier().isSpecConstant()) {
500             newType.getQualifier().makeSpecConstant();
501         }
502     } else {
503         newType.getQualifier().storage = EvqTemporary;
504         newType.getQualifier().specConstant = false;
505     }
506     result->setType(newType);
507
508 #ifndef GLSLANG_WEB
509     inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier());
510
511     // Propagate nonuniform
512     if (base->getQualifier().isNonUniform() || index->getQualifier().isNonUniform())
513         result->getWritableType().getQualifier().nonUniform = true;
514
515     if (anyIndexLimits)
516         handleIndexLimits(loc, base, index);
517 #endif
518
519     return result;
520 }
521
522 #ifndef GLSLANG_WEB
523
524 // for ES 2.0 (version 100) limitations for almost all index operations except vertex-shader uniforms
525 void TParseContext::handleIndexLimits(const TSourceLoc& /*loc*/, TIntermTyped* base, TIntermTyped* index)
526 {
527     if ((! limits.generalSamplerIndexing && base->getBasicType() == EbtSampler) ||
528         (! limits.generalUniformIndexing && base->getQualifier().isUniformOrBuffer() && language != EShLangVertex) ||
529         (! limits.generalAttributeMatrixVectorIndexing && base->getQualifier().isPipeInput() && language == EShLangVertex && (base->getType().isMatrix() || base->getType().isVector())) ||
530         (! limits.generalConstantMatrixVectorIndexing && base->getAsConstantUnion()) ||
531         (! limits.generalVariableIndexing && ! base->getType().getQualifier().isUniformOrBuffer() &&
532                                              ! base->getType().getQualifier().isPipeInput() &&
533                                              ! base->getType().getQualifier().isPipeOutput() &&
534                                              ! base->getType().getQualifier().isConstant()) ||
535         (! limits.generalVaryingIndexing && (base->getType().getQualifier().isPipeInput() ||
536                                                 base->getType().getQualifier().isPipeOutput()))) {
537         // it's too early to know what the inductive variables are, save it for post processing
538         needsIndexLimitationChecking.push_back(index);
539     }
540 }
541
542 // Make a shared symbol have a non-shared version that can be edited by the current
543 // compile, such that editing its type will not change the shared version and will
544 // effect all nodes sharing it.
545 void TParseContext::makeEditable(TSymbol*& symbol)
546 {
547     TParseContextBase::makeEditable(symbol);
548
549     // See if it's tied to IO resizing
550     if (isIoResizeArray(symbol->getType()))
551         ioArraySymbolResizeList.push_back(symbol);
552 }
553
554 // Return true if this is a geometry shader input array or tessellation control output array
555 // or mesh shader output array.
556 bool TParseContext::isIoResizeArray(const TType& type) const
557 {
558     return type.isArray() &&
559            ((language == EShLangGeometry    && type.getQualifier().storage == EvqVaryingIn) ||
560             (language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut &&
561                 ! type.getQualifier().patch) ||
562             (language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn &&
563                 type.getQualifier().pervertexNV) ||
564             (language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut &&
565                 !type.getQualifier().perTaskNV));
566 }
567
568 // If an array is not isIoResizeArray() but is an io array, make sure it has the right size
569 void TParseContext::fixIoArraySize(const TSourceLoc& loc, TType& type)
570 {
571     if (! type.isArray() || type.getQualifier().patch || symbolTable.atBuiltInLevel())
572         return;
573
574     assert(! isIoResizeArray(type));
575
576     if (type.getQualifier().storage != EvqVaryingIn || type.getQualifier().patch)
577         return;
578
579     if (language == EShLangTessControl || language == EShLangTessEvaluation) {
580         if (type.getOuterArraySize() != resources.maxPatchVertices) {
581             if (type.isSizedArray())
582                 error(loc, "tessellation input array size must be gl_MaxPatchVertices or implicitly sized", "[]", "");
583             type.changeOuterArraySize(resources.maxPatchVertices);
584         }
585     }
586 }
587
588 // Issue any errors if the non-array object is missing arrayness WRT
589 // shader I/O that has array requirements.
590 // All arrayness checking is handled in array paths, this is for
591 void TParseContext::ioArrayCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
592 {
593     if (! type.isArray() && ! symbolTable.atBuiltInLevel()) {
594         if (type.getQualifier().isArrayedIo(language) && !type.getQualifier().layoutPassthrough)
595             error(loc, "type must be an array:", type.getStorageQualifierString(), identifier.c_str());
596     }
597 }
598
599 // Handle a dereference of a geometry shader input array or tessellation control output array.
600 // See ioArraySymbolResizeList comment in ParseHelper.h.
601 //
602 void TParseContext::handleIoResizeArrayAccess(const TSourceLoc& /*loc*/, TIntermTyped* base)
603 {
604     TIntermSymbol* symbolNode = base->getAsSymbolNode();
605     assert(symbolNode);
606     if (! symbolNode)
607         return;
608
609     // fix array size, if it can be fixed and needs to be fixed (will allow variable indexing)
610     if (symbolNode->getType().isUnsizedArray()) {
611         int newSize = getIoArrayImplicitSize(symbolNode->getType().getQualifier());
612         if (newSize > 0)
613             symbolNode->getWritableType().changeOuterArraySize(newSize);
614     }
615 }
616
617 // If there has been an input primitive declaration (geometry shader) or an output
618 // number of vertices declaration(tessellation shader), make sure all input array types
619 // match it in size.  Types come either from nodes in the AST or symbols in the
620 // symbol table.
621 //
622 // Types without an array size will be given one.
623 // Types already having a size that is wrong will get an error.
624 //
625 void TParseContext::checkIoArraysConsistency(const TSourceLoc &loc, bool tailOnly)
626 {
627     int requiredSize = 0;
628     TString featureString;
629     size_t listSize = ioArraySymbolResizeList.size();
630     size_t i = 0;
631
632     // If tailOnly = true, only check the last array symbol in the list.
633     if (tailOnly) {
634         i = listSize - 1;
635     }
636     for (bool firstIteration = true; i < listSize; ++i) {
637         TType &type = ioArraySymbolResizeList[i]->getWritableType();
638
639         // As I/O array sizes don't change, fetch requiredSize only once,
640         // except for mesh shaders which could have different I/O array sizes based on type qualifiers.
641         if (firstIteration || (language == EShLangMeshNV)) {
642             requiredSize = getIoArrayImplicitSize(type.getQualifier(), &featureString);
643             if (requiredSize == 0)
644                 break;
645             firstIteration = false;
646         }
647
648         checkIoArrayConsistency(loc, requiredSize, featureString.c_str(), type,
649                                 ioArraySymbolResizeList[i]->getName());
650     }
651 }
652
653 int TParseContext::getIoArrayImplicitSize(const TQualifier &qualifier, TString *featureString) const
654 {
655     int expectedSize = 0;
656     TString str = "unknown";
657     unsigned int maxVertices = intermediate.getVertices() != TQualifier::layoutNotSet ? intermediate.getVertices() : 0;
658
659     if (language == EShLangGeometry) {
660         expectedSize = TQualifier::mapGeometryToSize(intermediate.getInputPrimitive());
661         str = TQualifier::getGeometryString(intermediate.getInputPrimitive());
662     }
663     else if (language == EShLangTessControl) {
664         expectedSize = maxVertices;
665         str = "vertices";
666     } else if (language == EShLangFragment) {
667         // Number of vertices for Fragment shader is always three.
668         expectedSize = 3;
669         str = "vertices";
670     } else if (language == EShLangMeshNV) {
671         unsigned int maxPrimitives =
672             intermediate.getPrimitives() != TQualifier::layoutNotSet ? intermediate.getPrimitives() : 0;
673         if (qualifier.builtIn == EbvPrimitiveIndicesNV) {
674             expectedSize = maxPrimitives * TQualifier::mapGeometryToSize(intermediate.getOutputPrimitive());
675             str = "max_primitives*";
676             str += TQualifier::getGeometryString(intermediate.getOutputPrimitive());
677         }
678         else if (qualifier.isPerPrimitive()) {
679             expectedSize = maxPrimitives;
680             str = "max_primitives";
681         }
682         else {
683             expectedSize = maxVertices;
684             str = "max_vertices";
685         }
686     }
687     if (featureString)
688         *featureString = str;
689     return expectedSize;
690 }
691
692 void TParseContext::checkIoArrayConsistency(const TSourceLoc& loc, int requiredSize, const char* feature, TType& type, const TString& name)
693 {
694     if (type.isUnsizedArray())
695         type.changeOuterArraySize(requiredSize);
696     else if (type.getOuterArraySize() != requiredSize) {
697         if (language == EShLangGeometry)
698             error(loc, "inconsistent input primitive for array size of", feature, name.c_str());
699         else if (language == EShLangTessControl)
700             error(loc, "inconsistent output number of vertices for array size of", feature, name.c_str());
701         else if (language == EShLangFragment) {
702             if (type.getOuterArraySize() > requiredSize)
703                 error(loc, " cannot be greater than 3 for pervertexNV", feature, name.c_str());
704         }
705         else if (language == EShLangMeshNV)
706             error(loc, "inconsistent output array size of", feature, name.c_str());
707         else
708             assert(0);
709     }
710 }
711
712 #endif // GLSLANG_WEB
713
714 // Handle seeing a binary node with a math operation.
715 // Returns nullptr if not semantically allowed.
716 TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right)
717 {
718     rValueErrorCheck(loc, str, left->getAsTyped());
719     rValueErrorCheck(loc, str, right->getAsTyped());
720
721     bool allowed = true;
722     switch (op) {
723     // TODO: Bring more source language-specific checks up from intermediate.cpp
724     // to the specific parse helpers for that source language.
725     case EOpLessThan:
726     case EOpGreaterThan:
727     case EOpLessThanEqual:
728     case EOpGreaterThanEqual:
729         if (! left->isScalar() || ! right->isScalar())
730             allowed = false;
731         break;
732     default:
733         break;
734     }
735
736     if (((left->getType().contains16BitFloat() || right->getType().contains16BitFloat()) && !float16Arithmetic()) ||
737         ((left->getType().contains16BitInt() || right->getType().contains16BitInt()) && !int16Arithmetic()) ||
738         ((left->getType().contains8BitInt() || right->getType().contains8BitInt()) && !int8Arithmetic())) {
739         allowed = false;
740     }
741
742     TIntermTyped* result = nullptr;
743     if (allowed)
744         result = intermediate.addBinaryMath(op, left, right, loc);
745
746     if (result == nullptr)
747         binaryOpError(loc, str, left->getCompleteString(), right->getCompleteString());
748
749     return result;
750 }
751
752 // Handle seeing a unary node with a math operation.
753 TIntermTyped* TParseContext::handleUnaryMath(const TSourceLoc& loc, const char* str, TOperator op, TIntermTyped* childNode)
754 {
755     rValueErrorCheck(loc, str, childNode);
756
757     bool allowed = true;
758     if ((childNode->getType().contains16BitFloat() && !float16Arithmetic()) ||
759         (childNode->getType().contains16BitInt() && !int16Arithmetic()) ||
760         (childNode->getType().contains8BitInt() && !int8Arithmetic())) {
761         allowed = false;
762     }
763
764     TIntermTyped* result = nullptr;
765     if (allowed)
766         result = intermediate.addUnaryMath(op, childNode, loc);
767
768     if (result)
769         return result;
770     else
771         unaryOpError(loc, str, childNode->getCompleteString());
772
773     return childNode;
774 }
775
776 //
777 // Handle seeing a base.field dereference in the grammar.
778 //
779 TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TIntermTyped* base, const TString& field)
780 {
781     variableCheck(base);
782
783     //
784     // .length() can't be resolved until we later see the function-calling syntax.
785     // Save away the name in the AST for now.  Processing is completed in
786     // handleLengthMethod().
787     //
788     if (field == "length") {
789         if (base->isArray()) {
790             profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, ".length");
791             profileRequires(loc, EEsProfile, 300, nullptr, ".length");
792         } else if (base->isVector() || base->isMatrix()) {
793             const char* feature = ".length() on vectors and matrices";
794             requireProfile(loc, ~EEsProfile, feature);
795             profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, feature);
796         } else if (!base->getType().isCoopMat()) {
797             error(loc, "does not operate on this type:", field.c_str(), base->getType().getCompleteString().c_str());
798
799             return base;
800         }
801
802         return intermediate.addMethod(base, TType(EbtInt), &field, loc);
803     }
804
805     // It's not .length() if we get to here.
806
807     if (base->isArray()) {
808         error(loc, "cannot apply to an array:", ".", field.c_str());
809
810         return base;
811     }
812
813     if (base->getType().isCoopMat()) {
814         error(loc, "cannot apply to a cooperative matrix type:", ".", field.c_str());
815         return base;
816     }
817
818     // It's neither an array nor .length() if we get here,
819     // leaving swizzles and struct/block dereferences.
820
821     TIntermTyped* result = base;
822     if ((base->isVector() || base->isScalar()) &&
823         (base->isFloatingDomain() || base->isIntegerDomain() || base->getBasicType() == EbtBool)) {
824         if (base->isScalar()) {
825             const char* dotFeature = "scalar swizzle";
826             requireProfile(loc, ~EEsProfile, dotFeature);
827             profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, dotFeature);
828         }
829
830         TSwizzleSelectors<TVectorSelector> selectors;
831         parseSwizzleSelector(loc, field, base->getVectorSize(), selectors);
832
833         if (base->isVector() && selectors.size() != 1 && base->getType().contains16BitFloat())
834             requireFloat16Arithmetic(loc, ".", "can't swizzle types containing float16");
835         if (base->isVector() && selectors.size() != 1 && base->getType().contains16BitInt())
836             requireInt16Arithmetic(loc, ".", "can't swizzle types containing (u)int16");
837         if (base->isVector() && selectors.size() != 1 && base->getType().contains8BitInt())
838             requireInt8Arithmetic(loc, ".", "can't swizzle types containing (u)int8");
839
840         if (base->isScalar()) {
841             if (selectors.size() == 1)
842                 return result;
843             else {
844                 TType type(base->getBasicType(), EvqTemporary, selectors.size());
845                 // Swizzle operations propagate specialization-constantness
846                 if (base->getQualifier().isSpecConstant())
847                     type.getQualifier().makeSpecConstant();
848                 return addConstructor(loc, base, type);
849             }
850         }
851
852         if (base->getType().getQualifier().isFrontEndConstant())
853             result = intermediate.foldSwizzle(base, selectors, loc);
854         else {
855             if (selectors.size() == 1) {
856                 TIntermTyped* index = intermediate.addConstantUnion(selectors[0], loc);
857                 result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
858                 result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision));
859             } else {
860                 TIntermTyped* index = intermediate.addSwizzle(selectors, loc);
861                 result = intermediate.addIndex(EOpVectorSwizzle, base, index, loc);
862                 result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision, selectors.size()));
863             }
864             // Swizzle operations propagate specialization-constantness
865             if (base->getType().getQualifier().isSpecConstant())
866                 result->getWritableType().getQualifier().makeSpecConstant();
867         }
868     } else if (base->isStruct() || base->isReference()) {
869         const TTypeList* fields = base->isReference() ?
870                                   base->getType().getReferentType()->getStruct() :
871                                   base->getType().getStruct();
872         bool fieldFound = false;
873         int member;
874         for (member = 0; member < (int)fields->size(); ++member) {
875             if ((*fields)[member].type->getFieldName() == field) {
876                 fieldFound = true;
877                 break;
878             }
879         }
880         if (fieldFound) {
881             if (base->getType().getQualifier().isFrontEndConstant())
882                 result = intermediate.foldDereference(base, member, loc);
883             else {
884                 blockMemberExtensionCheck(loc, base, member, field);
885                 TIntermTyped* index = intermediate.addConstantUnion(member, loc);
886                 result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc);
887                 result->setType(*(*fields)[member].type);
888                 if ((*fields)[member].type->getQualifier().isIo())
889                     intermediate.addIoAccessed(field);
890             }
891             inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier());
892         } else
893             error(loc, "no such field in structure", field.c_str(), "");
894     } else
895         error(loc, "does not apply to this type:", field.c_str(), base->getType().getCompleteString().c_str());
896
897     // Propagate noContraction up the dereference chain
898     if (base->getQualifier().isNoContraction())
899         result->getWritableType().getQualifier().setNoContraction();
900
901     // Propagate nonuniform
902     if (base->getQualifier().isNonUniform())
903         result->getWritableType().getQualifier().nonUniform = true;
904
905     return result;
906 }
907
908 void TParseContext::blockMemberExtensionCheck(const TSourceLoc& loc, const TIntermTyped* base, int member, const TString& memberName)
909 {
910     // a block that needs extension checking is either 'base', or if arrayed,
911     // one level removed to the left
912     const TIntermSymbol* baseSymbol = nullptr;
913     if (base->getAsBinaryNode() == nullptr)
914         baseSymbol = base->getAsSymbolNode();
915     else
916         baseSymbol = base->getAsBinaryNode()->getLeft()->getAsSymbolNode();
917     if (baseSymbol == nullptr)
918         return;
919     const TSymbol* symbol = symbolTable.find(baseSymbol->getName());
920     if (symbol == nullptr)
921         return;
922     const TVariable* variable = symbol->getAsVariable();
923     if (variable == nullptr)
924         return;
925     if (!variable->hasMemberExtensions())
926         return;
927
928     // We now have a variable that is the base of a dot reference
929     // with members that need extension checking.
930     if (variable->getNumMemberExtensions(member) > 0)
931         requireExtensions(loc, variable->getNumMemberExtensions(member), variable->getMemberExtensions(member), memberName.c_str());
932 }
933
934 //
935 // Handle seeing a function declarator in the grammar.  This is the precursor
936 // to recognizing a function prototype or function definition.
937 //
938 TFunction* TParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFunction& function, bool prototype)
939 {
940     // ES can't declare prototypes inside functions
941     if (! symbolTable.atGlobalLevel())
942         requireProfile(loc, ~EEsProfile, "local function declaration");
943
944     //
945     // Multiple declarations of the same function name are allowed.
946     //
947     // If this is a definition, the definition production code will check for redefinitions
948     // (we don't know at this point if it's a definition or not).
949     //
950     // Redeclarations (full signature match) are allowed.  But, return types and parameter qualifiers must also match.
951     //  - except ES 100, which only allows a single prototype
952     //
953     // ES 100 does not allow redefining, but does allow overloading of built-in functions.
954     // ES 300 does not allow redefining or overloading of built-in functions.
955     //
956     bool builtIn;
957     TSymbol* symbol = symbolTable.find(function.getMangledName(), &builtIn);
958     if (symbol && symbol->getAsFunction() && builtIn)
959         requireProfile(loc, ~EEsProfile, "redefinition of built-in function");
960     const TFunction* prevDec = symbol ? symbol->getAsFunction() : 0;
961     if (prevDec) {
962         if (prevDec->isPrototyped() && prototype)
963             profileRequires(loc, EEsProfile, 300, nullptr, "multiple prototypes for same function");
964         if (prevDec->getType() != function.getType())
965             error(loc, "overloaded functions must have the same return type", function.getName().c_str(), "");
966         for (int i = 0; i < prevDec->getParamCount(); ++i) {
967             if ((*prevDec)[i].type->getQualifier().storage != function[i].type->getQualifier().storage)
968                 error(loc, "overloaded functions must have the same parameter storage qualifiers for argument", function[i].type->getStorageQualifierString(), "%d", i+1);
969
970             if ((*prevDec)[i].type->getQualifier().precision != function[i].type->getQualifier().precision)
971                 error(loc, "overloaded functions must have the same parameter precision qualifiers for argument", function[i].type->getPrecisionQualifierString(), "%d", i+1);
972         }
973     }
974
975     arrayObjectCheck(loc, function.getType(), "array in function return type");
976
977     if (prototype) {
978         // All built-in functions are defined, even though they don't have a body.
979         // Count their prototype as a definition instead.
980         if (symbolTable.atBuiltInLevel())
981             function.setDefined();
982         else {
983             if (prevDec && ! builtIn)
984                 symbol->getAsFunction()->setPrototyped();  // need a writable one, but like having prevDec as a const
985             function.setPrototyped();
986         }
987     }
988
989     // This insert won't actually insert it if it's a duplicate signature, but it will still check for
990     // other forms of name collisions.
991     if (! symbolTable.insert(function))
992         error(loc, "function name is redeclaration of existing name", function.getName().c_str(), "");
993
994     //
995     // If this is a redeclaration, it could also be a definition,
996     // in which case, we need to use the parameter names from this one, and not the one that's
997     // being redeclared.  So, pass back this declaration, not the one in the symbol table.
998     //
999     return &function;
1000 }
1001
1002 //
1003 // Handle seeing the function prototype in front of a function definition in the grammar.
1004 // The body is handled after this function returns.
1005 //
1006 TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc, TFunction& function)
1007 {
1008     currentCaller = function.getMangledName();
1009     TSymbol* symbol = symbolTable.find(function.getMangledName());
1010     TFunction* prevDec = symbol ? symbol->getAsFunction() : nullptr;
1011
1012     if (! prevDec)
1013         error(loc, "can't find function", function.getName().c_str(), "");
1014     // Note:  'prevDec' could be 'function' if this is the first time we've seen function
1015     // as it would have just been put in the symbol table.  Otherwise, we're looking up
1016     // an earlier occurrence.
1017
1018     if (prevDec && prevDec->isDefined()) {
1019         // Then this function already has a body.
1020         error(loc, "function already has a body", function.getName().c_str(), "");
1021     }
1022     if (prevDec && ! prevDec->isDefined()) {
1023         prevDec->setDefined();
1024
1025         // Remember the return type for later checking for RETURN statements.
1026         currentFunctionType = &(prevDec->getType());
1027     } else
1028         currentFunctionType = new TType(EbtVoid);
1029     functionReturnsValue = false;
1030
1031     // Check for entry point
1032     if (function.getName().compare(intermediate.getEntryPointName().c_str()) == 0) {
1033         intermediate.setEntryPointMangledName(function.getMangledName().c_str());
1034         intermediate.incrementEntryPointCount();
1035         inMain = true;
1036     } else
1037         inMain = false;
1038
1039     //
1040     // Raise error message if main function takes any parameters or returns anything other than void
1041     //
1042     if (inMain) {
1043         if (function.getParamCount() > 0)
1044             error(loc, "function cannot take any parameter(s)", function.getName().c_str(), "");
1045         if (function.getType().getBasicType() != EbtVoid)
1046             error(loc, "", function.getType().getBasicTypeString().c_str(), "entry point cannot return a value");
1047     }
1048
1049     //
1050     // New symbol table scope for body of function plus its arguments
1051     //
1052     symbolTable.push();
1053
1054     //
1055     // Insert parameters into the symbol table.
1056     // If the parameter has no name, it's not an error, just don't insert it
1057     // (could be used for unused args).
1058     //
1059     // Also, accumulate the list of parameters into the HIL, so lower level code
1060     // knows where to find parameters.
1061     //
1062     TIntermAggregate* paramNodes = new TIntermAggregate;
1063     for (int i = 0; i < function.getParamCount(); i++) {
1064         TParameter& param = function[i];
1065         if (param.name != nullptr) {
1066             TVariable *variable = new TVariable(param.name, *param.type);
1067
1068             // Insert the parameters with name in the symbol table.
1069             if (! symbolTable.insert(*variable))
1070                 error(loc, "redefinition", variable->getName().c_str(), "");
1071             else {
1072                 // Transfer ownership of name pointer to symbol table.
1073                 param.name = nullptr;
1074
1075                 // Add the parameter to the HIL
1076                 paramNodes = intermediate.growAggregate(paramNodes,
1077                                                         intermediate.addSymbol(*variable, loc),
1078                                                         loc);
1079             }
1080         } else
1081             paramNodes = intermediate.growAggregate(paramNodes, intermediate.addSymbol(*param.type, loc), loc);
1082     }
1083     intermediate.setAggregateOperator(paramNodes, EOpParameters, TType(EbtVoid), loc);
1084     loopNestingLevel = 0;
1085     statementNestingLevel = 0;
1086     controlFlowNestingLevel = 0;
1087     postEntryPointReturn = false;
1088
1089     return paramNodes;
1090 }
1091
1092 //
1093 // Handle seeing function call syntax in the grammar, which could be any of
1094 //  - .length() method
1095 //  - constructor
1096 //  - a call to a built-in function mapped to an operator
1097 //  - a call to a built-in function that will remain a function call (e.g., texturing)
1098 //  - user function
1099 //  - subroutine call (not implemented yet)
1100 //
1101 TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction* function, TIntermNode* arguments)
1102 {
1103     TIntermTyped* result = nullptr;
1104
1105     if (function->getBuiltInOp() == EOpArrayLength)
1106         result = handleLengthMethod(loc, function, arguments);
1107     else if (function->getBuiltInOp() != EOpNull) {
1108         //
1109         // Then this should be a constructor.
1110         // Don't go through the symbol table for constructors.
1111         // Their parameters will be verified algorithmically.
1112         //
1113         TType type(EbtVoid);  // use this to get the type back
1114         if (! constructorError(loc, arguments, *function, function->getBuiltInOp(), type)) {
1115             //
1116             // It's a constructor, of type 'type'.
1117             //
1118             result = addConstructor(loc, arguments, type);
1119             if (result == nullptr)
1120                 error(loc, "cannot construct with these arguments", type.getCompleteString().c_str(), "");
1121         }
1122     } else {
1123         //
1124         // Find it in the symbol table.
1125         //
1126         const TFunction* fnCandidate;
1127         bool builtIn;
1128         fnCandidate = findFunction(loc, *function, builtIn);
1129         if (fnCandidate) {
1130             // This is a declared function that might map to
1131             //  - a built-in operator,
1132             //  - a built-in function not mapped to an operator, or
1133             //  - a user function.
1134
1135             // Error check for a function requiring specific extensions present.
1136             if (builtIn && fnCandidate->getNumExtensions())
1137                 requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str());
1138
1139             if (builtIn && fnCandidate->getType().contains16BitFloat())
1140                 requireFloat16Arithmetic(loc, "built-in function", "float16 types can only be in uniform block or buffer storage");
1141             if (builtIn && fnCandidate->getType().contains16BitInt())
1142                 requireInt16Arithmetic(loc, "built-in function", "(u)int16 types can only be in uniform block or buffer storage");
1143             if (builtIn && fnCandidate->getType().contains8BitInt())
1144                 requireInt8Arithmetic(loc, "built-in function", "(u)int8 types can only be in uniform block or buffer storage");
1145
1146             if (arguments != nullptr) {
1147                 // Make sure qualifications work for these arguments.
1148                 TIntermAggregate* aggregate = arguments->getAsAggregate();
1149                 for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
1150                     // At this early point there is a slight ambiguity between whether an aggregate 'arguments'
1151                     // is the single argument itself or its children are the arguments.  Only one argument
1152                     // means take 'arguments' itself as the one argument.
1153                     TIntermNode* arg = fnCandidate->getParamCount() == 1 ? arguments : (aggregate ? aggregate->getSequence()[i] : arguments);
1154                     TQualifier& formalQualifier = (*fnCandidate)[i].type->getQualifier();
1155                     if (formalQualifier.isParamOutput()) {
1156                         if (lValueErrorCheck(arguments->getLoc(), "assign", arg->getAsTyped()))
1157                             error(arguments->getLoc(), "Non-L-value cannot be passed for 'out' or 'inout' parameters.", "out", "");
1158                     }
1159                     const TType& argType = arg->getAsTyped()->getType();
1160                     const TQualifier& argQualifier = argType.getQualifier();
1161                     if (argQualifier.isMemory() && (argType.containsOpaque() || argType.isReference())) {
1162                         const char* message = "argument cannot drop memory qualifier when passed to formal parameter";
1163 #ifndef GLSLANG_WEB
1164                         if (argQualifier.volatil && ! formalQualifier.volatil)
1165                             error(arguments->getLoc(), message, "volatile", "");
1166                         if (argQualifier.coherent && ! (formalQualifier.devicecoherent || formalQualifier.coherent))
1167                             error(arguments->getLoc(), message, "coherent", "");
1168                         if (argQualifier.devicecoherent && ! (formalQualifier.devicecoherent || formalQualifier.coherent))
1169                             error(arguments->getLoc(), message, "devicecoherent", "");
1170                         if (argQualifier.queuefamilycoherent && ! (formalQualifier.queuefamilycoherent || formalQualifier.devicecoherent || formalQualifier.coherent))
1171                             error(arguments->getLoc(), message, "queuefamilycoherent", "");
1172                         if (argQualifier.workgroupcoherent && ! (formalQualifier.workgroupcoherent || formalQualifier.queuefamilycoherent || formalQualifier.devicecoherent || formalQualifier.coherent))
1173                             error(arguments->getLoc(), message, "workgroupcoherent", "");
1174                         if (argQualifier.subgroupcoherent && ! (formalQualifier.subgroupcoherent || formalQualifier.workgroupcoherent || formalQualifier.queuefamilycoherent || formalQualifier.devicecoherent || formalQualifier.coherent))
1175                             error(arguments->getLoc(), message, "subgroupcoherent", "");
1176                         if (argQualifier.readonly && ! formalQualifier.readonly)
1177                             error(arguments->getLoc(), message, "readonly", "");
1178                         if (argQualifier.writeonly && ! formalQualifier.writeonly)
1179                             error(arguments->getLoc(), message, "writeonly", "");
1180                         // Don't check 'restrict', it is different than the rest:
1181                         // "...but only restrict can be taken away from a calling argument, by a formal parameter that
1182                         // lacks the restrict qualifier..."
1183 #endif
1184                     }
1185                     if (!builtIn && argQualifier.getFormat() != formalQualifier.getFormat()) {
1186                         // we have mismatched formats, which should only be allowed if writeonly
1187                         // and at least one format is unknown
1188                         if (!formalQualifier.isWriteOnly() || (formalQualifier.getFormat() != ElfNone &&
1189                                                                   argQualifier.getFormat() != ElfNone))
1190                             error(arguments->getLoc(), "image formats must match", "format", "");
1191                     }
1192                     if (builtIn && arg->getAsTyped()->getType().contains16BitFloat())
1193                         requireFloat16Arithmetic(arguments->getLoc(), "built-in function", "float16 types can only be in uniform block or buffer storage");
1194                     if (builtIn && arg->getAsTyped()->getType().contains16BitInt())
1195                         requireInt16Arithmetic(arguments->getLoc(), "built-in function", "(u)int16 types can only be in uniform block or buffer storage");
1196                     if (builtIn && arg->getAsTyped()->getType().contains8BitInt())
1197                         requireInt8Arithmetic(arguments->getLoc(), "built-in function", "(u)int8 types can only be in uniform block or buffer storage");
1198
1199                     // TODO 4.5 functionality:  A shader will fail to compile
1200                     // if the value passed to the memargument of an atomic memory function does not correspond to a buffer or
1201                     // shared variable. It is acceptable to pass an element of an array or a single component of a vector to the
1202                     // memargument of an atomic memory function, as long as the underlying array or vector is a buffer or
1203                     // shared variable.
1204                 }
1205
1206                 // Convert 'in' arguments
1207                 addInputArgumentConversions(*fnCandidate, arguments);  // arguments may be modified if it's just a single argument node
1208             }
1209
1210             if (builtIn && fnCandidate->getBuiltInOp() != EOpNull) {
1211                 // A function call mapped to a built-in operation.
1212                 result = handleBuiltInFunctionCall(loc, arguments, *fnCandidate);
1213             } else {
1214                 // This is a function call not mapped to built-in operator.
1215                 // It could still be a built-in function, but only if PureOperatorBuiltins == false.
1216                 result = intermediate.setAggregateOperator(arguments, EOpFunctionCall, fnCandidate->getType(), loc);
1217                 TIntermAggregate* call = result->getAsAggregate();
1218                 call->setName(fnCandidate->getMangledName());
1219
1220                 // this is how we know whether the given function is a built-in function or a user-defined function
1221                 // if builtIn == false, it's a userDefined -> could be an overloaded built-in function also
1222                 // if builtIn == true, it's definitely a built-in function with EOpNull
1223                 if (! builtIn) {
1224                     call->setUserDefined();
1225                     if (symbolTable.atGlobalLevel()) {
1226                         requireProfile(loc, ~EEsProfile, "calling user function from global scope");
1227                         intermediate.addToCallGraph(infoSink, "main(", fnCandidate->getMangledName());
1228                     } else
1229                         intermediate.addToCallGraph(infoSink, currentCaller, fnCandidate->getMangledName());
1230                 }
1231
1232 #ifndef GLSLANG_WEB
1233                 if (builtIn)
1234                     nonOpBuiltInCheck(loc, *fnCandidate, *call);
1235                 else
1236 #endif
1237                     userFunctionCallCheck(loc, *call);
1238             }
1239
1240             // Convert 'out' arguments.  If it was a constant folded built-in, it won't be an aggregate anymore.
1241             // Built-ins with a single argument aren't called with an aggregate, but they also don't have an output.
1242             // Also, build the qualifier list for user function calls, which are always called with an aggregate.
1243             if (result->getAsAggregate()) {
1244                 TQualifierList& qualifierList = result->getAsAggregate()->getQualifierList();
1245                 for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
1246                     TStorageQualifier qual = (*fnCandidate)[i].type->getQualifier().storage;
1247                     qualifierList.push_back(qual);
1248                 }
1249                 result = addOutputArgumentConversions(*fnCandidate, *result->getAsAggregate());
1250             }
1251
1252             if (result->getAsTyped()->getType().isCoopMat() &&
1253                !result->getAsTyped()->getType().isParameterized()) {
1254                 assert(fnCandidate->getBuiltInOp() == EOpCooperativeMatrixMulAdd);
1255
1256                 result->setType(result->getAsAggregate()->getSequence()[2]->getAsTyped()->getType());
1257             }
1258         }
1259     }
1260
1261     // generic error recovery
1262     // TODO: simplification: localize all the error recoveries that look like this, and taking type into account to reduce cascades
1263     if (result == nullptr)
1264         result = intermediate.addConstantUnion(0.0, EbtFloat, loc);
1265
1266     return result;
1267 }
1268
1269 TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNode* arguments,
1270                                                        const TFunction& function)
1271 {
1272     checkLocation(loc, function.getBuiltInOp());
1273     TIntermTyped *result = intermediate.addBuiltInFunctionCall(loc, function.getBuiltInOp(),
1274                                                                function.getParamCount() == 1,
1275                                                                arguments, function.getType());
1276     if (obeyPrecisionQualifiers())
1277         computeBuiltinPrecisions(*result, function);
1278
1279     if (result == nullptr) {
1280         if (arguments == nullptr)
1281             error(loc, " wrong operand type", "Internal Error",
1282                                       "built in unary operator function.  Type: %s", "");
1283         else
1284             error(arguments->getLoc(), " wrong operand type", "Internal Error",
1285                                       "built in unary operator function.  Type: %s",
1286                                       static_cast<TIntermTyped*>(arguments)->getCompleteString().c_str());
1287     } else if (result->getAsOperator())
1288         builtInOpCheck(loc, function, *result->getAsOperator());
1289
1290     return result;
1291 }
1292
1293 // "The operation of a built-in function can have a different precision
1294 // qualification than the precision qualification of the resulting value.
1295 // These two precision qualifications are established as follows.
1296 //
1297 // The precision qualification of the operation of a built-in function is
1298 // based on the precision qualification of its input arguments and formal
1299 // parameters:  When a formal parameter specifies a precision qualifier,
1300 // that is used, otherwise, the precision qualification of the calling
1301 // argument is used.  The highest precision of these will be the precision
1302 // qualification of the operation of the built-in function. Generally,
1303 // this is applied across all arguments to a built-in function, with the
1304 // exceptions being:
1305 //   - bitfieldExtract and bitfieldInsert ignore the 'offset' and 'bits'
1306 //     arguments.
1307 //   - interpolateAt* functions only look at the 'interpolant' argument.
1308 //
1309 // The precision qualification of the result of a built-in function is
1310 // determined in one of the following ways:
1311 //
1312 //   - For the texture sampling, image load, and image store functions,
1313 //     the precision of the return type matches the precision of the
1314 //     sampler type
1315 //
1316 //   Otherwise:
1317 //
1318 //   - For prototypes that do not specify a resulting precision qualifier,
1319 //     the precision will be the same as the precision of the operation.
1320 //
1321 //   - For prototypes that do specify a resulting precision qualifier,
1322 //     the specified precision qualifier is the precision qualification of
1323 //     the result."
1324 //
1325 void TParseContext::computeBuiltinPrecisions(TIntermTyped& node, const TFunction& function)
1326 {
1327     TPrecisionQualifier operationPrecision = EpqNone;
1328     TPrecisionQualifier resultPrecision = EpqNone;
1329
1330     TIntermOperator* opNode = node.getAsOperator();
1331     if (opNode == nullptr)
1332         return;
1333
1334     if (TIntermUnary* unaryNode = node.getAsUnaryNode()) {
1335         operationPrecision = std::max(function[0].type->getQualifier().precision,
1336                                       unaryNode->getOperand()->getType().getQualifier().precision);
1337         if (function.getType().getBasicType() != EbtBool)
1338             resultPrecision = function.getType().getQualifier().precision == EpqNone ?
1339                                         operationPrecision :
1340                                         function.getType().getQualifier().precision;
1341     } else if (TIntermAggregate* agg = node.getAsAggregate()) {
1342         TIntermSequence& sequence = agg->getSequence();
1343         unsigned int numArgs = (unsigned int)sequence.size();
1344         switch (agg->getOp()) {
1345         case EOpBitfieldExtract:
1346             numArgs = 1;
1347             break;
1348         case EOpBitfieldInsert:
1349             numArgs = 2;
1350             break;
1351         case EOpInterpolateAtCentroid:
1352         case EOpInterpolateAtOffset:
1353         case EOpInterpolateAtSample:
1354             numArgs = 1;
1355             break;
1356         case EOpDebugPrintf:
1357             numArgs = 0;
1358             break;
1359         default:
1360             break;
1361         }
1362         // find the maximum precision from the arguments and parameters
1363         for (unsigned int arg = 0; arg < numArgs; ++arg) {
1364             operationPrecision = std::max(operationPrecision, sequence[arg]->getAsTyped()->getQualifier().precision);
1365             operationPrecision = std::max(operationPrecision, function[arg].type->getQualifier().precision);
1366         }
1367         // compute the result precision
1368         if (agg->isSampling() ||
1369             agg->getOp() == EOpImageLoad || agg->getOp() == EOpImageStore ||
1370             agg->getOp() == EOpImageLoadLod || agg->getOp() == EOpImageStoreLod)
1371             resultPrecision = sequence[0]->getAsTyped()->getQualifier().precision;
1372         else if (function.getType().getBasicType() != EbtBool)
1373             resultPrecision = function.getType().getQualifier().precision == EpqNone ?
1374                                         operationPrecision :
1375                                         function.getType().getQualifier().precision;
1376     }
1377
1378     // Propagate precision through this node and its children. That algorithm stops
1379     // when a precision is found, so start by clearing this subroot precision
1380     opNode->getQualifier().precision = EpqNone;
1381     if (operationPrecision != EpqNone) {
1382         opNode->propagatePrecision(operationPrecision);
1383         opNode->setOperationPrecision(operationPrecision);
1384     }
1385     // Now, set the result precision, which might not match
1386     opNode->getQualifier().precision = resultPrecision;
1387 }
1388
1389 TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermTyped* value)
1390 {
1391 #ifndef GLSLANG_WEB
1392     storage16BitAssignmentCheck(loc, value->getType(), "return");
1393 #endif
1394
1395     functionReturnsValue = true;
1396     if (currentFunctionType->getBasicType() == EbtVoid) {
1397         error(loc, "void function cannot return a value", "return", "");
1398         return intermediate.addBranch(EOpReturn, loc);
1399     } else if (*currentFunctionType != value->getType()) {
1400         TIntermTyped* converted = intermediate.addConversion(EOpReturn, *currentFunctionType, value);
1401         if (converted) {
1402             if (*currentFunctionType != converted->getType())
1403                 error(loc, "cannot convert return value to function return type", "return", "");
1404             if (version < 420)
1405                 warn(loc, "type conversion on return values was not explicitly allowed until version 420", "return", "");
1406             return intermediate.addBranch(EOpReturn, converted, loc);
1407         } else {
1408             error(loc, "type does not match, or is not convertible to, the function's return type", "return", "");
1409             return intermediate.addBranch(EOpReturn, value, loc);
1410         }
1411     } else
1412         return intermediate.addBranch(EOpReturn, value, loc);
1413 }
1414
1415 // See if the operation is being done in an illegal location.
1416 void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op)
1417 {
1418 #ifndef GLSLANG_WEB
1419     switch (op) {
1420     case EOpBarrier:
1421         if (language == EShLangTessControl) {
1422             if (controlFlowNestingLevel > 0)
1423                 error(loc, "tessellation control barrier() cannot be placed within flow control", "", "");
1424             if (! inMain)
1425                 error(loc, "tessellation control barrier() must be in main()", "", "");
1426             else if (postEntryPointReturn)
1427                 error(loc, "tessellation control barrier() cannot be placed after a return from main()", "", "");
1428         }
1429         break;
1430     case EOpBeginInvocationInterlock:
1431         if (language != EShLangFragment)
1432             error(loc, "beginInvocationInterlockARB() must be in a fragment shader", "", "");
1433         if (! inMain)
1434             error(loc, "beginInvocationInterlockARB() must be in main()", "", "");
1435         else if (postEntryPointReturn)
1436             error(loc, "beginInvocationInterlockARB() cannot be placed after a return from main()", "", "");
1437         if (controlFlowNestingLevel > 0)
1438             error(loc, "beginInvocationInterlockARB() cannot be placed within flow control", "", "");
1439
1440         if (beginInvocationInterlockCount > 0)
1441             error(loc, "beginInvocationInterlockARB() must only be called once", "", "");
1442         if (endInvocationInterlockCount > 0)
1443             error(loc, "beginInvocationInterlockARB() must be called before endInvocationInterlockARB()", "", "");
1444
1445         beginInvocationInterlockCount++;
1446
1447         // default to pixel_interlock_ordered
1448         if (intermediate.getInterlockOrdering() == EioNone)
1449             intermediate.setInterlockOrdering(EioPixelInterlockOrdered);
1450         break;
1451     case EOpEndInvocationInterlock:
1452         if (language != EShLangFragment)
1453             error(loc, "endInvocationInterlockARB() must be in a fragment shader", "", "");
1454         if (! inMain)
1455             error(loc, "endInvocationInterlockARB() must be in main()", "", "");
1456         else if (postEntryPointReturn)
1457             error(loc, "endInvocationInterlockARB() cannot be placed after a return from main()", "", "");
1458         if (controlFlowNestingLevel > 0)
1459             error(loc, "endInvocationInterlockARB() cannot be placed within flow control", "", "");
1460
1461         if (endInvocationInterlockCount > 0)
1462             error(loc, "endInvocationInterlockARB() must only be called once", "", "");
1463         if (beginInvocationInterlockCount == 0)
1464             error(loc, "beginInvocationInterlockARB() must be called before endInvocationInterlockARB()", "", "");
1465
1466         endInvocationInterlockCount++;
1467         break;
1468     default:
1469         break;
1470     }
1471 #endif
1472 }
1473
1474 // Finish processing object.length(). This started earlier in handleDotDereference(), where
1475 // the ".length" part was recognized and semantically checked, and finished here where the
1476 // function syntax "()" is recognized.
1477 //
1478 // Return resulting tree node.
1479 TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction* function, TIntermNode* intermNode)
1480 {
1481     int length = 0;
1482
1483     if (function->getParamCount() > 0)
1484         error(loc, "method does not accept any arguments", function->getName().c_str(), "");
1485     else {
1486         const TType& type = intermNode->getAsTyped()->getType();
1487         if (type.isArray()) {
1488             if (type.isUnsizedArray()) {
1489 #ifndef GLSLANG_WEB
1490                 if (intermNode->getAsSymbolNode() && isIoResizeArray(type)) {
1491                     // We could be between a layout declaration that gives a built-in io array implicit size and
1492                     // a user redeclaration of that array, meaning we have to substitute its implicit size here
1493                     // without actually redeclaring the array.  (It is an error to use a member before the
1494                     // redeclaration, but not an error to use the array name itself.)
1495                     const TString& name = intermNode->getAsSymbolNode()->getName();
1496                     if (name == "gl_in" || name == "gl_out" || name == "gl_MeshVerticesNV" ||
1497                         name == "gl_MeshPrimitivesNV") {
1498                         length = getIoArrayImplicitSize(type.getQualifier());
1499                     }
1500                 }
1501 #endif
1502                 if (length == 0) {
1503 #ifndef GLSLANG_WEB
1504                     if (intermNode->getAsSymbolNode() && isIoResizeArray(type))
1505                         error(loc, "", function->getName().c_str(), "array must first be sized by a redeclaration or layout qualifier");
1506                     else if (isRuntimeLength(*intermNode->getAsTyped())) {
1507                         // Create a unary op and let the back end handle it
1508                         return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt));
1509                     } else
1510 #endif
1511                         error(loc, "", function->getName().c_str(), "array must be declared with a size before using this method");
1512                 }
1513             } else if (type.getOuterArrayNode()) {
1514                 // If the array's outer size is specified by an intermediate node, it means the array's length
1515                 // was specified by a specialization constant. In such a case, we should return the node of the
1516                 // specialization constants to represent the length.
1517                 return type.getOuterArrayNode();
1518             } else
1519                 length = type.getOuterArraySize();
1520         } else if (type.isMatrix())
1521             length = type.getMatrixCols();
1522         else if (type.isVector())
1523             length = type.getVectorSize();
1524         else if (type.isCoopMat())
1525             return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt));
1526         else {
1527             // we should not get here, because earlier semantic checking should have prevented this path
1528             error(loc, ".length()", "unexpected use of .length()", "");
1529         }
1530     }
1531
1532     if (length == 0)
1533         length = 1;
1534
1535     return intermediate.addConstantUnion(length, loc);
1536 }
1537
1538 //
1539 // Add any needed implicit conversions for function-call arguments to input parameters.
1540 //
1541 void TParseContext::addInputArgumentConversions(const TFunction& function, TIntermNode*& arguments) const
1542 {
1543 #ifndef GLSLANG_WEB
1544     TIntermAggregate* aggregate = arguments->getAsAggregate();
1545
1546     // Process each argument's conversion
1547     for (int i = 0; i < function.getParamCount(); ++i) {
1548         // At this early point there is a slight ambiguity between whether an aggregate 'arguments'
1549         // is the single argument itself or its children are the arguments.  Only one argument
1550         // means take 'arguments' itself as the one argument.
1551         TIntermTyped* arg = function.getParamCount() == 1 ? arguments->getAsTyped() : (aggregate ? aggregate->getSequence()[i]->getAsTyped() : arguments->getAsTyped());
1552         if (*function[i].type != arg->getType()) {
1553             if (function[i].type->getQualifier().isParamInput() &&
1554                !function[i].type->isCoopMat()) {
1555                 // In-qualified arguments just need an extra node added above the argument to
1556                 // convert to the correct type.
1557                 arg = intermediate.addConversion(EOpFunctionCall, *function[i].type, arg);
1558                 if (arg) {
1559                     if (function.getParamCount() == 1)
1560                         arguments = arg;
1561                     else {
1562                         if (aggregate)
1563                             aggregate->getSequence()[i] = arg;
1564                         else
1565                             arguments = arg;
1566                     }
1567                 }
1568             }
1569         }
1570     }
1571 #endif
1572 }
1573
1574 //
1575 // Add any needed implicit output conversions for function-call arguments.  This
1576 // can require a new tree topology, complicated further by whether the function
1577 // has a return value.
1578 //
1579 // Returns a node of a subtree that evaluates to the return value of the function.
1580 //
1581 TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& function, TIntermAggregate& intermNode) const
1582 {
1583 #ifdef GLSLANG_WEB
1584     return &intermNode;
1585 #else
1586     TIntermSequence& arguments = intermNode.getSequence();
1587
1588     // Will there be any output conversions?
1589     bool outputConversions = false;
1590     for (int i = 0; i < function.getParamCount(); ++i) {
1591         if (*function[i].type != arguments[i]->getAsTyped()->getType() && function[i].type->getQualifier().isParamOutput()) {
1592             outputConversions = true;
1593             break;
1594         }
1595     }
1596
1597     if (! outputConversions)
1598         return &intermNode;
1599
1600     // Setup for the new tree, if needed:
1601     //
1602     // Output conversions need a different tree topology.
1603     // Out-qualified arguments need a temporary of the correct type, with the call
1604     // followed by an assignment of the temporary to the original argument:
1605     //     void: function(arg, ...)  ->        (          function(tempArg, ...), arg = tempArg, ...)
1606     //     ret = function(arg, ...)  ->  ret = (tempRet = function(tempArg, ...), arg = tempArg, ..., tempRet)
1607     // Where the "tempArg" type needs no conversion as an argument, but will convert on assignment.
1608     TIntermTyped* conversionTree = nullptr;
1609     TVariable* tempRet = nullptr;
1610     if (intermNode.getBasicType() != EbtVoid) {
1611         // do the "tempRet = function(...), " bit from above
1612         tempRet = makeInternalVariable("tempReturn", intermNode.getType());
1613         TIntermSymbol* tempRetNode = intermediate.addSymbol(*tempRet, intermNode.getLoc());
1614         conversionTree = intermediate.addAssign(EOpAssign, tempRetNode, &intermNode, intermNode.getLoc());
1615     } else
1616         conversionTree = &intermNode;
1617
1618     conversionTree = intermediate.makeAggregate(conversionTree);
1619
1620     // Process each argument's conversion
1621     for (int i = 0; i < function.getParamCount(); ++i) {
1622         if (*function[i].type != arguments[i]->getAsTyped()->getType()) {
1623             if (function[i].type->getQualifier().isParamOutput()) {
1624                 // Out-qualified arguments need to use the topology set up above.
1625                 // do the " ...(tempArg, ...), arg = tempArg" bit from above
1626                 TType paramType;
1627                 paramType.shallowCopy(*function[i].type);
1628                 if (arguments[i]->getAsTyped()->getType().isParameterized() &&
1629                     !paramType.isParameterized()) {
1630                     paramType.shallowCopy(arguments[i]->getAsTyped()->getType());
1631                     paramType.copyTypeParameters(*arguments[i]->getAsTyped()->getType().getTypeParameters());
1632                 }
1633                 TVariable* tempArg = makeInternalVariable("tempArg", paramType);
1634                 tempArg->getWritableType().getQualifier().makeTemporary();
1635                 TIntermSymbol* tempArgNode = intermediate.addSymbol(*tempArg, intermNode.getLoc());
1636                 TIntermTyped* tempAssign = intermediate.addAssign(EOpAssign, arguments[i]->getAsTyped(), tempArgNode, arguments[i]->getLoc());
1637                 conversionTree = intermediate.growAggregate(conversionTree, tempAssign, arguments[i]->getLoc());
1638                 // replace the argument with another node for the same tempArg variable
1639                 arguments[i] = intermediate.addSymbol(*tempArg, intermNode.getLoc());
1640             }
1641         }
1642     }
1643
1644     // Finalize the tree topology (see bigger comment above).
1645     if (tempRet) {
1646         // do the "..., tempRet" bit from above
1647         TIntermSymbol* tempRetNode = intermediate.addSymbol(*tempRet, intermNode.getLoc());
1648         conversionTree = intermediate.growAggregate(conversionTree, tempRetNode, intermNode.getLoc());
1649     }
1650     conversionTree = intermediate.setAggregateOperator(conversionTree, EOpComma, intermNode.getType(), intermNode.getLoc());
1651
1652     return conversionTree;
1653 #endif
1654 }
1655
1656 void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& fnCandidate, const TIntermOperator& callNode)
1657 {
1658     const TIntermSequence* argp = &callNode.getAsAggregate()->getSequence();
1659
1660     //const int gl_SemanticsRelaxed         = 0x0;
1661     const int gl_SemanticsAcquire         = 0x2;
1662     const int gl_SemanticsRelease         = 0x4;
1663     const int gl_SemanticsAcquireRelease  = 0x8;
1664     const int gl_SemanticsMakeAvailable   = 0x2000;
1665     const int gl_SemanticsMakeVisible     = 0x4000;
1666     const int gl_SemanticsVolatile        = 0x8000;
1667
1668     //const int gl_StorageSemanticsNone     = 0x0;
1669     const int gl_StorageSemanticsBuffer   = 0x40;
1670     const int gl_StorageSemanticsShared   = 0x100;
1671     const int gl_StorageSemanticsImage    = 0x800;
1672     const int gl_StorageSemanticsOutput   = 0x1000;
1673
1674
1675     unsigned int semantics = 0, storageClassSemantics = 0;
1676     unsigned int semantics2 = 0, storageClassSemantics2 = 0;
1677
1678     const TIntermTyped* arg0 = (*argp)[0]->getAsTyped();
1679     const bool isMS = arg0->getBasicType() == EbtSampler && arg0->getType().getSampler().isMultiSample();
1680
1681     // Grab the semantics and storage class semantics from the operands, based on opcode
1682     switch (callNode.getOp()) {
1683     case EOpAtomicAdd:
1684     case EOpAtomicMin:
1685     case EOpAtomicMax:
1686     case EOpAtomicAnd:
1687     case EOpAtomicOr:
1688     case EOpAtomicXor:
1689     case EOpAtomicExchange:
1690     case EOpAtomicStore:
1691         storageClassSemantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst();
1692         semantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst();
1693         break;
1694     case EOpAtomicLoad:
1695         storageClassSemantics = (*argp)[2]->getAsConstantUnion()->getConstArray()[0].getIConst();
1696         semantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst();
1697         break;
1698     case EOpAtomicCompSwap:
1699         storageClassSemantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst();
1700         semantics = (*argp)[5]->getAsConstantUnion()->getConstArray()[0].getIConst();
1701         storageClassSemantics2 = (*argp)[6]->getAsConstantUnion()->getConstArray()[0].getIConst();
1702         semantics2 = (*argp)[7]->getAsConstantUnion()->getConstArray()[0].getIConst();
1703         break;
1704
1705     case EOpImageAtomicAdd:
1706     case EOpImageAtomicMin:
1707     case EOpImageAtomicMax:
1708     case EOpImageAtomicAnd:
1709     case EOpImageAtomicOr:
1710     case EOpImageAtomicXor:
1711     case EOpImageAtomicExchange:
1712     case EOpImageAtomicStore:
1713         storageClassSemantics = (*argp)[isMS ? 5 : 4]->getAsConstantUnion()->getConstArray()[0].getIConst();
1714         semantics = (*argp)[isMS ? 6 : 5]->getAsConstantUnion()->getConstArray()[0].getIConst();
1715         break;
1716     case EOpImageAtomicLoad:
1717         storageClassSemantics = (*argp)[isMS ? 4 : 3]->getAsConstantUnion()->getConstArray()[0].getIConst();
1718         semantics = (*argp)[isMS ? 5 : 4]->getAsConstantUnion()->getConstArray()[0].getIConst();
1719         break;
1720     case EOpImageAtomicCompSwap:
1721         storageClassSemantics = (*argp)[isMS ? 6 : 5]->getAsConstantUnion()->getConstArray()[0].getIConst();
1722         semantics = (*argp)[isMS ? 7 : 6]->getAsConstantUnion()->getConstArray()[0].getIConst();
1723         storageClassSemantics2 = (*argp)[isMS ? 8 : 7]->getAsConstantUnion()->getConstArray()[0].getIConst();
1724         semantics2 = (*argp)[isMS ? 9 : 8]->getAsConstantUnion()->getConstArray()[0].getIConst();
1725         break;
1726
1727     case EOpBarrier:
1728         storageClassSemantics = (*argp)[2]->getAsConstantUnion()->getConstArray()[0].getIConst();
1729         semantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst();
1730         break;
1731     case EOpMemoryBarrier:
1732         storageClassSemantics = (*argp)[1]->getAsConstantUnion()->getConstArray()[0].getIConst();
1733         semantics = (*argp)[2]->getAsConstantUnion()->getConstArray()[0].getIConst();
1734         break;
1735     default:
1736         break;
1737     }
1738
1739     if ((semantics & gl_SemanticsAcquire) && 
1740         (callNode.getOp() == EOpAtomicStore || callNode.getOp() == EOpImageAtomicStore)) {
1741         error(loc, "gl_SemanticsAcquire must not be used with (image) atomic store",
1742               fnCandidate.getName().c_str(), "");
1743     }
1744     if ((semantics & gl_SemanticsRelease) && 
1745         (callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpImageAtomicLoad)) {
1746         error(loc, "gl_SemanticsRelease must not be used with (image) atomic load",
1747               fnCandidate.getName().c_str(), "");
1748     }
1749     if ((semantics & gl_SemanticsAcquireRelease) && 
1750         (callNode.getOp() == EOpAtomicStore || callNode.getOp() == EOpImageAtomicStore || 
1751          callNode.getOp() == EOpAtomicLoad  || callNode.getOp() == EOpImageAtomicLoad)) {
1752         error(loc, "gl_SemanticsAcquireRelease must not be used with (image) atomic load/store",
1753               fnCandidate.getName().c_str(), "");
1754     }
1755     if (((semantics | semantics2) & ~(gl_SemanticsAcquire |
1756                                       gl_SemanticsRelease |
1757                                       gl_SemanticsAcquireRelease |
1758                                       gl_SemanticsMakeAvailable |
1759                                       gl_SemanticsMakeVisible |
1760                                       gl_SemanticsVolatile))) {
1761         error(loc, "Invalid semantics value", fnCandidate.getName().c_str(), "");
1762     }
1763     if (((storageClassSemantics | storageClassSemantics2) & ~(gl_StorageSemanticsBuffer |
1764                                                               gl_StorageSemanticsShared |
1765                                                               gl_StorageSemanticsImage |
1766                                                               gl_StorageSemanticsOutput))) {
1767         error(loc, "Invalid storage class semantics value", fnCandidate.getName().c_str(), "");
1768     }
1769
1770     if (callNode.getOp() == EOpMemoryBarrier) {
1771         if (!IsPow2(semantics & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
1772             error(loc, "Semantics must include exactly one of gl_SemanticsRelease, gl_SemanticsAcquire, or "
1773                        "gl_SemanticsAcquireRelease", fnCandidate.getName().c_str(), "");
1774         }
1775     } else {
1776         if (semantics & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease)) {
1777             if (!IsPow2(semantics & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
1778                 error(loc, "Semantics must not include multiple of gl_SemanticsRelease, gl_SemanticsAcquire, or "
1779                            "gl_SemanticsAcquireRelease", fnCandidate.getName().c_str(), "");
1780             }
1781         }
1782         if (semantics2 & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease)) {
1783             if (!IsPow2(semantics2 & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
1784                 error(loc, "semUnequal must not include multiple of gl_SemanticsRelease, gl_SemanticsAcquire, or "
1785                            "gl_SemanticsAcquireRelease", fnCandidate.getName().c_str(), "");
1786             }
1787         }
1788     }
1789     if (callNode.getOp() == EOpMemoryBarrier) {
1790         if (storageClassSemantics == 0) {
1791             error(loc, "Storage class semantics must not be zero", fnCandidate.getName().c_str(), "");
1792         }
1793     }
1794     if (callNode.getOp() == EOpBarrier && semantics != 0 && storageClassSemantics == 0) {
1795         error(loc, "Storage class semantics must not be zero", fnCandidate.getName().c_str(), "");
1796     }
1797     if ((callNode.getOp() == EOpAtomicCompSwap || callNode.getOp() == EOpImageAtomicCompSwap) &&
1798         (semantics2 & (gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
1799         error(loc, "semUnequal must not be gl_SemanticsRelease or gl_SemanticsAcquireRelease",
1800               fnCandidate.getName().c_str(), "");
1801     }
1802     if ((semantics & gl_SemanticsMakeAvailable) &&
1803         !(semantics & (gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
1804         error(loc, "gl_SemanticsMakeAvailable requires gl_SemanticsRelease or gl_SemanticsAcquireRelease",
1805               fnCandidate.getName().c_str(), "");
1806     }
1807     if ((semantics & gl_SemanticsMakeVisible) &&
1808         !(semantics & (gl_SemanticsAcquire | gl_SemanticsAcquireRelease))) {
1809         error(loc, "gl_SemanticsMakeVisible requires gl_SemanticsAcquire or gl_SemanticsAcquireRelease",
1810               fnCandidate.getName().c_str(), "");
1811     }
1812     if ((semantics & gl_SemanticsVolatile) &&
1813         (callNode.getOp() == EOpMemoryBarrier || callNode.getOp() == EOpBarrier)) {
1814         error(loc, "gl_SemanticsVolatile must not be used with memoryBarrier or controlBarrier",
1815               fnCandidate.getName().c_str(), "");
1816     }
1817     if ((callNode.getOp() == EOpAtomicCompSwap || callNode.getOp() == EOpImageAtomicCompSwap) &&
1818         ((semantics ^ semantics2) & gl_SemanticsVolatile)) {
1819         error(loc, "semEqual and semUnequal must either both include gl_SemanticsVolatile or neither",
1820               fnCandidate.getName().c_str(), "");
1821     }
1822 }
1823
1824 //
1825 // Do additional checking of built-in function calls that is not caught
1826 // by normal semantic checks on argument type, extension tagging, etc.
1827 //
1828 // Assumes there has been a semantically correct match to a built-in function prototype.
1829 //
1830 void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCandidate, TIntermOperator& callNode)
1831 {
1832     // Set up convenience accessors to the argument(s).  There is almost always
1833     // multiple arguments for the cases below, but when there might be one,
1834     // check the unaryArg first.
1835     const TIntermSequence* argp = nullptr;   // confusing to use [] syntax on a pointer, so this is to help get a reference
1836     const TIntermTyped* unaryArg = nullptr;
1837     const TIntermTyped* arg0 = nullptr;
1838     if (callNode.getAsAggregate()) {
1839         argp = &callNode.getAsAggregate()->getSequence();
1840         if (argp->size() > 0)
1841             arg0 = (*argp)[0]->getAsTyped();
1842     } else {
1843         assert(callNode.getAsUnaryNode());
1844         unaryArg = callNode.getAsUnaryNode()->getOperand();
1845         arg0 = unaryArg;
1846     }
1847
1848     TString featureString;
1849     const char* feature = nullptr;
1850     switch (callNode.getOp()) {
1851 #ifndef GLSLANG_WEB
1852     case EOpTextureGather:
1853     case EOpTextureGatherOffset:
1854     case EOpTextureGatherOffsets:
1855     {
1856         // Figure out which variants are allowed by what extensions,
1857         // and what arguments must be constant for which situations.
1858
1859         featureString = fnCandidate.getName();
1860         featureString += "(...)";
1861         feature = featureString.c_str();
1862         profileRequires(loc, EEsProfile, 310, nullptr, feature);
1863         int compArg = -1;  // track which argument, if any, is the constant component argument
1864         switch (callNode.getOp()) {
1865         case EOpTextureGather:
1866             // More than two arguments needs gpu_shader5, and rectangular or shadow needs gpu_shader5,
1867             // otherwise, need GL_ARB_texture_gather.
1868             if (fnCandidate.getParamCount() > 2 || fnCandidate[0].type->getSampler().dim == EsdRect || fnCandidate[0].type->getSampler().shadow) {
1869                 profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature);
1870                 if (! fnCandidate[0].type->getSampler().shadow)
1871                     compArg = 2;
1872             } else
1873                 profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_texture_gather, feature);
1874             break;
1875         case EOpTextureGatherOffset:
1876             // GL_ARB_texture_gather is good enough for 2D non-shadow textures with no component argument
1877             if (fnCandidate[0].type->getSampler().dim == Esd2D && ! fnCandidate[0].type->getSampler().shadow && fnCandidate.getParamCount() == 3)
1878                 profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_texture_gather, feature);
1879             else
1880                 profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature);
1881             if (! (*argp)[fnCandidate[0].type->getSampler().shadow ? 3 : 2]->getAsConstantUnion())
1882                 profileRequires(loc, EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5,
1883                                 "non-constant offset argument");
1884             if (! fnCandidate[0].type->getSampler().shadow)
1885                 compArg = 3;
1886             break;
1887         case EOpTextureGatherOffsets:
1888             profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature);
1889             if (! fnCandidate[0].type->getSampler().shadow)
1890                 compArg = 3;
1891             // check for constant offsets
1892             if (! (*argp)[fnCandidate[0].type->getSampler().shadow ? 3 : 2]->getAsConstantUnion())
1893                 error(loc, "must be a compile-time constant:", feature, "offsets argument");
1894             break;
1895         default:
1896             break;
1897         }
1898
1899         if (compArg > 0 && compArg < fnCandidate.getParamCount()) {
1900             if ((*argp)[compArg]->getAsConstantUnion()) {
1901                 int value = (*argp)[compArg]->getAsConstantUnion()->getConstArray()[0].getIConst();
1902                 if (value < 0 || value > 3)
1903                     error(loc, "must be 0, 1, 2, or 3:", feature, "component argument");
1904             } else
1905                 error(loc, "must be a compile-time constant:", feature, "component argument");
1906         }
1907
1908         bool bias = false;
1909         if (callNode.getOp() == EOpTextureGather)
1910             bias = fnCandidate.getParamCount() > 3;
1911         else if (callNode.getOp() == EOpTextureGatherOffset ||
1912                  callNode.getOp() == EOpTextureGatherOffsets)
1913             bias = fnCandidate.getParamCount() > 4;
1914
1915         if (bias) {
1916             featureString = fnCandidate.getName();
1917             featureString += "with bias argument";
1918             feature = featureString.c_str();
1919             profileRequires(loc, ~EEsProfile, 450, nullptr, feature);
1920             requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature);
1921         }
1922         break;
1923     }
1924     case EOpSparseTextureGather:
1925     case EOpSparseTextureGatherOffset:
1926     case EOpSparseTextureGatherOffsets:
1927     {
1928         bool bias = false;
1929         if (callNode.getOp() == EOpSparseTextureGather)
1930             bias = fnCandidate.getParamCount() > 4;
1931         else if (callNode.getOp() == EOpSparseTextureGatherOffset ||
1932                  callNode.getOp() == EOpSparseTextureGatherOffsets)
1933             bias = fnCandidate.getParamCount() > 5;
1934
1935         if (bias) {
1936             featureString = fnCandidate.getName();
1937             featureString += "with bias argument";
1938             feature = featureString.c_str();
1939             profileRequires(loc, ~EEsProfile, 450, nullptr, feature);
1940             requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature);
1941         }
1942
1943         break;
1944     }
1945
1946     case EOpSparseTextureGatherLod:
1947     case EOpSparseTextureGatherLodOffset:
1948     case EOpSparseTextureGatherLodOffsets:
1949     {
1950         requireExtensions(loc, 1, &E_GL_ARB_sparse_texture2, fnCandidate.getName().c_str());
1951         break;
1952     }
1953
1954     case EOpSwizzleInvocations:
1955     {
1956         if (! (*argp)[1]->getAsConstantUnion())
1957             error(loc, "argument must be compile-time constant", "offset", "");
1958         else {
1959             unsigned offset[4] = {};
1960             offset[0] = (*argp)[1]->getAsConstantUnion()->getConstArray()[0].getUConst();
1961             offset[1] = (*argp)[1]->getAsConstantUnion()->getConstArray()[1].getUConst();
1962             offset[2] = (*argp)[1]->getAsConstantUnion()->getConstArray()[2].getUConst();
1963             offset[3] = (*argp)[1]->getAsConstantUnion()->getConstArray()[3].getUConst();
1964             if (offset[0] > 3 || offset[1] > 3 || offset[2] > 3 || offset[3] > 3)
1965                 error(loc, "components must be in the range [0, 3]", "offset", "");
1966         }
1967
1968         break;
1969     }
1970
1971     case EOpSwizzleInvocationsMasked:
1972     {
1973         if (! (*argp)[1]->getAsConstantUnion())
1974             error(loc, "argument must be compile-time constant", "mask", "");
1975         else {
1976             unsigned mask[3] = {};
1977             mask[0] = (*argp)[1]->getAsConstantUnion()->getConstArray()[0].getUConst();
1978             mask[1] = (*argp)[1]->getAsConstantUnion()->getConstArray()[1].getUConst();
1979             mask[2] = (*argp)[1]->getAsConstantUnion()->getConstArray()[2].getUConst();
1980             if (mask[0] > 31 || mask[1] > 31 || mask[2] > 31)
1981                 error(loc, "components must be in the range [0, 31]", "mask", "");
1982         }
1983
1984         break;
1985     }
1986 #endif
1987
1988     case EOpTextureOffset:
1989     case EOpTextureFetchOffset:
1990     case EOpTextureProjOffset:
1991     case EOpTextureLodOffset:
1992     case EOpTextureProjLodOffset:
1993     case EOpTextureGradOffset:
1994     case EOpTextureProjGradOffset:
1995     {
1996         // Handle texture-offset limits checking
1997         // Pick which argument has to hold constant offsets
1998         int arg = -1;
1999         switch (callNode.getOp()) {
2000         case EOpTextureOffset:          arg = 2;  break;
2001         case EOpTextureFetchOffset:     arg = (arg0->getType().getSampler().isRect()) ? 2 : 3; break;
2002         case EOpTextureProjOffset:      arg = 2;  break;
2003         case EOpTextureLodOffset:       arg = 3;  break;
2004         case EOpTextureProjLodOffset:   arg = 3;  break;
2005         case EOpTextureGradOffset:      arg = 4;  break;
2006         case EOpTextureProjGradOffset:  arg = 4;  break;
2007         default:
2008             assert(0);
2009             break;
2010         }
2011
2012         if (arg > 0) {
2013
2014 #ifndef GLSLANG_WEB
2015             bool f16ShadowCompare = (*argp)[1]->getAsTyped()->getBasicType() == EbtFloat16 && arg0->getType().getSampler().shadow;
2016             if (f16ShadowCompare)
2017                 ++arg;
2018 #endif
2019             if (! (*argp)[arg]->getAsConstantUnion())
2020                 error(loc, "argument must be compile-time constant", "texel offset", "");
2021             else {
2022                 const TType& type = (*argp)[arg]->getAsTyped()->getType();
2023                 for (int c = 0; c < type.getVectorSize(); ++c) {
2024                     int offset = (*argp)[arg]->getAsConstantUnion()->getConstArray()[c].getIConst();
2025                     if (offset > resources.maxProgramTexelOffset || offset < resources.minProgramTexelOffset)
2026                         error(loc, "value is out of range:", "texel offset", "[gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]");
2027                 }
2028             }
2029         }
2030
2031         break;
2032     }
2033
2034 #ifndef GLSLANG_WEB
2035     case EOpTrace:
2036         if (!(*argp)[10]->getAsConstantUnion())
2037             error(loc, "argument must be compile-time constant", "payload number", "");
2038         break;
2039     case EOpExecuteCallable:
2040         if (!(*argp)[1]->getAsConstantUnion())
2041             error(loc, "argument must be compile-time constant", "callable data number", "");
2042         break;
2043
2044     case EOpTextureQuerySamples:
2045     case EOpImageQuerySamples:
2046         // GL_ARB_shader_texture_image_samples
2047         profileRequires(loc, ~EEsProfile, 450, E_GL_ARB_shader_texture_image_samples, "textureSamples and imageSamples");
2048         break;
2049
2050     case EOpImageAtomicAdd:
2051     case EOpImageAtomicMin:
2052     case EOpImageAtomicMax:
2053     case EOpImageAtomicAnd:
2054     case EOpImageAtomicOr:
2055     case EOpImageAtomicXor:
2056     case EOpImageAtomicExchange:
2057     case EOpImageAtomicCompSwap:
2058     case EOpImageAtomicLoad:
2059     case EOpImageAtomicStore:
2060     {
2061         // Make sure the image types have the correct layout() format and correct argument types
2062         const TType& imageType = arg0->getType();
2063         if (imageType.getSampler().type == EbtInt || imageType.getSampler().type == EbtUint) {
2064             if (imageType.getQualifier().getFormat() != ElfR32i && imageType.getQualifier().getFormat() != ElfR32ui)
2065                 error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), "");
2066         } else {
2067             if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0)
2068                 error(loc, "only supported on integer images", fnCandidate.getName().c_str(), "");
2069             else if (imageType.getQualifier().getFormat() != ElfR32f && isEsProfile())
2070                 error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), "");
2071         }
2072
2073         const size_t maxArgs = imageType.getSampler().isMultiSample() ? 5 : 4;
2074         if (argp->size() > maxArgs) {
2075             requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str());
2076             memorySemanticsCheck(loc, fnCandidate, callNode);
2077         }
2078
2079         break;
2080     }
2081
2082     case EOpAtomicAdd:
2083     case EOpAtomicMin:
2084     case EOpAtomicMax:
2085     case EOpAtomicAnd:
2086     case EOpAtomicOr:
2087     case EOpAtomicXor:
2088     case EOpAtomicExchange:
2089     case EOpAtomicCompSwap:
2090     case EOpAtomicLoad:
2091     case EOpAtomicStore:
2092     {
2093         if (argp->size() > 3) {
2094             requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str());
2095             memorySemanticsCheck(loc, fnCandidate, callNode);
2096         } else if (arg0->getType().getBasicType() == EbtInt64 || arg0->getType().getBasicType() == EbtUint64) {
2097             const char* const extensions[2] = { E_GL_NV_shader_atomic_int64,
2098                                                 E_GL_EXT_shader_atomic_int64 };
2099             requireExtensions(loc, 2, extensions, fnCandidate.getName().c_str());
2100         }
2101         break;
2102     }
2103
2104     case EOpInterpolateAtCentroid:
2105     case EOpInterpolateAtSample:
2106     case EOpInterpolateAtOffset:
2107     case EOpInterpolateAtVertex:
2108         // Make sure the first argument is an interpolant, or an array element of an interpolant
2109         if (arg0->getType().getQualifier().storage != EvqVaryingIn) {
2110             // It might still be an array element.
2111             //
2112             // We could check more, but the semantics of the first argument are already met; the
2113             // only way to turn an array into a float/vec* is array dereference and swizzle.
2114             //
2115             // ES and desktop 4.3 and earlier:  swizzles may not be used
2116             // desktop 4.4 and later: swizzles may be used
2117             bool swizzleOkay = (!isEsProfile()) && (version >= 440);
2118             const TIntermTyped* base = TIntermediate::findLValueBase(arg0, swizzleOkay);
2119             if (base == nullptr || base->getType().getQualifier().storage != EvqVaryingIn)
2120                 error(loc, "first argument must be an interpolant, or interpolant-array element", fnCandidate.getName().c_str(), "");
2121         }
2122
2123         if (callNode.getOp() == EOpInterpolateAtVertex) {
2124             if (!arg0->getType().getQualifier().isExplicitInterpolation())
2125                 error(loc, "argument must be qualified as __explicitInterpAMD in", "interpolant", "");
2126             else {
2127                 if (! (*argp)[1]->getAsConstantUnion())
2128                     error(loc, "argument must be compile-time constant", "vertex index", "");
2129                 else {
2130                     unsigned vertexIdx = (*argp)[1]->getAsConstantUnion()->getConstArray()[0].getUConst();
2131                     if (vertexIdx > 2)
2132                         error(loc, "must be in the range [0, 2]", "vertex index", "");
2133                 }
2134             }
2135         }
2136         break;
2137
2138     case EOpEmitStreamVertex:
2139     case EOpEndStreamPrimitive:
2140         intermediate.setMultiStream();
2141         break;
2142
2143     case EOpSubgroupClusteredAdd:
2144     case EOpSubgroupClusteredMul:
2145     case EOpSubgroupClusteredMin:
2146     case EOpSubgroupClusteredMax:
2147     case EOpSubgroupClusteredAnd:
2148     case EOpSubgroupClusteredOr:
2149     case EOpSubgroupClusteredXor:
2150         // The <clusterSize> as used in the subgroupClustered<op>() operations must be:
2151         // - An integral constant expression.
2152         // - At least 1.
2153         // - A power of 2.
2154         if ((*argp)[1]->getAsConstantUnion() == nullptr)
2155             error(loc, "argument must be compile-time constant", "cluster size", "");
2156         else {
2157             int size = (*argp)[1]->getAsConstantUnion()->getConstArray()[0].getIConst();
2158             if (size < 1)
2159                 error(loc, "argument must be at least 1", "cluster size", "");
2160             else if (!IsPow2(size))
2161                 error(loc, "argument must be a power of 2", "cluster size", "");
2162         }
2163         break;
2164
2165     case EOpSubgroupBroadcast:
2166     case EOpSubgroupQuadBroadcast:
2167         if (spvVersion.spv < EShTargetSpv_1_5) {
2168             // <id> must be an integral constant expression.
2169             if ((*argp)[1]->getAsConstantUnion() == nullptr)
2170                 error(loc, "argument must be compile-time constant", "id", "");
2171         }
2172         break;
2173
2174     case EOpBarrier:
2175     case EOpMemoryBarrier:
2176         if (argp->size() > 0) {
2177             requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str());
2178             memorySemanticsCheck(loc, fnCandidate, callNode);
2179         }
2180         break;
2181 #endif
2182
2183     default:
2184         break;
2185     }
2186
2187     // Texture operations on texture objects (aside from texelFetch on a
2188     // textureBuffer) require EXT_samplerless_texture_functions.
2189     switch (callNode.getOp()) {
2190     case EOpTextureQuerySize:
2191     case EOpTextureQueryLevels:
2192     case EOpTextureQuerySamples:
2193     case EOpTextureFetch:
2194     case EOpTextureFetchOffset:
2195     {
2196         const TSampler& sampler = fnCandidate[0].type->getSampler();
2197
2198         const bool isTexture = sampler.isTexture() && !sampler.isCombined();
2199         const bool isBuffer = sampler.isBuffer();
2200         const bool isFetch = callNode.getOp() == EOpTextureFetch || callNode.getOp() == EOpTextureFetchOffset;
2201
2202         if (isTexture && (!isBuffer || !isFetch))
2203             requireExtensions(loc, 1, &E_GL_EXT_samplerless_texture_functions, fnCandidate.getName().c_str());
2204
2205         break;
2206     }
2207
2208     default:
2209         break;
2210     }
2211
2212     if (callNode.isSubgroup()) {
2213         // these require SPIR-V 1.3
2214         if (spvVersion.spv > 0 && spvVersion.spv < EShTargetSpv_1_3)
2215             error(loc, "requires SPIR-V 1.3", "subgroup op", "");
2216
2217         // Check that if extended types are being used that the correct extensions are enabled.
2218         if (arg0 != nullptr) {
2219             const TType& type = arg0->getType();
2220             switch (type.getBasicType()) {
2221             default:
2222                 break;
2223             case EbtInt8:
2224             case EbtUint8:
2225                 requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int8, type.getCompleteString().c_str());
2226                 break;
2227             case EbtInt16:
2228             case EbtUint16:
2229                 requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int16, type.getCompleteString().c_str());
2230                 break;
2231             case EbtInt64:
2232             case EbtUint64:
2233                 requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int64, type.getCompleteString().c_str());
2234                 break;
2235             case EbtFloat16:
2236                 requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_float16, type.getCompleteString().c_str());
2237                 break;
2238             }
2239         }
2240     }
2241 }
2242
2243 #ifndef GLSLANG_WEB
2244
2245 extern bool PureOperatorBuiltins;
2246
2247 // Deprecated!  Use PureOperatorBuiltins == true instead, in which case this
2248 // functionality is handled in builtInOpCheck() instead of here.
2249 //
2250 // Do additional checking of built-in function calls that were not mapped
2251 // to built-in operations (e.g., texturing functions).
2252 //
2253 // Assumes there has been a semantically correct match to a built-in function.
2254 //
2255 void TParseContext::nonOpBuiltInCheck(const TSourceLoc& loc, const TFunction& fnCandidate, TIntermAggregate& callNode)
2256 {
2257     // Further maintenance of this function is deprecated, because the "correct"
2258     // future-oriented design is to not have to do string compares on function names.
2259
2260     // If PureOperatorBuiltins == true, then all built-ins should be mapped
2261     // to a TOperator, and this function would then never get called.
2262
2263     assert(PureOperatorBuiltins == false);
2264
2265     // built-in texturing functions get their return value precision from the precision of the sampler
2266     if (fnCandidate.getType().getQualifier().precision == EpqNone &&
2267         fnCandidate.getParamCount() > 0 && fnCandidate[0].type->getBasicType() == EbtSampler)
2268         callNode.getQualifier().precision = callNode.getSequence()[0]->getAsTyped()->getQualifier().precision;
2269
2270     if (fnCandidate.getName().compare(0, 7, "texture") == 0) {
2271         if (fnCandidate.getName().compare(0, 13, "textureGather") == 0) {
2272             TString featureString = fnCandidate.getName() + "(...)";
2273             const char* feature = featureString.c_str();
2274             profileRequires(loc, EEsProfile, 310, nullptr, feature);
2275
2276             int compArg = -1;  // track which argument, if any, is the constant component argument
2277             if (fnCandidate.getName().compare("textureGatherOffset") == 0) {
2278                 // GL_ARB_texture_gather is good enough for 2D non-shadow textures with no component argument
2279                 if (fnCandidate[0].type->getSampler().dim == Esd2D && ! fnCandidate[0].type->getSampler().shadow && fnCandidate.getParamCount() == 3)
2280                     profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_texture_gather, feature);
2281                 else
2282                     profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature);
2283                 int offsetArg = fnCandidate[0].type->getSampler().shadow ? 3 : 2;
2284                 if (! callNode.getSequence()[offsetArg]->getAsConstantUnion())
2285                     profileRequires(loc, EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5,
2286                                     "non-constant offset argument");
2287                 if (! fnCandidate[0].type->getSampler().shadow)
2288                     compArg = 3;
2289             } else if (fnCandidate.getName().compare("textureGatherOffsets") == 0) {
2290                 profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature);
2291                 if (! fnCandidate[0].type->getSampler().shadow)
2292                     compArg = 3;
2293                 // check for constant offsets
2294                 int offsetArg = fnCandidate[0].type->getSampler().shadow ? 3 : 2;
2295                 if (! callNode.getSequence()[offsetArg]->getAsConstantUnion())
2296                     error(loc, "must be a compile-time constant:", feature, "offsets argument");
2297             } else if (fnCandidate.getName().compare("textureGather") == 0) {
2298                 // More than two arguments needs gpu_shader5, and rectangular or shadow needs gpu_shader5,
2299                 // otherwise, need GL_ARB_texture_gather.
2300                 if (fnCandidate.getParamCount() > 2 || fnCandidate[0].type->getSampler().dim == EsdRect || fnCandidate[0].type->getSampler().shadow) {
2301                     profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature);
2302                     if (! fnCandidate[0].type->getSampler().shadow)
2303                         compArg = 2;
2304                 } else
2305                     profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_texture_gather, feature);
2306             }
2307
2308             if (compArg > 0 && compArg < fnCandidate.getParamCount()) {
2309                 if (callNode.getSequence()[compArg]->getAsConstantUnion()) {
2310                     int value = callNode.getSequence()[compArg]->getAsConstantUnion()->getConstArray()[0].getIConst();
2311                     if (value < 0 || value > 3)
2312                         error(loc, "must be 0, 1, 2, or 3:", feature, "component argument");
2313                 } else
2314                     error(loc, "must be a compile-time constant:", feature, "component argument");
2315             }
2316         } else {
2317             // this is only for functions not starting "textureGather"...
2318             if (fnCandidate.getName().find("Offset") != TString::npos) {
2319
2320                 // Handle texture-offset limits checking
2321                 int arg = -1;
2322                 if (fnCandidate.getName().compare("textureOffset") == 0)
2323                     arg = 2;
2324                 else if (fnCandidate.getName().compare("texelFetchOffset") == 0)
2325                     arg = 3;
2326                 else if (fnCandidate.getName().compare("textureProjOffset") == 0)
2327                     arg = 2;
2328                 else if (fnCandidate.getName().compare("textureLodOffset") == 0)
2329                     arg = 3;
2330                 else if (fnCandidate.getName().compare("textureProjLodOffset") == 0)
2331                     arg = 3;
2332                 else if (fnCandidate.getName().compare("textureGradOffset") == 0)
2333                     arg = 4;
2334                 else if (fnCandidate.getName().compare("textureProjGradOffset") == 0)
2335                     arg = 4;
2336
2337                 if (arg > 0) {
2338                     if (! callNode.getSequence()[arg]->getAsConstantUnion())
2339                         error(loc, "argument must be compile-time constant", "texel offset", "");
2340                     else {
2341                         const TType& type = callNode.getSequence()[arg]->getAsTyped()->getType();
2342                         for (int c = 0; c < type.getVectorSize(); ++c) {
2343                             int offset = callNode.getSequence()[arg]->getAsConstantUnion()->getConstArray()[c].getIConst();
2344                             if (offset > resources.maxProgramTexelOffset || offset < resources.minProgramTexelOffset)
2345                                 error(loc, "value is out of range:", "texel offset", "[gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]");
2346                         }
2347                     }
2348                 }
2349             }
2350         }
2351     }
2352
2353     // GL_ARB_shader_texture_image_samples
2354     if (fnCandidate.getName().compare(0, 14, "textureSamples") == 0 || fnCandidate.getName().compare(0, 12, "imageSamples") == 0)
2355         profileRequires(loc, ~EEsProfile, 450, E_GL_ARB_shader_texture_image_samples, "textureSamples and imageSamples");
2356
2357     if (fnCandidate.getName().compare(0, 11, "imageAtomic") == 0) {
2358         const TType& imageType = callNode.getSequence()[0]->getAsTyped()->getType();
2359         if (imageType.getSampler().type == EbtInt || imageType.getSampler().type == EbtUint) {
2360             if (imageType.getQualifier().getFormat() != ElfR32i && imageType.getQualifier().getFormat() != ElfR32ui)
2361                 error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), "");
2362         } else {
2363             if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0)
2364                 error(loc, "only supported on integer images", fnCandidate.getName().c_str(), "");
2365             else if (imageType.getQualifier().getFormat() != ElfR32f && isEsProfile())
2366                 error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), "");
2367         }
2368     }
2369 }
2370
2371 #endif
2372
2373 //
2374 // Do any extra checking for a user function call.
2375 //
2376 void TParseContext::userFunctionCallCheck(const TSourceLoc& loc, TIntermAggregate& callNode)
2377 {
2378     TIntermSequence& arguments = callNode.getSequence();
2379
2380     for (int i = 0; i < (int)arguments.size(); ++i)
2381         samplerConstructorLocationCheck(loc, "call argument", arguments[i]);
2382 }
2383
2384 //
2385 // Emit an error if this is a sampler constructor
2386 //
2387 void TParseContext::samplerConstructorLocationCheck(const TSourceLoc& loc, const char* token, TIntermNode* node)
2388 {
2389     if (node->getAsOperator() && node->getAsOperator()->getOp() == EOpConstructTextureSampler)
2390         error(loc, "sampler constructor must appear at point of use", token, "");
2391 }
2392
2393 //
2394 // Handle seeing a built-in constructor in a grammar production.
2395 //
2396 TFunction* TParseContext::handleConstructorCall(const TSourceLoc& loc, const TPublicType& publicType)
2397 {
2398     TType type(publicType);
2399     type.getQualifier().precision = EpqNone;
2400
2401     if (type.isArray()) {
2402         profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed constructor");
2403         profileRequires(loc, EEsProfile, 300, nullptr, "arrayed constructor");
2404     }
2405
2406     TOperator op = intermediate.mapTypeToConstructorOp(type);
2407
2408     if (op == EOpNull) {
2409         error(loc, "cannot construct this type", type.getBasicString(), "");
2410         op = EOpConstructFloat;
2411         TType errorType(EbtFloat);
2412         type.shallowCopy(errorType);
2413     }
2414
2415     TString empty("");
2416
2417     return new TFunction(&empty, type, op);
2418 }
2419
2420 // Handle seeing a precision qualifier in the grammar.
2421 void TParseContext::handlePrecisionQualifier(const TSourceLoc& /*loc*/, TQualifier& qualifier, TPrecisionQualifier precision)
2422 {
2423     if (obeyPrecisionQualifiers())
2424         qualifier.precision = precision;
2425 }
2426
2427 // Check for messages to give on seeing a precision qualifier used in a
2428 // declaration in the grammar.
2429 void TParseContext::checkPrecisionQualifier(const TSourceLoc& loc, TPrecisionQualifier)
2430 {
2431     if (precisionManager.shouldWarnAboutDefaults()) {
2432         warn(loc, "all default precisions are highp; use precision statements to quiet warning, e.g.:\n"
2433                   "         \"precision mediump int; precision highp float;\"", "", "");
2434         precisionManager.defaultWarningGiven();
2435     }
2436 }
2437
2438 //
2439 // Same error message for all places assignments don't work.
2440 //
2441 void TParseContext::assignError(const TSourceLoc& loc, const char* op, TString left, TString right)
2442 {
2443     error(loc, "", op, "cannot convert from '%s' to '%s'",
2444           right.c_str(), left.c_str());
2445 }
2446
2447 //
2448 // Same error message for all places unary operations don't work.
2449 //
2450 void TParseContext::unaryOpError(const TSourceLoc& loc, const char* op, TString operand)
2451 {
2452    error(loc, " wrong operand type", op,
2453           "no operation '%s' exists that takes an operand of type %s (or there is no acceptable conversion)",
2454           op, operand.c_str());
2455 }
2456
2457 //
2458 // Same error message for all binary operations don't work.
2459 //
2460 void TParseContext::binaryOpError(const TSourceLoc& loc, const char* op, TString left, TString right)
2461 {
2462     error(loc, " wrong operand types:", op,
2463             "no operation '%s' exists that takes a left-hand operand of type '%s' and "
2464             "a right operand of type '%s' (or there is no acceptable conversion)",
2465             op, left.c_str(), right.c_str());
2466 }
2467
2468 //
2469 // A basic type of EbtVoid is a key that the name string was seen in the source, but
2470 // it was not found as a variable in the symbol table.  If so, give the error
2471 // message and insert a dummy variable in the symbol table to prevent future errors.
2472 //
2473 void TParseContext::variableCheck(TIntermTyped*& nodePtr)
2474 {
2475     TIntermSymbol* symbol = nodePtr->getAsSymbolNode();
2476     if (! symbol)
2477         return;
2478
2479     if (symbol->getType().getBasicType() == EbtVoid) {
2480         const char *extraInfoFormat = "";
2481         if (spvVersion.vulkan != 0 && symbol->getName() == "gl_VertexID") {
2482           extraInfoFormat = "(Did you mean gl_VertexIndex?)";
2483         } else if (spvVersion.vulkan != 0 && symbol->getName() == "gl_InstanceID") {
2484           extraInfoFormat = "(Did you mean gl_InstanceIndex?)";
2485         }
2486         error(symbol->getLoc(), "undeclared identifier", symbol->getName().c_str(), extraInfoFormat);
2487
2488         // Add to symbol table to prevent future error messages on the same name
2489         if (symbol->getName().size() > 0) {
2490             TVariable* fakeVariable = new TVariable(&symbol->getName(), TType(EbtFloat));
2491             symbolTable.insert(*fakeVariable);
2492
2493             // substitute a symbol node for this new variable
2494             nodePtr = intermediate.addSymbol(*fakeVariable, symbol->getLoc());
2495         }
2496     } else {
2497         switch (symbol->getQualifier().storage) {
2498         case EvqPointCoord:
2499             profileRequires(symbol->getLoc(), ENoProfile, 120, nullptr, "gl_PointCoord");
2500             break;
2501         default: break; // some compilers want this
2502         }
2503     }
2504 }
2505
2506 //
2507 // Both test and if necessary, spit out an error, to see if the node is really
2508 // an l-value that can be operated on this way.
2509 //
2510 // Returns true if there was an error.
2511 //
2512 bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node)
2513 {
2514     TIntermBinary* binaryNode = node->getAsBinaryNode();
2515
2516     if (binaryNode) {
2517         bool errorReturn = false;
2518
2519         switch(binaryNode->getOp()) {
2520 #ifndef GLSLANG_WEB
2521         case EOpIndexDirect:
2522         case EOpIndexIndirect:
2523             // ...  tessellation control shader ...
2524             // If a per-vertex output variable is used as an l-value, it is a
2525             // compile-time or link-time error if the expression indicating the
2526             // vertex index is not the identifier gl_InvocationID.
2527             if (language == EShLangTessControl) {
2528                 const TType& leftType = binaryNode->getLeft()->getType();
2529                 if (leftType.getQualifier().storage == EvqVaryingOut && ! leftType.getQualifier().patch && binaryNode->getLeft()->getAsSymbolNode()) {
2530                     // we have a per-vertex output
2531                     const TIntermSymbol* rightSymbol = binaryNode->getRight()->getAsSymbolNode();
2532                     if (! rightSymbol || rightSymbol->getQualifier().builtIn != EbvInvocationId)
2533                         error(loc, "tessellation-control per-vertex output l-value must be indexed with gl_InvocationID", "[]", "");
2534                 }
2535             }
2536             break; // left node is checked by base class
2537 #endif
2538         case EOpVectorSwizzle:
2539             errorReturn = lValueErrorCheck(loc, op, binaryNode->getLeft());
2540             if (!errorReturn) {
2541                 int offset[4] = {0,0,0,0};
2542
2543                 TIntermTyped* rightNode = binaryNode->getRight();
2544                 TIntermAggregate *aggrNode = rightNode->getAsAggregate();
2545
2546                 for (TIntermSequence::iterator p = aggrNode->getSequence().begin();
2547                                                p != aggrNode->getSequence().end(); p++) {
2548                     int value = (*p)->getAsTyped()->getAsConstantUnion()->getConstArray()[0].getIConst();
2549                     offset[value]++;
2550                     if (offset[value] > 1) {
2551                         error(loc, " l-value of swizzle cannot have duplicate components", op, "", "");
2552
2553                         return true;
2554                     }
2555                 }
2556             }
2557
2558             return errorReturn;
2559         default:
2560             break;
2561         }
2562
2563         if (errorReturn) {
2564             error(loc, " l-value required", op, "", "");
2565             return true;
2566         }
2567     }
2568
2569     if (binaryNode && binaryNode->getOp() == EOpIndexDirectStruct && binaryNode->getLeft()->isReference())
2570         return false;
2571
2572     // Let the base class check errors
2573     if (TParseContextBase::lValueErrorCheck(loc, op, node))
2574         return true;
2575
2576     const char* symbol = nullptr;
2577     TIntermSymbol* symNode = node->getAsSymbolNode();
2578     if (symNode != nullptr)
2579         symbol = symNode->getName().c_str();
2580
2581     const char* message = nullptr;
2582     switch (node->getQualifier().storage) {
2583     case EvqVaryingIn:      message = "can't modify shader input";   break;
2584     case EvqInstanceId:     message = "can't modify gl_InstanceID";  break;
2585     case EvqVertexId:       message = "can't modify gl_VertexID";    break;
2586     case EvqFace:           message = "can't modify gl_FrontFace";   break;
2587     case EvqFragCoord:      message = "can't modify gl_FragCoord";   break;
2588     case EvqPointCoord:     message = "can't modify gl_PointCoord";  break;
2589     case EvqFragDepth:
2590         intermediate.setDepthReplacing();
2591         // "In addition, it is an error to statically write to gl_FragDepth in the fragment shader."
2592         if (isEsProfile() && intermediate.getEarlyFragmentTests())
2593             message = "can't modify gl_FragDepth if using early_fragment_tests";
2594         break;
2595
2596     default:
2597         break;
2598     }
2599
2600     if (message == nullptr && binaryNode == nullptr && symNode == nullptr) {
2601         error(loc, " l-value required", op, "", "");
2602
2603         return true;
2604     }
2605
2606     //
2607     // Everything else is okay, no error.
2608     //
2609     if (message == nullptr)
2610         return false;
2611
2612     //
2613     // If we get here, we have an error and a message.
2614     //
2615     if (symNode)
2616         error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message);
2617     else
2618         error(loc, " l-value required", op, "(%s)", message);
2619
2620     return true;
2621 }
2622
2623 // Test for and give an error if the node can't be read from.
2624 void TParseContext::rValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node)
2625 {
2626     // Let the base class check errors
2627     TParseContextBase::rValueErrorCheck(loc, op, node);
2628
2629     TIntermSymbol* symNode = node->getAsSymbolNode();
2630     if (!(symNode && symNode->getQualifier().isWriteOnly())) // base class checks
2631         if (symNode && symNode->getQualifier().isExplicitInterpolation())
2632             error(loc, "can't read from explicitly-interpolated object: ", op, symNode->getName().c_str());
2633 }
2634
2635 //
2636 // Both test, and if necessary spit out an error, to see if the node is really
2637 // a constant.
2638 //
2639 void TParseContext::constantValueCheck(TIntermTyped* node, const char* token)
2640 {
2641     if (! node->getQualifier().isConstant())
2642         error(node->getLoc(), "constant expression required", token, "");
2643 }
2644
2645 //
2646 // Both test, and if necessary spit out an error, to see if the node is really
2647 // an integer.
2648 //
2649 void TParseContext::integerCheck(const TIntermTyped* node, const char* token)
2650 {
2651     if ((node->getBasicType() == EbtInt || node->getBasicType() == EbtUint) && node->isScalar())
2652         return;
2653
2654     error(node->getLoc(), "scalar integer expression required", token, "");
2655 }
2656
2657 //
2658 // Both test, and if necessary spit out an error, to see if we are currently
2659 // globally scoped.
2660 //
2661 void TParseContext::globalCheck(const TSourceLoc& loc, const char* token)
2662 {
2663     if (! symbolTable.atGlobalLevel())
2664         error(loc, "not allowed in nested scope", token, "");
2665 }
2666
2667 //
2668 // Reserved errors for GLSL.
2669 //
2670 void TParseContext::reservedErrorCheck(const TSourceLoc& loc, const TString& identifier)
2671 {
2672     // "Identifiers starting with "gl_" are reserved for use by OpenGL, and may not be
2673     // declared in a shader; this results in a compile-time error."
2674     if (! symbolTable.atBuiltInLevel()) {
2675         if (builtInName(identifier))
2676             error(loc, "identifiers starting with \"gl_\" are reserved", identifier.c_str(), "");
2677
2678         // "__" are not supposed to be an error.  ES 300 (and desktop) added the clarification:
2679         // "In addition, all identifiers containing two consecutive underscores (__) are
2680         // reserved; using such a name does not itself result in an error, but may result
2681         // in undefined behavior."
2682         // however, before that, ES tests required an error.
2683         if (identifier.find("__") != TString::npos) {
2684             if (isEsProfile() && version < 300)
2685                 error(loc, "identifiers containing consecutive underscores (\"__\") are reserved, and an error if version < 300", identifier.c_str(), "");
2686             else
2687                 warn(loc, "identifiers containing consecutive underscores (\"__\") are reserved", identifier.c_str(), "");
2688         }
2689     }
2690 }
2691
2692 //
2693 // Reserved errors for the preprocessor.
2694 //
2695 void TParseContext::reservedPpErrorCheck(const TSourceLoc& loc, const char* identifier, const char* op)
2696 {
2697     // "__" are not supposed to be an error.  ES 300 (and desktop) added the clarification:
2698     // "All macro names containing two consecutive underscores ( __ ) are reserved;
2699     // defining such a name does not itself result in an error, but may result in
2700     // undefined behavior.  All macro names prefixed with "GL_" ("GL" followed by a
2701     // single underscore) are also reserved, and defining such a name results in a
2702     // compile-time error."
2703     // however, before that, ES tests required an error.
2704     if (strncmp(identifier, "GL_", 3) == 0)
2705         ppError(loc, "names beginning with \"GL_\" can't be (un)defined:", op,  identifier);
2706     else if (strncmp(identifier, "defined", 8) == 0)
2707         ppError(loc, "\"defined\" can't be (un)defined:", op,  identifier);
2708     else if (strstr(identifier, "__") != 0) {
2709         if (isEsProfile() && version >= 300 &&
2710             (strcmp(identifier, "__LINE__") == 0 ||
2711              strcmp(identifier, "__FILE__") == 0 ||
2712              strcmp(identifier, "__VERSION__") == 0))
2713             ppError(loc, "predefined names can't be (un)defined:", op,  identifier);
2714         else {
2715             if (isEsProfile() && version < 300)
2716                 ppError(loc, "names containing consecutive underscores are reserved, and an error if version < 300:", op, identifier);
2717             else
2718                 ppWarn(loc, "names containing consecutive underscores are reserved:", op, identifier);
2719         }
2720     }
2721 }
2722
2723 //
2724 // See if this version/profile allows use of the line-continuation character '\'.
2725 //
2726 // Returns true if a line continuation should be done.
2727 //
2728 bool TParseContext::lineContinuationCheck(const TSourceLoc& loc, bool endOfComment)
2729 {
2730 #ifdef GLSLANG_WEB
2731     return true;
2732 #endif
2733
2734     const char* message = "line continuation";
2735
2736     bool lineContinuationAllowed = (isEsProfile() && version >= 300) ||
2737                                    (!isEsProfile() && (version >= 420 || extensionTurnedOn(E_GL_ARB_shading_language_420pack)));
2738
2739     if (endOfComment) {
2740         if (lineContinuationAllowed)
2741             warn(loc, "used at end of comment; the following line is still part of the comment", message, "");
2742         else
2743             warn(loc, "used at end of comment, but this version does not provide line continuation", message, "");
2744
2745         return lineContinuationAllowed;
2746     }
2747
2748     if (relaxedErrors()) {
2749         if (! lineContinuationAllowed)
2750             warn(loc, "not allowed in this version", message, "");
2751         return true;
2752     } else {
2753         profileRequires(loc, EEsProfile, 300, nullptr, message);
2754         profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, message);
2755     }
2756
2757     return lineContinuationAllowed;
2758 }
2759
2760 bool TParseContext::builtInName(const TString& identifier)
2761 {
2762     return identifier.compare(0, 3, "gl_") == 0;
2763 }
2764
2765 //
2766 // Make sure there is enough data and not too many arguments provided to the
2767 // constructor to build something of the type of the constructor.  Also returns
2768 // the type of the constructor.
2769 //
2770 // Part of establishing type is establishing specialization-constness.
2771 // We don't yet know "top down" whether type is a specialization constant,
2772 // but a const constructor can becomes a specialization constant if any of
2773 // its children are, subject to KHR_vulkan_glsl rules:
2774 //
2775 //     - int(), uint(), and bool() constructors for type conversions
2776 //       from any of the following types to any of the following types:
2777 //         * int
2778 //         * uint
2779 //         * bool
2780 //     - vector versions of the above conversion constructors
2781 //
2782 // Returns true if there was an error in construction.
2783 //
2784 bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, TFunction& function, TOperator op, TType& type)
2785 {
2786     // See if the constructor does not establish the main type, only requalifies
2787     // it, in which case the type comes from the argument instead of from the
2788     // constructor function.
2789     switch (op) {
2790 #ifndef GLSLANG_WEB
2791     case EOpConstructNonuniform:
2792         if (node != nullptr && node->getAsTyped() != nullptr) {
2793             type.shallowCopy(node->getAsTyped()->getType());
2794             type.getQualifier().makeTemporary();
2795             type.getQualifier().nonUniform = true;
2796         }
2797         break;
2798 #endif
2799     default:
2800         type.shallowCopy(function.getType());
2801         break;
2802     }
2803
2804     // See if it's a matrix
2805     bool constructingMatrix = false;
2806     switch (op) {
2807     case EOpConstructTextureSampler:
2808         return constructorTextureSamplerError(loc, function);
2809     case EOpConstructMat2x2:
2810     case EOpConstructMat2x3:
2811     case EOpConstructMat2x4:
2812     case EOpConstructMat3x2:
2813     case EOpConstructMat3x3:
2814     case EOpConstructMat3x4:
2815     case EOpConstructMat4x2:
2816     case EOpConstructMat4x3:
2817     case EOpConstructMat4x4:
2818 #ifndef GLSLANG_WEB
2819     case EOpConstructDMat2x2:
2820     case EOpConstructDMat2x3:
2821     case EOpConstructDMat2x4:
2822     case EOpConstructDMat3x2:
2823     case EOpConstructDMat3x3:
2824     case EOpConstructDMat3x4:
2825     case EOpConstructDMat4x2:
2826     case EOpConstructDMat4x3:
2827     case EOpConstructDMat4x4:
2828     case EOpConstructF16Mat2x2:
2829     case EOpConstructF16Mat2x3:
2830     case EOpConstructF16Mat2x4:
2831     case EOpConstructF16Mat3x2:
2832     case EOpConstructF16Mat3x3:
2833     case EOpConstructF16Mat3x4:
2834     case EOpConstructF16Mat4x2:
2835     case EOpConstructF16Mat4x3:
2836     case EOpConstructF16Mat4x4:
2837 #endif
2838         constructingMatrix = true;
2839         break;
2840     default:
2841         break;
2842     }
2843
2844     //
2845     // Walk the arguments for first-pass checks and collection of information.
2846     //
2847
2848     int size = 0;
2849     bool constType = true;
2850     bool specConstType = false;   // value is only valid if constType is true
2851     bool full = false;
2852     bool overFull = false;
2853     bool matrixInMatrix = false;
2854     bool arrayArg = false;
2855     bool floatArgument = false;
2856     for (int arg = 0; arg < function.getParamCount(); ++arg) {
2857         if (function[arg].type->isArray()) {
2858             if (function[arg].type->isUnsizedArray()) {
2859                 // Can't construct from an unsized array.
2860                 error(loc, "array argument must be sized", "constructor", "");
2861                 return true;
2862             }
2863             arrayArg = true;
2864         }
2865         if (constructingMatrix && function[arg].type->isMatrix())
2866             matrixInMatrix = true;
2867
2868         // 'full' will go to true when enough args have been seen.  If we loop
2869         // again, there is an extra argument.
2870         if (full) {
2871             // For vectors and matrices, it's okay to have too many components
2872             // available, but not okay to have unused arguments.
2873             overFull = true;
2874         }
2875
2876         size += function[arg].type->computeNumComponents();
2877         if (op != EOpConstructStruct && ! type.isArray() && size >= type.computeNumComponents())
2878             full = true;
2879
2880         if (! function[arg].type->getQualifier().isConstant())
2881             constType = false;
2882         if (function[arg].type->getQualifier().isSpecConstant())
2883             specConstType = true;
2884         if (function[arg].type->isFloatingDomain())
2885             floatArgument = true;
2886         if (type.isStruct()) {
2887             if (function[arg].type->contains16BitFloat()) {
2888                 requireFloat16Arithmetic(loc, "constructor", "can't construct structure containing 16-bit type");
2889             }
2890             if (function[arg].type->contains16BitInt()) {
2891                 requireInt16Arithmetic(loc, "constructor", "can't construct structure containing 16-bit type");
2892             }
2893             if (function[arg].type->contains8BitInt()) {
2894                 requireInt8Arithmetic(loc, "constructor", "can't construct structure containing 8-bit type");
2895             }
2896         }
2897     }
2898     if (op == EOpConstructNonuniform)
2899         constType = false;
2900
2901 #ifndef GLSLANG_WEB
2902     switch (op) {
2903     case EOpConstructFloat16:
2904     case EOpConstructF16Vec2:
2905     case EOpConstructF16Vec3:
2906     case EOpConstructF16Vec4:
2907         if (type.isArray())
2908             requireFloat16Arithmetic(loc, "constructor", "16-bit arrays not supported");
2909         if (type.isVector() && function.getParamCount() != 1)
2910             requireFloat16Arithmetic(loc, "constructor", "16-bit vectors only take vector types");
2911         break;
2912     case EOpConstructUint16:
2913     case EOpConstructU16Vec2:
2914     case EOpConstructU16Vec3:
2915     case EOpConstructU16Vec4:
2916     case EOpConstructInt16:
2917     case EOpConstructI16Vec2:
2918     case EOpConstructI16Vec3:
2919     case EOpConstructI16Vec4:
2920         if (type.isArray())
2921             requireInt16Arithmetic(loc, "constructor", "16-bit arrays not supported");
2922         if (type.isVector() && function.getParamCount() != 1)
2923             requireInt16Arithmetic(loc, "constructor", "16-bit vectors only take vector types");
2924         break;
2925     case EOpConstructUint8:
2926     case EOpConstructU8Vec2:
2927     case EOpConstructU8Vec3:
2928     case EOpConstructU8Vec4:
2929     case EOpConstructInt8:
2930     case EOpConstructI8Vec2:
2931     case EOpConstructI8Vec3:
2932     case EOpConstructI8Vec4:
2933         if (type.isArray())
2934             requireInt8Arithmetic(loc, "constructor", "8-bit arrays not supported");
2935         if (type.isVector() && function.getParamCount() != 1)
2936             requireInt8Arithmetic(loc, "constructor", "8-bit vectors only take vector types");
2937         break;
2938     default:
2939         break;
2940     }
2941 #endif
2942
2943     // inherit constness from children
2944     if (constType) {
2945         bool makeSpecConst;
2946         // Finish pinning down spec-const semantics
2947         if (specConstType) {
2948             switch (op) {
2949             case EOpConstructInt8:
2950             case EOpConstructInt:
2951             case EOpConstructUint:
2952             case EOpConstructBool:
2953             case EOpConstructBVec2:
2954             case EOpConstructBVec3:
2955             case EOpConstructBVec4:
2956             case EOpConstructIVec2:
2957             case EOpConstructIVec3:
2958             case EOpConstructIVec4:
2959             case EOpConstructUVec2:
2960             case EOpConstructUVec3:
2961             case EOpConstructUVec4:
2962 #ifndef GLSLANG_WEB
2963             case EOpConstructUint8:
2964             case EOpConstructInt16:
2965             case EOpConstructUint16:
2966             case EOpConstructInt64:
2967             case EOpConstructUint64:
2968             case EOpConstructI8Vec2:
2969             case EOpConstructI8Vec3:
2970             case EOpConstructI8Vec4:
2971             case EOpConstructU8Vec2:
2972             case EOpConstructU8Vec3:
2973             case EOpConstructU8Vec4:
2974             case EOpConstructI16Vec2:
2975             case EOpConstructI16Vec3:
2976             case EOpConstructI16Vec4:
2977             case EOpConstructU16Vec2:
2978             case EOpConstructU16Vec3:
2979             case EOpConstructU16Vec4:
2980             case EOpConstructI64Vec2:
2981             case EOpConstructI64Vec3:
2982             case EOpConstructI64Vec4:
2983             case EOpConstructU64Vec2:
2984             case EOpConstructU64Vec3:
2985             case EOpConstructU64Vec4:
2986 #endif
2987                 // This was the list of valid ones, if they aren't converting from float
2988                 // and aren't making an array.
2989                 makeSpecConst = ! floatArgument && ! type.isArray();
2990                 break;
2991             default:
2992                 // anything else wasn't white-listed in the spec as a conversion
2993                 makeSpecConst = false;
2994                 break;
2995             }
2996         } else
2997             makeSpecConst = false;
2998
2999         if (makeSpecConst)
3000             type.getQualifier().makeSpecConstant();
3001         else if (specConstType)
3002             type.getQualifier().makeTemporary();
3003         else
3004             type.getQualifier().storage = EvqConst;
3005     }
3006
3007     if (type.isArray()) {
3008         if (function.getParamCount() == 0) {
3009             error(loc, "array constructor must have at least one argument", "constructor", "");
3010             return true;
3011         }
3012
3013         if (type.isUnsizedArray()) {
3014             // auto adapt the constructor type to the number of arguments
3015             type.changeOuterArraySize(function.getParamCount());
3016         } else if (type.getOuterArraySize() != function.getParamCount()) {
3017             error(loc, "array constructor needs one argument per array element", "constructor", "");
3018             return true;
3019         }
3020
3021         if (type.isArrayOfArrays()) {
3022             // Types have to match, but we're still making the type.
3023             // Finish making the type, and the comparison is done later
3024             // when checking for conversion.
3025             TArraySizes& arraySizes = *type.getArraySizes();
3026
3027             // At least the dimensionalities have to match.
3028             if (! function[0].type->isArray() ||
3029                     arraySizes.getNumDims() != function[0].type->getArraySizes()->getNumDims() + 1) {
3030                 error(loc, "array constructor argument not correct type to construct array element", "constructor", "");
3031                 return true;
3032             }
3033
3034             if (arraySizes.isInnerUnsized()) {
3035                 // "Arrays of arrays ..., and the size for any dimension is optional"
3036                 // That means we need to adopt (from the first argument) the other array sizes into the type.
3037                 for (int d = 1; d < arraySizes.getNumDims(); ++d) {
3038                     if (arraySizes.getDimSize(d) == UnsizedArraySize) {
3039                         arraySizes.setDimSize(d, function[0].type->getArraySizes()->getDimSize(d - 1));
3040                     }
3041                 }
3042             }
3043         }
3044     }
3045
3046     if (arrayArg && op != EOpConstructStruct && ! type.isArrayOfArrays()) {
3047         error(loc, "constructing non-array constituent from array argument", "constructor", "");
3048         return true;
3049     }
3050
3051     if (matrixInMatrix && ! type.isArray()) {
3052         profileRequires(loc, ENoProfile, 120, nullptr, "constructing matrix from matrix");
3053
3054         // "If a matrix argument is given to a matrix constructor,
3055         // it is a compile-time error to have any other arguments."
3056         if (function.getParamCount() != 1)
3057             error(loc, "matrix constructed from matrix can only have one argument", "constructor", "");
3058         return false;
3059     }
3060
3061     if (overFull) {
3062         error(loc, "too many arguments", "constructor", "");
3063         return true;
3064     }
3065
3066     if (op == EOpConstructStruct && ! type.isArray() && (int)type.getStruct()->size() != function.getParamCount()) {
3067         error(loc, "Number of constructor parameters does not match the number of structure fields", "constructor", "");
3068         return true;
3069     }
3070
3071     if ((op != EOpConstructStruct && size != 1 && size < type.computeNumComponents()) ||
3072         (op == EOpConstructStruct && size < type.computeNumComponents())) {
3073         error(loc, "not enough data provided for construction", "constructor", "");
3074         return true;
3075     }
3076
3077     if (type.isCoopMat() && function.getParamCount() != 1) {
3078         error(loc, "wrong number of arguments", "constructor", "");
3079         return true;
3080     }
3081     if (type.isCoopMat() &&
3082         !(function[0].type->isScalar() || function[0].type->isCoopMat())) {
3083         error(loc, "Cooperative matrix constructor argument must be scalar or cooperative matrix", "constructor", "");
3084         return true;
3085     }
3086
3087     TIntermTyped* typed = node->getAsTyped();
3088     if (typed == nullptr) {
3089         error(loc, "constructor argument does not have a type", "constructor", "");
3090         return true;
3091     }
3092     if (op != EOpConstructStruct && op != EOpConstructNonuniform && typed->getBasicType() == EbtSampler) {
3093         error(loc, "cannot convert a sampler", "constructor", "");
3094         return true;
3095     }
3096     if (op != EOpConstructStruct && typed->isAtomic()) {
3097         error(loc, "cannot convert an atomic_uint", "constructor", "");
3098         return true;
3099     }
3100     if (typed->getBasicType() == EbtVoid) {
3101         error(loc, "cannot convert a void", "constructor", "");
3102         return true;
3103     }
3104
3105     return false;
3106 }
3107
3108 // Verify all the correct semantics for constructing a combined texture/sampler.
3109 // Return true if the semantics are incorrect.
3110 bool TParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const TFunction& function)
3111 {
3112     TString constructorName = function.getType().getBasicTypeString();  // TODO: performance: should not be making copy; interface needs to change
3113     const char* token = constructorName.c_str();
3114
3115     // exactly two arguments needed
3116     if (function.getParamCount() != 2) {
3117         error(loc, "sampler-constructor requires two arguments", token, "");
3118         return true;
3119     }
3120
3121     // For now, not allowing arrayed constructors, the rest of this function
3122     // is set up to allow them, if this test is removed:
3123     if (function.getType().isArray()) {
3124         error(loc, "sampler-constructor cannot make an array of samplers", token, "");
3125         return true;
3126     }
3127
3128     // first argument
3129     //  * the constructor's first argument must be a texture type
3130     //  * the dimensionality (1D, 2D, 3D, Cube, Rect, Buffer, MS, and Array)
3131     //    of the texture type must match that of the constructed sampler type
3132     //    (that is, the suffixes of the type of the first argument and the
3133     //    type of the constructor will be spelled the same way)
3134     if (function[0].type->getBasicType() != EbtSampler ||
3135         ! function[0].type->getSampler().isTexture() ||
3136         function[0].type->isArray()) {
3137         error(loc, "sampler-constructor first argument must be a scalar textureXXX type", token, "");
3138         return true;
3139     }
3140     // simulate the first argument's impact on the result type, so it can be compared with the encapsulated operator!=()
3141     TSampler texture = function.getType().getSampler();
3142     texture.setCombined(false);
3143     texture.shadow = false;
3144     if (texture != function[0].type->getSampler()) {
3145         error(loc, "sampler-constructor first argument must match type and dimensionality of constructor type", token, "");
3146         return true;
3147     }
3148
3149     // second argument
3150     //   * the constructor's second argument must be a scalar of type
3151     //     *sampler* or *samplerShadow*
3152     if (  function[1].type->getBasicType() != EbtSampler ||
3153         ! function[1].type->getSampler().isPureSampler() ||
3154           function[1].type->isArray()) {
3155         error(loc, "sampler-constructor second argument must be a scalar type 'sampler'", token, "");
3156         return true;
3157     }
3158
3159     return false;
3160 }
3161
3162 // Checks to see if a void variable has been declared and raise an error message for such a case
3163 //
3164 // returns true in case of an error
3165 //
3166 bool TParseContext::voidErrorCheck(const TSourceLoc& loc, const TString& identifier, const TBasicType basicType)
3167 {
3168     if (basicType == EbtVoid) {
3169         error(loc, "illegal use of type 'void'", identifier.c_str(), "");
3170         return true;
3171     }
3172
3173     return false;
3174 }
3175
3176 // Checks to see if the node (for the expression) contains a scalar boolean expression or not
3177 void TParseContext::boolCheck(const TSourceLoc& loc, const TIntermTyped* type)
3178 {
3179     if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector())
3180         error(loc, "boolean expression expected", "", "");
3181 }
3182
3183 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
3184 void TParseContext::boolCheck(const TSourceLoc& loc, const TPublicType& pType)
3185 {
3186     if (pType.basicType != EbtBool || pType.arraySizes || pType.matrixCols > 1 || (pType.vectorSize > 1))
3187         error(loc, "boolean expression expected", "", "");
3188 }
3189
3190 void TParseContext::samplerCheck(const TSourceLoc& loc, const TType& type, const TString& identifier, TIntermTyped* /*initializer*/)
3191 {
3192     // Check that the appropriate extension is enabled if external sampler is used.
3193     // There are two extensions. The correct one must be used based on GLSL version.
3194     if (type.getBasicType() == EbtSampler && type.getSampler().isExternal()) {
3195         if (version < 300) {
3196             requireExtensions(loc, 1, &E_GL_OES_EGL_image_external, "samplerExternalOES");
3197         } else {
3198             requireExtensions(loc, 1, &E_GL_OES_EGL_image_external_essl3, "samplerExternalOES");
3199         }
3200     }
3201     if (type.getSampler().isYuv()) {
3202         requireExtensions(loc, 1, &E_GL_EXT_YUV_target, "__samplerExternal2DY2YEXT");
3203     }
3204
3205     if (type.getQualifier().storage == EvqUniform)
3206         return;
3207
3208     if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtSampler))
3209         error(loc, "non-uniform struct contains a sampler or image:", type.getBasicTypeString().c_str(), identifier.c_str());
3210     else if (type.getBasicType() == EbtSampler && type.getQualifier().storage != EvqUniform) {
3211         // non-uniform sampler
3212         // not yet:  okay if it has an initializer
3213         // if (! initializer)
3214         error(loc, "sampler/image types can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str());
3215     }
3216 }
3217
3218 #ifndef GLSLANG_WEB
3219
3220 void TParseContext::atomicUintCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
3221 {
3222     if (type.getQualifier().storage == EvqUniform)
3223         return;
3224
3225     if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtAtomicUint))
3226         error(loc, "non-uniform struct contains an atomic_uint:", type.getBasicTypeString().c_str(), identifier.c_str());
3227     else if (type.getBasicType() == EbtAtomicUint && type.getQualifier().storage != EvqUniform)
3228         error(loc, "atomic_uints can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str());
3229 }
3230
3231 void TParseContext::accStructCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
3232 {
3233     if (type.getQualifier().storage == EvqUniform)
3234         return;
3235
3236     if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtAccStruct))
3237         error(loc, "non-uniform struct contains an accelerationStructureNV:", type.getBasicTypeString().c_str(), identifier.c_str());
3238     else if (type.getBasicType() == EbtAccStruct && type.getQualifier().storage != EvqUniform)
3239         error(loc, "accelerationStructureNV can only be used in uniform variables or function parameters:",
3240             type.getBasicTypeString().c_str(), identifier.c_str());
3241
3242 }
3243
3244 #endif // GLSLANG_WEB
3245
3246 void TParseContext::transparentOpaqueCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
3247 {
3248     if (parsingBuiltins)
3249         return;
3250
3251     if (type.getQualifier().storage != EvqUniform)
3252         return;
3253
3254     if (type.containsNonOpaque()) {
3255         // Vulkan doesn't allow transparent uniforms outside of blocks
3256         if (spvVersion.vulkan > 0)
3257             vulkanRemoved(loc, "non-opaque uniforms outside a block");
3258         // OpenGL wants locations on these (unless they are getting automapped)
3259         if (spvVersion.openGl > 0 && !type.getQualifier().hasLocation() && !intermediate.getAutoMapLocations())
3260             error(loc, "non-opaque uniform variables need a layout(location=L)", identifier.c_str(), "");
3261     }
3262 }
3263
3264 //
3265 // Qualifier checks knowing the qualifier and that it is a member of a struct/block.
3266 //
3267 void TParseContext::memberQualifierCheck(glslang::TPublicType& publicType)
3268 {
3269     globalQualifierFixCheck(publicType.loc, publicType.qualifier);
3270     checkNoShaderLayouts(publicType.loc, publicType.shaderQualifiers);
3271     if (publicType.qualifier.isNonUniform()) {
3272         error(publicType.loc, "not allowed on block or structure members", "nonuniformEXT", "");
3273         publicType.qualifier.nonUniform = false;
3274     }
3275 }
3276
3277 //
3278 // Check/fix just a full qualifier (no variables or types yet, but qualifier is complete) at global level.
3279 //
3280 void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& qualifier)
3281 {
3282     bool nonuniformOkay = false;
3283
3284     // move from parameter/unknown qualifiers to pipeline in/out qualifiers
3285     switch (qualifier.storage) {
3286     case EvqIn:
3287         profileRequires(loc, ENoProfile, 130, nullptr, "in for stage inputs");
3288         profileRequires(loc, EEsProfile, 300, nullptr, "in for stage inputs");
3289         qualifier.storage = EvqVaryingIn;
3290         nonuniformOkay = true;
3291         break;
3292     case EvqOut:
3293         profileRequires(loc, ENoProfile, 130, nullptr, "out for stage outputs");
3294         profileRequires(loc, EEsProfile, 300, nullptr, "out for stage outputs");
3295         qualifier.storage = EvqVaryingOut;
3296         break;
3297     case EvqInOut:
3298         qualifier.storage = EvqVaryingIn;
3299         error(loc, "cannot use 'inout' at global scope", "", "");
3300         break;
3301     case EvqGlobal:
3302     case EvqTemporary:
3303         nonuniformOkay = true;
3304         break;
3305     default:
3306         break;
3307     }
3308
3309     if (!nonuniformOkay && qualifier.isNonUniform())
3310         error(loc, "for non-parameter, can only apply to 'in' or no storage qualifier", "nonuniformEXT", "");
3311
3312     invariantCheck(loc, qualifier);
3313 }
3314
3315 //
3316 // Check a full qualifier and type (no variable yet) at global level.
3317 //
3318 void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQualifier& qualifier, const TPublicType& publicType)
3319 {
3320     if (! symbolTable.atGlobalLevel())
3321         return;
3322
3323     if (!(publicType.userDef && publicType.userDef->isReference())) {
3324         if (qualifier.isMemoryQualifierImageAndSSBOOnly() && ! publicType.isImage() && publicType.qualifier.storage != EvqBuffer) {
3325             error(loc, "memory qualifiers cannot be used on this type", "", "");
3326         } else if (qualifier.isMemory() && (publicType.basicType != EbtSampler) && !publicType.qualifier.isUniformOrBuffer()) {
3327             error(loc, "memory qualifiers cannot be used on this type", "", "");
3328         }
3329     }
3330
3331     if (qualifier.storage == EvqBuffer &&
3332         publicType.basicType != EbtBlock &&
3333         !qualifier.hasBufferReference())
3334         error(loc, "buffers can be declared only as blocks", "buffer", "");
3335
3336     if (qualifier.storage != EvqVaryingIn && qualifier.storage != EvqVaryingOut)
3337         return;
3338
3339     if (publicType.shaderQualifiers.hasBlendEquation())
3340         error(loc, "can only be applied to a standalone 'out'", "blend equation", "");
3341
3342     // now, knowing it is a shader in/out, do all the in/out semantic checks
3343
3344     if (publicType.basicType == EbtBool && !parsingBuiltins) {
3345         error(loc, "cannot be bool", GetStorageQualifierString(qualifier.storage), "");
3346         return;
3347     }
3348
3349     if (isTypeInt(publicType.basicType) || publicType.basicType == EbtDouble)
3350         profileRequires(loc, EEsProfile, 300, nullptr, "shader input/output");
3351
3352     if (!qualifier.flat && !qualifier.isExplicitInterpolation() && !qualifier.isPervertexNV()) {
3353         if (isTypeInt(publicType.basicType) ||
3354             publicType.basicType == EbtDouble ||
3355             (publicType.userDef && (   publicType.userDef->containsBasicType(EbtInt)
3356                                     || publicType.userDef->containsBasicType(EbtUint)
3357                                     || publicType.userDef->contains16BitInt()
3358                                     || publicType.userDef->contains8BitInt()
3359                                     || publicType.userDef->contains64BitInt()
3360                                     || publicType.userDef->containsDouble()))) {
3361             if (qualifier.storage == EvqVaryingIn && language == EShLangFragment)
3362                 error(loc, "must be qualified as flat", TType::getBasicString(publicType.basicType), GetStorageQualifierString(qualifier.storage));
3363             else if (qualifier.storage == EvqVaryingOut && language == EShLangVertex && version == 300)
3364                 error(loc, "must be qualified as flat", TType::getBasicString(publicType.basicType), GetStorageQualifierString(qualifier.storage));
3365         }
3366     }
3367
3368     if (qualifier.isPatch() && qualifier.isInterpolation())
3369         error(loc, "cannot use interpolation qualifiers with patch", "patch", "");
3370
3371     if (qualifier.isTaskMemory() && publicType.basicType != EbtBlock)
3372         error(loc, "taskNV variables can be declared only as blocks", "taskNV", "");
3373
3374     if (qualifier.storage == EvqVaryingIn) {
3375         switch (language) {
3376         case EShLangVertex:
3377             if (publicType.basicType == EbtStruct) {
3378                 error(loc, "cannot be a structure or array", GetStorageQualifierString(qualifier.storage), "");
3379                 return;
3380             }
3381             if (publicType.arraySizes) {
3382                 requireProfile(loc, ~EEsProfile, "vertex input arrays");
3383                 profileRequires(loc, ENoProfile, 150, nullptr, "vertex input arrays");
3384             }
3385             if (publicType.basicType == EbtDouble)
3386                 profileRequires(loc, ~EEsProfile, 410, nullptr, "vertex-shader `double` type input");
3387             if (qualifier.isAuxiliary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.invariant)
3388                 error(loc, "vertex input cannot be further qualified", "", "");
3389             break;
3390         case EShLangFragment:
3391             if (publicType.userDef) {
3392                 profileRequires(loc, EEsProfile, 300, nullptr, "fragment-shader struct input");
3393                 profileRequires(loc, ~EEsProfile, 150, nullptr, "fragment-shader struct input");
3394                 if (publicType.userDef->containsStructure())
3395                     requireProfile(loc, ~EEsProfile, "fragment-shader struct input containing structure");
3396                 if (publicType.userDef->containsArray())
3397                     requireProfile(loc, ~EEsProfile, "fragment-shader struct input containing an array");
3398             }
3399             break;
3400        case EShLangCompute:
3401             if (! symbolTable.atBuiltInLevel())
3402                 error(loc, "global storage input qualifier cannot be used in a compute shader", "in", "");
3403             break;
3404 #ifndef GLSLANG_WEB
3405        case EShLangTessControl:
3406             if (qualifier.patch)
3407                 error(loc, "can only use on output in tessellation-control shader", "patch", "");
3408             break;
3409 #endif
3410         default:
3411             break;
3412         }
3413     } else {
3414         // qualifier.storage == EvqVaryingOut
3415         switch (language) {
3416         case EShLangVertex:
3417             if (publicType.userDef) {
3418                 profileRequires(loc, EEsProfile, 300, nullptr, "vertex-shader struct output");
3419                 profileRequires(loc, ~EEsProfile, 150, nullptr, "vertex-shader struct output");
3420                 if (publicType.userDef->containsStructure())
3421                     requireProfile(loc, ~EEsProfile, "vertex-shader struct output containing structure");
3422                 if (publicType.userDef->containsArray())
3423                     requireProfile(loc, ~EEsProfile, "vertex-shader struct output containing an array");
3424             }
3425
3426             break;
3427         case EShLangFragment:
3428             profileRequires(loc, EEsProfile, 300, nullptr, "fragment shader output");
3429             if (publicType.basicType == EbtStruct) {
3430                 error(loc, "cannot be a structure", GetStorageQualifierString(qualifier.storage), "");
3431                 return;
3432             }
3433             if (publicType.matrixRows > 0) {
3434                 error(loc, "cannot be a matrix", GetStorageQualifierString(qualifier.storage), "");
3435                 return;
3436             }
3437             if (qualifier.isAuxiliary())
3438                 error(loc, "can't use auxiliary qualifier on a fragment output", "centroid/sample/patch", "");
3439             if (qualifier.isInterpolation())
3440                 error(loc, "can't use interpolation qualifier on a fragment output", "flat/smooth/noperspective", "");
3441             if (publicType.basicType == EbtDouble || publicType.basicType == EbtInt64 || publicType.basicType == EbtUint64)
3442                 error(loc, "cannot contain a double, int64, or uint64", GetStorageQualifierString(qualifier.storage), "");
3443         break;
3444
3445         case EShLangCompute:
3446             error(loc, "global storage output qualifier cannot be used in a compute shader", "out", "");
3447             break;
3448 #ifndef GLSLANG_WEB
3449         case EShLangTessEvaluation:
3450             if (qualifier.patch)
3451                 error(loc, "can only use on input in tessellation-evaluation shader", "patch", "");
3452             break;
3453 #endif
3454         default:
3455             break;
3456         }
3457     }
3458 }
3459
3460 //
3461 // Merge characteristics of the 'src' qualifier into the 'dst'.
3462 // If there is duplication, issue error messages, unless 'force'
3463 // is specified, which means to just override default settings.
3464 //
3465 // Also, when force is false, it will be assumed that 'src' follows
3466 // 'dst', for the purpose of error checking order for versions
3467 // that require specific orderings of qualifiers.
3468 //
3469 void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, const TQualifier& src, bool force)
3470 {
3471     // Multiple auxiliary qualifiers (mostly done later by 'individual qualifiers')
3472     if (src.isAuxiliary() && dst.isAuxiliary())
3473         error(loc, "can only have one auxiliary qualifier (centroid, patch, and sample)", "", "");
3474
3475     // Multiple interpolation qualifiers (mostly done later by 'individual qualifiers')
3476     if (src.isInterpolation() && dst.isInterpolation())
3477         error(loc, "can only have one interpolation qualifier (flat, smooth, noperspective, __explicitInterpAMD)", "", "");
3478
3479     // Ordering
3480     if (! force && ((!isEsProfile() && version < 420) ||
3481                     (isEsProfile() && version < 310))
3482                 && ! extensionTurnedOn(E_GL_ARB_shading_language_420pack)) {
3483         // non-function parameters
3484         if (src.isNoContraction() && (dst.invariant || dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone))
3485             error(loc, "precise qualifier must appear first", "", "");
3486         if (src.invariant && (dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone))
3487             error(loc, "invariant qualifier must appear before interpolation, storage, and precision qualifiers ", "", "");
3488         else if (src.isInterpolation() && (dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone))
3489             error(loc, "interpolation qualifiers must appear before storage and precision qualifiers", "", "");
3490         else if (src.isAuxiliary() && (dst.storage != EvqTemporary || dst.precision != EpqNone))
3491             error(loc, "Auxiliary qualifiers (centroid, patch, and sample) must appear before storage and precision qualifiers", "", "");
3492         else if (src.storage != EvqTemporary && (dst.precision != EpqNone))
3493             error(loc, "precision qualifier must appear as last qualifier", "", "");
3494
3495         // function parameters
3496         if (src.isNoContraction() && (dst.storage == EvqConst || dst.storage == EvqIn || dst.storage == EvqOut))
3497             error(loc, "precise qualifier must appear first", "", "");
3498         if (src.storage == EvqConst && (dst.storage == EvqIn || dst.storage == EvqOut))
3499             error(loc, "in/out must appear before const", "", "");
3500     }
3501
3502     // Storage qualification
3503     if (dst.storage == EvqTemporary || dst.storage == EvqGlobal)
3504         dst.storage = src.storage;
3505     else if ((dst.storage == EvqIn  && src.storage == EvqOut) ||
3506              (dst.storage == EvqOut && src.storage == EvqIn))
3507         dst.storage = EvqInOut;
3508     else if ((dst.storage == EvqIn    && src.storage == EvqConst) ||
3509              (dst.storage == EvqConst && src.storage == EvqIn))
3510         dst.storage = EvqConstReadOnly;
3511     else if (src.storage != EvqTemporary &&
3512              src.storage != EvqGlobal)
3513         error(loc, "too many storage qualifiers", GetStorageQualifierString(src.storage), "");
3514
3515     // Precision qualifiers
3516     if (! force && src.precision != EpqNone && dst.precision != EpqNone)
3517         error(loc, "only one precision qualifier allowed", GetPrecisionQualifierString(src.precision), "");
3518     if (dst.precision == EpqNone || (force && src.precision != EpqNone))
3519         dst.precision = src.precision;
3520
3521 #ifndef GLSLANG_WEB
3522     if (!force && ((src.coherent && (dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
3523                    (src.devicecoherent && (dst.coherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
3524                    (src.queuefamilycoherent && (dst.coherent || dst.devicecoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
3525                    (src.workgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
3526                    (src.subgroupcoherent  && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.shadercallcoherent)) ||
3527                    (src.shadercallcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)))) {
3528         error(loc, "only one coherent/devicecoherent/queuefamilycoherent/workgroupcoherent/subgroupcoherent/shadercallcoherent qualifier allowed", 
3529             GetPrecisionQualifierString(src.precision), "");
3530     }
3531 #endif
3532     // Layout qualifiers
3533     mergeObjectLayoutQualifiers(dst, src, false);
3534
3535     // individual qualifiers
3536     bool repeated = false;
3537     #define MERGE_SINGLETON(field) repeated |= dst.field && src.field; dst.field |= src.field;
3538     MERGE_SINGLETON(invariant);
3539     MERGE_SINGLETON(centroid);
3540     MERGE_SINGLETON(smooth);
3541     MERGE_SINGLETON(flat);
3542     MERGE_SINGLETON(specConstant);
3543 #ifndef GLSLANG_WEB
3544     MERGE_SINGLETON(noContraction);
3545     MERGE_SINGLETON(nopersp);
3546     MERGE_SINGLETON(explicitInterp);
3547     MERGE_SINGLETON(perPrimitiveNV);
3548     MERGE_SINGLETON(perViewNV);
3549     MERGE_SINGLETON(perTaskNV);
3550     MERGE_SINGLETON(patch);
3551     MERGE_SINGLETON(sample);
3552     MERGE_SINGLETON(coherent);
3553     MERGE_SINGLETON(devicecoherent);
3554     MERGE_SINGLETON(queuefamilycoherent);
3555     MERGE_SINGLETON(workgroupcoherent);
3556     MERGE_SINGLETON(subgroupcoherent);
3557     MERGE_SINGLETON(shadercallcoherent);
3558     MERGE_SINGLETON(nonprivate);
3559     MERGE_SINGLETON(volatil);
3560     MERGE_SINGLETON(restrict);
3561     MERGE_SINGLETON(readonly);
3562     MERGE_SINGLETON(writeonly);
3563     MERGE_SINGLETON(nonUniform);
3564 #endif
3565
3566     if (repeated)
3567         error(loc, "replicated qualifiers", "", "");
3568 }
3569
3570 void TParseContext::setDefaultPrecision(const TSourceLoc& loc, TPublicType& publicType, TPrecisionQualifier qualifier)
3571 {
3572     TBasicType basicType = publicType.basicType;
3573
3574     if (basicType == EbtSampler) {
3575         defaultSamplerPrecision[computeSamplerTypeIndex(publicType.sampler)] = qualifier;
3576
3577         return;  // all is well
3578     }
3579
3580     if (basicType == EbtInt || basicType == EbtFloat) {
3581         if (publicType.isScalar()) {
3582             defaultPrecision[basicType] = qualifier;
3583             if (basicType == EbtInt) {
3584                 defaultPrecision[EbtUint] = qualifier;
3585                 precisionManager.explicitIntDefaultSeen();
3586             } else
3587                 precisionManager.explicitFloatDefaultSeen();
3588
3589             return;  // all is well
3590         }
3591     }
3592
3593     if (basicType == EbtAtomicUint) {
3594         if (qualifier != EpqHigh)
3595             error(loc, "can only apply highp to atomic_uint", "precision", "");
3596
3597         return;
3598     }
3599
3600     error(loc, "cannot apply precision statement to this type; use 'float', 'int' or a sampler type", TType::getBasicString(basicType), "");
3601 }
3602
3603 // used to flatten the sampler type space into a single dimension
3604 // correlates with the declaration of defaultSamplerPrecision[]
3605 int TParseContext::computeSamplerTypeIndex(TSampler& sampler)
3606 {
3607     int arrayIndex    = sampler.arrayed         ? 1 : 0;
3608     int shadowIndex   = sampler.shadow          ? 1 : 0;
3609     int externalIndex = sampler.isExternal()    ? 1 : 0;
3610     int imageIndex    = sampler.isImageClass()  ? 1 : 0;
3611     int msIndex       = sampler.isMultiSample() ? 1 : 0;
3612
3613     int flattened = EsdNumDims * (EbtNumTypes * (2 * (2 * (2 * (2 * arrayIndex + msIndex) + imageIndex) + shadowIndex) +
3614                                                  externalIndex) + sampler.type) + sampler.dim;
3615     assert(flattened < maxSamplerIndex);
3616
3617     return flattened;
3618 }
3619
3620 TPrecisionQualifier TParseContext::getDefaultPrecision(TPublicType& publicType)
3621 {
3622     if (publicType.basicType == EbtSampler)
3623         return defaultSamplerPrecision[computeSamplerTypeIndex(publicType.sampler)];
3624     else
3625         return defaultPrecision[publicType.basicType];
3626 }
3627
3628 void TParseContext::precisionQualifierCheck(const TSourceLoc& loc, TBasicType baseType, TQualifier& qualifier)
3629 {
3630     // Built-in symbols are allowed some ambiguous precisions, to be pinned down
3631     // later by context.
3632     if (! obeyPrecisionQualifiers() || parsingBuiltins)
3633         return;
3634
3635 #ifndef GLSLANG_WEB
3636     if (baseType == EbtAtomicUint && qualifier.precision != EpqNone && qualifier.precision != EpqHigh)
3637         error(loc, "atomic counters can only be highp", "atomic_uint", "");
3638 #endif
3639
3640     if (baseType == EbtFloat || baseType == EbtUint || baseType == EbtInt || baseType == EbtSampler || baseType == EbtAtomicUint) {
3641         if (qualifier.precision == EpqNone) {
3642             if (relaxedErrors())
3643                 warn(loc, "type requires declaration of default precision qualifier", TType::getBasicString(baseType), "substituting 'mediump'");
3644             else
3645                 error(loc, "type requires declaration of default precision qualifier", TType::getBasicString(baseType), "");
3646             qualifier.precision = EpqMedium;
3647             defaultPrecision[baseType] = EpqMedium;
3648         }
3649     } else if (qualifier.precision != EpqNone)
3650         error(loc, "type cannot have precision qualifier", TType::getBasicString(baseType), "");
3651 }
3652
3653 void TParseContext::parameterTypeCheck(const TSourceLoc& loc, TStorageQualifier qualifier, const TType& type)
3654 {
3655     if ((qualifier == EvqOut || qualifier == EvqInOut) && type.isOpaque())
3656         error(loc, "samplers and atomic_uints cannot be output parameters", type.getBasicTypeString().c_str(), "");
3657     if (!parsingBuiltins && type.contains16BitFloat())
3658         requireFloat16Arithmetic(loc, type.getBasicTypeString().c_str(), "float16 types can only be in uniform block or buffer storage");
3659     if (!parsingBuiltins && type.contains16BitInt())
3660         requireInt16Arithmetic(loc, type.getBasicTypeString().c_str(), "(u)int16 types can only be in uniform block or buffer storage");
3661     if (!parsingBuiltins && type.contains8BitInt())
3662         requireInt8Arithmetic(loc, type.getBasicTypeString().c_str(), "(u)int8 types can only be in uniform block or buffer storage");
3663 }
3664
3665 bool TParseContext::containsFieldWithBasicType(const TType& type, TBasicType basicType)
3666 {
3667     if (type.getBasicType() == basicType)
3668         return true;
3669
3670     if (type.getBasicType() == EbtStruct) {
3671         const TTypeList& structure = *type.getStruct();
3672         for (unsigned int i = 0; i < structure.size(); ++i) {
3673             if (containsFieldWithBasicType(*structure[i].type, basicType))
3674                 return true;
3675         }
3676     }
3677
3678     return false;
3679 }
3680
3681 //
3682 // Do size checking for an array type's size.
3683 //
3684 void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, TArraySize& sizePair, const char *sizeType)
3685 {
3686     bool isConst = false;
3687     sizePair.node = nullptr;
3688
3689     int size = 1;
3690
3691     TIntermConstantUnion* constant = expr->getAsConstantUnion();
3692     if (constant) {
3693         // handle true (non-specialization) constant
3694         size = constant->getConstArray()[0].getIConst();
3695         isConst = true;
3696     } else {
3697         // see if it's a specialization constant instead
3698         if (expr->getQualifier().isSpecConstant()) {
3699             isConst = true;
3700             sizePair.node = expr;
3701             TIntermSymbol* symbol = expr->getAsSymbolNode();
3702             if (symbol && symbol->getConstArray().size() > 0)
3703                 size = symbol->getConstArray()[0].getIConst();
3704         } else if (expr->getAsUnaryNode() &&
3705                    expr->getAsUnaryNode()->getOp() == glslang::EOpArrayLength &&
3706                    expr->getAsUnaryNode()->getOperand()->getType().isCoopMat()) {
3707             isConst = true;
3708             size = 1;
3709             sizePair.node = expr->getAsUnaryNode();
3710         }
3711     }
3712
3713     sizePair.size = size;
3714
3715     if (! isConst || (expr->getBasicType() != EbtInt && expr->getBasicType() != EbtUint)) {
3716         error(loc, sizeType, "", "must be a constant integer expression");
3717         return;
3718     }
3719
3720     if (size <= 0) {
3721         error(loc, sizeType, "", "must be a positive integer");
3722         return;
3723     }
3724 }
3725
3726 //
3727 // See if this qualifier can be an array.
3728 //
3729 // Returns true if there is an error.
3730 //
3731 bool TParseContext::arrayQualifierError(const TSourceLoc& loc, const TQualifier& qualifier)
3732 {
3733     if (qualifier.storage == EvqConst) {
3734         profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, "const array");
3735         profileRequires(loc, EEsProfile, 300, nullptr, "const array");
3736     }
3737
3738     if (qualifier.storage == EvqVaryingIn && language == EShLangVertex) {
3739         requireProfile(loc, ~EEsProfile, "vertex input arrays");
3740         profileRequires(loc, ENoProfile, 150, nullptr, "vertex input arrays");
3741     }
3742
3743     return false;
3744 }
3745
3746 //
3747 // See if this qualifier and type combination can be an array.
3748 // Assumes arrayQualifierError() was also called to catch the type-invariant tests.
3749 //
3750 // Returns true if there is an error.
3751 //
3752 bool TParseContext::arrayError(const TSourceLoc& loc, const TType& type)
3753 {
3754     if (type.getQualifier().storage == EvqVaryingOut && language == EShLangVertex) {
3755         if (type.isArrayOfArrays())
3756             requireProfile(loc, ~EEsProfile, "vertex-shader array-of-array output");
3757         else if (type.isStruct())
3758             requireProfile(loc, ~EEsProfile, "vertex-shader array-of-struct output");
3759     }
3760     if (type.getQualifier().storage == EvqVaryingIn && language == EShLangFragment) {
3761         if (type.isArrayOfArrays())
3762             requireProfile(loc, ~EEsProfile, "fragment-shader array-of-array input");
3763         else if (type.isStruct())
3764             requireProfile(loc, ~EEsProfile, "fragment-shader array-of-struct input");
3765     }
3766     if (type.getQualifier().storage == EvqVaryingOut && language == EShLangFragment) {
3767         if (type.isArrayOfArrays())
3768             requireProfile(loc, ~EEsProfile, "fragment-shader array-of-array output");
3769     }
3770
3771     return false;
3772 }
3773
3774 //
3775 // Require array to be completely sized
3776 //
3777 void TParseContext::arraySizeRequiredCheck(const TSourceLoc& loc, const TArraySizes& arraySizes)
3778 {
3779     if (!parsingBuiltins && arraySizes.hasUnsized())
3780         error(loc, "array size required", "", "");
3781 }
3782
3783 void TParseContext::structArrayCheck(const TSourceLoc& /*loc*/, const TType& type)
3784 {
3785     const TTypeList& structure = *type.getStruct();
3786     for (int m = 0; m < (int)structure.size(); ++m) {
3787         const TType& member = *structure[m].type;
3788         if (member.isArray())
3789             arraySizeRequiredCheck(structure[m].loc, *member.getArraySizes());
3790     }
3791 }
3792
3793 void TParseContext::arraySizesCheck(const TSourceLoc& loc, const TQualifier& qualifier, TArraySizes* arraySizes,
3794     const TIntermTyped* initializer, bool lastMember)
3795 {
3796     assert(arraySizes);
3797
3798     // always allow special built-in ins/outs sized to topologies
3799     if (parsingBuiltins)
3800         return;
3801
3802     // initializer must be a sized array, in which case
3803     // allow the initializer to set any unknown array sizes
3804     if (initializer != nullptr) {
3805         if (initializer->getType().isUnsizedArray())
3806             error(loc, "array initializer must be sized", "[]", "");
3807         return;
3808     }
3809
3810     // No environment allows any non-outer-dimension to be implicitly sized
3811     if (arraySizes->isInnerUnsized()) {
3812         error(loc, "only outermost dimension of an array of arrays can be implicitly sized", "[]", "");
3813         arraySizes->clearInnerUnsized();
3814     }
3815
3816     if (arraySizes->isInnerSpecialization() &&
3817         (qualifier.storage != EvqTemporary && qualifier.storage != EvqGlobal && qualifier.storage != EvqShared && qualifier.storage != EvqConst))
3818         error(loc, "only outermost dimension of an array of arrays can be a specialization constant", "[]", "");
3819
3820 #ifndef GLSLANG_WEB
3821
3822     // desktop always allows outer-dimension-unsized variable arrays,
3823     if (!isEsProfile())
3824         return;
3825
3826     // for ES, if size isn't coming from an initializer, it has to be explicitly declared now,
3827     // with very few exceptions
3828
3829     // implicitly-sized io exceptions:
3830     switch (language) {
3831     case EShLangGeometry:
3832         if (qualifier.storage == EvqVaryingIn)
3833             if ((isEsProfile() && version >= 320) ||
3834                 extensionsTurnedOn(Num_AEP_geometry_shader, AEP_geometry_shader))
3835                 return;
3836         break;
3837     case EShLangTessControl:
3838         if ( qualifier.storage == EvqVaryingIn ||
3839             (qualifier.storage == EvqVaryingOut && ! qualifier.isPatch()))
3840             if ((isEsProfile() && version >= 320) ||
3841                 extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader))
3842                 return;
3843         break;
3844     case EShLangTessEvaluation:
3845         if ((qualifier.storage == EvqVaryingIn && ! qualifier.isPatch()) ||
3846              qualifier.storage == EvqVaryingOut)
3847             if ((isEsProfile() && version >= 320) ||
3848                 extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader))
3849                 return;
3850         break;
3851     case EShLangMeshNV:
3852         if (qualifier.storage == EvqVaryingOut)
3853             if ((isEsProfile() && version >= 320) ||
3854                 extensionTurnedOn(E_GL_NV_mesh_shader))
3855                 return;
3856         break;
3857     default:
3858         break;
3859     }
3860
3861 #endif
3862
3863     // last member of ssbo block exception:
3864     if (qualifier.storage == EvqBuffer && lastMember)
3865         return;
3866
3867     arraySizeRequiredCheck(loc, *arraySizes);
3868 }
3869
3870 void TParseContext::arrayOfArrayVersionCheck(const TSourceLoc& loc, const TArraySizes* sizes)
3871 {
3872     if (sizes == nullptr || sizes->getNumDims() == 1)
3873         return;
3874
3875     const char* feature = "arrays of arrays";
3876
3877     requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature);
3878     profileRequires(loc, EEsProfile, 310, nullptr, feature);
3879     profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, feature);
3880 }
3881
3882 //
3883 // Do all the semantic checking for declaring or redeclaring an array, with and
3884 // without a size, and make the right changes to the symbol table.
3885 //
3886 void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifier, const TType& type, TSymbol*& symbol)
3887 {
3888     if (symbol == nullptr) {
3889         bool currentScope;
3890         symbol = symbolTable.find(identifier, nullptr, &currentScope);
3891
3892         if (symbol && builtInName(identifier) && ! symbolTable.atBuiltInLevel()) {
3893             // bad shader (errors already reported) trying to redeclare a built-in name as an array
3894             symbol = nullptr;
3895             return;
3896         }
3897         if (symbol == nullptr || ! currentScope) {
3898             //
3899             // Successfully process a new definition.
3900             // (Redeclarations have to take place at the same scope; otherwise they are hiding declarations)
3901             //
3902             symbol = new TVariable(&identifier, type);
3903             symbolTable.insert(*symbol);
3904             if (symbolTable.atGlobalLevel())
3905                 trackLinkage(*symbol);
3906
3907 #ifndef GLSLANG_WEB
3908             if (! symbolTable.atBuiltInLevel()) {
3909                 if (isIoResizeArray(type)) {
3910                     ioArraySymbolResizeList.push_back(symbol);
3911                     checkIoArraysConsistency(loc, true);
3912                 } else
3913                     fixIoArraySize(loc, symbol->getWritableType());
3914             }
3915 #endif
3916
3917             return;
3918         }
3919         if (symbol->getAsAnonMember()) {
3920             error(loc, "cannot redeclare a user-block member array", identifier.c_str(), "");
3921             symbol = nullptr;
3922             return;
3923         }
3924     }
3925
3926     //
3927     // Process a redeclaration.
3928     //
3929
3930     if (symbol == nullptr) {
3931         error(loc, "array variable name expected", identifier.c_str(), "");
3932         return;
3933     }
3934
3935     // redeclareBuiltinVariable() should have already done the copyUp()
3936     TType& existingType = symbol->getWritableType();
3937
3938     if (! existingType.isArray()) {
3939         error(loc, "redeclaring non-array as array", identifier.c_str(), "");
3940         return;
3941     }
3942
3943     if (! existingType.sameElementType(type)) {
3944         error(loc, "redeclaration of array with a different element type", identifier.c_str(), "");
3945         return;
3946     }
3947
3948     if (! existingType.sameInnerArrayness(type)) {
3949         error(loc, "redeclaration of array with a different array dimensions or sizes", identifier.c_str(), "");
3950         return;
3951     }
3952
3953 #ifndef GLSLANG_WEB
3954     if (existingType.isSizedArray()) {
3955         // be more leniant for input arrays to geometry shaders and tessellation control outputs, where the redeclaration is the same size
3956         if (! (isIoResizeArray(type) && existingType.getOuterArraySize() == type.getOuterArraySize()))
3957             error(loc, "redeclaration of array with size", identifier.c_str(), "");
3958         return;
3959     }
3960
3961     arrayLimitCheck(loc, identifier, type.getOuterArraySize());
3962
3963     existingType.updateArraySizes(type);
3964
3965     if (isIoResizeArray(type))
3966         checkIoArraysConsistency(loc);
3967 #endif
3968 }
3969
3970 #ifndef GLSLANG_WEB
3971
3972 // Policy and error check for needing a runtime sized array.
3973 void TParseContext::checkRuntimeSizable(const TSourceLoc& loc, const TIntermTyped& base)
3974 {
3975     // runtime length implies runtime sizeable, so no problem
3976     if (isRuntimeLength(base))
3977         return;
3978
3979     // Check for last member of a bufferreference type, which is runtime sizeable
3980     // but doesn't support runtime length
3981     if (base.getType().getQualifier().storage == EvqBuffer) {
3982         const TIntermBinary* binary = base.getAsBinaryNode();
3983         if (binary != nullptr &&
3984             binary->getOp() == EOpIndexDirectStruct &&
3985             binary->getLeft()->isReference()) {
3986
3987             const int index = binary->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
3988             const int memberCount = (int)binary->getLeft()->getType().getReferentType()->getStruct()->size();
3989             if (index == memberCount - 1)
3990                 return;
3991         }
3992     }
3993
3994     // check for additional things allowed by GL_EXT_nonuniform_qualifier
3995     if (base.getBasicType() == EbtSampler || base.getBasicType() == EbtAccStruct ||
3996         (base.getBasicType() == EbtBlock && base.getType().getQualifier().isUniformOrBuffer()))
3997         requireExtensions(loc, 1, &E_GL_EXT_nonuniform_qualifier, "variable index");
3998     else
3999         error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable");
4000 }
4001
4002 // Policy decision for whether a run-time .length() is allowed.
4003 bool TParseContext::isRuntimeLength(const TIntermTyped& base) const
4004 {
4005     if (base.getType().getQualifier().storage == EvqBuffer) {
4006         // in a buffer block
4007         const TIntermBinary* binary = base.getAsBinaryNode();
4008         if (binary != nullptr && binary->getOp() == EOpIndexDirectStruct) {
4009             // is it the last member?
4010             const int index = binary->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
4011
4012             if (binary->getLeft()->isReference())
4013                 return false;
4014
4015             const int memberCount = (int)binary->getLeft()->getType().getStruct()->size();
4016             if (index == memberCount - 1)
4017                 return true;
4018         }
4019     }
4020
4021     return false;
4022 }
4023
4024 // Check if mesh perviewNV attributes have a view dimension
4025 // and resize it to gl_MaxMeshViewCountNV when implicitly sized.
4026 void TParseContext::checkAndResizeMeshViewDim(const TSourceLoc& loc, TType& type, bool isBlockMember)
4027 {
4028     // see if member is a per-view attribute
4029     if (!type.getQualifier().isPerView())
4030         return;
4031
4032     if ((isBlockMember && type.isArray()) || (!isBlockMember && type.isArrayOfArrays())) {
4033         // since we don't have the maxMeshViewCountNV set during parsing builtins, we hardcode the value.
4034         int maxViewCount = parsingBuiltins ? 4 : resources.maxMeshViewCountNV;
4035         // For block members, outermost array dimension is the view dimension.
4036         // For non-block members, outermost array dimension is the vertex/primitive dimension
4037         // and 2nd outermost is the view dimension.
4038         int viewDim = isBlockMember ? 0 : 1;
4039         int viewDimSize = type.getArraySizes()->getDimSize(viewDim);
4040
4041         if (viewDimSize != UnsizedArraySize && viewDimSize != maxViewCount)
4042             error(loc, "mesh view output array size must be gl_MaxMeshViewCountNV or implicitly sized", "[]", "");
4043         else if (viewDimSize == UnsizedArraySize)
4044             type.getArraySizes()->setDimSize(viewDim, maxViewCount);
4045     }
4046     else {
4047         error(loc, "requires a view array dimension", "perviewNV", "");
4048     }
4049 }
4050
4051 #endif // GLSLANG_WEB
4052
4053 // Returns true if the first argument to the #line directive is the line number for the next line.
4054 //
4055 // Desktop, pre-version 3.30:  "After processing this directive
4056 // (including its new-line), the implementation will behave as if it is compiling at line number line+1 and
4057 // source string number source-string-number."
4058 //
4059 // Desktop, version 3.30 and later, and ES:  "After processing this directive
4060 // (including its new-line), the implementation will behave as if it is compiling at line number line and
4061 // source string number source-string-number.
4062 bool TParseContext::lineDirectiveShouldSetNextLine() const
4063 {
4064     return isEsProfile() || version >= 330;
4065 }
4066
4067 //
4068 // Enforce non-initializer type/qualifier rules.
4069 //
4070 void TParseContext::nonInitConstCheck(const TSourceLoc& loc, TString& identifier, TType& type)
4071 {
4072     //
4073     // Make the qualifier make sense, given that there is not an initializer.
4074     //
4075     if (type.getQualifier().storage == EvqConst ||
4076         type.getQualifier().storage == EvqConstReadOnly) {
4077         type.getQualifier().makeTemporary();
4078         error(loc, "variables with qualifier 'const' must be initialized", identifier.c_str(), "");
4079     }
4080 }
4081
4082 //
4083 // See if the identifier is a built-in symbol that can be redeclared, and if so,
4084 // copy the symbol table's read-only built-in variable to the current
4085 // global level, where it can be modified based on the passed in type.
4086 //
4087 // Returns nullptr if no redeclaration took place; meaning a normal declaration still
4088 // needs to occur for it, not necessarily an error.
4089 //
4090 // Returns a redeclared and type-modified variable if a redeclarated occurred.
4091 //
4092 TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TString& identifier,
4093                                                  const TQualifier& qualifier, const TShaderQualifiers& publicType)
4094 {
4095 #ifndef GLSLANG_WEB
4096     if (! builtInName(identifier) || symbolTable.atBuiltInLevel() || ! symbolTable.atGlobalLevel())
4097         return nullptr;
4098
4099     bool nonEsRedecls = (!isEsProfile() && (version >= 130 || identifier == "gl_TexCoord"));
4100     bool    esRedecls = (isEsProfile() &&
4101                          (version >= 320 || extensionsTurnedOn(Num_AEP_shader_io_blocks, AEP_shader_io_blocks)));
4102     if (! esRedecls && ! nonEsRedecls)
4103         return nullptr;
4104
4105     // Special case when using GL_ARB_separate_shader_objects
4106     bool ssoPre150 = false;  // means the only reason this variable is redeclared is due to this combination
4107     if (!isEsProfile() && version <= 140 && extensionTurnedOn(E_GL_ARB_separate_shader_objects)) {
4108         if (identifier == "gl_Position"     ||
4109             identifier == "gl_PointSize"    ||
4110             identifier == "gl_ClipVertex"   ||
4111             identifier == "gl_FogFragCoord")
4112             ssoPre150 = true;
4113     }
4114
4115     // Potentially redeclaring a built-in variable...
4116
4117     if (ssoPre150 ||
4118         (identifier == "gl_FragDepth"           && ((nonEsRedecls && version >= 420) || esRedecls)) ||
4119         (identifier == "gl_FragCoord"           && ((nonEsRedecls && version >= 150) || esRedecls)) ||
4120          identifier == "gl_ClipDistance"                                                            ||
4121          identifier == "gl_CullDistance"                                                            ||
4122          identifier == "gl_FrontColor"                                                              ||
4123          identifier == "gl_BackColor"                                                               ||
4124          identifier == "gl_FrontSecondaryColor"                                                     ||
4125          identifier == "gl_BackSecondaryColor"                                                      ||
4126          identifier == "gl_SecondaryColor"                                                          ||
4127         (identifier == "gl_Color"               && language == EShLangFragment)                     ||
4128         (identifier == "gl_FragStencilRefARB"   && (nonEsRedecls && version >= 140)
4129                                                 && language == EShLangFragment)                     ||
4130          identifier == "gl_SampleMask"                                                              ||
4131          identifier == "gl_Layer"                                                                   ||
4132          identifier == "gl_PrimitiveIndicesNV"                                                      ||
4133          identifier == "gl_TexCoord") {
4134
4135         // Find the existing symbol, if any.
4136         bool builtIn;
4137         TSymbol* symbol = symbolTable.find(identifier, &builtIn);
4138
4139         // If the symbol was not found, this must be a version/profile/stage
4140         // that doesn't have it.
4141         if (! symbol)
4142             return nullptr;
4143
4144         // If it wasn't at a built-in level, then it's already been redeclared;
4145         // that is, this is a redeclaration of a redeclaration; reuse that initial
4146         // redeclaration.  Otherwise, make the new one.
4147         if (builtIn)
4148             makeEditable(symbol);
4149
4150         // Now, modify the type of the copy, as per the type of the current redeclaration.
4151
4152         TQualifier& symbolQualifier = symbol->getWritableType().getQualifier();
4153         if (ssoPre150) {
4154             if (intermediate.inIoAccessed(identifier))
4155                 error(loc, "cannot redeclare after use", identifier.c_str(), "");
4156             if (qualifier.hasLayout())
4157                 error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str());
4158             if (qualifier.isMemory() || qualifier.isAuxiliary() || (language == EShLangVertex   && qualifier.storage != EvqVaryingOut) ||
4159                                                                    (language == EShLangFragment && qualifier.storage != EvqVaryingIn))
4160                 error(loc, "cannot change storage, memory, or auxiliary qualification of", "redeclaration", symbol->getName().c_str());
4161             if (! qualifier.smooth)
4162                 error(loc, "cannot change interpolation qualification of", "redeclaration", symbol->getName().c_str());
4163         } else if (identifier == "gl_FrontColor"          ||
4164                    identifier == "gl_BackColor"           ||
4165                    identifier == "gl_FrontSecondaryColor" ||
4166                    identifier == "gl_BackSecondaryColor"  ||
4167                    identifier == "gl_SecondaryColor"      ||
4168                    identifier == "gl_Color") {
4169             symbolQualifier.flat = qualifier.flat;
4170             symbolQualifier.smooth = qualifier.smooth;
4171             symbolQualifier.nopersp = qualifier.nopersp;
4172             if (qualifier.hasLayout())
4173                 error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str());
4174             if (qualifier.isMemory() || qualifier.isAuxiliary() || symbol->getType().getQualifier().storage != qualifier.storage)
4175                 error(loc, "cannot change storage, memory, or auxiliary qualification of", "redeclaration", symbol->getName().c_str());
4176         } else if (identifier == "gl_TexCoord"     ||
4177                    identifier == "gl_ClipDistance" ||
4178                    identifier == "gl_CullDistance") {
4179             if (qualifier.hasLayout() || qualifier.isMemory() || qualifier.isAuxiliary() ||
4180                 qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
4181                 symbolQualifier.storage != qualifier.storage)
4182                 error(loc, "cannot change qualification of", "redeclaration", symbol->getName().c_str());
4183         } else if (identifier == "gl_FragCoord") {
4184             if (intermediate.inIoAccessed("gl_FragCoord"))
4185                 error(loc, "cannot redeclare after use", "gl_FragCoord", "");
4186             if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
4187                 qualifier.isMemory() || qualifier.isAuxiliary())
4188                 error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str());
4189             if (qualifier.storage != EvqVaryingIn)
4190                 error(loc, "cannot change input storage qualification of", "redeclaration", symbol->getName().c_str());
4191             if (! builtIn && (publicType.pixelCenterInteger != intermediate.getPixelCenterInteger() ||
4192                               publicType.originUpperLeft != intermediate.getOriginUpperLeft()))
4193                 error(loc, "cannot redeclare with different qualification:", "redeclaration", symbol->getName().c_str());
4194             if (publicType.pixelCenterInteger)
4195                 intermediate.setPixelCenterInteger();
4196             if (publicType.originUpperLeft)
4197                 intermediate.setOriginUpperLeft();
4198         } else if (identifier == "gl_FragDepth") {
4199             if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
4200                 qualifier.isMemory() || qualifier.isAuxiliary())
4201                 error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str());
4202             if (qualifier.storage != EvqVaryingOut)
4203                 error(loc, "cannot change output storage qualification of", "redeclaration", symbol->getName().c_str());
4204             if (publicType.layoutDepth != EldNone) {
4205                 if (intermediate.inIoAccessed("gl_FragDepth"))
4206                     error(loc, "cannot redeclare after use", "gl_FragDepth", "");
4207                 if (! intermediate.setDepth(publicType.layoutDepth))
4208                     error(loc, "all redeclarations must use the same depth layout on", "redeclaration", symbol->getName().c_str());
4209             }
4210         }
4211         else if (
4212             identifier == "gl_PrimitiveIndicesNV" ||
4213             identifier == "gl_FragStencilRefARB") {
4214             if (qualifier.hasLayout())
4215                 error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str());
4216             if (qualifier.storage != EvqVaryingOut)
4217                 error(loc, "cannot change output storage qualification of", "redeclaration", symbol->getName().c_str());
4218         }
4219         else if (identifier == "gl_SampleMask") {
4220             if (!publicType.layoutOverrideCoverage) {
4221                 error(loc, "redeclaration only allowed for override_coverage layout", "redeclaration", symbol->getName().c_str());
4222             }
4223             intermediate.setLayoutOverrideCoverage();
4224         }
4225         else if (identifier == "gl_Layer") {
4226             if (!qualifier.layoutViewportRelative && qualifier.layoutSecondaryViewportRelativeOffset == -2048)
4227                 error(loc, "redeclaration only allowed for viewport_relative or secondary_view_offset layout", "redeclaration", symbol->getName().c_str());
4228             symbolQualifier.layoutViewportRelative = qualifier.layoutViewportRelative;
4229             symbolQualifier.layoutSecondaryViewportRelativeOffset = qualifier.layoutSecondaryViewportRelativeOffset;
4230         }
4231
4232         // TODO: semantics quality: separate smooth from nothing declared, then use IsInterpolation for several tests above
4233
4234         return symbol;
4235     }
4236 #endif
4237
4238     return nullptr;
4239 }
4240
4241 //
4242 // Either redeclare the requested block, or give an error message why it can't be done.
4243 //
4244 // TODO: functionality: explicitly sizing members of redeclared blocks is not giving them an explicit size
4245 void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newTypeList, const TString& blockName,
4246     const TString* instanceName, TArraySizes* arraySizes)
4247 {
4248 #ifndef GLSLANG_WEB
4249     const char* feature = "built-in block redeclaration";
4250     profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature);
4251     profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_separate_shader_objects, feature);
4252
4253     if (blockName != "gl_PerVertex" && blockName != "gl_PerFragment" &&
4254         blockName != "gl_MeshPerVertexNV" && blockName != "gl_MeshPerPrimitiveNV") {
4255         error(loc, "cannot redeclare block: ", "block declaration", blockName.c_str());
4256         return;
4257     }
4258
4259     // Redeclaring a built-in block...
4260
4261     if (instanceName && ! builtInName(*instanceName)) {
4262         error(loc, "cannot redeclare a built-in block with a user name", instanceName->c_str(), "");
4263         return;
4264     }
4265
4266     // Blocks with instance names are easy to find, lookup the instance name,
4267     // Anonymous blocks need to be found via a member.
4268     bool builtIn;
4269     TSymbol* block;
4270     if (instanceName)
4271         block = symbolTable.find(*instanceName, &builtIn);
4272     else
4273         block = symbolTable.find(newTypeList.front().type->getFieldName(), &builtIn);
4274
4275     // If the block was not found, this must be a version/profile/stage
4276     // that doesn't have it, or the instance name is wrong.
4277     const char* errorName = instanceName ? instanceName->c_str() : newTypeList.front().type->getFieldName().c_str();
4278     if (! block) {
4279         error(loc, "no declaration found for redeclaration", errorName, "");
4280         return;
4281     }
4282     // Built-in blocks cannot be redeclared more than once, which if happened,
4283     // we'd be finding the already redeclared one here, rather than the built in.
4284     if (! builtIn) {
4285         error(loc, "can only redeclare a built-in block once, and before any use", blockName.c_str(), "");
4286         return;
4287     }
4288
4289     // Copy the block to make a writable version, to insert into the block table after editing.
4290     block = symbolTable.copyUpDeferredInsert(block);
4291
4292     if (block->getType().getBasicType() != EbtBlock) {
4293         error(loc, "cannot redeclare a non block as a block", errorName, "");
4294         return;
4295     }
4296
4297     // Fix XFB stuff up, it applies to the order of the redeclaration, not
4298     // the order of the original members.
4299     if (currentBlockQualifier.storage == EvqVaryingOut && globalOutputDefaults.hasXfbBuffer()) {
4300         if (!currentBlockQualifier.hasXfbBuffer())
4301             currentBlockQualifier.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer;
4302         if (!currentBlockQualifier.hasStream())
4303             currentBlockQualifier.layoutStream = globalOutputDefaults.layoutStream;
4304         fixXfbOffsets(currentBlockQualifier, newTypeList);
4305     }
4306
4307     // Edit and error check the container against the redeclaration
4308     //  - remove unused members
4309     //  - ensure remaining qualifiers/types match
4310
4311     TType& type = block->getWritableType();
4312
4313     // if gl_PerVertex is redeclared for the purpose of passing through "gl_Position"
4314     // for passthrough purpose, the redeclared block should have the same qualifers as
4315     // the current one
4316     if (currentBlockQualifier.layoutPassthrough) {
4317         type.getQualifier().layoutPassthrough = currentBlockQualifier.layoutPassthrough;
4318         type.getQualifier().storage = currentBlockQualifier.storage;
4319         type.getQualifier().layoutStream = currentBlockQualifier.layoutStream;
4320         type.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer;
4321     }
4322
4323     TTypeList::iterator member = type.getWritableStruct()->begin();
4324     size_t numOriginalMembersFound = 0;
4325     while (member != type.getStruct()->end()) {
4326         // look for match
4327         bool found = false;
4328         TTypeList::const_iterator newMember;
4329         TSourceLoc memberLoc;
4330         memberLoc.init();
4331         for (newMember = newTypeList.begin(); newMember != newTypeList.end(); ++newMember) {
4332             if (member->type->getFieldName() == newMember->type->getFieldName()) {
4333                 found = true;
4334                 memberLoc = newMember->loc;
4335                 break;
4336             }
4337         }
4338
4339         if (found) {
4340             ++numOriginalMembersFound;
4341             // - ensure match between redeclared members' types
4342             // - check for things that can't be changed
4343             // - update things that can be changed
4344             TType& oldType = *member->type;
4345             const TType& newType = *newMember->type;
4346             if (! newType.sameElementType(oldType))
4347                 error(memberLoc, "cannot redeclare block member with a different type", member->type->getFieldName().c_str(), "");
4348             if (oldType.isArray() != newType.isArray())
4349                 error(memberLoc, "cannot change arrayness of redeclared block member", member->type->getFieldName().c_str(), "");
4350             else if (! oldType.getQualifier().isPerView() && ! oldType.sameArrayness(newType) && oldType.isSizedArray())
4351                 error(memberLoc, "cannot change array size of redeclared block member", member->type->getFieldName().c_str(), "");
4352             else if (! oldType.getQualifier().isPerView() && newType.isArray())
4353                 arrayLimitCheck(loc, member->type->getFieldName(), newType.getOuterArraySize());
4354             if (oldType.getQualifier().isPerView() && ! newType.getQualifier().isPerView())
4355                 error(memberLoc, "missing perviewNV qualifier to redeclared block member", member->type->getFieldName().c_str(), "");
4356             else if (! oldType.getQualifier().isPerView() && newType.getQualifier().isPerView())
4357                 error(memberLoc, "cannot add perviewNV qualifier to redeclared block member", member->type->getFieldName().c_str(), "");
4358             else if (newType.getQualifier().isPerView()) {
4359                 if (oldType.getArraySizes()->getNumDims() != newType.getArraySizes()->getNumDims())
4360                     error(memberLoc, "cannot change arrayness of redeclared block member", member->type->getFieldName().c_str(), "");
4361                 else if (! newType.isUnsizedArray() && newType.getOuterArraySize() != resources.maxMeshViewCountNV)
4362                     error(loc, "mesh view output array size must be gl_MaxMeshViewCountNV or implicitly sized", "[]", "");
4363                 else if (newType.getArraySizes()->getNumDims() == 2) {
4364                     int innerDimSize = newType.getArraySizes()->getDimSize(1);
4365                     arrayLimitCheck(memberLoc, member->type->getFieldName(), innerDimSize);
4366                     oldType.getArraySizes()->setDimSize(1, innerDimSize);
4367                 }
4368             }
4369             if (oldType.getQualifier().isPerPrimitive() && ! newType.getQualifier().isPerPrimitive())
4370                 error(memberLoc, "missing perprimitiveNV qualifier to redeclared block member", member->type->getFieldName().c_str(), "");
4371             else if (! oldType.getQualifier().isPerPrimitive() && newType.getQualifier().isPerPrimitive())
4372                 error(memberLoc, "cannot add perprimitiveNV qualifier to redeclared block member", member->type->getFieldName().c_str(), "");
4373             if (newType.getQualifier().isMemory())
4374                 error(memberLoc, "cannot add memory qualifier to redeclared block member", member->type->getFieldName().c_str(), "");
4375             if (newType.getQualifier().hasNonXfbLayout())
4376                 error(memberLoc, "cannot add non-XFB layout to redeclared block member", member->type->getFieldName().c_str(), "");
4377             if (newType.getQualifier().patch)
4378                 error(memberLoc, "cannot add patch to redeclared block member", member->type->getFieldName().c_str(), "");
4379             if (newType.getQualifier().hasXfbBuffer() &&
4380                 newType.getQualifier().layoutXfbBuffer != currentBlockQualifier.layoutXfbBuffer)
4381                 error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_buffer", "");
4382             if (newType.getQualifier().hasStream() &&
4383                 newType.getQualifier().layoutStream != currentBlockQualifier.layoutStream)
4384                 error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_stream", "");
4385             oldType.getQualifier().centroid = newType.getQualifier().centroid;
4386             oldType.getQualifier().sample = newType.getQualifier().sample;
4387             oldType.getQualifier().invariant = newType.getQualifier().invariant;
4388             oldType.getQualifier().noContraction = newType.getQualifier().noContraction;
4389             oldType.getQualifier().smooth = newType.getQualifier().smooth;
4390             oldType.getQualifier().flat = newType.getQualifier().flat;
4391             oldType.getQualifier().nopersp = newType.getQualifier().nopersp;
4392             oldType.getQualifier().layoutXfbOffset = newType.getQualifier().layoutXfbOffset;
4393             oldType.getQualifier().layoutXfbBuffer = newType.getQualifier().layoutXfbBuffer;
4394             oldType.getQualifier().layoutXfbStride = newType.getQualifier().layoutXfbStride;
4395             if (oldType.getQualifier().layoutXfbOffset != TQualifier::layoutXfbBufferEnd) {
4396                 // If any member has an xfb_offset, then the block's xfb_buffer inherents current xfb_buffer,
4397                 // and for xfb processing, the member needs it as well, along with xfb_stride.
4398                 type.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer;
4399                 oldType.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer;
4400             }
4401             if (oldType.isUnsizedArray() && newType.isSizedArray())
4402                 oldType.changeOuterArraySize(newType.getOuterArraySize());
4403
4404             //  check and process the member's type, which will include managing xfb information
4405             layoutTypeCheck(loc, oldType);
4406
4407             // go to next member
4408             ++member;
4409         } else {
4410             // For missing members of anonymous blocks that have been redeclared,
4411             // hide the original (shared) declaration.
4412             // Instance-named blocks can just have the member removed.
4413             if (instanceName)
4414                 member = type.getWritableStruct()->erase(member);
4415             else {
4416                 member->type->hideMember();
4417                 ++member;
4418             }
4419         }
4420     }
4421
4422     if (spvVersion.vulkan > 0) {
4423         // ...then streams apply to built-in blocks, instead of them being only on stream 0
4424         type.getQualifier().layoutStream = currentBlockQualifier.layoutStream;
4425     }
4426
4427     if (numOriginalMembersFound < newTypeList.size())
4428         error(loc, "block redeclaration has extra members", blockName.c_str(), "");
4429     if (type.isArray() != (arraySizes != nullptr) ||
4430         (type.isArray() && arraySizes != nullptr && type.getArraySizes()->getNumDims() != arraySizes->getNumDims()))
4431         error(loc, "cannot change arrayness of redeclared block", blockName.c_str(), "");
4432     else if (type.isArray()) {
4433         // At this point, we know both are arrays and both have the same number of dimensions.
4434
4435         // It is okay for a built-in block redeclaration to be unsized, and keep the size of the
4436         // original block declaration.
4437         if (!arraySizes->isSized() && type.isSizedArray())
4438             arraySizes->changeOuterSize(type.getOuterArraySize());
4439
4440         // And, okay to be giving a size to the array, by the redeclaration
4441         if (!type.isSizedArray() && arraySizes->isSized())
4442             type.changeOuterArraySize(arraySizes->getOuterSize());
4443
4444         // Now, they must match in all dimensions.
4445         if (type.isSizedArray() && *type.getArraySizes() != *arraySizes)
4446             error(loc, "cannot change array size of redeclared block", blockName.c_str(), "");
4447     }
4448
4449     symbolTable.insert(*block);
4450
4451     // Check for general layout qualifier errors
4452     layoutObjectCheck(loc, *block);
4453
4454     // Tracking for implicit sizing of array
4455     if (isIoResizeArray(block->getType())) {
4456         ioArraySymbolResizeList.push_back(block);
4457         checkIoArraysConsistency(loc, true);
4458     } else if (block->getType().isArray())
4459         fixIoArraySize(loc, block->getWritableType());
4460
4461     // Save it in the AST for linker use.
4462     trackLinkage(*block);
4463 #endif // GLSLANG_WEB
4464 }
4465
4466 void TParseContext::paramCheckFixStorage(const TSourceLoc& loc, const TStorageQualifier& qualifier, TType& type)
4467 {
4468     switch (qualifier) {
4469     case EvqConst:
4470     case EvqConstReadOnly:
4471         type.getQualifier().storage = EvqConstReadOnly;
4472         break;
4473     case EvqIn:
4474     case EvqOut:
4475     case EvqInOut:
4476         type.getQualifier().storage = qualifier;
4477         break;
4478     case EvqGlobal:
4479     case EvqTemporary:
4480         type.getQualifier().storage = EvqIn;
4481         break;
4482     default:
4483         type.getQualifier().storage = EvqIn;
4484         error(loc, "storage qualifier not allowed on function parameter", GetStorageQualifierString(qualifier), "");
4485         break;
4486     }
4487 }
4488
4489 void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& qualifier, TType& type)
4490 {
4491 #ifndef GLSLANG_WEB
4492     if (qualifier.isMemory()) {
4493         type.getQualifier().volatil   = qualifier.volatil;
4494         type.getQualifier().coherent  = qualifier.coherent;
4495         type.getQualifier().devicecoherent  = qualifier.devicecoherent ;
4496         type.getQualifier().queuefamilycoherent  = qualifier.queuefamilycoherent;
4497         type.getQualifier().workgroupcoherent  = qualifier.workgroupcoherent;
4498         type.getQualifier().subgroupcoherent  = qualifier.subgroupcoherent;
4499         type.getQualifier().shadercallcoherent = qualifier.shadercallcoherent;
4500         type.getQualifier().nonprivate = qualifier.nonprivate;
4501         type.getQualifier().readonly  = qualifier.readonly;
4502         type.getQualifier().writeonly = qualifier.writeonly;
4503         type.getQualifier().restrict  = qualifier.restrict;
4504     }
4505 #endif
4506
4507     if (qualifier.isAuxiliary() ||
4508         qualifier.isInterpolation())
4509         error(loc, "cannot use auxiliary or interpolation qualifiers on a function parameter", "", "");
4510     if (qualifier.hasLayout())
4511         error(loc, "cannot use layout qualifiers on a function parameter", "", "");
4512     if (qualifier.invariant)
4513         error(loc, "cannot use invariant qualifier on a function parameter", "", "");
4514     if (qualifier.isNoContraction()) {
4515         if (qualifier.isParamOutput())
4516             type.getQualifier().setNoContraction();
4517         else
4518             warn(loc, "qualifier has no effect on non-output parameters", "precise", "");
4519     }
4520     if (qualifier.isNonUniform())
4521         type.getQualifier().nonUniform = qualifier.nonUniform;
4522
4523     paramCheckFixStorage(loc, qualifier.storage, type);
4524 }
4525
4526 void TParseContext::nestedBlockCheck(const TSourceLoc& loc)
4527 {
4528     if (structNestingLevel > 0)
4529         error(loc, "cannot nest a block definition inside a structure or block", "", "");
4530     ++structNestingLevel;
4531 }
4532
4533 void TParseContext::nestedStructCheck(const TSourceLoc& loc)
4534 {
4535     if (structNestingLevel > 0)
4536         error(loc, "cannot nest a structure definition inside a structure or block", "", "");
4537     ++structNestingLevel;
4538 }
4539
4540 void TParseContext::arrayObjectCheck(const TSourceLoc& loc, const TType& type, const char* op)
4541 {
4542     // Some versions don't allow comparing arrays or structures containing arrays
4543     if (type.containsArray()) {
4544         profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, op);
4545         profileRequires(loc, EEsProfile, 300, nullptr, op);
4546     }
4547 }
4548
4549 void TParseContext::opaqueCheck(const TSourceLoc& loc, const TType& type, const char* op)
4550 {
4551     if (containsFieldWithBasicType(type, EbtSampler))
4552         error(loc, "can't use with samplers or structs containing samplers", op, "");
4553 }
4554
4555 void TParseContext::referenceCheck(const TSourceLoc& loc, const TType& type, const char* op)
4556 {
4557 #ifndef GLSLANG_WEB
4558     if (containsFieldWithBasicType(type, EbtReference))
4559         error(loc, "can't use with reference types", op, "");
4560 #endif
4561 }
4562
4563 void TParseContext::storage16BitAssignmentCheck(const TSourceLoc& loc, const TType& type, const char* op)
4564 {
4565 #ifndef GLSLANG_WEB
4566     if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtFloat16))
4567         requireFloat16Arithmetic(loc, op, "can't use with structs containing float16");
4568
4569     if (type.isArray() && type.getBasicType() == EbtFloat16)
4570         requireFloat16Arithmetic(loc, op, "can't use with arrays containing float16");
4571
4572     if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtInt16))
4573         requireInt16Arithmetic(loc, op, "can't use with structs containing int16");
4574
4575     if (type.isArray() && type.getBasicType() == EbtInt16)
4576         requireInt16Arithmetic(loc, op, "can't use with arrays containing int16");
4577
4578     if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtUint16))
4579         requireInt16Arithmetic(loc, op, "can't use with structs containing uint16");
4580
4581     if (type.isArray() && type.getBasicType() == EbtUint16)
4582         requireInt16Arithmetic(loc, op, "can't use with arrays containing uint16");
4583
4584     if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtInt8))
4585         requireInt8Arithmetic(loc, op, "can't use with structs containing int8");
4586
4587     if (type.isArray() && type.getBasicType() == EbtInt8)
4588         requireInt8Arithmetic(loc, op, "can't use with arrays containing int8");
4589
4590     if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtUint8))
4591         requireInt8Arithmetic(loc, op, "can't use with structs containing uint8");
4592
4593     if (type.isArray() && type.getBasicType() == EbtUint8)
4594         requireInt8Arithmetic(loc, op, "can't use with arrays containing uint8");
4595 #endif
4596 }
4597
4598 void TParseContext::specializationCheck(const TSourceLoc& loc, const TType& type, const char* op)
4599 {
4600     if (type.containsSpecializationSize())
4601         error(loc, "can't use with types containing arrays sized with a specialization constant", op, "");
4602 }
4603
4604 void TParseContext::structTypeCheck(const TSourceLoc& /*loc*/, TPublicType& publicType)
4605 {
4606     const TTypeList& typeList = *publicType.userDef->getStruct();
4607
4608     // fix and check for member storage qualifiers and types that don't belong within a structure
4609     for (unsigned int member = 0; member < typeList.size(); ++member) {
4610         TQualifier& memberQualifier = typeList[member].type->getQualifier();
4611         const TSourceLoc& memberLoc = typeList[member].loc;
4612         if (memberQualifier.isAuxiliary() ||
4613             memberQualifier.isInterpolation() ||
4614             (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal))
4615             error(memberLoc, "cannot use storage or interpolation qualifiers on structure members", typeList[member].type->getFieldName().c_str(), "");
4616         if (memberQualifier.isMemory())
4617             error(memberLoc, "cannot use memory qualifiers on structure members", typeList[member].type->getFieldName().c_str(), "");
4618         if (memberQualifier.hasLayout()) {
4619             error(memberLoc, "cannot use layout qualifiers on structure members", typeList[member].type->getFieldName().c_str(), "");
4620             memberQualifier.clearLayout();
4621         }
4622         if (memberQualifier.invariant)
4623             error(memberLoc, "cannot use invariant qualifier on structure members", typeList[member].type->getFieldName().c_str(), "");
4624     }
4625 }
4626
4627 //
4628 // See if this loop satisfies the limitations for ES 2.0 (version 100) for loops in Appendex A:
4629 //
4630 // "The loop index has type int or float.
4631 //
4632 // "The for statement has the form:
4633 //     for ( init-declaration ; condition ; expression )
4634 //     init-declaration has the form: type-specifier identifier = constant-expression
4635 //     condition has the form:  loop-index relational_operator constant-expression
4636 //         where relational_operator is one of: > >= < <= == or !=
4637 //     expression [sic] has one of the following forms:
4638 //         loop-index++
4639 //         loop-index--
4640 //         loop-index += constant-expression
4641 //         loop-index -= constant-expression
4642 //
4643 // The body is handled in an AST traversal.
4644 //
4645 void TParseContext::inductiveLoopCheck(const TSourceLoc& loc, TIntermNode* init, TIntermLoop* loop)
4646 {
4647 #ifndef GLSLANG_WEB
4648     // loop index init must exist and be a declaration, which shows up in the AST as an aggregate of size 1 of the declaration
4649     bool badInit = false;
4650     if (! init || ! init->getAsAggregate() || init->getAsAggregate()->getSequence().size() != 1)
4651         badInit = true;
4652     TIntermBinary* binaryInit = 0;
4653     if (! badInit) {
4654         // get the declaration assignment
4655         binaryInit = init->getAsAggregate()->getSequence()[0]->getAsBinaryNode();
4656         if (! binaryInit)
4657             badInit = true;
4658     }
4659     if (badInit) {
4660         error(loc, "inductive-loop init-declaration requires the form \"type-specifier loop-index = constant-expression\"", "limitations", "");
4661         return;
4662     }
4663
4664     // loop index must be type int or float
4665     if (! binaryInit->getType().isScalar() || (binaryInit->getBasicType() != EbtInt && binaryInit->getBasicType() != EbtFloat)) {
4666         error(loc, "inductive loop requires a scalar 'int' or 'float' loop index", "limitations", "");
4667         return;
4668     }
4669
4670     // init is the form "loop-index = constant"
4671     if (binaryInit->getOp() != EOpAssign || ! binaryInit->getLeft()->getAsSymbolNode() || ! binaryInit->getRight()->getAsConstantUnion()) {
4672         error(loc, "inductive-loop init-declaration requires the form \"type-specifier loop-index = constant-expression\"", "limitations", "");
4673         return;
4674     }
4675
4676     // get the unique id of the loop index
4677     int loopIndex = binaryInit->getLeft()->getAsSymbolNode()->getId();
4678     inductiveLoopIds.insert(loopIndex);
4679
4680     // condition's form must be "loop-index relational-operator constant-expression"
4681     bool badCond = ! loop->getTest();
4682     if (! badCond) {
4683         TIntermBinary* binaryCond = loop->getTest()->getAsBinaryNode();
4684         badCond = ! binaryCond;
4685         if (! badCond) {
4686             switch (binaryCond->getOp()) {
4687             case EOpGreaterThan:
4688             case EOpGreaterThanEqual:
4689             case EOpLessThan:
4690             case EOpLessThanEqual:
4691             case EOpEqual:
4692             case EOpNotEqual:
4693                 break;
4694             default:
4695                 badCond = true;
4696             }
4697         }
4698         if (binaryCond && (! binaryCond->getLeft()->getAsSymbolNode() ||
4699                            binaryCond->getLeft()->getAsSymbolNode()->getId() != loopIndex ||
4700                            ! binaryCond->getRight()->getAsConstantUnion()))
4701             badCond = true;
4702     }
4703     if (badCond) {
4704         error(loc, "inductive-loop condition requires the form \"loop-index <comparison-op> constant-expression\"", "limitations", "");
4705         return;
4706     }
4707
4708     // loop-index++
4709     // loop-index--
4710     // loop-index += constant-expression
4711     // loop-index -= constant-expression
4712     bool badTerminal = ! loop->getTerminal();
4713     if (! badTerminal) {
4714         TIntermUnary* unaryTerminal = loop->getTerminal()->getAsUnaryNode();
4715         TIntermBinary* binaryTerminal = loop->getTerminal()->getAsBinaryNode();
4716         if (unaryTerminal || binaryTerminal) {
4717             switch(loop->getTerminal()->getAsOperator()->getOp()) {
4718             case EOpPostDecrement:
4719             case EOpPostIncrement:
4720             case EOpAddAssign:
4721             case EOpSubAssign:
4722                 break;
4723             default:
4724                 badTerminal = true;
4725             }
4726         } else
4727             badTerminal = true;
4728         if (binaryTerminal && (! binaryTerminal->getLeft()->getAsSymbolNode() ||
4729                                binaryTerminal->getLeft()->getAsSymbolNode()->getId() != loopIndex ||
4730                                ! binaryTerminal->getRight()->getAsConstantUnion()))
4731             badTerminal = true;
4732         if (unaryTerminal && (! unaryTerminal->getOperand()->getAsSymbolNode() ||
4733                               unaryTerminal->getOperand()->getAsSymbolNode()->getId() != loopIndex))
4734             badTerminal = true;
4735     }
4736     if (badTerminal) {
4737         error(loc, "inductive-loop termination requires the form \"loop-index++, loop-index--, loop-index += constant-expression, or loop-index -= constant-expression\"", "limitations", "");
4738         return;
4739     }
4740
4741     // the body
4742     inductiveLoopBodyCheck(loop->getBody(), loopIndex, symbolTable);
4743 #endif
4744 }
4745
4746 #ifndef GLSLANG_WEB
4747 // Do limit checks for built-in arrays.
4748 void TParseContext::arrayLimitCheck(const TSourceLoc& loc, const TString& identifier, int size)
4749 {
4750     if (identifier.compare("gl_TexCoord") == 0)
4751         limitCheck(loc, size, "gl_MaxTextureCoords", "gl_TexCoord array size");
4752     else if (identifier.compare("gl_ClipDistance") == 0)
4753         limitCheck(loc, size, "gl_MaxClipDistances", "gl_ClipDistance array size");
4754     else if (identifier.compare("gl_CullDistance") == 0)
4755         limitCheck(loc, size, "gl_MaxCullDistances", "gl_CullDistance array size");
4756     else if (identifier.compare("gl_ClipDistancePerViewNV") == 0)
4757         limitCheck(loc, size, "gl_MaxClipDistances", "gl_ClipDistancePerViewNV array size");
4758     else if (identifier.compare("gl_CullDistancePerViewNV") == 0)
4759         limitCheck(loc, size, "gl_MaxCullDistances", "gl_CullDistancePerViewNV array size");
4760 }
4761 #endif // GLSLANG_WEB
4762
4763 // See if the provided value is less than or equal to the symbol indicated by limit,
4764 // which should be a constant in the symbol table.
4765 void TParseContext::limitCheck(const TSourceLoc& loc, int value, const char* limit, const char* feature)
4766 {
4767     TSymbol* symbol = symbolTable.find(limit);
4768     assert(symbol->getAsVariable());
4769     const TConstUnionArray& constArray = symbol->getAsVariable()->getConstArray();
4770     assert(! constArray.empty());
4771     if (value > constArray[0].getIConst())
4772         error(loc, "must be less than or equal to", feature, "%s (%d)", limit, constArray[0].getIConst());
4773 }
4774
4775 #ifndef GLSLANG_WEB
4776
4777 //
4778 // Do any additional error checking, etc., once we know the parsing is done.
4779 //
4780 void TParseContext::finish()
4781 {
4782     TParseContextBase::finish();
4783
4784     if (parsingBuiltins)
4785         return;
4786
4787     // Check on array indexes for ES 2.0 (version 100) limitations.
4788     for (size_t i = 0; i < needsIndexLimitationChecking.size(); ++i)
4789         constantIndexExpressionCheck(needsIndexLimitationChecking[i]);
4790
4791     // Check for stages that are enabled by extension.
4792     // Can't do this at the beginning, it is chicken and egg to add a stage by
4793     // extension.
4794     // Stage-specific features were correctly tested for already, this is just
4795     // about the stage itself.
4796     switch (language) {
4797     case EShLangGeometry:
4798         if (isEsProfile() && version == 310)
4799             requireExtensions(getCurrentLoc(), Num_AEP_geometry_shader, AEP_geometry_shader, "geometry shaders");
4800         break;
4801     case EShLangTessControl:
4802     case EShLangTessEvaluation:
4803         if (isEsProfile() && version == 310)
4804             requireExtensions(getCurrentLoc(), Num_AEP_tessellation_shader, AEP_tessellation_shader, "tessellation shaders");
4805         else if (!isEsProfile() && version < 400)
4806             requireExtensions(getCurrentLoc(), 1, &E_GL_ARB_tessellation_shader, "tessellation shaders");
4807         break;
4808     case EShLangCompute:
4809         if (!isEsProfile() && version < 430)
4810             requireExtensions(getCurrentLoc(), 1, &E_GL_ARB_compute_shader, "compute shaders");
4811         break;
4812     case EShLangTaskNV:
4813         requireExtensions(getCurrentLoc(), 1, &E_GL_NV_mesh_shader, "task shaders");
4814         break;
4815     case EShLangMeshNV:
4816         requireExtensions(getCurrentLoc(), 1, &E_GL_NV_mesh_shader, "mesh shaders");
4817         break;
4818     default:
4819         break;
4820     }
4821
4822     // Set default outputs for GL_NV_geometry_shader_passthrough
4823     if (language == EShLangGeometry && extensionTurnedOn(E_SPV_NV_geometry_shader_passthrough)) {
4824         if (intermediate.getOutputPrimitive() == ElgNone) {
4825             switch (intermediate.getInputPrimitive()) {
4826             case ElgPoints:      intermediate.setOutputPrimitive(ElgPoints);    break;
4827             case ElgLines:       intermediate.setOutputPrimitive(ElgLineStrip); break;
4828             case ElgTriangles:   intermediate.setOutputPrimitive(ElgTriangleStrip); break;
4829             default: break;
4830             }
4831         }
4832         if (intermediate.getVertices() == TQualifier::layoutNotSet) {
4833             switch (intermediate.getInputPrimitive()) {
4834             case ElgPoints:      intermediate.setVertices(1); break;
4835             case ElgLines:       intermediate.setVertices(2); break;
4836             case ElgTriangles:   intermediate.setVertices(3); break;
4837             default: break;
4838             }
4839         }
4840     }
4841 }
4842 #endif // GLSLANG_WEB
4843
4844 //
4845 // Layout qualifier stuff.
4846 //
4847
4848 // Put the id's layout qualification into the public type, for qualifiers not having a number set.
4849 // This is before we know any type information for error checking.
4850 void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publicType, TString& id)
4851 {
4852     std::transform(id.begin(), id.end(), id.begin(), ::tolower);
4853
4854     if (id == TQualifier::getLayoutMatrixString(ElmColumnMajor)) {
4855         publicType.qualifier.layoutMatrix = ElmColumnMajor;
4856         return;
4857     }
4858     if (id == TQualifier::getLayoutMatrixString(ElmRowMajor)) {
4859         publicType.qualifier.layoutMatrix = ElmRowMajor;
4860         return;
4861     }
4862     if (id == TQualifier::getLayoutPackingString(ElpPacked)) {
4863         if (spvVersion.spv != 0)
4864             spvRemoved(loc, "packed");
4865         publicType.qualifier.layoutPacking = ElpPacked;
4866         return;
4867     }
4868     if (id == TQualifier::getLayoutPackingString(ElpShared)) {
4869         if (spvVersion.spv != 0)
4870             spvRemoved(loc, "shared");
4871         publicType.qualifier.layoutPacking = ElpShared;
4872         return;
4873     }
4874     if (id == TQualifier::getLayoutPackingString(ElpStd140)) {
4875         publicType.qualifier.layoutPacking = ElpStd140;
4876         return;
4877     }
4878 #ifndef GLSLANG_WEB
4879     if (id == TQualifier::getLayoutPackingString(ElpStd430)) {
4880         requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "std430");
4881         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, "std430");
4882         profileRequires(loc, EEsProfile, 310, nullptr, "std430");
4883         publicType.qualifier.layoutPacking = ElpStd430;
4884         return;
4885     }
4886     if (id == TQualifier::getLayoutPackingString(ElpScalar)) {
4887         requireVulkan(loc, "scalar");
4888         requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "scalar block layout");
4889         publicType.qualifier.layoutPacking = ElpScalar;
4890         return;
4891     }
4892     // TODO: compile-time performance: may need to stop doing linear searches
4893     for (TLayoutFormat format = (TLayoutFormat)(ElfNone + 1); format < ElfCount; format = (TLayoutFormat)(format + 1)) {
4894         if (id == TQualifier::getLayoutFormatString(format)) {
4895             if ((format > ElfEsFloatGuard && format < ElfFloatGuard) ||
4896                 (format > ElfEsIntGuard && format < ElfIntGuard) ||
4897                 (format > ElfEsUintGuard && format < ElfCount))
4898                 requireProfile(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, "image load-store format");
4899             profileRequires(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, 420, E_GL_ARB_shader_image_load_store, "image load store");
4900             profileRequires(loc, EEsProfile, 310, E_GL_ARB_shader_image_load_store, "image load store");
4901             publicType.qualifier.layoutFormat = format;
4902             return;
4903         }
4904     }
4905     if (id == "push_constant") {
4906         requireVulkan(loc, "push_constant");
4907         publicType.qualifier.layoutPushConstant = true;
4908         return;
4909     }
4910     if (id == "buffer_reference") {
4911         requireVulkan(loc, "buffer_reference");
4912         requireExtensions(loc, 1, &E_GL_EXT_buffer_reference, "buffer_reference");
4913         publicType.qualifier.layoutBufferReference = true;
4914         intermediate.setUseStorageBuffer();
4915         intermediate.setUsePhysicalStorageBuffer();
4916         return;
4917     }
4918     if (language == EShLangGeometry || language == EShLangTessEvaluation || language == EShLangMeshNV) {
4919         if (id == TQualifier::getGeometryString(ElgTriangles)) {
4920             publicType.shaderQualifiers.geometry = ElgTriangles;
4921             return;
4922         }
4923         if (language == EShLangGeometry || language == EShLangMeshNV) {
4924             if (id == TQualifier::getGeometryString(ElgPoints)) {
4925                 publicType.shaderQualifiers.geometry = ElgPoints;
4926                 return;
4927             }
4928             if (id == TQualifier::getGeometryString(ElgLines)) {
4929                 publicType.shaderQualifiers.geometry = ElgLines;
4930                 return;
4931             }
4932             if (language == EShLangGeometry) {
4933                 if (id == TQualifier::getGeometryString(ElgLineStrip)) {
4934                     publicType.shaderQualifiers.geometry = ElgLineStrip;
4935                     return;
4936                 }
4937                 if (id == TQualifier::getGeometryString(ElgLinesAdjacency)) {
4938                     publicType.shaderQualifiers.geometry = ElgLinesAdjacency;
4939                     return;
4940                 }
4941                 if (id == TQualifier::getGeometryString(ElgTrianglesAdjacency)) {
4942                     publicType.shaderQualifiers.geometry = ElgTrianglesAdjacency;
4943                     return;
4944                 }
4945                 if (id == TQualifier::getGeometryString(ElgTriangleStrip)) {
4946                     publicType.shaderQualifiers.geometry = ElgTriangleStrip;
4947                     return;
4948                 }
4949                 if (id == "passthrough") {
4950                     requireExtensions(loc, 1, &E_SPV_NV_geometry_shader_passthrough, "geometry shader passthrough");
4951                     publicType.qualifier.layoutPassthrough = true;
4952                     intermediate.setGeoPassthroughEXT();
4953                     return;
4954                 }
4955             }
4956         } else {
4957             assert(language == EShLangTessEvaluation);
4958
4959             // input primitive
4960             if (id == TQualifier::getGeometryString(ElgTriangles)) {
4961                 publicType.shaderQualifiers.geometry = ElgTriangles;
4962                 return;
4963             }
4964             if (id == TQualifier::getGeometryString(ElgQuads)) {
4965                 publicType.shaderQualifiers.geometry = ElgQuads;
4966                 return;
4967             }
4968             if (id == TQualifier::getGeometryString(ElgIsolines)) {
4969                 publicType.shaderQualifiers.geometry = ElgIsolines;
4970                 return;
4971             }
4972
4973             // vertex spacing
4974             if (id == TQualifier::getVertexSpacingString(EvsEqual)) {
4975                 publicType.shaderQualifiers.spacing = EvsEqual;
4976                 return;
4977             }
4978             if (id == TQualifier::getVertexSpacingString(EvsFractionalEven)) {
4979                 publicType.shaderQualifiers.spacing = EvsFractionalEven;
4980                 return;
4981             }
4982             if (id == TQualifier::getVertexSpacingString(EvsFractionalOdd)) {
4983                 publicType.shaderQualifiers.spacing = EvsFractionalOdd;
4984                 return;
4985             }
4986
4987             // triangle order
4988             if (id == TQualifier::getVertexOrderString(EvoCw)) {
4989                 publicType.shaderQualifiers.order = EvoCw;
4990                 return;
4991             }
4992             if (id == TQualifier::getVertexOrderString(EvoCcw)) {
4993                 publicType.shaderQualifiers.order = EvoCcw;
4994                 return;
4995             }
4996
4997             // point mode
4998             if (id == "point_mode") {
4999                 publicType.shaderQualifiers.pointMode = true;
5000                 return;
5001             }
5002         }
5003     }
5004     if (language == EShLangFragment) {
5005         if (id == "origin_upper_left") {
5006             requireProfile(loc, ECoreProfile | ECompatibilityProfile, "origin_upper_left");
5007             publicType.shaderQualifiers.originUpperLeft = true;
5008             return;
5009         }
5010         if (id == "pixel_center_integer") {
5011             requireProfile(loc, ECoreProfile | ECompatibilityProfile, "pixel_center_integer");
5012             publicType.shaderQualifiers.pixelCenterInteger = true;
5013             return;
5014         }
5015         if (id == "early_fragment_tests") {
5016             profileRequires(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, 420, E_GL_ARB_shader_image_load_store, "early_fragment_tests");
5017             profileRequires(loc, EEsProfile, 310, nullptr, "early_fragment_tests");
5018             publicType.shaderQualifiers.earlyFragmentTests = true;
5019             return;
5020         }
5021         if (id == "post_depth_coverage") {
5022             requireExtensions(loc, Num_post_depth_coverageEXTs, post_depth_coverageEXTs, "post depth coverage");
5023             if (extensionTurnedOn(E_GL_ARB_post_depth_coverage)) {
5024                 publicType.shaderQualifiers.earlyFragmentTests = true;
5025             }
5026             publicType.shaderQualifiers.postDepthCoverage = true;
5027             return;
5028         }
5029         for (TLayoutDepth depth = (TLayoutDepth)(EldNone + 1); depth < EldCount; depth = (TLayoutDepth)(depth+1)) {
5030             if (id == TQualifier::getLayoutDepthString(depth)) {
5031                 requireProfile(loc, ECoreProfile | ECompatibilityProfile, "depth layout qualifier");
5032                 profileRequires(loc, ECoreProfile | ECompatibilityProfile, 420, nullptr, "depth layout qualifier");
5033                 publicType.shaderQualifiers.layoutDepth = depth;
5034                 return;
5035             }
5036         }
5037         for (TInterlockOrdering order = (TInterlockOrdering)(EioNone + 1); order < EioCount; order = (TInterlockOrdering)(order+1)) {
5038             if (id == TQualifier::getInterlockOrderingString(order)) {
5039                 requireProfile(loc, ECoreProfile | ECompatibilityProfile, "fragment shader interlock layout qualifier");
5040                 profileRequires(loc, ECoreProfile | ECompatibilityProfile, 450, nullptr, "fragment shader interlock layout qualifier");
5041                 requireExtensions(loc, 1, &E_GL_ARB_fragment_shader_interlock, TQualifier::getInterlockOrderingString(order));
5042                 if (order == EioShadingRateInterlockOrdered || order == EioShadingRateInterlockUnordered)
5043                     requireExtensions(loc, 1, &E_GL_NV_shading_rate_image, TQualifier::getInterlockOrderingString(order));
5044                 publicType.shaderQualifiers.interlockOrdering = order;
5045                 return;
5046             }
5047         }
5048         if (id.compare(0, 13, "blend_support") == 0) {
5049             bool found = false;
5050             for (TBlendEquationShift be = (TBlendEquationShift)0; be < EBlendCount; be = (TBlendEquationShift)(be + 1)) {
5051                 if (id == TQualifier::getBlendEquationString(be)) {
5052                     profileRequires(loc, EEsProfile, 320, E_GL_KHR_blend_equation_advanced, "blend equation");
5053                     profileRequires(loc, ~EEsProfile, 0, E_GL_KHR_blend_equation_advanced, "blend equation");
5054                     intermediate.addBlendEquation(be);
5055                     publicType.shaderQualifiers.blendEquation = true;
5056                     found = true;
5057                     break;
5058                 }
5059             }
5060             if (! found)
5061                 error(loc, "unknown blend equation", "blend_support", "");
5062             return;
5063         }
5064         if (id == "override_coverage") {
5065             requireExtensions(loc, 1, &E_GL_NV_sample_mask_override_coverage, "sample mask override coverage");
5066             publicType.shaderQualifiers.layoutOverrideCoverage = true;
5067             return;
5068         }
5069     }
5070     if (language == EShLangVertex ||
5071         language == EShLangTessControl ||
5072         language == EShLangTessEvaluation ||
5073         language == EShLangGeometry ) {
5074         if (id == "viewport_relative") {
5075             requireExtensions(loc, 1, &E_GL_NV_viewport_array2, "view port array2");
5076             publicType.qualifier.layoutViewportRelative = true;
5077             return;
5078         }
5079     } else {
5080         if (language == EShLangRayGen || language == EShLangIntersect ||
5081         language == EShLangAnyHit || language == EShLangClosestHit ||
5082         language == EShLangMiss || language == EShLangCallable) {
5083             if (id == "shaderrecordnv" || id == "shaderrecordext") {
5084                 if (id == "shaderrecordnv") {
5085                     requireExtensions(loc, 1, &E_GL_NV_ray_tracing, "shader record NV");
5086                 } else {
5087                     requireExtensions(loc, 1, &E_GL_EXT_ray_tracing, "shader record EXT");
5088                 }
5089                 publicType.qualifier.layoutShaderRecord = true;
5090                 return;
5091             }
5092
5093         }
5094     }
5095     if (language == EShLangCompute) {
5096         if (id.compare(0, 17, "derivative_group_") == 0) {
5097             requireExtensions(loc, 1, &E_GL_NV_compute_shader_derivatives, "compute shader derivatives");
5098             if (id == "derivative_group_quadsnv") {
5099                 publicType.shaderQualifiers.layoutDerivativeGroupQuads = true;
5100                 return;
5101             } else if (id == "derivative_group_linearnv") {
5102                 publicType.shaderQualifiers.layoutDerivativeGroupLinear = true;
5103                 return;
5104             }
5105         }
5106     }
5107 #endif
5108
5109     error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), "");
5110 }
5111
5112 // Put the id's layout qualifier value into the public type, for qualifiers having a number set.
5113 // This is before we know any type information for error checking.
5114 void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publicType, TString& id, const TIntermTyped* node)
5115 {
5116     const char* feature = "layout-id value";
5117     const char* nonLiteralFeature = "non-literal layout-id value";
5118
5119     integerCheck(node, feature);
5120     const TIntermConstantUnion* constUnion = node->getAsConstantUnion();
5121     int value;
5122     bool nonLiteral = false;
5123     if (constUnion) {
5124         value = constUnion->getConstArray()[0].getIConst();
5125         if (! constUnion->isLiteral()) {
5126             requireProfile(loc, ECoreProfile | ECompatibilityProfile, nonLiteralFeature);
5127             profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, nonLiteralFeature);
5128         }
5129     } else {
5130         // grammar should have give out the error message
5131         value = 0;
5132         nonLiteral = true;
5133     }
5134
5135     if (value < 0) {
5136         error(loc, "cannot be negative", feature, "");
5137         return;
5138     }
5139
5140     std::transform(id.begin(), id.end(), id.begin(), ::tolower);
5141
5142     if (id == "offset") {
5143         // "offset" can be for either
5144         //  - uniform offsets
5145         //  - atomic_uint offsets
5146         const char* feature = "offset";
5147         if (spvVersion.spv == 0) {
5148             requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature);
5149             const char* exts[2] = { E_GL_ARB_enhanced_layouts, E_GL_ARB_shader_atomic_counters };
5150             profileRequires(loc, ECoreProfile | ECompatibilityProfile, 420, 2, exts, feature);
5151             profileRequires(loc, EEsProfile, 310, nullptr, feature);
5152         }
5153         publicType.qualifier.layoutOffset = value;
5154         publicType.qualifier.explicitOffset = true;
5155         if (nonLiteral)
5156             error(loc, "needs a literal integer", "offset", "");
5157         return;
5158     } else if (id == "align") {
5159         const char* feature = "uniform buffer-member align";
5160         if (spvVersion.spv == 0) {
5161             requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature);
5162             profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, feature);
5163         }
5164         // "The specified alignment must be a power of 2, or a compile-time error results."
5165         if (! IsPow2(value))
5166             error(loc, "must be a power of 2", "align", "");
5167         else
5168             publicType.qualifier.layoutAlign = value;
5169         if (nonLiteral)
5170             error(loc, "needs a literal integer", "align", "");
5171         return;
5172     } else if (id == "location") {
5173         profileRequires(loc, EEsProfile, 300, nullptr, "location");
5174         const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location }; 
5175         // GL_ARB_explicit_uniform_location requires 330 or GL_ARB_explicit_attrib_location we do not need to add it here
5176         profileRequires(loc, ~EEsProfile, 330, 2, exts, "location");
5177         if ((unsigned int)value >= TQualifier::layoutLocationEnd)
5178             error(loc, "location is too large", id.c_str(), "");
5179         else
5180             publicType.qualifier.layoutLocation = value;
5181         if (nonLiteral)
5182             error(loc, "needs a literal integer", "location", "");
5183         return;
5184     } else if (id == "set") {
5185         if ((unsigned int)value >= TQualifier::layoutSetEnd)
5186             error(loc, "set is too large", id.c_str(), "");
5187         else
5188             publicType.qualifier.layoutSet = value;
5189         if (value != 0)
5190             requireVulkan(loc, "descriptor set");
5191         if (nonLiteral)
5192             error(loc, "needs a literal integer", "set", "");
5193         return;
5194     } else if (id == "binding") {
5195 #ifndef GLSLANG_WEB
5196         profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, "binding");
5197         profileRequires(loc, EEsProfile, 310, nullptr, "binding");
5198 #endif
5199         if ((unsigned int)value >= TQualifier::layoutBindingEnd)
5200             error(loc, "binding is too large", id.c_str(), "");
5201         else
5202             publicType.qualifier.layoutBinding = value;
5203         if (nonLiteral)
5204             error(loc, "needs a literal integer", "binding", "");
5205         return;
5206     }
5207     if (id == "constant_id") {
5208         requireSpv(loc, "constant_id");
5209         if (value >= (int)TQualifier::layoutSpecConstantIdEnd) {
5210             error(loc, "specialization-constant id is too large", id.c_str(), "");
5211         } else {
5212             publicType.qualifier.layoutSpecConstantId = value;
5213             publicType.qualifier.specConstant = true;
5214             if (! intermediate.addUsedConstantId(value))
5215                 error(loc, "specialization-constant id already used", id.c_str(), "");
5216         }
5217         if (nonLiteral)
5218             error(loc, "needs a literal integer", "constant_id", "");
5219         return;
5220     }
5221 #ifndef GLSLANG_WEB
5222     if (id == "component") {
5223         requireProfile(loc, ECoreProfile | ECompatibilityProfile, "component");
5224         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, "component");
5225         if ((unsigned)value >= TQualifier::layoutComponentEnd)
5226             error(loc, "component is too large", id.c_str(), "");
5227         else
5228             publicType.qualifier.layoutComponent = value;
5229         if (nonLiteral)
5230             error(loc, "needs a literal integer", "component", "");
5231         return;
5232     }
5233     if (id.compare(0, 4, "xfb_") == 0) {
5234         // "Any shader making any static use (after preprocessing) of any of these
5235         // *xfb_* qualifiers will cause the shader to be in a transform feedback
5236         // capturing mode and hence responsible for describing the transform feedback
5237         // setup."
5238         intermediate.setXfbMode();
5239         const char* feature = "transform feedback qualifier";
5240         requireStage(loc, (EShLanguageMask)(EShLangVertexMask | EShLangGeometryMask | EShLangTessControlMask | EShLangTessEvaluationMask), feature);
5241         requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature);
5242         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, feature);
5243         if (id == "xfb_buffer") {
5244             // "It is a compile-time error to specify an *xfb_buffer* that is greater than
5245             // the implementation-dependent constant gl_MaxTransformFeedbackBuffers."
5246             if (value >= resources.maxTransformFeedbackBuffers)
5247                 error(loc, "buffer is too large:", id.c_str(), "gl_MaxTransformFeedbackBuffers is %d", resources.maxTransformFeedbackBuffers);
5248             if (value >= (int)TQualifier::layoutXfbBufferEnd)
5249                 error(loc, "buffer is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbBufferEnd-1);
5250             else
5251                 publicType.qualifier.layoutXfbBuffer = value;
5252             if (nonLiteral)
5253                 error(loc, "needs a literal integer", "xfb_buffer", "");
5254             return;
5255         } else if (id == "xfb_offset") {
5256             if (value >= (int)TQualifier::layoutXfbOffsetEnd)
5257                 error(loc, "offset is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbOffsetEnd-1);
5258             else
5259                 publicType.qualifier.layoutXfbOffset = value;
5260             if (nonLiteral)
5261                 error(loc, "needs a literal integer", "xfb_offset", "");
5262             return;
5263         } else if (id == "xfb_stride") {
5264             // "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
5265             // implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents."
5266             if (value > 4 * resources.maxTransformFeedbackInterleavedComponents) {
5267                 error(loc, "1/4 stride is too large:", id.c_str(), "gl_MaxTransformFeedbackInterleavedComponents is %d",
5268                     resources.maxTransformFeedbackInterleavedComponents);
5269             }
5270             if (value >= (int)TQualifier::layoutXfbStrideEnd)
5271                 error(loc, "stride is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbStrideEnd-1);
5272             else
5273                 publicType.qualifier.layoutXfbStride = value;
5274             if (nonLiteral)
5275                 error(loc, "needs a literal integer", "xfb_stride", "");
5276             return;
5277         }
5278     }
5279     if (id == "input_attachment_index") {
5280         requireVulkan(loc, "input_attachment_index");
5281         if (value >= (int)TQualifier::layoutAttachmentEnd)
5282             error(loc, "attachment index is too large", id.c_str(), "");
5283         else
5284             publicType.qualifier.layoutAttachment = value;
5285         if (nonLiteral)
5286             error(loc, "needs a literal integer", "input_attachment_index", "");
5287         return;
5288     }
5289     if (id == "num_views") {
5290         requireExtensions(loc, Num_OVR_multiview_EXTs, OVR_multiview_EXTs, "num_views");
5291         publicType.shaderQualifiers.numViews = value;
5292         if (nonLiteral)
5293             error(loc, "needs a literal integer", "num_views", "");
5294         return;
5295     }
5296     if (language == EShLangVertex ||
5297         language == EShLangTessControl ||
5298         language == EShLangTessEvaluation ||
5299         language == EShLangGeometry) {
5300         if (id == "secondary_view_offset") {
5301             requireExtensions(loc, 1, &E_GL_NV_stereo_view_rendering, "stereo view rendering");
5302             publicType.qualifier.layoutSecondaryViewportRelativeOffset = value;
5303             if (nonLiteral)
5304                 error(loc, "needs a literal integer", "secondary_view_offset", "");
5305             return;
5306         }
5307     }
5308
5309     if (id == "buffer_reference_align") {
5310         requireExtensions(loc, 1, &E_GL_EXT_buffer_reference, "buffer_reference_align");
5311         if (! IsPow2(value))
5312             error(loc, "must be a power of 2", "buffer_reference_align", "");
5313         else
5314             publicType.qualifier.layoutBufferReferenceAlign = (unsigned int)std::log2(value);
5315         if (nonLiteral)
5316             error(loc, "needs a literal integer", "buffer_reference_align", "");
5317         return;
5318     }
5319 #endif
5320
5321     switch (language) {
5322 #ifndef GLSLANG_WEB
5323     case EShLangTessControl:
5324         if (id == "vertices") {
5325             if (value == 0)
5326                 error(loc, "must be greater than 0", "vertices", "");
5327             else
5328                 publicType.shaderQualifiers.vertices = value;
5329             if (nonLiteral)
5330                 error(loc, "needs a literal integer", "vertices", "");
5331             return;
5332         }
5333         break;
5334
5335     case EShLangGeometry:
5336         if (id == "invocations") {
5337             profileRequires(loc, ECompatibilityProfile | ECoreProfile, 400, nullptr, "invocations");
5338             if (value == 0)
5339                 error(loc, "must be at least 1", "invocations", "");
5340             else
5341                 publicType.shaderQualifiers.invocations = value;
5342             if (nonLiteral)
5343                 error(loc, "needs a literal integer", "invocations", "");
5344             return;
5345         }
5346         if (id == "max_vertices") {
5347             publicType.shaderQualifiers.vertices = value;
5348             if (value > resources.maxGeometryOutputVertices)
5349                 error(loc, "too large, must be less than gl_MaxGeometryOutputVertices", "max_vertices", "");
5350             if (nonLiteral)
5351                 error(loc, "needs a literal integer", "max_vertices", "");
5352             return;
5353         }
5354         if (id == "stream") {
5355             requireProfile(loc, ~EEsProfile, "selecting output stream");
5356             publicType.qualifier.layoutStream = value;
5357             if (value > 0)
5358                 intermediate.setMultiStream();
5359             if (nonLiteral)
5360                 error(loc, "needs a literal integer", "stream", "");
5361             return;
5362         }
5363         break;
5364
5365     case EShLangFragment:
5366         if (id == "index") {
5367             requireProfile(loc, ECompatibilityProfile | ECoreProfile, "index layout qualifier on fragment output");
5368             const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location };
5369             profileRequires(loc, ECompatibilityProfile | ECoreProfile, 330, 2, exts, "index layout qualifier on fragment output");
5370
5371             // "It is also a compile-time error if a fragment shader sets a layout index to less than 0 or greater than 1."
5372             if (value < 0 || value > 1) {
5373                 value = 0;
5374                 error(loc, "value must be 0 or 1", "index", "");
5375             }
5376
5377             publicType.qualifier.layoutIndex = value;
5378             if (nonLiteral)
5379                 error(loc, "needs a literal integer", "index", "");
5380             return;
5381         }
5382         break;
5383
5384     case EShLangMeshNV:
5385         if (id == "max_vertices") {
5386             requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "max_vertices");
5387             publicType.shaderQualifiers.vertices = value;
5388             if (value > resources.maxMeshOutputVerticesNV)
5389                 error(loc, "too large, must be less than gl_MaxMeshOutputVerticesNV", "max_vertices", "");
5390             if (nonLiteral)
5391                 error(loc, "needs a literal integer", "max_vertices", "");
5392             return;
5393         }
5394         if (id == "max_primitives") {
5395             requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "max_primitives");
5396             publicType.shaderQualifiers.primitives = value;
5397             if (value > resources.maxMeshOutputPrimitivesNV)
5398                 error(loc, "too large, must be less than gl_MaxMeshOutputPrimitivesNV", "max_primitives", "");
5399             if (nonLiteral)
5400                 error(loc, "needs a literal integer", "max_primitives", "");
5401             return;
5402         }
5403         // Fall through
5404
5405     case EShLangTaskNV:
5406         // Fall through
5407 #endif
5408     case EShLangCompute:
5409         if (id.compare(0, 11, "local_size_") == 0) {
5410 #ifndef GLSLANG_WEB
5411             if (language == EShLangMeshNV || language == EShLangTaskNV) {
5412                 requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "gl_WorkGroupSize");
5413             } else {
5414                 profileRequires(loc, EEsProfile, 310, 0, "gl_WorkGroupSize");
5415                 profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_compute_shader, "gl_WorkGroupSize");
5416             }
5417 #endif
5418             if (nonLiteral)
5419                 error(loc, "needs a literal integer", "local_size", "");
5420             if (id.size() == 12 && value == 0) {
5421                 error(loc, "must be at least 1", id.c_str(), "");
5422                 return;
5423             }
5424             if (id == "local_size_x") {
5425                 publicType.shaderQualifiers.localSize[0] = value;
5426                 publicType.shaderQualifiers.localSizeNotDefault[0] = true;
5427                 return;
5428             }
5429             if (id == "local_size_y") {
5430                 publicType.shaderQualifiers.localSize[1] = value;
5431                 publicType.shaderQualifiers.localSizeNotDefault[1] = true;
5432                 return;
5433             }
5434             if (id == "local_size_z") {
5435                 publicType.shaderQualifiers.localSize[2] = value;
5436                 publicType.shaderQualifiers.localSizeNotDefault[2] = true;
5437                 return;
5438             }
5439             if (spvVersion.spv != 0) {
5440                 if (id == "local_size_x_id") {
5441                     publicType.shaderQualifiers.localSizeSpecId[0] = value;
5442                     return;
5443                 }
5444                 if (id == "local_size_y_id") {
5445                     publicType.shaderQualifiers.localSizeSpecId[1] = value;
5446                     return;
5447                 }
5448                 if (id == "local_size_z_id") {
5449                     publicType.shaderQualifiers.localSizeSpecId[2] = value;
5450                     return;
5451                 }
5452             }
5453         }
5454         break;
5455
5456     default:
5457         break;
5458     }
5459
5460     error(loc, "there is no such layout identifier for this stage taking an assigned value", id.c_str(), "");
5461 }
5462
5463 // Merge any layout qualifier information from src into dst, leaving everything else in dst alone
5464 //
5465 // "More than one layout qualifier may appear in a single declaration.
5466 // Additionally, the same layout-qualifier-name can occur multiple times
5467 // within a layout qualifier or across multiple layout qualifiers in the
5468 // same declaration. When the same layout-qualifier-name occurs
5469 // multiple times, in a single declaration, the last occurrence overrides
5470 // the former occurrence(s).  Further, if such a layout-qualifier-name
5471 // will effect subsequent declarations or other observable behavior, it
5472 // is only the last occurrence that will have any effect, behaving as if
5473 // the earlier occurrence(s) within the declaration are not present.
5474 // This is also true for overriding layout-qualifier-names, where one
5475 // overrides the other (e.g., row_major vs. column_major); only the last
5476 // occurrence has any effect."
5477 void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifier& src, bool inheritOnly)
5478 {
5479     if (src.hasMatrix())
5480         dst.layoutMatrix = src.layoutMatrix;
5481     if (src.hasPacking())
5482         dst.layoutPacking = src.layoutPacking;
5483
5484 #ifndef GLSLANG_WEB
5485     if (src.hasStream())
5486         dst.layoutStream = src.layoutStream;
5487     if (src.hasFormat())
5488         dst.layoutFormat = src.layoutFormat;
5489     if (src.hasXfbBuffer())
5490         dst.layoutXfbBuffer = src.layoutXfbBuffer;
5491     if (src.hasBufferReferenceAlign())
5492         dst.layoutBufferReferenceAlign = src.layoutBufferReferenceAlign;
5493 #endif
5494
5495     if (src.hasAlign())
5496         dst.layoutAlign = src.layoutAlign;
5497
5498     if (! inheritOnly) {
5499         if (src.hasLocation())
5500             dst.layoutLocation = src.layoutLocation;
5501         if (src.hasOffset())
5502             dst.layoutOffset = src.layoutOffset;
5503         if (src.hasSet())
5504             dst.layoutSet = src.layoutSet;
5505         if (src.layoutBinding != TQualifier::layoutBindingEnd)
5506             dst.layoutBinding = src.layoutBinding;
5507
5508         if (src.hasSpecConstantId())
5509             dst.layoutSpecConstantId = src.layoutSpecConstantId;
5510
5511 #ifndef GLSLANG_WEB
5512         if (src.hasComponent())
5513             dst.layoutComponent = src.layoutComponent;
5514         if (src.hasIndex())
5515             dst.layoutIndex = src.layoutIndex;
5516         if (src.hasXfbStride())
5517             dst.layoutXfbStride = src.layoutXfbStride;
5518         if (src.hasXfbOffset())
5519             dst.layoutXfbOffset = src.layoutXfbOffset;
5520         if (src.hasAttachment())
5521             dst.layoutAttachment = src.layoutAttachment;
5522         if (src.layoutPushConstant)
5523             dst.layoutPushConstant = true;
5524
5525         if (src.layoutBufferReference)
5526             dst.layoutBufferReference = true;
5527
5528         if (src.layoutPassthrough)
5529             dst.layoutPassthrough = true;
5530         if (src.layoutViewportRelative)
5531             dst.layoutViewportRelative = true;
5532         if (src.layoutSecondaryViewportRelativeOffset != -2048)
5533             dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset;
5534         if (src.layoutShaderRecord)
5535             dst.layoutShaderRecord = true;
5536         if (src.pervertexNV)
5537             dst.pervertexNV = true;
5538 #endif
5539     }
5540 }
5541
5542 // Do error layout error checking given a full variable/block declaration.
5543 void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symbol)
5544 {
5545     const TType& type = symbol.getType();
5546     const TQualifier& qualifier = type.getQualifier();
5547
5548     // first, cross check WRT to just the type
5549     layoutTypeCheck(loc, type);
5550
5551     // now, any remaining error checking based on the object itself
5552
5553     if (qualifier.hasAnyLocation()) {
5554         switch (qualifier.storage) {
5555         case EvqUniform:
5556         case EvqBuffer:
5557             if (symbol.getAsVariable() == nullptr)
5558                 error(loc, "can only be used on variable declaration", "location", "");
5559             break;
5560         default:
5561             break;
5562         }
5563     }
5564
5565     // user-variable location check, which are required for SPIR-V in/out:
5566     //  - variables have it directly,
5567     //  - blocks have it on each member (already enforced), so check first one
5568     if (spvVersion.spv > 0 && !parsingBuiltins && qualifier.builtIn == EbvNone &&
5569         !qualifier.hasLocation() && !intermediate.getAutoMapLocations()) {
5570
5571         switch (qualifier.storage) {
5572         case EvqVaryingIn:
5573         case EvqVaryingOut:
5574             if (!type.getQualifier().isTaskMemory() &&
5575                 (type.getBasicType() != EbtBlock ||
5576                  (!(*type.getStruct())[0].type->getQualifier().hasLocation() &&
5577                    (*type.getStruct())[0].type->getQualifier().builtIn == EbvNone)))
5578                 error(loc, "SPIR-V requires location for user input/output", "location", "");
5579             break;
5580         default:
5581             break;
5582         }
5583     }
5584
5585     // Check packing and matrix
5586     if (qualifier.hasUniformLayout()) {
5587         switch (qualifier.storage) {
5588         case EvqUniform:
5589         case EvqBuffer:
5590             if (type.getBasicType() != EbtBlock) {
5591                 if (qualifier.hasMatrix())
5592                     error(loc, "cannot specify matrix layout on a variable declaration", "layout", "");
5593                 if (qualifier.hasPacking())
5594                     error(loc, "cannot specify packing on a variable declaration", "layout", "");
5595                 // "The offset qualifier can only be used on block members of blocks..."
5596                 if (qualifier.hasOffset() && !type.isAtomic())
5597                     error(loc, "cannot specify on a variable declaration", "offset", "");
5598                 // "The align qualifier can only be used on blocks or block members..."
5599                 if (qualifier.hasAlign())
5600                     error(loc, "cannot specify on a variable declaration", "align", "");
5601                 if (qualifier.isPushConstant())
5602                     error(loc, "can only specify on a uniform block", "push_constant", "");
5603                 if (qualifier.isShaderRecord())
5604                     error(loc, "can only specify on a buffer block", "shaderRecordNV", "");
5605             }
5606             break;
5607         default:
5608             // these were already filtered by layoutTypeCheck() (or its callees)
5609             break;
5610         }
5611     }
5612 }
5613
5614 // "For some blocks declared as arrays, the location can only be applied at the block level:
5615 // When a block is declared as an array where additional locations are needed for each member
5616 // for each block array element, it is a compile-time error to specify locations on the block
5617 // members.  That is, when locations would be under specified by applying them on block members,
5618 // they are not allowed on block members.  For arrayed interfaces (those generally having an
5619 // extra level of arrayness due to interface expansion), the outer array is stripped before
5620 // applying this rule."
5621 void TParseContext::layoutMemberLocationArrayCheck(const TSourceLoc& loc, bool memberWithLocation,
5622     TArraySizes* arraySizes)
5623 {
5624     if (memberWithLocation && arraySizes != nullptr) {
5625         if (arraySizes->getNumDims() > (currentBlockQualifier.isArrayedIo(language) ? 1 : 0))
5626             error(loc, "cannot use in a block array where new locations are needed for each block element",
5627                        "location", "");
5628     }
5629 }
5630
5631 // Do layout error checking with respect to a type.
5632 void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
5633 {
5634     const TQualifier& qualifier = type.getQualifier();
5635
5636     // first, intra-layout qualifier-only error checking
5637     layoutQualifierCheck(loc, qualifier);
5638
5639     // now, error checking combining type and qualifier
5640
5641     if (qualifier.hasAnyLocation()) {
5642         if (qualifier.hasLocation()) {
5643             if (qualifier.storage == EvqVaryingOut && language == EShLangFragment) {
5644                 if (qualifier.layoutLocation >= (unsigned int)resources.maxDrawBuffers)
5645                     error(loc, "too large for fragment output", "location", "");
5646             }
5647         }
5648         if (qualifier.hasComponent()) {
5649             // "It is a compile-time error if this sequence of components gets larger than 3."
5650             if (qualifier.layoutComponent + type.getVectorSize() * (type.getBasicType() == EbtDouble ? 2 : 1) > 4)
5651                 error(loc, "type overflows the available 4 components", "component", "");
5652
5653             // "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."
5654             if (type.isMatrix() || type.getBasicType() == EbtBlock || type.getBasicType() == EbtStruct)
5655                 error(loc, "cannot apply to a matrix, structure, or block", "component", "");
5656
5657             // " It is a compile-time error to use component 1 or 3 as the beginning of a double or dvec2."
5658             if (type.getBasicType() == EbtDouble)
5659                 if (qualifier.layoutComponent & 1)
5660                     error(loc, "doubles cannot start on an odd-numbered component", "component", "");
5661         }
5662
5663         switch (qualifier.storage) {
5664         case EvqVaryingIn:
5665         case EvqVaryingOut:
5666             if (type.getBasicType() == EbtBlock)
5667                 profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, "location qualifier on in/out block");
5668             if (type.getQualifier().isTaskMemory())
5669                 error(loc, "cannot apply to taskNV in/out blocks", "location", "");
5670             break;
5671         case EvqUniform:
5672         case EvqBuffer:
5673             if (type.getBasicType() == EbtBlock)
5674                 error(loc, "cannot apply to uniform or buffer block", "location", "");
5675             break;
5676 #ifndef GLSLANG_WEB
5677         case EvqPayload:
5678         case EvqPayloadIn:
5679         case EvqHitAttr:
5680         case EvqCallableData:
5681         case EvqCallableDataIn:
5682             break;
5683 #endif
5684         default:
5685             error(loc, "can only apply to uniform, buffer, in, or out storage qualifiers", "location", "");
5686             break;
5687         }
5688
5689         bool typeCollision;
5690         int repeated = intermediate.addUsedLocation(qualifier, type, typeCollision);
5691         if (repeated >= 0 && ! typeCollision)
5692             error(loc, "overlapping use of location", "location", "%d", repeated);
5693         // "fragment-shader outputs ... if two variables are placed within the same
5694         // location, they must have the same underlying type (floating-point or integer)"
5695         if (typeCollision && language == EShLangFragment && qualifier.isPipeOutput())
5696             error(loc, "fragment outputs sharing the same location must be the same basic type", "location", "%d", repeated);
5697     }
5698
5699 #ifndef GLSLANG_WEB
5700     if (qualifier.hasXfbOffset() && qualifier.hasXfbBuffer()) {
5701         int repeated = intermediate.addXfbBufferOffset(type);
5702         if (repeated >= 0)
5703             error(loc, "overlapping offsets at", "xfb_offset", "offset %d in buffer %d", repeated, qualifier.layoutXfbBuffer);
5704
5705         // "The offset must be a multiple of the size of the first component of the first
5706         // qualified variable or block member, or a compile-time error results. Further, if applied to an aggregate
5707         // containing a double or 64-bit integer, the offset must also be a multiple of 8..."
5708         if ((type.containsBasicType(EbtDouble) || type.containsBasicType(EbtInt64) || type.containsBasicType(EbtUint64)) &&
5709             ! IsMultipleOfPow2(qualifier.layoutXfbOffset, 8))
5710             error(loc, "type contains double or 64-bit integer; xfb_offset must be a multiple of 8", "xfb_offset", "");
5711         else if ((type.containsBasicType(EbtBool) || type.containsBasicType(EbtFloat) ||
5712                   type.containsBasicType(EbtInt) || type.containsBasicType(EbtUint)) &&
5713                  ! IsMultipleOfPow2(qualifier.layoutXfbOffset, 4))
5714             error(loc, "must be a multiple of size of first component", "xfb_offset", "");
5715         // ..., if applied to an aggregate containing a half float or 16-bit integer, the offset must also be a multiple of 2..."
5716         else if ((type.contains16BitFloat() || type.containsBasicType(EbtInt16) || type.containsBasicType(EbtUint16)) &&
5717                  !IsMultipleOfPow2(qualifier.layoutXfbOffset, 2))
5718             error(loc, "type contains half float or 16-bit integer; xfb_offset must be a multiple of 2", "xfb_offset", "");
5719     }
5720     if (qualifier.hasXfbStride() && qualifier.hasXfbBuffer()) {
5721         if (! intermediate.setXfbBufferStride(qualifier.layoutXfbBuffer, qualifier.layoutXfbStride))
5722             error(loc, "all stride settings must match for xfb buffer", "xfb_stride", "%d", qualifier.layoutXfbBuffer);
5723     }
5724 #endif
5725
5726     if (qualifier.hasBinding()) {
5727         // Binding checking, from the spec:
5728         //
5729         // "If the binding point for any uniform or shader storage block instance is less than zero, or greater than or
5730         // equal to the implementation-dependent maximum number of uniform buffer bindings, a compile-time
5731         // error will occur. When the binding identifier is used with a uniform or shader storage block instanced as
5732         // an array of size N, all elements of the array from binding through binding + N - 1 must be within this
5733         // range."
5734         //
5735         if (! type.isOpaque() && type.getBasicType() != EbtBlock)
5736             error(loc, "requires block, or sampler/image, or atomic-counter type", "binding", "");
5737         if (type.getBasicType() == EbtSampler) {
5738             int lastBinding = qualifier.layoutBinding;
5739             if (type.isArray()) {
5740                 if (spvVersion.vulkan > 0)
5741                     lastBinding += 1;
5742                 else {
5743                     if (type.isSizedArray())
5744                         lastBinding += type.getCumulativeArraySize();
5745                     else {
5746                         lastBinding += 1;
5747 #ifndef GLSLANG_WEB
5748                         if (spvVersion.vulkan == 0)
5749                             warn(loc, "assuming binding count of one for compile-time checking of binding numbers for unsized array", "[]", "");
5750 #endif
5751                     }
5752                 }
5753             }
5754 #ifndef GLSLANG_WEB
5755             if (spvVersion.vulkan == 0 && lastBinding >= resources.maxCombinedTextureImageUnits)
5756                 error(loc, "sampler binding not less than gl_MaxCombinedTextureImageUnits", "binding", type.isArray() ? "(using array)" : "");
5757 #endif
5758         }
5759         if (type.isAtomic()) {
5760             if (qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) {
5761                 error(loc, "atomic_uint binding is too large; see gl_MaxAtomicCounterBindings", "binding", "");
5762                 return;
5763             }
5764         }
5765     } else if (!intermediate.getAutoMapBindings()) {
5766         // some types require bindings
5767
5768         // atomic_uint
5769         if (type.isAtomic())
5770             error(loc, "layout(binding=X) is required", "atomic_uint", "");
5771
5772         // SPIR-V
5773         if (spvVersion.spv > 0) {
5774             if (qualifier.isUniformOrBuffer()) {
5775                 if (type.getBasicType() == EbtBlock && !qualifier.isPushConstant() &&
5776                        !qualifier.isShaderRecord() &&
5777                        !qualifier.hasAttachment() &&
5778                        !qualifier.hasBufferReference())
5779                     error(loc, "uniform/buffer blocks require layout(binding=X)", "binding", "");
5780                 else if (spvVersion.vulkan > 0 && type.getBasicType() == EbtSampler)
5781                     error(loc, "sampler/texture/image requires layout(binding=X)", "binding", "");
5782             }
5783         }
5784     }
5785
5786     // some things can't have arrays of arrays
5787     if (type.isArrayOfArrays()) {
5788         if (spvVersion.vulkan > 0) {
5789             if (type.isOpaque() || (type.getQualifier().isUniformOrBuffer() && type.getBasicType() == EbtBlock))
5790                 warn(loc, "Generating SPIR-V array-of-arrays, but Vulkan only supports single array level for this resource", "[][]", "");
5791         }
5792     }
5793
5794     // "The offset qualifier can only be used on block members of blocks..."
5795     if (qualifier.hasOffset()) {
5796         if (type.getBasicType() == EbtBlock)
5797             error(loc, "only applies to block members, not blocks", "offset", "");
5798     }
5799
5800     // Image format
5801     if (qualifier.hasFormat()) {
5802         if (! type.isImage())
5803             error(loc, "only apply to images", TQualifier::getLayoutFormatString(qualifier.getFormat()), "");
5804         else {
5805             if (type.getSampler().type == EbtFloat && qualifier.getFormat() > ElfFloatGuard)
5806                 error(loc, "does not apply to floating point images", TQualifier::getLayoutFormatString(qualifier.getFormat()), "");
5807             if (type.getSampler().type == EbtInt && (qualifier.getFormat() < ElfFloatGuard || qualifier.getFormat() > ElfIntGuard))
5808                 error(loc, "does not apply to signed integer images", TQualifier::getLayoutFormatString(qualifier.getFormat()), "");
5809             if (type.getSampler().type == EbtUint && qualifier.getFormat() < ElfIntGuard)
5810                 error(loc, "does not apply to unsigned integer images", TQualifier::getLayoutFormatString(qualifier.getFormat()), "");
5811
5812             if (isEsProfile()) {
5813                 // "Except for image variables qualified with the format qualifiers r32f, r32i, and r32ui, image variables must
5814                 // specify either memory qualifier readonly or the memory qualifier writeonly."
5815                 if (! (qualifier.getFormat() == ElfR32f || qualifier.getFormat() == ElfR32i || qualifier.getFormat() == ElfR32ui)) {
5816                     if (! qualifier.isReadOnly() && ! qualifier.isWriteOnly())
5817                         error(loc, "format requires readonly or writeonly memory qualifier", TQualifier::getLayoutFormatString(qualifier.getFormat()), "");
5818                 }
5819             }
5820         }
5821     } else if (type.isImage() && ! qualifier.isWriteOnly()) {
5822         const char *explanation = "image variables not declared 'writeonly' and without a format layout qualifier";
5823         requireProfile(loc, ECoreProfile | ECompatibilityProfile, explanation);
5824         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shader_image_load_formatted, explanation);
5825     }
5826
5827     if (qualifier.isPushConstant() && type.getBasicType() != EbtBlock)
5828         error(loc, "can only be used with a block", "push_constant", "");
5829
5830     if (qualifier.hasBufferReference() && type.getBasicType() != EbtBlock)
5831         error(loc, "can only be used with a block", "buffer_reference", "");
5832
5833     if (qualifier.isShaderRecord() && type.getBasicType() != EbtBlock)
5834         error(loc, "can only be used with a block", "shaderRecordNV", "");
5835
5836     // input attachment
5837     if (type.isSubpass()) {
5838         if (! qualifier.hasAttachment())
5839             error(loc, "requires an input_attachment_index layout qualifier", "subpass", "");
5840     } else {
5841         if (qualifier.hasAttachment())
5842             error(loc, "can only be used with a subpass", "input_attachment_index", "");
5843     }
5844
5845     // specialization-constant id
5846     if (qualifier.hasSpecConstantId()) {
5847         if (type.getQualifier().storage != EvqConst)
5848             error(loc, "can only be applied to 'const'-qualified scalar", "constant_id", "");
5849         if (! type.isScalar())
5850             error(loc, "can only be applied to a scalar", "constant_id", "");
5851         switch (type.getBasicType())
5852         {
5853         case EbtInt8:
5854         case EbtUint8:
5855         case EbtInt16:
5856         case EbtUint16:
5857         case EbtInt:
5858         case EbtUint:
5859         case EbtInt64:
5860         case EbtUint64:
5861         case EbtBool:
5862         case EbtFloat:
5863         case EbtDouble:
5864         case EbtFloat16:
5865             break;
5866         default:
5867             error(loc, "cannot be applied to this type", "constant_id", "");
5868             break;
5869         }
5870     }
5871 }
5872
5873 // Do layout error checking that can be done within a layout qualifier proper, not needing to know
5874 // if there are blocks, atomic counters, variables, etc.
5875 void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier& qualifier)
5876 {
5877     if (qualifier.storage == EvqShared && qualifier.hasLayout())
5878         error(loc, "cannot apply layout qualifiers to a shared variable", "shared", "");
5879
5880     // "It is a compile-time error to use *component* without also specifying the location qualifier (order does not matter)."
5881     if (qualifier.hasComponent() && ! qualifier.hasLocation())
5882         error(loc, "must specify 'location' to use 'component'", "component", "");
5883
5884     if (qualifier.hasAnyLocation()) {
5885
5886         // "As with input layout qualifiers, all shaders except compute shaders
5887         // allow *location* layout qualifiers on output variable declarations,
5888         // output block declarations, and output block member declarations."
5889
5890         switch (qualifier.storage) {
5891 #ifndef GLSLANG_WEB
5892         case EvqVaryingIn:
5893         {
5894             const char* feature = "location qualifier on input";
5895             if (isEsProfile() && version < 310)
5896                 requireStage(loc, EShLangVertex, feature);
5897             else
5898                 requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature);
5899             if (language == EShLangVertex) {
5900                 const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location };
5901                 profileRequires(loc, ~EEsProfile, 330, 2, exts, feature);
5902                 profileRequires(loc, EEsProfile, 300, nullptr, feature);
5903             } else {
5904                 profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_separate_shader_objects, feature);
5905                 profileRequires(loc, EEsProfile, 310, nullptr, feature);
5906             }
5907             break;
5908         }
5909         case EvqVaryingOut:
5910         {
5911             const char* feature = "location qualifier on output";
5912             if (isEsProfile() && version < 310)
5913                 requireStage(loc, EShLangFragment, feature);
5914             else
5915                 requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature);
5916             if (language == EShLangFragment) {
5917                 const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location };
5918                 profileRequires(loc, ~EEsProfile, 330, 2, exts, feature);
5919                 profileRequires(loc, EEsProfile, 300, nullptr, feature);
5920             } else {
5921                 profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_separate_shader_objects, feature);
5922                 profileRequires(loc, EEsProfile, 310, nullptr, feature);
5923             }
5924             break;
5925         }
5926 #endif
5927         case EvqUniform:
5928         case EvqBuffer:
5929         {
5930             const char* feature = "location qualifier on uniform or buffer";
5931             requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile | ENoProfile, feature);
5932             profileRequires(loc, ~EEsProfile, 330, E_GL_ARB_explicit_attrib_location, feature);
5933             profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_explicit_uniform_location, feature);
5934             profileRequires(loc, EEsProfile, 310, nullptr, feature);
5935             break;
5936         }
5937         default:
5938             break;
5939         }
5940         if (qualifier.hasIndex()) {
5941             if (qualifier.storage != EvqVaryingOut)
5942                 error(loc, "can only be used on an output", "index", "");
5943             if (! qualifier.hasLocation())
5944                 error(loc, "can only be used with an explicit location", "index", "");
5945         }
5946     }
5947
5948     if (qualifier.hasBinding()) {
5949         if (! qualifier.isUniformOrBuffer() && !qualifier.isTaskMemory())
5950             error(loc, "requires uniform or buffer storage qualifier", "binding", "");
5951     }
5952     if (qualifier.hasStream()) {
5953         if (!qualifier.isPipeOutput())
5954             error(loc, "can only be used on an output", "stream", "");
5955     }
5956     if (qualifier.hasXfb()) {
5957         if (!qualifier.isPipeOutput())
5958             error(loc, "can only be used on an output", "xfb layout qualifier", "");
5959     }
5960     if (qualifier.hasUniformLayout()) {
5961         if (! qualifier.isUniformOrBuffer() && !qualifier.isTaskMemory()) {
5962             if (qualifier.hasMatrix() || qualifier.hasPacking())
5963                 error(loc, "matrix or packing qualifiers can only be used on a uniform or buffer", "layout", "");
5964             if (qualifier.hasOffset() || qualifier.hasAlign())
5965                 error(loc, "offset/align can only be used on a uniform or buffer", "layout", "");
5966         }
5967     }
5968     if (qualifier.isPushConstant()) {
5969         if (qualifier.storage != EvqUniform)
5970             error(loc, "can only be used with a uniform", "push_constant", "");
5971         if (qualifier.hasSet())
5972             error(loc, "cannot be used with push_constant", "set", "");
5973     }
5974     if (qualifier.hasBufferReference()) {
5975         if (qualifier.storage != EvqBuffer)
5976             error(loc, "can only be used with buffer", "buffer_reference", "");
5977     }
5978     if (qualifier.isShaderRecord()) {
5979         if (qualifier.storage != EvqBuffer)
5980             error(loc, "can only be used with a buffer", "shaderRecordNV", "");
5981         if (qualifier.hasBinding())
5982             error(loc, "cannot be used with shaderRecordNV", "binding", "");
5983         if (qualifier.hasSet())
5984             error(loc, "cannot be used with shaderRecordNV", "set", "");
5985
5986     }
5987     if (qualifier.storage == EvqHitAttr && qualifier.hasLayout()) {
5988         error(loc, "cannot apply layout qualifiers to hitAttributeNV variable", "hitAttributeNV", "");
5989     }
5990 }
5991
5992 // For places that can't have shader-level layout qualifiers
5993 void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQualifiers& shaderQualifiers)
5994 {
5995 #ifndef GLSLANG_WEB
5996     const char* message = "can only apply to a standalone qualifier";
5997
5998     if (shaderQualifiers.geometry != ElgNone)
5999         error(loc, message, TQualifier::getGeometryString(shaderQualifiers.geometry), "");
6000     if (shaderQualifiers.spacing != EvsNone)
6001         error(loc, message, TQualifier::getVertexSpacingString(shaderQualifiers.spacing), "");
6002     if (shaderQualifiers.order != EvoNone)
6003         error(loc, message, TQualifier::getVertexOrderString(shaderQualifiers.order), "");
6004     if (shaderQualifiers.pointMode)
6005         error(loc, message, "point_mode", "");
6006     if (shaderQualifiers.invocations != TQualifier::layoutNotSet)
6007         error(loc, message, "invocations", "");
6008     for (int i = 0; i < 3; ++i) {
6009         if (shaderQualifiers.localSize[i] > 1)
6010             error(loc, message, "local_size", "");
6011         if (shaderQualifiers.localSizeSpecId[i] != TQualifier::layoutNotSet)
6012             error(loc, message, "local_size id", "");
6013     }
6014     if (shaderQualifiers.vertices != TQualifier::layoutNotSet) {
6015         if (language == EShLangGeometry || language == EShLangMeshNV)
6016             error(loc, message, "max_vertices", "");
6017         else if (language == EShLangTessControl)
6018             error(loc, message, "vertices", "");
6019         else
6020             assert(0);
6021     }
6022     if (shaderQualifiers.earlyFragmentTests)
6023         error(loc, message, "early_fragment_tests", "");
6024     if (shaderQualifiers.postDepthCoverage)
6025         error(loc, message, "post_depth_coverage", "");
6026     if (shaderQualifiers.primitives != TQualifier::layoutNotSet) {
6027         if (language == EShLangMeshNV)
6028             error(loc, message, "max_primitives", "");
6029         else
6030             assert(0);
6031     }
6032     if (shaderQualifiers.hasBlendEquation())
6033         error(loc, message, "blend equation", "");
6034     if (shaderQualifiers.numViews != TQualifier::layoutNotSet)
6035         error(loc, message, "num_views", "");
6036     if (shaderQualifiers.interlockOrdering != EioNone)
6037         error(loc, message, TQualifier::getInterlockOrderingString(shaderQualifiers.interlockOrdering), "");
6038 #endif
6039 }
6040
6041 // Correct and/or advance an object's offset layout qualifier.
6042 void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol)
6043 {
6044     const TQualifier& qualifier = symbol.getType().getQualifier();
6045 #ifndef GLSLANG_WEB
6046     if (symbol.getType().isAtomic()) {
6047         if (qualifier.hasBinding() && (int)qualifier.layoutBinding < resources.maxAtomicCounterBindings) {
6048
6049             // Set the offset
6050             int offset;
6051             if (qualifier.hasOffset())
6052                 offset = qualifier.layoutOffset;
6053             else
6054                 offset = atomicUintOffsets[qualifier.layoutBinding];
6055
6056             if (offset % 4 != 0)
6057                 error(loc, "atomic counters offset should align based on 4:", "offset", "%d", offset);
6058
6059             symbol.getWritableType().getQualifier().layoutOffset = offset;
6060
6061             // Check for overlap
6062             int numOffsets = 4;
6063             if (symbol.getType().isArray()) {
6064                 if (symbol.getType().isSizedArray() && !symbol.getType().getArraySizes()->isInnerUnsized())
6065                     numOffsets *= symbol.getType().getCumulativeArraySize();
6066                 else {
6067                     // "It is a compile-time error to declare an unsized array of atomic_uint."
6068                     error(loc, "array must be explicitly sized", "atomic_uint", "");
6069                 }
6070             }
6071             int repeated = intermediate.addUsedOffsets(qualifier.layoutBinding, offset, numOffsets);
6072             if (repeated >= 0)
6073                 error(loc, "atomic counters sharing the same offset:", "offset", "%d", repeated);
6074
6075             // Bump the default offset
6076             atomicUintOffsets[qualifier.layoutBinding] = offset + numOffsets;
6077         }
6078     }
6079 #endif
6080 }
6081
6082 //
6083 // Look up a function name in the symbol table, and make sure it is a function.
6084 //
6085 // Return the function symbol if found, otherwise nullptr.
6086 //
6087 const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
6088 {
6089     if (symbolTable.isFunctionNameVariable(call.getName())) {
6090         error(loc, "can't use function syntax on variable", call.getName().c_str(), "");
6091         return nullptr;
6092     }
6093
6094 #ifdef GLSLANG_WEB
6095     return findFunctionExact(loc, call, builtIn);
6096 #endif
6097
6098     const TFunction* function = nullptr;
6099
6100     // debugPrintfEXT has var args and is in the symbol table as "debugPrintfEXT()",
6101     // mangled to "debugPrintfEXT("
6102     if (call.getName() == "debugPrintfEXT") {
6103         TSymbol* symbol = symbolTable.find("debugPrintfEXT(", &builtIn);
6104         if (symbol)
6105             return symbol->getAsFunction();
6106     }
6107
6108     bool explicitTypesEnabled = extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
6109                                 extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int8) ||
6110                                 extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int16) ||
6111                                 extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int32) ||
6112                                 extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int64) ||
6113                                 extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16) ||
6114                                 extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float32) ||
6115                                 extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float64);
6116
6117     if (isEsProfile() || version < 120)
6118         function = findFunctionExact(loc, call, builtIn);
6119     else if (version < 400)
6120         function = extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) ? findFunction400(loc, call, builtIn) : findFunction120(loc, call, builtIn);
6121     else if (explicitTypesEnabled)
6122         function = findFunctionExplicitTypes(loc, call, builtIn);
6123     else
6124         function = findFunction400(loc, call, builtIn);
6125
6126     return function;
6127 }
6128
6129 // Function finding algorithm for ES and desktop 110.
6130 const TFunction* TParseContext::findFunctionExact(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
6131 {
6132     TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn);
6133     if (symbol == nullptr) {
6134         error(loc, "no matching overloaded function found", call.getName().c_str(), "");
6135
6136         return nullptr;
6137     }
6138
6139     return symbol->getAsFunction();
6140 }
6141
6142 // Function finding algorithm for desktop versions 120 through 330.
6143 const TFunction* TParseContext::findFunction120(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
6144 {
6145     // first, look for an exact match
6146     TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn);
6147     if (symbol)
6148         return symbol->getAsFunction();
6149
6150     // exact match not found, look through a list of overloaded functions of the same name
6151
6152     // "If no exact match is found, then [implicit conversions] will be applied to find a match. Mismatched types
6153     // on input parameters (in or inout or default) must have a conversion from the calling argument type to the
6154     // formal parameter type. Mismatched types on output parameters (out or inout) must have a conversion
6155     // from the formal parameter type to the calling argument type.  When argument conversions are used to find
6156     // a match, it is a semantic error if there are multiple ways to apply these conversions to make the call match
6157     // more than one function."
6158
6159     const TFunction* candidate = nullptr;
6160     TVector<const TFunction*> candidateList;
6161     symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
6162
6163     for (auto it = candidateList.begin(); it != candidateList.end(); ++it) {
6164         const TFunction& function = *(*it);
6165
6166         // to even be a potential match, number of arguments has to match
6167         if (call.getParamCount() != function.getParamCount())
6168             continue;
6169
6170         bool possibleMatch = true;
6171         for (int i = 0; i < function.getParamCount(); ++i) {
6172             // same types is easy
6173             if (*function[i].type == *call[i].type)
6174                 continue;
6175
6176             // We have a mismatch in type, see if it is implicitly convertible
6177
6178             if (function[i].type->isArray() || call[i].type->isArray() ||
6179                 ! function[i].type->sameElementShape(*call[i].type))
6180                 possibleMatch = false;
6181             else {
6182                 // do direction-specific checks for conversion of basic type
6183                 if (function[i].type->getQualifier().isParamInput()) {
6184                     if (! intermediate.canImplicitlyPromote(call[i].type->getBasicType(), function[i].type->getBasicType()))
6185                         possibleMatch = false;
6186                 }
6187                 if (function[i].type->getQualifier().isParamOutput()) {
6188                     if (! intermediate.canImplicitlyPromote(function[i].type->getBasicType(), call[i].type->getBasicType()))
6189                         possibleMatch = false;
6190                 }
6191             }
6192             if (! possibleMatch)
6193                 break;
6194         }
6195         if (possibleMatch) {
6196             if (candidate) {
6197                 // our second match, meaning ambiguity
6198                 error(loc, "ambiguous function signature match: multiple signatures match under implicit type conversion", call.getName().c_str(), "");
6199             } else
6200                 candidate = &function;
6201         }
6202     }
6203
6204     if (candidate == nullptr)
6205         error(loc, "no matching overloaded function found", call.getName().c_str(), "");
6206
6207     return candidate;
6208 }
6209
6210 // Function finding algorithm for desktop version 400 and above.
6211 //
6212 // "When function calls are resolved, an exact type match for all the arguments
6213 // is sought. If an exact match is found, all other functions are ignored, and
6214 // the exact match is used. If no exact match is found, then the implicit
6215 // conversions in section 4.1.10 Implicit Conversions will be applied to find
6216 // a match. Mismatched types on input parameters (in or inout or default) must
6217 // have a conversion from the calling argument type to the formal parameter type.
6218 // Mismatched types on output parameters (out or inout) must have a conversion
6219 // from the formal parameter type to the calling argument type.
6220 //
6221 // "If implicit conversions can be used to find more than one matching function,
6222 // a single best-matching function is sought. To determine a best match, the
6223 // conversions between calling argument and formal parameter types are compared
6224 // for each function argument and pair of matching functions. After these
6225 // comparisons are performed, each pair of matching functions are compared.
6226 // A function declaration A is considered a better match than function
6227 // declaration B if
6228 //
6229 //  * for at least one function argument, the conversion for that argument in A
6230 //    is better than the corresponding conversion in B; and
6231 //  * there is no function argument for which the conversion in B is better than
6232 //    the corresponding conversion in A.
6233 //
6234 // "If a single function declaration is considered a better match than every
6235 // other matching function declaration, it will be used. Otherwise, a
6236 // compile-time semantic error for an ambiguous overloaded function call occurs.
6237 //
6238 // "To determine whether the conversion for a single argument in one match is
6239 // better than that for another match, the following rules are applied, in order:
6240 //
6241 //  1. An exact match is better than a match involving any implicit conversion.
6242 //  2. A match involving an implicit conversion from float to double is better
6243 //     than a match involving any other implicit conversion.
6244 //  3. A match involving an implicit conversion from either int or uint to float
6245 //     is better than a match involving an implicit conversion from either int
6246 //     or uint to double.
6247 //
6248 // "If none of the rules above apply to a particular pair of conversions, neither
6249 // conversion is considered better than the other."
6250 //
6251 const TFunction* TParseContext::findFunction400(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
6252 {
6253     // first, look for an exact match
6254     TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn);
6255     if (symbol)
6256         return symbol->getAsFunction();
6257
6258     // no exact match, use the generic selector, parameterized by the GLSL rules
6259
6260     // create list of candidates to send
6261     TVector<const TFunction*> candidateList;
6262     symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
6263
6264     // can 'from' convert to 'to'?
6265     const auto convertible = [this,builtIn](const TType& from, const TType& to, TOperator, int) -> bool {
6266         if (from == to)
6267             return true;
6268         if (from.coopMatParameterOK(to))
6269             return true;
6270         // Allow a sized array to be passed through an unsized array parameter, for coopMatLoad/Store functions
6271         if (builtIn && from.isArray() && to.isUnsizedArray()) {
6272             TType fromElementType(from, 0);
6273             TType toElementType(to, 0);
6274             if (fromElementType == toElementType)
6275                 return true;
6276         }
6277         if (from.isArray() || to.isArray() || ! from.sameElementShape(to))
6278             return false;
6279         if (from.isCoopMat() && to.isCoopMat())
6280             return from.sameCoopMatBaseType(to);
6281         return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType());
6282     };
6283
6284     // Is 'to2' a better conversion than 'to1'?
6285     // Ties should not be considered as better.
6286     // Assumes 'convertible' already said true.
6287     const auto better = [](const TType& from, const TType& to1, const TType& to2) -> bool {
6288         // 1. exact match
6289         if (from == to2)
6290             return from != to1;
6291         if (from == to1)
6292             return false;
6293
6294         // 2. float -> double is better
6295         if (from.getBasicType() == EbtFloat) {
6296             if (to2.getBasicType() == EbtDouble && to1.getBasicType() != EbtDouble)
6297                 return true;
6298         }
6299
6300         // 3. -> float is better than -> double
6301         return to2.getBasicType() == EbtFloat && to1.getBasicType() == EbtDouble;
6302     };
6303
6304     // for ambiguity reporting
6305     bool tie = false;
6306
6307     // send to the generic selector
6308     const TFunction* bestMatch = selectFunction(candidateList, call, convertible, better, tie);
6309
6310     if (bestMatch == nullptr)
6311         error(loc, "no matching overloaded function found", call.getName().c_str(), "");
6312     else if (tie)
6313         error(loc, "ambiguous best function under implicit type conversion", call.getName().c_str(), "");
6314
6315     return bestMatch;
6316 }
6317
6318 // "To determine whether the conversion for a single argument in one match
6319 //  is better than that for another match, the conversion is assigned of the
6320 //  three ranks ordered from best to worst:
6321 //   1. Exact match: no conversion.
6322 //    2. Promotion: integral or floating-point promotion.
6323 //    3. Conversion: integral conversion, floating-point conversion,
6324 //       floating-integral conversion.
6325 //  A conversion C1 is better than a conversion C2 if the rank of C1 is
6326 //  better than the rank of C2."
6327 const TFunction* TParseContext::findFunctionExplicitTypes(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
6328 {
6329     // first, look for an exact match
6330     TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn);
6331     if (symbol)
6332         return symbol->getAsFunction();
6333
6334     // no exact match, use the generic selector, parameterized by the GLSL rules
6335
6336     // create list of candidates to send
6337     TVector<const TFunction*> candidateList;
6338     symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
6339
6340     // can 'from' convert to 'to'?
6341     const auto convertible = [this,builtIn](const TType& from, const TType& to, TOperator, int) -> bool {
6342         if (from == to)
6343             return true;
6344         if (from.coopMatParameterOK(to))
6345             return true;
6346         // Allow a sized array to be passed through an unsized array parameter, for coopMatLoad/Store functions
6347         if (builtIn && from.isArray() && to.isUnsizedArray()) {
6348             TType fromElementType(from, 0);
6349             TType toElementType(to, 0);
6350             if (fromElementType == toElementType)
6351                 return true;
6352         }
6353         if (from.isArray() || to.isArray() || ! from.sameElementShape(to))
6354             return false;
6355         if (from.isCoopMat() && to.isCoopMat())
6356             return from.sameCoopMatBaseType(to);
6357         return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType());
6358     };
6359
6360     // Is 'to2' a better conversion than 'to1'?
6361     // Ties should not be considered as better.
6362     // Assumes 'convertible' already said true.
6363     const auto better = [this](const TType& from, const TType& to1, const TType& to2) -> bool {
6364         // 1. exact match
6365         if (from == to2)
6366             return from != to1;
6367         if (from == to1)
6368             return false;
6369
6370         // 2. Promotion (integral, floating-point) is better
6371         TBasicType from_type = from.getBasicType();
6372         TBasicType to1_type = to1.getBasicType();
6373         TBasicType to2_type = to2.getBasicType();
6374         bool isPromotion1 = (intermediate.isIntegralPromotion(from_type, to1_type) ||
6375                              intermediate.isFPPromotion(from_type, to1_type));
6376         bool isPromotion2 = (intermediate.isIntegralPromotion(from_type, to2_type) ||
6377                              intermediate.isFPPromotion(from_type, to2_type));
6378         if (isPromotion2)
6379             return !isPromotion1;
6380         if(isPromotion1)
6381             return false;
6382
6383         // 3. Conversion (integral, floating-point , floating-integral)
6384         bool isConversion1 = (intermediate.isIntegralConversion(from_type, to1_type) ||
6385                               intermediate.isFPConversion(from_type, to1_type) ||
6386                               intermediate.isFPIntegralConversion(from_type, to1_type));
6387         bool isConversion2 = (intermediate.isIntegralConversion(from_type, to2_type) ||
6388                               intermediate.isFPConversion(from_type, to2_type) ||
6389                               intermediate.isFPIntegralConversion(from_type, to2_type));
6390
6391         return isConversion2 && !isConversion1;
6392     };
6393
6394     // for ambiguity reporting
6395     bool tie = false;
6396
6397     // send to the generic selector
6398     const TFunction* bestMatch = selectFunction(candidateList, call, convertible, better, tie);
6399
6400     if (bestMatch == nullptr)
6401         error(loc, "no matching overloaded function found", call.getName().c_str(), "");
6402     else if (tie)
6403         error(loc, "ambiguous best function under implicit type conversion", call.getName().c_str(), "");
6404
6405     return bestMatch;
6406 }
6407
6408 // When a declaration includes a type, but not a variable name, it can be used
6409 // to establish defaults.
6410 void TParseContext::declareTypeDefaults(const TSourceLoc& loc, const TPublicType& publicType)
6411 {
6412 #ifndef GLSLANG_WEB
6413     if (publicType.basicType == EbtAtomicUint && publicType.qualifier.hasBinding()) {
6414         if (publicType.qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) {
6415             error(loc, "atomic_uint binding is too large", "binding", "");
6416             return;
6417         }
6418
6419         if(publicType.qualifier.hasOffset()) {
6420             atomicUintOffsets[publicType.qualifier.layoutBinding] = publicType.qualifier.layoutOffset;
6421         }
6422         return;
6423     }
6424
6425     if (publicType.qualifier.hasLayout() && !publicType.qualifier.hasBufferReference())
6426         warn(loc, "useless application of layout qualifier", "layout", "");
6427 #endif
6428 }
6429
6430 //
6431 // Do everything necessary to handle a variable (non-block) declaration.
6432 // Either redeclaring a variable, or making a new one, updating the symbol
6433 // table, and all error checking.
6434 //
6435 // Returns a subtree node that computes an initializer, if needed.
6436 // Returns nullptr if there is no code to execute for initialization.
6437 //
6438 // 'publicType' is the type part of the declaration (to the left)
6439 // 'arraySizes' is the arrayness tagged on the identifier (to the right)
6440 //
6441 TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& identifier, const TPublicType& publicType,
6442     TArraySizes* arraySizes, TIntermTyped* initializer)
6443 {
6444     // Make a fresh type that combines the characteristics from the individual
6445     // identifier syntax and the declaration-type syntax.
6446     TType type(publicType);
6447     type.transferArraySizes(arraySizes);
6448     type.copyArrayInnerSizes(publicType.arraySizes);
6449     arrayOfArrayVersionCheck(loc, type.getArraySizes());
6450
6451     if (type.isCoopMat()) {
6452         intermediate.setUseVulkanMemoryModel();
6453         intermediate.setUseStorageBuffer();
6454
6455         if (!publicType.typeParameters || publicType.typeParameters->getNumDims() != 4) {
6456             error(loc, "expected four type parameters", identifier.c_str(), "");
6457         }
6458         if (publicType.typeParameters) {
6459             if (isTypeFloat(publicType.basicType) &&
6460                 publicType.typeParameters->getDimSize(0) != 16 &&
6461                 publicType.typeParameters->getDimSize(0) != 32 &&
6462                 publicType.typeParameters->getDimSize(0) != 64) {
6463                 error(loc, "expected 16, 32, or 64 bits for first type parameter", identifier.c_str(), "");
6464             }
6465             if (isTypeInt(publicType.basicType) &&
6466                 publicType.typeParameters->getDimSize(0) != 8 &&
6467                 publicType.typeParameters->getDimSize(0) != 32) {
6468                 error(loc, "expected 8 or 32 bits for first type parameter", identifier.c_str(), "");
6469             }
6470         }
6471
6472     } else {
6473         if (publicType.typeParameters && publicType.typeParameters->getNumDims() != 0) {
6474             error(loc, "unexpected type parameters", identifier.c_str(), "");
6475         }
6476     }
6477
6478     if (voidErrorCheck(loc, identifier, type.getBasicType()))
6479         return nullptr;
6480
6481     if (initializer)
6482         rValueErrorCheck(loc, "initializer", initializer);
6483     else
6484         nonInitConstCheck(loc, identifier, type);
6485
6486     samplerCheck(loc, type, identifier, initializer);
6487     transparentOpaqueCheck(loc, type, identifier);
6488 #ifndef GLSLANG_WEB
6489     atomicUintCheck(loc, type, identifier);
6490     accStructCheck(loc, type, identifier);
6491     checkAndResizeMeshViewDim(loc, type, /*isBlockMember*/ false);
6492 #endif
6493     if (type.getQualifier().storage == EvqConst && type.containsReference()) {
6494         error(loc, "variables with reference type can't have qualifier 'const'", "qualifier", "");
6495     }
6496
6497     if (type.getQualifier().storage != EvqUniform && type.getQualifier().storage != EvqBuffer) {
6498         if (type.contains16BitFloat())
6499             requireFloat16Arithmetic(loc, "qualifier", "float16 types can only be in uniform block or buffer storage");
6500         if (type.contains16BitInt())
6501             requireInt16Arithmetic(loc, "qualifier", "(u)int16 types can only be in uniform block or buffer storage");
6502         if (type.contains8BitInt())
6503             requireInt8Arithmetic(loc, "qualifier", "(u)int8 types can only be in uniform block or buffer storage");
6504     }
6505
6506     if (type.getQualifier().storage == EvqShared && type.containsCoopMat())
6507         error(loc, "qualifier", "Cooperative matrix types must not be used in shared memory", "");
6508
6509     if (identifier != "gl_FragCoord" && (publicType.shaderQualifiers.originUpperLeft || publicType.shaderQualifiers.pixelCenterInteger))
6510         error(loc, "can only apply origin_upper_left and pixel_center_origin to gl_FragCoord", "layout qualifier", "");
6511     if (identifier != "gl_FragDepth" && publicType.shaderQualifiers.getDepth() != EldNone)
6512         error(loc, "can only apply depth layout to gl_FragDepth", "layout qualifier", "");
6513
6514     // Check for redeclaration of built-ins and/or attempting to declare a reserved name
6515     TSymbol* symbol = redeclareBuiltinVariable(loc, identifier, type.getQualifier(), publicType.shaderQualifiers);
6516     if (symbol == nullptr)
6517         reservedErrorCheck(loc, identifier);
6518
6519     inheritGlobalDefaults(type.getQualifier());
6520
6521     // Declare the variable
6522     if (type.isArray()) {
6523         // Check that implicit sizing is only where allowed.
6524         arraySizesCheck(loc, type.getQualifier(), type.getArraySizes(), initializer, false);
6525
6526         if (! arrayQualifierError(loc, type.getQualifier()) && ! arrayError(loc, type))
6527             declareArray(loc, identifier, type, symbol);
6528
6529         if (initializer) {
6530             profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, "initializer");
6531             profileRequires(loc, EEsProfile, 300, nullptr, "initializer");
6532         }
6533     } else {
6534         // non-array case
6535         if (symbol == nullptr)
6536             symbol = declareNonArray(loc, identifier, type);
6537         else if (type != symbol->getType())
6538             error(loc, "cannot change the type of", "redeclaration", symbol->getName().c_str());
6539     }
6540
6541     if (symbol == nullptr)
6542         return nullptr;
6543
6544     // Deal with initializer
6545     TIntermNode* initNode = nullptr;
6546     if (symbol != nullptr && initializer) {
6547         TVariable* variable = symbol->getAsVariable();
6548         if (! variable) {
6549             error(loc, "initializer requires a variable, not a member", identifier.c_str(), "");
6550             return nullptr;
6551         }
6552         initNode = executeInitializer(loc, initializer, variable);
6553     }
6554
6555     // look for errors in layout qualifier use
6556     layoutObjectCheck(loc, *symbol);
6557
6558     // fix up
6559     fixOffset(loc, *symbol);
6560
6561     return initNode;
6562 }
6563
6564 // Pick up global defaults from the provide global defaults into dst.
6565 void TParseContext::inheritGlobalDefaults(TQualifier& dst) const
6566 {
6567 #ifndef GLSLANG_WEB
6568     if (dst.storage == EvqVaryingOut) {
6569         if (! dst.hasStream() && language == EShLangGeometry)
6570             dst.layoutStream = globalOutputDefaults.layoutStream;
6571         if (! dst.hasXfbBuffer())
6572             dst.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer;
6573     }
6574 #endif
6575 }
6576
6577 //
6578 // Make an internal-only variable whose name is for debug purposes only
6579 // and won't be searched for.  Callers will only use the return value to use
6580 // the variable, not the name to look it up.  It is okay if the name
6581 // is the same as other names; there won't be any conflict.
6582 //
6583 TVariable* TParseContext::makeInternalVariable(const char* name, const TType& type) const
6584 {
6585     TString* nameString = NewPoolTString(name);
6586     TVariable* variable = new TVariable(nameString, type);
6587     symbolTable.makeInternalVariable(*variable);
6588
6589     return variable;
6590 }
6591
6592 //
6593 // Declare a non-array variable, the main point being there is no redeclaration
6594 // for resizing allowed.
6595 //
6596 // Return the successfully declared variable.
6597 //
6598 TVariable* TParseContext::declareNonArray(const TSourceLoc& loc, const TString& identifier, const TType& type)
6599 {
6600     // make a new variable
6601     TVariable* variable = new TVariable(&identifier, type);
6602
6603 #ifndef GLSLANG_WEB
6604     ioArrayCheck(loc, type, identifier);
6605 #endif
6606
6607     // add variable to symbol table
6608     if (symbolTable.insert(*variable)) {
6609         if (symbolTable.atGlobalLevel())
6610             trackLinkage(*variable);
6611         return variable;
6612     }
6613
6614     error(loc, "redefinition", variable->getName().c_str(), "");
6615     return nullptr;
6616 }
6617
6618 //
6619 // Handle all types of initializers from the grammar.
6620 //
6621 // Returning nullptr just means there is no code to execute to handle the
6622 // initializer, which will, for example, be the case for constant initializers.
6623 //
6624 TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyped* initializer, TVariable* variable)
6625 {
6626     //
6627     // Identifier must be of type constant, a global, or a temporary, and
6628     // starting at version 120, desktop allows uniforms to have initializers.
6629     //
6630     TStorageQualifier qualifier = variable->getType().getQualifier().storage;
6631     if (! (qualifier == EvqTemporary || qualifier == EvqGlobal || qualifier == EvqConst ||
6632            (qualifier == EvqUniform && !isEsProfile() && version >= 120))) {
6633         error(loc, " cannot initialize this type of qualifier ", variable->getType().getStorageQualifierString(), "");
6634         return nullptr;
6635     }
6636     arrayObjectCheck(loc, variable->getType(), "array initializer");
6637
6638     //
6639     // If the initializer was from braces { ... }, we convert the whole subtree to a
6640     // constructor-style subtree, allowing the rest of the code to operate
6641     // identically for both kinds of initializers.
6642     //
6643     // Type can't be deduced from the initializer list, so a skeletal type to
6644     // follow has to be passed in.  Constness and specialization-constness
6645     // should be deduced bottom up, not dictated by the skeletal type.
6646     //
6647     TType skeletalType;
6648     skeletalType.shallowCopy(variable->getType());
6649     skeletalType.getQualifier().makeTemporary();
6650 #ifndef GLSLANG_WEB
6651     initializer = convertInitializerList(loc, skeletalType, initializer);
6652 #endif
6653     if (! initializer) {
6654         // error recovery; don't leave const without constant values
6655         if (qualifier == EvqConst)
6656             variable->getWritableType().getQualifier().makeTemporary();
6657         return nullptr;
6658     }
6659
6660     // Fix outer arrayness if variable is unsized, getting size from the initializer
6661     if (initializer->getType().isSizedArray() && variable->getType().isUnsizedArray())
6662         variable->getWritableType().changeOuterArraySize(initializer->getType().getOuterArraySize());
6663
6664     // Inner arrayness can also get set by an initializer
6665     if (initializer->getType().isArrayOfArrays() && variable->getType().isArrayOfArrays() &&
6666         initializer->getType().getArraySizes()->getNumDims() ==
6667            variable->getType().getArraySizes()->getNumDims()) {
6668         // adopt unsized sizes from the initializer's sizes
6669         for (int d = 1; d < variable->getType().getArraySizes()->getNumDims(); ++d) {
6670             if (variable->getType().getArraySizes()->getDimSize(d) == UnsizedArraySize) {
6671                 variable->getWritableType().getArraySizes()->setDimSize(d,
6672                     initializer->getType().getArraySizes()->getDimSize(d));
6673             }
6674         }
6675     }
6676
6677     // Uniforms require a compile-time constant initializer
6678     if (qualifier == EvqUniform && ! initializer->getType().getQualifier().isFrontEndConstant()) {
6679         error(loc, "uniform initializers must be constant", "=", "'%s'", variable->getType().getCompleteString().c_str());
6680         variable->getWritableType().getQualifier().makeTemporary();
6681         return nullptr;
6682     }
6683     // Global consts require a constant initializer (specialization constant is okay)
6684     if (qualifier == EvqConst && symbolTable.atGlobalLevel() && ! initializer->getType().getQualifier().isConstant()) {
6685         error(loc, "global const initializers must be constant", "=", "'%s'", variable->getType().getCompleteString().c_str());
6686         variable->getWritableType().getQualifier().makeTemporary();
6687         return nullptr;
6688     }
6689
6690     // Const variables require a constant initializer, depending on version
6691     if (qualifier == EvqConst) {
6692         if (! initializer->getType().getQualifier().isConstant()) {
6693             const char* initFeature = "non-constant initializer";
6694             requireProfile(loc, ~EEsProfile, initFeature);
6695             profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature);
6696             variable->getWritableType().getQualifier().storage = EvqConstReadOnly;
6697             qualifier = EvqConstReadOnly;
6698         }
6699     } else {
6700         // Non-const global variables in ES need a const initializer.
6701         //
6702         // "In declarations of global variables with no storage qualifier or with a const
6703         // qualifier any initializer must be a constant expression."
6704         if (symbolTable.atGlobalLevel() && ! initializer->getType().getQualifier().isConstant()) {
6705             const char* initFeature = "non-constant global initializer (needs GL_EXT_shader_non_constant_global_initializers)";
6706             if (isEsProfile()) {
6707                 if (relaxedErrors() && ! extensionTurnedOn(E_GL_EXT_shader_non_constant_global_initializers))
6708                     warn(loc, "not allowed in this version", initFeature, "");
6709                 else
6710                     profileRequires(loc, EEsProfile, 0, E_GL_EXT_shader_non_constant_global_initializers, initFeature);
6711             }
6712         }
6713     }
6714
6715     if (qualifier == EvqConst || qualifier == EvqUniform) {
6716         // Compile-time tagging of the variable with its constant value...
6717
6718         initializer = intermediate.addConversion(EOpAssign, variable->getType(), initializer);
6719         if (! initializer || ! initializer->getType().getQualifier().isConstant() || variable->getType() != initializer->getType()) {
6720             error(loc, "non-matching or non-convertible constant type for const initializer",
6721                   variable->getType().getStorageQualifierString(), "");
6722             variable->getWritableType().getQualifier().makeTemporary();
6723             return nullptr;
6724         }
6725
6726         // We either have a folded constant in getAsConstantUnion, or we have to use
6727         // the initializer's subtree in the AST to represent the computation of a
6728         // specialization constant.
6729         assert(initializer->getAsConstantUnion() || initializer->getType().getQualifier().isSpecConstant());
6730         if (initializer->getAsConstantUnion())
6731             variable->setConstArray(initializer->getAsConstantUnion()->getConstArray());
6732         else {
6733             // It's a specialization constant.
6734             variable->getWritableType().getQualifier().makeSpecConstant();
6735
6736             // Keep the subtree that computes the specialization constant with the variable.
6737             // Later, a symbol node will adopt the subtree from the variable.
6738             variable->setConstSubtree(initializer);
6739         }
6740     } else {
6741         // normal assigning of a value to a variable...
6742         specializationCheck(loc, initializer->getType(), "initializer");
6743         TIntermSymbol* intermSymbol = intermediate.addSymbol(*variable, loc);
6744         TIntermTyped* initNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, loc);
6745         if (! initNode)
6746             assignError(loc, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
6747
6748         return initNode;
6749     }
6750
6751     return nullptr;
6752 }
6753
6754 //
6755 // Reprocess any initializer-list (the  "{ ... }" syntax) parts of the
6756 // initializer.
6757 //
6758 // Need to hierarchically assign correct types and implicit
6759 // conversions. Will do this mimicking the same process used for
6760 // creating a constructor-style initializer, ensuring we get the
6761 // same form.  However, it has to in parallel walk the 'type'
6762 // passed in, as type cannot be deduced from an initializer list.
6763 //
6764 TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const TType& type, TIntermTyped* initializer)
6765 {
6766     // Will operate recursively.  Once a subtree is found that is constructor style,
6767     // everything below it is already good: Only the "top part" of the initializer
6768     // can be an initializer list, where "top part" can extend for several (or all) levels.
6769
6770     // see if we have bottomed out in the tree within the initializer-list part
6771     TIntermAggregate* initList = initializer->getAsAggregate();
6772     if (! initList || initList->getOp() != EOpNull)
6773         return initializer;
6774
6775     // Of the initializer-list set of nodes, need to process bottom up,
6776     // so recurse deep, then process on the way up.
6777
6778     // Go down the tree here...
6779     if (type.isArray()) {
6780         // The type's array might be unsized, which could be okay, so base sizes on the size of the aggregate.
6781         // Later on, initializer execution code will deal with array size logic.
6782         TType arrayType;
6783         arrayType.shallowCopy(type);                     // sharing struct stuff is fine
6784         arrayType.copyArraySizes(*type.getArraySizes());  // but get a fresh copy of the array information, to edit below
6785
6786         // edit array sizes to fill in unsized dimensions
6787         arrayType.changeOuterArraySize((int)initList->getSequence().size());
6788         TIntermTyped* firstInit = initList->getSequence()[0]->getAsTyped();
6789         if (arrayType.isArrayOfArrays() && firstInit->getType().isArray() &&
6790             arrayType.getArraySizes()->getNumDims() == firstInit->getType().getArraySizes()->getNumDims() + 1) {
6791             for (int d = 1; d < arrayType.getArraySizes()->getNumDims(); ++d) {
6792                 if (arrayType.getArraySizes()->getDimSize(d) == UnsizedArraySize)
6793                     arrayType.getArraySizes()->setDimSize(d, firstInit->getType().getArraySizes()->getDimSize(d - 1));
6794             }
6795         }
6796
6797         TType elementType(arrayType, 0); // dereferenced type
6798         for (size_t i = 0; i < initList->getSequence().size(); ++i) {
6799             initList->getSequence()[i] = convertInitializerList(loc, elementType, initList->getSequence()[i]->getAsTyped());
6800             if (initList->getSequence()[i] == nullptr)
6801                 return nullptr;
6802         }
6803
6804         return addConstructor(loc, initList, arrayType);
6805     } else if (type.isStruct()) {
6806         if (type.getStruct()->size() != initList->getSequence().size()) {
6807             error(loc, "wrong number of structure members", "initializer list", "");
6808             return nullptr;
6809         }
6810         for (size_t i = 0; i < type.getStruct()->size(); ++i) {
6811             initList->getSequence()[i] = convertInitializerList(loc, *(*type.getStruct())[i].type, initList->getSequence()[i]->getAsTyped());
6812             if (initList->getSequence()[i] == nullptr)
6813                 return nullptr;
6814         }
6815     } else if (type.isMatrix()) {
6816         if (type.getMatrixCols() != (int)initList->getSequence().size()) {
6817             error(loc, "wrong number of matrix columns:", "initializer list", type.getCompleteString().c_str());
6818             return nullptr;
6819         }
6820         TType vectorType(type, 0); // dereferenced type
6821         for (int i = 0; i < type.getMatrixCols(); ++i) {
6822             initList->getSequence()[i] = convertInitializerList(loc, vectorType, initList->getSequence()[i]->getAsTyped());
6823             if (initList->getSequence()[i] == nullptr)
6824                 return nullptr;
6825         }
6826     } else if (type.isVector()) {
6827         if (type.getVectorSize() != (int)initList->getSequence().size()) {
6828             error(loc, "wrong vector size (or rows in a matrix column):", "initializer list", type.getCompleteString().c_str());
6829             return nullptr;
6830         }
6831     } else {
6832         error(loc, "unexpected initializer-list type:", "initializer list", type.getCompleteString().c_str());
6833         return nullptr;
6834     }
6835
6836     // Now that the subtree is processed, process this node as if the
6837     // initializer list is a set of arguments to a constructor.
6838     TIntermNode* emulatedConstructorArguments;
6839     if (initList->getSequence().size() == 1)
6840         emulatedConstructorArguments = initList->getSequence()[0];
6841     else
6842         emulatedConstructorArguments = initList;
6843     return addConstructor(loc, emulatedConstructorArguments, type);
6844 }
6845
6846 //
6847 // Test for the correctness of the parameters passed to various constructor functions
6848 // and also convert them to the right data type, if allowed and required.
6849 //
6850 // 'node' is what to construct from.
6851 // 'type' is what type to construct.
6852 //
6853 // Returns nullptr for an error or the constructed node (aggregate or typed) for no error.
6854 //
6855 TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* node, const TType& type)
6856 {
6857     if (node == nullptr || node->getAsTyped() == nullptr)
6858         return nullptr;
6859     rValueErrorCheck(loc, "constructor", node->getAsTyped());
6860
6861     TIntermAggregate* aggrNode = node->getAsAggregate();
6862     TOperator op = intermediate.mapTypeToConstructorOp(type);
6863
6864     // Combined texture-sampler constructors are completely semantic checked
6865     // in constructorTextureSamplerError()
6866     if (op == EOpConstructTextureSampler) {
6867         if (aggrNode->getSequence()[1]->getAsTyped()->getType().getSampler().shadow) {
6868             // Transfer depth into the texture (SPIR-V image) type, as a hint
6869             // for tools to know this texture/image is a depth image.
6870             aggrNode->getSequence()[0]->getAsTyped()->getWritableType().getSampler().shadow = true;
6871         }
6872         return intermediate.setAggregateOperator(aggrNode, op, type, loc);
6873     }
6874
6875     TTypeList::const_iterator memberTypes;
6876     if (op == EOpConstructStruct)
6877         memberTypes = type.getStruct()->begin();
6878
6879     TType elementType;
6880     if (type.isArray()) {
6881         TType dereferenced(type, 0);
6882         elementType.shallowCopy(dereferenced);
6883     } else
6884         elementType.shallowCopy(type);
6885
6886     bool singleArg;
6887     if (aggrNode) {
6888         if (aggrNode->getOp() != EOpNull)
6889             singleArg = true;
6890         else
6891             singleArg = false;
6892     } else
6893         singleArg = true;
6894
6895     TIntermTyped *newNode;
6896     if (singleArg) {
6897         // If structure constructor or array constructor is being called
6898         // for only one parameter inside the structure, we need to call constructAggregate function once.
6899         if (type.isArray())
6900             newNode = constructAggregate(node, elementType, 1, node->getLoc());
6901         else if (op == EOpConstructStruct)
6902             newNode = constructAggregate(node, *(*memberTypes).type, 1, node->getLoc());
6903         else
6904             newNode = constructBuiltIn(type, op, node->getAsTyped(), node->getLoc(), false);
6905
6906         if (newNode && (type.isArray() || op == EOpConstructStruct))
6907             newNode = intermediate.setAggregateOperator(newNode, EOpConstructStruct, type, loc);
6908
6909         return newNode;
6910     }
6911
6912     //
6913     // Handle list of arguments.
6914     //
6915     TIntermSequence &sequenceVector = aggrNode->getSequence();    // Stores the information about the parameter to the constructor
6916     // if the structure constructor contains more than one parameter, then construct
6917     // each parameter
6918
6919     int paramCount = 0;  // keeps track of the constructor parameter number being checked
6920
6921     // for each parameter to the constructor call, check to see if the right type is passed or convert them
6922     // to the right type if possible (and allowed).
6923     // for structure constructors, just check if the right type is passed, no conversion is allowed.
6924     for (TIntermSequence::iterator p = sequenceVector.begin();
6925                                    p != sequenceVector.end(); p++, paramCount++) {
6926         if (type.isArray())
6927             newNode = constructAggregate(*p, elementType, paramCount+1, node->getLoc());
6928         else if (op == EOpConstructStruct)
6929             newNode = constructAggregate(*p, *(memberTypes[paramCount]).type, paramCount+1, node->getLoc());
6930         else
6931             newNode = constructBuiltIn(type, op, (*p)->getAsTyped(), node->getLoc(), true);
6932
6933         if (newNode)
6934             *p = newNode;
6935         else
6936             return nullptr;
6937     }
6938
6939     return intermediate.setAggregateOperator(aggrNode, op, type, loc);
6940 }
6941
6942 // Function for constructor implementation. Calls addUnaryMath with appropriate EOp value
6943 // for the parameter to the constructor (passed to this function). Essentially, it converts
6944 // the parameter types correctly. If a constructor expects an int (like ivec2) and is passed a
6945 // float, then float is converted to int.
6946 //
6947 // Returns nullptr for an error or the constructed node.
6948 //
6949 TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermTyped* node, const TSourceLoc& loc,
6950     bool subset)
6951 {
6952     // If we are changing a matrix in both domain of basic type and to a non matrix,
6953     // do the shape change first (by default, below, basic type is changed before shape).
6954     // This avoids requesting a matrix of a new type that is going to be discarded anyway.
6955     // TODO: This could be generalized to more type combinations, but that would require
6956     // more extensive testing and full algorithm rework. For now, the need to do two changes makes
6957     // the recursive call work, and avoids the most egregious case of creating integer matrices.
6958     if (node->getType().isMatrix() && (type.isScalar() || type.isVector()) &&
6959             type.isFloatingDomain() != node->getType().isFloatingDomain()) {
6960         TType transitionType(node->getBasicType(), glslang::EvqTemporary, type.getVectorSize(), 0, 0, node->isVector());
6961         TOperator transitionOp = intermediate.mapTypeToConstructorOp(transitionType);
6962         node = constructBuiltIn(transitionType, transitionOp, node, loc, false);
6963     }
6964
6965     TIntermTyped* newNode;
6966     TOperator basicOp;
6967
6968     //
6969     // First, convert types as needed.
6970     //
6971     switch (op) {
6972     case EOpConstructVec2:
6973     case EOpConstructVec3:
6974     case EOpConstructVec4:
6975     case EOpConstructMat2x2:
6976     case EOpConstructMat2x3:
6977     case EOpConstructMat2x4:
6978     case EOpConstructMat3x2:
6979     case EOpConstructMat3x3:
6980     case EOpConstructMat3x4:
6981     case EOpConstructMat4x2:
6982     case EOpConstructMat4x3:
6983     case EOpConstructMat4x4:
6984     case EOpConstructFloat:
6985         basicOp = EOpConstructFloat;
6986         break;
6987
6988     case EOpConstructIVec2:
6989     case EOpConstructIVec3:
6990     case EOpConstructIVec4:
6991     case EOpConstructInt:
6992         basicOp = EOpConstructInt;
6993         break;
6994
6995     case EOpConstructUVec2:
6996         if (node->getType().getBasicType() == EbtReference) {
6997             requireExtensions(loc, 1, &E_GL_EXT_buffer_reference_uvec2, "reference conversion to uvec2");
6998             TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvPtrToUvec2, true, node,
6999                 type);
7000             return newNode;
7001         }
7002     case EOpConstructUVec3:
7003     case EOpConstructUVec4:
7004     case EOpConstructUint:
7005         basicOp = EOpConstructUint;
7006         break;
7007
7008     case EOpConstructBVec2:
7009     case EOpConstructBVec3:
7010     case EOpConstructBVec4:
7011     case EOpConstructBool:
7012         basicOp = EOpConstructBool;
7013         break;
7014
7015 #ifndef GLSLANG_WEB
7016
7017     case EOpConstructDVec2:
7018     case EOpConstructDVec3:
7019     case EOpConstructDVec4:
7020     case EOpConstructDMat2x2:
7021     case EOpConstructDMat2x3:
7022     case EOpConstructDMat2x4:
7023     case EOpConstructDMat3x2:
7024     case EOpConstructDMat3x3:
7025     case EOpConstructDMat3x4:
7026     case EOpConstructDMat4x2:
7027     case EOpConstructDMat4x3:
7028     case EOpConstructDMat4x4:
7029     case EOpConstructDouble:
7030         basicOp = EOpConstructDouble;
7031         break;
7032
7033     case EOpConstructF16Vec2:
7034     case EOpConstructF16Vec3:
7035     case EOpConstructF16Vec4:
7036     case EOpConstructF16Mat2x2:
7037     case EOpConstructF16Mat2x3:
7038     case EOpConstructF16Mat2x4:
7039     case EOpConstructF16Mat3x2:
7040     case EOpConstructF16Mat3x3:
7041     case EOpConstructF16Mat3x4:
7042     case EOpConstructF16Mat4x2:
7043     case EOpConstructF16Mat4x3:
7044     case EOpConstructF16Mat4x4:
7045     case EOpConstructFloat16:
7046         basicOp = EOpConstructFloat16;
7047         // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types,
7048         // so construct a 32-bit type and convert
7049         if (!intermediate.getArithemeticFloat16Enabled()) {
7050             TType tempType(EbtFloat, EvqTemporary, type.getVectorSize());
7051             newNode = node;
7052             if (tempType != newNode->getType()) {
7053                 TOperator aggregateOp;
7054                 if (op == EOpConstructFloat16)
7055                     aggregateOp = EOpConstructFloat;
7056                 else
7057                     aggregateOp = (TOperator)(EOpConstructVec2 + op - EOpConstructF16Vec2);
7058                 newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc());
7059             }
7060             newNode = intermediate.addConversion(EbtFloat16, newNode);
7061             return newNode;
7062         }
7063         break;
7064
7065     case EOpConstructI8Vec2:
7066     case EOpConstructI8Vec3:
7067     case EOpConstructI8Vec4:
7068     case EOpConstructInt8:
7069         basicOp = EOpConstructInt8;
7070         // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types,
7071         // so construct a 32-bit type and convert
7072         if (!intermediate.getArithemeticInt8Enabled()) {
7073             TType tempType(EbtInt, EvqTemporary, type.getVectorSize());
7074             newNode = node;
7075             if (tempType != newNode->getType()) {
7076                 TOperator aggregateOp;
7077                 if (op == EOpConstructInt8)
7078                     aggregateOp = EOpConstructInt;
7079                 else
7080                     aggregateOp = (TOperator)(EOpConstructIVec2 + op - EOpConstructI8Vec2);
7081                 newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc());
7082             }
7083             newNode = intermediate.addConversion(EbtInt8, newNode);
7084             return newNode;
7085         }
7086         break;
7087
7088     case EOpConstructU8Vec2:
7089     case EOpConstructU8Vec3:
7090     case EOpConstructU8Vec4:
7091     case EOpConstructUint8:
7092         basicOp = EOpConstructUint8;
7093         // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types,
7094         // so construct a 32-bit type and convert
7095         if (!intermediate.getArithemeticInt8Enabled()) {
7096             TType tempType(EbtUint, EvqTemporary, type.getVectorSize());
7097             newNode = node;
7098             if (tempType != newNode->getType()) {
7099                 TOperator aggregateOp;
7100                 if (op == EOpConstructUint8)
7101                     aggregateOp = EOpConstructUint;
7102                 else
7103                     aggregateOp = (TOperator)(EOpConstructUVec2 + op - EOpConstructU8Vec2);
7104                 newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc());
7105             }
7106             newNode = intermediate.addConversion(EbtUint8, newNode);
7107             return newNode;
7108         }
7109         break;
7110
7111     case EOpConstructI16Vec2:
7112     case EOpConstructI16Vec3:
7113     case EOpConstructI16Vec4:
7114     case EOpConstructInt16:
7115         basicOp = EOpConstructInt16;
7116         // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types,
7117         // so construct a 32-bit type and convert
7118         if (!intermediate.getArithemeticInt16Enabled()) {
7119             TType tempType(EbtInt, EvqTemporary, type.getVectorSize());
7120             newNode = node;
7121             if (tempType != newNode->getType()) {
7122                 TOperator aggregateOp;
7123                 if (op == EOpConstructInt16)
7124                     aggregateOp = EOpConstructInt;
7125                 else
7126                     aggregateOp = (TOperator)(EOpConstructIVec2 + op - EOpConstructI16Vec2);
7127                 newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc());
7128             }
7129             newNode = intermediate.addConversion(EbtInt16, newNode);
7130             return newNode;
7131         }
7132         break;
7133
7134     case EOpConstructU16Vec2:
7135     case EOpConstructU16Vec3:
7136     case EOpConstructU16Vec4:
7137     case EOpConstructUint16:
7138         basicOp = EOpConstructUint16;
7139         // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types,
7140         // so construct a 32-bit type and convert
7141         if (!intermediate.getArithemeticInt16Enabled()) {
7142             TType tempType(EbtUint, EvqTemporary, type.getVectorSize());
7143             newNode = node;
7144             if (tempType != newNode->getType()) {
7145                 TOperator aggregateOp;
7146                 if (op == EOpConstructUint16)
7147                     aggregateOp = EOpConstructUint;
7148                 else
7149                     aggregateOp = (TOperator)(EOpConstructUVec2 + op - EOpConstructU16Vec2);
7150                 newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc());
7151             }
7152             newNode = intermediate.addConversion(EbtUint16, newNode);
7153             return newNode;
7154         }
7155         break;
7156
7157     case EOpConstructI64Vec2:
7158     case EOpConstructI64Vec3:
7159     case EOpConstructI64Vec4:
7160     case EOpConstructInt64:
7161         basicOp = EOpConstructInt64;
7162         break;
7163
7164     case EOpConstructUint64:
7165         if (type.isScalar() && node->getType().isReference()) {
7166             TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvPtrToUint64, true, node, type);
7167             return newNode;
7168         }
7169         // fall through
7170     case EOpConstructU64Vec2:
7171     case EOpConstructU64Vec3:
7172     case EOpConstructU64Vec4:
7173         basicOp = EOpConstructUint64;
7174         break;
7175
7176     case EOpConstructNonuniform:
7177         // Make a nonuniform copy of node
7178         newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpCopyObject, true, node, type);
7179         return newNode;
7180
7181     case EOpConstructReference:
7182         // construct reference from reference
7183         if (node->getType().isReference()) {
7184             newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConstructReference, true, node, type);
7185             return newNode;
7186         // construct reference from uint64
7187         } else if (node->getType().isScalar() && node->getType().getBasicType() == EbtUint64) {
7188             TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvUint64ToPtr, true, node,
7189                 type);
7190             return newNode;
7191         // construct reference from uvec2
7192         } else if (node->getType().isVector() && node->getType().getBasicType() == EbtUint &&
7193                    node->getVectorSize() == 2) {
7194             requireExtensions(loc, 1, &E_GL_EXT_buffer_reference_uvec2, "uvec2 conversion to reference");
7195             TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvUvec2ToPtr, true, node,
7196                 type);
7197             return newNode;
7198         } else {
7199             return nullptr;
7200         }
7201
7202     case EOpConstructCooperativeMatrix:
7203         if (!node->getType().isCoopMat()) {
7204             if (type.getBasicType() != node->getType().getBasicType()) {
7205                 node = intermediate.addConversion(type.getBasicType(), node);
7206             }
7207             node = intermediate.setAggregateOperator(node, EOpConstructCooperativeMatrix, type, node->getLoc());
7208         } else {
7209             TOperator op = EOpNull;
7210             switch (type.getBasicType()) {
7211             default:
7212                 assert(0);
7213                 break;
7214             case EbtInt:
7215                 switch (node->getType().getBasicType()) {
7216                     case EbtFloat:   op = EOpConvFloatToInt;    break;
7217                     case EbtFloat16: op = EOpConvFloat16ToInt;  break;
7218                     case EbtUint8:   op = EOpConvUint8ToInt;    break;
7219                     case EbtInt8:    op = EOpConvInt8ToInt;     break;
7220                     case EbtUint:    op = EOpConvUintToInt;     break;
7221                     default: assert(0);
7222                 }
7223                 break;
7224             case EbtUint:
7225                 switch (node->getType().getBasicType()) {
7226                     case EbtFloat:   op = EOpConvFloatToUint;    break;
7227                     case EbtFloat16: op = EOpConvFloat16ToUint;  break;
7228                     case EbtUint8:   op = EOpConvUint8ToUint;    break;
7229                     case EbtInt8:    op = EOpConvInt8ToUint;     break;
7230                     case EbtInt:     op = EOpConvIntToUint;      break;
7231                     case EbtUint:    op = EOpConvUintToInt8;     break;
7232                     default: assert(0);
7233                 }
7234                 break;
7235             case EbtInt8:
7236                 switch (node->getType().getBasicType()) {
7237                     case EbtFloat:   op = EOpConvFloatToInt8;    break;
7238                     case EbtFloat16: op = EOpConvFloat16ToInt8;  break;
7239                     case EbtUint8:   op = EOpConvUint8ToInt8;    break;
7240                     case EbtInt:     op = EOpConvIntToInt8;      break;
7241                     case EbtUint:    op = EOpConvUintToInt8;     break;
7242                     default: assert(0);
7243                 }
7244                 break;
7245             case EbtUint8:
7246                 switch (node->getType().getBasicType()) {
7247                     case EbtFloat:   op = EOpConvFloatToUint8;   break;
7248                     case EbtFloat16: op = EOpConvFloat16ToUint8; break;
7249                     case EbtInt8:    op = EOpConvInt8ToUint8;    break;
7250                     case EbtInt:     op = EOpConvIntToUint8;     break;
7251                     case EbtUint:    op = EOpConvUintToUint8;    break;
7252                     default: assert(0);
7253                 }
7254                 break;
7255             case EbtFloat:
7256                 switch (node->getType().getBasicType()) {
7257                     case EbtFloat16: op = EOpConvFloat16ToFloat;  break;
7258                     case EbtInt8:    op = EOpConvInt8ToFloat;     break;
7259                     case EbtUint8:   op = EOpConvUint8ToFloat;    break;
7260                     case EbtInt:     op = EOpConvIntToFloat;      break;
7261                     case EbtUint:    op = EOpConvUintToFloat;     break;
7262                     default: assert(0);
7263                 }
7264                 break;
7265             case EbtFloat16:
7266                 switch (node->getType().getBasicType()) {
7267                     case EbtFloat:  op = EOpConvFloatToFloat16;  break;
7268                     case EbtInt8:   op = EOpConvInt8ToFloat16;   break;
7269                     case EbtUint8:  op = EOpConvUint8ToFloat16;  break;
7270                     case EbtInt:    op = EOpConvIntToFloat16;    break;
7271                     case EbtUint:   op = EOpConvUintToFloat16;   break;
7272                     default: assert(0);
7273                 }
7274                 break;
7275             }
7276
7277             node = intermediate.addUnaryNode(op, node, node->getLoc(), type);
7278             // If it's a (non-specialization) constant, it must be folded.
7279             if (node->getAsUnaryNode()->getOperand()->getAsConstantUnion())
7280                 return node->getAsUnaryNode()->getOperand()->getAsConstantUnion()->fold(op, node->getType());
7281         }
7282
7283         return node;
7284
7285 #endif // GLSLANG_WEB
7286
7287     default:
7288         error(loc, "unsupported construction", "", "");
7289
7290         return nullptr;
7291     }
7292     newNode = intermediate.addUnaryMath(basicOp, node, node->getLoc());
7293     if (newNode == nullptr) {
7294         error(loc, "can't convert", "constructor", "");
7295         return nullptr;
7296     }
7297
7298     //
7299     // Now, if there still isn't an operation to do the construction, and we need one, add one.
7300     //
7301
7302     // Otherwise, skip out early.
7303     if (subset || (newNode != node && newNode->getType() == type))
7304         return newNode;
7305
7306     // setAggregateOperator will insert a new node for the constructor, as needed.
7307     return intermediate.setAggregateOperator(newNode, op, type, loc);
7308 }
7309
7310 // This function tests for the type of the parameters to the structure or array constructor. Raises
7311 // an error message if the expected type does not match the parameter passed to the constructor.
7312 //
7313 // Returns nullptr for an error or the input node itself if the expected and the given parameter types match.
7314 //
7315 TIntermTyped* TParseContext::constructAggregate(TIntermNode* node, const TType& type, int paramCount, const TSourceLoc& loc)
7316 {
7317     TIntermTyped* converted = intermediate.addConversion(EOpConstructStruct, type, node->getAsTyped());
7318     if (! converted || converted->getType() != type) {
7319         error(loc, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount,
7320               node->getAsTyped()->getType().getCompleteString().c_str(), type.getCompleteString().c_str());
7321
7322         return nullptr;
7323     }
7324
7325     return converted;
7326 }
7327
7328 // If a memory qualifier is present in 'to', also make it present in 'from'.
7329 void TParseContext::inheritMemoryQualifiers(const TQualifier& from, TQualifier& to)
7330 {
7331 #ifndef GLSLANG_WEB
7332     if (from.isReadOnly())
7333         to.readonly = from.readonly;
7334     if (from.isWriteOnly())
7335         to.writeonly = from.writeonly;
7336     if (from.coherent)
7337         to.coherent = from.coherent;
7338     if (from.volatil)
7339         to.volatil = from.volatil;
7340     if (from.restrict)
7341         to.restrict = from.restrict;
7342 #endif
7343 }
7344
7345 //
7346 // Do everything needed to add an interface block.
7347 //
7348 void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, const TString* instanceName,
7349     TArraySizes* arraySizes)
7350 {
7351     blockStageIoCheck(loc, currentBlockQualifier);
7352     blockQualifierCheck(loc, currentBlockQualifier, instanceName != nullptr);
7353     if (arraySizes != nullptr) {
7354         arraySizesCheck(loc, currentBlockQualifier, arraySizes, nullptr, false);
7355         arrayOfArrayVersionCheck(loc, arraySizes);
7356         if (arraySizes->getNumDims() > 1)
7357             requireProfile(loc, ~EEsProfile, "array-of-array of block");
7358     }
7359
7360     // Inherit and check member storage qualifiers WRT to the block-level qualifier.
7361     for (unsigned int member = 0; member < typeList.size(); ++member) {
7362         TType& memberType = *typeList[member].type;
7363         TQualifier& memberQualifier = memberType.getQualifier();
7364         const TSourceLoc& memberLoc = typeList[member].loc;
7365         globalQualifierFixCheck(memberLoc, memberQualifier);
7366         if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal && memberQualifier.storage != currentBlockQualifier.storage)
7367             error(memberLoc, "member storage qualifier cannot contradict block storage qualifier", memberType.getFieldName().c_str(), "");
7368         memberQualifier.storage = currentBlockQualifier.storage;
7369 #ifndef GLSLANG_WEB
7370         inheritMemoryQualifiers(currentBlockQualifier, memberQualifier);
7371         if (currentBlockQualifier.perPrimitiveNV)
7372             memberQualifier.perPrimitiveNV = currentBlockQualifier.perPrimitiveNV;
7373         if (currentBlockQualifier.perViewNV)
7374             memberQualifier.perViewNV = currentBlockQualifier.perViewNV;
7375         if (currentBlockQualifier.perTaskNV)
7376             memberQualifier.perTaskNV = currentBlockQualifier.perTaskNV;
7377 #endif
7378         if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary()))
7379             error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), "");
7380         if (memberType.isArray())
7381             arraySizesCheck(memberLoc, currentBlockQualifier, memberType.getArraySizes(), nullptr, member == typeList.size() - 1);
7382         if (memberQualifier.hasOffset()) {
7383             if (spvVersion.spv == 0) {
7384                 requireProfile(memberLoc, ~EEsProfile, "offset on block member");
7385                 profileRequires(memberLoc, ~EEsProfile, 440, E_GL_ARB_enhanced_layouts, "offset on block member");
7386             }
7387         }
7388
7389         if (memberType.containsOpaque())
7390             error(memberLoc, "member of block cannot be or contain a sampler, image, or atomic_uint type", typeList[member].type->getFieldName().c_str(), "");
7391
7392         if (memberType.containsCoopMat())
7393             error(memberLoc, "member of block cannot be or contain a cooperative matrix type", typeList[member].type->getFieldName().c_str(), "");
7394     }
7395
7396     // This might be a redeclaration of a built-in block.  If so, redeclareBuiltinBlock() will
7397     // do all the rest.
7398     if (! symbolTable.atBuiltInLevel() && builtInName(*blockName)) {
7399         redeclareBuiltinBlock(loc, typeList, *blockName, instanceName, arraySizes);
7400         return;
7401     }
7402
7403     // Not a redeclaration of a built-in; check that all names are user names.
7404     reservedErrorCheck(loc, *blockName);
7405     if (instanceName)
7406         reservedErrorCheck(loc, *instanceName);
7407     for (unsigned int member = 0; member < typeList.size(); ++member)
7408         reservedErrorCheck(typeList[member].loc, typeList[member].type->getFieldName());
7409
7410     // Make default block qualification, and adjust the member qualifications
7411
7412     TQualifier defaultQualification;
7413     switch (currentBlockQualifier.storage) {
7414     case EvqUniform:    defaultQualification = globalUniformDefaults;    break;
7415     case EvqBuffer:     defaultQualification = globalBufferDefaults;     break;
7416     case EvqVaryingIn:  defaultQualification = globalInputDefaults;      break;
7417     case EvqVaryingOut: defaultQualification = globalOutputDefaults;     break;
7418     default:            defaultQualification.clear();                    break;
7419     }
7420
7421     // Special case for "push_constant uniform", which has a default of std430,
7422     // contrary to normal uniform defaults, and can't have a default tracked for it.
7423     if ((currentBlockQualifier.isPushConstant() && !currentBlockQualifier.hasPacking()) ||
7424         (currentBlockQualifier.isShaderRecord() && !currentBlockQualifier.hasPacking()))
7425         currentBlockQualifier.layoutPacking = ElpStd430;
7426
7427     // Special case for "taskNV in/out", which has a default of std430,
7428     if (currentBlockQualifier.isTaskMemory() && !currentBlockQualifier.hasPacking())
7429         currentBlockQualifier.layoutPacking = ElpStd430;
7430
7431     // fix and check for member layout qualifiers
7432
7433     mergeObjectLayoutQualifiers(defaultQualification, currentBlockQualifier, true);
7434
7435     // "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
7436     if (currentBlockQualifier.hasAlign()) {
7437         if (defaultQualification.layoutPacking != ElpStd140 &&
7438             defaultQualification.layoutPacking != ElpStd430 &&
7439             defaultQualification.layoutPacking != ElpScalar) {
7440             error(loc, "can only be used with std140, std430, or scalar layout packing", "align", "");
7441             defaultQualification.layoutAlign = -1;
7442         }
7443     }
7444
7445     bool memberWithLocation = false;
7446     bool memberWithoutLocation = false;
7447     bool memberWithPerViewQualifier = false;
7448     for (unsigned int member = 0; member < typeList.size(); ++member) {
7449         TQualifier& memberQualifier = typeList[member].type->getQualifier();
7450         const TSourceLoc& memberLoc = typeList[member].loc;
7451 #ifndef GLSLANG_WEB
7452         if (memberQualifier.hasStream()) {
7453             if (defaultQualification.layoutStream != memberQualifier.layoutStream)
7454                 error(memberLoc, "member cannot contradict block", "stream", "");
7455         }
7456
7457         // "This includes a block's inheritance of the
7458         // current global default buffer, a block member's inheritance of the block's
7459         // buffer, and the requirement that any *xfb_buffer* declared on a block
7460         // member must match the buffer inherited from the block."
7461         if (memberQualifier.hasXfbBuffer()) {
7462             if (defaultQualification.layoutXfbBuffer != memberQualifier.layoutXfbBuffer)
7463                 error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_buffer", "");
7464         }
7465 #endif
7466
7467         if (memberQualifier.hasPacking())
7468             error(memberLoc, "member of block cannot have a packing layout qualifier", typeList[member].type->getFieldName().c_str(), "");
7469         if (memberQualifier.hasLocation()) {
7470             const char* feature = "location on block member";
7471             switch (currentBlockQualifier.storage) {
7472 #ifndef GLSLANG_WEB
7473             case EvqVaryingIn:
7474             case EvqVaryingOut:
7475                 requireProfile(memberLoc, ECoreProfile | ECompatibilityProfile | EEsProfile, feature);
7476                 profileRequires(memberLoc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, feature);
7477                 profileRequires(memberLoc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature);
7478                 memberWithLocation = true;
7479                 break;
7480 #endif
7481             default:
7482                 error(memberLoc, "can only use in an in/out block", feature, "");
7483                 break;
7484             }
7485         } else
7486             memberWithoutLocation = true;
7487
7488         // "The offset qualifier can only be used on block members of blocks declared with std140 or std430 layouts."
7489         // "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
7490         if (memberQualifier.hasAlign() || memberQualifier.hasOffset()) {
7491             if (defaultQualification.layoutPacking != ElpStd140 &&
7492                 defaultQualification.layoutPacking != ElpStd430 &&
7493                 defaultQualification.layoutPacking != ElpScalar)
7494                 error(memberLoc, "can only be used with std140, std430, or scalar layout packing", "offset/align", "");
7495         }
7496
7497         if (memberQualifier.isPerView()) {
7498             memberWithPerViewQualifier = true;
7499         }
7500
7501         TQualifier newMemberQualification = defaultQualification;
7502         mergeQualifiers(memberLoc, newMemberQualification, memberQualifier, false);
7503         memberQualifier = newMemberQualification;
7504     }
7505
7506     layoutMemberLocationArrayCheck(loc, memberWithLocation, arraySizes);
7507
7508 #ifndef GLSLANG_WEB
7509     // Ensure that the block has an XfbBuffer assigned. This is needed
7510     // because if the block has a XfbOffset assigned, then it is
7511     // assumed that it has implicitly assigned the current global
7512     // XfbBuffer, and because it's members need to be assigned a
7513     // XfbOffset if they lack it.
7514     if (currentBlockQualifier.storage == EvqVaryingOut && globalOutputDefaults.hasXfbBuffer()) {
7515        if (!currentBlockQualifier.hasXfbBuffer() && currentBlockQualifier.hasXfbOffset())
7516           currentBlockQualifier.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer;
7517     }
7518 #endif
7519
7520     // Process the members
7521     fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation);
7522     fixXfbOffsets(currentBlockQualifier, typeList);
7523     fixBlockUniformOffsets(currentBlockQualifier, typeList);
7524     for (unsigned int member = 0; member < typeList.size(); ++member)
7525         layoutTypeCheck(typeList[member].loc, *typeList[member].type);
7526
7527 #ifndef GLSLANG_WEB
7528     if (memberWithPerViewQualifier) {
7529         for (unsigned int member = 0; member < typeList.size(); ++member) {
7530             checkAndResizeMeshViewDim(typeList[member].loc, *typeList[member].type, /*isBlockMember*/ true);
7531         }
7532     }
7533 #endif
7534
7535     // reverse merge, so that currentBlockQualifier now has all layout information
7536     // (can't use defaultQualification directly, it's missing other non-layout-default-class qualifiers)
7537     mergeObjectLayoutQualifiers(currentBlockQualifier, defaultQualification, true);
7538
7539     //
7540     // Build and add the interface block as a new type named 'blockName'
7541     //
7542
7543     TType blockType(&typeList, *blockName, currentBlockQualifier);
7544     if (arraySizes != nullptr)
7545         blockType.transferArraySizes(arraySizes);
7546
7547 #ifndef GLSLANG_WEB
7548     if (arraySizes == nullptr)
7549         ioArrayCheck(loc, blockType, instanceName ? *instanceName : *blockName);
7550     if (currentBlockQualifier.hasBufferReference()) {
7551
7552         if (currentBlockQualifier.storage != EvqBuffer)
7553             error(loc, "can only be used with buffer", "buffer_reference", "");
7554
7555         // Create the block reference type. If it was forward-declared, detect that
7556         // as a referent struct type with no members. Replace the referent type with
7557         // blockType.
7558         TType blockNameType(EbtReference, blockType, *blockName);
7559         TVariable* blockNameVar = new TVariable(blockName, blockNameType, true);
7560         if (! symbolTable.insert(*blockNameVar)) {
7561             TSymbol* existingName = symbolTable.find(*blockName);
7562             if (existingName->getType().isReference() &&
7563                 existingName->getType().getReferentType()->getStruct() &&
7564                 existingName->getType().getReferentType()->getStruct()->size() == 0 &&
7565                 existingName->getType().getQualifier().storage == blockType.getQualifier().storage) {
7566                 existingName->getType().getReferentType()->deepCopy(blockType);
7567             } else {
7568                 error(loc, "block name cannot be redefined", blockName->c_str(), "");
7569             }
7570         }
7571         if (!instanceName) {
7572             return;
7573         }
7574     } else
7575 #endif
7576     {
7577         //
7578         // Don't make a user-defined type out of block name; that will cause an error
7579         // if the same block name gets reused in a different interface.
7580         //
7581         // "Block names have no other use within a shader
7582         // beyond interface matching; it is a compile-time error to use a block name at global scope for anything
7583         // other than as a block name (e.g., use of a block name for a global variable name or function name is
7584         // currently reserved)."
7585         //
7586         // Use the symbol table to prevent normal reuse of the block's name, as a variable entry,
7587         // whose type is EbtBlock, but without all the structure; that will come from the type
7588         // the instances point to.
7589         //
7590         TType blockNameType(EbtBlock, blockType.getQualifier().storage);
7591         TVariable* blockNameVar = new TVariable(blockName, blockNameType);
7592         if (! symbolTable.insert(*blockNameVar)) {
7593             TSymbol* existingName = symbolTable.find(*blockName);
7594             if (existingName->getType().getBasicType() == EbtBlock) {
7595                 if (existingName->getType().getQualifier().storage == blockType.getQualifier().storage) {
7596                     error(loc, "Cannot reuse block name within the same interface:", blockName->c_str(), blockType.getStorageQualifierString());
7597                     return;
7598                 }
7599             } else {
7600                 error(loc, "block name cannot redefine a non-block name", blockName->c_str(), "");
7601                 return;
7602             }
7603         }
7604     }
7605
7606     // Add the variable, as anonymous or named instanceName.
7607     // Make an anonymous variable if no name was provided.
7608     if (! instanceName)
7609         instanceName = NewPoolTString("");
7610
7611     TVariable& variable = *new TVariable(instanceName, blockType);
7612     if (! symbolTable.insert(variable)) {
7613         if (*instanceName == "")
7614             error(loc, "nameless block contains a member that already has a name at global scope", blockName->c_str(), "");
7615         else
7616             error(loc, "block instance name redefinition", variable.getName().c_str(), "");
7617
7618         return;
7619     }
7620
7621     // Check for general layout qualifier errors
7622     layoutObjectCheck(loc, variable);
7623
7624 #ifndef GLSLANG_WEB
7625     // fix up
7626     if (isIoResizeArray(blockType)) {
7627         ioArraySymbolResizeList.push_back(&variable);
7628         checkIoArraysConsistency(loc, true);
7629     } else
7630         fixIoArraySize(loc, variable.getWritableType());
7631 #endif
7632
7633     // Save it in the AST for linker use.
7634     trackLinkage(variable);
7635 }
7636
7637 // Do all block-declaration checking regarding the combination of in/out/uniform/buffer
7638 // with a particular stage.
7639 void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& qualifier)
7640 {
7641     const char *extsrt[2] = { E_GL_NV_ray_tracing, E_GL_EXT_ray_tracing };
7642     switch (qualifier.storage) {
7643     case EvqUniform:
7644         profileRequires(loc, EEsProfile, 300, nullptr, "uniform block");
7645         profileRequires(loc, ENoProfile, 140, E_GL_ARB_uniform_buffer_object, "uniform block");
7646         if (currentBlockQualifier.layoutPacking == ElpStd430 && ! currentBlockQualifier.isPushConstant())
7647             requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "std430 requires the buffer storage qualifier");
7648         break;
7649     case EvqBuffer:
7650         requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "buffer block");
7651         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, "buffer block");
7652         profileRequires(loc, EEsProfile, 310, nullptr, "buffer block");
7653         break;
7654     case EvqVaryingIn:
7655         profileRequires(loc, ~EEsProfile, 150, E_GL_ARB_separate_shader_objects, "input block");
7656         // It is a compile-time error to have an input block in a vertex shader or an output block in a fragment shader
7657         // "Compute shaders do not permit user-defined input variables..."
7658         requireStage(loc, (EShLanguageMask)(EShLangTessControlMask|EShLangTessEvaluationMask|EShLangGeometryMask|
7659             EShLangFragmentMask|EShLangMeshNVMask), "input block");
7660         if (language == EShLangFragment) {
7661             profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "fragment input block");
7662         } else if (language == EShLangMeshNV && ! qualifier.isTaskMemory()) {
7663             error(loc, "input blocks cannot be used in a mesh shader", "out", "");
7664         }
7665         break;
7666     case EvqVaryingOut:
7667         profileRequires(loc, ~EEsProfile, 150, E_GL_ARB_separate_shader_objects, "output block");
7668         requireStage(loc, (EShLanguageMask)(EShLangVertexMask|EShLangTessControlMask|EShLangTessEvaluationMask|
7669             EShLangGeometryMask|EShLangMeshNVMask|EShLangTaskNVMask), "output block");
7670         // ES 310 can have a block before shader_io is turned on, so skip this test for built-ins
7671         if (language == EShLangVertex && ! parsingBuiltins) {
7672             profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "vertex output block");
7673         } else if (language == EShLangMeshNV && qualifier.isTaskMemory()) {
7674             error(loc, "can only use on input blocks in mesh shader", "taskNV", "");
7675         } else if (language == EShLangTaskNV && ! qualifier.isTaskMemory()) {
7676             error(loc, "output blocks cannot be used in a task shader", "out", "");
7677         }
7678         break;
7679 #ifndef GLSLANG_WEB
7680     case EvqPayload:
7681         profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "rayPayloadNV block");
7682         requireStage(loc, (EShLanguageMask)(EShLangRayGenMask | EShLangAnyHitMask | EShLangClosestHitMask | EShLangMissMask),
7683             "rayPayloadNV block");
7684         break;
7685     case EvqPayloadIn:
7686         profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "rayPayloadInNV block");
7687         requireStage(loc, (EShLanguageMask)(EShLangAnyHitMask | EShLangClosestHitMask | EShLangMissMask),
7688             "rayPayloadInNV block");
7689         break;
7690     case EvqHitAttr:
7691         profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "hitAttributeNV block");
7692         requireStage(loc, (EShLanguageMask)(EShLangIntersectMask | EShLangAnyHitMask | EShLangClosestHitMask), "hitAttributeNV block");
7693         break;
7694     case EvqCallableData:
7695         profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "callableDataNV block");
7696         requireStage(loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | EShLangMissMask | EShLangCallableMask),
7697             "callableDataNV block");
7698         break;
7699     case EvqCallableDataIn:
7700         profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "callableDataInNV block");
7701         requireStage(loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInNV block");
7702         break;
7703 #endif
7704     default:
7705         error(loc, "only uniform, buffer, in, or out blocks are supported", blockName->c_str(), "");
7706         break;
7707     }
7708 }
7709
7710 // Do all block-declaration checking regarding its qualifiers.
7711 void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier& qualifier, bool /*instanceName*/)
7712 {
7713     // The 4.5 specification says:
7714     //
7715     // interface-block :
7716     //    layout-qualifieropt interface-qualifier  block-name { member-list } instance-nameopt ;
7717     //
7718     // interface-qualifier :
7719     //    in
7720     //    out
7721     //    patch in
7722     //    patch out
7723     //    uniform
7724     //    buffer
7725     //
7726     // Note however memory qualifiers aren't included, yet the specification also says
7727     //
7728     // "...memory qualifiers may also be used in the declaration of shader storage blocks..."
7729
7730     if (qualifier.isInterpolation())
7731         error(loc, "cannot use interpolation qualifiers on an interface block", "flat/smooth/noperspective", "");
7732     if (qualifier.centroid)
7733         error(loc, "cannot use centroid qualifier on an interface block", "centroid", "");
7734     if (qualifier.isSample())
7735         error(loc, "cannot use sample qualifier on an interface block", "sample", "");
7736     if (qualifier.invariant)
7737         error(loc, "cannot use invariant qualifier on an interface block", "invariant", "");
7738     if (qualifier.isPushConstant())
7739         intermediate.addPushConstantCount();
7740     if (qualifier.isShaderRecord())
7741         intermediate.addShaderRecordCount();
7742     if (qualifier.isTaskMemory())
7743         intermediate.addTaskNVCount();
7744 }
7745
7746 //
7747 // "For a block, this process applies to the entire block, or until the first member
7748 // is reached that has a location layout qualifier. When a block member is declared with a location
7749 // qualifier, its location comes from that qualifier: The member's location qualifier overrides the block-level
7750 // declaration. Subsequent members are again assigned consecutive locations, based on the newest location,
7751 // until the next member declared with a location qualifier. The values used for locations do not have to be
7752 // declared in increasing order."
7753 void TParseContext::fixBlockLocations(const TSourceLoc& loc, TQualifier& qualifier, TTypeList& typeList, bool memberWithLocation, bool memberWithoutLocation)
7754 {
7755     // "If a block has no block-level location layout qualifier, it is required that either all or none of its members
7756     // have a location layout qualifier, or a compile-time error results."
7757     if (! qualifier.hasLocation() && memberWithLocation && memberWithoutLocation)
7758         error(loc, "either the block needs a location, or all members need a location, or no members have a location", "location", "");
7759     else {
7760         if (memberWithLocation) {
7761             // remove any block-level location and make it per *every* member
7762             int nextLocation = 0;  // by the rule above, initial value is not relevant
7763             if (qualifier.hasAnyLocation()) {
7764                 nextLocation = qualifier.layoutLocation;
7765                 qualifier.layoutLocation = TQualifier::layoutLocationEnd;
7766                 if (qualifier.hasComponent()) {
7767                     // "It is a compile-time error to apply the *component* qualifier to a ... block"
7768                     error(loc, "cannot apply to a block", "component", "");
7769                 }
7770                 if (qualifier.hasIndex()) {
7771                     error(loc, "cannot apply to a block", "index", "");
7772                 }
7773             }
7774             for (unsigned int member = 0; member < typeList.size(); ++member) {
7775                 TQualifier& memberQualifier = typeList[member].type->getQualifier();
7776                 const TSourceLoc& memberLoc = typeList[member].loc;
7777                 if (! memberQualifier.hasLocation()) {
7778                     if (nextLocation >= (int)TQualifier::layoutLocationEnd)
7779                         error(memberLoc, "location is too large", "location", "");
7780                     memberQualifier.layoutLocation = nextLocation;
7781                     memberQualifier.layoutComponent = TQualifier::layoutComponentEnd;
7782                 }
7783                 nextLocation = memberQualifier.layoutLocation + intermediate.computeTypeLocationSize(
7784                                     *typeList[member].type, language);
7785             }
7786         }
7787     }
7788 }
7789
7790 void TParseContext::fixXfbOffsets(TQualifier& qualifier, TTypeList& typeList)
7791 {
7792 #ifndef GLSLANG_WEB
7793     // "If a block is qualified with xfb_offset, all its
7794     // members are assigned transform feedback buffer offsets. If a block is not qualified with xfb_offset, any
7795     // members of that block not qualified with an xfb_offset will not be assigned transform feedback buffer
7796     // offsets."
7797
7798     if (! qualifier.hasXfbBuffer() || ! qualifier.hasXfbOffset())
7799         return;
7800
7801     int nextOffset = qualifier.layoutXfbOffset;
7802     for (unsigned int member = 0; member < typeList.size(); ++member) {
7803         TQualifier& memberQualifier = typeList[member].type->getQualifier();
7804         bool contains64BitType = false;
7805         bool contains32BitType = false;
7806         bool contains16BitType = false;
7807         int memberSize = intermediate.computeTypeXfbSize(*typeList[member].type, contains64BitType, contains32BitType, contains16BitType);
7808         // see if we need to auto-assign an offset to this member
7809         if (! memberQualifier.hasXfbOffset()) {
7810             // "if applied to an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8"
7811             if (contains64BitType)
7812                 RoundToPow2(nextOffset, 8);
7813             else if (contains32BitType)
7814                 RoundToPow2(nextOffset, 4);
7815             else if (contains16BitType)
7816                 RoundToPow2(nextOffset, 2);
7817             memberQualifier.layoutXfbOffset = nextOffset;
7818         } else
7819             nextOffset = memberQualifier.layoutXfbOffset;
7820         nextOffset += memberSize;
7821     }
7822
7823     // The above gave all block members an offset, so we can take it off the block now,
7824     // which will avoid double counting the offset usage.
7825     qualifier.layoutXfbOffset = TQualifier::layoutXfbOffsetEnd;
7826 #endif
7827 }
7828
7829 // Calculate and save the offset of each block member, using the recursively
7830 // defined block offset rules and the user-provided offset and align.
7831 //
7832 // Also, compute and save the total size of the block. For the block's size, arrayness
7833 // is not taken into account, as each element is backed by a separate buffer.
7834 //
7835 void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typeList)
7836 {
7837     if (!qualifier.isUniformOrBuffer() && !qualifier.isTaskMemory())
7838         return;
7839     if (qualifier.layoutPacking != ElpStd140 && qualifier.layoutPacking != ElpStd430 && qualifier.layoutPacking != ElpScalar)
7840         return;
7841
7842     int offset = 0;
7843     int memberSize;
7844     for (unsigned int member = 0; member < typeList.size(); ++member) {
7845         TQualifier& memberQualifier = typeList[member].type->getQualifier();
7846         const TSourceLoc& memberLoc = typeList[member].loc;
7847
7848         // "When align is applied to an array, it effects only the start of the array, not the array's internal stride."
7849
7850         // modify just the children's view of matrix layout, if there is one for this member
7851         TLayoutMatrix subMatrixLayout = typeList[member].type->getQualifier().layoutMatrix;
7852         int dummyStride;
7853         int memberAlignment = intermediate.getMemberAlignment(*typeList[member].type, memberSize, dummyStride, qualifier.layoutPacking,
7854                                                               subMatrixLayout != ElmNone ? subMatrixLayout == ElmRowMajor : qualifier.layoutMatrix == ElmRowMajor);
7855         if (memberQualifier.hasOffset()) {
7856             // "The specified offset must be a multiple
7857             // of the base alignment of the type of the block member it qualifies, or a compile-time error results."
7858             if (! IsMultipleOfPow2(memberQualifier.layoutOffset, memberAlignment))
7859                 error(memberLoc, "must be a multiple of the member's alignment", "offset", "");
7860
7861             // GLSL: "It is a compile-time error to specify an offset that is smaller than the offset of the previous
7862             // member in the block or that lies within the previous member of the block"
7863             if (spvVersion.spv == 0) {
7864                 if (memberQualifier.layoutOffset < offset)
7865                     error(memberLoc, "cannot lie in previous members", "offset", "");
7866
7867                 // "The offset qualifier forces the qualified member to start at or after the specified
7868                 // integral-constant expression, which will be its byte offset from the beginning of the buffer.
7869                 // "The actual offset of a member is computed as
7870                 // follows: If offset was declared, start with that offset, otherwise start with the next available offset."
7871                 offset = std::max(offset, memberQualifier.layoutOffset);
7872             } else {
7873                 // TODO: Vulkan: "It is a compile-time error to have any offset, explicit or assigned,
7874                 // that lies within another member of the block."
7875
7876                 offset = memberQualifier.layoutOffset;
7877             }
7878         }
7879
7880         // "The actual alignment of a member will be the greater of the specified align alignment and the standard
7881         // (e.g., std140) base alignment for the member's type."
7882         if (memberQualifier.hasAlign())
7883             memberAlignment = std::max(memberAlignment, memberQualifier.layoutAlign);
7884
7885         // "If the resulting offset is not a multiple of the actual alignment,
7886         // increase it to the first offset that is a multiple of
7887         // the actual alignment."
7888         RoundToPow2(offset, memberAlignment);
7889         typeList[member].type->getQualifier().layoutOffset = offset;
7890         offset += memberSize;
7891     }
7892 }
7893
7894 // For an identifier that is already declared, add more qualification to it.
7895 void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qualifier, const TString& identifier)
7896 {
7897     TSymbol* symbol = symbolTable.find(identifier);
7898
7899     // A forward declaration of a block reference looks to the grammar like adding
7900     // a qualifier to an existing symbol. Detect this and create the block reference
7901     // type with an empty type list, which will be filled in later in
7902     // TParseContext::declareBlock.
7903     if (!symbol && qualifier.hasBufferReference()) {
7904         TTypeList typeList;
7905         TType blockType(&typeList, identifier, qualifier);;
7906         TType blockNameType(EbtReference, blockType, identifier);
7907         TVariable* blockNameVar = new TVariable(&identifier, blockNameType, true);
7908         if (! symbolTable.insert(*blockNameVar)) {
7909             error(loc, "block name cannot redefine a non-block name", blockName->c_str(), "");
7910         }
7911         return;
7912     }
7913
7914     if (! symbol) {
7915         error(loc, "identifier not previously declared", identifier.c_str(), "");
7916         return;
7917     }
7918     if (symbol->getAsFunction()) {
7919         error(loc, "cannot re-qualify a function name", identifier.c_str(), "");
7920         return;
7921     }
7922
7923     if (qualifier.isAuxiliary() ||
7924         qualifier.isMemory() ||
7925         qualifier.isInterpolation() ||
7926         qualifier.hasLayout() ||
7927         qualifier.storage != EvqTemporary ||
7928         qualifier.precision != EpqNone) {
7929         error(loc, "cannot add storage, auxiliary, memory, interpolation, layout, or precision qualifier to an existing variable", identifier.c_str(), "");
7930         return;
7931     }
7932
7933     // For read-only built-ins, add a new symbol for holding the modified qualifier.
7934     // This will bring up an entire block, if a block type has to be modified (e.g., gl_Position inside a block)
7935     if (symbol->isReadOnly())
7936         symbol = symbolTable.copyUp(symbol);
7937
7938     if (qualifier.invariant) {
7939         if (intermediate.inIoAccessed(identifier))
7940             error(loc, "cannot change qualification after use", "invariant", "");
7941         symbol->getWritableType().getQualifier().invariant = true;
7942         invariantCheck(loc, symbol->getType().getQualifier());
7943     } else if (qualifier.isNoContraction()) {
7944         if (intermediate.inIoAccessed(identifier))
7945             error(loc, "cannot change qualification after use", "precise", "");
7946         symbol->getWritableType().getQualifier().setNoContraction();
7947     } else if (qualifier.specConstant) {
7948         symbol->getWritableType().getQualifier().makeSpecConstant();
7949         if (qualifier.hasSpecConstantId())
7950             symbol->getWritableType().getQualifier().layoutSpecConstantId = qualifier.layoutSpecConstantId;
7951     } else
7952         warn(loc, "unknown requalification", "", "");
7953 }
7954
7955 void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qualifier, TIdentifierList& identifiers)
7956 {
7957     for (unsigned int i = 0; i < identifiers.size(); ++i)
7958         addQualifierToExisting(loc, qualifier, *identifiers[i]);
7959 }
7960
7961 // Make sure 'invariant' isn't being applied to a non-allowed object.
7962 void TParseContext::invariantCheck(const TSourceLoc& loc, const TQualifier& qualifier)
7963 {
7964     if (! qualifier.invariant)
7965         return;
7966
7967     bool pipeOut = qualifier.isPipeOutput();
7968     bool pipeIn = qualifier.isPipeInput();
7969     if (version >= 300 || (!isEsProfile() && version >= 420)) {
7970         if (! pipeOut)
7971             error(loc, "can only apply to an output", "invariant", "");
7972     } else {
7973         if ((language == EShLangVertex && pipeIn) || (! pipeOut && ! pipeIn))
7974             error(loc, "can only apply to an output, or to an input in a non-vertex stage\n", "invariant", "");
7975     }
7976 }
7977
7978 //
7979 // Updating default qualifier for the case of a declaration with just a qualifier,
7980 // no type, block, or identifier.
7981 //
7982 void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, const TPublicType& publicType)
7983 {
7984 #ifndef GLSLANG_WEB
7985     if (publicType.shaderQualifiers.vertices != TQualifier::layoutNotSet) {
7986         assert(language == EShLangTessControl || language == EShLangGeometry || language == EShLangMeshNV);
7987         const char* id = (language == EShLangTessControl) ? "vertices" : "max_vertices";
7988
7989         if (publicType.qualifier.storage != EvqVaryingOut)
7990             error(loc, "can only apply to 'out'", id, "");
7991         if (! intermediate.setVertices(publicType.shaderQualifiers.vertices))
7992             error(loc, "cannot change previously set layout value", id, "");
7993
7994         if (language == EShLangTessControl)
7995             checkIoArraysConsistency(loc);
7996     }
7997     if (publicType.shaderQualifiers.primitives != TQualifier::layoutNotSet) {
7998         assert(language == EShLangMeshNV);
7999         const char* id = "max_primitives";
8000
8001         if (publicType.qualifier.storage != EvqVaryingOut)
8002             error(loc, "can only apply to 'out'", id, "");
8003         if (! intermediate.setPrimitives(publicType.shaderQualifiers.primitives))
8004             error(loc, "cannot change previously set layout value", id, "");
8005     }
8006     if (publicType.shaderQualifiers.invocations != TQualifier::layoutNotSet) {
8007         if (publicType.qualifier.storage != EvqVaryingIn)
8008             error(loc, "can only apply to 'in'", "invocations", "");
8009         if (! intermediate.setInvocations(publicType.shaderQualifiers.invocations))
8010             error(loc, "cannot change previously set layout value", "invocations", "");
8011     }
8012     if (publicType.shaderQualifiers.geometry != ElgNone) {
8013         if (publicType.qualifier.storage == EvqVaryingIn) {
8014             switch (publicType.shaderQualifiers.geometry) {
8015             case ElgPoints:
8016             case ElgLines:
8017             case ElgLinesAdjacency:
8018             case ElgTriangles:
8019             case ElgTrianglesAdjacency:
8020             case ElgQuads:
8021             case ElgIsolines:
8022                 if (language == EShLangMeshNV) {
8023                     error(loc, "cannot apply to input", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
8024                     break;
8025                 }
8026                 if (intermediate.setInputPrimitive(publicType.shaderQualifiers.geometry)) {
8027                     if (language == EShLangGeometry)
8028                         checkIoArraysConsistency(loc);
8029                 } else
8030                     error(loc, "cannot change previously set input primitive", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
8031                 break;
8032             default:
8033                 error(loc, "cannot apply to input", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
8034             }
8035         } else if (publicType.qualifier.storage == EvqVaryingOut) {
8036             switch (publicType.shaderQualifiers.geometry) {
8037             case ElgLines:
8038             case ElgTriangles:
8039                 if (language != EShLangMeshNV) {
8040                     error(loc, "cannot apply to 'out'", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
8041                     break;
8042                 }
8043                 // Fall through
8044             case ElgPoints:
8045             case ElgLineStrip:
8046             case ElgTriangleStrip:
8047                 if (! intermediate.setOutputPrimitive(publicType.shaderQualifiers.geometry))
8048                     error(loc, "cannot change previously set output primitive", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
8049                 break;
8050             default:
8051                 error(loc, "cannot apply to 'out'", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
8052             }
8053         } else
8054             error(loc, "cannot apply to:", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), GetStorageQualifierString(publicType.qualifier.storage));
8055     }
8056     if (publicType.shaderQualifiers.spacing != EvsNone) {
8057         if (publicType.qualifier.storage == EvqVaryingIn) {
8058             if (! intermediate.setVertexSpacing(publicType.shaderQualifiers.spacing))
8059                 error(loc, "cannot change previously set vertex spacing", TQualifier::getVertexSpacingString(publicType.shaderQualifiers.spacing), "");
8060         } else
8061             error(loc, "can only apply to 'in'", TQualifier::getVertexSpacingString(publicType.shaderQualifiers.spacing), "");
8062     }
8063     if (publicType.shaderQualifiers.order != EvoNone) {
8064         if (publicType.qualifier.storage == EvqVaryingIn) {
8065             if (! intermediate.setVertexOrder(publicType.shaderQualifiers.order))
8066                 error(loc, "cannot change previously set vertex order", TQualifier::getVertexOrderString(publicType.shaderQualifiers.order), "");
8067         } else
8068             error(loc, "can only apply to 'in'", TQualifier::getVertexOrderString(publicType.shaderQualifiers.order), "");
8069     }
8070     if (publicType.shaderQualifiers.pointMode) {
8071         if (publicType.qualifier.storage == EvqVaryingIn)
8072             intermediate.setPointMode();
8073         else
8074             error(loc, "can only apply to 'in'", "point_mode", "");
8075     }
8076 #endif
8077     for (int i = 0; i < 3; ++i) {
8078         if (publicType.shaderQualifiers.localSizeNotDefault[i]) {
8079             if (publicType.qualifier.storage == EvqVaryingIn) {
8080                 if (! intermediate.setLocalSize(i, publicType.shaderQualifiers.localSize[i]))
8081                     error(loc, "cannot change previously set size", "local_size", "");
8082                 else {
8083                     int max = 0;
8084                     if (language == EShLangCompute) {
8085                         switch (i) {
8086                         case 0: max = resources.maxComputeWorkGroupSizeX; break;
8087                         case 1: max = resources.maxComputeWorkGroupSizeY; break;
8088                         case 2: max = resources.maxComputeWorkGroupSizeZ; break;
8089                         default: break;
8090                         }
8091                         if (intermediate.getLocalSize(i) > (unsigned int)max)
8092                             error(loc, "too large; see gl_MaxComputeWorkGroupSize", "local_size", "");
8093                     }
8094 #ifndef GLSLANG_WEB
8095                     else if (language == EShLangMeshNV) {
8096                         switch (i) {
8097                         case 0: max = resources.maxMeshWorkGroupSizeX_NV; break;
8098                         case 1: max = resources.maxMeshWorkGroupSizeY_NV; break;
8099                         case 2: max = resources.maxMeshWorkGroupSizeZ_NV; break;
8100                         default: break;
8101                         }
8102                         if (intermediate.getLocalSize(i) > (unsigned int)max)
8103                             error(loc, "too large; see gl_MaxMeshWorkGroupSizeNV", "local_size", "");
8104                     } else if (language == EShLangTaskNV) {
8105                         switch (i) {
8106                         case 0: max = resources.maxTaskWorkGroupSizeX_NV; break;
8107                         case 1: max = resources.maxTaskWorkGroupSizeY_NV; break;
8108                         case 2: max = resources.maxTaskWorkGroupSizeZ_NV; break;
8109                         default: break;
8110                         }
8111                         if (intermediate.getLocalSize(i) > (unsigned int)max)
8112                             error(loc, "too large; see gl_MaxTaskWorkGroupSizeNV", "local_size", "");
8113                     }
8114 #endif
8115                     else {
8116                         assert(0);
8117                     }
8118
8119                     // Fix the existing constant gl_WorkGroupSize with this new information.
8120                     TVariable* workGroupSize = getEditableVariable("gl_WorkGroupSize");
8121                     if (workGroupSize != nullptr)
8122                         workGroupSize->getWritableConstArray()[i].setUConst(intermediate.getLocalSize(i));
8123                 }
8124             } else
8125                 error(loc, "can only apply to 'in'", "local_size", "");
8126         }
8127         if (publicType.shaderQualifiers.localSizeSpecId[i] != TQualifier::layoutNotSet) {
8128             if (publicType.qualifier.storage == EvqVaryingIn) {
8129                 if (! intermediate.setLocalSizeSpecId(i, publicType.shaderQualifiers.localSizeSpecId[i]))
8130                     error(loc, "cannot change previously set size", "local_size", "");
8131             } else
8132                 error(loc, "can only apply to 'in'", "local_size id", "");
8133             // Set the workgroup built-in variable as a specialization constant
8134             TVariable* workGroupSize = getEditableVariable("gl_WorkGroupSize");
8135             if (workGroupSize != nullptr)
8136                 workGroupSize->getWritableType().getQualifier().specConstant = true;
8137         }
8138     }
8139
8140 #ifndef GLSLANG_WEB
8141     if (publicType.shaderQualifiers.earlyFragmentTests) {
8142         if (publicType.qualifier.storage == EvqVaryingIn)
8143             intermediate.setEarlyFragmentTests();
8144         else
8145             error(loc, "can only apply to 'in'", "early_fragment_tests", "");
8146     }
8147     if (publicType.shaderQualifiers.postDepthCoverage) {
8148         if (publicType.qualifier.storage == EvqVaryingIn)
8149             intermediate.setPostDepthCoverage();
8150         else
8151             error(loc, "can only apply to 'in'", "post_coverage_coverage", "");
8152     }
8153     if (publicType.shaderQualifiers.hasBlendEquation()) {
8154         if (publicType.qualifier.storage != EvqVaryingOut)
8155             error(loc, "can only apply to 'out'", "blend equation", "");
8156     }
8157     if (publicType.shaderQualifiers.interlockOrdering) {
8158         if (publicType.qualifier.storage == EvqVaryingIn) {
8159             if (!intermediate.setInterlockOrdering(publicType.shaderQualifiers.interlockOrdering))
8160                 error(loc, "cannot change previously set fragment shader interlock ordering", TQualifier::getInterlockOrderingString(publicType.shaderQualifiers.interlockOrdering), "");
8161         }
8162         else
8163             error(loc, "can only apply to 'in'", TQualifier::getInterlockOrderingString(publicType.shaderQualifiers.interlockOrdering), "");
8164     }
8165
8166     if (publicType.shaderQualifiers.layoutDerivativeGroupQuads &&
8167         publicType.shaderQualifiers.layoutDerivativeGroupLinear) {
8168         error(loc, "cannot be both specified", "derivative_group_quadsNV and derivative_group_linearNV", "");
8169     }
8170
8171     if (publicType.shaderQualifiers.layoutDerivativeGroupQuads) {
8172         if (publicType.qualifier.storage == EvqVaryingIn) {
8173             if ((intermediate.getLocalSize(0) & 1) ||
8174                 (intermediate.getLocalSize(1) & 1))
8175                 error(loc, "requires local_size_x and local_size_y to be multiple of two", "derivative_group_quadsNV", "");
8176             else
8177                 intermediate.setLayoutDerivativeMode(LayoutDerivativeGroupQuads);
8178         }
8179         else
8180             error(loc, "can only apply to 'in'", "derivative_group_quadsNV", "");
8181     }
8182     if (publicType.shaderQualifiers.layoutDerivativeGroupLinear) {
8183         if (publicType.qualifier.storage == EvqVaryingIn) {
8184             if((intermediate.getLocalSize(0) *
8185                 intermediate.getLocalSize(1) *
8186                 intermediate.getLocalSize(2)) % 4 != 0)
8187                 error(loc, "requires total group size to be multiple of four", "derivative_group_linearNV", "");
8188             else
8189                 intermediate.setLayoutDerivativeMode(LayoutDerivativeGroupLinear);
8190         }
8191         else
8192             error(loc, "can only apply to 'in'", "derivative_group_linearNV", "");
8193     }
8194     // Check mesh out array sizes, once all the necessary out qualifiers are defined.
8195     if ((language == EShLangMeshNV) &&
8196         (intermediate.getVertices() != TQualifier::layoutNotSet) &&
8197         (intermediate.getPrimitives() != TQualifier::layoutNotSet) &&
8198         (intermediate.getOutputPrimitive() != ElgNone))
8199     {
8200         checkIoArraysConsistency(loc);
8201     }
8202 #endif 
8203     const TQualifier& qualifier = publicType.qualifier;
8204
8205     if (qualifier.isAuxiliary() ||
8206         qualifier.isMemory() ||
8207         qualifier.isInterpolation() ||
8208         qualifier.precision != EpqNone)
8209         error(loc, "cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type)", "qualifier", "");
8210
8211     // "The offset qualifier can only be used on block members of blocks..."
8212     // "The align qualifier can only be used on blocks or block members..."
8213     if (qualifier.hasOffset() ||
8214         qualifier.hasAlign())
8215         error(loc, "cannot use offset or align qualifiers in a default qualifier declaration (declaration with no type)", "layout qualifier", "");
8216
8217     layoutQualifierCheck(loc, qualifier);
8218
8219     switch (qualifier.storage) {
8220     case EvqUniform:
8221         if (qualifier.hasMatrix())
8222             globalUniformDefaults.layoutMatrix = qualifier.layoutMatrix;
8223         if (qualifier.hasPacking())
8224             globalUniformDefaults.layoutPacking = qualifier.layoutPacking;
8225         break;
8226     case EvqBuffer:
8227         if (qualifier.hasMatrix())
8228             globalBufferDefaults.layoutMatrix = qualifier.layoutMatrix;
8229         if (qualifier.hasPacking())
8230             globalBufferDefaults.layoutPacking = qualifier.layoutPacking;
8231         break;
8232     case EvqVaryingIn:
8233         break;
8234     case EvqVaryingOut:
8235 #ifndef GLSLANG_WEB
8236         if (qualifier.hasStream())
8237             globalOutputDefaults.layoutStream = qualifier.layoutStream;
8238         if (qualifier.hasXfbBuffer())
8239             globalOutputDefaults.layoutXfbBuffer = qualifier.layoutXfbBuffer;
8240         if (globalOutputDefaults.hasXfbBuffer() && qualifier.hasXfbStride()) {
8241             if (! intermediate.setXfbBufferStride(globalOutputDefaults.layoutXfbBuffer, qualifier.layoutXfbStride))
8242                 error(loc, "all stride settings must match for xfb buffer", "xfb_stride", "%d", qualifier.layoutXfbBuffer);
8243         }
8244 #endif
8245         break;
8246     default:
8247         error(loc, "default qualifier requires 'uniform', 'buffer', 'in', or 'out' storage qualification", "", "");
8248         return;
8249     }
8250
8251     if (qualifier.hasBinding())
8252         error(loc, "cannot declare a default, include a type or full declaration", "binding", "");
8253     if (qualifier.hasAnyLocation())
8254         error(loc, "cannot declare a default, use a full declaration", "location/component/index", "");
8255     if (qualifier.hasXfbOffset())
8256         error(loc, "cannot declare a default, use a full declaration", "xfb_offset", "");
8257     if (qualifier.isPushConstant())
8258         error(loc, "cannot declare a default, can only be used on a block", "push_constant", "");
8259     if (qualifier.hasBufferReference())
8260         error(loc, "cannot declare a default, can only be used on a block", "buffer_reference", "");
8261     if (qualifier.hasSpecConstantId())
8262         error(loc, "cannot declare a default, can only be used on a scalar", "constant_id", "");
8263     if (qualifier.isShaderRecord())
8264         error(loc, "cannot declare a default, can only be used on a block", "shaderRecordNV", "");
8265 }
8266
8267 //
8268 // Take the sequence of statements that has been built up since the last case/default,
8269 // put it on the list of top-level nodes for the current (inner-most) switch statement,
8270 // and follow that by the case/default we are on now.  (See switch topology comment on
8271 // TIntermSwitch.)
8272 //
8273 void TParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode)
8274 {
8275     TIntermSequence* switchSequence = switchSequenceStack.back();
8276
8277     if (statements) {
8278         if (switchSequence->size() == 0)
8279             error(statements->getLoc(), "cannot have statements before first case/default label", "switch", "");
8280         statements->setOperator(EOpSequence);
8281         switchSequence->push_back(statements);
8282     }
8283     if (branchNode) {
8284         // check all previous cases for the same label (or both are 'default')
8285         for (unsigned int s = 0; s < switchSequence->size(); ++s) {
8286             TIntermBranch* prevBranch = (*switchSequence)[s]->getAsBranchNode();
8287             if (prevBranch) {
8288                 TIntermTyped* prevExpression = prevBranch->getExpression();
8289                 TIntermTyped* newExpression = branchNode->getAsBranchNode()->getExpression();
8290                 if (prevExpression == nullptr && newExpression == nullptr)
8291                     error(branchNode->getLoc(), "duplicate label", "default", "");
8292                 else if (prevExpression != nullptr &&
8293                           newExpression != nullptr &&
8294                          prevExpression->getAsConstantUnion() &&
8295                           newExpression->getAsConstantUnion() &&
8296                          prevExpression->getAsConstantUnion()->getConstArray()[0].getIConst() ==
8297                           newExpression->getAsConstantUnion()->getConstArray()[0].getIConst())
8298                     error(branchNode->getLoc(), "duplicated value", "case", "");
8299             }
8300         }
8301         switchSequence->push_back(branchNode);
8302     }
8303 }
8304
8305 //
8306 // Turn the top-level node sequence built up of wrapupSwitchSubsequence9)
8307 // into a switch node.
8308 //
8309 TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expression, TIntermAggregate* lastStatements)
8310 {
8311     profileRequires(loc, EEsProfile, 300, nullptr, "switch statements");
8312     profileRequires(loc, ENoProfile, 130, nullptr, "switch statements");
8313
8314     wrapupSwitchSubsequence(lastStatements, nullptr);
8315
8316     if (expression == nullptr ||
8317         (expression->getBasicType() != EbtInt && expression->getBasicType() != EbtUint) ||
8318         expression->getType().isArray() || expression->getType().isMatrix() || expression->getType().isVector())
8319             error(loc, "condition must be a scalar integer expression", "switch", "");
8320
8321     // If there is nothing to do, drop the switch but still execute the expression
8322     TIntermSequence* switchSequence = switchSequenceStack.back();
8323     if (switchSequence->size() == 0)
8324         return expression;
8325
8326     if (lastStatements == nullptr) {
8327         // This was originally an ERRROR, because early versions of the specification said
8328         // "it is an error to have no statement between a label and the end of the switch statement."
8329         // The specifications were updated to remove this (being ill-defined what a "statement" was),
8330         // so, this became a warning.  However, 3.0 tests still check for the error.
8331         if (isEsProfile() && version <= 300 && ! relaxedErrors())
8332             error(loc, "last case/default label not followed by statements", "switch", "");
8333         else
8334             warn(loc, "last case/default label not followed by statements", "switch", "");
8335
8336         // emulate a break for error recovery
8337         lastStatements = intermediate.makeAggregate(intermediate.addBranch(EOpBreak, loc));
8338         lastStatements->setOperator(EOpSequence);
8339         switchSequence->push_back(lastStatements);
8340     }
8341
8342     TIntermAggregate* body = new TIntermAggregate(EOpSequence);
8343     body->getSequence() = *switchSequenceStack.back();
8344     body->setLoc(loc);
8345
8346     TIntermSwitch* switchNode = new TIntermSwitch(expression, body);
8347     switchNode->setLoc(loc);
8348
8349     return switchNode;
8350 }
8351
8352 } // end namespace glslang
8353