LCOV - code coverage report
Current view: top level - gfx/angle/src/compiler/translator - ParseContext.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 1946 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 109 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
       3             : // Use of this source code is governed by a BSD-style license that can be
       4             : // found in the LICENSE file.
       5             : //
       6             : 
       7             : #include "compiler/translator/ParseContext.h"
       8             : 
       9             : #include <stdarg.h>
      10             : #include <stdio.h>
      11             : 
      12             : #include "compiler/preprocessor/SourceLocation.h"
      13             : #include "compiler/translator/Cache.h"
      14             : #include "compiler/translator/glslang.h"
      15             : #include "compiler/translator/ValidateSwitch.h"
      16             : #include "compiler/translator/ValidateGlobalInitializer.h"
      17             : #include "compiler/translator/util.h"
      18             : 
      19             : namespace sh
      20             : {
      21             : 
      22             : ///////////////////////////////////////////////////////////////////////
      23             : //
      24             : // Sub- vector and matrix fields
      25             : //
      26             : ////////////////////////////////////////////////////////////////////////
      27             : 
      28             : namespace
      29             : {
      30             : 
      31             : const int kWebGLMaxStructNesting = 4;
      32             : 
      33           0 : bool ContainsSampler(const TType &type)
      34             : {
      35           0 :     if (IsSampler(type.getBasicType()))
      36           0 :         return true;
      37             : 
      38           0 :     if (type.getBasicType() == EbtStruct || type.isInterfaceBlock())
      39             :     {
      40           0 :         const TFieldList &fields = type.getStruct()->fields();
      41           0 :         for (unsigned int i = 0; i < fields.size(); ++i)
      42             :         {
      43           0 :             if (ContainsSampler(*fields[i]->type()))
      44           0 :                 return true;
      45             :         }
      46             :     }
      47             : 
      48           0 :     return false;
      49             : }
      50             : 
      51           0 : bool ContainsImage(const TType &type)
      52             : {
      53           0 :     if (IsImage(type.getBasicType()))
      54           0 :         return true;
      55             : 
      56           0 :     if (type.getBasicType() == EbtStruct || type.isInterfaceBlock())
      57             :     {
      58           0 :         const TFieldList &fields = type.getStruct()->fields();
      59           0 :         for (unsigned int i = 0; i < fields.size(); ++i)
      60             :         {
      61           0 :             if (ContainsImage(*fields[i]->type()))
      62           0 :                 return true;
      63             :         }
      64             :     }
      65             : 
      66           0 :     return false;
      67             : }
      68             : 
      69             : }  // namespace
      70             : 
      71           0 : TParseContext::TParseContext(TSymbolTable &symt,
      72             :                              TExtensionBehavior &ext,
      73             :                              sh::GLenum type,
      74             :                              ShShaderSpec spec,
      75             :                              ShCompileOptions options,
      76             :                              bool checksPrecErrors,
      77             :                              TInfoSink &is,
      78           0 :                              const ShBuiltInResources &resources)
      79             :     : intermediate(),
      80             :       symbolTable(symt),
      81             :       mDeferredSingleDeclarationErrorCheck(false),
      82             :       mShaderType(type),
      83             :       mShaderSpec(spec),
      84             :       mCompileOptions(options),
      85             :       mShaderVersion(100),
      86             :       mTreeRoot(nullptr),
      87             :       mLoopNestingLevel(0),
      88             :       mStructNestingLevel(0),
      89             :       mSwitchNestingLevel(0),
      90             :       mCurrentFunctionType(nullptr),
      91             :       mFunctionReturnsValue(false),
      92             :       mChecksPrecisionErrors(checksPrecErrors),
      93             :       mFragmentPrecisionHighOnESSL1(false),
      94             :       mDefaultMatrixPacking(EmpColumnMajor),
      95           0 :       mDefaultBlockStorage(sh::IsWebGLBasedSpec(spec) ? EbsStd140 : EbsShared),
      96             :       mDiagnostics(is),
      97             :       mDirectiveHandler(ext,
      98             :                         mDiagnostics,
      99             :                         mShaderVersion,
     100             :                         mShaderType,
     101           0 :                         resources.WEBGL_debug_shader_precision == 1),
     102           0 :       mPreprocessor(&mDiagnostics, &mDirectiveHandler, pp::PreprocessorSettings()),
     103             :       mScanner(nullptr),
     104             :       mUsesFragData(false),
     105             :       mUsesFragColor(false),
     106             :       mUsesSecondaryOutputs(false),
     107           0 :       mMinProgramTexelOffset(resources.MinProgramTexelOffset),
     108           0 :       mMaxProgramTexelOffset(resources.MaxProgramTexelOffset),
     109             :       mComputeShaderLocalSizeDeclared(false),
     110           0 :       mDeclaringFunction(false)
     111             : {
     112           0 :     mComputeShaderLocalSize.fill(-1);
     113           0 : }
     114             : 
     115             : //
     116             : // Look at a '.' field selector string and change it into offsets
     117             : // for a vector.
     118             : //
     119           0 : bool TParseContext::parseVectorFields(const TString &compString,
     120             :                                       int vecSize,
     121             :                                       TVectorFields &fields,
     122             :                                       const TSourceLoc &line)
     123             : {
     124           0 :     fields.num = (int)compString.size();
     125           0 :     if (fields.num > 4)
     126             :     {
     127           0 :         error(line, "illegal vector field selection", compString.c_str());
     128           0 :         return false;
     129             :     }
     130             : 
     131             :     enum
     132             :     {
     133             :         exyzw,
     134             :         ergba,
     135             :         estpq
     136             :     } fieldSet[4];
     137             : 
     138           0 :     for (int i = 0; i < fields.num; ++i)
     139             :     {
     140           0 :         switch (compString[i])
     141             :         {
     142             :             case 'x':
     143           0 :                 fields.offsets[i] = 0;
     144           0 :                 fieldSet[i]       = exyzw;
     145           0 :                 break;
     146             :             case 'r':
     147           0 :                 fields.offsets[i] = 0;
     148           0 :                 fieldSet[i]       = ergba;
     149           0 :                 break;
     150             :             case 's':
     151           0 :                 fields.offsets[i] = 0;
     152           0 :                 fieldSet[i]       = estpq;
     153           0 :                 break;
     154             :             case 'y':
     155           0 :                 fields.offsets[i] = 1;
     156           0 :                 fieldSet[i]       = exyzw;
     157           0 :                 break;
     158             :             case 'g':
     159           0 :                 fields.offsets[i] = 1;
     160           0 :                 fieldSet[i]       = ergba;
     161           0 :                 break;
     162             :             case 't':
     163           0 :                 fields.offsets[i] = 1;
     164           0 :                 fieldSet[i]       = estpq;
     165           0 :                 break;
     166             :             case 'z':
     167           0 :                 fields.offsets[i] = 2;
     168           0 :                 fieldSet[i]       = exyzw;
     169           0 :                 break;
     170             :             case 'b':
     171           0 :                 fields.offsets[i] = 2;
     172           0 :                 fieldSet[i]       = ergba;
     173           0 :                 break;
     174             :             case 'p':
     175           0 :                 fields.offsets[i] = 2;
     176           0 :                 fieldSet[i]       = estpq;
     177           0 :                 break;
     178             : 
     179             :             case 'w':
     180           0 :                 fields.offsets[i] = 3;
     181           0 :                 fieldSet[i]       = exyzw;
     182           0 :                 break;
     183             :             case 'a':
     184           0 :                 fields.offsets[i] = 3;
     185           0 :                 fieldSet[i]       = ergba;
     186           0 :                 break;
     187             :             case 'q':
     188           0 :                 fields.offsets[i] = 3;
     189           0 :                 fieldSet[i]       = estpq;
     190           0 :                 break;
     191             :             default:
     192           0 :                 error(line, "illegal vector field selection", compString.c_str());
     193           0 :                 return false;
     194             :         }
     195             :     }
     196             : 
     197           0 :     for (int i = 0; i < fields.num; ++i)
     198             :     {
     199           0 :         if (fields.offsets[i] >= vecSize)
     200             :         {
     201           0 :             error(line, "vector field selection out of range", compString.c_str());
     202           0 :             return false;
     203             :         }
     204             : 
     205           0 :         if (i > 0)
     206             :         {
     207           0 :             if (fieldSet[i] != fieldSet[i - 1])
     208             :             {
     209           0 :                 error(line, "illegal - vector component fields not from the same set",
     210           0 :                       compString.c_str());
     211           0 :                 return false;
     212             :             }
     213             :         }
     214             :     }
     215             : 
     216           0 :     return true;
     217             : }
     218             : 
     219             : ///////////////////////////////////////////////////////////////////////
     220             : //
     221             : // Errors
     222             : //
     223             : ////////////////////////////////////////////////////////////////////////
     224             : 
     225             : 
     226             : //
     227             : // Used by flex/bison to output all syntax and parsing errors.
     228             : //
     229           0 : void TParseContext::error(const TSourceLoc &loc,
     230             :                           const char *reason,
     231             :                           const char *token,
     232             :                           const char *extraInfo)
     233             : {
     234           0 :     mDiagnostics.error(loc, reason, token, extraInfo);
     235           0 : }
     236             : 
     237           0 : void TParseContext::warning(const TSourceLoc &loc,
     238             :                             const char *reason,
     239             :                             const char *token,
     240             :                             const char *extraInfo)
     241             : {
     242           0 :     mDiagnostics.warning(loc, reason, token, extraInfo);
     243           0 : }
     244             : 
     245           0 : void TParseContext::outOfRangeError(bool isError,
     246             :                                     const TSourceLoc &loc,
     247             :                                     const char *reason,
     248             :                                     const char *token,
     249             :                                     const char *extraInfo)
     250             : {
     251           0 :     if (isError)
     252             :     {
     253           0 :         error(loc, reason, token, extraInfo);
     254             :     }
     255             :     else
     256             :     {
     257           0 :         warning(loc, reason, token, extraInfo);
     258             :     }
     259           0 : }
     260             : 
     261             : //
     262             : // Same error message for all places assignments don't work.
     263             : //
     264           0 : void TParseContext::assignError(const TSourceLoc &line, const char *op, TString left, TString right)
     265             : {
     266           0 :     std::stringstream extraInfoStream;
     267           0 :     extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'";
     268           0 :     std::string extraInfo = extraInfoStream.str();
     269           0 :     error(line, "", op, extraInfo.c_str());
     270           0 : }
     271             : 
     272             : //
     273             : // Same error message for all places unary operations don't work.
     274             : //
     275           0 : void TParseContext::unaryOpError(const TSourceLoc &line, const char *op, TString operand)
     276             : {
     277           0 :     std::stringstream extraInfoStream;
     278             :     extraInfoStream << "no operation '" << op << "' exists that takes an operand of type "
     279           0 :                     << operand << " (or there is no acceptable conversion)";
     280           0 :     std::string extraInfo = extraInfoStream.str();
     281           0 :     error(line, " wrong operand type", op, extraInfo.c_str());
     282           0 : }
     283             : 
     284             : //
     285             : // Same error message for all binary operations don't work.
     286             : //
     287           0 : void TParseContext::binaryOpError(const TSourceLoc &line,
     288             :                                   const char *op,
     289             :                                   TString left,
     290             :                                   TString right)
     291             : {
     292           0 :     std::stringstream extraInfoStream;
     293             :     extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '"
     294             :                     << left << "' and a right operand of type '" << right
     295           0 :                     << "' (or there is no acceptable conversion)";
     296           0 :     std::string extraInfo = extraInfoStream.str();
     297           0 :     error(line, " wrong operand types ", op, extraInfo.c_str());
     298           0 : }
     299             : 
     300           0 : void TParseContext::checkPrecisionSpecified(const TSourceLoc &line,
     301             :                                             TPrecision precision,
     302             :                                             TBasicType type)
     303             : {
     304           0 :     if (!mChecksPrecisionErrors)
     305           0 :         return;
     306             : 
     307           0 :     if (precision != EbpUndefined && !SupportsPrecision(type))
     308             :     {
     309           0 :         error(line, "illegal type for precision qualifier", getBasicString(type));
     310             :     }
     311             : 
     312           0 :     if (precision == EbpUndefined)
     313             :     {
     314           0 :         switch (type)
     315             :         {
     316             :             case EbtFloat:
     317           0 :                 error(line, "No precision specified for (float)", "");
     318           0 :                 return;
     319             :             case EbtInt:
     320             :             case EbtUInt:
     321           0 :                 UNREACHABLE();  // there's always a predeclared qualifier
     322             :                 error(line, "No precision specified (int)", "");
     323             :                 return;
     324             :             default:
     325           0 :                 if (IsSampler(type))
     326             :                 {
     327           0 :                     error(line, "No precision specified (sampler)", "");
     328           0 :                     return;
     329             :                 }
     330           0 :                 if (IsImage(type))
     331             :                 {
     332           0 :                     error(line, "No precision specified (image)", "");
     333           0 :                     return;
     334             :                 }
     335             :         }
     336             :     }
     337             : }
     338             : 
     339             : // Both test and if necessary, spit out an error, to see if the node is really
     340             : // an l-value that can be operated on this way.
     341           0 : bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIntermTyped *node)
     342             : {
     343           0 :     TIntermSymbol *symNode    = node->getAsSymbolNode();
     344           0 :     TIntermBinary *binaryNode = node->getAsBinaryNode();
     345           0 :     TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
     346             : 
     347           0 :     if (swizzleNode)
     348             :     {
     349           0 :         bool ok = checkCanBeLValue(line, op, swizzleNode->getOperand());
     350           0 :         if (ok && swizzleNode->hasDuplicateOffsets())
     351             :         {
     352           0 :             error(line, " l-value of swizzle cannot have duplicate components", op);
     353           0 :             return false;
     354             :         }
     355           0 :         return ok;
     356             :     }
     357             : 
     358           0 :     if (binaryNode)
     359             :     {
     360           0 :         switch (binaryNode->getOp())
     361             :         {
     362             :             case EOpIndexDirect:
     363             :             case EOpIndexIndirect:
     364             :             case EOpIndexDirectStruct:
     365             :             case EOpIndexDirectInterfaceBlock:
     366           0 :                 return checkCanBeLValue(line, op, binaryNode->getLeft());
     367             :             default:
     368           0 :                 break;
     369             :         }
     370           0 :         error(line, " l-value required", op);
     371           0 :         return false;
     372             :     }
     373             : 
     374           0 :     const char *symbol = 0;
     375           0 :     if (symNode != 0)
     376           0 :         symbol = symNode->getSymbol().c_str();
     377             : 
     378           0 :     const char *message = 0;
     379           0 :     switch (node->getQualifier())
     380             :     {
     381             :         case EvqConst:
     382           0 :             message = "can't modify a const";
     383           0 :             break;
     384             :         case EvqConstReadOnly:
     385           0 :             message = "can't modify a const";
     386           0 :             break;
     387             :         case EvqAttribute:
     388           0 :             message = "can't modify an attribute";
     389           0 :             break;
     390             :         case EvqFragmentIn:
     391           0 :             message = "can't modify an input";
     392           0 :             break;
     393             :         case EvqVertexIn:
     394           0 :             message = "can't modify an input";
     395           0 :             break;
     396             :         case EvqUniform:
     397           0 :             message = "can't modify a uniform";
     398           0 :             break;
     399             :         case EvqVaryingIn:
     400           0 :             message = "can't modify a varying";
     401           0 :             break;
     402             :         case EvqFragCoord:
     403           0 :             message = "can't modify gl_FragCoord";
     404           0 :             break;
     405             :         case EvqFrontFacing:
     406           0 :             message = "can't modify gl_FrontFacing";
     407           0 :             break;
     408             :         case EvqPointCoord:
     409           0 :             message = "can't modify gl_PointCoord";
     410           0 :             break;
     411             :         case EvqNumWorkGroups:
     412           0 :             message = "can't modify gl_NumWorkGroups";
     413           0 :             break;
     414             :         case EvqWorkGroupSize:
     415           0 :             message = "can't modify gl_WorkGroupSize";
     416           0 :             break;
     417             :         case EvqWorkGroupID:
     418           0 :             message = "can't modify gl_WorkGroupID";
     419           0 :             break;
     420             :         case EvqLocalInvocationID:
     421           0 :             message = "can't modify gl_LocalInvocationID";
     422           0 :             break;
     423             :         case EvqGlobalInvocationID:
     424           0 :             message = "can't modify gl_GlobalInvocationID";
     425           0 :             break;
     426             :         case EvqLocalInvocationIndex:
     427           0 :             message = "can't modify gl_LocalInvocationIndex";
     428           0 :             break;
     429             :         case EvqComputeIn:
     430           0 :             message = "can't modify work group size variable";
     431           0 :             break;
     432             :         default:
     433             :             //
     434             :             // Type that can't be written to?
     435             :             //
     436           0 :             if (node->getBasicType() == EbtVoid)
     437             :             {
     438           0 :                 message = "can't modify void";
     439             :             }
     440           0 :             if (IsSampler(node->getBasicType()))
     441             :             {
     442           0 :                 message = "can't modify a sampler";
     443             :             }
     444           0 :             if (IsImage(node->getBasicType()))
     445             :             {
     446           0 :                 message = "can't modify an image";
     447             :             }
     448             :     }
     449             : 
     450           0 :     if (message == 0 && binaryNode == 0 && symNode == 0)
     451             :     {
     452           0 :         error(line, " l-value required", op);
     453             : 
     454           0 :         return false;
     455             :     }
     456             : 
     457             :     //
     458             :     // Everything else is okay, no error.
     459             :     //
     460           0 :     if (message == 0)
     461           0 :         return true;
     462             : 
     463             :     //
     464             :     // If we get here, we have an error and a message.
     465             :     //
     466           0 :     if (symNode)
     467             :     {
     468           0 :         std::stringstream extraInfoStream;
     469           0 :         extraInfoStream << "\"" << symbol << "\" (" << message << ")";
     470           0 :         std::string extraInfo = extraInfoStream.str();
     471           0 :         error(line, " l-value required", op, extraInfo.c_str());
     472             :     }
     473             :     else
     474             :     {
     475           0 :         std::stringstream extraInfoStream;
     476           0 :         extraInfoStream << "(" << message << ")";
     477           0 :         std::string extraInfo = extraInfoStream.str();
     478           0 :         error(line, " l-value required", op, extraInfo.c_str());
     479             :     }
     480             : 
     481           0 :     return false;
     482             : }
     483             : 
     484             : // Both test, and if necessary spit out an error, to see if the node is really
     485             : // a constant.
     486           0 : void TParseContext::checkIsConst(TIntermTyped *node)
     487             : {
     488           0 :     if (node->getQualifier() != EvqConst)
     489             :     {
     490           0 :         error(node->getLine(), "constant expression required", "");
     491             :     }
     492           0 : }
     493             : 
     494             : // Both test, and if necessary spit out an error, to see if the node is really
     495             : // an integer.
     496           0 : void TParseContext::checkIsScalarInteger(TIntermTyped *node, const char *token)
     497             : {
     498           0 :     if (!node->isScalarInt())
     499             :     {
     500           0 :         error(node->getLine(), "integer expression required", token);
     501             :     }
     502           0 : }
     503             : 
     504             : // Both test, and if necessary spit out an error, to see if we are currently
     505             : // globally scoped.
     506           0 : bool TParseContext::checkIsAtGlobalLevel(const TSourceLoc &line, const char *token)
     507             : {
     508           0 :     if (!symbolTable.atGlobalLevel())
     509             :     {
     510           0 :         error(line, "only allowed at global scope", token);
     511           0 :         return false;
     512             :     }
     513           0 :     return true;
     514             : }
     515             : 
     516             : // For now, keep it simple:  if it starts "gl_", it's reserved, independent
     517             : // of scope.  Except, if the symbol table is at the built-in push-level,
     518             : // which is when we are parsing built-ins.
     519             : // Also checks for "webgl_" and "_webgl_" reserved identifiers if parsing a
     520             : // webgl shader.
     521           0 : bool TParseContext::checkIsNotReserved(const TSourceLoc &line, const TString &identifier)
     522             : {
     523             :     static const char *reservedErrMsg = "reserved built-in name";
     524           0 :     if (!symbolTable.atBuiltInLevel())
     525             :     {
     526           0 :         if (identifier.compare(0, 3, "gl_") == 0)
     527             :         {
     528           0 :             error(line, reservedErrMsg, "gl_");
     529           0 :             return false;
     530             :         }
     531           0 :         if (sh::IsWebGLBasedSpec(mShaderSpec))
     532             :         {
     533           0 :             if (identifier.compare(0, 6, "webgl_") == 0)
     534             :             {
     535           0 :                 error(line, reservedErrMsg, "webgl_");
     536           0 :                 return false;
     537             :             }
     538           0 :             if (identifier.compare(0, 7, "_webgl_") == 0)
     539             :             {
     540           0 :                 error(line, reservedErrMsg, "_webgl_");
     541           0 :                 return false;
     542             :             }
     543             :         }
     544           0 :         if (identifier.find("__") != TString::npos)
     545             :         {
     546           0 :             error(line,
     547             :                   "identifiers containing two consecutive underscores (__) are reserved as "
     548             :                   "possible future keywords",
     549           0 :                   identifier.c_str());
     550           0 :             return false;
     551             :         }
     552             :     }
     553             : 
     554           0 :     return true;
     555             : }
     556             : 
     557             : // Make sure there is enough data provided to the constructor to build
     558             : // something of the type of the constructor.  Also returns the type of
     559             : // the constructor.
     560           0 : bool TParseContext::checkConstructorArguments(const TSourceLoc &line,
     561             :                                               TIntermNode *argumentsNode,
     562             :                                               const TFunction &function,
     563             :                                               TOperator op,
     564             :                                               const TType &type)
     565             : {
     566           0 :     bool constructingMatrix = false;
     567           0 :     switch (op)
     568             :     {
     569             :         case EOpConstructMat2:
     570             :         case EOpConstructMat2x3:
     571             :         case EOpConstructMat2x4:
     572             :         case EOpConstructMat3x2:
     573             :         case EOpConstructMat3:
     574             :         case EOpConstructMat3x4:
     575             :         case EOpConstructMat4x2:
     576             :         case EOpConstructMat4x3:
     577             :         case EOpConstructMat4:
     578           0 :             constructingMatrix = true;
     579           0 :             break;
     580             :         default:
     581           0 :             break;
     582             :     }
     583             : 
     584             :     //
     585             :     // Note: It's okay to have too many components available, but not okay to have unused
     586             :     // arguments.  'full' will go to true when enough args have been seen.  If we loop
     587             :     // again, there is an extra argument, so 'overfull' will become true.
     588             :     //
     589             : 
     590           0 :     size_t size         = 0;
     591           0 :     bool full           = false;
     592           0 :     bool overFull       = false;
     593           0 :     bool matrixInMatrix = false;
     594           0 :     bool arrayArg = false;
     595           0 :     for (size_t i = 0; i < function.getParamCount(); ++i)
     596             :     {
     597           0 :         const TConstParameter &param = function.getParam(i);
     598           0 :         size += param.type->getObjectSize();
     599             : 
     600           0 :         if (constructingMatrix && param.type->isMatrix())
     601           0 :             matrixInMatrix = true;
     602           0 :         if (full)
     603           0 :             overFull = true;
     604           0 :         if (op != EOpConstructStruct && !type.isArray() && size >= type.getObjectSize())
     605           0 :             full = true;
     606           0 :         if (param.type->isArray())
     607           0 :             arrayArg = true;
     608             :     }
     609             : 
     610           0 :     if (type.isArray())
     611             :     {
     612             :         // The size of an unsized constructor should already have been determined.
     613           0 :         ASSERT(!type.isUnsizedArray());
     614           0 :         if (static_cast<size_t>(type.getArraySize()) != function.getParamCount())
     615             :         {
     616           0 :             error(line, "array constructor needs one argument per array element", "constructor");
     617           0 :             return false;
     618             :         }
     619             :     }
     620             : 
     621           0 :     if (arrayArg && op != EOpConstructStruct)
     622             :     {
     623           0 :         error(line, "constructing from a non-dereferenced array", "constructor");
     624           0 :         return false;
     625             :     }
     626             : 
     627           0 :     if (matrixInMatrix && !type.isArray())
     628             :     {
     629           0 :         if (function.getParamCount() != 1)
     630             :         {
     631             :             error(line, "constructing matrix from matrix can only take one argument",
     632           0 :                   "constructor");
     633           0 :             return false;
     634             :         }
     635             :     }
     636             : 
     637           0 :     if (overFull)
     638             :     {
     639           0 :         error(line, "too many arguments", "constructor");
     640           0 :         return false;
     641             :     }
     642             : 
     643           0 :     if (op == EOpConstructStruct && !type.isArray() &&
     644           0 :         type.getStruct()->fields().size() != function.getParamCount())
     645             :     {
     646             :         error(line,
     647             :               "Number of constructor parameters does not match the number of structure fields",
     648           0 :               "constructor");
     649           0 :         return false;
     650             :     }
     651             : 
     652           0 :     if (!type.isMatrix() || !matrixInMatrix)
     653             :     {
     654           0 :         if ((op != EOpConstructStruct && size != 1 && size < type.getObjectSize()) ||
     655           0 :             (op == EOpConstructStruct && size < type.getObjectSize()))
     656             :         {
     657           0 :             error(line, "not enough data provided for construction", "constructor");
     658           0 :             return false;
     659             :         }
     660             :     }
     661             : 
     662           0 :     if (argumentsNode == nullptr)
     663             :     {
     664           0 :         error(line, "constructor does not have any arguments", "constructor");
     665           0 :         return false;
     666             :     }
     667             : 
     668           0 :     TIntermAggregate *argumentsAgg = argumentsNode->getAsAggregate();
     669           0 :     for (TIntermNode *&argNode : *argumentsAgg->getSequence())
     670             :     {
     671           0 :         TIntermTyped *argTyped = argNode->getAsTyped();
     672           0 :         ASSERT(argTyped != nullptr);
     673           0 :         if (op != EOpConstructStruct && IsSampler(argTyped->getBasicType()))
     674             :         {
     675           0 :             error(line, "cannot convert a sampler", "constructor");
     676           0 :             return false;
     677             :         }
     678           0 :         if (op != EOpConstructStruct && IsImage(argTyped->getBasicType()))
     679             :         {
     680           0 :             error(line, "cannot convert an image", "constructor");
     681           0 :             return false;
     682             :         }
     683           0 :         if (argTyped->getBasicType() == EbtVoid)
     684             :         {
     685           0 :             error(line, "cannot convert a void", "constructor");
     686           0 :             return false;
     687             :         }
     688             :     }
     689             : 
     690           0 :     if (type.isArray())
     691             :     {
     692             :         // GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of
     693             :         // the array.
     694           0 :         for (TIntermNode *&argNode : *argumentsAgg->getSequence())
     695             :         {
     696           0 :             const TType &argType = argNode->getAsTyped()->getType();
     697             :             // It has already been checked that the argument is not an array.
     698           0 :             ASSERT(!argType.isArray());
     699           0 :             if (!argType.sameElementType(type))
     700             :             {
     701           0 :                 error(line, "Array constructor argument has an incorrect type", "Error");
     702           0 :                 return false;
     703             :             }
     704             :         }
     705             :     }
     706           0 :     else if (op == EOpConstructStruct)
     707             :     {
     708           0 :         const TFieldList &fields = type.getStruct()->fields();
     709           0 :         TIntermSequence *args    = argumentsAgg->getSequence();
     710             : 
     711           0 :         for (size_t i = 0; i < fields.size(); i++)
     712             :         {
     713           0 :             if (i >= args->size() || (*args)[i]->getAsTyped()->getType() != *fields[i]->type())
     714             :             {
     715             :                 error(line, "Structure constructor arguments do not match structure fields",
     716           0 :                       "Error");
     717           0 :                 return false;
     718             :             }
     719             :         }
     720             :     }
     721             : 
     722           0 :     return true;
     723             : }
     724             : 
     725             : // This function checks to see if a void variable has been declared and raise an error message for
     726             : // such a case
     727             : //
     728             : // returns true in case of an error
     729             : //
     730           0 : bool TParseContext::checkIsNonVoid(const TSourceLoc &line,
     731             :                                    const TString &identifier,
     732             :                                    const TBasicType &type)
     733             : {
     734           0 :     if (type == EbtVoid)
     735             :     {
     736           0 :         error(line, "illegal use of type 'void'", identifier.c_str());
     737           0 :         return false;
     738             :     }
     739             : 
     740           0 :     return true;
     741             : }
     742             : 
     743             : // This function checks to see if the node (for the expression) contains a scalar boolean expression
     744             : // or not.
     745           0 : void TParseContext::checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type)
     746             : {
     747           0 :     if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector())
     748             :     {
     749           0 :         error(line, "boolean expression expected", "");
     750             :     }
     751           0 : }
     752             : 
     753             : // This function checks to see if the node (for the expression) contains a scalar boolean expression
     754             : // or not.
     755           0 : void TParseContext::checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType)
     756             : {
     757           0 :     if (pType.getBasicType() != EbtBool || pType.isAggregate())
     758             :     {
     759           0 :         error(line, "boolean expression expected", "");
     760             :     }
     761           0 : }
     762             : 
     763           0 : bool TParseContext::checkIsNotSampler(const TSourceLoc &line,
     764             :                                       const TTypeSpecifierNonArray &pType,
     765             :                                       const char *reason)
     766             : {
     767           0 :     if (pType.type == EbtStruct)
     768             :     {
     769           0 :         if (ContainsSampler(*pType.userDef))
     770             :         {
     771           0 :             error(line, reason, getBasicString(pType.type), "(structure contains a sampler)");
     772           0 :             return false;
     773             :         }
     774             : 
     775           0 :         return true;
     776             :     }
     777           0 :     else if (IsSampler(pType.type))
     778             :     {
     779           0 :         error(line, reason, getBasicString(pType.type));
     780           0 :         return false;
     781             :     }
     782             : 
     783           0 :     return true;
     784             : }
     785             : 
     786           0 : bool TParseContext::checkIsNotImage(const TSourceLoc &line,
     787             :                                     const TTypeSpecifierNonArray &pType,
     788             :                                     const char *reason)
     789             : {
     790           0 :     if (pType.type == EbtStruct)
     791             :     {
     792           0 :         if (ContainsImage(*pType.userDef))
     793             :         {
     794           0 :             error(line, reason, getBasicString(pType.type), "(structure contains an image)");
     795             : 
     796           0 :             return false;
     797             :         }
     798             : 
     799           0 :         return true;
     800             :     }
     801           0 :     else if (IsImage(pType.type))
     802             :     {
     803           0 :         error(line, reason, getBasicString(pType.type));
     804             : 
     805           0 :         return false;
     806             :     }
     807             : 
     808           0 :     return true;
     809             : }
     810             : 
     811           0 : void TParseContext::checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line,
     812             :                                                           const TPublicType &pType)
     813             : {
     814           0 :     if (pType.layoutQualifier.location != -1)
     815             :     {
     816             :         error(line, "location must only be specified for a single input or output variable",
     817           0 :               "location");
     818             :     }
     819           0 : }
     820             : 
     821           0 : void TParseContext::checkLocationIsNotSpecified(const TSourceLoc &location,
     822             :                                                 const TLayoutQualifier &layoutQualifier)
     823             : {
     824           0 :     if (layoutQualifier.location != -1)
     825             :     {
     826             :         error(location, "invalid layout qualifier:", "location",
     827           0 :               "only valid on program inputs and outputs");
     828             :     }
     829           0 : }
     830             : 
     831           0 : void TParseContext::checkOutParameterIsNotOpaqueType(const TSourceLoc &line,
     832             :                                                      TQualifier qualifier,
     833             :                                                      const TType &type)
     834             : {
     835           0 :     checkOutParameterIsNotSampler(line, qualifier, type);
     836           0 :     checkOutParameterIsNotImage(line, qualifier, type);
     837           0 : }
     838             : 
     839           0 : void TParseContext::checkOutParameterIsNotSampler(const TSourceLoc &line,
     840             :                                                   TQualifier qualifier,
     841             :                                                   const TType &type)
     842             : {
     843           0 :     ASSERT(qualifier == EvqOut || qualifier == EvqInOut);
     844           0 :     if (IsSampler(type.getBasicType()))
     845             :     {
     846           0 :         error(line, "samplers cannot be output parameters", type.getBasicString());
     847             :     }
     848           0 : }
     849             : 
     850           0 : void TParseContext::checkOutParameterIsNotImage(const TSourceLoc &line,
     851             :                                                 TQualifier qualifier,
     852             :                                                 const TType &type)
     853             : {
     854           0 :     ASSERT(qualifier == EvqOut || qualifier == EvqInOut);
     855           0 :     if (IsImage(type.getBasicType()))
     856             :     {
     857           0 :         error(line, "images cannot be output parameters", type.getBasicString());
     858             :     }
     859           0 : }
     860             : 
     861             : // Do size checking for an array type's size.
     862           0 : unsigned int TParseContext::checkIsValidArraySize(const TSourceLoc &line, TIntermTyped *expr)
     863             : {
     864           0 :     TIntermConstantUnion *constant = expr->getAsConstantUnion();
     865             : 
     866             :     // TODO(oetuaho@nvidia.com): Get rid of the constant == nullptr check here once all constant
     867             :     // expressions can be folded. Right now we don't allow constant expressions that ANGLE can't
     868             :     // fold as array size.
     869           0 :     if (expr->getQualifier() != EvqConst || constant == nullptr || !constant->isScalarInt())
     870             :     {
     871           0 :         error(line, "array size must be a constant integer expression", "");
     872           0 :         return 1u;
     873             :     }
     874             : 
     875           0 :     unsigned int size = 0u;
     876             : 
     877           0 :     if (constant->getBasicType() == EbtUInt)
     878             :     {
     879           0 :         size = constant->getUConst(0);
     880             :     }
     881             :     else
     882             :     {
     883           0 :         int signedSize = constant->getIConst(0);
     884             : 
     885           0 :         if (signedSize < 0)
     886             :         {
     887           0 :             error(line, "array size must be non-negative", "");
     888           0 :             return 1u;
     889             :         }
     890             : 
     891           0 :         size = static_cast<unsigned int>(signedSize);
     892             :     }
     893             : 
     894           0 :     if (size == 0u)
     895             :     {
     896           0 :         error(line, "array size must be greater than zero", "");
     897           0 :         return 1u;
     898             :     }
     899             : 
     900             :     // The size of arrays is restricted here to prevent issues further down the
     901             :     // compiler/translator/driver stack. Shader Model 5 generation hardware is limited to
     902             :     // 4096 registers so this should be reasonable even for aggressively optimizable code.
     903           0 :     const unsigned int sizeLimit = 65536;
     904             : 
     905           0 :     if (size > sizeLimit)
     906             :     {
     907           0 :         error(line, "array size too large", "");
     908           0 :         return 1u;
     909             :     }
     910             : 
     911           0 :     return size;
     912             : }
     913             : 
     914             : // See if this qualifier can be an array.
     915           0 : bool TParseContext::checkIsValidQualifierForArray(const TSourceLoc &line,
     916             :                                                   const TPublicType &elementQualifier)
     917             : {
     918           0 :     if ((elementQualifier.qualifier == EvqAttribute) ||
     919           0 :         (elementQualifier.qualifier == EvqVertexIn) ||
     920           0 :         (elementQualifier.qualifier == EvqConst && mShaderVersion < 300))
     921             :     {
     922           0 :         error(line, "cannot declare arrays of this qualifier",
     923           0 :               TType(elementQualifier).getQualifierString());
     924           0 :         return false;
     925             :     }
     926             : 
     927           0 :     return true;
     928             : }
     929             : 
     930             : // See if this element type can be formed into an array.
     931           0 : bool TParseContext::checkIsValidTypeForArray(const TSourceLoc &line, const TPublicType &elementType)
     932             : {
     933             :     //
     934             :     // Can the type be an array?
     935             :     //
     936           0 :     if (elementType.array)
     937             :     {
     938           0 :         error(line, "cannot declare arrays of arrays",
     939           0 :               TType(elementType).getCompleteString().c_str());
     940           0 :         return false;
     941             :     }
     942             :     // In ESSL1.00 shaders, structs cannot be varying (section 4.3.5). This is checked elsewhere.
     943             :     // In ESSL3.00 shaders, struct inputs/outputs are allowed but not arrays of structs (section
     944             :     // 4.3.4).
     945           0 :     if (mShaderVersion >= 300 && elementType.getBasicType() == EbtStruct &&
     946           0 :         sh::IsVarying(elementType.qualifier))
     947             :     {
     948           0 :         error(line, "cannot declare arrays of structs of this qualifier",
     949           0 :               TType(elementType).getCompleteString().c_str());
     950           0 :         return false;
     951             :     }
     952             : 
     953           0 :     return true;
     954             : }
     955             : 
     956             : // Check if this qualified element type can be formed into an array.
     957           0 : bool TParseContext::checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation,
     958             :                                                          const TPublicType &elementType)
     959             : {
     960           0 :     if (checkIsValidTypeForArray(indexLocation, elementType))
     961             :     {
     962           0 :         return checkIsValidQualifierForArray(indexLocation, elementType);
     963             :     }
     964           0 :     return false;
     965             : }
     966             : 
     967             : // Enforce non-initializer type/qualifier rules.
     968           0 : void TParseContext::checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
     969             :                                                          const TString &identifier,
     970             :                                                          TPublicType *type)
     971             : {
     972           0 :     ASSERT(type != nullptr);
     973           0 :     if (type->qualifier == EvqConst)
     974             :     {
     975             :         // Make the qualifier make sense.
     976           0 :         type->qualifier = EvqTemporary;
     977             : 
     978             :         // Generate informative error messages for ESSL1.
     979             :         // In ESSL3 arrays and structures containing arrays can be constant.
     980           0 :         if (mShaderVersion < 300 && type->isStructureContainingArrays())
     981             :         {
     982           0 :             error(line,
     983             :                   "structures containing arrays may not be declared constant since they cannot be "
     984             :                   "initialized",
     985           0 :                   identifier.c_str());
     986             :         }
     987             :         else
     988             :         {
     989           0 :             error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
     990             :         }
     991           0 :         return;
     992             :     }
     993           0 :     if (type->isUnsizedArray())
     994             :     {
     995           0 :         error(line, "implicitly sized arrays need to be initialized", identifier.c_str());
     996             :     }
     997             : }
     998             : 
     999             : // Do some simple checks that are shared between all variable declarations,
    1000             : // and update the symbol table.
    1001             : //
    1002             : // Returns true if declaring the variable succeeded.
    1003             : //
    1004           0 : bool TParseContext::declareVariable(const TSourceLoc &line,
    1005             :                                     const TString &identifier,
    1006             :                                     const TType &type,
    1007             :                                     TVariable **variable)
    1008             : {
    1009           0 :     ASSERT((*variable) == nullptr);
    1010             : 
    1011           0 :     bool needsReservedCheck = true;
    1012             : 
    1013             :     // gl_LastFragData may be redeclared with a new precision qualifier
    1014           0 :     if (type.isArray() && identifier.compare(0, 15, "gl_LastFragData") == 0)
    1015             :     {
    1016             :         const TVariable *maxDrawBuffers = static_cast<const TVariable *>(
    1017           0 :             symbolTable.findBuiltIn("gl_MaxDrawBuffers", mShaderVersion));
    1018           0 :         if (static_cast<int>(type.getArraySize()) == maxDrawBuffers->getConstPointer()->getIConst())
    1019             :         {
    1020           0 :             if (TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion))
    1021             :             {
    1022           0 :                 needsReservedCheck = !checkCanUseExtension(line, builtInSymbol->getExtension());
    1023             :             }
    1024             :         }
    1025             :         else
    1026             :         {
    1027           0 :             error(line, "redeclaration of gl_LastFragData with size != gl_MaxDrawBuffers",
    1028           0 :                   identifier.c_str());
    1029           0 :             return false;
    1030             :         }
    1031             :     }
    1032             : 
    1033           0 :     if (needsReservedCheck && !checkIsNotReserved(line, identifier))
    1034           0 :         return false;
    1035             : 
    1036           0 :     (*variable) = new TVariable(&identifier, type);
    1037           0 :     if (!symbolTable.declare(*variable))
    1038             :     {
    1039           0 :         error(line, "redefinition", identifier.c_str());
    1040           0 :         *variable = nullptr;
    1041           0 :         return false;
    1042             :     }
    1043             : 
    1044           0 :     if (!checkIsNonVoid(line, identifier, type.getBasicType()))
    1045           0 :         return false;
    1046             : 
    1047           0 :     return true;
    1048             : }
    1049             : 
    1050           0 : void TParseContext::checkIsParameterQualifierValid(
    1051             :     const TSourceLoc &line,
    1052             :     const TTypeQualifierBuilder &typeQualifierBuilder,
    1053             :     TType *type)
    1054             : {
    1055           0 :     TTypeQualifier typeQualifier = typeQualifierBuilder.getParameterTypeQualifier(&mDiagnostics);
    1056             : 
    1057           0 :     if (typeQualifier.qualifier == EvqOut || typeQualifier.qualifier == EvqInOut)
    1058             :     {
    1059           0 :         checkOutParameterIsNotOpaqueType(line, typeQualifier.qualifier, *type);
    1060             :     }
    1061             : 
    1062           0 :     if (!IsImage(type->getBasicType()))
    1063             :     {
    1064           0 :         checkIsMemoryQualifierNotSpecified(typeQualifier.memoryQualifier, line);
    1065             :     }
    1066             :     else
    1067             :     {
    1068           0 :         type->setMemoryQualifier(typeQualifier.memoryQualifier);
    1069             :     }
    1070             : 
    1071           0 :     type->setQualifier(typeQualifier.qualifier);
    1072             : 
    1073           0 :     if (typeQualifier.precision != EbpUndefined)
    1074             :     {
    1075           0 :         type->setPrecision(typeQualifier.precision);
    1076             :     }
    1077           0 : }
    1078             : 
    1079           0 : bool TParseContext::checkCanUseExtension(const TSourceLoc &line, const TString &extension)
    1080             : {
    1081           0 :     const TExtensionBehavior &extBehavior   = extensionBehavior();
    1082           0 :     TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str());
    1083           0 :     if (iter == extBehavior.end())
    1084             :     {
    1085           0 :         error(line, "extension", extension.c_str(), "is not supported");
    1086           0 :         return false;
    1087             :     }
    1088             :     // In GLSL ES, an extension's default behavior is "disable".
    1089           0 :     if (iter->second == EBhDisable || iter->second == EBhUndefined)
    1090             :     {
    1091           0 :         error(line, "extension", extension.c_str(), "is disabled");
    1092           0 :         return false;
    1093             :     }
    1094           0 :     if (iter->second == EBhWarn)
    1095             :     {
    1096           0 :         warning(line, "extension", extension.c_str(), "is being used");
    1097           0 :         return true;
    1098             :     }
    1099             : 
    1100           0 :     return true;
    1101             : }
    1102             : 
    1103             : // These checks are common for all declarations starting a declarator list, and declarators that
    1104             : // follow an empty declaration.
    1105           0 : void TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType,
    1106             :                                                 const TSourceLoc &identifierLocation)
    1107             : {
    1108           0 :     switch (publicType.qualifier)
    1109             :     {
    1110             :         case EvqVaryingIn:
    1111             :         case EvqVaryingOut:
    1112             :         case EvqAttribute:
    1113             :         case EvqVertexIn:
    1114             :         case EvqFragmentOut:
    1115             :         case EvqComputeIn:
    1116           0 :             if (publicType.getBasicType() == EbtStruct)
    1117             :             {
    1118           0 :                 error(identifierLocation, "cannot be used with a structure",
    1119           0 :                       getQualifierString(publicType.qualifier));
    1120           0 :                 return;
    1121             :             }
    1122             : 
    1123             :         default:
    1124           0 :             break;
    1125             :     }
    1126             : 
    1127           0 :     if (publicType.qualifier != EvqUniform &&
    1128           0 :         !checkIsNotSampler(identifierLocation, publicType.typeSpecifierNonArray,
    1129             :                            "samplers must be uniform"))
    1130             :     {
    1131           0 :         return;
    1132             :     }
    1133           0 :     if (publicType.qualifier != EvqUniform &&
    1134           0 :         !checkIsNotImage(identifierLocation, publicType.typeSpecifierNonArray,
    1135             :                          "images must be uniform"))
    1136             :     {
    1137           0 :         return;
    1138             :     }
    1139             : 
    1140             :     // check for layout qualifier issues
    1141           0 :     const TLayoutQualifier layoutQualifier = publicType.layoutQualifier;
    1142             : 
    1143           0 :     if (layoutQualifier.matrixPacking != EmpUnspecified)
    1144             :     {
    1145           0 :         error(identifierLocation, "layout qualifier",
    1146           0 :               getMatrixPackingString(layoutQualifier.matrixPacking),
    1147           0 :               "only valid for interface blocks");
    1148           0 :         return;
    1149             :     }
    1150             : 
    1151           0 :     if (layoutQualifier.blockStorage != EbsUnspecified)
    1152             :     {
    1153           0 :         error(identifierLocation, "layout qualifier",
    1154           0 :               getBlockStorageString(layoutQualifier.blockStorage),
    1155           0 :               "only valid for interface blocks");
    1156           0 :         return;
    1157             :     }
    1158             : 
    1159           0 :     if (publicType.qualifier != EvqVertexIn && publicType.qualifier != EvqFragmentOut)
    1160             :     {
    1161           0 :         checkLocationIsNotSpecified(identifierLocation, publicType.layoutQualifier);
    1162             :     }
    1163             : 
    1164           0 :     if (IsImage(publicType.getBasicType()))
    1165             :     {
    1166             : 
    1167           0 :         switch (layoutQualifier.imageInternalFormat)
    1168             :         {
    1169             :             case EiifRGBA32F:
    1170             :             case EiifRGBA16F:
    1171             :             case EiifR32F:
    1172             :             case EiifRGBA8:
    1173             :             case EiifRGBA8_SNORM:
    1174           0 :                 if (!IsFloatImage(publicType.getBasicType()))
    1175             :                 {
    1176           0 :                     error(identifierLocation,
    1177             :                           "internal image format requires a floating image type",
    1178           0 :                           getBasicString(publicType.getBasicType()));
    1179           0 :                     return;
    1180             :                 }
    1181           0 :                 break;
    1182             :             case EiifRGBA32I:
    1183             :             case EiifRGBA16I:
    1184             :             case EiifRGBA8I:
    1185             :             case EiifR32I:
    1186           0 :                 if (!IsIntegerImage(publicType.getBasicType()))
    1187             :                 {
    1188           0 :                     error(identifierLocation,
    1189             :                           "internal image format requires an integer image type",
    1190           0 :                           getBasicString(publicType.getBasicType()));
    1191           0 :                     return;
    1192             :                 }
    1193           0 :                 break;
    1194             :             case EiifRGBA32UI:
    1195             :             case EiifRGBA16UI:
    1196             :             case EiifRGBA8UI:
    1197             :             case EiifR32UI:
    1198           0 :                 if (!IsUnsignedImage(publicType.getBasicType()))
    1199             :                 {
    1200           0 :                     error(identifierLocation,
    1201             :                           "internal image format requires an unsigned image type",
    1202           0 :                           getBasicString(publicType.getBasicType()));
    1203           0 :                     return;
    1204             :                 }
    1205           0 :                 break;
    1206             :             case EiifUnspecified:
    1207           0 :                 error(identifierLocation, "layout qualifier", "No image internal format specified");
    1208           0 :                 return;
    1209             :             default:
    1210           0 :                 error(identifierLocation, "layout qualifier", "unrecognized token");
    1211           0 :                 return;
    1212             :         }
    1213             : 
    1214             :         // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
    1215           0 :         switch (layoutQualifier.imageInternalFormat)
    1216             :         {
    1217             :             case EiifR32F:
    1218             :             case EiifR32I:
    1219             :             case EiifR32UI:
    1220           0 :                 break;
    1221             :             default:
    1222           0 :                 if (!publicType.memoryQualifier.readonly && !publicType.memoryQualifier.writeonly)
    1223             :                 {
    1224             :                     error(identifierLocation, "layout qualifier",
    1225             :                           "Except for images with the r32f, r32i and r32ui format qualifiers, "
    1226           0 :                           "image variables must be qualified readonly and/or writeonly");
    1227           0 :                     return;
    1228             :                 }
    1229           0 :                 break;
    1230             :         }
    1231             :     }
    1232             :     else
    1233             :     {
    1234             : 
    1235           0 :         if (!checkInternalFormatIsNotSpecified(identifierLocation,
    1236           0 :                                                layoutQualifier.imageInternalFormat))
    1237             :         {
    1238           0 :             return;
    1239             :         }
    1240             : 
    1241           0 :         if (!checkIsMemoryQualifierNotSpecified(publicType.memoryQualifier, identifierLocation))
    1242             :         {
    1243           0 :             return;
    1244             :         }
    1245             :     }
    1246             : }
    1247             : 
    1248           0 : void TParseContext::checkLayoutQualifierSupported(const TSourceLoc &location,
    1249             :                                                   const TString &layoutQualifierName,
    1250             :                                                   int versionRequired)
    1251             : {
    1252             : 
    1253           0 :     if (mShaderVersion < versionRequired)
    1254             :     {
    1255           0 :         error(location, "invalid layout qualifier:", layoutQualifierName.c_str(), "not supported");
    1256             :     }
    1257           0 : }
    1258             : 
    1259           0 : bool TParseContext::checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
    1260             :                                                      const TLayoutQualifier &layoutQualifier)
    1261             : {
    1262           0 :     const sh::WorkGroupSize &localSize = layoutQualifier.localSize;
    1263           0 :     for (size_t i = 0u; i < localSize.size(); ++i)
    1264             :     {
    1265           0 :         if (localSize[i] != -1)
    1266             :         {
    1267           0 :             error(location, "invalid layout qualifier:", getWorkGroupSizeString(i),
    1268           0 :                   "only valid when used with 'in' in a compute shader global layout declaration");
    1269           0 :             return false;
    1270             :         }
    1271             :     }
    1272             : 
    1273           0 :     return true;
    1274             : }
    1275             : 
    1276           0 : bool TParseContext::checkInternalFormatIsNotSpecified(const TSourceLoc &location,
    1277             :                                                       TLayoutImageInternalFormat internalFormat)
    1278             : {
    1279           0 :     if (internalFormat != EiifUnspecified)
    1280             :     {
    1281           0 :         error(location, "invalid layout qualifier:", getImageInternalFormatString(internalFormat),
    1282           0 :               "only valid when used with images");
    1283           0 :         return false;
    1284             :     }
    1285           0 :     return true;
    1286             : }
    1287             : 
    1288           0 : void TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate,
    1289             :                                                  TIntermAggregate *fnCall)
    1290             : {
    1291           0 :     for (size_t i = 0; i < fnCandidate->getParamCount(); ++i)
    1292             :     {
    1293           0 :         TQualifier qual = fnCandidate->getParam(i).type->getQualifier();
    1294           0 :         if (qual == EvqOut || qual == EvqInOut)
    1295             :         {
    1296           0 :             TIntermTyped *argument = (*(fnCall->getSequence()))[i]->getAsTyped();
    1297           0 :             if (!checkCanBeLValue(argument->getLine(), "assign", argument))
    1298             :             {
    1299           0 :                 error(argument->getLine(),
    1300           0 :                       "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
    1301           0 :                 return;
    1302             :             }
    1303             :         }
    1304             :     }
    1305             : }
    1306             : 
    1307           0 : void TParseContext::checkInvariantVariableQualifier(bool invariant,
    1308             :                                                     const TQualifier qualifier,
    1309             :                                                     const TSourceLoc &invariantLocation)
    1310             : {
    1311           0 :     if (!invariant)
    1312           0 :         return;
    1313             : 
    1314           0 :     if (mShaderVersion < 300)
    1315             :     {
    1316             :         // input variables in the fragment shader can be also qualified as invariant
    1317           0 :         if (!sh::CanBeInvariantESSL1(qualifier))
    1318             :         {
    1319           0 :             error(invariantLocation, "Cannot be qualified as invariant.", "invariant");
    1320             :         }
    1321             :     }
    1322             :     else
    1323             :     {
    1324           0 :         if (!sh::CanBeInvariantESSL3OrGreater(qualifier))
    1325             :         {
    1326           0 :             error(invariantLocation, "Cannot be qualified as invariant.", "invariant");
    1327             :         }
    1328             :     }
    1329             : }
    1330             : 
    1331           0 : bool TParseContext::supportsExtension(const char *extension)
    1332             : {
    1333           0 :     const TExtensionBehavior &extbehavior   = extensionBehavior();
    1334           0 :     TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
    1335           0 :     return (iter != extbehavior.end());
    1336             : }
    1337             : 
    1338           0 : bool TParseContext::isExtensionEnabled(const char *extension) const
    1339             : {
    1340           0 :     return ::IsExtensionEnabled(extensionBehavior(), extension);
    1341             : }
    1342             : 
    1343           0 : void TParseContext::handleExtensionDirective(const TSourceLoc &loc,
    1344             :                                              const char *extName,
    1345             :                                              const char *behavior)
    1346             : {
    1347           0 :     pp::SourceLocation srcLoc;
    1348           0 :     srcLoc.file = loc.first_file;
    1349           0 :     srcLoc.line = loc.first_line;
    1350           0 :     mDirectiveHandler.handleExtension(srcLoc, extName, behavior);
    1351           0 : }
    1352             : 
    1353           0 : void TParseContext::handlePragmaDirective(const TSourceLoc &loc,
    1354             :                                           const char *name,
    1355             :                                           const char *value,
    1356             :                                           bool stdgl)
    1357             : {
    1358           0 :     pp::SourceLocation srcLoc;
    1359           0 :     srcLoc.file = loc.first_file;
    1360           0 :     srcLoc.line = loc.first_line;
    1361           0 :     mDirectiveHandler.handlePragma(srcLoc, name, value, stdgl);
    1362           0 : }
    1363             : 
    1364           0 : sh::WorkGroupSize TParseContext::getComputeShaderLocalSize() const
    1365             : {
    1366             :     sh::WorkGroupSize result;
    1367           0 :     for (size_t i = 0u; i < result.size(); ++i)
    1368             :     {
    1369           0 :         if (mComputeShaderLocalSizeDeclared && mComputeShaderLocalSize[i] == -1)
    1370             :         {
    1371           0 :             result[i] = 1;
    1372             :         }
    1373             :         else
    1374             :         {
    1375           0 :             result[i] = mComputeShaderLocalSize[i];
    1376             :         }
    1377             :     }
    1378           0 :     return result;
    1379             : }
    1380             : 
    1381             : /////////////////////////////////////////////////////////////////////////////////
    1382             : //
    1383             : // Non-Errors.
    1384             : //
    1385             : /////////////////////////////////////////////////////////////////////////////////
    1386             : 
    1387           0 : const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location,
    1388             :                                                  const TString *name,
    1389             :                                                  const TSymbol *symbol)
    1390             : {
    1391           0 :     const TVariable *variable = NULL;
    1392             : 
    1393           0 :     if (!symbol)
    1394             :     {
    1395           0 :         error(location, "undeclared identifier", name->c_str());
    1396             :     }
    1397           0 :     else if (!symbol->isVariable())
    1398             :     {
    1399           0 :         error(location, "variable expected", name->c_str());
    1400             :     }
    1401             :     else
    1402             :     {
    1403           0 :         variable = static_cast<const TVariable *>(symbol);
    1404             : 
    1405           0 :         if (symbolTable.findBuiltIn(variable->getName(), mShaderVersion) &&
    1406           0 :             !variable->getExtension().empty())
    1407             :         {
    1408           0 :             checkCanUseExtension(location, variable->getExtension());
    1409             :         }
    1410             : 
    1411             :         // Reject shaders using both gl_FragData and gl_FragColor
    1412           0 :         TQualifier qualifier = variable->getType().getQualifier();
    1413           0 :         if (qualifier == EvqFragData || qualifier == EvqSecondaryFragDataEXT)
    1414             :         {
    1415           0 :             mUsesFragData = true;
    1416             :         }
    1417           0 :         else if (qualifier == EvqFragColor || qualifier == EvqSecondaryFragColorEXT)
    1418             :         {
    1419           0 :             mUsesFragColor = true;
    1420             :         }
    1421           0 :         if (qualifier == EvqSecondaryFragDataEXT || qualifier == EvqSecondaryFragColorEXT)
    1422             :         {
    1423           0 :             mUsesSecondaryOutputs = true;
    1424             :         }
    1425             : 
    1426             :         // This validation is not quite correct - it's only an error to write to
    1427             :         // both FragData and FragColor. For simplicity, and because users shouldn't
    1428             :         // be rewarded for reading from undefined varaibles, return an error
    1429             :         // if they are both referenced, rather than assigned.
    1430           0 :         if (mUsesFragData && mUsesFragColor)
    1431             :         {
    1432           0 :             const char *errorMessage = "cannot use both gl_FragData and gl_FragColor";
    1433           0 :             if (mUsesSecondaryOutputs)
    1434             :             {
    1435           0 :                 errorMessage =
    1436             :                     "cannot use both output variable sets (gl_FragData, gl_SecondaryFragDataEXT)"
    1437             :                     " and (gl_FragColor, gl_SecondaryFragColorEXT)";
    1438             :             }
    1439           0 :             error(location, errorMessage, name->c_str());
    1440             :         }
    1441             : 
    1442             :         // GLSL ES 3.1 Revision 4, 7.1.3 Compute Shader Special Variables
    1443           0 :         if (getShaderType() == GL_COMPUTE_SHADER && !mComputeShaderLocalSizeDeclared &&
    1444             :             qualifier == EvqWorkGroupSize)
    1445             :         {
    1446             :             error(location,
    1447             :                   "It is an error to use gl_WorkGroupSize before declaring the local group size",
    1448           0 :                   "gl_WorkGroupSize");
    1449             :         }
    1450             :     }
    1451             : 
    1452           0 :     if (!variable)
    1453             :     {
    1454           0 :         TType type(EbtFloat, EbpUndefined);
    1455           0 :         TVariable *fakeVariable = new TVariable(name, type);
    1456           0 :         symbolTable.declare(fakeVariable);
    1457           0 :         variable = fakeVariable;
    1458             :     }
    1459             : 
    1460           0 :     return variable;
    1461             : }
    1462             : 
    1463           0 : TIntermTyped *TParseContext::parseVariableIdentifier(const TSourceLoc &location,
    1464             :                                                      const TString *name,
    1465             :                                                      const TSymbol *symbol)
    1466             : {
    1467           0 :     const TVariable *variable = getNamedVariable(location, name, symbol);
    1468             : 
    1469           0 :     if (variable->getConstPointer())
    1470             :     {
    1471           0 :         const TConstantUnion *constArray = variable->getConstPointer();
    1472           0 :         return intermediate.addConstantUnion(constArray, variable->getType(), location);
    1473             :     }
    1474           0 :     else if (variable->getType().getQualifier() == EvqWorkGroupSize &&
    1475           0 :              mComputeShaderLocalSizeDeclared)
    1476             :     {
    1477             :         // gl_WorkGroupSize can be used to size arrays according to the ESSL 3.10.4 spec, so it
    1478             :         // needs to be added to the AST as a constant and not as a symbol.
    1479           0 :         sh::WorkGroupSize workGroupSize = getComputeShaderLocalSize();
    1480           0 :         TConstantUnion *constArray      = new TConstantUnion[3];
    1481           0 :         for (size_t i = 0; i < 3; ++i)
    1482             :         {
    1483           0 :             constArray[i].setUConst(static_cast<unsigned int>(workGroupSize[i]));
    1484             :         }
    1485             : 
    1486           0 :         ASSERT(variable->getType().getBasicType() == EbtUInt);
    1487           0 :         ASSERT(variable->getType().getObjectSize() == 3);
    1488             : 
    1489           0 :         TType type(variable->getType());
    1490           0 :         type.setQualifier(EvqConst);
    1491           0 :         return intermediate.addConstantUnion(constArray, type, location);
    1492             :     }
    1493             :     else
    1494             :     {
    1495           0 :         return intermediate.addSymbol(variable->getUniqueId(), variable->getName(),
    1496           0 :                                       variable->getType(), location);
    1497             :     }
    1498             : }
    1499             : 
    1500             : //
    1501             : // Look up a function name in the symbol table, and make sure it is a function.
    1502             : //
    1503             : // Return the function symbol if found, otherwise 0.
    1504             : //
    1505           0 : const TFunction *TParseContext::findFunction(const TSourceLoc &line,
    1506             :                                              TFunction *call,
    1507             :                                              int inputShaderVersion,
    1508             :                                              bool *builtIn)
    1509             : {
    1510             :     // First find by unmangled name to check whether the function name has been
    1511             :     // hidden by a variable name or struct typename.
    1512             :     // If a function is found, check for one with a matching argument list.
    1513           0 :     const TSymbol *symbol = symbolTable.find(call->getName(), inputShaderVersion, builtIn);
    1514           0 :     if (symbol == 0 || symbol->isFunction())
    1515             :     {
    1516           0 :         symbol = symbolTable.find(call->getMangledName(), inputShaderVersion, builtIn);
    1517             :     }
    1518             : 
    1519           0 :     if (symbol == 0)
    1520             :     {
    1521           0 :         error(line, "no matching overloaded function found", call->getName().c_str());
    1522           0 :         return 0;
    1523             :     }
    1524             : 
    1525           0 :     if (!symbol->isFunction())
    1526             :     {
    1527           0 :         error(line, "function name expected", call->getName().c_str());
    1528           0 :         return 0;
    1529             :     }
    1530             : 
    1531           0 :     return static_cast<const TFunction *>(symbol);
    1532             : }
    1533             : 
    1534             : //
    1535             : // Initializers show up in several places in the grammar.  Have one set of
    1536             : // code to handle them here.
    1537             : //
    1538             : // Returns true on error, false if no error
    1539             : //
    1540           0 : bool TParseContext::executeInitializer(const TSourceLoc &line,
    1541             :                                        const TString &identifier,
    1542             :                                        const TPublicType &pType,
    1543             :                                        TIntermTyped *initializer,
    1544             :                                        TIntermBinary **initNode)
    1545             : {
    1546           0 :     ASSERT(initNode != nullptr);
    1547           0 :     ASSERT(*initNode == nullptr);
    1548           0 :     TType type = TType(pType);
    1549             : 
    1550           0 :     TVariable *variable = nullptr;
    1551           0 :     if (type.isUnsizedArray())
    1552             :     {
    1553             :         // We have not checked yet whether the initializer actually is an array or not.
    1554           0 :         if (initializer->isArray())
    1555             :         {
    1556           0 :             type.setArraySize(initializer->getArraySize());
    1557             :         }
    1558             :         else
    1559             :         {
    1560             :             // Having a non-array initializer for an unsized array will result in an error later,
    1561             :             // so we don't generate an error message here.
    1562           0 :             type.setArraySize(1u);
    1563             :         }
    1564             :     }
    1565           0 :     if (!declareVariable(line, identifier, type, &variable))
    1566             :     {
    1567           0 :         return true;
    1568             :     }
    1569             : 
    1570           0 :     bool globalInitWarning = false;
    1571           0 :     if (symbolTable.atGlobalLevel() &&
    1572           0 :         !ValidateGlobalInitializer(initializer, this, &globalInitWarning))
    1573             :     {
    1574             :         // Error message does not completely match behavior with ESSL 1.00, but
    1575             :         // we want to steer developers towards only using constant expressions.
    1576           0 :         error(line, "global variable initializers must be constant expressions", "=");
    1577           0 :         return true;
    1578             :     }
    1579           0 :     if (globalInitWarning)
    1580             :     {
    1581             :         warning(
    1582             :             line,
    1583             :             "global variable initializers should be constant expressions "
    1584             :             "(uniforms and globals are allowed in global initializers for legacy compatibility)",
    1585           0 :             "=");
    1586             :     }
    1587             : 
    1588             :     //
    1589             :     // identifier must be of type constant, a global, or a temporary
    1590             :     //
    1591           0 :     TQualifier qualifier = variable->getType().getQualifier();
    1592           0 :     if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst))
    1593             :     {
    1594           0 :         error(line, " cannot initialize this type of qualifier ",
    1595           0 :               variable->getType().getQualifierString());
    1596           0 :         return true;
    1597             :     }
    1598             :     //
    1599             :     // test for and propagate constant
    1600             :     //
    1601             : 
    1602           0 :     if (qualifier == EvqConst)
    1603             :     {
    1604           0 :         if (qualifier != initializer->getType().getQualifier())
    1605             :         {
    1606           0 :             std::stringstream extraInfoStream;
    1607           0 :             extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
    1608           0 :             std::string extraInfo = extraInfoStream.str();
    1609           0 :             error(line, " assigning non-constant to", "=", extraInfo.c_str());
    1610           0 :             variable->getType().setQualifier(EvqTemporary);
    1611           0 :             return true;
    1612             :         }
    1613           0 :         if (type != initializer->getType())
    1614             :         {
    1615           0 :             error(line, " non-matching types for const initializer ",
    1616           0 :                   variable->getType().getQualifierString());
    1617           0 :             variable->getType().setQualifier(EvqTemporary);
    1618           0 :             return true;
    1619             :         }
    1620             : 
    1621             :         // Save the constant folded value to the variable if possible. For example array
    1622             :         // initializers are not folded, since that way copying the array literal to multiple places
    1623             :         // in the shader is avoided.
    1624             :         // TODO(oetuaho@nvidia.com): Consider constant folding array initialization in cases where
    1625             :         // it would be beneficial.
    1626           0 :         if (initializer->getAsConstantUnion())
    1627             :         {
    1628           0 :             variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
    1629           0 :             *initNode = nullptr;
    1630           0 :             return false;
    1631             :         }
    1632           0 :         else if (initializer->getAsSymbolNode())
    1633             :         {
    1634             :             const TSymbol *symbol =
    1635           0 :                 symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), 0);
    1636           0 :             const TVariable *tVar = static_cast<const TVariable *>(symbol);
    1637             : 
    1638           0 :             const TConstantUnion *constArray = tVar->getConstPointer();
    1639           0 :             if (constArray)
    1640             :             {
    1641           0 :                 variable->shareConstPointer(constArray);
    1642           0 :                 *initNode = nullptr;
    1643           0 :                 return false;
    1644             :             }
    1645             :         }
    1646             :     }
    1647             : 
    1648           0 :     TIntermSymbol *intermSymbol = intermediate.addSymbol(
    1649           0 :         variable->getUniqueId(), variable->getName(), variable->getType(), line);
    1650           0 :     *initNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
    1651           0 :     if (*initNode == nullptr)
    1652             :     {
    1653           0 :         assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
    1654           0 :         return true;
    1655             :     }
    1656             : 
    1657           0 :     return false;
    1658             : }
    1659             : 
    1660           0 : void TParseContext::addFullySpecifiedType(TPublicType *typeSpecifier)
    1661             : {
    1662           0 :     checkPrecisionSpecified(typeSpecifier->getLine(), typeSpecifier->precision,
    1663           0 :                             typeSpecifier->getBasicType());
    1664             : 
    1665           0 :     if (mShaderVersion < 300 && typeSpecifier->array)
    1666             :     {
    1667           0 :         error(typeSpecifier->getLine(), "not supported", "first-class array");
    1668           0 :         typeSpecifier->clearArrayness();
    1669             :     }
    1670           0 : }
    1671             : 
    1672           0 : TPublicType TParseContext::addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
    1673             :                                                  const TPublicType &typeSpecifier)
    1674             : {
    1675           0 :     TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics);
    1676             : 
    1677           0 :     TPublicType returnType     = typeSpecifier;
    1678           0 :     returnType.qualifier       = typeQualifier.qualifier;
    1679           0 :     returnType.invariant       = typeQualifier.invariant;
    1680           0 :     returnType.layoutQualifier = typeQualifier.layoutQualifier;
    1681           0 :     returnType.memoryQualifier = typeQualifier.memoryQualifier;
    1682           0 :     returnType.precision       = typeSpecifier.precision;
    1683             : 
    1684           0 :     if (typeQualifier.precision != EbpUndefined)
    1685             :     {
    1686           0 :         returnType.precision = typeQualifier.precision;
    1687             :     }
    1688             : 
    1689           0 :     checkPrecisionSpecified(typeSpecifier.getLine(), returnType.precision,
    1690           0 :                             typeSpecifier.getBasicType());
    1691             : 
    1692           0 :     checkInvariantVariableQualifier(returnType.invariant, returnType.qualifier,
    1693           0 :                                     typeSpecifier.getLine());
    1694             : 
    1695           0 :     checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), returnType.layoutQualifier);
    1696             : 
    1697           0 :     if (mShaderVersion < 300)
    1698             :     {
    1699           0 :         if (typeSpecifier.array)
    1700             :         {
    1701           0 :             error(typeSpecifier.getLine(), "not supported", "first-class array");
    1702           0 :             returnType.clearArrayness();
    1703             :         }
    1704             : 
    1705           0 :         if (returnType.qualifier == EvqAttribute &&
    1706           0 :             (typeSpecifier.getBasicType() == EbtBool || typeSpecifier.getBasicType() == EbtInt))
    1707             :         {
    1708           0 :             error(typeSpecifier.getLine(), "cannot be bool or int",
    1709           0 :                   getQualifierString(returnType.qualifier));
    1710             :         }
    1711             : 
    1712           0 :         if ((returnType.qualifier == EvqVaryingIn || returnType.qualifier == EvqVaryingOut) &&
    1713           0 :             (typeSpecifier.getBasicType() == EbtBool || typeSpecifier.getBasicType() == EbtInt))
    1714             :         {
    1715           0 :             error(typeSpecifier.getLine(), "cannot be bool or int",
    1716           0 :                   getQualifierString(returnType.qualifier));
    1717             :         }
    1718             :     }
    1719             :     else
    1720             :     {
    1721           0 :         if (!returnType.layoutQualifier.isEmpty())
    1722             :         {
    1723           0 :             checkIsAtGlobalLevel(typeSpecifier.getLine(), "layout");
    1724             :         }
    1725           0 :         if (sh::IsVarying(returnType.qualifier) || returnType.qualifier == EvqVertexIn ||
    1726           0 :             returnType.qualifier == EvqFragmentOut)
    1727             :         {
    1728           0 :             checkInputOutputTypeIsValidES3(returnType.qualifier, typeSpecifier,
    1729           0 :                                            typeSpecifier.getLine());
    1730             :         }
    1731           0 :         if (returnType.qualifier == EvqComputeIn)
    1732             :         {
    1733           0 :             error(typeSpecifier.getLine(), "'in' can be only used to specify the local group size",
    1734           0 :                   "in");
    1735             :         }
    1736             :     }
    1737             : 
    1738           0 :     return returnType;
    1739             : }
    1740             : 
    1741           0 : void TParseContext::checkInputOutputTypeIsValidES3(const TQualifier qualifier,
    1742             :                                                    const TPublicType &type,
    1743             :                                                    const TSourceLoc &qualifierLocation)
    1744             : {
    1745             :     // An input/output variable can never be bool or a sampler. Samplers are checked elsewhere.
    1746           0 :     if (type.getBasicType() == EbtBool)
    1747             :     {
    1748           0 :         error(qualifierLocation, "cannot be bool", getQualifierString(qualifier));
    1749             :     }
    1750             : 
    1751             :     // Specific restrictions apply for vertex shader inputs and fragment shader outputs.
    1752           0 :     switch (qualifier)
    1753             :     {
    1754             :         case EvqVertexIn:
    1755             :             // ESSL 3.00 section 4.3.4
    1756           0 :             if (type.array)
    1757             :             {
    1758           0 :                 error(qualifierLocation, "cannot be array", getQualifierString(qualifier));
    1759             :             }
    1760             :             // Vertex inputs with a struct type are disallowed in singleDeclarationErrorCheck
    1761           0 :             return;
    1762             :         case EvqFragmentOut:
    1763             :             // ESSL 3.00 section 4.3.6
    1764           0 :             if (type.typeSpecifierNonArray.isMatrix())
    1765             :             {
    1766           0 :                 error(qualifierLocation, "cannot be matrix", getQualifierString(qualifier));
    1767             :             }
    1768             :             // Fragment outputs with a struct type are disallowed in singleDeclarationErrorCheck
    1769           0 :             return;
    1770             :         default:
    1771           0 :             break;
    1772             :     }
    1773             : 
    1774             :     // Vertex shader outputs / fragment shader inputs have a different, slightly more lenient set of
    1775             :     // restrictions.
    1776             :     bool typeContainsIntegers =
    1777           0 :         (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt ||
    1778           0 :          type.isStructureContainingType(EbtInt) || type.isStructureContainingType(EbtUInt));
    1779           0 :     if (typeContainsIntegers && qualifier != EvqFlatIn && qualifier != EvqFlatOut)
    1780             :     {
    1781           0 :         error(qualifierLocation, "must use 'flat' interpolation here",
    1782           0 :               getQualifierString(qualifier));
    1783             :     }
    1784             : 
    1785           0 :     if (type.getBasicType() == EbtStruct)
    1786             :     {
    1787             :         // ESSL 3.00 sections 4.3.4 and 4.3.6.
    1788             :         // These restrictions are only implied by the ESSL 3.00 spec, but
    1789             :         // the ESSL 3.10 spec lists these restrictions explicitly.
    1790           0 :         if (type.array)
    1791             :         {
    1792           0 :             error(qualifierLocation, "cannot be an array of structures",
    1793           0 :                   getQualifierString(qualifier));
    1794             :         }
    1795           0 :         if (type.isStructureContainingArrays())
    1796             :         {
    1797           0 :             error(qualifierLocation, "cannot be a structure containing an array",
    1798           0 :                   getQualifierString(qualifier));
    1799             :         }
    1800           0 :         if (type.isStructureContainingType(EbtStruct))
    1801             :         {
    1802           0 :             error(qualifierLocation, "cannot be a structure containing a structure",
    1803           0 :                   getQualifierString(qualifier));
    1804             :         }
    1805           0 :         if (type.isStructureContainingType(EbtBool))
    1806             :         {
    1807           0 :             error(qualifierLocation, "cannot be a structure containing a bool",
    1808           0 :                   getQualifierString(qualifier));
    1809             :         }
    1810             :     }
    1811             : }
    1812             : 
    1813           0 : void TParseContext::checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier)
    1814             : {
    1815           0 :     if (qualifier.getType() == QtStorage)
    1816             :     {
    1817             :         const TStorageQualifierWrapper &storageQualifier =
    1818           0 :             static_cast<const TStorageQualifierWrapper &>(qualifier);
    1819           0 :         if (!declaringFunction() && storageQualifier.getQualifier() != EvqConst &&
    1820           0 :             !symbolTable.atGlobalLevel())
    1821             :         {
    1822           0 :             error(storageQualifier.getLine(),
    1823             :                   "Local variables can only use the const storage qualifier.",
    1824           0 :                   storageQualifier.getQualifierString().c_str());
    1825             :         }
    1826             :     }
    1827           0 : }
    1828             : 
    1829           0 : bool TParseContext::checkIsMemoryQualifierNotSpecified(const TMemoryQualifier &memoryQualifier,
    1830             :                                                        const TSourceLoc &location)
    1831             : {
    1832           0 :     if (memoryQualifier.readonly)
    1833             :     {
    1834           0 :         error(location, "Only allowed with images.", "readonly");
    1835           0 :         return false;
    1836             :     }
    1837           0 :     if (memoryQualifier.writeonly)
    1838             :     {
    1839           0 :         error(location, "Only allowed with images.", "writeonly");
    1840           0 :         return false;
    1841             :     }
    1842           0 :     if (memoryQualifier.coherent)
    1843             :     {
    1844           0 :         error(location, "Only allowed with images.", "coherent");
    1845           0 :         return false;
    1846             :     }
    1847           0 :     if (memoryQualifier.restrictQualifier)
    1848             :     {
    1849           0 :         error(location, "Only allowed with images.", "restrict");
    1850           0 :         return false;
    1851             :     }
    1852           0 :     if (memoryQualifier.volatileQualifier)
    1853             :     {
    1854           0 :         error(location, "Only allowed with images.", "volatile");
    1855           0 :         return false;
    1856             :     }
    1857           0 :     return true;
    1858             : }
    1859             : 
    1860           0 : TIntermDeclaration *TParseContext::parseSingleDeclaration(
    1861             :     TPublicType &publicType,
    1862             :     const TSourceLoc &identifierOrTypeLocation,
    1863             :     const TString &identifier)
    1864             : {
    1865           0 :     TType type(publicType);
    1866           0 :     if ((mCompileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL) &&
    1867           0 :         mDirectiveHandler.pragma().stdgl.invariantAll)
    1868             :     {
    1869           0 :         TQualifier qualifier = type.getQualifier();
    1870             : 
    1871             :         // The directive handler has already taken care of rejecting invalid uses of this pragma
    1872             :         // (for example, in ESSL 3.00 fragment shaders), so at this point, flatten it into all
    1873             :         // affected variable declarations:
    1874             :         //
    1875             :         // 1. Built-in special variables which are inputs to the fragment shader. (These are handled
    1876             :         // elsewhere, in TranslatorGLSL.)
    1877             :         //
    1878             :         // 2. Outputs from vertex shaders in ESSL 1.00 and 3.00 (EvqVaryingOut and EvqVertexOut). It
    1879             :         // is actually less likely that there will be bugs in the handling of ESSL 3.00 shaders, but
    1880             :         // the way this is currently implemented we have to enable this compiler option before
    1881             :         // parsing the shader and determining the shading language version it uses. If this were
    1882             :         // implemented as a post-pass, the workaround could be more targeted.
    1883             :         //
    1884             :         // 3. Inputs in ESSL 1.00 fragment shaders (EvqVaryingIn). This is somewhat in violation of
    1885             :         // the specification, but there are desktop OpenGL drivers that expect that this is the
    1886             :         // behavior of the #pragma when specified in ESSL 1.00 fragment shaders.
    1887           0 :         if (qualifier == EvqVaryingOut || qualifier == EvqVertexOut || qualifier == EvqVaryingIn)
    1888             :         {
    1889           0 :             type.setInvariant(true);
    1890             :         }
    1891             :     }
    1892             : 
    1893           0 :     TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, type, identifierOrTypeLocation);
    1894             : 
    1895           0 :     bool emptyDeclaration = (identifier == "");
    1896             : 
    1897           0 :     mDeferredSingleDeclarationErrorCheck = emptyDeclaration;
    1898             : 
    1899           0 :     TIntermDeclaration *declaration = new TIntermDeclaration();
    1900           0 :     declaration->setLine(identifierOrTypeLocation);
    1901             : 
    1902           0 :     if (emptyDeclaration)
    1903             :     {
    1904           0 :         if (publicType.isUnsizedArray())
    1905             :         {
    1906             :             // ESSL3 spec section 4.1.9: Array declaration which leaves the size unspecified is an
    1907             :             // error. It is assumed that this applies to empty declarations as well.
    1908           0 :             error(identifierOrTypeLocation, "empty array declaration needs to specify a size",
    1909           0 :                   identifier.c_str());
    1910             :         }
    1911             :     }
    1912             :     else
    1913             :     {
    1914           0 :         singleDeclarationErrorCheck(publicType, identifierOrTypeLocation);
    1915             : 
    1916           0 :         checkCanBeDeclaredWithoutInitializer(identifierOrTypeLocation, identifier, &publicType);
    1917             : 
    1918           0 :         TVariable *variable = nullptr;
    1919           0 :         declareVariable(identifierOrTypeLocation, identifier, type, &variable);
    1920             : 
    1921           0 :         if (variable && symbol)
    1922             :         {
    1923           0 :             symbol->setId(variable->getUniqueId());
    1924             :         }
    1925             :     }
    1926             : 
    1927             :     // We append the symbol even if the declaration is empty, mainly because of struct declarations
    1928             :     // that may just declare a type.
    1929           0 :     declaration->appendDeclarator(symbol);
    1930             : 
    1931           0 :     return declaration;
    1932             : }
    1933             : 
    1934           0 : TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(TPublicType &publicType,
    1935             :                                                                const TSourceLoc &identifierLocation,
    1936             :                                                                const TString &identifier,
    1937             :                                                                const TSourceLoc &indexLocation,
    1938             :                                                                TIntermTyped *indexExpression)
    1939             : {
    1940           0 :     mDeferredSingleDeclarationErrorCheck = false;
    1941             : 
    1942           0 :     singleDeclarationErrorCheck(publicType, identifierLocation);
    1943             : 
    1944           0 :     checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &publicType);
    1945             : 
    1946           0 :     checkIsValidTypeAndQualifierForArray(indexLocation, publicType);
    1947             : 
    1948           0 :     TType arrayType(publicType);
    1949             : 
    1950           0 :     unsigned int size = checkIsValidArraySize(identifierLocation, indexExpression);
    1951             :     // Make the type an array even if size check failed.
    1952             :     // This ensures useless error messages regarding the variable's non-arrayness won't follow.
    1953           0 :     arrayType.setArraySize(size);
    1954             : 
    1955           0 :     TVariable *variable = nullptr;
    1956           0 :     declareVariable(identifierLocation, identifier, arrayType, &variable);
    1957             : 
    1958           0 :     TIntermDeclaration *declaration = new TIntermDeclaration();
    1959           0 :     declaration->setLine(identifierLocation);
    1960             : 
    1961           0 :     TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation);
    1962           0 :     if (variable && symbol)
    1963             :     {
    1964           0 :         symbol->setId(variable->getUniqueId());
    1965           0 :         declaration->appendDeclarator(symbol);
    1966             :     }
    1967             : 
    1968           0 :     return declaration;
    1969             : }
    1970             : 
    1971           0 : TIntermDeclaration *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType,
    1972             :                                                               const TSourceLoc &identifierLocation,
    1973             :                                                               const TString &identifier,
    1974             :                                                               const TSourceLoc &initLocation,
    1975             :                                                               TIntermTyped *initializer)
    1976             : {
    1977           0 :     mDeferredSingleDeclarationErrorCheck = false;
    1978             : 
    1979           0 :     singleDeclarationErrorCheck(publicType, identifierLocation);
    1980             : 
    1981           0 :     TIntermDeclaration *declaration = new TIntermDeclaration();
    1982           0 :     declaration->setLine(identifierLocation);
    1983             : 
    1984           0 :     TIntermBinary *initNode = nullptr;
    1985           0 :     if (!executeInitializer(identifierLocation, identifier, publicType, initializer, &initNode))
    1986             :     {
    1987           0 :         if (initNode)
    1988             :         {
    1989           0 :             declaration->appendDeclarator(initNode);
    1990             :         }
    1991             :     }
    1992           0 :     return declaration;
    1993             : }
    1994             : 
    1995           0 : TIntermDeclaration *TParseContext::parseSingleArrayInitDeclaration(
    1996             :     TPublicType &publicType,
    1997             :     const TSourceLoc &identifierLocation,
    1998             :     const TString &identifier,
    1999             :     const TSourceLoc &indexLocation,
    2000             :     TIntermTyped *indexExpression,
    2001             :     const TSourceLoc &initLocation,
    2002             :     TIntermTyped *initializer)
    2003             : {
    2004           0 :     mDeferredSingleDeclarationErrorCheck = false;
    2005             : 
    2006           0 :     singleDeclarationErrorCheck(publicType, identifierLocation);
    2007             : 
    2008           0 :     checkIsValidTypeAndQualifierForArray(indexLocation, publicType);
    2009             : 
    2010           0 :     TPublicType arrayType(publicType);
    2011             : 
    2012           0 :     unsigned int size = 0u;
    2013             :     // If indexExpression is nullptr, then the array will eventually get its size implicitly from
    2014             :     // the initializer.
    2015           0 :     if (indexExpression != nullptr)
    2016             :     {
    2017           0 :         size = checkIsValidArraySize(identifierLocation, indexExpression);
    2018             :     }
    2019             :     // Make the type an array even if size check failed.
    2020             :     // This ensures useless error messages regarding the variable's non-arrayness won't follow.
    2021           0 :     arrayType.setArraySize(size);
    2022             : 
    2023           0 :     TIntermDeclaration *declaration = new TIntermDeclaration();
    2024           0 :     declaration->setLine(identifierLocation);
    2025             : 
    2026             :     // initNode will correspond to the whole of "type b[n] = initializer".
    2027           0 :     TIntermBinary *initNode = nullptr;
    2028           0 :     if (!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
    2029             :     {
    2030           0 :         if (initNode)
    2031             :         {
    2032           0 :             declaration->appendDeclarator(initNode);
    2033             :         }
    2034             :     }
    2035             : 
    2036           0 :     return declaration;
    2037             : }
    2038             : 
    2039           0 : TIntermAggregate *TParseContext::parseInvariantDeclaration(
    2040             :     const TTypeQualifierBuilder &typeQualifierBuilder,
    2041             :     const TSourceLoc &identifierLoc,
    2042             :     const TString *identifier,
    2043             :     const TSymbol *symbol)
    2044             : {
    2045           0 :     TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics);
    2046             : 
    2047           0 :     if (!typeQualifier.invariant)
    2048             :     {
    2049           0 :         error(identifierLoc, "Expected invariant", identifier->c_str());
    2050           0 :         return nullptr;
    2051             :     }
    2052           0 :     if (!checkIsAtGlobalLevel(identifierLoc, "invariant varying"))
    2053             :     {
    2054           0 :         return nullptr;
    2055             :     }
    2056           0 :     if (!symbol)
    2057             :     {
    2058           0 :         error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str());
    2059           0 :         return nullptr;
    2060             :     }
    2061           0 :     if (!IsQualifierUnspecified(typeQualifier.qualifier))
    2062             :     {
    2063           0 :         error(identifierLoc, "invariant declaration specifies qualifier",
    2064           0 :               getQualifierString(typeQualifier.qualifier));
    2065             :     }
    2066           0 :     if (typeQualifier.precision != EbpUndefined)
    2067             :     {
    2068           0 :         error(identifierLoc, "invariant declaration specifies precision",
    2069           0 :               getPrecisionString(typeQualifier.precision));
    2070             :     }
    2071           0 :     if (!typeQualifier.layoutQualifier.isEmpty())
    2072             :     {
    2073           0 :         error(identifierLoc, "invariant declaration specifies layout", "'layout'");
    2074             :     }
    2075             : 
    2076           0 :     const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
    2077           0 :     ASSERT(variable);
    2078           0 :     const TType &type = variable->getType();
    2079             : 
    2080           0 :     checkInvariantVariableQualifier(typeQualifier.invariant, type.getQualifier(),
    2081           0 :                                     typeQualifier.line);
    2082           0 :     checkIsMemoryQualifierNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
    2083             : 
    2084           0 :     symbolTable.addInvariantVarying(std::string(identifier->c_str()));
    2085             : 
    2086             :     TIntermSymbol *intermSymbol =
    2087           0 :         intermediate.addSymbol(variable->getUniqueId(), *identifier, type, identifierLoc);
    2088             : 
    2089           0 :     TIntermAggregate *aggregate = TIntermediate::MakeAggregate(intermSymbol, identifierLoc);
    2090           0 :     aggregate->setOp(EOpInvariantDeclaration);
    2091           0 :     return aggregate;
    2092             : }
    2093             : 
    2094           0 : void TParseContext::parseDeclarator(TPublicType &publicType,
    2095             :                                     const TSourceLoc &identifierLocation,
    2096             :                                     const TString &identifier,
    2097             :                                     TIntermDeclaration *declarationOut)
    2098             : {
    2099             :     // If the declaration starting this declarator list was empty (example: int,), some checks were
    2100             :     // not performed.
    2101           0 :     if (mDeferredSingleDeclarationErrorCheck)
    2102             :     {
    2103           0 :         singleDeclarationErrorCheck(publicType, identifierLocation);
    2104           0 :         mDeferredSingleDeclarationErrorCheck = false;
    2105             :     }
    2106             : 
    2107           0 :     checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
    2108             : 
    2109           0 :     checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &publicType);
    2110             : 
    2111           0 :     TVariable *variable = nullptr;
    2112           0 :     declareVariable(identifierLocation, identifier, TType(publicType), &variable);
    2113             : 
    2114             :     TIntermSymbol *symbol =
    2115           0 :         intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation);
    2116           0 :     if (variable && symbol)
    2117             :     {
    2118           0 :         symbol->setId(variable->getUniqueId());
    2119           0 :         declarationOut->appendDeclarator(symbol);
    2120             :     }
    2121           0 : }
    2122             : 
    2123           0 : void TParseContext::parseArrayDeclarator(TPublicType &publicType,
    2124             :                                          const TSourceLoc &identifierLocation,
    2125             :                                          const TString &identifier,
    2126             :                                          const TSourceLoc &arrayLocation,
    2127             :                                          TIntermTyped *indexExpression,
    2128             :                                          TIntermDeclaration *declarationOut)
    2129             : {
    2130             :     // If the declaration starting this declarator list was empty (example: int,), some checks were
    2131             :     // not performed.
    2132           0 :     if (mDeferredSingleDeclarationErrorCheck)
    2133             :     {
    2134           0 :         singleDeclarationErrorCheck(publicType, identifierLocation);
    2135           0 :         mDeferredSingleDeclarationErrorCheck = false;
    2136             :     }
    2137             : 
    2138           0 :     checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
    2139             : 
    2140           0 :     checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &publicType);
    2141             : 
    2142           0 :     if (checkIsValidTypeAndQualifierForArray(arrayLocation, publicType))
    2143             :     {
    2144           0 :         TType arrayType = TType(publicType);
    2145           0 :         unsigned int size = checkIsValidArraySize(arrayLocation, indexExpression);
    2146           0 :         arrayType.setArraySize(size);
    2147             : 
    2148           0 :         TVariable *variable = nullptr;
    2149           0 :         declareVariable(identifierLocation, identifier, arrayType, &variable);
    2150             : 
    2151             :         TIntermSymbol *symbol =
    2152           0 :             intermediate.addSymbol(0, identifier, arrayType, identifierLocation);
    2153           0 :         if (variable && symbol)
    2154           0 :             symbol->setId(variable->getUniqueId());
    2155             : 
    2156           0 :         declarationOut->appendDeclarator(symbol);
    2157             :     }
    2158           0 : }
    2159             : 
    2160           0 : void TParseContext::parseInitDeclarator(const TPublicType &publicType,
    2161             :                                         const TSourceLoc &identifierLocation,
    2162             :                                         const TString &identifier,
    2163             :                                         const TSourceLoc &initLocation,
    2164             :                                         TIntermTyped *initializer,
    2165             :                                         TIntermDeclaration *declarationOut)
    2166             : {
    2167             :     // If the declaration starting this declarator list was empty (example: int,), some checks were
    2168             :     // not performed.
    2169           0 :     if (mDeferredSingleDeclarationErrorCheck)
    2170             :     {
    2171           0 :         singleDeclarationErrorCheck(publicType, identifierLocation);
    2172           0 :         mDeferredSingleDeclarationErrorCheck = false;
    2173             :     }
    2174             : 
    2175           0 :     checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
    2176             : 
    2177           0 :     TIntermBinary *initNode = nullptr;
    2178           0 :     if (!executeInitializer(identifierLocation, identifier, publicType, initializer, &initNode))
    2179             :     {
    2180             :         //
    2181             :         // build the intermediate representation
    2182             :         //
    2183           0 :         if (initNode)
    2184             :         {
    2185           0 :             declarationOut->appendDeclarator(initNode);
    2186             :         }
    2187             :     }
    2188           0 : }
    2189             : 
    2190           0 : void TParseContext::parseArrayInitDeclarator(const TPublicType &publicType,
    2191             :                                              const TSourceLoc &identifierLocation,
    2192             :                                              const TString &identifier,
    2193             :                                              const TSourceLoc &indexLocation,
    2194             :                                              TIntermTyped *indexExpression,
    2195             :                                              const TSourceLoc &initLocation,
    2196             :                                              TIntermTyped *initializer,
    2197             :                                              TIntermDeclaration *declarationOut)
    2198             : {
    2199             :     // If the declaration starting this declarator list was empty (example: int,), some checks were
    2200             :     // not performed.
    2201           0 :     if (mDeferredSingleDeclarationErrorCheck)
    2202             :     {
    2203           0 :         singleDeclarationErrorCheck(publicType, identifierLocation);
    2204           0 :         mDeferredSingleDeclarationErrorCheck = false;
    2205             :     }
    2206             : 
    2207           0 :     checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
    2208             : 
    2209           0 :     checkIsValidTypeAndQualifierForArray(indexLocation, publicType);
    2210             : 
    2211           0 :     TPublicType arrayType(publicType);
    2212             : 
    2213           0 :     unsigned int size = 0u;
    2214             :     // If indexExpression is nullptr, then the array will eventually get its size implicitly from
    2215             :     // the initializer.
    2216           0 :     if (indexExpression != nullptr)
    2217             :     {
    2218           0 :         size = checkIsValidArraySize(identifierLocation, indexExpression);
    2219             :     }
    2220             :     // Make the type an array even if size check failed.
    2221             :     // This ensures useless error messages regarding the variable's non-arrayness won't follow.
    2222           0 :     arrayType.setArraySize(size);
    2223             : 
    2224             :     // initNode will correspond to the whole of "b[n] = initializer".
    2225           0 :     TIntermBinary *initNode = nullptr;
    2226           0 :     if (!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
    2227             :     {
    2228           0 :         if (initNode)
    2229             :         {
    2230           0 :             declarationOut->appendDeclarator(initNode);
    2231             :         }
    2232             :     }
    2233           0 : }
    2234             : 
    2235           0 : void TParseContext::parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder)
    2236             : {
    2237           0 :     TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics);
    2238           0 :     const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier;
    2239             : 
    2240           0 :     checkInvariantVariableQualifier(typeQualifier.invariant, typeQualifier.qualifier,
    2241           0 :                                     typeQualifier.line);
    2242             : 
    2243             :     // It should never be the case, but some strange parser errors can send us here.
    2244           0 :     if (layoutQualifier.isEmpty())
    2245             :     {
    2246           0 :         error(typeQualifier.line, "Error during layout qualifier parsing.", "?");
    2247           0 :         return;
    2248             :     }
    2249             : 
    2250           0 :     if (!layoutQualifier.isCombinationValid())
    2251             :     {
    2252           0 :         error(typeQualifier.line, "invalid combination:", "layout");
    2253           0 :         return;
    2254             :     }
    2255             : 
    2256           0 :     checkIsMemoryQualifierNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
    2257             : 
    2258           0 :     checkInternalFormatIsNotSpecified(typeQualifier.line, layoutQualifier.imageInternalFormat);
    2259             : 
    2260           0 :     if (typeQualifier.qualifier == EvqComputeIn)
    2261             :     {
    2262           0 :         if (mComputeShaderLocalSizeDeclared &&
    2263           0 :             !layoutQualifier.isLocalSizeEqual(mComputeShaderLocalSize))
    2264             :         {
    2265             :             error(typeQualifier.line, "Work group size does not match the previous declaration",
    2266           0 :                   "layout");
    2267           0 :             return;
    2268             :         }
    2269             : 
    2270           0 :         if (mShaderVersion < 310)
    2271             :         {
    2272           0 :             error(typeQualifier.line, "in type qualifier supported in GLSL ES 3.10 only", "layout");
    2273           0 :             return;
    2274             :         }
    2275             : 
    2276           0 :         if (!layoutQualifier.localSize.isAnyValueSet())
    2277             :         {
    2278           0 :             error(typeQualifier.line, "No local work group size specified", "layout");
    2279           0 :             return;
    2280             :         }
    2281             : 
    2282             :         const TVariable *maxComputeWorkGroupSize = static_cast<const TVariable *>(
    2283           0 :             symbolTable.findBuiltIn("gl_MaxComputeWorkGroupSize", mShaderVersion));
    2284             : 
    2285             :         const TConstantUnion *maxComputeWorkGroupSizeData =
    2286           0 :             maxComputeWorkGroupSize->getConstPointer();
    2287             : 
    2288           0 :         for (size_t i = 0u; i < layoutQualifier.localSize.size(); ++i)
    2289             :         {
    2290           0 :             if (layoutQualifier.localSize[i] != -1)
    2291             :             {
    2292           0 :                 mComputeShaderLocalSize[i]             = layoutQualifier.localSize[i];
    2293           0 :                 const int maxComputeWorkGroupSizeValue = maxComputeWorkGroupSizeData[i].getIConst();
    2294           0 :                 if (mComputeShaderLocalSize[i] < 1 ||
    2295           0 :                     mComputeShaderLocalSize[i] > maxComputeWorkGroupSizeValue)
    2296             :                 {
    2297           0 :                     std::stringstream errorMessageStream;
    2298           0 :                     errorMessageStream << "Value must be at least 1 and no greater than "
    2299           0 :                                        << maxComputeWorkGroupSizeValue;
    2300           0 :                     const std::string &errorMessage = errorMessageStream.str();
    2301             : 
    2302           0 :                     error(typeQualifier.line, "invalid value:", getWorkGroupSizeString(i),
    2303           0 :                           errorMessage.c_str());
    2304           0 :                     return;
    2305             :                 }
    2306             :             }
    2307             :         }
    2308             : 
    2309           0 :         mComputeShaderLocalSizeDeclared = true;
    2310             :     }
    2311             :     else
    2312             :     {
    2313             : 
    2314           0 :         if (!checkWorkGroupSizeIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier))
    2315             :         {
    2316           0 :             return;
    2317             :         }
    2318             : 
    2319           0 :         if (typeQualifier.qualifier != EvqUniform)
    2320             :         {
    2321           0 :             error(typeQualifier.line, "invalid qualifier:",
    2322           0 :                   getQualifierString(typeQualifier.qualifier), "global layout must be uniform");
    2323           0 :             return;
    2324             :         }
    2325             : 
    2326           0 :         if (mShaderVersion < 300)
    2327             :         {
    2328             :             error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 and above",
    2329           0 :                   "layout");
    2330           0 :             return;
    2331             :         }
    2332             : 
    2333           0 :         checkLocationIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier);
    2334             : 
    2335           0 :         if (layoutQualifier.matrixPacking != EmpUnspecified)
    2336             :         {
    2337           0 :             mDefaultMatrixPacking = layoutQualifier.matrixPacking;
    2338             :         }
    2339             : 
    2340           0 :         if (layoutQualifier.blockStorage != EbsUnspecified)
    2341             :         {
    2342           0 :             mDefaultBlockStorage = layoutQualifier.blockStorage;
    2343             :         }
    2344             :     }
    2345             : }
    2346             : 
    2347           0 : TIntermAggregate *TParseContext::addFunctionPrototypeDeclaration(const TFunction &parsedFunction,
    2348             :                                                                  const TSourceLoc &location)
    2349             : {
    2350             :     // Note: function found from the symbol table could be the same as parsedFunction if this is the
    2351             :     // first declaration. Either way the instance in the symbol table is used to track whether the
    2352             :     // function is declared multiple times.
    2353             :     TFunction *function = static_cast<TFunction *>(
    2354           0 :         symbolTable.find(parsedFunction.getMangledName(), getShaderVersion()));
    2355           0 :     if (function->hasPrototypeDeclaration() && mShaderVersion == 100)
    2356             :     {
    2357             :         // ESSL 1.00.17 section 4.2.7.
    2358             :         // Doesn't apply to ESSL 3.00.4: see section 4.2.3.
    2359           0 :         error(location, "duplicate function prototype declarations are not allowed", "function");
    2360             :     }
    2361           0 :     function->setHasPrototypeDeclaration();
    2362             : 
    2363           0 :     TIntermAggregate *prototype = new TIntermAggregate;
    2364             :     // TODO(oetuaho@nvidia.com): Instead of converting the function information here, the node could
    2365             :     // point to the data that already exists in the symbol table.
    2366           0 :     prototype->setType(function->getReturnType());
    2367           0 :     prototype->getFunctionSymbolInfo()->setFromFunction(*function);
    2368             : 
    2369           0 :     for (size_t i = 0; i < function->getParamCount(); i++)
    2370             :     {
    2371           0 :         const TConstParameter &param = function->getParam(i);
    2372           0 :         if (param.name != 0)
    2373             :         {
    2374           0 :             TVariable variable(param.name, *param.type);
    2375             : 
    2376           0 :             TIntermSymbol *paramSymbol = intermediate.addSymbol(
    2377           0 :                 variable.getUniqueId(), variable.getName(), variable.getType(), location);
    2378           0 :             prototype = intermediate.growAggregate(prototype, paramSymbol, location);
    2379             :         }
    2380             :         else
    2381             :         {
    2382           0 :             TIntermSymbol *paramSymbol = intermediate.addSymbol(0, "", *param.type, location);
    2383           0 :             prototype                  = intermediate.growAggregate(prototype, paramSymbol, location);
    2384             :         }
    2385             :     }
    2386             : 
    2387           0 :     prototype->setOp(EOpPrototype);
    2388             : 
    2389           0 :     symbolTable.pop();
    2390             : 
    2391           0 :     if (!symbolTable.atGlobalLevel())
    2392             :     {
    2393             :         // ESSL 3.00.4 section 4.2.4.
    2394           0 :         error(location, "local function prototype declarations are not allowed", "function");
    2395             :     }
    2396             : 
    2397           0 :     return prototype;
    2398             : }
    2399             : 
    2400           0 : TIntermFunctionDefinition *TParseContext::addFunctionDefinition(
    2401             :     const TFunction &function,
    2402             :     TIntermAggregate *functionParameters,
    2403             :     TIntermBlock *functionBody,
    2404             :     const TSourceLoc &location)
    2405             : {
    2406             :     // Check that non-void functions have at least one return statement.
    2407           0 :     if (mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue)
    2408             :     {
    2409           0 :         error(location, "function does not return a value:", "", function.getName().c_str());
    2410             :     }
    2411             : 
    2412           0 :     if (functionBody == nullptr)
    2413             :     {
    2414           0 :         functionBody = new TIntermBlock();
    2415           0 :         functionBody->setLine(location);
    2416             :     }
    2417             :     TIntermFunctionDefinition *functionNode =
    2418           0 :         new TIntermFunctionDefinition(function.getReturnType(), functionParameters, functionBody);
    2419           0 :     functionNode->setLine(location);
    2420             : 
    2421           0 :     functionNode->getFunctionSymbolInfo()->setFromFunction(function);
    2422             : 
    2423           0 :     symbolTable.pop();
    2424           0 :     return functionNode;
    2425             : }
    2426             : 
    2427           0 : void TParseContext::parseFunctionDefinitionHeader(const TSourceLoc &location,
    2428             :                                                   TFunction **function,
    2429             :                                                   TIntermAggregate **aggregateOut)
    2430             : {
    2431           0 :     ASSERT(function);
    2432           0 :     ASSERT(*function);
    2433             :     const TSymbol *builtIn =
    2434           0 :         symbolTable.findBuiltIn((*function)->getMangledName(), getShaderVersion());
    2435             : 
    2436           0 :     if (builtIn)
    2437             :     {
    2438           0 :         error(location, "built-in functions cannot be redefined", (*function)->getName().c_str());
    2439             :     }
    2440             :     else
    2441             :     {
    2442             :         TFunction *prevDec = static_cast<TFunction *>(
    2443           0 :             symbolTable.find((*function)->getMangledName(), getShaderVersion()));
    2444             : 
    2445             :         // Note: 'prevDec' could be 'function' if this is the first time we've seen function as it
    2446             :         // would have just been put in the symbol table. Otherwise, we're looking up an earlier
    2447             :         // occurance.
    2448           0 :         if (*function != prevDec)
    2449             :         {
    2450             :             // Swap the parameters of the previous declaration to the parameters of the function
    2451             :             // definition (parameter names may differ).
    2452           0 :             prevDec->swapParameters(**function);
    2453             : 
    2454             :             // The function definition will share the same symbol as any previous declaration.
    2455           0 :             *function = prevDec;
    2456             :         }
    2457             : 
    2458           0 :         if ((*function)->isDefined())
    2459             :         {
    2460           0 :             error(location, "function already has a body", (*function)->getName().c_str());
    2461             :         }
    2462             : 
    2463           0 :         (*function)->setDefined();
    2464             :     }
    2465             : 
    2466             :     // Raise error message if main function takes any parameters or return anything other than void
    2467           0 :     if ((*function)->getName() == "main")
    2468             :     {
    2469           0 :         if ((*function)->getParamCount() > 0)
    2470             :         {
    2471           0 :             error(location, "function cannot take any parameter(s)",
    2472           0 :                   (*function)->getName().c_str());
    2473             :         }
    2474           0 :         if ((*function)->getReturnType().getBasicType() != EbtVoid)
    2475             :         {
    2476           0 :             error(location, "", (*function)->getReturnType().getBasicString(),
    2477           0 :                   "main function cannot return a value");
    2478             :         }
    2479             :     }
    2480             : 
    2481             :     //
    2482             :     // Remember the return type for later checking for RETURN statements.
    2483             :     //
    2484           0 :     mCurrentFunctionType  = &((*function)->getReturnType());
    2485           0 :     mFunctionReturnsValue = false;
    2486             : 
    2487             :     //
    2488             :     // Insert parameters into the symbol table.
    2489             :     // If the parameter has no name, it's not an error, just don't insert it
    2490             :     // (could be used for unused args).
    2491             :     //
    2492             :     // Also, accumulate the list of parameters into the HIL, so lower level code
    2493             :     // knows where to find parameters.
    2494             :     //
    2495           0 :     TIntermAggregate *paramNodes = new TIntermAggregate;
    2496           0 :     for (size_t i = 0; i < (*function)->getParamCount(); i++)
    2497             :     {
    2498           0 :         const TConstParameter &param = (*function)->getParam(i);
    2499           0 :         if (param.name != 0)
    2500             :         {
    2501           0 :             TVariable *variable = new TVariable(param.name, *param.type);
    2502             :             //
    2503             :             // Insert the parameters with name in the symbol table.
    2504             :             //
    2505           0 :             if (!symbolTable.declare(variable))
    2506             :             {
    2507           0 :                 error(location, "redefinition", variable->getName().c_str());
    2508           0 :                 paramNodes = intermediate.growAggregate(
    2509           0 :                     paramNodes, intermediate.addSymbol(0, "", *param.type, location), location);
    2510           0 :                 continue;
    2511             :             }
    2512             : 
    2513             :             //
    2514             :             // Add the parameter to the HIL
    2515             :             //
    2516           0 :             TIntermSymbol *symbol = intermediate.addSymbol(
    2517           0 :                 variable->getUniqueId(), variable->getName(), variable->getType(), location);
    2518             : 
    2519           0 :             paramNodes = intermediate.growAggregate(paramNodes, symbol, location);
    2520             :         }
    2521             :         else
    2522             :         {
    2523           0 :             paramNodes = intermediate.growAggregate(
    2524           0 :                 paramNodes, intermediate.addSymbol(0, "", *param.type, location), location);
    2525             :         }
    2526             :     }
    2527           0 :     intermediate.setAggregateOperator(paramNodes, EOpParameters, location);
    2528           0 :     *aggregateOut = paramNodes;
    2529           0 :     setLoopNestingLevel(0);
    2530           0 : }
    2531             : 
    2532           0 : TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TFunction *function)
    2533             : {
    2534             :     //
    2535             :     // We don't know at this point whether this is a function definition or a prototype.
    2536             :     // The definition production code will check for redefinitions.
    2537             :     // In the case of ESSL 1.00 the prototype production code will also check for redeclarations.
    2538             :     //
    2539             :     // Return types and parameter qualifiers must match in all redeclarations, so those are checked
    2540             :     // here.
    2541             :     //
    2542             :     TFunction *prevDec =
    2543           0 :         static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion()));
    2544             : 
    2545           0 :     if (getShaderVersion() >= 300 && symbolTable.hasUnmangledBuiltIn(function->getName().c_str()))
    2546             :     {
    2547             :         // With ESSL 3.00, names of built-in functions cannot be redeclared as functions.
    2548             :         // Therefore overloading or redefining builtin functions is an error.
    2549           0 :         error(location, "Name of a built-in function cannot be redeclared as function",
    2550           0 :               function->getName().c_str());
    2551             :     }
    2552           0 :     else if (prevDec)
    2553             :     {
    2554           0 :         if (prevDec->getReturnType() != function->getReturnType())
    2555             :         {
    2556           0 :             error(location, "function must have the same return type in all of its declarations",
    2557           0 :                   function->getReturnType().getBasicString());
    2558             :         }
    2559           0 :         for (size_t i = 0; i < prevDec->getParamCount(); ++i)
    2560             :         {
    2561           0 :             if (prevDec->getParam(i).type->getQualifier() !=
    2562           0 :                 function->getParam(i).type->getQualifier())
    2563             :             {
    2564           0 :                 error(location,
    2565             :                       "function must have the same parameter qualifiers in all of its declarations",
    2566           0 :                       function->getParam(i).type->getQualifierString());
    2567             :             }
    2568             :         }
    2569             :     }
    2570             : 
    2571             :     //
    2572             :     // Check for previously declared variables using the same name.
    2573             :     //
    2574           0 :     TSymbol *prevSym = symbolTable.find(function->getName(), getShaderVersion());
    2575           0 :     if (prevSym)
    2576             :     {
    2577           0 :         if (!prevSym->isFunction())
    2578             :         {
    2579           0 :             error(location, "redefinition", function->getName().c_str(), "function");
    2580             :         }
    2581             :     }
    2582             :     else
    2583             :     {
    2584             :         // Insert the unmangled name to detect potential future redefinition as a variable.
    2585           0 :         symbolTable.getOuterLevel()->insertUnmangled(function);
    2586             :     }
    2587             : 
    2588             :     // We're at the inner scope level of the function's arguments and body statement.
    2589             :     // Add the function prototype to the surrounding scope instead.
    2590           0 :     symbolTable.getOuterLevel()->insert(function);
    2591             : 
    2592             :     //
    2593             :     // If this is a redeclaration, it could also be a definition, in which case, we want to use the
    2594             :     // variable names from this one, and not the one that's
    2595             :     // being redeclared.  So, pass back up this declaration, not the one in the symbol table.
    2596             :     //
    2597           0 :     return function;
    2598             : }
    2599             : 
    2600           0 : TFunction *TParseContext::parseFunctionHeader(const TPublicType &type,
    2601             :                                               const TString *name,
    2602             :                                               const TSourceLoc &location)
    2603             : {
    2604           0 :     if (type.qualifier != EvqGlobal && type.qualifier != EvqTemporary)
    2605             :     {
    2606           0 :         error(location, "no qualifiers allowed for function return",
    2607           0 :               getQualifierString(type.qualifier));
    2608             :     }
    2609           0 :     if (!type.layoutQualifier.isEmpty())
    2610             :     {
    2611           0 :         error(location, "no qualifiers allowed for function return", "layout");
    2612             :     }
    2613             :     // make sure a sampler or an image is not involved as well...
    2614           0 :     checkIsNotSampler(location, type.typeSpecifierNonArray,
    2615           0 :                       "samplers can't be function return values");
    2616           0 :     checkIsNotImage(location, type.typeSpecifierNonArray, "images can't be function return values");
    2617           0 :     if (mShaderVersion < 300)
    2618             :     {
    2619             :         // Array return values are forbidden, but there's also no valid syntax for declaring array
    2620             :         // return values in ESSL 1.00.
    2621           0 :         ASSERT(type.arraySize == 0 || mDiagnostics.numErrors() > 0);
    2622             : 
    2623           0 :         if (type.isStructureContainingArrays())
    2624             :         {
    2625             :             // ESSL 1.00.17 section 6.1 Function Definitions
    2626           0 :             error(location, "structures containing arrays can't be function return values",
    2627           0 :                   TType(type).getCompleteString().c_str());
    2628             :         }
    2629             :     }
    2630             : 
    2631             :     // Add the function as a prototype after parsing it (we do not support recursion)
    2632           0 :     return new TFunction(name, new TType(type));
    2633             : }
    2634             : 
    2635           0 : TFunction *TParseContext::addConstructorFunc(const TPublicType &publicTypeIn)
    2636             : {
    2637           0 :     TPublicType publicType = publicTypeIn;
    2638           0 :     if (publicType.isStructSpecifier())
    2639             :     {
    2640           0 :         error(publicType.getLine(), "constructor can't be a structure definition",
    2641           0 :               getBasicString(publicType.getBasicType()));
    2642             :     }
    2643             : 
    2644           0 :     TOperator op = EOpNull;
    2645           0 :     if (publicType.getUserDef())
    2646             :     {
    2647           0 :         op = EOpConstructStruct;
    2648             :     }
    2649             :     else
    2650             :     {
    2651           0 :         op = sh::TypeToConstructorOperator(TType(publicType));
    2652           0 :         if (op == EOpNull)
    2653             :         {
    2654           0 :             error(publicType.getLine(), "cannot construct this type",
    2655           0 :                   getBasicString(publicType.getBasicType()));
    2656           0 :             publicType.setBasicType(EbtFloat);
    2657           0 :             op              = EOpConstructFloat;
    2658             :         }
    2659             :     }
    2660             : 
    2661           0 :     TString tempString;
    2662           0 :     const TType *type = new TType(publicType);
    2663           0 :     return new TFunction(&tempString, type, op);
    2664             : }
    2665             : 
    2666             : // This function is used to test for the correctness of the parameters passed to various constructor
    2667             : // functions and also convert them to the right datatype if it is allowed and required.
    2668             : //
    2669             : // Returns a node to add to the tree regardless of if an error was generated or not.
    2670             : //
    2671           0 : TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments,
    2672             :                                             TOperator op,
    2673             :                                             TFunction *fnCall,
    2674             :                                             const TSourceLoc &line)
    2675             : {
    2676           0 :     TType type = fnCall->getReturnType();
    2677           0 :     if (type.isUnsizedArray())
    2678             :     {
    2679           0 :         if (fnCall->getParamCount() == 0)
    2680             :         {
    2681           0 :             error(line, "implicitly sized array constructor must have at least one argument", "[]");
    2682           0 :             type.setArraySize(1u);
    2683           0 :             return TIntermTyped::CreateZero(type);
    2684             :         }
    2685           0 :         type.setArraySize(static_cast<unsigned int>(fnCall->getParamCount()));
    2686             :     }
    2687           0 :     bool constType = true;
    2688           0 :     for (size_t i = 0; i < fnCall->getParamCount(); ++i)
    2689             :     {
    2690           0 :         const TConstParameter &param = fnCall->getParam(i);
    2691           0 :         if (param.type->getQualifier() != EvqConst)
    2692           0 :             constType = false;
    2693             :     }
    2694           0 :     if (constType)
    2695           0 :         type.setQualifier(EvqConst);
    2696             : 
    2697           0 :     if (!checkConstructorArguments(line, arguments, *fnCall, op, type))
    2698             :     {
    2699           0 :         TIntermTyped *dummyNode = intermediate.setAggregateOperator(nullptr, op, line);
    2700           0 :         dummyNode->setType(type);
    2701           0 :         return dummyNode;
    2702             :     }
    2703           0 :     TIntermAggregate *constructor = arguments->getAsAggregate();
    2704           0 :     ASSERT(constructor != nullptr);
    2705             : 
    2706             :     // Turn the argument list itself into a constructor
    2707           0 :     constructor->setOp(op);
    2708           0 :     constructor->setLine(line);
    2709           0 :     ASSERT(constructor->isConstructor());
    2710             : 
    2711             :     // Need to set type before setPrecisionFromChildren() because bool doesn't have precision.
    2712           0 :     constructor->setType(type);
    2713             : 
    2714             :     // Structs should not be precision qualified, the individual members may be.
    2715             :     // Built-in types on the other hand should be precision qualified.
    2716           0 :     if (op != EOpConstructStruct)
    2717             :     {
    2718           0 :         constructor->setPrecisionFromChildren();
    2719           0 :         type.setPrecision(constructor->getPrecision());
    2720             :     }
    2721             : 
    2722           0 :     constructor->setType(type);
    2723             : 
    2724           0 :     TIntermTyped *constConstructor = intermediate.foldAggregateBuiltIn(constructor, &mDiagnostics);
    2725           0 :     if (constConstructor)
    2726             :     {
    2727           0 :         return constConstructor;
    2728             :     }
    2729             : 
    2730           0 :     return constructor;
    2731             : }
    2732             : 
    2733             : //
    2734             : // Interface/uniform blocks
    2735             : //
    2736           0 : TIntermDeclaration *TParseContext::addInterfaceBlock(
    2737             :     const TTypeQualifierBuilder &typeQualifierBuilder,
    2738             :     const TSourceLoc &nameLine,
    2739             :     const TString &blockName,
    2740             :     TFieldList *fieldList,
    2741             :     const TString *instanceName,
    2742             :     const TSourceLoc &instanceLine,
    2743             :     TIntermTyped *arrayIndex,
    2744             :     const TSourceLoc &arrayIndexLine)
    2745             : {
    2746           0 :     checkIsNotReserved(nameLine, blockName);
    2747             : 
    2748           0 :     TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics);
    2749             : 
    2750           0 :     if (typeQualifier.qualifier != EvqUniform)
    2751             :     {
    2752           0 :         error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier),
    2753           0 :               "interface blocks must be uniform");
    2754             :     }
    2755             : 
    2756           0 :     if (typeQualifier.invariant)
    2757             :     {
    2758           0 :         error(typeQualifier.line, "invalid qualifier on interface block member", "invariant");
    2759             :     }
    2760             : 
    2761           0 :     checkIsMemoryQualifierNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
    2762             : 
    2763           0 :     TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier;
    2764           0 :     checkLocationIsNotSpecified(typeQualifier.line, blockLayoutQualifier);
    2765             : 
    2766           0 :     if (blockLayoutQualifier.matrixPacking == EmpUnspecified)
    2767             :     {
    2768           0 :         blockLayoutQualifier.matrixPacking = mDefaultMatrixPacking;
    2769             :     }
    2770             : 
    2771           0 :     if (blockLayoutQualifier.blockStorage == EbsUnspecified)
    2772             :     {
    2773           0 :         blockLayoutQualifier.blockStorage = mDefaultBlockStorage;
    2774             :     }
    2775             : 
    2776           0 :     checkWorkGroupSizeIsNotSpecified(nameLine, blockLayoutQualifier);
    2777             : 
    2778           0 :     checkInternalFormatIsNotSpecified(nameLine, blockLayoutQualifier.imageInternalFormat);
    2779             : 
    2780           0 :     TSymbol *blockNameSymbol = new TInterfaceBlockName(&blockName);
    2781           0 :     if (!symbolTable.declare(blockNameSymbol))
    2782             :     {
    2783           0 :         error(nameLine, "redefinition", blockName.c_str(), "interface block name");
    2784             :     }
    2785             : 
    2786             :     // check for sampler types and apply layout qualifiers
    2787           0 :     for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
    2788             :     {
    2789           0 :         TField *field    = (*fieldList)[memberIndex];
    2790           0 :         TType *fieldType = field->type();
    2791           0 :         if (IsSampler(fieldType->getBasicType()))
    2792             :         {
    2793           0 :             error(field->line(), "unsupported type", fieldType->getBasicString(),
    2794           0 :                   "sampler types are not allowed in interface blocks");
    2795             :         }
    2796             : 
    2797           0 :         if (IsImage(fieldType->getBasicType()))
    2798             :         {
    2799           0 :             error(field->line(), "unsupported type", fieldType->getBasicString(),
    2800           0 :                   "image types are not allowed in interface blocks");
    2801             :         }
    2802             : 
    2803           0 :         const TQualifier qualifier = fieldType->getQualifier();
    2804           0 :         switch (qualifier)
    2805             :         {
    2806             :             case EvqGlobal:
    2807             :             case EvqUniform:
    2808           0 :                 break;
    2809             :             default:
    2810           0 :                 error(field->line(), "invalid qualifier on interface block member",
    2811           0 :                       getQualifierString(qualifier));
    2812           0 :                 break;
    2813             :         }
    2814             : 
    2815           0 :         if (fieldType->isInvariant())
    2816             :         {
    2817           0 :             error(field->line(), "invalid qualifier on interface block member", "invariant");
    2818             :         }
    2819             : 
    2820             :         // check layout qualifiers
    2821           0 :         TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier();
    2822           0 :         checkLocationIsNotSpecified(field->line(), fieldLayoutQualifier);
    2823             : 
    2824           0 :         if (fieldLayoutQualifier.blockStorage != EbsUnspecified)
    2825             :         {
    2826           0 :             error(field->line(), "invalid layout qualifier:",
    2827           0 :                   getBlockStorageString(fieldLayoutQualifier.blockStorage), "cannot be used here");
    2828             :         }
    2829             : 
    2830           0 :         if (fieldLayoutQualifier.matrixPacking == EmpUnspecified)
    2831             :         {
    2832           0 :             fieldLayoutQualifier.matrixPacking = blockLayoutQualifier.matrixPacking;
    2833             :         }
    2834           0 :         else if (!fieldType->isMatrix() && fieldType->getBasicType() != EbtStruct)
    2835             :         {
    2836           0 :             warning(field->line(), "extraneous layout qualifier:",
    2837             :                     getMatrixPackingString(fieldLayoutQualifier.matrixPacking),
    2838           0 :                     "only has an effect on matrix types");
    2839             :         }
    2840             : 
    2841           0 :         fieldType->setLayoutQualifier(fieldLayoutQualifier);
    2842             :     }
    2843             : 
    2844             :     // add array index
    2845           0 :     unsigned int arraySize = 0;
    2846           0 :     if (arrayIndex != nullptr)
    2847             :     {
    2848           0 :         arraySize = checkIsValidArraySize(arrayIndexLine, arrayIndex);
    2849             :     }
    2850             : 
    2851             :     TInterfaceBlock *interfaceBlock =
    2852           0 :         new TInterfaceBlock(&blockName, fieldList, instanceName, arraySize, blockLayoutQualifier);
    2853             :     TType interfaceBlockType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier,
    2854           0 :                              arraySize);
    2855             : 
    2856           0 :     TString symbolName = "";
    2857           0 :     int symbolId       = 0;
    2858             : 
    2859           0 :     if (!instanceName)
    2860             :     {
    2861             :         // define symbols for the members of the interface block
    2862           0 :         for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
    2863             :         {
    2864           0 :             TField *field    = (*fieldList)[memberIndex];
    2865           0 :             TType *fieldType = field->type();
    2866             : 
    2867             :             // set parent pointer of the field variable
    2868           0 :             fieldType->setInterfaceBlock(interfaceBlock);
    2869             : 
    2870           0 :             TVariable *fieldVariable = new TVariable(&field->name(), *fieldType);
    2871           0 :             fieldVariable->setQualifier(typeQualifier.qualifier);
    2872             : 
    2873           0 :             if (!symbolTable.declare(fieldVariable))
    2874             :             {
    2875           0 :                 error(field->line(), "redefinition", field->name().c_str(),
    2876           0 :                       "interface block member name");
    2877             :             }
    2878             :         }
    2879             :     }
    2880             :     else
    2881             :     {
    2882           0 :         checkIsNotReserved(instanceLine, *instanceName);
    2883             : 
    2884             :         // add a symbol for this interface block
    2885           0 :         TVariable *instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false);
    2886           0 :         instanceTypeDef->setQualifier(typeQualifier.qualifier);
    2887             : 
    2888           0 :         if (!symbolTable.declare(instanceTypeDef))
    2889             :         {
    2890           0 :             error(instanceLine, "redefinition", instanceName->c_str(),
    2891           0 :                   "interface block instance name");
    2892             :         }
    2893             : 
    2894           0 :         symbolId   = instanceTypeDef->getUniqueId();
    2895           0 :         symbolName = instanceTypeDef->getName();
    2896             :     }
    2897             : 
    2898             :     TIntermSymbol *blockSymbol =
    2899           0 :         intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line);
    2900           0 :     TIntermDeclaration *declaration = new TIntermDeclaration();
    2901           0 :     declaration->appendDeclarator(blockSymbol);
    2902           0 :     declaration->setLine(nameLine);
    2903             : 
    2904           0 :     exitStructDeclaration();
    2905           0 :     return declaration;
    2906             : }
    2907             : 
    2908           0 : void TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString &identifier)
    2909             : {
    2910           0 :     ++mStructNestingLevel;
    2911             : 
    2912             :     // Embedded structure definitions are not supported per GLSL ES spec.
    2913             :     // They aren't allowed in GLSL either, but we need to detect this here
    2914             :     // so we don't rely on the GLSL compiler to catch it.
    2915           0 :     if (mStructNestingLevel > 1)
    2916             :     {
    2917           0 :         error(line, "", "Embedded struct definitions are not allowed");
    2918             :     }
    2919           0 : }
    2920             : 
    2921           0 : void TParseContext::exitStructDeclaration()
    2922             : {
    2923           0 :     --mStructNestingLevel;
    2924           0 : }
    2925             : 
    2926           0 : void TParseContext::checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field)
    2927             : {
    2928           0 :     if (!sh::IsWebGLBasedSpec(mShaderSpec))
    2929             :     {
    2930           0 :         return;
    2931             :     }
    2932             : 
    2933           0 :     if (field.type()->getBasicType() != EbtStruct)
    2934             :     {
    2935           0 :         return;
    2936             :     }
    2937             : 
    2938             :     // We're already inside a structure definition at this point, so add
    2939             :     // one to the field's struct nesting.
    2940           0 :     if (1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting)
    2941             :     {
    2942           0 :         std::stringstream reasonStream;
    2943           0 :         reasonStream << "Reference of struct type " << field.type()->getStruct()->name().c_str()
    2944           0 :                      << " exceeds maximum allowed nesting level of " << kWebGLMaxStructNesting;
    2945           0 :         std::string reason = reasonStream.str();
    2946           0 :         error(line, reason.c_str(), field.name().c_str(), "");
    2947           0 :         return;
    2948             :     }
    2949             : }
    2950             : 
    2951             : //
    2952             : // Parse an array index expression
    2953             : //
    2954           0 : TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
    2955             :                                                 const TSourceLoc &location,
    2956             :                                                 TIntermTyped *indexExpression)
    2957             : {
    2958           0 :     if (!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector())
    2959             :     {
    2960           0 :         if (baseExpression->getAsSymbolNode())
    2961             :         {
    2962           0 :             error(location, " left of '[' is not of type array, matrix, or vector ",
    2963           0 :                   baseExpression->getAsSymbolNode()->getSymbol().c_str());
    2964             :         }
    2965             :         else
    2966             :         {
    2967           0 :             error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
    2968             :         }
    2969             : 
    2970           0 :         TConstantUnion *unionArray = new TConstantUnion[1];
    2971           0 :         unionArray->setFConst(0.0f);
    2972           0 :         return intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst),
    2973           0 :                                              location);
    2974             :     }
    2975             : 
    2976           0 :     TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion();
    2977             : 
    2978             :     // TODO(oetuaho@nvidia.com): Get rid of indexConstantUnion == nullptr below once ANGLE is able
    2979             :     // to constant fold all constant expressions. Right now we don't allow indexing interface blocks
    2980             :     // or fragment outputs with expressions that ANGLE is not able to constant fold, even if the
    2981             :     // index is a constant expression.
    2982           0 :     if (indexExpression->getQualifier() != EvqConst || indexConstantUnion == nullptr)
    2983             :     {
    2984           0 :         if (baseExpression->isInterfaceBlock())
    2985             :         {
    2986             :             error(
    2987             :                 location, "", "[",
    2988           0 :                 "array indexes for interface blocks arrays must be constant integral expressions");
    2989             :         }
    2990           0 :         else if (baseExpression->getQualifier() == EvqFragmentOut)
    2991             :         {
    2992             :             error(location, "", "[",
    2993           0 :                   "array indexes for fragment outputs must be constant integral expressions");
    2994             :         }
    2995           0 :         else if (mShaderSpec == SH_WEBGL2_SPEC && baseExpression->getQualifier() == EvqFragData)
    2996             :         {
    2997           0 :             error(location, "", "[", "array index for gl_FragData must be constant zero");
    2998             :         }
    2999             :     }
    3000             : 
    3001           0 :     if (indexConstantUnion)
    3002             :     {
    3003             :         // If an out-of-range index is not qualified as constant, the behavior in the spec is
    3004             :         // undefined. This applies even if ANGLE has been able to constant fold it (ANGLE may
    3005             :         // constant fold expressions that are not constant expressions). The most compatible way to
    3006             :         // handle this case is to report a warning instead of an error and force the index to be in
    3007             :         // the correct range.
    3008           0 :         bool outOfRangeIndexIsError = indexExpression->getQualifier() == EvqConst;
    3009           0 :         int index = indexConstantUnion->getIConst(0);
    3010             : 
    3011           0 :         int safeIndex = -1;
    3012             : 
    3013           0 :         if (baseExpression->isArray())
    3014             :         {
    3015           0 :             if (baseExpression->getQualifier() == EvqFragData && index > 0)
    3016             :             {
    3017           0 :                 if (mShaderSpec == SH_WEBGL2_SPEC)
    3018             :                 {
    3019             :                     // Error has been already generated if index is not const.
    3020           0 :                     if (indexExpression->getQualifier() == EvqConst)
    3021             :                     {
    3022             :                         error(location, "", "[",
    3023           0 :                               "array index for gl_FragData must be constant zero");
    3024             :                     }
    3025           0 :                     safeIndex = 0;
    3026             :                 }
    3027           0 :                 else if (!isExtensionEnabled("GL_EXT_draw_buffers"))
    3028             :                 {
    3029           0 :                     outOfRangeError(outOfRangeIndexIsError, location, "", "[",
    3030             :                                     "array index for gl_FragData must be zero when "
    3031           0 :                                     "GL_EXT_draw_buffers is disabled");
    3032           0 :                     safeIndex = 0;
    3033             :                 }
    3034             :             }
    3035             :             // Only do generic out-of-range check if similar error hasn't already been reported.
    3036           0 :             if (safeIndex < 0)
    3037             :             {
    3038           0 :                 safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
    3039           0 :                                                  baseExpression->getArraySize(),
    3040           0 :                                                  "array index out of range", "[]");
    3041             :             }
    3042             :         }
    3043           0 :         else if (baseExpression->isMatrix())
    3044             :         {
    3045           0 :             safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
    3046           0 :                                              baseExpression->getType().getCols(),
    3047           0 :                                              "matrix field selection out of range", "[]");
    3048             :         }
    3049           0 :         else if (baseExpression->isVector())
    3050             :         {
    3051           0 :             safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
    3052           0 :                                              baseExpression->getType().getNominalSize(),
    3053           0 :                                              "vector field selection out of range", "[]");
    3054             :         }
    3055             : 
    3056           0 :         ASSERT(safeIndex >= 0);
    3057             :         // Data of constant unions can't be changed, because it may be shared with other
    3058             :         // constant unions or even builtins, like gl_MaxDrawBuffers. Instead use a new
    3059             :         // sanitized object.
    3060           0 :         if (safeIndex != index)
    3061             :         {
    3062           0 :             TConstantUnion *safeConstantUnion = new TConstantUnion();
    3063           0 :             safeConstantUnion->setIConst(safeIndex);
    3064           0 :             indexConstantUnion->replaceConstantUnion(safeConstantUnion);
    3065             :         }
    3066             : 
    3067           0 :         return intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location,
    3068           0 :                                      &mDiagnostics);
    3069             :     }
    3070             :     else
    3071             :     {
    3072           0 :         return intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location,
    3073           0 :                                      &mDiagnostics);
    3074             :     }
    3075             : }
    3076             : 
    3077           0 : int TParseContext::checkIndexOutOfRange(bool outOfRangeIndexIsError,
    3078             :                                         const TSourceLoc &location,
    3079             :                                         int index,
    3080             :                                         int arraySize,
    3081             :                                         const char *reason,
    3082             :                                         const char *token)
    3083             : {
    3084           0 :     if (index >= arraySize || index < 0)
    3085             :     {
    3086           0 :         std::stringstream extraInfoStream;
    3087           0 :         extraInfoStream << "'" << index << "'";
    3088           0 :         std::string extraInfo = extraInfoStream.str();
    3089           0 :         outOfRangeError(outOfRangeIndexIsError, location, reason, token, extraInfo.c_str());
    3090           0 :         if (index < 0)
    3091             :         {
    3092           0 :             return 0;
    3093             :         }
    3094             :         else
    3095             :         {
    3096           0 :             return arraySize - 1;
    3097             :         }
    3098             :     }
    3099           0 :     return index;
    3100             : }
    3101             : 
    3102           0 : TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression,
    3103             :                                                          const TSourceLoc &dotLocation,
    3104             :                                                          const TString &fieldString,
    3105             :                                                          const TSourceLoc &fieldLocation)
    3106             : {
    3107           0 :     if (baseExpression->isArray())
    3108             :     {
    3109           0 :         error(fieldLocation, "cannot apply dot operator to an array", ".");
    3110           0 :         return baseExpression;
    3111             :     }
    3112             : 
    3113           0 :     if (baseExpression->isVector())
    3114             :     {
    3115             :         TVectorFields fields;
    3116           0 :         if (!parseVectorFields(fieldString, baseExpression->getNominalSize(), fields,
    3117             :                                fieldLocation))
    3118             :         {
    3119           0 :             fields.num        = 1;
    3120           0 :             fields.offsets[0] = 0;
    3121             :         }
    3122             : 
    3123           0 :         return TIntermediate::AddSwizzle(baseExpression, fields, dotLocation);
    3124             :     }
    3125           0 :     else if (baseExpression->getBasicType() == EbtStruct)
    3126             :     {
    3127           0 :         const TFieldList &fields = baseExpression->getType().getStruct()->fields();
    3128           0 :         if (fields.empty())
    3129             :         {
    3130           0 :             error(dotLocation, "structure has no fields", "Internal Error");
    3131           0 :             return baseExpression;
    3132             :         }
    3133             :         else
    3134             :         {
    3135           0 :             bool fieldFound = false;
    3136             :             unsigned int i;
    3137           0 :             for (i = 0; i < fields.size(); ++i)
    3138             :             {
    3139           0 :                 if (fields[i]->name() == fieldString)
    3140             :                 {
    3141           0 :                     fieldFound = true;
    3142           0 :                     break;
    3143             :                 }
    3144             :             }
    3145           0 :             if (fieldFound)
    3146             :             {
    3147           0 :                 TIntermTyped *index = TIntermTyped::CreateIndexNode(i);
    3148           0 :                 index->setLine(fieldLocation);
    3149           0 :                 return intermediate.addIndex(EOpIndexDirectStruct, baseExpression, index,
    3150           0 :                                              dotLocation, &mDiagnostics);
    3151             :             }
    3152             :             else
    3153             :             {
    3154           0 :                 error(dotLocation, " no such field in structure", fieldString.c_str());
    3155           0 :                 return baseExpression;
    3156             :             }
    3157             :         }
    3158             :     }
    3159           0 :     else if (baseExpression->isInterfaceBlock())
    3160             :     {
    3161           0 :         const TFieldList &fields = baseExpression->getType().getInterfaceBlock()->fields();
    3162           0 :         if (fields.empty())
    3163             :         {
    3164           0 :             error(dotLocation, "interface block has no fields", "Internal Error");
    3165           0 :             return baseExpression;
    3166             :         }
    3167             :         else
    3168             :         {
    3169           0 :             bool fieldFound = false;
    3170             :             unsigned int i;
    3171           0 :             for (i = 0; i < fields.size(); ++i)
    3172             :             {
    3173           0 :                 if (fields[i]->name() == fieldString)
    3174             :                 {
    3175           0 :                     fieldFound = true;
    3176           0 :                     break;
    3177             :                 }
    3178             :             }
    3179           0 :             if (fieldFound)
    3180             :             {
    3181           0 :                 TIntermTyped *index = TIntermTyped::CreateIndexNode(i);
    3182           0 :                 index->setLine(fieldLocation);
    3183           0 :                 return intermediate.addIndex(EOpIndexDirectInterfaceBlock, baseExpression, index,
    3184           0 :                                              dotLocation, &mDiagnostics);
    3185             :             }
    3186             :             else
    3187             :             {
    3188           0 :                 error(dotLocation, " no such field in interface block", fieldString.c_str());
    3189           0 :                 return baseExpression;
    3190             :             }
    3191             :         }
    3192             :     }
    3193             :     else
    3194             :     {
    3195           0 :         if (mShaderVersion < 300)
    3196             :         {
    3197           0 :             error(dotLocation, " field selection requires structure or vector on left hand side",
    3198           0 :                   fieldString.c_str());
    3199             :         }
    3200             :         else
    3201             :         {
    3202           0 :             error(dotLocation,
    3203             :                   " field selection requires structure, vector, or interface block on left hand "
    3204             :                   "side",
    3205           0 :                   fieldString.c_str());
    3206             :         }
    3207           0 :         return baseExpression;
    3208             :     }
    3209             : }
    3210             : 
    3211           0 : TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType,
    3212             :                                                      const TSourceLoc &qualifierTypeLine)
    3213             : {
    3214           0 :     TLayoutQualifier qualifier = TLayoutQualifier::create();
    3215             : 
    3216           0 :     if (qualifierType == "shared")
    3217             :     {
    3218           0 :         if (sh::IsWebGLBasedSpec(mShaderSpec))
    3219             :         {
    3220           0 :             error(qualifierTypeLine, "Only std140 layout is allowed in WebGL", "shared");
    3221             :         }
    3222           0 :         qualifier.blockStorage = EbsShared;
    3223             :     }
    3224           0 :     else if (qualifierType == "packed")
    3225             :     {
    3226           0 :         if (sh::IsWebGLBasedSpec(mShaderSpec))
    3227             :         {
    3228           0 :             error(qualifierTypeLine, "Only std140 layout is allowed in WebGL", "packed");
    3229             :         }
    3230           0 :         qualifier.blockStorage = EbsPacked;
    3231             :     }
    3232           0 :     else if (qualifierType == "std140")
    3233             :     {
    3234           0 :         qualifier.blockStorage = EbsStd140;
    3235             :     }
    3236           0 :     else if (qualifierType == "row_major")
    3237             :     {
    3238           0 :         qualifier.matrixPacking = EmpRowMajor;
    3239             :     }
    3240           0 :     else if (qualifierType == "column_major")
    3241             :     {
    3242           0 :         qualifier.matrixPacking = EmpColumnMajor;
    3243             :     }
    3244           0 :     else if (qualifierType == "location")
    3245             :     {
    3246           0 :         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(),
    3247           0 :               "location requires an argument");
    3248             :     }
    3249           0 :     else if (qualifierType == "rgba32f")
    3250             :     {
    3251           0 :         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
    3252           0 :         qualifier.imageInternalFormat = EiifRGBA32F;
    3253             :     }
    3254           0 :     else if (qualifierType == "rgba16f")
    3255             :     {
    3256           0 :         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
    3257           0 :         qualifier.imageInternalFormat = EiifRGBA16F;
    3258             :     }
    3259           0 :     else if (qualifierType == "r32f")
    3260             :     {
    3261           0 :         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
    3262           0 :         qualifier.imageInternalFormat = EiifR32F;
    3263             :     }
    3264           0 :     else if (qualifierType == "rgba8")
    3265             :     {
    3266           0 :         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
    3267           0 :         qualifier.imageInternalFormat = EiifRGBA8;
    3268             :     }
    3269           0 :     else if (qualifierType == "rgba8_snorm")
    3270             :     {
    3271           0 :         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
    3272           0 :         qualifier.imageInternalFormat = EiifRGBA8_SNORM;
    3273             :     }
    3274           0 :     else if (qualifierType == "rgba32i")
    3275             :     {
    3276           0 :         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
    3277           0 :         qualifier.imageInternalFormat = EiifRGBA32I;
    3278             :     }
    3279           0 :     else if (qualifierType == "rgba16i")
    3280             :     {
    3281           0 :         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
    3282           0 :         qualifier.imageInternalFormat = EiifRGBA16I;
    3283             :     }
    3284           0 :     else if (qualifierType == "rgba8i")
    3285             :     {
    3286           0 :         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
    3287           0 :         qualifier.imageInternalFormat = EiifRGBA8I;
    3288             :     }
    3289           0 :     else if (qualifierType == "r32i")
    3290             :     {
    3291           0 :         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
    3292           0 :         qualifier.imageInternalFormat = EiifR32I;
    3293             :     }
    3294           0 :     else if (qualifierType == "rgba32ui")
    3295             :     {
    3296           0 :         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
    3297           0 :         qualifier.imageInternalFormat = EiifRGBA32UI;
    3298             :     }
    3299           0 :     else if (qualifierType == "rgba16ui")
    3300             :     {
    3301           0 :         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
    3302           0 :         qualifier.imageInternalFormat = EiifRGBA16UI;
    3303             :     }
    3304           0 :     else if (qualifierType == "rgba8ui")
    3305             :     {
    3306           0 :         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
    3307           0 :         qualifier.imageInternalFormat = EiifRGBA8UI;
    3308             :     }
    3309           0 :     else if (qualifierType == "r32ui")
    3310             :     {
    3311           0 :         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
    3312           0 :         qualifier.imageInternalFormat = EiifR32UI;
    3313             :     }
    3314             : 
    3315             :     else
    3316             :     {
    3317           0 :         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
    3318             :     }
    3319             : 
    3320           0 :     return qualifier;
    3321             : }
    3322             : 
    3323           0 : void TParseContext::parseLocalSize(const TString &qualifierType,
    3324             :                                    const TSourceLoc &qualifierTypeLine,
    3325             :                                    int intValue,
    3326             :                                    const TSourceLoc &intValueLine,
    3327             :                                    const std::string &intValueString,
    3328             :                                    size_t index,
    3329             :                                    sh::WorkGroupSize *localSize)
    3330             : {
    3331           0 :     checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
    3332           0 :     if (intValue < 1)
    3333             :     {
    3334           0 :         std::string errorMessage = std::string(getWorkGroupSizeString(index)) + " must be positive";
    3335           0 :         error(intValueLine, "out of range:", intValueString.c_str(), errorMessage.c_str());
    3336             :     }
    3337           0 :     (*localSize)[index] = intValue;
    3338           0 : }
    3339             : 
    3340           0 : TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType,
    3341             :                                                      const TSourceLoc &qualifierTypeLine,
    3342             :                                                      int intValue,
    3343             :                                                      const TSourceLoc &intValueLine)
    3344             : {
    3345           0 :     TLayoutQualifier qualifier = TLayoutQualifier::create();
    3346             : 
    3347           0 :     std::string intValueString = Str(intValue);
    3348             : 
    3349           0 :     if (qualifierType == "location")
    3350             :     {
    3351             :         // must check that location is non-negative
    3352           0 :         if (intValue < 0)
    3353             :         {
    3354           0 :             error(intValueLine, "out of range:", intValueString.c_str(),
    3355           0 :                   "location must be non-negative");
    3356             :         }
    3357             :         else
    3358             :         {
    3359           0 :             qualifier.location = intValue;
    3360           0 :             qualifier.locationsSpecified = 1;
    3361             :         }
    3362             :     }
    3363           0 :     else if (qualifierType == "local_size_x")
    3364             :     {
    3365             :         parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 0u,
    3366           0 :                        &qualifier.localSize);
    3367             :     }
    3368           0 :     else if (qualifierType == "local_size_y")
    3369             :     {
    3370             :         parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 1u,
    3371           0 :                        &qualifier.localSize);
    3372             :     }
    3373           0 :     else if (qualifierType == "local_size_z")
    3374             :     {
    3375             :         parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 2u,
    3376           0 :                        &qualifier.localSize);
    3377             :     }
    3378             :     else
    3379             :     {
    3380           0 :         error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
    3381             :     }
    3382             : 
    3383           0 :     return qualifier;
    3384             : }
    3385             : 
    3386           0 : TTypeQualifierBuilder *TParseContext::createTypeQualifierBuilder(const TSourceLoc &loc)
    3387             : {
    3388             :     return new TTypeQualifierBuilder(
    3389           0 :         new TStorageQualifierWrapper(symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary, loc),
    3390           0 :         mShaderVersion);
    3391             : }
    3392             : 
    3393           0 : TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier,
    3394             :                                                      TLayoutQualifier rightQualifier,
    3395             :                                                      const TSourceLoc &rightQualifierLocation)
    3396             : {
    3397             :     return sh::JoinLayoutQualifiers(leftQualifier, rightQualifier, rightQualifierLocation,
    3398           0 :                                     &mDiagnostics);
    3399             : }
    3400             : 
    3401           0 : TFieldList *TParseContext::addStructDeclaratorListWithQualifiers(
    3402             :     const TTypeQualifierBuilder &typeQualifierBuilder,
    3403             :     TPublicType *typeSpecifier,
    3404             :     TFieldList *fieldList)
    3405             : {
    3406           0 :     TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics);
    3407             : 
    3408           0 :     typeSpecifier->qualifier       = typeQualifier.qualifier;
    3409           0 :     typeSpecifier->layoutQualifier = typeQualifier.layoutQualifier;
    3410           0 :     typeSpecifier->memoryQualifier = typeQualifier.memoryQualifier;
    3411           0 :     typeSpecifier->invariant       = typeQualifier.invariant;
    3412           0 :     if (typeQualifier.precision != EbpUndefined)
    3413             :     {
    3414           0 :         typeSpecifier->precision = typeQualifier.precision;
    3415             :     }
    3416           0 :     return addStructDeclaratorList(*typeSpecifier, fieldList);
    3417             : }
    3418             : 
    3419           0 : TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecifier,
    3420             :                                                    TFieldList *fieldList)
    3421             : {
    3422           0 :     checkPrecisionSpecified(typeSpecifier.getLine(), typeSpecifier.precision,
    3423           0 :                             typeSpecifier.getBasicType());
    3424             : 
    3425           0 :     checkIsNonVoid(typeSpecifier.getLine(), (*fieldList)[0]->name(), typeSpecifier.getBasicType());
    3426             : 
    3427           0 :     checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), typeSpecifier.layoutQualifier);
    3428             : 
    3429           0 :     for (unsigned int i = 0; i < fieldList->size(); ++i)
    3430             :     {
    3431             :         //
    3432             :         // Careful not to replace already known aspects of type, like array-ness
    3433             :         //
    3434           0 :         TType *type = (*fieldList)[i]->type();
    3435           0 :         type->setBasicType(typeSpecifier.getBasicType());
    3436           0 :         type->setPrimarySize(typeSpecifier.getPrimarySize());
    3437           0 :         type->setSecondarySize(typeSpecifier.getSecondarySize());
    3438           0 :         type->setPrecision(typeSpecifier.precision);
    3439           0 :         type->setQualifier(typeSpecifier.qualifier);
    3440           0 :         type->setLayoutQualifier(typeSpecifier.layoutQualifier);
    3441           0 :         type->setMemoryQualifier(typeSpecifier.memoryQualifier);
    3442           0 :         type->setInvariant(typeSpecifier.invariant);
    3443             : 
    3444             :         // don't allow arrays of arrays
    3445           0 :         if (type->isArray())
    3446             :         {
    3447           0 :             checkIsValidTypeForArray(typeSpecifier.getLine(), typeSpecifier);
    3448             :         }
    3449           0 :         if (typeSpecifier.array)
    3450           0 :             type->setArraySize(static_cast<unsigned int>(typeSpecifier.arraySize));
    3451           0 :         if (typeSpecifier.getUserDef())
    3452             :         {
    3453           0 :             type->setStruct(typeSpecifier.getUserDef()->getStruct());
    3454             :         }
    3455             : 
    3456           0 :         checkIsBelowStructNestingLimit(typeSpecifier.getLine(), *(*fieldList)[i]);
    3457             :     }
    3458             : 
    3459           0 :     return fieldList;
    3460             : }
    3461             : 
    3462           0 : TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine,
    3463             :                                                    const TSourceLoc &nameLine,
    3464             :                                                    const TString *structName,
    3465             :                                                    TFieldList *fieldList)
    3466             : {
    3467           0 :     TStructure *structure = new TStructure(structName, fieldList);
    3468           0 :     TType *structureType  = new TType(structure);
    3469             : 
    3470             :     // Store a bool in the struct if we're at global scope, to allow us to
    3471             :     // skip the local struct scoping workaround in HLSL.
    3472           0 :     structure->setAtGlobalScope(symbolTable.atGlobalLevel());
    3473             : 
    3474           0 :     if (!structName->empty())
    3475             :     {
    3476           0 :         checkIsNotReserved(nameLine, *structName);
    3477           0 :         TVariable *userTypeDef = new TVariable(structName, *structureType, true);
    3478           0 :         if (!symbolTable.declare(userTypeDef))
    3479             :         {
    3480           0 :             error(nameLine, "redefinition", structName->c_str(), "struct");
    3481             :         }
    3482             :     }
    3483             : 
    3484             :     // ensure we do not specify any storage qualifiers on the struct members
    3485           0 :     for (unsigned int typeListIndex = 0; typeListIndex < fieldList->size(); typeListIndex++)
    3486             :     {
    3487           0 :         const TField &field        = *(*fieldList)[typeListIndex];
    3488           0 :         const TQualifier qualifier = field.type()->getQualifier();
    3489           0 :         switch (qualifier)
    3490             :         {
    3491             :             case EvqGlobal:
    3492             :             case EvqTemporary:
    3493           0 :                 break;
    3494             :             default:
    3495           0 :                 error(field.line(), "invalid qualifier on struct member",
    3496           0 :                       getQualifierString(qualifier));
    3497           0 :                 break;
    3498             :         }
    3499           0 :         if (field.type()->isInvariant())
    3500             :         {
    3501           0 :             error(field.line(), "invalid qualifier on struct member", "invariant");
    3502             :         }
    3503           0 :         if (IsImage(field.type()->getBasicType()))
    3504             :         {
    3505           0 :             error(field.line(), "disallowed type in struct", field.type()->getBasicString());
    3506             :         }
    3507             : 
    3508           0 :         checkIsMemoryQualifierNotSpecified(field.type()->getMemoryQualifier(), field.line());
    3509             : 
    3510           0 :         checkLocationIsNotSpecified(field.line(), field.type()->getLayoutQualifier());
    3511             :     }
    3512             : 
    3513             :     TTypeSpecifierNonArray typeSpecifierNonArray;
    3514           0 :     typeSpecifierNonArray.initialize(EbtStruct, structLine);
    3515           0 :     typeSpecifierNonArray.userDef           = structureType;
    3516           0 :     typeSpecifierNonArray.isStructSpecifier = true;
    3517           0 :     exitStructDeclaration();
    3518             : 
    3519           0 :     return typeSpecifierNonArray;
    3520             : }
    3521             : 
    3522           0 : TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init,
    3523             :                                         TIntermBlock *statementList,
    3524             :                                         const TSourceLoc &loc)
    3525             : {
    3526           0 :     TBasicType switchType = init->getBasicType();
    3527           0 :     if ((switchType != EbtInt && switchType != EbtUInt) || init->isMatrix() || init->isArray() ||
    3528           0 :         init->isVector())
    3529             :     {
    3530           0 :         error(init->getLine(), "init-expression in a switch statement must be a scalar integer",
    3531           0 :               "switch");
    3532           0 :         return nullptr;
    3533             :     }
    3534             : 
    3535           0 :     if (statementList)
    3536             :     {
    3537           0 :         if (!ValidateSwitch::validate(switchType, this, statementList, loc))
    3538             :         {
    3539           0 :             return nullptr;
    3540             :         }
    3541             :     }
    3542             : 
    3543           0 :     TIntermSwitch *node = intermediate.addSwitch(init, statementList, loc);
    3544           0 :     if (node == nullptr)
    3545             :     {
    3546           0 :         error(loc, "erroneous switch statement", "switch");
    3547           0 :         return nullptr;
    3548             :     }
    3549           0 :     return node;
    3550             : }
    3551             : 
    3552           0 : TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &loc)
    3553             : {
    3554           0 :     if (mSwitchNestingLevel == 0)
    3555             :     {
    3556           0 :         error(loc, "case labels need to be inside switch statements", "case");
    3557           0 :         return nullptr;
    3558             :     }
    3559           0 :     if (condition == nullptr)
    3560             :     {
    3561           0 :         error(loc, "case label must have a condition", "case");
    3562           0 :         return nullptr;
    3563             :     }
    3564           0 :     if ((condition->getBasicType() != EbtInt && condition->getBasicType() != EbtUInt) ||
    3565           0 :         condition->isMatrix() || condition->isArray() || condition->isVector())
    3566             :     {
    3567           0 :         error(condition->getLine(), "case label must be a scalar integer", "case");
    3568             :     }
    3569           0 :     TIntermConstantUnion *conditionConst = condition->getAsConstantUnion();
    3570             :     // TODO(oetuaho@nvidia.com): Get rid of the conditionConst == nullptr check once all constant
    3571             :     // expressions can be folded. Right now we don't allow constant expressions that ANGLE can't
    3572             :     // fold in case labels.
    3573           0 :     if (condition->getQualifier() != EvqConst || conditionConst == nullptr)
    3574             :     {
    3575           0 :         error(condition->getLine(), "case label must be constant", "case");
    3576             :     }
    3577           0 :     TIntermCase *node = intermediate.addCase(condition, loc);
    3578           0 :     if (node == nullptr)
    3579             :     {
    3580           0 :         error(loc, "erroneous case statement", "case");
    3581           0 :         return nullptr;
    3582             :     }
    3583           0 :     return node;
    3584             : }
    3585             : 
    3586           0 : TIntermCase *TParseContext::addDefault(const TSourceLoc &loc)
    3587             : {
    3588           0 :     if (mSwitchNestingLevel == 0)
    3589             :     {
    3590           0 :         error(loc, "default labels need to be inside switch statements", "default");
    3591           0 :         return nullptr;
    3592             :     }
    3593           0 :     TIntermCase *node = intermediate.addCase(nullptr, loc);
    3594           0 :     if (node == nullptr)
    3595             :     {
    3596           0 :         error(loc, "erroneous default statement", "default");
    3597           0 :         return nullptr;
    3598             :     }
    3599           0 :     return node;
    3600             : }
    3601             : 
    3602           0 : TIntermTyped *TParseContext::createUnaryMath(TOperator op,
    3603             :                                              TIntermTyped *child,
    3604             :                                              const TSourceLoc &loc,
    3605             :                                              const TType *funcReturnType)
    3606             : {
    3607           0 :     if (child == nullptr)
    3608             :     {
    3609           0 :         return nullptr;
    3610             :     }
    3611             : 
    3612           0 :     switch (op)
    3613             :     {
    3614             :         case EOpLogicalNot:
    3615           0 :             if (child->getBasicType() != EbtBool || child->isMatrix() || child->isArray() ||
    3616           0 :                 child->isVector())
    3617             :             {
    3618           0 :                 return nullptr;
    3619             :             }
    3620           0 :             break;
    3621             :         case EOpBitwiseNot:
    3622           0 :             if ((child->getBasicType() != EbtInt && child->getBasicType() != EbtUInt) ||
    3623           0 :                 child->isMatrix() || child->isArray())
    3624             :             {
    3625           0 :                 return nullptr;
    3626             :             }
    3627           0 :             break;
    3628             :         case EOpPostIncrement:
    3629             :         case EOpPreIncrement:
    3630             :         case EOpPostDecrement:
    3631             :         case EOpPreDecrement:
    3632             :         case EOpNegative:
    3633             :         case EOpPositive:
    3634           0 :             if (child->getBasicType() == EbtStruct || child->getBasicType() == EbtBool ||
    3635           0 :                 child->isArray() || IsOpaqueType(child->getBasicType()))
    3636             :             {
    3637           0 :                 return nullptr;
    3638             :             }
    3639             :         // Operators for built-ins are already type checked against their prototype.
    3640             :         default:
    3641           0 :             break;
    3642             :     }
    3643             : 
    3644           0 :     TIntermUnary *node = new TIntermUnary(op, child);
    3645           0 :     node->setLine(loc);
    3646             : 
    3647           0 :     TIntermTyped *foldedNode = node->fold(&mDiagnostics);
    3648           0 :     if (foldedNode)
    3649           0 :         return foldedNode;
    3650             : 
    3651           0 :     return node;
    3652             : }
    3653             : 
    3654           0 : TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
    3655             : {
    3656           0 :     TIntermTyped *node = createUnaryMath(op, child, loc, nullptr);
    3657           0 :     if (node == nullptr)
    3658             :     {
    3659           0 :         unaryOpError(loc, GetOperatorString(op), child->getCompleteString());
    3660           0 :         return child;
    3661             :     }
    3662           0 :     return node;
    3663             : }
    3664             : 
    3665           0 : TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op,
    3666             :                                                 TIntermTyped *child,
    3667             :                                                 const TSourceLoc &loc)
    3668             : {
    3669           0 :     checkCanBeLValue(loc, GetOperatorString(op), child);
    3670           0 :     return addUnaryMath(op, child, loc);
    3671             : }
    3672             : 
    3673           0 : bool TParseContext::binaryOpCommonCheck(TOperator op,
    3674             :                                         TIntermTyped *left,
    3675             :                                         TIntermTyped *right,
    3676             :                                         const TSourceLoc &loc)
    3677             : {
    3678           0 :     if (left->getType().getStruct() || right->getType().getStruct())
    3679             :     {
    3680           0 :         switch (op)
    3681             :         {
    3682             :             case EOpIndexDirectStruct:
    3683           0 :                 ASSERT(left->getType().getStruct());
    3684           0 :                 break;
    3685             :             case EOpEqual:
    3686             :             case EOpNotEqual:
    3687             :             case EOpAssign:
    3688             :             case EOpInitialize:
    3689           0 :                 if (left->getType() != right->getType())
    3690             :                 {
    3691           0 :                     return false;
    3692             :                 }
    3693           0 :                 break;
    3694             :             default:
    3695           0 :                 error(loc, "Invalid operation for structs", GetOperatorString(op));
    3696           0 :                 return false;
    3697             :         }
    3698             :     }
    3699             : 
    3700           0 :     if (left->isArray() || right->isArray())
    3701             :     {
    3702           0 :         if (mShaderVersion < 300)
    3703             :         {
    3704           0 :             error(loc, "Invalid operation for arrays", GetOperatorString(op));
    3705           0 :             return false;
    3706             :         }
    3707             : 
    3708           0 :         if (left->isArray() != right->isArray())
    3709             :         {
    3710           0 :             error(loc, "array / non-array mismatch", GetOperatorString(op));
    3711           0 :             return false;
    3712             :         }
    3713             : 
    3714           0 :         switch (op)
    3715             :         {
    3716             :             case EOpEqual:
    3717             :             case EOpNotEqual:
    3718             :             case EOpAssign:
    3719             :             case EOpInitialize:
    3720           0 :                 break;
    3721             :             default:
    3722           0 :                 error(loc, "Invalid operation for arrays", GetOperatorString(op));
    3723           0 :                 return false;
    3724             :         }
    3725             :         // At this point, size of implicitly sized arrays should be resolved.
    3726           0 :         if (left->getArraySize() != right->getArraySize())
    3727             :         {
    3728           0 :             error(loc, "array size mismatch", GetOperatorString(op));
    3729           0 :             return false;
    3730             :         }
    3731             :     }
    3732             : 
    3733             :     // Check ops which require integer / ivec parameters
    3734           0 :     bool isBitShift = false;
    3735           0 :     switch (op)
    3736             :     {
    3737             :         case EOpBitShiftLeft:
    3738             :         case EOpBitShiftRight:
    3739             :         case EOpBitShiftLeftAssign:
    3740             :         case EOpBitShiftRightAssign:
    3741             :             // Unsigned can be bit-shifted by signed and vice versa, but we need to
    3742             :             // check that the basic type is an integer type.
    3743           0 :             isBitShift = true;
    3744           0 :             if (!IsInteger(left->getBasicType()) || !IsInteger(right->getBasicType()))
    3745             :             {
    3746           0 :                 return false;
    3747             :             }
    3748           0 :             break;
    3749             :         case EOpBitwiseAnd:
    3750             :         case EOpBitwiseXor:
    3751             :         case EOpBitwiseOr:
    3752             :         case EOpBitwiseAndAssign:
    3753             :         case EOpBitwiseXorAssign:
    3754             :         case EOpBitwiseOrAssign:
    3755             :             // It is enough to check the type of only one operand, since later it
    3756             :             // is checked that the operand types match.
    3757           0 :             if (!IsInteger(left->getBasicType()))
    3758             :             {
    3759           0 :                 return false;
    3760             :             }
    3761           0 :             break;
    3762             :         default:
    3763           0 :             break;
    3764             :     }
    3765             : 
    3766             :     // GLSL ES 1.00 and 3.00 do not support implicit type casting.
    3767             :     // So the basic type should usually match.
    3768           0 :     if (!isBitShift && left->getBasicType() != right->getBasicType())
    3769             :     {
    3770           0 :         return false;
    3771             :     }
    3772             : 
    3773             :     // Check that:
    3774             :     // 1. Type sizes match exactly on ops that require that.
    3775             :     // 2. Restrictions for structs that contain arrays or samplers are respected.
    3776             :     // 3. Arithmetic op type dimensionality restrictions for ops other than multiply are respected.
    3777           0 :     switch (op)
    3778             :     {
    3779             :         case EOpAssign:
    3780             :         case EOpInitialize:
    3781             :         case EOpEqual:
    3782             :         case EOpNotEqual:
    3783             :             // ESSL 1.00 sections 5.7, 5.8, 5.9
    3784           0 :             if (mShaderVersion < 300 && left->getType().isStructureContainingArrays())
    3785             :             {
    3786           0 :                 error(loc, "undefined operation for structs containing arrays",
    3787           0 :                       GetOperatorString(op));
    3788           0 :                 return false;
    3789             :             }
    3790             :             // Samplers as l-values are disallowed also in ESSL 3.00, see section 4.1.7,
    3791             :             // we interpret the spec so that this extends to structs containing samplers,
    3792             :             // similarly to ESSL 1.00 spec.
    3793           0 :             if ((mShaderVersion < 300 || op == EOpAssign || op == EOpInitialize) &&
    3794           0 :                 left->getType().isStructureContainingSamplers())
    3795             :             {
    3796           0 :                 error(loc, "undefined operation for structs containing samplers",
    3797           0 :                       GetOperatorString(op));
    3798           0 :                 return false;
    3799             :             }
    3800             : 
    3801           0 :             if ((op == EOpAssign || op == EOpInitialize) &&
    3802           0 :                 left->getType().isStructureContainingImages())
    3803             :             {
    3804           0 :                 error(loc, "undefined operation for structs containing images",
    3805           0 :                       GetOperatorString(op));
    3806           0 :                 return false;
    3807             :             }
    3808             :         case EOpLessThan:
    3809             :         case EOpGreaterThan:
    3810             :         case EOpLessThanEqual:
    3811             :         case EOpGreaterThanEqual:
    3812           0 :             if ((left->getNominalSize() != right->getNominalSize()) ||
    3813           0 :                 (left->getSecondarySize() != right->getSecondarySize()))
    3814             :             {
    3815           0 :                 return false;
    3816             :             }
    3817           0 :             break;
    3818             :         case EOpAdd:
    3819             :         case EOpSub:
    3820             :         case EOpDiv:
    3821             :         case EOpIMod:
    3822             :         case EOpBitShiftLeft:
    3823             :         case EOpBitShiftRight:
    3824             :         case EOpBitwiseAnd:
    3825             :         case EOpBitwiseXor:
    3826             :         case EOpBitwiseOr:
    3827             :         case EOpAddAssign:
    3828             :         case EOpSubAssign:
    3829             :         case EOpDivAssign:
    3830             :         case EOpIModAssign:
    3831             :         case EOpBitShiftLeftAssign:
    3832             :         case EOpBitShiftRightAssign:
    3833             :         case EOpBitwiseAndAssign:
    3834             :         case EOpBitwiseXorAssign:
    3835             :         case EOpBitwiseOrAssign:
    3836           0 :             if ((left->isMatrix() && right->isVector()) || (left->isVector() && right->isMatrix()))
    3837             :             {
    3838           0 :                 return false;
    3839             :             }
    3840             : 
    3841             :             // Are the sizes compatible?
    3842           0 :             if (left->getNominalSize() != right->getNominalSize() ||
    3843           0 :                 left->getSecondarySize() != right->getSecondarySize())
    3844             :             {
    3845             :                 // If the nominal sizes of operands do not match:
    3846             :                 // One of them must be a scalar.
    3847           0 :                 if (!left->isScalar() && !right->isScalar())
    3848           0 :                     return false;
    3849             : 
    3850             :                 // In the case of compound assignment other than multiply-assign,
    3851             :                 // the right side needs to be a scalar. Otherwise a vector/matrix
    3852             :                 // would be assigned to a scalar. A scalar can't be shifted by a
    3853             :                 // vector either.
    3854           0 :                 if (!right->isScalar() &&
    3855           0 :                     (IsAssignment(op) || op == EOpBitShiftLeft || op == EOpBitShiftRight))
    3856           0 :                     return false;
    3857             :             }
    3858           0 :             break;
    3859             :         default:
    3860           0 :             break;
    3861             :     }
    3862             : 
    3863           0 :     return true;
    3864             : }
    3865             : 
    3866           0 : bool TParseContext::isMultiplicationTypeCombinationValid(TOperator op,
    3867             :                                                          const TType &left,
    3868             :                                                          const TType &right)
    3869             : {
    3870           0 :     switch (op)
    3871             :     {
    3872             :         case EOpMul:
    3873             :         case EOpMulAssign:
    3874           0 :             return left.getNominalSize() == right.getNominalSize() &&
    3875           0 :                    left.getSecondarySize() == right.getSecondarySize();
    3876             :         case EOpVectorTimesScalar:
    3877           0 :             return true;
    3878             :         case EOpVectorTimesScalarAssign:
    3879           0 :             ASSERT(!left.isMatrix() && !right.isMatrix());
    3880           0 :             return left.isVector() && !right.isVector();
    3881             :         case EOpVectorTimesMatrix:
    3882           0 :             return left.getNominalSize() == right.getRows();
    3883             :         case EOpVectorTimesMatrixAssign:
    3884           0 :             ASSERT(!left.isMatrix() && right.isMatrix());
    3885           0 :             return left.isVector() && left.getNominalSize() == right.getRows() &&
    3886           0 :                    left.getNominalSize() == right.getCols();
    3887             :         case EOpMatrixTimesVector:
    3888           0 :             return left.getCols() == right.getNominalSize();
    3889             :         case EOpMatrixTimesScalar:
    3890           0 :             return true;
    3891             :         case EOpMatrixTimesScalarAssign:
    3892           0 :             ASSERT(left.isMatrix() && !right.isMatrix());
    3893           0 :             return !right.isVector();
    3894             :         case EOpMatrixTimesMatrix:
    3895           0 :             return left.getCols() == right.getRows();
    3896             :         case EOpMatrixTimesMatrixAssign:
    3897           0 :             ASSERT(left.isMatrix() && right.isMatrix());
    3898             :             // We need to check two things:
    3899             :             // 1. The matrix multiplication step is valid.
    3900             :             // 2. The result will have the same number of columns as the lvalue.
    3901           0 :             return left.getCols() == right.getRows() && left.getCols() == right.getCols();
    3902             : 
    3903             :         default:
    3904           0 :             UNREACHABLE();
    3905             :             return false;
    3906             :     }
    3907             : }
    3908             : 
    3909           0 : TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op,
    3910             :                                                    TIntermTyped *left,
    3911             :                                                    TIntermTyped *right,
    3912             :                                                    const TSourceLoc &loc)
    3913             : {
    3914           0 :     if (!binaryOpCommonCheck(op, left, right, loc))
    3915           0 :         return nullptr;
    3916             : 
    3917           0 :     switch (op)
    3918             :     {
    3919             :         case EOpEqual:
    3920             :         case EOpNotEqual:
    3921           0 :             break;
    3922             :         case EOpLessThan:
    3923             :         case EOpGreaterThan:
    3924             :         case EOpLessThanEqual:
    3925             :         case EOpGreaterThanEqual:
    3926           0 :             ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() &&
    3927             :                    !right->getType().getStruct());
    3928           0 :             if (left->isMatrix() || left->isVector())
    3929             :             {
    3930           0 :                 return nullptr;
    3931             :             }
    3932           0 :             break;
    3933             :         case EOpLogicalOr:
    3934             :         case EOpLogicalXor:
    3935             :         case EOpLogicalAnd:
    3936           0 :             ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() &&
    3937             :                    !right->getType().getStruct());
    3938           0 :             if (left->getBasicType() != EbtBool || !left->isScalar() || !right->isScalar())
    3939             :             {
    3940           0 :                 return nullptr;
    3941             :             }
    3942             :             // Basic types matching should have been already checked.
    3943           0 :             ASSERT(right->getBasicType() == EbtBool);
    3944           0 :             break;
    3945             :         case EOpAdd:
    3946             :         case EOpSub:
    3947             :         case EOpDiv:
    3948             :         case EOpMul:
    3949           0 :             ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() &&
    3950             :                    !right->getType().getStruct());
    3951           0 :             if (left->getBasicType() == EbtBool)
    3952             :             {
    3953           0 :                 return nullptr;
    3954             :             }
    3955           0 :             break;
    3956             :         case EOpIMod:
    3957           0 :             ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() &&
    3958             :                    !right->getType().getStruct());
    3959             :             // Note that this is only for the % operator, not for mod()
    3960           0 :             if (left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat)
    3961             :             {
    3962           0 :                 return nullptr;
    3963             :             }
    3964           0 :             break;
    3965             :         default:
    3966           0 :             break;
    3967             :     }
    3968             : 
    3969           0 :     if (op == EOpMul)
    3970             :     {
    3971           0 :         op = TIntermBinary::GetMulOpBasedOnOperands(left->getType(), right->getType());
    3972           0 :         if (!isMultiplicationTypeCombinationValid(op, left->getType(), right->getType()))
    3973             :         {
    3974           0 :             return nullptr;
    3975             :         }
    3976             :     }
    3977             : 
    3978           0 :     TIntermBinary *node = new TIntermBinary(op, left, right);
    3979           0 :     node->setLine(loc);
    3980             : 
    3981             :     // See if we can fold constants.
    3982           0 :     TIntermTyped *foldedNode = node->fold(&mDiagnostics);
    3983           0 :     if (foldedNode)
    3984           0 :         return foldedNode;
    3985             : 
    3986           0 :     return node;
    3987             : }
    3988             : 
    3989           0 : TIntermTyped *TParseContext::addBinaryMath(TOperator op,
    3990             :                                            TIntermTyped *left,
    3991             :                                            TIntermTyped *right,
    3992             :                                            const TSourceLoc &loc)
    3993             : {
    3994           0 :     TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
    3995           0 :     if (node == 0)
    3996             :     {
    3997           0 :         binaryOpError(loc, GetOperatorString(op), left->getCompleteString(),
    3998           0 :                       right->getCompleteString());
    3999           0 :         return left;
    4000             :     }
    4001           0 :     return node;
    4002             : }
    4003             : 
    4004           0 : TIntermTyped *TParseContext::addBinaryMathBooleanResult(TOperator op,
    4005             :                                                         TIntermTyped *left,
    4006             :                                                         TIntermTyped *right,
    4007             :                                                         const TSourceLoc &loc)
    4008             : {
    4009           0 :     TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
    4010           0 :     if (node == 0)
    4011             :     {
    4012           0 :         binaryOpError(loc, GetOperatorString(op), left->getCompleteString(),
    4013           0 :                       right->getCompleteString());
    4014           0 :         TConstantUnion *unionArray = new TConstantUnion[1];
    4015           0 :         unionArray->setBConst(false);
    4016           0 :         return intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst),
    4017           0 :                                              loc);
    4018             :     }
    4019           0 :     return node;
    4020             : }
    4021             : 
    4022           0 : TIntermBinary *TParseContext::createAssign(TOperator op,
    4023             :                                            TIntermTyped *left,
    4024             :                                            TIntermTyped *right,
    4025             :                                            const TSourceLoc &loc)
    4026             : {
    4027           0 :     if (binaryOpCommonCheck(op, left, right, loc))
    4028             :     {
    4029           0 :         if (op == EOpMulAssign)
    4030             :         {
    4031           0 :             op = TIntermBinary::GetMulAssignOpBasedOnOperands(left->getType(), right->getType());
    4032           0 :             if (!isMultiplicationTypeCombinationValid(op, left->getType(), right->getType()))
    4033             :             {
    4034           0 :                 return nullptr;
    4035             :             }
    4036             :         }
    4037           0 :         TIntermBinary *node = new TIntermBinary(op, left, right);
    4038           0 :         node->setLine(loc);
    4039             : 
    4040           0 :         return node;
    4041             :     }
    4042           0 :     return nullptr;
    4043             : }
    4044             : 
    4045           0 : TIntermTyped *TParseContext::addAssign(TOperator op,
    4046             :                                        TIntermTyped *left,
    4047             :                                        TIntermTyped *right,
    4048             :                                        const TSourceLoc &loc)
    4049             : {
    4050           0 :     TIntermTyped *node = createAssign(op, left, right, loc);
    4051           0 :     if (node == nullptr)
    4052             :     {
    4053           0 :         assignError(loc, "assign", left->getCompleteString(), right->getCompleteString());
    4054           0 :         return left;
    4055             :     }
    4056           0 :     return node;
    4057             : }
    4058             : 
    4059           0 : TIntermTyped *TParseContext::addComma(TIntermTyped *left,
    4060             :                                       TIntermTyped *right,
    4061             :                                       const TSourceLoc &loc)
    4062             : {
    4063             :     // WebGL2 section 5.26, the following results in an error:
    4064             :     // "Sequence operator applied to void, arrays, or structs containing arrays"
    4065           0 :     if (mShaderSpec == SH_WEBGL2_SPEC && (left->isArray() || left->getBasicType() == EbtVoid ||
    4066           0 :                                           left->getType().isStructureContainingArrays() ||
    4067           0 :                                           right->isArray() || right->getBasicType() == EbtVoid ||
    4068           0 :                                           right->getType().isStructureContainingArrays()))
    4069             :     {
    4070             :         error(loc,
    4071             :               "sequence operator is not allowed for void, arrays, or structs containing arrays",
    4072           0 :               ",");
    4073             :     }
    4074             : 
    4075           0 :     return TIntermediate::AddComma(left, right, loc, mShaderVersion);
    4076             : }
    4077             : 
    4078           0 : TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc)
    4079             : {
    4080           0 :     switch (op)
    4081             :     {
    4082             :         case EOpContinue:
    4083           0 :             if (mLoopNestingLevel <= 0)
    4084             :             {
    4085           0 :                 error(loc, "continue statement only allowed in loops", "");
    4086             :             }
    4087           0 :             break;
    4088             :         case EOpBreak:
    4089           0 :             if (mLoopNestingLevel <= 0 && mSwitchNestingLevel <= 0)
    4090             :             {
    4091           0 :                 error(loc, "break statement only allowed in loops and switch statements", "");
    4092             :             }
    4093           0 :             break;
    4094             :         case EOpReturn:
    4095           0 :             if (mCurrentFunctionType->getBasicType() != EbtVoid)
    4096             :             {
    4097           0 :                 error(loc, "non-void function must return a value", "return");
    4098             :             }
    4099           0 :             break;
    4100             :         default:
    4101             :             // No checks for discard
    4102           0 :             break;
    4103             :     }
    4104           0 :     return intermediate.addBranch(op, loc);
    4105             : }
    4106             : 
    4107           0 : TIntermBranch *TParseContext::addBranch(TOperator op,
    4108             :                                         TIntermTyped *returnValue,
    4109             :                                         const TSourceLoc &loc)
    4110             : {
    4111           0 :     ASSERT(op == EOpReturn);
    4112           0 :     mFunctionReturnsValue = true;
    4113           0 :     if (mCurrentFunctionType->getBasicType() == EbtVoid)
    4114             :     {
    4115           0 :         error(loc, "void function cannot return a value", "return");
    4116             :     }
    4117           0 :     else if (*mCurrentFunctionType != returnValue->getType())
    4118             :     {
    4119           0 :         error(loc, "function return is not matching type:", "return");
    4120             :     }
    4121           0 :     return intermediate.addBranch(op, returnValue, loc);
    4122             : }
    4123             : 
    4124           0 : void TParseContext::checkTextureOffsetConst(TIntermAggregate *functionCall)
    4125             : {
    4126           0 :     ASSERT(!functionCall->isUserDefined());
    4127           0 :     const TString &name        = functionCall->getFunctionSymbolInfo()->getName();
    4128           0 :     TIntermNode *offset        = nullptr;
    4129           0 :     TIntermSequence *arguments = functionCall->getSequence();
    4130           0 :     if (name.compare(0, 16, "texelFetchOffset") == 0 ||
    4131           0 :         name.compare(0, 16, "textureLodOffset") == 0 ||
    4132           0 :         name.compare(0, 20, "textureProjLodOffset") == 0 ||
    4133           0 :         name.compare(0, 17, "textureGradOffset") == 0 ||
    4134           0 :         name.compare(0, 21, "textureProjGradOffset") == 0)
    4135             :     {
    4136           0 :         offset = arguments->back();
    4137             :     }
    4138           0 :     else if (name.compare(0, 13, "textureOffset") == 0 ||
    4139           0 :              name.compare(0, 17, "textureProjOffset") == 0)
    4140             :     {
    4141             :         // A bias parameter might follow the offset parameter.
    4142           0 :         ASSERT(arguments->size() >= 3);
    4143           0 :         offset = (*arguments)[2];
    4144             :     }
    4145           0 :     if (offset != nullptr)
    4146             :     {
    4147           0 :         TIntermConstantUnion *offsetConstantUnion = offset->getAsConstantUnion();
    4148           0 :         if (offset->getAsTyped()->getQualifier() != EvqConst || !offsetConstantUnion)
    4149             :         {
    4150           0 :             TString unmangledName = TFunction::unmangleName(name);
    4151           0 :             error(functionCall->getLine(), "Texture offset must be a constant expression",
    4152           0 :                   unmangledName.c_str());
    4153             :         }
    4154             :         else
    4155             :         {
    4156           0 :             ASSERT(offsetConstantUnion->getBasicType() == EbtInt);
    4157           0 :             size_t size                  = offsetConstantUnion->getType().getObjectSize();
    4158           0 :             const TConstantUnion *values = offsetConstantUnion->getUnionArrayPointer();
    4159           0 :             for (size_t i = 0u; i < size; ++i)
    4160             :             {
    4161           0 :                 int offsetValue = values[i].getIConst();
    4162           0 :                 if (offsetValue > mMaxProgramTexelOffset || offsetValue < mMinProgramTexelOffset)
    4163             :                 {
    4164           0 :                     std::stringstream tokenStream;
    4165           0 :                     tokenStream << offsetValue;
    4166           0 :                     std::string token = tokenStream.str();
    4167           0 :                     error(offset->getLine(), "Texture offset value out of valid range",
    4168           0 :                           token.c_str());
    4169             :                 }
    4170             :             }
    4171             :         }
    4172             :     }
    4173           0 : }
    4174             : 
    4175             : // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
    4176           0 : void TParseContext::checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall)
    4177             : {
    4178           0 :     ASSERT(!functionCall->isUserDefined());
    4179           0 :     const TString &name = functionCall->getFunctionSymbolInfo()->getName();
    4180             : 
    4181           0 :     if (name.compare(0, 5, "image") == 0)
    4182             :     {
    4183           0 :         TIntermSequence *arguments = functionCall->getSequence();
    4184           0 :         TIntermNode *imageNode     = (*arguments)[0];
    4185           0 :         TIntermSymbol *imageSymbol = imageNode->getAsSymbolNode();
    4186             : 
    4187           0 :         const TMemoryQualifier &memoryQualifier = imageSymbol->getMemoryQualifier();
    4188             : 
    4189           0 :         if (name.compare(5, 5, "Store") == 0)
    4190             :         {
    4191           0 :             if (memoryQualifier.readonly)
    4192             :             {
    4193           0 :                 error(imageNode->getLine(),
    4194             :                       "'imageStore' cannot be used with images qualified as 'readonly'",
    4195           0 :                       imageSymbol->getSymbol().c_str());
    4196             :             }
    4197             :         }
    4198           0 :         else if (name.compare(5, 4, "Load") == 0)
    4199             :         {
    4200           0 :             if (memoryQualifier.writeonly)
    4201             :             {
    4202           0 :                 error(imageNode->getLine(),
    4203             :                       "'imageLoad' cannot be used with images qualified as 'writeonly'",
    4204           0 :                       imageSymbol->getSymbol().c_str());
    4205             :             }
    4206             :         }
    4207             :     }
    4208           0 : }
    4209             : 
    4210             : // GLSL ES 3.10 Revision 4, 13.51 Matching of Memory Qualifiers in Function Parameters
    4211           0 : void TParseContext::checkImageMemoryAccessForUserDefinedFunctions(
    4212             :     const TFunction *functionDefinition,
    4213             :     const TIntermAggregate *functionCall)
    4214             : {
    4215           0 :     ASSERT(functionCall->isUserDefined());
    4216             : 
    4217           0 :     const TIntermSequence &arguments = *functionCall->getSequence();
    4218             : 
    4219           0 :     ASSERT(functionDefinition->getParamCount() == arguments.size());
    4220             : 
    4221           0 :     for (size_t i = 0; i < arguments.size(); ++i)
    4222             :     {
    4223           0 :         const TType &functionArgumentType  = arguments[i]->getAsTyped()->getType();
    4224           0 :         const TType &functionParameterType = *functionDefinition->getParam(i).type;
    4225           0 :         ASSERT(functionArgumentType.getBasicType() == functionParameterType.getBasicType());
    4226             : 
    4227           0 :         if (IsImage(functionArgumentType.getBasicType()))
    4228             :         {
    4229             :             const TMemoryQualifier &functionArgumentMemoryQualifier =
    4230           0 :                 functionArgumentType.getMemoryQualifier();
    4231             :             const TMemoryQualifier &functionParameterMemoryQualifier =
    4232           0 :                 functionParameterType.getMemoryQualifier();
    4233           0 :             if (functionArgumentMemoryQualifier.readonly &&
    4234           0 :                 !functionParameterMemoryQualifier.readonly)
    4235             :             {
    4236           0 :                 error(functionCall->getLine(),
    4237             :                       "Function call discards the 'readonly' qualifier from image",
    4238           0 :                       arguments[i]->getAsSymbolNode()->getSymbol().c_str());
    4239             :             }
    4240             : 
    4241           0 :             if (functionArgumentMemoryQualifier.writeonly &&
    4242           0 :                 !functionParameterMemoryQualifier.writeonly)
    4243             :             {
    4244           0 :                 error(functionCall->getLine(),
    4245             :                       "Function call discards the 'writeonly' qualifier from image",
    4246           0 :                       arguments[i]->getAsSymbolNode()->getSymbol().c_str());
    4247             :             }
    4248             : 
    4249           0 :             if (functionArgumentMemoryQualifier.coherent &&
    4250           0 :                 !functionParameterMemoryQualifier.coherent)
    4251             :             {
    4252           0 :                 error(functionCall->getLine(),
    4253             :                       "Function call discards the 'coherent' qualifier from image",
    4254           0 :                       arguments[i]->getAsSymbolNode()->getSymbol().c_str());
    4255             :             }
    4256             : 
    4257           0 :             if (functionArgumentMemoryQualifier.volatileQualifier &&
    4258           0 :                 !functionParameterMemoryQualifier.volatileQualifier)
    4259             :             {
    4260           0 :                 error(functionCall->getLine(),
    4261             :                       "Function call discards the 'volatile' qualifier from image",
    4262           0 :                       arguments[i]->getAsSymbolNode()->getSymbol().c_str());
    4263             :             }
    4264             :         }
    4265             :     }
    4266           0 : }
    4267             : 
    4268           0 : TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall,
    4269             :                                                      TIntermNode *paramNode,
    4270             :                                                      TIntermNode *thisNode,
    4271             :                                                      const TSourceLoc &loc,
    4272             :                                                      bool *fatalError)
    4273             : {
    4274           0 :     *fatalError            = false;
    4275           0 :     TOperator op           = fnCall->getBuiltInOp();
    4276           0 :     TIntermTyped *callNode = nullptr;
    4277             : 
    4278           0 :     if (thisNode != nullptr)
    4279             :     {
    4280           0 :         TConstantUnion *unionArray = new TConstantUnion[1];
    4281           0 :         int arraySize              = 0;
    4282           0 :         TIntermTyped *typedThis = thisNode->getAsTyped();
    4283           0 :         if (fnCall->getName() != "length")
    4284             :         {
    4285           0 :             error(loc, "invalid method", fnCall->getName().c_str());
    4286             :         }
    4287           0 :         else if (paramNode != nullptr)
    4288             :         {
    4289           0 :             error(loc, "method takes no parameters", "length");
    4290             :         }
    4291           0 :         else if (typedThis == nullptr || !typedThis->isArray())
    4292             :         {
    4293           0 :             error(loc, "length can only be called on arrays", "length");
    4294             :         }
    4295             :         else
    4296             :         {
    4297           0 :             arraySize = typedThis->getArraySize();
    4298           0 :             if (typedThis->getAsSymbolNode() == nullptr)
    4299             :             {
    4300             :                 // This code path can be hit with expressions like these:
    4301             :                 // (a = b).length()
    4302             :                 // (func()).length()
    4303             :                 // (int[3](0, 1, 2)).length()
    4304             :                 // ESSL 3.00 section 5.9 defines expressions so that this is not actually a valid
    4305             :                 // expression.
    4306             :                 // It allows "An array name with the length method applied" in contrast to GLSL 4.4
    4307             :                 // spec section 5.9 which allows "An array, vector or matrix expression with the
    4308             :                 // length method applied".
    4309             :                 error(loc, "length can only be called on array names, not on array expressions",
    4310           0 :                       "length");
    4311             :             }
    4312             :         }
    4313           0 :         unionArray->setIConst(arraySize);
    4314             :         callNode =
    4315           0 :             intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), loc);
    4316             :     }
    4317           0 :     else if (op != EOpNull)
    4318             :     {
    4319             :         // Then this should be a constructor.
    4320           0 :         callNode = addConstructor(paramNode, op, fnCall, loc);
    4321             :     }
    4322             :     else
    4323             :     {
    4324             :         //
    4325             :         // Not a constructor.  Find it in the symbol table.
    4326             :         //
    4327             :         const TFunction *fnCandidate;
    4328             :         bool builtIn;
    4329           0 :         fnCandidate = findFunction(loc, fnCall, mShaderVersion, &builtIn);
    4330           0 :         if (fnCandidate)
    4331             :         {
    4332             :             //
    4333             :             // A declared function.
    4334             :             //
    4335           0 :             if (builtIn && !fnCandidate->getExtension().empty())
    4336             :             {
    4337           0 :                 checkCanUseExtension(loc, fnCandidate->getExtension());
    4338             :             }
    4339           0 :             op = fnCandidate->getBuiltInOp();
    4340           0 :             if (builtIn && op != EOpNull)
    4341             :             {
    4342             :                 //
    4343             :                 // A function call mapped to a built-in operation.
    4344             :                 //
    4345           0 :                 if (fnCandidate->getParamCount() == 1)
    4346             :                 {
    4347             :                     //
    4348             :                     // Treat it like a built-in unary operator.
    4349             :                     //
    4350           0 :                     TIntermAggregate *paramAgg = paramNode->getAsAggregate();
    4351           0 :                     paramNode                  = paramAgg->getSequence()->front();
    4352           0 :                     callNode = createUnaryMath(op, paramNode->getAsTyped(), loc,
    4353           0 :                                                &fnCandidate->getReturnType());
    4354           0 :                     if (callNode == nullptr)
    4355             :                     {
    4356           0 :                         std::stringstream extraInfoStream;
    4357             :                         extraInfoStream
    4358             :                             << "built in unary operator function.  Type: "
    4359           0 :                             << static_cast<TIntermTyped *>(paramNode)->getCompleteString();
    4360           0 :                         std::string extraInfo = extraInfoStream.str();
    4361           0 :                         error(paramNode->getLine(), " wrong operand type", "Internal Error",
    4362           0 :                               extraInfo.c_str());
    4363           0 :                         *fatalError = true;
    4364           0 :                         return nullptr;
    4365             :                     }
    4366             :                 }
    4367             :                 else
    4368             :                 {
    4369             :                     TIntermAggregate *aggregate =
    4370           0 :                         intermediate.setAggregateOperator(paramNode, op, loc);
    4371           0 :                     aggregate->setType(fnCandidate->getReturnType());
    4372           0 :                     aggregate->setPrecisionFromChildren();
    4373           0 :                     if (aggregate->areChildrenConstQualified())
    4374             :                     {
    4375           0 :                         aggregate->getTypePointer()->setQualifier(EvqConst);
    4376             :                     }
    4377             : 
    4378             :                     // Some built-in functions have out parameters too.
    4379           0 :                     functionCallLValueErrorCheck(fnCandidate, aggregate);
    4380             : 
    4381             :                     // See if we can constant fold a built-in. Note that this may be possible even
    4382             :                     // if it is not const-qualified.
    4383             :                     TIntermTyped *foldedNode =
    4384           0 :                         intermediate.foldAggregateBuiltIn(aggregate, &mDiagnostics);
    4385           0 :                     if (foldedNode)
    4386             :                     {
    4387           0 :                         callNode = foldedNode;
    4388             :                     }
    4389             :                     else
    4390             :                     {
    4391           0 :                         callNode = aggregate;
    4392             :                     }
    4393           0 :                 }
    4394             :             }
    4395             :             else
    4396             :             {
    4397             :                 // This is a real function call
    4398             :                 TIntermAggregate *aggregate =
    4399           0 :                     intermediate.setAggregateOperator(paramNode, EOpFunctionCall, loc);
    4400           0 :                 aggregate->setType(fnCandidate->getReturnType());
    4401             : 
    4402             :                 // this is how we know whether the given function is a builtIn function or a user
    4403             :                 // defined function
    4404             :                 // if builtIn == false, it's a userDefined -> could be an overloaded
    4405             :                 // builtIn function also
    4406             :                 // if builtIn == true, it's definitely a builtIn function with EOpNull
    4407           0 :                 if (!builtIn)
    4408           0 :                     aggregate->setUserDefined();
    4409           0 :                 aggregate->getFunctionSymbolInfo()->setFromFunction(*fnCandidate);
    4410             : 
    4411             :                 // This needs to happen after the function info including name is set
    4412           0 :                 if (builtIn)
    4413             :                 {
    4414           0 :                     aggregate->setBuiltInFunctionPrecision();
    4415             : 
    4416           0 :                     checkTextureOffsetConst(aggregate);
    4417             : 
    4418           0 :                     checkImageMemoryAccessForBuiltinFunctions(aggregate);
    4419             :                 }
    4420             :                 else
    4421             :                 {
    4422           0 :                     checkImageMemoryAccessForUserDefinedFunctions(fnCandidate, aggregate);
    4423             :                 }
    4424             : 
    4425           0 :                 callNode = aggregate;
    4426             : 
    4427           0 :                 functionCallLValueErrorCheck(fnCandidate, aggregate);
    4428             :             }
    4429             :         }
    4430             :         else
    4431             :         {
    4432             :             // error message was put out by findFunction()
    4433             :             // Put on a dummy node for error recovery
    4434           0 :             TConstantUnion *unionArray = new TConstantUnion[1];
    4435           0 :             unionArray->setFConst(0.0f);
    4436           0 :             callNode = intermediate.addConstantUnion(unionArray,
    4437           0 :                                                      TType(EbtFloat, EbpUndefined, EvqConst), loc);
    4438             :         }
    4439             :     }
    4440           0 :     return callNode;
    4441             : }
    4442             : 
    4443           0 : TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond,
    4444             :                                                  TIntermTyped *trueExpression,
    4445             :                                                  TIntermTyped *falseExpression,
    4446             :                                                  const TSourceLoc &loc)
    4447             : {
    4448           0 :     checkIsScalarBool(loc, cond);
    4449             : 
    4450           0 :     if (trueExpression->getType() != falseExpression->getType())
    4451             :     {
    4452           0 :         binaryOpError(loc, ":", trueExpression->getCompleteString(),
    4453           0 :                       falseExpression->getCompleteString());
    4454           0 :         return falseExpression;
    4455             :     }
    4456           0 :     if (IsOpaqueType(trueExpression->getBasicType()))
    4457             :     {
    4458             :         // ESSL 1.00 section 4.1.7
    4459             :         // ESSL 3.00 section 4.1.7
    4460             :         // Opaque/sampler types are not allowed in most types of expressions, including ternary.
    4461             :         // Note that structs containing opaque types don't need to be checked as structs are
    4462             :         // forbidden below.
    4463           0 :         error(loc, "ternary operator is not allowed for opaque types", ":");
    4464           0 :         return falseExpression;
    4465             :     }
    4466             : 
    4467             :     // ESSL1 sections 5.2 and 5.7:
    4468             :     // ESSL3 section 5.7:
    4469             :     // Ternary operator is not among the operators allowed for structures/arrays.
    4470           0 :     if (trueExpression->isArray() || trueExpression->getBasicType() == EbtStruct)
    4471             :     {
    4472           0 :         error(loc, "ternary operator is not allowed for structures or arrays", ":");
    4473           0 :         return falseExpression;
    4474             :     }
    4475             :     // WebGL2 section 5.26, the following results in an error:
    4476             :     // "Ternary operator applied to void, arrays, or structs containing arrays"
    4477           0 :     if (mShaderSpec == SH_WEBGL2_SPEC && trueExpression->getBasicType() == EbtVoid)
    4478             :     {
    4479           0 :         error(loc, "ternary operator is not allowed for void", ":");
    4480           0 :         return falseExpression;
    4481             :     }
    4482             : 
    4483           0 :     return TIntermediate::AddTernarySelection(cond, trueExpression, falseExpression, loc);
    4484             : }
    4485             : 
    4486             : //
    4487             : // Parse an array of strings using yyparse.
    4488             : //
    4489             : // Returns 0 for success.
    4490             : //
    4491           0 : int PaParseStrings(size_t count,
    4492             :                    const char *const string[],
    4493             :                    const int length[],
    4494             :                    TParseContext *context)
    4495             : {
    4496           0 :     if ((count == 0) || (string == NULL))
    4497           0 :         return 1;
    4498             : 
    4499           0 :     if (glslang_initialize(context))
    4500           0 :         return 1;
    4501             : 
    4502           0 :     int error = glslang_scan(count, string, length, context);
    4503           0 :     if (!error)
    4504           0 :         error = glslang_parse(context);
    4505             : 
    4506           0 :     glslang_finalize(context);
    4507             : 
    4508           0 :     return (error == 0) && (context->numErrors() == 0) ? 0 : 1;
    4509             : }
    4510             : 
    4511             : }  // namespace sh

Generated by: LCOV version 1.13