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