• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2002 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 "common/mathutil.h"
13 #include "common/utilities.h"
14 #include "compiler/preprocessor/SourceLocation.h"
15 #include "compiler/translator/Declarator.h"
16 #include "compiler/translator/StaticType.h"
17 #include "compiler/translator/ValidateGlobalInitializer.h"
18 #include "compiler/translator/ValidateSwitch.h"
19 #include "compiler/translator/glslang.h"
20 #include "compiler/translator/tree_util/IntermNode_util.h"
21 #include "compiler/translator/util.h"
22 
23 namespace sh
24 {
25 
26 ///////////////////////////////////////////////////////////////////////
27 //
28 // Sub- vector and matrix fields
29 //
30 ////////////////////////////////////////////////////////////////////////
31 
32 namespace
33 {
34 
35 const int kWebGLMaxStructNesting = 4;
36 
37 bool ContainsSampler(const TStructure *structType);
38 
ContainsSampler(const TType & type)39 bool ContainsSampler(const TType &type)
40 {
41     if (IsSampler(type.getBasicType()))
42     {
43         return true;
44     }
45     if (type.getBasicType() == EbtStruct)
46     {
47         return ContainsSampler(type.getStruct());
48     }
49 
50     return false;
51 }
52 
ContainsSampler(const TStructure * structType)53 bool ContainsSampler(const TStructure *structType)
54 {
55     for (const auto &field : structType->fields())
56     {
57         if (ContainsSampler(*field->type()))
58             return true;
59     }
60     return false;
61 }
62 
63 // Get a token from an image argument to use as an error message token.
GetImageArgumentToken(TIntermTyped * imageNode)64 const char *GetImageArgumentToken(TIntermTyped *imageNode)
65 {
66     ASSERT(IsImage(imageNode->getBasicType()));
67     while (imageNode->getAsBinaryNode() &&
68            (imageNode->getAsBinaryNode()->getOp() == EOpIndexIndirect ||
69             imageNode->getAsBinaryNode()->getOp() == EOpIndexDirect))
70     {
71         imageNode = imageNode->getAsBinaryNode()->getLeft();
72     }
73     TIntermSymbol *imageSymbol = imageNode->getAsSymbolNode();
74     if (imageSymbol)
75     {
76         return imageSymbol->getName().data();
77     }
78     return "image";
79 }
80 
CanSetDefaultPrecisionOnType(const TPublicType & type)81 bool CanSetDefaultPrecisionOnType(const TPublicType &type)
82 {
83     if (!SupportsPrecision(type.getBasicType()))
84     {
85         return false;
86     }
87     if (type.getBasicType() == EbtUInt)
88     {
89         // ESSL 3.00.4 section 4.5.4
90         return false;
91     }
92     if (type.isAggregate())
93     {
94         // Not allowed to set for aggregate types
95         return false;
96     }
97     return true;
98 }
99 
100 // Map input primitive types to input array sizes in a geometry shader.
GetGeometryShaderInputArraySize(TLayoutPrimitiveType primitiveType)101 GLuint GetGeometryShaderInputArraySize(TLayoutPrimitiveType primitiveType)
102 {
103     switch (primitiveType)
104     {
105         case EptPoints:
106             return 1u;
107         case EptLines:
108             return 2u;
109         case EptTriangles:
110             return 3u;
111         case EptLinesAdjacency:
112             return 4u;
113         case EptTrianglesAdjacency:
114             return 6u;
115         default:
116             UNREACHABLE();
117             return 0u;
118     }
119 }
120 
IsBufferOrSharedVariable(TIntermTyped * var)121 bool IsBufferOrSharedVariable(TIntermTyped *var)
122 {
123     if (var->isInterfaceBlock() || var->getQualifier() == EvqBuffer ||
124         var->getQualifier() == EvqShared)
125     {
126         return true;
127     }
128     return false;
129 }
130 
FindLValueBase(TIntermTyped * node)131 TIntermTyped *FindLValueBase(TIntermTyped *node)
132 {
133     do
134     {
135         const TIntermBinary *binary = node->getAsBinaryNode();
136         if (binary == nullptr)
137         {
138             return node;
139         }
140 
141         TOperator op = binary->getOp();
142         if (op != EOpIndexDirect && op != EOpIndexIndirect)
143         {
144             return static_cast<TIntermTyped *>(nullptr);
145         }
146 
147         node = binary->getLeft();
148     } while (true);
149 }
150 
AddAdvancedBlendEquation(gl::BlendEquationType eq,TLayoutQualifier * qualifier)151 void AddAdvancedBlendEquation(gl::BlendEquationType eq, TLayoutQualifier *qualifier)
152 {
153     qualifier->advancedBlendEquations.set(static_cast<uint32_t>(eq));
154 }
155 
IsValidWithPixelLocalStorage(TLayoutImageInternalFormat internalFormat)156 constexpr bool IsValidWithPixelLocalStorage(TLayoutImageInternalFormat internalFormat)
157 {
158     switch (internalFormat)
159     {
160         case EiifRGBA8:
161         case EiifRGBA8I:
162         case EiifRGBA8UI:
163         case EiifR32F:
164         case EiifR32UI:
165             return true;
166         default:
167             return false;
168     }
169 }
170 }  // namespace
171 
172 // This tracks each binding point's current default offset for inheritance of subsequent
173 // variables using the same binding, and keeps offsets unique and non overlapping.
174 // See GLSL ES 3.1, section 4.4.6.
175 class TParseContext::AtomicCounterBindingState
176 {
177   public:
AtomicCounterBindingState()178     AtomicCounterBindingState() : mDefaultOffset(0) {}
179     // Inserts a new span and returns -1 if overlapping, else returns the starting offset of
180     // newly inserted span.
insertSpan(int start,size_t length)181     int insertSpan(int start, size_t length)
182     {
183         gl::RangeI newSpan(start, start + static_cast<int>(length));
184         for (const auto &span : mSpans)
185         {
186             if (newSpan.intersects(span))
187             {
188                 return -1;
189             }
190         }
191         mSpans.push_back(newSpan);
192         mDefaultOffset = newSpan.high();
193         return start;
194     }
195     // Inserts a new span starting from the default offset.
appendSpan(size_t length)196     int appendSpan(size_t length) { return insertSpan(mDefaultOffset, length); }
setDefaultOffset(int offset)197     void setDefaultOffset(int offset) { mDefaultOffset = offset; }
198 
199   private:
200     int mDefaultOffset;
201     std::vector<gl::RangeI> mSpans;
202 };
203 
TParseContext(TSymbolTable & symt,TExtensionBehavior & ext,sh::GLenum type,ShShaderSpec spec,const ShCompileOptions & options,bool checksPrecErrors,TDiagnostics * diagnostics,const ShBuiltInResources & resources,ShShaderOutput outputType)204 TParseContext::TParseContext(TSymbolTable &symt,
205                              TExtensionBehavior &ext,
206                              sh::GLenum type,
207                              ShShaderSpec spec,
208                              const ShCompileOptions &options,
209                              bool checksPrecErrors,
210                              TDiagnostics *diagnostics,
211                              const ShBuiltInResources &resources,
212                              ShShaderOutput outputType)
213     : symbolTable(symt),
214       mDeferredNonEmptyDeclarationErrorCheck(false),
215       mShaderType(type),
216       mShaderSpec(spec),
217       mCompileOptions(options),
218       mShaderVersion(100),
219       mTreeRoot(nullptr),
220       mLoopNestingLevel(0),
221       mStructNestingLevel(0),
222       mSwitchNestingLevel(0),
223       mCurrentFunctionType(nullptr),
224       mFunctionReturnsValue(false),
225       mChecksPrecisionErrors(checksPrecErrors),
226       mFragmentPrecisionHighOnESSL1(false),
227       mEarlyFragmentTestsSpecified(false),
228       mHasDiscard(false),
229       mSampleQualifierSpecified(false),
230       mPositionRedeclaredForSeparateShaderObject(false),
231       mPointSizeRedeclaredForSeparateShaderObject(false),
232       mPositionOrPointSizeUsedForSeparateShaderObject(false),
233       mDefaultUniformMatrixPacking(EmpColumnMajor),
234       mDefaultUniformBlockStorage(sh::IsWebGLBasedSpec(spec) ? EbsStd140 : EbsShared),
235       mDefaultBufferMatrixPacking(EmpColumnMajor),
236       mDefaultBufferBlockStorage(sh::IsWebGLBasedSpec(spec) ? EbsStd140 : EbsShared),
237       mDiagnostics(diagnostics),
238       mDirectiveHandler(ext, *mDiagnostics, mShaderVersion, mShaderType),
239       mPreprocessor(mDiagnostics, &mDirectiveHandler, angle::pp::PreprocessorSettings(spec)),
240       mScanner(nullptr),
241       mMinProgramTexelOffset(resources.MinProgramTexelOffset),
242       mMaxProgramTexelOffset(resources.MaxProgramTexelOffset),
243       mMinProgramTextureGatherOffset(resources.MinProgramTextureGatherOffset),
244       mMaxProgramTextureGatherOffset(resources.MaxProgramTextureGatherOffset),
245       mComputeShaderLocalSizeDeclared(false),
246       mComputeShaderLocalSize(-1),
247       mNumViews(-1),
248       mMaxNumViews(resources.MaxViewsOVR),
249       mMaxImageUnits(resources.MaxImageUnits),
250       mMaxCombinedTextureImageUnits(resources.MaxCombinedTextureImageUnits),
251       mMaxUniformLocations(resources.MaxUniformLocations),
252       mMaxUniformBufferBindings(resources.MaxUniformBufferBindings),
253       mMaxVertexAttribs(resources.MaxVertexAttribs),
254       mMaxAtomicCounterBindings(resources.MaxAtomicCounterBindings),
255       mMaxShaderStorageBufferBindings(resources.MaxShaderStorageBufferBindings),
256       mDeclaringFunction(false),
257       mGeometryShaderInputPrimitiveType(EptUndefined),
258       mGeometryShaderOutputPrimitiveType(EptUndefined),
259       mGeometryShaderInvocations(0),
260       mGeometryShaderMaxVertices(-1),
261       mMaxGeometryShaderInvocations(resources.MaxGeometryShaderInvocations),
262       mMaxGeometryShaderMaxVertices(resources.MaxGeometryOutputVertices),
263       mGeometryInputArraySize(0),
264       mMaxPatchVertices(resources.MaxPatchVertices),
265       mTessControlShaderOutputVertices(0),
266       mTessEvaluationShaderInputPrimitiveType(EtetUndefined),
267       mTessEvaluationShaderInputVertexSpacingType(EtetUndefined),
268       mTessEvaluationShaderInputOrderingType(EtetUndefined),
269       mTessEvaluationShaderInputPointType(EtetUndefined),
270       mHasAnyPreciseType(false),
271       mAdvancedBlendEquations(0),
272       mFunctionBodyNewScope(false),
273       mOutputType(outputType)
274 {}
275 
~TParseContext()276 TParseContext::~TParseContext() {}
277 
anyMultiviewExtensionAvailable()278 bool TParseContext::anyMultiviewExtensionAvailable()
279 {
280     return isExtensionEnabled(TExtension::OVR_multiview) ||
281            isExtensionEnabled(TExtension::OVR_multiview2);
282 }
283 
parseVectorFields(const TSourceLoc & line,const ImmutableString & compString,int vecSize,TVector<int> * fieldOffsets)284 bool TParseContext::parseVectorFields(const TSourceLoc &line,
285                                       const ImmutableString &compString,
286                                       int vecSize,
287                                       TVector<int> *fieldOffsets)
288 {
289     ASSERT(fieldOffsets);
290     size_t fieldCount = compString.length();
291     if (fieldCount > 4u)
292     {
293         error(line, "illegal vector field selection", compString);
294         return false;
295     }
296     fieldOffsets->resize(fieldCount);
297 
298     enum
299     {
300         exyzw,
301         ergba,
302         estpq
303     } fieldSet[4];
304 
305     for (unsigned int i = 0u; i < fieldOffsets->size(); ++i)
306     {
307         switch (compString[i])
308         {
309             case 'x':
310                 (*fieldOffsets)[i] = 0;
311                 fieldSet[i]        = exyzw;
312                 break;
313             case 'r':
314                 (*fieldOffsets)[i] = 0;
315                 fieldSet[i]        = ergba;
316                 break;
317             case 's':
318                 (*fieldOffsets)[i] = 0;
319                 fieldSet[i]        = estpq;
320                 break;
321             case 'y':
322                 (*fieldOffsets)[i] = 1;
323                 fieldSet[i]        = exyzw;
324                 break;
325             case 'g':
326                 (*fieldOffsets)[i] = 1;
327                 fieldSet[i]        = ergba;
328                 break;
329             case 't':
330                 (*fieldOffsets)[i] = 1;
331                 fieldSet[i]        = estpq;
332                 break;
333             case 'z':
334                 (*fieldOffsets)[i] = 2;
335                 fieldSet[i]        = exyzw;
336                 break;
337             case 'b':
338                 (*fieldOffsets)[i] = 2;
339                 fieldSet[i]        = ergba;
340                 break;
341             case 'p':
342                 (*fieldOffsets)[i] = 2;
343                 fieldSet[i]        = estpq;
344                 break;
345 
346             case 'w':
347                 (*fieldOffsets)[i] = 3;
348                 fieldSet[i]        = exyzw;
349                 break;
350             case 'a':
351                 (*fieldOffsets)[i] = 3;
352                 fieldSet[i]        = ergba;
353                 break;
354             case 'q':
355                 (*fieldOffsets)[i] = 3;
356                 fieldSet[i]        = estpq;
357                 break;
358             default:
359                 error(line, "illegal vector field selection", compString);
360                 return false;
361         }
362     }
363 
364     for (unsigned int i = 0u; i < fieldOffsets->size(); ++i)
365     {
366         if ((*fieldOffsets)[i] >= vecSize)
367         {
368             error(line, "vector field selection out of range", compString);
369             return false;
370         }
371 
372         if (i > 0)
373         {
374             if (fieldSet[i] != fieldSet[i - 1])
375             {
376                 error(line, "illegal - vector component fields not from the same set", compString);
377                 return false;
378             }
379         }
380     }
381 
382     return true;
383 }
384 
385 ///////////////////////////////////////////////////////////////////////
386 //
387 // Errors
388 //
389 ////////////////////////////////////////////////////////////////////////
390 
391 //
392 // Used by flex/bison to output all syntax and parsing errors.
393 //
error(const TSourceLoc & loc,const char * reason,const char * token)394 void TParseContext::error(const TSourceLoc &loc, const char *reason, const char *token)
395 {
396     mDiagnostics->error(loc, reason, token);
397 }
398 
error(const TSourceLoc & loc,const char * reason,const ImmutableString & token)399 void TParseContext::error(const TSourceLoc &loc, const char *reason, const ImmutableString &token)
400 {
401     mDiagnostics->error(loc, reason, token.data());
402 }
403 
warning(const TSourceLoc & loc,const char * reason,const char * token)404 void TParseContext::warning(const TSourceLoc &loc, const char *reason, const char *token)
405 {
406     mDiagnostics->warning(loc, reason, token);
407 }
408 
errorIfPLSDeclared(const TSourceLoc & loc,PLSIllegalOperations op)409 void TParseContext::errorIfPLSDeclared(const TSourceLoc &loc, PLSIllegalOperations op)
410 {
411     if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
412     {
413         return;
414     }
415     if (mPLSBindings.empty())
416     {
417         // No pixel local storage uniforms have been declared yet. Remember this potential error in
418         // case PLS gets declared later.
419         mPLSPotentialErrors.emplace_back(loc, op);
420         return;
421     }
422     switch (op)
423     {
424         case PLSIllegalOperations::Discard:
425             error(loc, "illegal discard when pixel local storage is declared", "discard");
426             break;
427         case PLSIllegalOperations::ReturnFromMain:
428             error(loc, "illegal return from main when pixel local storage is declared", "return");
429             break;
430         case PLSIllegalOperations::AssignFragDepth:
431             error(loc, "value not assignable when pixel local storage is declared", "gl_FragDepth");
432             break;
433         case PLSIllegalOperations::AssignSampleMask:
434             error(loc, "value not assignable when pixel local storage is declared",
435                   "gl_SampleMask");
436             break;
437         case PLSIllegalOperations::FragDataIndexNonzero:
438             error(loc, "illegal nonzero index qualifier when pixel local storage is declared",
439                   "layout");
440             break;
441         case PLSIllegalOperations::EnableAdvancedBlendEquation:
442             error(loc, "illegal advanced blend equation when pixel local storage is declared",
443                   "layout");
444             break;
445     }
446 }
447 
outOfRangeError(bool isError,const TSourceLoc & loc,const char * reason,const char * token)448 void TParseContext::outOfRangeError(bool isError,
449                                     const TSourceLoc &loc,
450                                     const char *reason,
451                                     const char *token)
452 {
453     if (isError)
454     {
455         error(loc, reason, token);
456     }
457     else
458     {
459         warning(loc, reason, token);
460     }
461 }
462 
setTreeRoot(TIntermBlock * treeRoot)463 void TParseContext::setTreeRoot(TIntermBlock *treeRoot)
464 {
465     mTreeRoot = treeRoot;
466     mTreeRoot->setIsTreeRoot();
467 }
468 
469 //
470 // Same error message for all places assignments don't work.
471 //
assignError(const TSourceLoc & line,const char * op,const TType & left,const TType & right)472 void TParseContext::assignError(const TSourceLoc &line,
473                                 const char *op,
474                                 const TType &left,
475                                 const TType &right)
476 {
477     TInfoSinkBase reasonStream;
478     reasonStream << "cannot convert from '" << right << "' to '" << left << "'";
479     error(line, reasonStream.c_str(), op);
480 }
481 
482 //
483 // Same error message for all places unary operations don't work.
484 //
unaryOpError(const TSourceLoc & line,const char * op,const TType & operand)485 void TParseContext::unaryOpError(const TSourceLoc &line, const char *op, const TType &operand)
486 {
487     TInfoSinkBase reasonStream;
488     reasonStream << "wrong operand type - no operation '" << op
489                  << "' exists that takes an operand of type " << operand
490                  << " (or there is no acceptable conversion)";
491     error(line, reasonStream.c_str(), op);
492 }
493 
494 //
495 // Same error message for all binary operations don't work.
496 //
binaryOpError(const TSourceLoc & line,const char * op,const TType & left,const TType & right)497 void TParseContext::binaryOpError(const TSourceLoc &line,
498                                   const char *op,
499                                   const TType &left,
500                                   const TType &right)
501 {
502     TInfoSinkBase reasonStream;
503     reasonStream << "wrong operand types - no operation '" << op
504                  << "' exists that takes a left-hand operand of type '" << left
505                  << "' and a right operand of type '" << right
506                  << "' (or there is no acceptable conversion)";
507     error(line, reasonStream.c_str(), op);
508 }
509 
checkPrecisionSpecified(const TSourceLoc & line,TPrecision precision,TBasicType type)510 void TParseContext::checkPrecisionSpecified(const TSourceLoc &line,
511                                             TPrecision precision,
512                                             TBasicType type)
513 {
514     if (!mChecksPrecisionErrors)
515         return;
516 
517     if (precision != EbpUndefined && !SupportsPrecision(type))
518     {
519         error(line, "illegal type for precision qualifier", getBasicString(type));
520     }
521 
522     if (precision == EbpUndefined)
523     {
524         switch (type)
525         {
526             case EbtFloat:
527                 error(line, "No precision specified for (float)", "");
528                 return;
529             case EbtInt:
530             case EbtUInt:
531                 UNREACHABLE();  // there's always a predeclared qualifier
532                 error(line, "No precision specified (int)", "");
533                 return;
534             default:
535                 if (IsOpaqueType(type))
536                 {
537                     error(line, "No precision specified", getBasicString(type));
538                     return;
539                 }
540         }
541     }
542 }
543 
markStaticReadIfSymbol(TIntermNode * node)544 void TParseContext::markStaticReadIfSymbol(TIntermNode *node)
545 {
546     TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
547     if (swizzleNode)
548     {
549         markStaticReadIfSymbol(swizzleNode->getOperand());
550         return;
551     }
552     TIntermBinary *binaryNode = node->getAsBinaryNode();
553     if (binaryNode)
554     {
555         switch (binaryNode->getOp())
556         {
557             case EOpIndexDirect:
558             case EOpIndexIndirect:
559             case EOpIndexDirectStruct:
560             case EOpIndexDirectInterfaceBlock:
561                 markStaticReadIfSymbol(binaryNode->getLeft());
562                 return;
563             default:
564                 return;
565         }
566     }
567     TIntermSymbol *symbolNode = node->getAsSymbolNode();
568     if (symbolNode)
569     {
570         symbolTable.markStaticRead(symbolNode->variable());
571     }
572 }
573 
574 // Both test and if necessary, spit out an error, to see if the node is really
575 // an l-value that can be operated on this way.
checkCanBeLValue(const TSourceLoc & line,const char * op,TIntermTyped * node)576 bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIntermTyped *node)
577 {
578     TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
579     if (swizzleNode)
580     {
581         bool ok = checkCanBeLValue(line, op, swizzleNode->getOperand());
582         if (ok && swizzleNode->hasDuplicateOffsets())
583         {
584             error(line, " l-value of swizzle cannot have duplicate components", op);
585             return false;
586         }
587         return ok;
588     }
589 
590     TIntermBinary *binaryNode = node->getAsBinaryNode();
591     if (binaryNode)
592     {
593         switch (binaryNode->getOp())
594         {
595             case EOpIndexDirect:
596             case EOpIndexIndirect:
597             case EOpIndexDirectStruct:
598             case EOpIndexDirectInterfaceBlock:
599                 if (node->getMemoryQualifier().readonly)
600                 {
601                     error(line, "can't modify a readonly variable", op);
602                     return false;
603                 }
604                 return checkCanBeLValue(line, op, binaryNode->getLeft());
605             default:
606                 break;
607         }
608         error(line, " l-value required", op);
609         return false;
610     }
611 
612     std::string message;
613     switch (node->getQualifier())
614     {
615         case EvqConst:
616             message = "can't modify a const";
617             break;
618         case EvqParamConst:
619             message = "can't modify a const";
620             break;
621         case EvqAttribute:
622             message = "can't modify an attribute";
623             break;
624         case EvqFragmentIn:
625         case EvqVertexIn:
626         case EvqGeometryIn:
627         case EvqTessControlIn:
628         case EvqTessEvaluationIn:
629         case EvqSmoothIn:
630         case EvqFlatIn:
631         case EvqNoPerspectiveIn:
632         case EvqCentroidIn:
633         case EvqSampleIn:
634         case EvqNoPerspectiveCentroidIn:
635         case EvqNoPerspectiveSampleIn:
636             message = "can't modify an input";
637             break;
638         case EvqUniform:
639             message = "can't modify a uniform";
640             break;
641         case EvqVaryingIn:
642             message = "can't modify a varying";
643             break;
644         case EvqFragCoord:
645             message = "can't modify gl_FragCoord";
646             break;
647         case EvqFrontFacing:
648             message = "can't modify gl_FrontFacing";
649             break;
650         case EvqHelperInvocation:
651             message = "can't modify gl_HelperInvocation";
652             break;
653         case EvqPointCoord:
654             message = "can't modify gl_PointCoord";
655             break;
656         case EvqNumWorkGroups:
657             message = "can't modify gl_NumWorkGroups";
658             break;
659         case EvqWorkGroupSize:
660             message = "can't modify gl_WorkGroupSize";
661             break;
662         case EvqWorkGroupID:
663             message = "can't modify gl_WorkGroupID";
664             break;
665         case EvqLocalInvocationID:
666             message = "can't modify gl_LocalInvocationID";
667             break;
668         case EvqGlobalInvocationID:
669             message = "can't modify gl_GlobalInvocationID";
670             break;
671         case EvqLocalInvocationIndex:
672             message = "can't modify gl_LocalInvocationIndex";
673             break;
674         case EvqViewIDOVR:
675             message = "can't modify gl_ViewID_OVR";
676             break;
677         case EvqComputeIn:
678             message = "can't modify work group size variable";
679             break;
680         case EvqPerVertexIn:
681             message = "can't modify any member in gl_in";
682             break;
683         case EvqPrimitiveIDIn:
684             message = "can't modify gl_PrimitiveIDIn";
685             break;
686         case EvqInvocationID:
687             message = "can't modify gl_InvocationID";
688             break;
689         case EvqPrimitiveID:
690             if (mShaderType == GL_FRAGMENT_SHADER)
691             {
692                 message = "can't modify gl_PrimitiveID in a fragment shader";
693             }
694             break;
695         case EvqLayerIn:
696             message = "can't modify gl_Layer in a fragment shader";
697             break;
698         case EvqSampleID:
699             message = "can't modify gl_SampleID";
700             break;
701         case EvqSampleMaskIn:
702             message = "can't modify gl_SampleMaskIn";
703             break;
704         case EvqSamplePosition:
705             message = "can't modify gl_SamplePosition";
706             break;
707         case EvqClipDistance:
708             if (mShaderType == GL_FRAGMENT_SHADER)
709             {
710                 message = "can't modify gl_ClipDistance in a fragment shader";
711             }
712             break;
713         case EvqCullDistance:
714             if (mShaderType == GL_FRAGMENT_SHADER)
715             {
716                 message = "can't modify gl_CullDistance in a fragment shader";
717             }
718             break;
719         case EvqFragDepth:
720             errorIfPLSDeclared(line, PLSIllegalOperations::AssignFragDepth);
721             break;
722         case EvqSampleMask:
723             errorIfPLSDeclared(line, PLSIllegalOperations::AssignSampleMask);
724             break;
725         default:
726             //
727             // Type that can't be written to?
728             //
729             if (node->getBasicType() == EbtVoid)
730             {
731                 message = "can't modify void";
732             }
733             if (IsOpaqueType(node->getBasicType()))
734             {
735                 message = "can't modify a variable with type ";
736                 message += getBasicString(node->getBasicType());
737             }
738             else if (node->getMemoryQualifier().readonly)
739             {
740                 message = "can't modify a readonly variable";
741             }
742     }
743 
744     ASSERT(binaryNode == nullptr && swizzleNode == nullptr);
745     TIntermSymbol *symNode = node->getAsSymbolNode();
746     if (message.empty() && symNode != nullptr)
747     {
748         symbolTable.markStaticWrite(symNode->variable());
749         return true;
750     }
751 
752     std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
753     reasonStream << "l-value required";
754     if (!message.empty())
755     {
756         if (symNode)
757         {
758             // Symbol inside an expression can't be nameless.
759             ASSERT(symNode->variable().symbolType() != SymbolType::Empty);
760             const ImmutableString &symbol = symNode->getName();
761             reasonStream << " (" << message << " \"" << symbol << "\")";
762         }
763         else
764         {
765             reasonStream << " (" << message << ")";
766         }
767     }
768     std::string reason = reasonStream.str();
769     error(line, reason.c_str(), op);
770 
771     return false;
772 }
773 
774 // Both test, and if necessary spit out an error, to see if the node is really
775 // a constant.
checkIsConst(TIntermTyped * node)776 void TParseContext::checkIsConst(TIntermTyped *node)
777 {
778     if (node->getQualifier() != EvqConst)
779     {
780         error(node->getLine(), "constant expression required", "");
781     }
782 }
783 
784 // Both test, and if necessary spit out an error, to see if the node is really
785 // an integer.
checkIsScalarInteger(TIntermTyped * node,const char * token)786 void TParseContext::checkIsScalarInteger(TIntermTyped *node, const char *token)
787 {
788     if (!node->isScalarInt())
789     {
790         error(node->getLine(), "integer expression required", token);
791     }
792 }
793 
794 // Both test, and if necessary spit out an error, to see if we are currently
795 // globally scoped.
checkIsAtGlobalLevel(const TSourceLoc & line,const char * token)796 bool TParseContext::checkIsAtGlobalLevel(const TSourceLoc &line, const char *token)
797 {
798     if (!symbolTable.atGlobalLevel())
799     {
800         error(line, "only allowed at global scope", token);
801         return false;
802     }
803     return true;
804 }
805 
806 // ESSL 3.00.5 sections 3.8 and 3.9.
807 // If it starts "gl_" or contains two consecutive underscores, it's reserved.
808 // Also checks for "webgl_" and "_webgl_" reserved identifiers if parsing a webgl shader.
checkIsNotReserved(const TSourceLoc & line,const ImmutableString & identifier)809 bool TParseContext::checkIsNotReserved(const TSourceLoc &line, const ImmutableString &identifier)
810 {
811     static const char *reservedErrMsg = "reserved built-in name";
812     if (gl::IsBuiltInName(identifier.data()))
813     {
814         error(line, reservedErrMsg, "gl_");
815         return false;
816     }
817     if (sh::IsWebGLBasedSpec(mShaderSpec))
818     {
819         if (identifier.beginsWith("webgl_"))
820         {
821             error(line, reservedErrMsg, "webgl_");
822             return false;
823         }
824         if (identifier.beginsWith("_webgl_"))
825         {
826             error(line, reservedErrMsg, "_webgl_");
827             return false;
828         }
829     }
830     if (identifier.contains("__"))
831     {
832         if (sh::IsWebGLBasedSpec(mShaderSpec))
833         {
834             error(line,
835                   "identifiers containing two consecutive underscores (__) are reserved as "
836                   "possible future keywords",
837                   identifier);
838             return false;
839         }
840         else
841         {
842             // Using double underscores is allowed, but may result in unintended behaviors, so a
843             // warning is issued.
844             // OpenGL ES Shader Language 3.2 specification:
845             // > 3.7. Keywords
846             // > ...
847             // > In addition, all identifiers containing two consecutive underscores (__) are
848             // > reserved for use by underlying software layers. Defining such a name in a shader
849             // > does not itself result in an error, but may result in unintended behaviors that
850             // > stem from having multiple definitions of the same name.
851             warning(line,
852                     "all identifiers containing two consecutive underscores (__) are reserved - "
853                     "unintented behaviors are possible",
854                     identifier.data());
855         }
856     }
857     return true;
858 }
859 
860 // Make sure the argument types are correct for constructing a specific type.
checkConstructorArguments(const TSourceLoc & line,const TIntermSequence & arguments,const TType & type)861 bool TParseContext::checkConstructorArguments(const TSourceLoc &line,
862                                               const TIntermSequence &arguments,
863                                               const TType &type)
864 {
865     if (arguments.empty())
866     {
867         error(line, "constructor does not have any arguments", "constructor");
868         return false;
869     }
870 
871     for (TIntermNode *arg : arguments)
872     {
873         markStaticReadIfSymbol(arg);
874         const TIntermTyped *argTyped = arg->getAsTyped();
875         ASSERT(argTyped != nullptr);
876         if (type.getBasicType() != EbtStruct && IsOpaqueType(argTyped->getBasicType()))
877         {
878             std::string reason("cannot convert a variable with type ");
879             reason += getBasicString(argTyped->getBasicType());
880             error(line, reason.c_str(), "constructor");
881             return false;
882         }
883         else if (argTyped->getMemoryQualifier().writeonly)
884         {
885             error(line, "cannot convert a variable with writeonly", "constructor");
886             return false;
887         }
888         if (argTyped->getBasicType() == EbtVoid)
889         {
890             error(line, "cannot convert a void", "constructor");
891             return false;
892         }
893     }
894 
895     if (type.isArray())
896     {
897         // The size of an unsized constructor should already have been determined.
898         ASSERT(!type.isUnsizedArray());
899         if (static_cast<size_t>(type.getOutermostArraySize()) != arguments.size())
900         {
901             error(line, "array constructor needs one argument per array element", "constructor");
902             return false;
903         }
904         // GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of
905         // the array.
906         for (TIntermNode *const &argNode : arguments)
907         {
908             const TType &argType = argNode->getAsTyped()->getType();
909             if (mShaderVersion < 310 && argType.isArray())
910             {
911                 error(line, "constructing from a non-dereferenced array", "constructor");
912                 return false;
913             }
914             if (!argType.isElementTypeOf(type))
915             {
916                 error(line, "Array constructor argument has an incorrect type", "constructor");
917                 return false;
918             }
919         }
920     }
921     else if (type.getBasicType() == EbtStruct)
922     {
923         const TFieldList &fields = type.getStruct()->fields();
924         if (fields.size() != arguments.size())
925         {
926             error(line,
927                   "Number of constructor parameters does not match the number of structure fields",
928                   "constructor");
929             return false;
930         }
931 
932         for (size_t i = 0; i < fields.size(); i++)
933         {
934             if (i >= arguments.size() ||
935                 arguments[i]->getAsTyped()->getType() != *fields[i]->type())
936             {
937                 error(line, "Structure constructor arguments do not match structure fields",
938                       "constructor");
939                 return false;
940             }
941         }
942     }
943     else
944     {
945         // We're constructing a scalar, vector, or matrix.
946 
947         // Note: It's okay to have too many components available, but not okay to have unused
948         // arguments. 'full' will go to true when enough args have been seen. If we loop again,
949         // there is an extra argument, so 'overFull' will become true.
950 
951         size_t size    = 0;
952         bool full      = false;
953         bool overFull  = false;
954         bool matrixArg = false;
955         for (TIntermNode *arg : arguments)
956         {
957             const TIntermTyped *argTyped = arg->getAsTyped();
958             ASSERT(argTyped != nullptr);
959 
960             if (argTyped->getBasicType() == EbtStruct)
961             {
962                 error(line, "a struct cannot be used as a constructor argument for this type",
963                       "constructor");
964                 return false;
965             }
966             if (argTyped->getType().isArray())
967             {
968                 error(line, "constructing from a non-dereferenced array", "constructor");
969                 return false;
970             }
971             if (argTyped->getType().isMatrix())
972             {
973                 matrixArg = true;
974             }
975 
976             size += argTyped->getType().getObjectSize();
977             if (full)
978             {
979                 overFull = true;
980             }
981             if (size >= type.getObjectSize())
982             {
983                 full = true;
984             }
985         }
986 
987         if (type.isMatrix() && matrixArg)
988         {
989             if (arguments.size() != 1)
990             {
991                 error(line, "constructing matrix from matrix can only take one argument",
992                       "constructor");
993                 return false;
994             }
995         }
996         else
997         {
998             if (size != 1 && size < type.getObjectSize())
999             {
1000                 error(line, "not enough data provided for construction", "constructor");
1001                 return false;
1002             }
1003             if (overFull)
1004             {
1005                 error(line, "too many arguments", "constructor");
1006                 return false;
1007             }
1008         }
1009     }
1010 
1011     return true;
1012 }
1013 
1014 // This function checks to see if a void variable has been declared and raise an error message for
1015 // such a case
1016 //
1017 // returns true in case of an error
1018 //
checkIsNonVoid(const TSourceLoc & line,const ImmutableString & identifier,const TBasicType & type)1019 bool TParseContext::checkIsNonVoid(const TSourceLoc &line,
1020                                    const ImmutableString &identifier,
1021                                    const TBasicType &type)
1022 {
1023     if (type == EbtVoid)
1024     {
1025         error(line, "illegal use of type 'void'", identifier);
1026         return false;
1027     }
1028 
1029     return true;
1030 }
1031 
1032 // This function checks to see if the node (for the expression) contains a scalar boolean expression
1033 // or not.
checkIsScalarBool(const TSourceLoc & line,const TIntermTyped * type)1034 bool TParseContext::checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type)
1035 {
1036     if (type->getBasicType() != EbtBool || !type->isScalar())
1037     {
1038         error(line, "boolean expression expected", "");
1039         return false;
1040     }
1041     return true;
1042 }
1043 
1044 // This function checks to see if the node (for the expression) contains a scalar boolean expression
1045 // or not.
checkIsScalarBool(const TSourceLoc & line,const TPublicType & pType)1046 void TParseContext::checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType)
1047 {
1048     if (pType.getBasicType() != EbtBool || pType.isAggregate())
1049     {
1050         error(line, "boolean expression expected", "");
1051     }
1052 }
1053 
checkIsNotOpaqueType(const TSourceLoc & line,const TTypeSpecifierNonArray & pType,const char * reason)1054 bool TParseContext::checkIsNotOpaqueType(const TSourceLoc &line,
1055                                          const TTypeSpecifierNonArray &pType,
1056                                          const char *reason)
1057 {
1058     if (pType.type == EbtStruct)
1059     {
1060         if (ContainsSampler(pType.userDef))
1061         {
1062             std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
1063             reasonStream << reason << " (structure contains a sampler)";
1064             std::string reasonStr = reasonStream.str();
1065             error(line, reasonStr.c_str(), getBasicString(pType.type));
1066             return false;
1067         }
1068         // only samplers need to be checked from structs, since other opaque types can't be struct
1069         // members.
1070         return true;
1071     }
1072     else if (IsOpaqueType(pType.type))
1073     {
1074         error(line, reason, getBasicString(pType.type));
1075         return false;
1076     }
1077 
1078     return true;
1079 }
1080 
checkDeclaratorLocationIsNotSpecified(const TSourceLoc & line,const TPublicType & pType)1081 void TParseContext::checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line,
1082                                                           const TPublicType &pType)
1083 {
1084     if (pType.layoutQualifier.location != -1)
1085     {
1086         error(line, "location must only be specified for a single input or output variable",
1087               "location");
1088     }
1089 }
1090 
checkLocationIsNotSpecified(const TSourceLoc & location,const TLayoutQualifier & layoutQualifier)1091 void TParseContext::checkLocationIsNotSpecified(const TSourceLoc &location,
1092                                                 const TLayoutQualifier &layoutQualifier)
1093 {
1094     if (layoutQualifier.location != -1)
1095     {
1096         const char *errorMsg = "invalid layout qualifier: only valid on program inputs and outputs";
1097         if (mShaderVersion >= 310)
1098         {
1099             errorMsg =
1100                 "invalid layout qualifier: only valid on shader inputs, outputs, and uniforms";
1101         }
1102         error(location, errorMsg, "location");
1103     }
1104 }
1105 
checkStd430IsForShaderStorageBlock(const TSourceLoc & location,const TLayoutBlockStorage & blockStorage,const TQualifier & qualifier)1106 void TParseContext::checkStd430IsForShaderStorageBlock(const TSourceLoc &location,
1107                                                        const TLayoutBlockStorage &blockStorage,
1108                                                        const TQualifier &qualifier)
1109 {
1110     if (blockStorage == EbsStd430 && qualifier != EvqBuffer)
1111     {
1112         error(location, "The std430 layout is supported only for shader storage blocks.", "std430");
1113     }
1114 }
1115 
checkOutParameterIsNotOpaqueType(const TSourceLoc & line,TQualifier qualifier,const TType & type)1116 void TParseContext::checkOutParameterIsNotOpaqueType(const TSourceLoc &line,
1117                                                      TQualifier qualifier,
1118                                                      const TType &type)
1119 {
1120     ASSERT(qualifier == EvqParamOut || qualifier == EvqParamInOut);
1121     if (IsOpaqueType(type.getBasicType()))
1122     {
1123         error(line, "opaque types cannot be output parameters", type.getBasicString());
1124     }
1125 }
1126 
1127 // Do size checking for an array type's size.
checkIsValidArraySize(const TSourceLoc & line,TIntermTyped * expr)1128 unsigned int TParseContext::checkIsValidArraySize(const TSourceLoc &line, TIntermTyped *expr)
1129 {
1130     TIntermConstantUnion *constant = expr->getAsConstantUnion();
1131 
1132     // ANGLE should be able to fold any EvqConst expressions resulting in an integer - but to be
1133     // safe against corner cases we still check for constant folding. Some interpretations of the
1134     // spec have allowed constant expressions with side effects - like array length() method on a
1135     // non-constant array.
1136     if (expr->getQualifier() != EvqConst || constant == nullptr || !constant->isScalarInt())
1137     {
1138         error(line, "array size must be a constant integer expression", "");
1139         return 1u;
1140     }
1141 
1142     unsigned int size = 0u;
1143 
1144     if (constant->getBasicType() == EbtUInt)
1145     {
1146         size = constant->getUConst(0);
1147     }
1148     else
1149     {
1150         int signedSize = constant->getIConst(0);
1151 
1152         if (signedSize < 0)
1153         {
1154             error(line, "array size must be non-negative", "");
1155             return 1u;
1156         }
1157 
1158         size = static_cast<unsigned int>(signedSize);
1159     }
1160 
1161     if (size == 0u)
1162     {
1163         error(line, "array size must be greater than zero", "");
1164         return 1u;
1165     }
1166 
1167     if (IsOutputHLSL(getOutputType()))
1168     {
1169         // The size of arrays is restricted here to prevent issues further down the
1170         // compiler/translator/driver stack. Shader Model 5 generation hardware is limited to
1171         // 4096 registers so this should be reasonable even for aggressively optimizable code.
1172         const unsigned int sizeLimit = 65536;
1173 
1174         if (size > sizeLimit)
1175         {
1176             error(line, "array size too large", "");
1177             return 1u;
1178         }
1179     }
1180 
1181     return size;
1182 }
1183 
1184 // See if this qualifier can be an array.
checkIsValidQualifierForArray(const TSourceLoc & line,const TPublicType & elementQualifier)1185 bool TParseContext::checkIsValidQualifierForArray(const TSourceLoc &line,
1186                                                   const TPublicType &elementQualifier)
1187 {
1188     if ((elementQualifier.qualifier == EvqAttribute) ||
1189         (elementQualifier.qualifier == EvqVertexIn) ||
1190         (elementQualifier.qualifier == EvqConst && mShaderVersion < 300))
1191     {
1192         error(line, "cannot declare arrays of this qualifier",
1193               TType(elementQualifier).getQualifierString());
1194         return false;
1195     }
1196 
1197     return true;
1198 }
1199 
1200 // See if this element type can be formed into an array.
checkArrayElementIsNotArray(const TSourceLoc & line,const TPublicType & elementType)1201 bool TParseContext::checkArrayElementIsNotArray(const TSourceLoc &line,
1202                                                 const TPublicType &elementType)
1203 {
1204     if (mShaderVersion < 310 && elementType.isArray())
1205     {
1206         TInfoSinkBase typeString;
1207         typeString << TType(elementType);
1208         error(line, "cannot declare arrays of arrays", typeString.c_str());
1209         return false;
1210     }
1211     return true;
1212 }
1213 
1214 // Check for array-of-arrays being used as non-allowed shader inputs/outputs.
checkArrayOfArraysInOut(const TSourceLoc & line,const TPublicType & elementType,const TType & arrayType)1215 bool TParseContext::checkArrayOfArraysInOut(const TSourceLoc &line,
1216                                             const TPublicType &elementType,
1217                                             const TType &arrayType)
1218 {
1219     if (arrayType.isArrayOfArrays())
1220     {
1221         if (elementType.qualifier == EvqVertexOut)
1222         {
1223             error(line, "vertex shader output cannot be an array of arrays",
1224                   TType(elementType).getQualifierString());
1225             return false;
1226         }
1227         if (elementType.qualifier == EvqFragmentIn)
1228         {
1229             error(line, "fragment shader input cannot be an array of arrays",
1230                   TType(elementType).getQualifierString());
1231             return false;
1232         }
1233         if (elementType.qualifier == EvqFragmentOut || elementType.qualifier == EvqFragmentInOut)
1234         {
1235             error(line, "fragment shader output cannot be an array of arrays",
1236                   TType(elementType).getQualifierString());
1237             return false;
1238         }
1239     }
1240     return true;
1241 }
1242 
1243 // Check if this qualified element type can be formed into an array. This is only called when array
1244 // brackets are associated with an identifier in a declaration, like this:
1245 //   float a[2];
1246 // Similar checks are done in addFullySpecifiedType for array declarations where the array brackets
1247 // are associated with the type, like this:
1248 //   float[2] a;
checkIsValidTypeAndQualifierForArray(const TSourceLoc & indexLocation,const TPublicType & elementType)1249 bool TParseContext::checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation,
1250                                                          const TPublicType &elementType)
1251 {
1252     if (!checkArrayElementIsNotArray(indexLocation, elementType))
1253     {
1254         return false;
1255     }
1256     // In ESSL1.00 shaders, structs cannot be varying (section 4.3.5). This is checked elsewhere.
1257     // In ESSL3.00 shaders, struct inputs/outputs are allowed but not arrays of structs (section
1258     // 4.3.4).
1259     // Geometry shader requires each user-defined input be declared as arrays or inside input
1260     // blocks declared as arrays (GL_EXT_geometry_shader section 11.1gs.4.3). For the purposes of
1261     // interface matching, such variables and blocks are treated as though they were not declared
1262     // as arrays (GL_EXT_geometry_shader section 7.4.1).
1263     if (mShaderVersion >= 300 && elementType.getBasicType() == EbtStruct &&
1264         sh::IsVarying(elementType.qualifier) &&
1265         !IsGeometryShaderInput(mShaderType, elementType.qualifier) &&
1266         !IsTessellationControlShaderInput(mShaderType, elementType.qualifier) &&
1267         !IsTessellationEvaluationShaderInput(mShaderType, elementType.qualifier) &&
1268         !IsTessellationControlShaderOutput(mShaderType, elementType.qualifier))
1269     {
1270         TInfoSinkBase typeString;
1271         typeString << TType(elementType);
1272         error(indexLocation, "cannot declare arrays of structs of this qualifier",
1273               typeString.c_str());
1274         return false;
1275     }
1276     return checkIsValidQualifierForArray(indexLocation, elementType);
1277 }
1278 
1279 // Enforce non-initializer type/qualifier rules.
checkCanBeDeclaredWithoutInitializer(const TSourceLoc & line,const ImmutableString & identifier,TType * type)1280 void TParseContext::checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
1281                                                          const ImmutableString &identifier,
1282                                                          TType *type)
1283 {
1284     ASSERT(type != nullptr);
1285     if (type->getQualifier() == EvqConst)
1286     {
1287         // Make the qualifier make sense.
1288         type->setQualifier(EvqTemporary);
1289 
1290         // Generate informative error messages for ESSL1.
1291         // In ESSL3 arrays and structures containing arrays can be constant.
1292         if (mShaderVersion < 300 && type->isStructureContainingArrays())
1293         {
1294             error(line,
1295                   "structures containing arrays may not be declared constant since they cannot be "
1296                   "initialized",
1297                   identifier);
1298         }
1299         else
1300         {
1301             error(line, "variables with qualifier 'const' must be initialized", identifier);
1302         }
1303     }
1304 
1305     // Implicitly declared arrays are only allowed with tessellation or geometry shader inputs
1306     if (type->isArray() &&
1307         ((mShaderType != GL_TESS_CONTROL_SHADER && mShaderType != GL_TESS_EVALUATION_SHADER &&
1308           mShaderType != GL_GEOMETRY_SHADER) ||
1309          (mShaderType == GL_GEOMETRY_SHADER && type->getQualifier() == EvqGeometryOut)))
1310     {
1311         const TSpan<const unsigned int> &arraySizes = type->getArraySizes();
1312         for (unsigned int size : arraySizes)
1313         {
1314             if (size == 0)
1315             {
1316                 error(line,
1317                       "implicitly sized arrays only allowed for tessellation shaders "
1318                       "or geometry shader inputs",
1319                       identifier);
1320             }
1321         }
1322     }
1323 }
1324 
1325 // Do some simple checks that are shared between all variable declarations,
1326 // and update the symbol table.
1327 //
1328 // Returns true if declaring the variable succeeded.
1329 //
declareVariable(const TSourceLoc & line,const ImmutableString & identifier,const TType * type,TVariable ** variable)1330 bool TParseContext::declareVariable(const TSourceLoc &line,
1331                                     const ImmutableString &identifier,
1332                                     const TType *type,
1333                                     TVariable **variable)
1334 {
1335     ASSERT((*variable) == nullptr);
1336 
1337     SymbolType symbolType = SymbolType::UserDefined;
1338     switch (type->getQualifier())
1339     {
1340         case EvqClipDistance:
1341         case EvqCullDistance:
1342         case EvqFragDepth:
1343         case EvqLastFragData:
1344         case EvqLastFragColor:
1345             symbolType = SymbolType::BuiltIn;
1346             break;
1347         default:
1348             break;
1349     }
1350 
1351     (*variable) = new TVariable(&symbolTable, identifier, type, symbolType);
1352 
1353     ASSERT(type->getLayoutQualifier().index == -1 ||
1354            (isExtensionEnabled(TExtension::EXT_blend_func_extended) &&
1355             mShaderType == GL_FRAGMENT_SHADER && mShaderVersion >= 300));
1356     if (type->getQualifier() == EvqFragmentOut)
1357     {
1358         if (type->getLayoutQualifier().index != -1 && type->getLayoutQualifier().location == -1)
1359         {
1360             error(line,
1361                   "If index layout qualifier is specified for a fragment output, location must "
1362                   "also be specified.",
1363                   "index");
1364             return false;
1365         }
1366     }
1367     else
1368     {
1369         checkIndexIsNotSpecified(line, type->getLayoutQualifier().index);
1370     }
1371 
1372     if (!((identifier.beginsWith("gl_LastFragData") || type->getQualifier() == EvqFragmentInOut) &&
1373           (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch) ||
1374            isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent))))
1375     {
1376         checkNoncoherentIsNotSpecified(line, type->getLayoutQualifier().noncoherent);
1377     }
1378     else if (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent) &&
1379              !isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch))
1380     {
1381         checkNoncoherentIsSpecified(line, type->getLayoutQualifier().noncoherent);
1382     }
1383 
1384     checkBindingIsValid(line, *type);
1385 
1386     bool needsReservedCheck = true;
1387 
1388     // gl_LastFragData may be redeclared with a new precision qualifier
1389     if (type->isArray() && identifier.beginsWith("gl_LastFragData"))
1390     {
1391         const TVariable *maxDrawBuffers = static_cast<const TVariable *>(
1392             symbolTable.findBuiltIn(ImmutableString("gl_MaxDrawBuffers"), mShaderVersion));
1393         if (type->isArrayOfArrays())
1394         {
1395             error(line, "redeclaration of gl_LastFragData as an array of arrays", identifier);
1396             return false;
1397         }
1398         else if (static_cast<int>(type->getOutermostArraySize()) ==
1399                  maxDrawBuffers->getConstPointer()->getIConst())
1400         {
1401             if (const TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion))
1402             {
1403                 needsReservedCheck = !checkCanUseOneOfExtensions(line, builtInSymbol->extensions());
1404             }
1405         }
1406         else
1407         {
1408             error(line, "redeclaration of gl_LastFragData with size != gl_MaxDrawBuffers",
1409                   identifier);
1410             return false;
1411         }
1412     }
1413     else if (identifier.beginsWith("gl_LastFragColorARM"))
1414     {
1415         // gl_LastFragColorARM may be redeclared with a new precision qualifier
1416         if (const TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion))
1417         {
1418             needsReservedCheck = !checkCanUseOneOfExtensions(line, builtInSymbol->extensions());
1419         }
1420     }
1421     else if (type->isArray() && identifier == "gl_ClipDistance")
1422     {
1423         // gl_ClipDistance can be redeclared with smaller size than gl_MaxClipDistances
1424         const TVariable *maxClipDistances = static_cast<const TVariable *>(
1425             symbolTable.findBuiltIn(ImmutableString("gl_MaxClipDistances"), mShaderVersion));
1426         if (!maxClipDistances)
1427         {
1428             // Unsupported extension
1429             needsReservedCheck = true;
1430         }
1431         else if (type->isArrayOfArrays())
1432         {
1433             error(line, "redeclaration of gl_ClipDistance as an array of arrays", identifier);
1434             return false;
1435         }
1436         else if (static_cast<int>(type->getOutermostArraySize()) <=
1437                  maxClipDistances->getConstPointer()->getIConst())
1438         {
1439             const TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion);
1440             if (builtInSymbol)
1441             {
1442                 needsReservedCheck = !checkCanUseOneOfExtensions(line, builtInSymbol->extensions());
1443             }
1444         }
1445         else
1446         {
1447             error(line, "redeclaration of gl_ClipDistance with size > gl_MaxClipDistances",
1448                   identifier);
1449             return false;
1450         }
1451     }
1452     else if (type->isArray() && identifier == "gl_CullDistance")
1453     {
1454         // gl_CullDistance can be redeclared with smaller size than gl_MaxCullDistances
1455         const TVariable *maxCullDistances = static_cast<const TVariable *>(
1456             symbolTable.findBuiltIn(ImmutableString("gl_MaxCullDistances"), mShaderVersion));
1457         if (!maxCullDistances)
1458         {
1459             // Unsupported extension
1460             needsReservedCheck = true;
1461         }
1462         else if (type->isArrayOfArrays())
1463         {
1464             error(line, "redeclaration of gl_CullDistance as an array of arrays", identifier);
1465             return false;
1466         }
1467         else if (static_cast<int>(type->getOutermostArraySize()) <=
1468                  maxCullDistances->getConstPointer()->getIConst())
1469         {
1470             if (const TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion))
1471             {
1472                 needsReservedCheck = !checkCanUseOneOfExtensions(line, builtInSymbol->extensions());
1473             }
1474         }
1475         else
1476         {
1477             error(line, "redeclaration of gl_CullDistance with size > gl_MaxCullDistances",
1478                   identifier);
1479             return false;
1480         }
1481     }
1482     else if (isExtensionEnabled(TExtension::EXT_conservative_depth) &&
1483              mShaderType == GL_FRAGMENT_SHADER && identifier == "gl_FragDepth")
1484     {
1485         if (type->getBasicType() != EbtFloat || type->getNominalSize() != 1 ||
1486             type->getSecondarySize() != 1 || type->isArray())
1487         {
1488             error(line, "gl_FragDepth can only be redeclared as float", identifier);
1489             return false;
1490         }
1491         needsReservedCheck = false;
1492     }
1493     else if (isExtensionEnabled(TExtension::EXT_separate_shader_objects) &&
1494              mShaderType == GL_VERTEX_SHADER)
1495     {
1496         bool isRedefiningPositionOrPointSize = false;
1497         if (identifier == "gl_Position")
1498         {
1499             if (type->getBasicType() != EbtFloat || type->getNominalSize() != 4 ||
1500                 type->getSecondarySize() != 1 || type->isArray())
1501             {
1502                 error(line, "gl_Position can only be redeclared as vec4", identifier);
1503                 return false;
1504             }
1505             needsReservedCheck                         = false;
1506             mPositionRedeclaredForSeparateShaderObject = true;
1507             isRedefiningPositionOrPointSize            = true;
1508         }
1509         else if (identifier == "gl_PointSize")
1510         {
1511             if (type->getBasicType() != EbtFloat || type->getNominalSize() != 1 ||
1512                 type->getSecondarySize() != 1 || type->isArray())
1513             {
1514                 error(line, "gl_PointSize can only be redeclared as float", identifier);
1515                 return false;
1516             }
1517             needsReservedCheck                          = false;
1518             mPointSizeRedeclaredForSeparateShaderObject = true;
1519             isRedefiningPositionOrPointSize             = true;
1520         }
1521         if (isRedefiningPositionOrPointSize && mPositionOrPointSizeUsedForSeparateShaderObject)
1522         {
1523             error(line,
1524                   "When EXT_separate_shader_objects is enabled, both gl_Position and "
1525                   "gl_PointSize must be redeclared before either is used",
1526                   identifier);
1527         }
1528     }
1529 
1530     if (needsReservedCheck && !checkIsNotReserved(line, identifier))
1531         return false;
1532 
1533     if (!symbolTable.declare(*variable))
1534     {
1535         error(line, "redefinition", identifier);
1536         return false;
1537     }
1538 
1539     if (!checkIsNonVoid(line, identifier, type->getBasicType()))
1540         return false;
1541 
1542     return true;
1543 }
1544 
checkIsParameterQualifierValid(const TSourceLoc & line,const TTypeQualifierBuilder & typeQualifierBuilder,TType * type)1545 void TParseContext::checkIsParameterQualifierValid(
1546     const TSourceLoc &line,
1547     const TTypeQualifierBuilder &typeQualifierBuilder,
1548     TType *type)
1549 {
1550     // The only parameter qualifiers a parameter can have are in, out, inout or const.
1551     TTypeQualifier typeQualifier =
1552         typeQualifierBuilder.getParameterTypeQualifier(type->getBasicType(), mDiagnostics);
1553 
1554     if (typeQualifier.qualifier == EvqParamOut || typeQualifier.qualifier == EvqParamInOut)
1555     {
1556         checkOutParameterIsNotOpaqueType(line, typeQualifier.qualifier, *type);
1557     }
1558 
1559     if (!IsImage(type->getBasicType()))
1560     {
1561         checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, line);
1562     }
1563     else
1564     {
1565         type->setMemoryQualifier(typeQualifier.memoryQualifier);
1566     }
1567 
1568     type->setQualifier(typeQualifier.qualifier);
1569 
1570     if (typeQualifier.precision != EbpUndefined)
1571     {
1572         type->setPrecision(typeQualifier.precision);
1573     }
1574 
1575     if (typeQualifier.precise)
1576     {
1577         type->setPrecise(true);
1578     }
1579 }
1580 
1581 template <size_t size>
checkCanUseOneOfExtensions(const TSourceLoc & line,const std::array<TExtension,size> & extensions)1582 bool TParseContext::checkCanUseOneOfExtensions(const TSourceLoc &line,
1583                                                const std::array<TExtension, size> &extensions)
1584 {
1585     ASSERT(!extensions.empty());
1586     const TExtensionBehavior &extBehavior = extensionBehavior();
1587 
1588     bool canUseWithWarning    = false;
1589     bool canUseWithoutWarning = false;
1590 
1591     const char *errorMsgString   = "";
1592     TExtension errorMsgExtension = TExtension::UNDEFINED;
1593 
1594     for (TExtension extension : extensions)
1595     {
1596         auto extIter = extBehavior.find(extension);
1597         if (canUseWithWarning)
1598         {
1599             // We already have an extension that we can use, but with a warning.
1600             // See if we can use the alternative extension without a warning.
1601             if (extIter == extBehavior.end())
1602             {
1603                 continue;
1604             }
1605             if (extIter->second == EBhEnable || extIter->second == EBhRequire)
1606             {
1607                 canUseWithoutWarning = true;
1608                 break;
1609             }
1610             continue;
1611         }
1612         if (extension == TExtension::UNDEFINED)
1613         {
1614             continue;
1615         }
1616         else if (extIter == extBehavior.end())
1617         {
1618             errorMsgString    = "extension is not supported";
1619             errorMsgExtension = extension;
1620         }
1621         else if (extIter->second == EBhUndefined || extIter->second == EBhDisable)
1622         {
1623             errorMsgString    = "extension is disabled";
1624             errorMsgExtension = extension;
1625         }
1626         else if (extIter->second == EBhWarn)
1627         {
1628             errorMsgExtension = extension;
1629             canUseWithWarning = true;
1630         }
1631         else
1632         {
1633             ASSERT(extIter->second == EBhEnable || extIter->second == EBhRequire);
1634             canUseWithoutWarning = true;
1635             break;
1636         }
1637     }
1638 
1639     if (canUseWithoutWarning)
1640     {
1641         return true;
1642     }
1643     if (canUseWithWarning)
1644     {
1645         warning(line, "extension is being used", GetExtensionNameString(errorMsgExtension));
1646         return true;
1647     }
1648     error(line, errorMsgString, GetExtensionNameString(errorMsgExtension));
1649     return false;
1650 }
1651 
1652 template bool TParseContext::checkCanUseOneOfExtensions(
1653     const TSourceLoc &line,
1654     const std::array<TExtension, 1> &extensions);
1655 template bool TParseContext::checkCanUseOneOfExtensions(
1656     const TSourceLoc &line,
1657     const std::array<TExtension, 2> &extensions);
1658 template bool TParseContext::checkCanUseOneOfExtensions(
1659     const TSourceLoc &line,
1660     const std::array<TExtension, 3> &extensions);
1661 
checkCanUseExtension(const TSourceLoc & line,TExtension extension)1662 bool TParseContext::checkCanUseExtension(const TSourceLoc &line, TExtension extension)
1663 {
1664     ASSERT(extension != TExtension::UNDEFINED);
1665     return checkCanUseOneOfExtensions(line, std::array<TExtension, 1u>{{extension}});
1666 }
1667 
1668 // ESSL 3.00.6 section 4.8 Empty Declarations: "The combinations of qualifiers that cause
1669 // compile-time or link-time errors are the same whether or not the declaration is empty".
1670 // This function implements all the checks that are done on qualifiers regardless of if the
1671 // declaration is empty.
declarationQualifierErrorCheck(const sh::TQualifier qualifier,const sh::TLayoutQualifier & layoutQualifier,const TSourceLoc & location)1672 void TParseContext::declarationQualifierErrorCheck(const sh::TQualifier qualifier,
1673                                                    const sh::TLayoutQualifier &layoutQualifier,
1674                                                    const TSourceLoc &location)
1675 {
1676     if (qualifier == EvqShared && !layoutQualifier.isEmpty())
1677     {
1678         error(location, "Shared memory declarations cannot have layout specified", "layout");
1679     }
1680 
1681     if (layoutQualifier.matrixPacking != EmpUnspecified)
1682     {
1683         error(location, "layout qualifier only valid for interface blocks",
1684               getMatrixPackingString(layoutQualifier.matrixPacking));
1685         return;
1686     }
1687 
1688     if (layoutQualifier.blockStorage != EbsUnspecified)
1689     {
1690         error(location, "layout qualifier only valid for interface blocks",
1691               getBlockStorageString(layoutQualifier.blockStorage));
1692         return;
1693     }
1694 
1695     if (qualifier != EvqFragDepth)
1696     {
1697         checkDepthIsNotSpecified(location, layoutQualifier.depth);
1698     }
1699 
1700     if (qualifier == EvqFragmentOut)
1701     {
1702         if (layoutQualifier.location != -1 && layoutQualifier.yuv == true)
1703         {
1704             error(location, "invalid layout qualifier combination", "yuv");
1705             return;
1706         }
1707     }
1708     else
1709     {
1710         checkYuvIsNotSpecified(location, layoutQualifier.yuv);
1711     }
1712 
1713     if (qualifier != EvqFragmentIn)
1714     {
1715         checkEarlyFragmentTestsIsNotSpecified(location, layoutQualifier.earlyFragmentTests);
1716     }
1717 
1718     // If multiview extension is enabled, "in" qualifier is allowed in the vertex shader in previous
1719     // parsing steps. So it needs to be checked here.
1720     if (anyMultiviewExtensionAvailable() && mShaderVersion < 300 && qualifier == EvqVertexIn)
1721     {
1722         error(location, "storage qualifier supported in GLSL ES 3.00 and above only", "in");
1723     }
1724 
1725     bool canHaveLocation = qualifier == EvqVertexIn || qualifier == EvqFragmentOut;
1726     if (mShaderVersion >= 300 &&
1727         (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch) ||
1728          isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent)))
1729     {
1730         // In the case of EXT_shader_framebuffer_fetch or EXT_shader_framebuffer_fetch_non_coherent
1731         // extension, the location of inout qualifier is used to set the input attachment index
1732         canHaveLocation = canHaveLocation || qualifier == EvqFragmentInOut;
1733     }
1734     if (mShaderVersion >= 310)
1735     {
1736         canHaveLocation = canHaveLocation || qualifier == EvqUniform || IsVarying(qualifier);
1737         // We're not checking whether the uniform location is in range here since that depends on
1738         // the type of the variable.
1739         // The type can only be fully determined for non-empty declarations.
1740     }
1741     if (!canHaveLocation)
1742     {
1743         checkLocationIsNotSpecified(location, layoutQualifier);
1744     }
1745 }
1746 
atomicCounterQualifierErrorCheck(const TPublicType & publicType,const TSourceLoc & location)1747 void TParseContext::atomicCounterQualifierErrorCheck(const TPublicType &publicType,
1748                                                      const TSourceLoc &location)
1749 {
1750     if (publicType.precision != EbpHigh)
1751     {
1752         error(location, "Can only be highp", "atomic counter");
1753     }
1754     // dEQP enforces compile error if location is specified. See uniform_location.test.
1755     if (publicType.layoutQualifier.location != -1)
1756     {
1757         error(location, "location must not be set for atomic_uint", "layout");
1758     }
1759     if (publicType.layoutQualifier.binding == -1)
1760     {
1761         error(location, "no binding specified", "atomic counter");
1762     }
1763 }
1764 
emptyDeclarationErrorCheck(const TType & type,const TSourceLoc & location)1765 void TParseContext::emptyDeclarationErrorCheck(const TType &type, const TSourceLoc &location)
1766 {
1767     if (type.isUnsizedArray())
1768     {
1769         // ESSL3 spec section 4.1.9: Array declaration which leaves the size unspecified is an
1770         // error. It is assumed that this applies to empty declarations as well.
1771         error(location, "empty array declaration needs to specify a size", "");
1772     }
1773 
1774     if (type.getQualifier() != EvqFragmentOut)
1775     {
1776         checkIndexIsNotSpecified(location, type.getLayoutQualifier().index);
1777     }
1778 }
1779 
1780 // These checks are done for all declarations that are non-empty. They're done for non-empty
1781 // declarations starting a declarator list, and declarators that follow an empty declaration.
nonEmptyDeclarationErrorCheck(const TPublicType & publicType,const TSourceLoc & identifierLocation)1782 void TParseContext::nonEmptyDeclarationErrorCheck(const TPublicType &publicType,
1783                                                   const TSourceLoc &identifierLocation)
1784 {
1785     switch (publicType.qualifier)
1786     {
1787         case EvqVaryingIn:
1788         case EvqVaryingOut:
1789         case EvqAttribute:
1790         case EvqVertexIn:
1791         case EvqFragmentOut:
1792         case EvqFragmentInOut:
1793         case EvqComputeIn:
1794             if (publicType.getBasicType() == EbtStruct)
1795             {
1796                 error(identifierLocation, "cannot be used with a structure",
1797                       getQualifierString(publicType.qualifier));
1798                 return;
1799             }
1800             break;
1801         case EvqBuffer:
1802             if (publicType.getBasicType() != EbtInterfaceBlock)
1803             {
1804                 error(identifierLocation,
1805                       "cannot declare buffer variables at global scope(outside a block)",
1806                       getQualifierString(publicType.qualifier));
1807                 return;
1808             }
1809             break;
1810         default:
1811             break;
1812     }
1813     std::string reason(getBasicString(publicType.getBasicType()));
1814     reason += "s must be uniform";
1815     if (publicType.qualifier != EvqUniform &&
1816         !checkIsNotOpaqueType(identifierLocation, publicType.typeSpecifierNonArray, reason.c_str()))
1817     {
1818         return;
1819     }
1820 
1821     if ((publicType.qualifier != EvqTemporary && publicType.qualifier != EvqGlobal &&
1822          publicType.qualifier != EvqConst) &&
1823         publicType.getBasicType() == EbtYuvCscStandardEXT)
1824     {
1825         error(identifierLocation, "cannot be used with a yuvCscStandardEXT",
1826               getQualifierString(publicType.qualifier));
1827         return;
1828     }
1829 
1830     if (mShaderVersion >= 310 && publicType.qualifier == EvqUniform)
1831     {
1832         // Valid uniform declarations can't be unsized arrays since uniforms can't be initialized.
1833         // But invalid shaders may still reach here with an unsized array declaration.
1834         TType type(publicType);
1835         if (!type.isUnsizedArray())
1836         {
1837             checkUniformLocationInRange(identifierLocation, type.getLocationCount(),
1838                                         publicType.layoutQualifier);
1839         }
1840     }
1841 
1842     if (mShaderVersion >= 300 && publicType.qualifier == EvqVertexIn)
1843     {
1844         // Valid vertex input declarations can't be unsized arrays since they can't be initialized.
1845         // But invalid shaders may still reach here with an unsized array declaration.
1846         TType type(publicType);
1847         if (!type.isUnsizedArray())
1848         {
1849             checkAttributeLocationInRange(identifierLocation, type.getLocationCount(),
1850                                           publicType.layoutQualifier);
1851         }
1852     }
1853 
1854     // check for layout qualifier issues
1855     const TLayoutQualifier layoutQualifier = publicType.layoutQualifier;
1856 
1857     if (IsImage(publicType.getBasicType()))
1858     {
1859 
1860         switch (layoutQualifier.imageInternalFormat)
1861         {
1862             case EiifRGBA32F:
1863             case EiifRGBA16F:
1864             case EiifR32F:
1865             case EiifRGBA8:
1866             case EiifRGBA8_SNORM:
1867                 if (!IsFloatImage(publicType.getBasicType()))
1868                 {
1869                     error(identifierLocation,
1870                           "internal image format requires a floating image type",
1871                           getBasicString(publicType.getBasicType()));
1872                     return;
1873                 }
1874                 break;
1875             case EiifRGBA32I:
1876             case EiifRGBA16I:
1877             case EiifRGBA8I:
1878             case EiifR32I:
1879                 if (!IsIntegerImage(publicType.getBasicType()))
1880                 {
1881                     error(identifierLocation,
1882                           "internal image format requires an integer image type",
1883                           getBasicString(publicType.getBasicType()));
1884                     return;
1885                 }
1886                 break;
1887             case EiifRGBA32UI:
1888             case EiifRGBA16UI:
1889             case EiifRGBA8UI:
1890             case EiifR32UI:
1891                 if (!IsUnsignedImage(publicType.getBasicType()))
1892                 {
1893                     error(identifierLocation,
1894                           "internal image format requires an unsigned image type",
1895                           getBasicString(publicType.getBasicType()));
1896                     return;
1897                 }
1898                 break;
1899             case EiifUnspecified:
1900                 error(identifierLocation, "layout qualifier", "No image internal format specified");
1901                 return;
1902             default:
1903                 error(identifierLocation, "layout qualifier", "unrecognized token");
1904                 return;
1905         }
1906 
1907         // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
1908         switch (layoutQualifier.imageInternalFormat)
1909         {
1910             case EiifR32F:
1911             case EiifR32I:
1912             case EiifR32UI:
1913                 break;
1914             default:
1915                 if (!publicType.memoryQualifier.readonly && !publicType.memoryQualifier.writeonly)
1916                 {
1917                     error(identifierLocation, "layout qualifier",
1918                           "Except for images with the r32f, r32i and r32ui format qualifiers, "
1919                           "image variables must be qualified readonly and/or writeonly");
1920                     return;
1921                 }
1922                 break;
1923         }
1924     }
1925     else if (IsPixelLocal(publicType.getBasicType()))
1926     {
1927         if (getShaderType() != GL_FRAGMENT_SHADER)
1928         {
1929             error(identifierLocation,
1930                   "undefined use of pixel local storage outside a fragment shader",
1931                   getBasicString(publicType.getBasicType()));
1932             return;
1933         }
1934         switch (layoutQualifier.imageInternalFormat)
1935         {
1936             case EiifR32F:
1937             case EiifRGBA8:
1938                 if (publicType.getBasicType() != EbtPixelLocalANGLE)
1939                 {
1940                     error(identifierLocation, "pixel local storage format requires pixelLocalANGLE",
1941                           getImageInternalFormatString(layoutQualifier.imageInternalFormat));
1942                 }
1943                 break;
1944             case EiifRGBA8I:
1945                 if (publicType.getBasicType() != EbtIPixelLocalANGLE)
1946                 {
1947                     error(identifierLocation,
1948                           "pixel local storage format requires ipixelLocalANGLE",
1949                           getImageInternalFormatString(layoutQualifier.imageInternalFormat));
1950                 }
1951                 break;
1952             case EiifR32UI:
1953             case EiifRGBA8UI:
1954                 if (publicType.getBasicType() != EbtUPixelLocalANGLE)
1955                 {
1956                     error(identifierLocation,
1957                           "pixel local storage format requires upixelLocalANGLE",
1958                           getImageInternalFormatString(layoutQualifier.imageInternalFormat));
1959                 }
1960                 break;
1961             case EiifR32I:
1962             case EiifRGBA8_SNORM:
1963             case EiifRGBA16F:
1964             case EiifRGBA32F:
1965             case EiifRGBA16I:
1966             case EiifRGBA32I:
1967             case EiifRGBA16UI:
1968             case EiifRGBA32UI:
1969             default:
1970                 ASSERT(!IsValidWithPixelLocalStorage(layoutQualifier.imageInternalFormat));
1971                 error(identifierLocation, "illegal pixel local storage format",
1972                       getImageInternalFormatString(layoutQualifier.imageInternalFormat));
1973                 break;
1974             case EiifUnspecified:
1975                 error(identifierLocation, "pixel local storage requires a format specifier",
1976                       "layout qualifier");
1977                 break;
1978         }
1979         checkMemoryQualifierIsNotSpecified(publicType.memoryQualifier, identifierLocation);
1980         checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
1981     }
1982     else
1983     {
1984         checkInternalFormatIsNotSpecified(identifierLocation, layoutQualifier.imageInternalFormat);
1985         checkMemoryQualifierIsNotSpecified(publicType.memoryQualifier, identifierLocation);
1986     }
1987 
1988     if (IsAtomicCounter(publicType.getBasicType()))
1989     {
1990         atomicCounterQualifierErrorCheck(publicType, identifierLocation);
1991     }
1992     else
1993     {
1994         checkOffsetIsNotSpecified(identifierLocation, layoutQualifier.offset);
1995     }
1996 }
1997 
checkBindingIsValid(const TSourceLoc & identifierLocation,const TType & type)1998 void TParseContext::checkBindingIsValid(const TSourceLoc &identifierLocation, const TType &type)
1999 {
2000     TLayoutQualifier layoutQualifier = type.getLayoutQualifier();
2001     // Note that the ESSL 3.10 section 4.4.5 is not particularly clear on how the binding qualifier
2002     // on arrays of arrays should be handled. We interpret the spec so that the binding value is
2003     // incremented for each element of the innermost nested arrays. This is in line with how arrays
2004     // of arrays of blocks are specified to behave in GLSL 4.50 and a conservative interpretation
2005     // when it comes to which shaders are accepted by the compiler.
2006     int arrayTotalElementCount = type.getArraySizeProduct();
2007     if (IsPixelLocal(type.getBasicType()))
2008     {
2009         checkPixelLocalStorageBindingIsValid(identifierLocation, type);
2010     }
2011     else if (mShaderVersion < 310)
2012     {
2013         checkBindingIsNotSpecified(identifierLocation, layoutQualifier.binding);
2014     }
2015     else if (IsImage(type.getBasicType()))
2016     {
2017         checkImageBindingIsValid(identifierLocation, layoutQualifier.binding,
2018                                  arrayTotalElementCount);
2019     }
2020     else if (IsSampler(type.getBasicType()))
2021     {
2022         checkSamplerBindingIsValid(identifierLocation, layoutQualifier.binding,
2023                                    arrayTotalElementCount);
2024     }
2025     else if (IsAtomicCounter(type.getBasicType()))
2026     {
2027         checkAtomicCounterBindingIsValid(identifierLocation, layoutQualifier.binding);
2028     }
2029     else
2030     {
2031         ASSERT(!IsOpaqueType(type.getBasicType()));
2032         checkBindingIsNotSpecified(identifierLocation, layoutQualifier.binding);
2033     }
2034 }
2035 
checkCanUseLayoutQualifier(const TSourceLoc & location)2036 void TParseContext::checkCanUseLayoutQualifier(const TSourceLoc &location)
2037 {
2038     constexpr std::array<TExtension, 4u> extensions{
2039         {TExtension::EXT_shader_framebuffer_fetch,
2040          TExtension::EXT_shader_framebuffer_fetch_non_coherent,
2041          TExtension::KHR_blend_equation_advanced, TExtension::ANGLE_shader_pixel_local_storage}};
2042     if (getShaderVersion() < 300 && !checkCanUseOneOfExtensions(location, extensions))
2043     {
2044         error(location, "qualifier supported in GLSL ES 3.00 and above only", "layout");
2045     }
2046 }
2047 
checkLayoutQualifierSupported(const TSourceLoc & location,const ImmutableString & layoutQualifierName,int versionRequired)2048 bool TParseContext::checkLayoutQualifierSupported(const TSourceLoc &location,
2049                                                   const ImmutableString &layoutQualifierName,
2050                                                   int versionRequired)
2051 {
2052 
2053     if (mShaderVersion < versionRequired)
2054     {
2055         error(location, "invalid layout qualifier: not supported", layoutQualifierName);
2056         return false;
2057     }
2058     return true;
2059 }
2060 
checkWorkGroupSizeIsNotSpecified(const TSourceLoc & location,const TLayoutQualifier & layoutQualifier)2061 bool TParseContext::checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
2062                                                      const TLayoutQualifier &layoutQualifier)
2063 {
2064     const sh::WorkGroupSize &localSize = layoutQualifier.localSize;
2065     for (size_t i = 0u; i < localSize.size(); ++i)
2066     {
2067         if (localSize[i] != -1)
2068         {
2069             error(location,
2070                   "invalid layout qualifier: only valid when used with 'in' in a compute shader "
2071                   "global layout declaration",
2072                   getWorkGroupSizeString(i));
2073             return false;
2074         }
2075     }
2076 
2077     return true;
2078 }
2079 
checkInternalFormatIsNotSpecified(const TSourceLoc & location,TLayoutImageInternalFormat internalFormat)2080 void TParseContext::checkInternalFormatIsNotSpecified(const TSourceLoc &location,
2081                                                       TLayoutImageInternalFormat internalFormat)
2082 {
2083     if (internalFormat != EiifUnspecified)
2084     {
2085         if (mShaderVersion < 310)
2086         {
2087             if (IsValidWithPixelLocalStorage(internalFormat))
2088             {
2089                 error(location,
2090                       "invalid layout qualifier: not supported before GLSL ES 3.10, except pixel "
2091                       "local storage",
2092                       getImageInternalFormatString(internalFormat));
2093             }
2094             else
2095             {
2096                 error(location, "invalid layout qualifier: not supported before GLSL ES 3.10",
2097                       getImageInternalFormatString(internalFormat));
2098             }
2099         }
2100         else
2101         {
2102             if (IsValidWithPixelLocalStorage(internalFormat))
2103             {
2104                 error(location,
2105                       "invalid layout qualifier: only valid when used with images or pixel local "
2106                       "storage ",
2107                       getImageInternalFormatString(internalFormat));
2108             }
2109             else
2110             {
2111                 error(location, "invalid layout qualifier: only valid when used with images",
2112                       getImageInternalFormatString(internalFormat));
2113             }
2114         }
2115     }
2116 }
2117 
checkIndexIsNotSpecified(const TSourceLoc & location,int index)2118 void TParseContext::checkIndexIsNotSpecified(const TSourceLoc &location, int index)
2119 {
2120     if (index != -1)
2121     {
2122         error(location,
2123               "invalid layout qualifier: only valid when used with a fragment shader output in "
2124               "ESSL version >= 3.00 and EXT_blend_func_extended is enabled",
2125               "index");
2126     }
2127 }
2128 
checkBindingIsNotSpecified(const TSourceLoc & location,int binding)2129 void TParseContext::checkBindingIsNotSpecified(const TSourceLoc &location, int binding)
2130 {
2131     if (binding != -1)
2132     {
2133         if (mShaderVersion < 310)
2134         {
2135             error(location,
2136                   "invalid layout qualifier: only valid when used with pixel local storage",
2137                   "binding");
2138         }
2139         else
2140         {
2141             error(location,
2142                   "invalid layout qualifier: only valid when used with opaque types or blocks",
2143                   "binding");
2144         }
2145     }
2146 }
2147 
checkOffsetIsNotSpecified(const TSourceLoc & location,int offset)2148 void TParseContext::checkOffsetIsNotSpecified(const TSourceLoc &location, int offset)
2149 {
2150     if (offset != -1)
2151     {
2152         error(location, "invalid layout qualifier: only valid when used with atomic counters",
2153               "offset");
2154     }
2155 }
2156 
checkImageBindingIsValid(const TSourceLoc & location,int binding,int arrayTotalElementCount)2157 void TParseContext::checkImageBindingIsValid(const TSourceLoc &location,
2158                                              int binding,
2159                                              int arrayTotalElementCount)
2160 {
2161     // Expects arraySize to be 1 when setting binding for only a single variable.
2162     if (binding >= 0 && binding + arrayTotalElementCount > mMaxImageUnits)
2163     {
2164         error(location, "image binding greater than gl_MaxImageUnits", "binding");
2165     }
2166 }
2167 
checkSamplerBindingIsValid(const TSourceLoc & location,int binding,int arrayTotalElementCount)2168 void TParseContext::checkSamplerBindingIsValid(const TSourceLoc &location,
2169                                                int binding,
2170                                                int arrayTotalElementCount)
2171 {
2172     // Expects arraySize to be 1 when setting binding for only a single variable.
2173     if (binding >= 0 && binding + arrayTotalElementCount > mMaxCombinedTextureImageUnits)
2174     {
2175         error(location, "sampler binding greater than maximum texture units", "binding");
2176     }
2177 }
2178 
checkBlockBindingIsValid(const TSourceLoc & location,const TQualifier & qualifier,int binding,int arraySize)2179 void TParseContext::checkBlockBindingIsValid(const TSourceLoc &location,
2180                                              const TQualifier &qualifier,
2181                                              int binding,
2182                                              int arraySize)
2183 {
2184     int size = (arraySize == 0 ? 1 : arraySize);
2185     if (qualifier == EvqUniform)
2186     {
2187         if (binding + size > mMaxUniformBufferBindings)
2188         {
2189             error(location, "uniform block binding greater than MAX_UNIFORM_BUFFER_BINDINGS",
2190                   "binding");
2191         }
2192     }
2193     else if (qualifier == EvqBuffer)
2194     {
2195         if (binding + size > mMaxShaderStorageBufferBindings)
2196         {
2197             error(location,
2198                   "shader storage block binding greater than MAX_SHADER_STORAGE_BUFFER_BINDINGS",
2199                   "binding");
2200         }
2201     }
2202 }
checkAtomicCounterBindingIsValid(const TSourceLoc & location,int binding)2203 void TParseContext::checkAtomicCounterBindingIsValid(const TSourceLoc &location, int binding)
2204 {
2205     if (binding >= mMaxAtomicCounterBindings)
2206     {
2207         error(location, "atomic counter binding greater than gl_MaxAtomicCounterBindings",
2208               "binding");
2209     }
2210 }
2211 
checkPixelLocalStorageBindingIsValid(const TSourceLoc & location,const TType & type)2212 void TParseContext::checkPixelLocalStorageBindingIsValid(const TSourceLoc &location,
2213                                                          const TType &type)
2214 {
2215     TLayoutQualifier layoutQualifier = type.getLayoutQualifier();
2216     if (type.isArray())
2217     {
2218         // PLS is not allowed in arrays.
2219         // TODO(anglebug.com/7279): Consider allowing this once more backends are implemented.
2220         error(location, "pixel local storage handles cannot be aggregated in arrays", "array");
2221     }
2222     else if (layoutQualifier.binding < 0)
2223     {
2224         error(location, "pixel local storage requires a binding index", "layout qualifier");
2225     }
2226     // TODO(anglebug.com/7279):
2227     // else if (binding >= GL_MAX_LOCAL_STORAGE_PLANES_ANGLE)
2228     // {
2229     // }
2230     else if (mPLSBindings.find(layoutQualifier.binding) != mPLSBindings.end())
2231     {
2232         error(location, "duplicate pixel local storage binding index",
2233               std::to_string(layoutQualifier.binding).c_str());
2234     }
2235     else
2236     {
2237         mPLSBindings[layoutQualifier.binding] = layoutQualifier.imageInternalFormat;
2238         // "mPLSBindings" is how we know whether pixel local storage uniforms have been declared, so
2239         // flush the queue of potential errors once mPLSBindings isn't empty.
2240         if (!mPLSPotentialErrors.empty())
2241         {
2242             for (const auto &[loc, op] : mPLSPotentialErrors)
2243             {
2244                 errorIfPLSDeclared(loc, op);
2245             }
2246             mPLSPotentialErrors.clear();
2247         }
2248     }
2249 }
2250 
checkUniformLocationInRange(const TSourceLoc & location,int objectLocationCount,const TLayoutQualifier & layoutQualifier)2251 void TParseContext::checkUniformLocationInRange(const TSourceLoc &location,
2252                                                 int objectLocationCount,
2253                                                 const TLayoutQualifier &layoutQualifier)
2254 {
2255     int loc = layoutQualifier.location;
2256     if (loc >= 0)  // Shader-specified location
2257     {
2258         if (loc >= mMaxUniformLocations || objectLocationCount > mMaxUniformLocations ||
2259             static_cast<unsigned int>(loc) + static_cast<unsigned int>(objectLocationCount) >
2260                 static_cast<unsigned int>(mMaxUniformLocations))
2261         {
2262             error(location, "Uniform location out of range", "location");
2263         }
2264     }
2265 }
2266 
checkAttributeLocationInRange(const TSourceLoc & location,int objectLocationCount,const TLayoutQualifier & layoutQualifier)2267 void TParseContext::checkAttributeLocationInRange(const TSourceLoc &location,
2268                                                   int objectLocationCount,
2269                                                   const TLayoutQualifier &layoutQualifier)
2270 {
2271     int loc = layoutQualifier.location;
2272     if (loc >= 0)  // Shader-specified location
2273     {
2274         if (loc >= mMaxVertexAttribs || objectLocationCount > mMaxVertexAttribs ||
2275             static_cast<unsigned int>(loc) + static_cast<unsigned int>(objectLocationCount) >
2276                 static_cast<unsigned int>(mMaxVertexAttribs))
2277         {
2278             error(location, "Attribute location out of range", "location");
2279         }
2280     }
2281 }
2282 
checkDepthIsNotSpecified(const TSourceLoc & location,TLayoutDepth depth)2283 void TParseContext::checkDepthIsNotSpecified(const TSourceLoc &location, TLayoutDepth depth)
2284 {
2285     if (depth != EdUnspecified)
2286     {
2287         error(location, "invalid layout qualifier: only valid on gl_FragDepth",
2288               getDepthString(depth));
2289     }
2290 }
2291 
checkYuvIsNotSpecified(const TSourceLoc & location,bool yuv)2292 void TParseContext::checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv)
2293 {
2294     if (yuv != false)
2295     {
2296         error(location, "invalid layout qualifier: only valid on program outputs", "yuv");
2297     }
2298 }
2299 
checkEarlyFragmentTestsIsNotSpecified(const TSourceLoc & location,bool earlyFragmentTests)2300 void TParseContext::checkEarlyFragmentTestsIsNotSpecified(const TSourceLoc &location,
2301                                                           bool earlyFragmentTests)
2302 {
2303     if (earlyFragmentTests != false)
2304     {
2305         error(location,
2306               "invalid layout qualifier: only valid when used with 'in' in a fragment shader",
2307               "early_fragment_tests");
2308     }
2309 }
2310 
checkNoncoherentIsSpecified(const TSourceLoc & location,bool noncoherent)2311 void TParseContext::checkNoncoherentIsSpecified(const TSourceLoc &location, bool noncoherent)
2312 {
2313     if (noncoherent == false)
2314     {
2315         error(location,
2316               "'noncoherent' qualifier must be used when "
2317               "GL_EXT_shader_framebuffer_fetch_non_coherent extension is used",
2318               "noncoherent");
2319     }
2320 }
2321 
checkNoncoherentIsNotSpecified(const TSourceLoc & location,bool noncoherent)2322 void TParseContext::checkNoncoherentIsNotSpecified(const TSourceLoc &location, bool noncoherent)
2323 {
2324     if (noncoherent != false)
2325     {
2326         error(location,
2327               "invalid layout qualifier: only valid when used with 'gl_LastFragData' or the "
2328               "variable decorated with 'inout' in a fragment shader",
2329               "noncoherent");
2330     }
2331 }
2332 
checkTCSOutVarIndexIsValid(TIntermBinary * binaryExpression,const TSourceLoc & location)2333 void TParseContext::checkTCSOutVarIndexIsValid(TIntermBinary *binaryExpression,
2334                                                const TSourceLoc &location)
2335 {
2336     ASSERT(binaryExpression->getOp() == EOpIndexIndirect ||
2337            binaryExpression->getOp() == EOpIndexDirect);
2338     const TIntermSymbol *intermSymbol = binaryExpression->getRight()->getAsSymbolNode();
2339     if ((intermSymbol == nullptr) || (intermSymbol->getName() != "gl_InvocationID"))
2340     {
2341         error(location,
2342               "tessellation-control per-vertex output l-value must be indexed with "
2343               "gl_InvocationID",
2344               "[");
2345     }
2346 }
2347 
functionCallRValueLValueErrorCheck(const TFunction * fnCandidate,TIntermAggregate * fnCall)2348 void TParseContext::functionCallRValueLValueErrorCheck(const TFunction *fnCandidate,
2349                                                        TIntermAggregate *fnCall)
2350 {
2351     for (size_t i = 0; i < fnCandidate->getParamCount(); ++i)
2352     {
2353         TQualifier qual        = fnCandidate->getParam(i)->getType().getQualifier();
2354         TIntermTyped *argument = (*(fnCall->getSequence()))[i]->getAsTyped();
2355         bool argumentIsRead    = (IsQualifierUnspecified(qual) || qual == EvqParamIn ||
2356                                qual == EvqParamInOut || qual == EvqParamConst);
2357         if (argumentIsRead)
2358         {
2359             markStaticReadIfSymbol(argument);
2360             if (!IsImage(argument->getBasicType()))
2361             {
2362                 if (argument->getMemoryQualifier().writeonly)
2363                 {
2364                     error(argument->getLine(),
2365                           "Writeonly value cannot be passed for 'in' or 'inout' parameters.",
2366                           fnCall->functionName());
2367                     return;
2368                 }
2369             }
2370         }
2371         if (qual == EvqParamOut || qual == EvqParamInOut)
2372         {
2373             if (!checkCanBeLValue(argument->getLine(), "assign", argument))
2374             {
2375                 error(argument->getLine(),
2376                       "Constant value cannot be passed for 'out' or 'inout' parameters.",
2377                       fnCall->functionName());
2378                 return;
2379             }
2380         }
2381     }
2382 }
2383 
checkInvariantVariableQualifier(bool invariant,const TQualifier qualifier,const TSourceLoc & invariantLocation)2384 void TParseContext::checkInvariantVariableQualifier(bool invariant,
2385                                                     const TQualifier qualifier,
2386                                                     const TSourceLoc &invariantLocation)
2387 {
2388     if (!invariant)
2389         return;
2390 
2391     if (mShaderVersion < 300)
2392     {
2393         // input variables in the fragment shader can be also qualified as invariant
2394         if (!sh::CanBeInvariantESSL1(qualifier))
2395         {
2396             error(invariantLocation, "Cannot be qualified as invariant.", "invariant");
2397         }
2398     }
2399     else
2400     {
2401         if (!sh::CanBeInvariantESSL3OrGreater(qualifier))
2402         {
2403             error(invariantLocation, "Cannot be qualified as invariant.", "invariant");
2404         }
2405     }
2406 }
2407 
checkAdvancedBlendEquationsNotSpecified(const TSourceLoc & location,const AdvancedBlendEquations & advancedBlendEquations,const TQualifier & qualifier)2408 void TParseContext::checkAdvancedBlendEquationsNotSpecified(
2409     const TSourceLoc &location,
2410     const AdvancedBlendEquations &advancedBlendEquations,
2411     const TQualifier &qualifier)
2412 {
2413     if (advancedBlendEquations.any() && qualifier != EvqFragmentOut)
2414     {
2415         error(location,
2416               "invalid layout qualifier: blending equation qualifiers are only permitted on the "
2417               "fragment 'out' qualifier ",
2418               "blend_support_qualifier");
2419     }
2420 }
2421 
isExtensionEnabled(TExtension extension) const2422 bool TParseContext::isExtensionEnabled(TExtension extension) const
2423 {
2424     return IsExtensionEnabled(extensionBehavior(), extension);
2425 }
2426 
handleExtensionDirective(const TSourceLoc & loc,const char * extName,const char * behavior)2427 void TParseContext::handleExtensionDirective(const TSourceLoc &loc,
2428                                              const char *extName,
2429                                              const char *behavior)
2430 {
2431     angle::pp::SourceLocation srcLoc;
2432     srcLoc.file = loc.first_file;
2433     srcLoc.line = loc.first_line;
2434     mDirectiveHandler.handleExtension(srcLoc, extName, behavior);
2435 }
2436 
handlePragmaDirective(const TSourceLoc & loc,const char * name,const char * value,bool stdgl)2437 void TParseContext::handlePragmaDirective(const TSourceLoc &loc,
2438                                           const char *name,
2439                                           const char *value,
2440                                           bool stdgl)
2441 {
2442     angle::pp::SourceLocation srcLoc;
2443     srcLoc.file = loc.first_file;
2444     srcLoc.line = loc.first_line;
2445     mDirectiveHandler.handlePragma(srcLoc, name, value, stdgl);
2446 }
2447 
getComputeShaderLocalSize() const2448 sh::WorkGroupSize TParseContext::getComputeShaderLocalSize() const
2449 {
2450     sh::WorkGroupSize result(-1);
2451     for (size_t i = 0u; i < result.size(); ++i)
2452     {
2453         if (mComputeShaderLocalSizeDeclared && mComputeShaderLocalSize[i] == -1)
2454         {
2455             result[i] = 1;
2456         }
2457         else
2458         {
2459             result[i] = mComputeShaderLocalSize[i];
2460         }
2461     }
2462     return result;
2463 }
2464 
addScalarLiteral(const TConstantUnion * constantUnion,const TSourceLoc & line)2465 TIntermConstantUnion *TParseContext::addScalarLiteral(const TConstantUnion *constantUnion,
2466                                                       const TSourceLoc &line)
2467 {
2468     TIntermConstantUnion *node = new TIntermConstantUnion(
2469         constantUnion, TType(constantUnion->getType(), EbpUndefined, EvqConst));
2470     node->setLine(line);
2471     return node;
2472 }
2473 
2474 /////////////////////////////////////////////////////////////////////////////////
2475 //
2476 // Non-Errors.
2477 //
2478 /////////////////////////////////////////////////////////////////////////////////
2479 
getNamedVariable(const TSourceLoc & location,const ImmutableString & name,const TSymbol * symbol)2480 const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location,
2481                                                  const ImmutableString &name,
2482                                                  const TSymbol *symbol)
2483 {
2484     if (!symbol)
2485     {
2486         error(location, "undeclared identifier", name);
2487         return nullptr;
2488     }
2489 
2490     if (!symbol->isVariable())
2491     {
2492         error(location, "variable expected", name);
2493         return nullptr;
2494     }
2495 
2496     const TVariable *variable = static_cast<const TVariable *>(symbol);
2497 
2498     if (!variable->extensions().empty() && variable->extensions()[0] != TExtension::UNDEFINED)
2499     {
2500         checkCanUseOneOfExtensions(location, variable->extensions());
2501     }
2502 
2503     // GLSL ES 3.1 Revision 4, 7.1.3 Compute Shader Special Variables
2504     if (getShaderType() == GL_COMPUTE_SHADER && !mComputeShaderLocalSizeDeclared &&
2505         variable->getType().getQualifier() == EvqWorkGroupSize)
2506     {
2507         error(location,
2508               "It is an error to use gl_WorkGroupSize before declaring the local group size",
2509               "gl_WorkGroupSize");
2510     }
2511 
2512     // If EXT_shader_framebuffer_fetch_non_coherent is used, gl_LastFragData should be decorated
2513     // with 'layout(noncoherent)' EXT_shader_framebuffer_fetch_non_coherent spec: "Unless the
2514     // GL_EXT_shader_framebuffer_fetch extension  has been enabled in addition, it's an error to use
2515     // gl_LastFragData if it hasn't been explicitly redeclared with layout(noncoherent)."
2516     if (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent) &&
2517         !isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch) &&
2518         variable->getType().getQualifier() == EvqLastFragData)
2519     {
2520         checkNoncoherentIsSpecified(location, variable->getType().getLayoutQualifier().noncoherent);
2521     }
2522 
2523     // When EXT_separate_shader_objects is enabled, gl_Position and gl_PointSize must both be
2524     // redeclared before either is accessed:
2525     //
2526     // > The following vertex shader outputs may be redeclared at global scope to
2527     // > specify a built-in output interface, with or without special qualifiers:
2528     // >
2529     // >     gl_Position
2530     // >     gl_PointSize
2531     // >
2532     // >   When compiling shaders using either of the above variables, both such
2533     // >   variables must be redeclared prior to use.  ((Note:  This restriction
2534     // >   applies only to shaders using version 300 that enable the
2535     // >   EXT_separate_shader_objects extension; shaders not enabling the
2536     // >   extension do not have this requirement.))
2537     //
2538     // However, there are dEQP tests that enable all extensions and don't actually redeclare these
2539     // variables.  Per https://gitlab.khronos.org/opengl/API/-/issues/169, there are drivers that do
2540     // enforce this, but they fail linking instead of compilation.
2541     //
2542     // In ANGLE, we make sure that they are both redeclared before use if any is redeclared, but if
2543     // neither are redeclared, we don't fail compilation.  Currently, linking also doesn't fail in
2544     // ANGLE (similarly to almost all other drivers).
2545     if (isExtensionEnabled(TExtension::EXT_separate_shader_objects) &&
2546         mShaderType == GL_VERTEX_SHADER)
2547     {
2548         if (variable->getType().getQualifier() == EvqPosition ||
2549             variable->getType().getQualifier() == EvqPointSize)
2550         {
2551             mPositionOrPointSizeUsedForSeparateShaderObject = true;
2552             const bool eitherIsRedeclared = mPositionRedeclaredForSeparateShaderObject ||
2553                                             mPointSizeRedeclaredForSeparateShaderObject;
2554             const bool bothAreRedeclared = mPositionRedeclaredForSeparateShaderObject &&
2555                                            mPointSizeRedeclaredForSeparateShaderObject;
2556 
2557             if (eitherIsRedeclared && !bothAreRedeclared)
2558             {
2559                 error(location,
2560                       "When EXT_separate_shader_objects is enabled, both gl_Position and "
2561                       "gl_PointSize must be redeclared before either is used",
2562                       name);
2563             }
2564         }
2565     }
2566 
2567     return variable;
2568 }
2569 
parseVariableIdentifier(const TSourceLoc & location,const ImmutableString & name,const TSymbol * symbol)2570 TIntermTyped *TParseContext::parseVariableIdentifier(const TSourceLoc &location,
2571                                                      const ImmutableString &name,
2572                                                      const TSymbol *symbol)
2573 {
2574     const TVariable *variable = getNamedVariable(location, name, symbol);
2575 
2576     if (!variable)
2577     {
2578         TIntermTyped *node = CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
2579         node->setLine(location);
2580         return node;
2581     }
2582 
2583     const TType &variableType = variable->getType();
2584     TIntermTyped *node        = nullptr;
2585 
2586     if (variable->getConstPointer() && variableType.canReplaceWithConstantUnion())
2587     {
2588         const TConstantUnion *constArray = variable->getConstPointer();
2589         node                             = new TIntermConstantUnion(constArray, variableType);
2590     }
2591     else if (variableType.getQualifier() == EvqWorkGroupSize && mComputeShaderLocalSizeDeclared)
2592     {
2593         // gl_WorkGroupSize can be used to size arrays according to the ESSL 3.10.4 spec, so it
2594         // needs to be added to the AST as a constant and not as a symbol.
2595         sh::WorkGroupSize workGroupSize = getComputeShaderLocalSize();
2596         TConstantUnion *constArray      = new TConstantUnion[3];
2597         for (size_t i = 0; i < 3; ++i)
2598         {
2599             constArray[i].setUConst(static_cast<unsigned int>(workGroupSize[i]));
2600         }
2601 
2602         ASSERT(variableType.getBasicType() == EbtUInt);
2603         ASSERT(variableType.getObjectSize() == 3);
2604 
2605         TType type(variableType);
2606         type.setQualifier(EvqConst);
2607         node = new TIntermConstantUnion(constArray, type);
2608     }
2609     else if ((mGeometryShaderInputPrimitiveType != EptUndefined) &&
2610              (variableType.getQualifier() == EvqPerVertexIn))
2611     {
2612         ASSERT(symbolTable.getGlInVariableWithArraySize() != nullptr);
2613         node = new TIntermSymbol(symbolTable.getGlInVariableWithArraySize());
2614     }
2615     else
2616     {
2617         node = new TIntermSymbol(variable);
2618     }
2619     ASSERT(node != nullptr);
2620     node->setLine(location);
2621     return node;
2622 }
2623 
adjustRedeclaredBuiltInType(const TSourceLoc & line,const ImmutableString & identifier,TType * type)2624 void TParseContext::adjustRedeclaredBuiltInType(const TSourceLoc &line,
2625                                                 const ImmutableString &identifier,
2626                                                 TType *type)
2627 {
2628     if (identifier == "gl_ClipDistance")
2629     {
2630         const TQualifier qualifier = type->getQualifier();
2631         if ((mShaderType == GL_VERTEX_SHADER &&
2632              !(qualifier == EvqVertexOut || qualifier == EvqVaryingOut)) ||
2633             (mShaderType == GL_FRAGMENT_SHADER && qualifier != EvqFragmentIn))
2634         {
2635             error(line, "invalid or missing storage qualifier", identifier);
2636             return;
2637         }
2638 
2639         type->setQualifier(EvqClipDistance);
2640     }
2641     else if (identifier == "gl_CullDistance")
2642     {
2643         const TQualifier qualifier = type->getQualifier();
2644         if ((mShaderType == GL_VERTEX_SHADER && qualifier != EvqVertexOut) ||
2645             (mShaderType == GL_FRAGMENT_SHADER && qualifier != EvqFragmentIn))
2646         {
2647             error(line, "invalid or missing storage qualifier", identifier);
2648             return;
2649         }
2650 
2651         type->setQualifier(EvqCullDistance);
2652     }
2653     else if (identifier == "gl_LastFragData")
2654     {
2655         type->setQualifier(EvqLastFragData);
2656     }
2657     else if (identifier == "gl_LastFragColorARM")
2658     {
2659         type->setQualifier(EvqLastFragColor);
2660     }
2661     else if (identifier == "gl_Position")
2662     {
2663         type->setQualifier(EvqPosition);
2664     }
2665     else if (identifier == "gl_PointSize")
2666     {
2667         type->setQualifier(EvqPointSize);
2668     }
2669 }
2670 
2671 // Initializers show up in several places in the grammar.  Have one set of
2672 // code to handle them here.
2673 //
2674 // Returns true on success.
executeInitializer(const TSourceLoc & line,const ImmutableString & identifier,TType * type,TIntermTyped * initializer,TIntermBinary ** initNode)2675 bool TParseContext::executeInitializer(const TSourceLoc &line,
2676                                        const ImmutableString &identifier,
2677                                        TType *type,
2678                                        TIntermTyped *initializer,
2679                                        TIntermBinary **initNode)
2680 {
2681     ASSERT(initNode != nullptr);
2682     ASSERT(*initNode == nullptr);
2683 
2684     if (type->isUnsizedArray())
2685     {
2686         // In case initializer is not an array or type has more dimensions than initializer, this
2687         // will default to setting array sizes to 1. We have not checked yet whether the initializer
2688         // actually is an array or not. Having a non-array initializer for an unsized array will
2689         // result in an error later, so we don't generate an error message here.
2690         type->sizeUnsizedArrays(initializer->getType().getArraySizes());
2691     }
2692 
2693     const TQualifier qualifier = type->getQualifier();
2694 
2695     bool constError = false;
2696     if (qualifier == EvqConst)
2697     {
2698         if (EvqConst != initializer->getType().getQualifier())
2699         {
2700             TInfoSinkBase reasonStream;
2701             reasonStream << "assigning non-constant to '" << *type << "'";
2702             error(line, reasonStream.c_str(), "=");
2703 
2704             // We're still going to declare the variable to avoid extra error messages.
2705             type->setQualifier(EvqTemporary);
2706             constError = true;
2707         }
2708     }
2709 
2710     TVariable *variable = nullptr;
2711     if (!declareVariable(line, identifier, type, &variable))
2712     {
2713         return false;
2714     }
2715 
2716     if (constError)
2717     {
2718         return false;
2719     }
2720 
2721     bool nonConstGlobalInitializers =
2722         IsExtensionEnabled(mDirectiveHandler.extensionBehavior(),
2723                            TExtension::EXT_shader_non_constant_global_initializers);
2724     bool globalInitWarning = false;
2725     if (symbolTable.atGlobalLevel() &&
2726         !ValidateGlobalInitializer(initializer, mShaderVersion, sh::IsWebGLBasedSpec(mShaderSpec),
2727                                    nonConstGlobalInitializers, &globalInitWarning))
2728     {
2729         // Error message does not completely match behavior with ESSL 1.00, but
2730         // we want to steer developers towards only using constant expressions.
2731         error(line, "global variable initializers must be constant expressions", "=");
2732         return false;
2733     }
2734     if (globalInitWarning)
2735     {
2736         warning(
2737             line,
2738             "global variable initializers should be constant expressions "
2739             "(uniforms and globals are allowed in global initializers for legacy compatibility)",
2740             "=");
2741     }
2742 
2743     // identifier must be of type constant, a global, or a temporary
2744     if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst))
2745     {
2746         error(line, " cannot initialize this type of qualifier ",
2747               variable->getType().getQualifierString());
2748         return false;
2749     }
2750 
2751     TIntermSymbol *intermSymbol = new TIntermSymbol(variable);
2752     intermSymbol->setLine(line);
2753 
2754     if (!binaryOpCommonCheck(EOpInitialize, intermSymbol, initializer, line))
2755     {
2756         assignError(line, "=", variable->getType(), initializer->getType());
2757         return false;
2758     }
2759 
2760     if (qualifier == EvqConst)
2761     {
2762         // Save the constant folded value to the variable if possible.
2763         const TConstantUnion *constArray = initializer->getConstantValue();
2764         if (constArray)
2765         {
2766             variable->shareConstPointer(constArray);
2767             if (initializer->getType().canReplaceWithConstantUnion())
2768             {
2769                 ASSERT(*initNode == nullptr);
2770                 return true;
2771             }
2772         }
2773     }
2774 
2775     *initNode = new TIntermBinary(EOpInitialize, intermSymbol, initializer);
2776     markStaticReadIfSymbol(initializer);
2777     (*initNode)->setLine(line);
2778     return true;
2779 }
2780 
addConditionInitializer(const TPublicType & pType,const ImmutableString & identifier,TIntermTyped * initializer,const TSourceLoc & loc)2781 TIntermNode *TParseContext::addConditionInitializer(const TPublicType &pType,
2782                                                     const ImmutableString &identifier,
2783                                                     TIntermTyped *initializer,
2784                                                     const TSourceLoc &loc)
2785 {
2786     checkIsScalarBool(loc, pType);
2787     TIntermBinary *initNode = nullptr;
2788     TType *type             = new TType(pType);
2789     if (executeInitializer(loc, identifier, type, initializer, &initNode))
2790     {
2791         // The initializer is valid. The init condition needs to have a node - either the
2792         // initializer node, or a constant node in case the initialized variable is const and won't
2793         // be recorded in the AST.
2794         if (initNode == nullptr)
2795         {
2796             return initializer;
2797         }
2798         else
2799         {
2800             TIntermDeclaration *declaration = new TIntermDeclaration();
2801             declaration->appendDeclarator(initNode);
2802             return declaration;
2803         }
2804     }
2805     return nullptr;
2806 }
2807 
addLoop(TLoopType type,TIntermNode * init,TIntermNode * cond,TIntermTyped * expr,TIntermNode * body,const TSourceLoc & line)2808 TIntermNode *TParseContext::addLoop(TLoopType type,
2809                                     TIntermNode *init,
2810                                     TIntermNode *cond,
2811                                     TIntermTyped *expr,
2812                                     TIntermNode *body,
2813                                     const TSourceLoc &line)
2814 {
2815     TIntermNode *node       = nullptr;
2816     TIntermTyped *typedCond = nullptr;
2817     if (cond)
2818     {
2819         markStaticReadIfSymbol(cond);
2820         typedCond = cond->getAsTyped();
2821     }
2822     if (expr)
2823     {
2824         markStaticReadIfSymbol(expr);
2825     }
2826     // In case the loop body was not parsed as a block and contains a statement that simply refers
2827     // to a variable, we need to mark it as statically used.
2828     if (body)
2829     {
2830         markStaticReadIfSymbol(body);
2831     }
2832     if (cond == nullptr || typedCond)
2833     {
2834         if (type == ELoopDoWhile && typedCond)
2835         {
2836             checkIsScalarBool(line, typedCond);
2837         }
2838         // In the case of other loops, it was checked before that the condition is a scalar boolean.
2839         ASSERT(mDiagnostics->numErrors() > 0 || typedCond == nullptr ||
2840                (typedCond->getBasicType() == EbtBool && !typedCond->isArray() &&
2841                 !typedCond->isVector()));
2842 
2843         node = new TIntermLoop(type, init, typedCond, expr, EnsureBlock(body));
2844         node->setLine(line);
2845         return node;
2846     }
2847 
2848     ASSERT(type != ELoopDoWhile);
2849 
2850     TIntermDeclaration *declaration = cond->getAsDeclarationNode();
2851     ASSERT(declaration);
2852     TIntermBinary *declarator = declaration->getSequence()->front()->getAsBinaryNode();
2853     ASSERT(declarator->getLeft()->getAsSymbolNode());
2854 
2855     // The condition is a declaration. In the AST representation we don't support declarations as
2856     // loop conditions. Wrap the loop to a block that declares the condition variable and contains
2857     // the loop.
2858     TIntermBlock *block = new TIntermBlock();
2859 
2860     TIntermDeclaration *declareCondition = new TIntermDeclaration();
2861     declareCondition->appendDeclarator(declarator->getLeft()->deepCopy());
2862     block->appendStatement(declareCondition);
2863 
2864     TIntermBinary *conditionInit = new TIntermBinary(EOpAssign, declarator->getLeft()->deepCopy(),
2865                                                      declarator->getRight()->deepCopy());
2866     TIntermLoop *loop = new TIntermLoop(type, init, conditionInit, expr, EnsureBlock(body));
2867     block->appendStatement(loop);
2868     loop->setLine(line);
2869     block->setLine(line);
2870     return block;
2871 }
2872 
addIfElse(TIntermTyped * cond,TIntermNodePair code,const TSourceLoc & loc)2873 TIntermNode *TParseContext::addIfElse(TIntermTyped *cond,
2874                                       TIntermNodePair code,
2875                                       const TSourceLoc &loc)
2876 {
2877     bool isScalarBool = checkIsScalarBool(loc, cond);
2878     // In case the conditional statements were not parsed as blocks and contain a statement that
2879     // simply refers to a variable, we need to mark them as statically used.
2880     if (code.node1)
2881     {
2882         markStaticReadIfSymbol(code.node1);
2883     }
2884     if (code.node2)
2885     {
2886         markStaticReadIfSymbol(code.node2);
2887     }
2888 
2889     // For compile time constant conditions, prune the code now.
2890     if (isScalarBool && cond->getAsConstantUnion())
2891     {
2892         if (cond->getAsConstantUnion()->getBConst(0) == true)
2893         {
2894             return EnsureBlock(code.node1);
2895         }
2896         else
2897         {
2898             return EnsureBlock(code.node2);
2899         }
2900     }
2901 
2902     TIntermIfElse *node = new TIntermIfElse(cond, EnsureBlock(code.node1), EnsureBlock(code.node2));
2903     markStaticReadIfSymbol(cond);
2904     node->setLine(loc);
2905 
2906     return node;
2907 }
2908 
addFullySpecifiedType(TPublicType * typeSpecifier)2909 void TParseContext::addFullySpecifiedType(TPublicType *typeSpecifier)
2910 {
2911     checkPrecisionSpecified(typeSpecifier->getLine(), typeSpecifier->precision,
2912                             typeSpecifier->getBasicType());
2913 
2914     if (mShaderVersion < 300 && typeSpecifier->isArray())
2915     {
2916         error(typeSpecifier->getLine(), "not supported", "first-class array");
2917         typeSpecifier->clearArrayness();
2918     }
2919 }
2920 
addFullySpecifiedType(const TTypeQualifierBuilder & typeQualifierBuilder,const TPublicType & typeSpecifier)2921 TPublicType TParseContext::addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
2922                                                  const TPublicType &typeSpecifier)
2923 {
2924     TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
2925 
2926     TPublicType returnType     = typeSpecifier;
2927     returnType.qualifier       = typeQualifier.qualifier;
2928     returnType.invariant       = typeQualifier.invariant;
2929     returnType.precise         = typeQualifier.precise;
2930     returnType.layoutQualifier = typeQualifier.layoutQualifier;
2931     returnType.memoryQualifier = typeQualifier.memoryQualifier;
2932     returnType.precision       = typeSpecifier.precision;
2933 
2934     if (typeQualifier.precision != EbpUndefined)
2935     {
2936         returnType.precision = typeQualifier.precision;
2937     }
2938 
2939     checkPrecisionSpecified(typeSpecifier.getLine(), returnType.precision,
2940                             typeSpecifier.getBasicType());
2941 
2942     checkInvariantVariableQualifier(returnType.invariant, returnType.qualifier,
2943                                     typeSpecifier.getLine());
2944 
2945     checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), returnType.layoutQualifier);
2946 
2947     checkEarlyFragmentTestsIsNotSpecified(typeSpecifier.getLine(),
2948                                           returnType.layoutQualifier.earlyFragmentTests);
2949 
2950     if (returnType.qualifier == EvqSampleIn || returnType.qualifier == EvqSampleOut ||
2951         returnType.qualifier == EvqNoPerspectiveSampleIn ||
2952         returnType.qualifier == EvqNoPerspectiveSampleOut)
2953     {
2954         mSampleQualifierSpecified = true;
2955     }
2956 
2957     if (mShaderVersion < 300)
2958     {
2959         if (typeSpecifier.isArray())
2960         {
2961             error(typeSpecifier.getLine(), "not supported", "first-class array");
2962             returnType.clearArrayness();
2963         }
2964 
2965         if (returnType.qualifier == EvqAttribute &&
2966             (typeSpecifier.getBasicType() == EbtBool || typeSpecifier.getBasicType() == EbtInt))
2967         {
2968             error(typeSpecifier.getLine(), "cannot be bool or int",
2969                   getQualifierString(returnType.qualifier));
2970         }
2971 
2972         if ((returnType.qualifier == EvqVaryingIn || returnType.qualifier == EvqVaryingOut) &&
2973             (typeSpecifier.getBasicType() == EbtBool || typeSpecifier.getBasicType() == EbtInt))
2974         {
2975             error(typeSpecifier.getLine(), "cannot be bool or int",
2976                   getQualifierString(returnType.qualifier));
2977         }
2978     }
2979     else
2980     {
2981         if (!returnType.layoutQualifier.isEmpty())
2982         {
2983             checkIsAtGlobalLevel(typeSpecifier.getLine(), "layout");
2984         }
2985         if (sh::IsVarying(returnType.qualifier) || returnType.qualifier == EvqVertexIn ||
2986             returnType.qualifier == EvqFragmentOut || returnType.qualifier == EvqFragmentInOut)
2987         {
2988             checkInputOutputTypeIsValidES3(returnType.qualifier, typeSpecifier,
2989                                            typeSpecifier.getLine());
2990         }
2991         if (returnType.qualifier == EvqComputeIn)
2992         {
2993             error(typeSpecifier.getLine(), "'in' can be only used to specify the local group size",
2994                   "in");
2995         }
2996     }
2997 
2998     return returnType;
2999 }
3000 
checkInputOutputTypeIsValidES3(const TQualifier qualifier,const TPublicType & type,const TSourceLoc & qualifierLocation)3001 void TParseContext::checkInputOutputTypeIsValidES3(const TQualifier qualifier,
3002                                                    const TPublicType &type,
3003                                                    const TSourceLoc &qualifierLocation)
3004 {
3005     // An input/output variable can never be bool or a sampler. Samplers are checked elsewhere.
3006     if (type.getBasicType() == EbtBool)
3007     {
3008         error(qualifierLocation, "cannot be bool", getQualifierString(qualifier));
3009     }
3010 
3011     // Specific restrictions apply for vertex shader inputs and fragment shader outputs.
3012     switch (qualifier)
3013     {
3014         case EvqVertexIn:
3015             // ESSL 3.00 section 4.3.4
3016             if (type.isArray())
3017             {
3018                 error(qualifierLocation, "cannot be array", getQualifierString(qualifier));
3019             }
3020             // Vertex inputs with a struct type are disallowed in nonEmptyDeclarationErrorCheck
3021             return;
3022         case EvqFragmentOut:
3023         case EvqFragmentInOut:
3024             // ESSL 3.00 section 4.3.6
3025             if (type.typeSpecifierNonArray.isMatrix())
3026             {
3027                 error(qualifierLocation, "cannot be matrix", getQualifierString(qualifier));
3028             }
3029             // Fragment outputs with a struct type are disallowed in nonEmptyDeclarationErrorCheck
3030             return;
3031         default:
3032             break;
3033     }
3034 
3035     // Vertex shader outputs / fragment shader inputs have a different, slightly more lenient set of
3036     // restrictions.
3037     bool typeContainsIntegers =
3038         (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt ||
3039          type.isStructureContainingType(EbtInt) || type.isStructureContainingType(EbtUInt));
3040     bool extendedShaderTypes = mShaderVersion >= 320 ||
3041                                isExtensionEnabled(TExtension::EXT_geometry_shader) ||
3042                                isExtensionEnabled(TExtension::OES_geometry_shader) ||
3043                                isExtensionEnabled(TExtension::EXT_tessellation_shader);
3044     if (typeContainsIntegers && qualifier != EvqFlatIn && qualifier != EvqFlatOut &&
3045         (!extendedShaderTypes || mShaderType == GL_FRAGMENT_SHADER))
3046     {
3047         error(qualifierLocation, "must use 'flat' interpolation here",
3048               getQualifierString(qualifier));
3049     }
3050 
3051     if (type.getBasicType() == EbtStruct)
3052     {
3053         // ESSL 3.00 sections 4.3.4 and 4.3.6.
3054         // These restrictions are only implied by the ESSL 3.00 spec, but
3055         // the ESSL 3.10 spec lists these restrictions explicitly.
3056         if (type.isArray())
3057         {
3058             error(qualifierLocation, "cannot be an array of structures",
3059                   getQualifierString(qualifier));
3060         }
3061         if (type.isStructureContainingArrays())
3062         {
3063             error(qualifierLocation, "cannot be a structure containing an array",
3064                   getQualifierString(qualifier));
3065         }
3066         if (type.isStructureContainingType(EbtStruct))
3067         {
3068             error(qualifierLocation, "cannot be a structure containing a structure",
3069                   getQualifierString(qualifier));
3070         }
3071         if (type.isStructureContainingType(EbtBool))
3072         {
3073             error(qualifierLocation, "cannot be a structure containing a bool",
3074                   getQualifierString(qualifier));
3075         }
3076     }
3077 }
3078 
checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase & qualifier)3079 void TParseContext::checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier)
3080 {
3081     if (qualifier.getType() == QtStorage)
3082     {
3083         const TStorageQualifierWrapper &storageQualifier =
3084             static_cast<const TStorageQualifierWrapper &>(qualifier);
3085         if (!declaringFunction() && storageQualifier.getQualifier() != EvqConst &&
3086             !symbolTable.atGlobalLevel())
3087         {
3088             error(storageQualifier.getLine(),
3089                   "Local variables can only use the const storage qualifier.",
3090                   storageQualifier.getQualifierString());
3091         }
3092     }
3093 }
3094 
checkMemoryQualifierIsNotSpecified(const TMemoryQualifier & memoryQualifier,const TSourceLoc & location)3095 void TParseContext::checkMemoryQualifierIsNotSpecified(const TMemoryQualifier &memoryQualifier,
3096                                                        const TSourceLoc &location)
3097 {
3098     const std::string reason(
3099         "Only allowed with shader storage blocks, variables declared within shader storage blocks "
3100         "and variables declared as image types.");
3101     if (memoryQualifier.readonly)
3102     {
3103         error(location, reason.c_str(), "readonly");
3104     }
3105     if (memoryQualifier.writeonly)
3106     {
3107         error(location, reason.c_str(), "writeonly");
3108     }
3109     if (memoryQualifier.coherent)
3110     {
3111         error(location, reason.c_str(), "coherent");
3112     }
3113     if (memoryQualifier.restrictQualifier)
3114     {
3115         error(location, reason.c_str(), "restrict");
3116     }
3117     if (memoryQualifier.volatileQualifier)
3118     {
3119         error(location, reason.c_str(), "volatile");
3120     }
3121 }
3122 
3123 // Make sure there is no offset overlapping, and store the newly assigned offset to "type" in
3124 // intermediate tree.
checkAtomicCounterOffsetDoesNotOverlap(bool forceAppend,const TSourceLoc & loc,TType * type)3125 void TParseContext::checkAtomicCounterOffsetDoesNotOverlap(bool forceAppend,
3126                                                            const TSourceLoc &loc,
3127                                                            TType *type)
3128 {
3129     const size_t size = type->isArray() ? kAtomicCounterArrayStride * type->getArraySizeProduct()
3130                                         : kAtomicCounterSize;
3131     TLayoutQualifier layoutQualifier = type->getLayoutQualifier();
3132     auto &bindingState               = mAtomicCounterBindingStates[layoutQualifier.binding];
3133     int offset;
3134     if (layoutQualifier.offset == -1 || forceAppend)
3135     {
3136         offset = bindingState.appendSpan(size);
3137     }
3138     else
3139     {
3140         offset = bindingState.insertSpan(layoutQualifier.offset, size);
3141     }
3142     if (offset == -1)
3143     {
3144         error(loc, "Offset overlapping", "atomic counter");
3145         return;
3146     }
3147     layoutQualifier.offset = offset;
3148     type->setLayoutQualifier(layoutQualifier);
3149 }
3150 
checkAtomicCounterOffsetAlignment(const TSourceLoc & location,const TType & type)3151 void TParseContext::checkAtomicCounterOffsetAlignment(const TSourceLoc &location, const TType &type)
3152 {
3153     TLayoutQualifier layoutQualifier = type.getLayoutQualifier();
3154 
3155     // OpenGL ES 3.1 Table 6.5, Atomic counter offset must be a multiple of 4
3156     if (layoutQualifier.offset % 4 != 0)
3157     {
3158         error(location, "Offset must be multiple of 4", "atomic counter");
3159     }
3160 }
3161 
checkGeometryShaderInputAndSetArraySize(const TSourceLoc & location,const ImmutableString & token,TType * type)3162 void TParseContext::checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location,
3163                                                             const ImmutableString &token,
3164                                                             TType *type)
3165 {
3166     if (IsGeometryShaderInput(mShaderType, type->getQualifier()))
3167     {
3168         if (type->isArray() && type->getOutermostArraySize() == 0u)
3169         {
3170             // Set size for the unsized geometry shader inputs if they are declared after a valid
3171             // input primitive declaration.
3172             if (mGeometryShaderInputPrimitiveType != EptUndefined)
3173             {
3174                 ASSERT(symbolTable.getGlInVariableWithArraySize() != nullptr);
3175                 type->sizeOutermostUnsizedArray(
3176                     symbolTable.getGlInVariableWithArraySize()->getType().getOutermostArraySize());
3177             }
3178             else
3179             {
3180                 // [GLSL ES 3.2 SPEC Chapter 4.4.1.2]
3181                 // An input can be declared without an array size if there is a previous layout
3182                 // which specifies the size.
3183                 warning(location,
3184                         "Missing a valid input primitive declaration before declaring an unsized "
3185                         "array input",
3186                         "Deferred");
3187                 mDeferredArrayTypesToSize.push_back(type);
3188             }
3189         }
3190         else if (type->isArray())
3191         {
3192             setGeometryShaderInputArraySize(type->getOutermostArraySize(), location);
3193         }
3194         else
3195         {
3196             error(location, "Geometry shader input variable must be declared as an array", token);
3197         }
3198     }
3199 }
3200 
checkTessellationShaderUnsizedArraysAndSetSize(const TSourceLoc & location,const ImmutableString & token,TType * type)3201 void TParseContext::checkTessellationShaderUnsizedArraysAndSetSize(const TSourceLoc &location,
3202                                                                    const ImmutableString &token,
3203                                                                    TType *type)
3204 {
3205     TQualifier qualifier = type->getQualifier();
3206     if (!IsTessellationControlShaderOutput(mShaderType, qualifier) &&
3207         !IsTessellationControlShaderInput(mShaderType, qualifier) &&
3208         !IsTessellationEvaluationShaderInput(mShaderType, qualifier))
3209     {
3210         return;
3211     }
3212 
3213     // Such variables must be declared as arrays or inside output blocks declared as arrays.
3214     if (!type->isArray())
3215     {
3216         error(location, "Tessellation interface variables must be declared as an array", token);
3217         return;
3218     }
3219 
3220     // If a size is specified, it must match the maximum patch size.
3221     unsigned int outermostSize = type->getOutermostArraySize();
3222     if (outermostSize == 0u)
3223     {
3224         switch (qualifier)
3225         {
3226             case EvqTessControlIn:
3227             case EvqTessEvaluationIn:
3228             case EvqSmoothIn:
3229             case EvqFlatIn:
3230             case EvqNoPerspectiveIn:
3231             case EvqCentroidIn:
3232             case EvqSampleIn:
3233             case EvqNoPerspectiveCentroidIn:
3234             case EvqNoPerspectiveSampleIn:
3235                 // Declaring an array size is optional. If no size is specified, it will be taken
3236                 // from the implementation-dependent maximum patch size (gl_MaxPatchVertices).
3237                 ASSERT(mMaxPatchVertices > 0);
3238                 type->sizeOutermostUnsizedArray(mMaxPatchVertices);
3239                 break;
3240             case EvqTessControlOut:
3241             case EvqTessEvaluationOut:
3242             case EvqSmoothOut:
3243             case EvqFlatOut:
3244             case EvqNoPerspectiveOut:
3245             case EvqCentroidOut:
3246             case EvqSampleOut:
3247             case EvqNoPerspectiveCentroidOut:
3248             case EvqNoPerspectiveSampleOut:
3249                 // Declaring an array size is optional. If no size is specified, it will be taken
3250                 // from output patch size declared in the shader.  If the patch size is not yet
3251                 // declared, this is deferred until such time as it does.
3252                 if (mTessControlShaderOutputVertices == 0)
3253                 {
3254                     mDeferredArrayTypesToSize.push_back(type);
3255                 }
3256                 else
3257                 {
3258                     type->sizeOutermostUnsizedArray(mTessControlShaderOutputVertices);
3259                 }
3260                 break;
3261             default:
3262                 UNREACHABLE();
3263                 break;
3264         }
3265         return;
3266     }
3267 
3268     if (IsTessellationControlShaderInput(mShaderType, qualifier) ||
3269         IsTessellationEvaluationShaderInput(mShaderType, qualifier))
3270     {
3271         if (outermostSize != static_cast<unsigned int>(mMaxPatchVertices))
3272         {
3273             error(location,
3274                   "If a size is specified for a tessellation control or evaluation user-defined "
3275                   "input variable, it must match the maximum patch size (gl_MaxPatchVertices).",
3276                   token);
3277         }
3278     }
3279     else if (IsTessellationControlShaderOutput(mShaderType, qualifier))
3280     {
3281         if (outermostSize != static_cast<unsigned int>(mTessControlShaderOutputVertices) &&
3282             mTessControlShaderOutputVertices != 0)
3283         {
3284             error(location,
3285                   "If a size is specified for a tessellation control user-defined per-vertex "
3286                   "output variable, it must match the the number of vertices in the output "
3287                   "patch.",
3288                   token);
3289         }
3290     }
3291 }
3292 
parseSingleDeclaration(TPublicType & publicType,const TSourceLoc & identifierOrTypeLocation,const ImmutableString & identifier)3293 TIntermDeclaration *TParseContext::parseSingleDeclaration(
3294     TPublicType &publicType,
3295     const TSourceLoc &identifierOrTypeLocation,
3296     const ImmutableString &identifier)
3297 {
3298     TType *type = new TType(publicType);
3299     if (mCompileOptions.flattenPragmaSTDGLInvariantAll &&
3300         mDirectiveHandler.pragma().stdgl.invariantAll)
3301     {
3302         TQualifier qualifier = type->getQualifier();
3303 
3304         // The directive handler has already taken care of rejecting invalid uses of this pragma
3305         // (for example, in ESSL 3.00 fragment shaders), so at this point, flatten it into all
3306         // affected variable declarations:
3307         //
3308         // 1. Built-in special variables which are inputs to the fragment shader. (These are handled
3309         // elsewhere, in TranslatorGLSL.)
3310         //
3311         // 2. Outputs from vertex shaders in ESSL 1.00 and 3.00 (EvqVaryingOut and EvqVertexOut). It
3312         // is actually less likely that there will be bugs in the handling of ESSL 3.00 shaders, but
3313         // the way this is currently implemented we have to enable this compiler option before
3314         // parsing the shader and determining the shading language version it uses. If this were
3315         // implemented as a post-pass, the workaround could be more targeted.
3316         if (qualifier == EvqVaryingOut || qualifier == EvqVertexOut)
3317         {
3318             type->setInvariant(true);
3319         }
3320     }
3321 
3322     if (identifier == "gl_FragDepth")
3323     {
3324         if (type->getQualifier() == EvqFragmentOut)
3325         {
3326             type->setQualifier(EvqFragDepth);
3327         }
3328         else
3329         {
3330             error(identifierOrTypeLocation,
3331                   "gl_FragDepth can only be redeclared as fragment output", identifier);
3332         }
3333     }
3334 
3335     checkGeometryShaderInputAndSetArraySize(identifierOrTypeLocation, identifier, type);
3336     checkTessellationShaderUnsizedArraysAndSetSize(identifierOrTypeLocation, identifier, type);
3337 
3338     declarationQualifierErrorCheck(type->getQualifier(), publicType.layoutQualifier,
3339                                    identifierOrTypeLocation);
3340 
3341     bool emptyDeclaration                  = (identifier == "");
3342     mDeferredNonEmptyDeclarationErrorCheck = emptyDeclaration;
3343 
3344     TIntermSymbol *symbol = nullptr;
3345     if (emptyDeclaration)
3346     {
3347         emptyDeclarationErrorCheck(*type, identifierOrTypeLocation);
3348         // In most cases we don't need to create a symbol node for an empty declaration.
3349         // But if the empty declaration is declaring a struct type, the symbol node will store that.
3350         if (type->getBasicType() == EbtStruct)
3351         {
3352             TVariable *emptyVariable =
3353                 new TVariable(&symbolTable, kEmptyImmutableString, type, SymbolType::Empty);
3354             symbol = new TIntermSymbol(emptyVariable);
3355         }
3356         else if (IsAtomicCounter(publicType.getBasicType()))
3357         {
3358             setAtomicCounterBindingDefaultOffset(publicType, identifierOrTypeLocation);
3359         }
3360     }
3361     else
3362     {
3363         nonEmptyDeclarationErrorCheck(publicType, identifierOrTypeLocation);
3364 
3365         checkCanBeDeclaredWithoutInitializer(identifierOrTypeLocation, identifier, type);
3366 
3367         if (IsAtomicCounter(type->getBasicType()))
3368         {
3369             checkAtomicCounterOffsetDoesNotOverlap(false, identifierOrTypeLocation, type);
3370 
3371             checkAtomicCounterOffsetAlignment(identifierOrTypeLocation, *type);
3372         }
3373 
3374         TVariable *variable = nullptr;
3375         if (declareVariable(identifierOrTypeLocation, identifier, type, &variable))
3376         {
3377             symbol = new TIntermSymbol(variable);
3378         }
3379     }
3380 
3381     adjustRedeclaredBuiltInType(identifierOrTypeLocation, identifier, type);
3382 
3383     TIntermDeclaration *declaration = new TIntermDeclaration();
3384     declaration->setLine(identifierOrTypeLocation);
3385     if (symbol)
3386     {
3387         symbol->setLine(identifierOrTypeLocation);
3388         declaration->appendDeclarator(symbol);
3389     }
3390     return declaration;
3391 }
3392 
parseSingleArrayDeclaration(TPublicType & elementType,const TSourceLoc & identifierLocation,const ImmutableString & identifier,const TSourceLoc & indexLocation,const TVector<unsigned int> & arraySizes)3393 TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(
3394     TPublicType &elementType,
3395     const TSourceLoc &identifierLocation,
3396     const ImmutableString &identifier,
3397     const TSourceLoc &indexLocation,
3398     const TVector<unsigned int> &arraySizes)
3399 {
3400     mDeferredNonEmptyDeclarationErrorCheck = false;
3401 
3402     declarationQualifierErrorCheck(elementType.qualifier, elementType.layoutQualifier,
3403                                    identifierLocation);
3404 
3405     nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
3406 
3407     checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
3408 
3409     TType *arrayType = new TType(elementType);
3410     arrayType->makeArrays(arraySizes);
3411 
3412     checkArrayOfArraysInOut(indexLocation, elementType, *arrayType);
3413 
3414     checkGeometryShaderInputAndSetArraySize(indexLocation, identifier, arrayType);
3415     checkTessellationShaderUnsizedArraysAndSetSize(indexLocation, identifier, arrayType);
3416 
3417     checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, arrayType);
3418 
3419     if (IsAtomicCounter(arrayType->getBasicType()))
3420     {
3421         checkAtomicCounterOffsetDoesNotOverlap(false, identifierLocation, arrayType);
3422 
3423         checkAtomicCounterOffsetAlignment(identifierLocation, *arrayType);
3424     }
3425 
3426     adjustRedeclaredBuiltInType(identifierLocation, identifier, arrayType);
3427 
3428     TIntermDeclaration *declaration = new TIntermDeclaration();
3429     declaration->setLine(identifierLocation);
3430 
3431     TVariable *variable = nullptr;
3432     if (declareVariable(identifierLocation, identifier, arrayType, &variable))
3433     {
3434         TIntermSymbol *symbol = new TIntermSymbol(variable);
3435         symbol->setLine(identifierLocation);
3436         declaration->appendDeclarator(symbol);
3437     }
3438 
3439     return declaration;
3440 }
3441 
parseSingleInitDeclaration(const TPublicType & publicType,const TSourceLoc & identifierLocation,const ImmutableString & identifier,const TSourceLoc & initLocation,TIntermTyped * initializer)3442 TIntermDeclaration *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType,
3443                                                               const TSourceLoc &identifierLocation,
3444                                                               const ImmutableString &identifier,
3445                                                               const TSourceLoc &initLocation,
3446                                                               TIntermTyped *initializer)
3447 {
3448     mDeferredNonEmptyDeclarationErrorCheck = false;
3449 
3450     declarationQualifierErrorCheck(publicType.qualifier, publicType.layoutQualifier,
3451                                    identifierLocation);
3452 
3453     nonEmptyDeclarationErrorCheck(publicType, identifierLocation);
3454 
3455     TIntermDeclaration *declaration = new TIntermDeclaration();
3456     declaration->setLine(identifierLocation);
3457 
3458     TIntermBinary *initNode = nullptr;
3459     TType *type             = new TType(publicType);
3460     if (executeInitializer(identifierLocation, identifier, type, initializer, &initNode))
3461     {
3462         if (initNode)
3463         {
3464             declaration->appendDeclarator(initNode);
3465         }
3466         else if (publicType.isStructSpecifier())
3467         {
3468             // The initialization got constant folded.  If it's a struct, declare the struct anyway.
3469             TVariable *emptyVariable =
3470                 new TVariable(&symbolTable, kEmptyImmutableString, type, SymbolType::Empty);
3471             TIntermSymbol *symbol = new TIntermSymbol(emptyVariable);
3472             symbol->setLine(publicType.getLine());
3473             declaration->appendDeclarator(symbol);
3474         }
3475     }
3476     return declaration;
3477 }
3478 
parseSingleArrayInitDeclaration(TPublicType & elementType,const TSourceLoc & identifierLocation,const ImmutableString & identifier,const TSourceLoc & indexLocation,const TVector<unsigned int> & arraySizes,const TSourceLoc & initLocation,TIntermTyped * initializer)3479 TIntermDeclaration *TParseContext::parseSingleArrayInitDeclaration(
3480     TPublicType &elementType,
3481     const TSourceLoc &identifierLocation,
3482     const ImmutableString &identifier,
3483     const TSourceLoc &indexLocation,
3484     const TVector<unsigned int> &arraySizes,
3485     const TSourceLoc &initLocation,
3486     TIntermTyped *initializer)
3487 {
3488     mDeferredNonEmptyDeclarationErrorCheck = false;
3489 
3490     declarationQualifierErrorCheck(elementType.qualifier, elementType.layoutQualifier,
3491                                    identifierLocation);
3492 
3493     nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
3494 
3495     checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
3496 
3497     TType *arrayType = new TType(elementType);
3498     arrayType->makeArrays(arraySizes);
3499 
3500     TIntermDeclaration *declaration = new TIntermDeclaration();
3501     declaration->setLine(identifierLocation);
3502 
3503     // initNode will correspond to the whole of "type b[n] = initializer".
3504     TIntermBinary *initNode = nullptr;
3505     if (executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
3506     {
3507         if (initNode)
3508         {
3509             declaration->appendDeclarator(initNode);
3510         }
3511     }
3512 
3513     return declaration;
3514 }
3515 
parseGlobalQualifierDeclaration(const TTypeQualifierBuilder & typeQualifierBuilder,const TSourceLoc & identifierLoc,const ImmutableString & identifier,const TSymbol * symbol)3516 TIntermGlobalQualifierDeclaration *TParseContext::parseGlobalQualifierDeclaration(
3517     const TTypeQualifierBuilder &typeQualifierBuilder,
3518     const TSourceLoc &identifierLoc,
3519     const ImmutableString &identifier,
3520     const TSymbol *symbol)
3521 {
3522     TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
3523 
3524     if (!typeQualifier.invariant && !typeQualifier.precise)
3525     {
3526         error(identifierLoc, "Expected invariant or precise", identifier);
3527         return nullptr;
3528     }
3529     if (typeQualifier.invariant && !checkIsAtGlobalLevel(identifierLoc, "invariant varying"))
3530     {
3531         return nullptr;
3532     }
3533     if (!symbol)
3534     {
3535         error(identifierLoc, "undeclared identifier declared as invariant or precise", identifier);
3536         return nullptr;
3537     }
3538     if (!IsQualifierUnspecified(typeQualifier.qualifier))
3539     {
3540         error(identifierLoc, "invariant or precise declaration specifies qualifier",
3541               getQualifierString(typeQualifier.qualifier));
3542     }
3543     if (typeQualifier.precision != EbpUndefined)
3544     {
3545         error(identifierLoc, "invariant or precise declaration specifies precision",
3546               getPrecisionString(typeQualifier.precision));
3547     }
3548     if (!typeQualifier.layoutQualifier.isEmpty())
3549     {
3550         error(identifierLoc, "invariant or precise declaration specifies layout", "'layout'");
3551     }
3552 
3553     const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
3554     if (!variable)
3555     {
3556         return nullptr;
3557     }
3558     const TType &type = variable->getType();
3559 
3560     checkInvariantVariableQualifier(typeQualifier.invariant, type.getQualifier(),
3561                                     typeQualifier.line);
3562     checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
3563 
3564     symbolTable.addInvariantVarying(*variable);
3565 
3566     TIntermSymbol *intermSymbol = new TIntermSymbol(variable);
3567     intermSymbol->setLine(identifierLoc);
3568 
3569     return new TIntermGlobalQualifierDeclaration(intermSymbol, typeQualifier.precise,
3570                                                  identifierLoc);
3571 }
3572 
parseDeclarator(TPublicType & publicType,const TSourceLoc & identifierLocation,const ImmutableString & identifier,TIntermDeclaration * declarationOut)3573 void TParseContext::parseDeclarator(TPublicType &publicType,
3574                                     const TSourceLoc &identifierLocation,
3575                                     const ImmutableString &identifier,
3576                                     TIntermDeclaration *declarationOut)
3577 {
3578     // If the declaration starting this declarator list was empty (example: int,), some checks were
3579     // not performed.
3580     if (mDeferredNonEmptyDeclarationErrorCheck)
3581     {
3582         nonEmptyDeclarationErrorCheck(publicType, identifierLocation);
3583         mDeferredNonEmptyDeclarationErrorCheck = false;
3584     }
3585 
3586     checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
3587 
3588     TType *type = new TType(publicType);
3589 
3590     checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier, type);
3591     checkTessellationShaderUnsizedArraysAndSetSize(identifierLocation, identifier, type);
3592 
3593     checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, type);
3594 
3595     if (IsAtomicCounter(type->getBasicType()))
3596     {
3597         checkAtomicCounterOffsetDoesNotOverlap(true, identifierLocation, type);
3598 
3599         checkAtomicCounterOffsetAlignment(identifierLocation, *type);
3600     }
3601 
3602     adjustRedeclaredBuiltInType(identifierLocation, identifier, type);
3603 
3604     TVariable *variable = nullptr;
3605     if (declareVariable(identifierLocation, identifier, type, &variable))
3606     {
3607         TIntermSymbol *symbol = new TIntermSymbol(variable);
3608         symbol->setLine(identifierLocation);
3609         declarationOut->appendDeclarator(symbol);
3610     }
3611 }
3612 
parseArrayDeclarator(TPublicType & elementType,const TSourceLoc & identifierLocation,const ImmutableString & identifier,const TSourceLoc & arrayLocation,const TVector<unsigned int> & arraySizes,TIntermDeclaration * declarationOut)3613 void TParseContext::parseArrayDeclarator(TPublicType &elementType,
3614                                          const TSourceLoc &identifierLocation,
3615                                          const ImmutableString &identifier,
3616                                          const TSourceLoc &arrayLocation,
3617                                          const TVector<unsigned int> &arraySizes,
3618                                          TIntermDeclaration *declarationOut)
3619 {
3620     // If the declaration starting this declarator list was empty (example: int,), some checks were
3621     // not performed.
3622     if (mDeferredNonEmptyDeclarationErrorCheck)
3623     {
3624         nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
3625         mDeferredNonEmptyDeclarationErrorCheck = false;
3626     }
3627 
3628     checkDeclaratorLocationIsNotSpecified(identifierLocation, elementType);
3629 
3630     if (checkIsValidTypeAndQualifierForArray(arrayLocation, elementType))
3631     {
3632         TType *arrayType = new TType(elementType);
3633         arrayType->makeArrays(arraySizes);
3634 
3635         checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier, arrayType);
3636         checkTessellationShaderUnsizedArraysAndSetSize(identifierLocation, identifier, arrayType);
3637 
3638         checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, arrayType);
3639 
3640         if (IsAtomicCounter(arrayType->getBasicType()))
3641         {
3642             checkAtomicCounterOffsetDoesNotOverlap(true, identifierLocation, arrayType);
3643 
3644             checkAtomicCounterOffsetAlignment(identifierLocation, *arrayType);
3645         }
3646 
3647         adjustRedeclaredBuiltInType(identifierLocation, identifier, arrayType);
3648 
3649         TVariable *variable = nullptr;
3650         if (declareVariable(identifierLocation, identifier, arrayType, &variable))
3651         {
3652             TIntermSymbol *symbol = new TIntermSymbol(variable);
3653             symbol->setLine(identifierLocation);
3654             declarationOut->appendDeclarator(symbol);
3655         }
3656     }
3657 }
3658 
parseInitDeclarator(const TPublicType & publicType,const TSourceLoc & identifierLocation,const ImmutableString & identifier,const TSourceLoc & initLocation,TIntermTyped * initializer,TIntermDeclaration * declarationOut)3659 void TParseContext::parseInitDeclarator(const TPublicType &publicType,
3660                                         const TSourceLoc &identifierLocation,
3661                                         const ImmutableString &identifier,
3662                                         const TSourceLoc &initLocation,
3663                                         TIntermTyped *initializer,
3664                                         TIntermDeclaration *declarationOut)
3665 {
3666     // If the declaration starting this declarator list was empty (example: int,), some checks were
3667     // not performed.
3668     if (mDeferredNonEmptyDeclarationErrorCheck)
3669     {
3670         nonEmptyDeclarationErrorCheck(publicType, identifierLocation);
3671         mDeferredNonEmptyDeclarationErrorCheck = false;
3672     }
3673 
3674     checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
3675 
3676     TIntermBinary *initNode = nullptr;
3677     TType *type             = new TType(publicType);
3678     if (executeInitializer(identifierLocation, identifier, type, initializer, &initNode))
3679     {
3680         //
3681         // build the intermediate representation
3682         //
3683         if (initNode)
3684         {
3685             declarationOut->appendDeclarator(initNode);
3686         }
3687     }
3688 }
3689 
parseArrayInitDeclarator(const TPublicType & elementType,const TSourceLoc & identifierLocation,const ImmutableString & identifier,const TSourceLoc & indexLocation,const TVector<unsigned int> & arraySizes,const TSourceLoc & initLocation,TIntermTyped * initializer,TIntermDeclaration * declarationOut)3690 void TParseContext::parseArrayInitDeclarator(const TPublicType &elementType,
3691                                              const TSourceLoc &identifierLocation,
3692                                              const ImmutableString &identifier,
3693                                              const TSourceLoc &indexLocation,
3694                                              const TVector<unsigned int> &arraySizes,
3695                                              const TSourceLoc &initLocation,
3696                                              TIntermTyped *initializer,
3697                                              TIntermDeclaration *declarationOut)
3698 {
3699     // If the declaration starting this declarator list was empty (example: int,), some checks were
3700     // not performed.
3701     if (mDeferredNonEmptyDeclarationErrorCheck)
3702     {
3703         nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
3704         mDeferredNonEmptyDeclarationErrorCheck = false;
3705     }
3706 
3707     checkDeclaratorLocationIsNotSpecified(identifierLocation, elementType);
3708 
3709     checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
3710 
3711     TType *arrayType = new TType(elementType);
3712     arrayType->makeArrays(arraySizes);
3713 
3714     // initNode will correspond to the whole of "b[n] = initializer".
3715     TIntermBinary *initNode = nullptr;
3716     if (executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
3717     {
3718         if (initNode)
3719         {
3720             declarationOut->appendDeclarator(initNode);
3721         }
3722     }
3723 }
3724 
addEmptyStatement(const TSourceLoc & location)3725 TIntermNode *TParseContext::addEmptyStatement(const TSourceLoc &location)
3726 {
3727     // It's simpler to parse an empty statement as a constant expression rather than having a
3728     // different type of node just for empty statements, that will be pruned from the AST anyway.
3729     TIntermNode *node = CreateZeroNode(TType(EbtInt, EbpMedium));
3730     node->setLine(location);
3731     return node;
3732 }
3733 
setAtomicCounterBindingDefaultOffset(const TPublicType & publicType,const TSourceLoc & location)3734 void TParseContext::setAtomicCounterBindingDefaultOffset(const TPublicType &publicType,
3735                                                          const TSourceLoc &location)
3736 {
3737     const TLayoutQualifier &layoutQualifier = publicType.layoutQualifier;
3738     checkAtomicCounterBindingIsValid(location, layoutQualifier.binding);
3739     if (layoutQualifier.binding == -1 || layoutQualifier.offset == -1)
3740     {
3741         error(location, "Requires both binding and offset", "layout");
3742         return;
3743     }
3744     mAtomicCounterBindingStates[layoutQualifier.binding].setDefaultOffset(layoutQualifier.offset);
3745 }
3746 
parseDefaultPrecisionQualifier(const TPrecision precision,const TPublicType & type,const TSourceLoc & loc)3747 void TParseContext::parseDefaultPrecisionQualifier(const TPrecision precision,
3748                                                    const TPublicType &type,
3749                                                    const TSourceLoc &loc)
3750 {
3751     if ((precision == EbpHigh) && (getShaderType() == GL_FRAGMENT_SHADER) &&
3752         !getFragmentPrecisionHigh())
3753     {
3754         error(loc, "precision is not supported in fragment shader", "highp");
3755     }
3756 
3757     if (!CanSetDefaultPrecisionOnType(type))
3758     {
3759         error(loc, "illegal type argument for default precision qualifier",
3760               getBasicString(type.getBasicType()));
3761         return;
3762     }
3763     symbolTable.setDefaultPrecision(type.getBasicType(), precision);
3764 }
3765 
checkPrimitiveTypeMatchesTypeQualifier(const TTypeQualifier & typeQualifier)3766 bool TParseContext::checkPrimitiveTypeMatchesTypeQualifier(const TTypeQualifier &typeQualifier)
3767 {
3768     switch (typeQualifier.layoutQualifier.primitiveType)
3769     {
3770         case EptLines:
3771         case EptLinesAdjacency:
3772         case EptTriangles:
3773         case EptTrianglesAdjacency:
3774             return typeQualifier.qualifier == EvqGeometryIn;
3775 
3776         case EptLineStrip:
3777         case EptTriangleStrip:
3778             return typeQualifier.qualifier == EvqGeometryOut;
3779 
3780         case EptPoints:
3781             return true;
3782 
3783         default:
3784             UNREACHABLE();
3785             return false;
3786     }
3787 }
3788 
setGeometryShaderInputArraySize(unsigned int inputArraySize,const TSourceLoc & line)3789 void TParseContext::setGeometryShaderInputArraySize(unsigned int inputArraySize,
3790                                                     const TSourceLoc &line)
3791 {
3792     if (!symbolTable.setGlInArraySize(inputArraySize))
3793     {
3794         error(line,
3795               "Array size or input primitive declaration doesn't match the size of earlier sized "
3796               "array inputs.",
3797               "layout");
3798     }
3799     mGeometryInputArraySize = inputArraySize;
3800 }
3801 
parseGeometryShaderInputLayoutQualifier(const TTypeQualifier & typeQualifier)3802 bool TParseContext::parseGeometryShaderInputLayoutQualifier(const TTypeQualifier &typeQualifier)
3803 {
3804     ASSERT(typeQualifier.qualifier == EvqGeometryIn);
3805 
3806     const TLayoutQualifier &layoutQualifier = typeQualifier.layoutQualifier;
3807 
3808     if (layoutQualifier.maxVertices != -1)
3809     {
3810         error(typeQualifier.line,
3811               "max_vertices can only be declared in 'out' layout in a geometry shader", "layout");
3812         return false;
3813     }
3814 
3815     // Set mGeometryInputPrimitiveType if exists
3816     if (layoutQualifier.primitiveType != EptUndefined)
3817     {
3818         if (!checkPrimitiveTypeMatchesTypeQualifier(typeQualifier))
3819         {
3820             error(typeQualifier.line, "invalid primitive type for 'in' layout", "layout");
3821             return false;
3822         }
3823 
3824         if (mGeometryShaderInputPrimitiveType == EptUndefined)
3825         {
3826             mGeometryShaderInputPrimitiveType = layoutQualifier.primitiveType;
3827             setGeometryShaderInputArraySize(
3828                 GetGeometryShaderInputArraySize(mGeometryShaderInputPrimitiveType),
3829                 typeQualifier.line);
3830         }
3831         else if (mGeometryShaderInputPrimitiveType != layoutQualifier.primitiveType)
3832         {
3833             error(typeQualifier.line, "primitive doesn't match earlier input primitive declaration",
3834                   "layout");
3835             return false;
3836         }
3837 
3838         // Size any implicitly sized arrays that have already been declared.
3839         for (TType *type : mDeferredArrayTypesToSize)
3840         {
3841             type->sizeOutermostUnsizedArray(
3842                 symbolTable.getGlInVariableWithArraySize()->getType().getOutermostArraySize());
3843         }
3844         mDeferredArrayTypesToSize.clear();
3845     }
3846 
3847     // Set mGeometryInvocations if exists
3848     if (layoutQualifier.invocations > 0)
3849     {
3850         if (mGeometryShaderInvocations == 0)
3851         {
3852             mGeometryShaderInvocations = layoutQualifier.invocations;
3853         }
3854         else if (mGeometryShaderInvocations != layoutQualifier.invocations)
3855         {
3856             error(typeQualifier.line, "invocations contradicts to the earlier declaration",
3857                   "layout");
3858             return false;
3859         }
3860     }
3861 
3862     return true;
3863 }
3864 
parseGeometryShaderOutputLayoutQualifier(const TTypeQualifier & typeQualifier)3865 bool TParseContext::parseGeometryShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier)
3866 {
3867     ASSERT(typeQualifier.qualifier == EvqGeometryOut);
3868 
3869     const TLayoutQualifier &layoutQualifier = typeQualifier.layoutQualifier;
3870 
3871     if (layoutQualifier.invocations > 0)
3872     {
3873         error(typeQualifier.line,
3874               "invocations can only be declared in 'in' layout in a geometry shader", "layout");
3875         return false;
3876     }
3877 
3878     // Set mGeometryOutputPrimitiveType if exists
3879     if (layoutQualifier.primitiveType != EptUndefined)
3880     {
3881         if (!checkPrimitiveTypeMatchesTypeQualifier(typeQualifier))
3882         {
3883             error(typeQualifier.line, "invalid primitive type for 'out' layout", "layout");
3884             return false;
3885         }
3886 
3887         if (mGeometryShaderOutputPrimitiveType == EptUndefined)
3888         {
3889             mGeometryShaderOutputPrimitiveType = layoutQualifier.primitiveType;
3890         }
3891         else if (mGeometryShaderOutputPrimitiveType != layoutQualifier.primitiveType)
3892         {
3893             error(typeQualifier.line,
3894                   "primitive doesn't match earlier output primitive declaration", "layout");
3895             return false;
3896         }
3897     }
3898 
3899     // Set mGeometryMaxVertices if exists
3900     if (layoutQualifier.maxVertices > -1)
3901     {
3902         if (mGeometryShaderMaxVertices == -1)
3903         {
3904             mGeometryShaderMaxVertices = layoutQualifier.maxVertices;
3905         }
3906         else if (mGeometryShaderMaxVertices != layoutQualifier.maxVertices)
3907         {
3908             error(typeQualifier.line, "max_vertices contradicts to the earlier declaration",
3909                   "layout");
3910             return false;
3911         }
3912     }
3913 
3914     return true;
3915 }
3916 
parseTessControlShaderOutputLayoutQualifier(const TTypeQualifier & typeQualifier)3917 bool TParseContext::parseTessControlShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier)
3918 {
3919     ASSERT(typeQualifier.qualifier == EvqTessControlOut);
3920 
3921     const TLayoutQualifier &layoutQualifier = typeQualifier.layoutQualifier;
3922 
3923     if (layoutQualifier.vertices == 0)
3924     {
3925         error(typeQualifier.line, "No vertices specified", "layout");
3926         return false;
3927     }
3928 
3929     // Set mTessControlShaderOutputVertices if exists
3930     if (mTessControlShaderOutputVertices == 0)
3931     {
3932         mTessControlShaderOutputVertices = layoutQualifier.vertices;
3933 
3934         // Size any implicitly sized arrays that have already been declared.
3935         for (TType *type : mDeferredArrayTypesToSize)
3936         {
3937             type->sizeOutermostUnsizedArray(mTessControlShaderOutputVertices);
3938         }
3939         mDeferredArrayTypesToSize.clear();
3940     }
3941     else
3942     {
3943         error(typeQualifier.line, "Duplicated vertices specified", "layout");
3944     }
3945     return true;
3946 }
3947 
parseTessEvaluationShaderInputLayoutQualifier(const TTypeQualifier & typeQualifier)3948 bool TParseContext::parseTessEvaluationShaderInputLayoutQualifier(
3949     const TTypeQualifier &typeQualifier)
3950 {
3951     ASSERT(typeQualifier.qualifier == EvqTessEvaluationIn);
3952 
3953     const TLayoutQualifier &layoutQualifier = typeQualifier.layoutQualifier;
3954 
3955     // Set mTessEvaluationShaderInputPrimitiveType if exists
3956     if (layoutQualifier.tesPrimitiveType != EtetUndefined)
3957     {
3958         if (mTessEvaluationShaderInputPrimitiveType == EtetUndefined)
3959         {
3960             mTessEvaluationShaderInputPrimitiveType = layoutQualifier.tesPrimitiveType;
3961         }
3962         else
3963         {
3964             error(typeQualifier.line, "Duplicated primitive type declaration", "layout");
3965         }
3966     }
3967     // Set mTessEvaluationShaderVertexSpacingType if exists
3968     if (layoutQualifier.tesVertexSpacingType != EtetUndefined)
3969     {
3970         if (mTessEvaluationShaderInputVertexSpacingType == EtetUndefined)
3971         {
3972             mTessEvaluationShaderInputVertexSpacingType = layoutQualifier.tesVertexSpacingType;
3973         }
3974         else
3975         {
3976             error(typeQualifier.line, "Duplicated vertex spacing declaration", "layout");
3977         }
3978     }
3979     // Set mTessEvaluationShaderInputOrderingType if exists
3980     if (layoutQualifier.tesOrderingType != EtetUndefined)
3981     {
3982         if (mTessEvaluationShaderInputOrderingType == EtetUndefined)
3983         {
3984             mTessEvaluationShaderInputOrderingType = layoutQualifier.tesOrderingType;
3985         }
3986         else
3987         {
3988             error(typeQualifier.line, "Duplicated ordering declaration", "layout");
3989         }
3990     }
3991     // Set mTessEvaluationShaderInputPointType if exists
3992     if (layoutQualifier.tesPointType != EtetUndefined)
3993     {
3994         if (mTessEvaluationShaderInputPointType == EtetUndefined)
3995         {
3996             mTessEvaluationShaderInputPointType = layoutQualifier.tesPointType;
3997         }
3998         else
3999         {
4000             error(typeQualifier.line, "Duplicated point type declaration", "layout");
4001         }
4002     }
4003 
4004     return true;
4005 }
4006 
parseGlobalLayoutQualifier(const TTypeQualifierBuilder & typeQualifierBuilder)4007 void TParseContext::parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder)
4008 {
4009     TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
4010     const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier;
4011 
4012     checkInvariantVariableQualifier(typeQualifier.invariant, typeQualifier.qualifier,
4013                                     typeQualifier.line);
4014 
4015     // It should never be the case, but some strange parser errors can send us here.
4016     if (layoutQualifier.isEmpty())
4017     {
4018         error(typeQualifier.line, "Error during layout qualifier parsing.", "?");
4019         return;
4020     }
4021 
4022     if (!layoutQualifier.isCombinationValid())
4023     {
4024         error(typeQualifier.line, "invalid layout qualifier combination", "layout");
4025         return;
4026     }
4027 
4028     checkIndexIsNotSpecified(typeQualifier.line, layoutQualifier.index);
4029 
4030     checkBindingIsNotSpecified(typeQualifier.line, layoutQualifier.binding);
4031 
4032     checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
4033 
4034     checkInternalFormatIsNotSpecified(typeQualifier.line, layoutQualifier.imageInternalFormat);
4035 
4036     checkDepthIsNotSpecified(typeQualifier.line, layoutQualifier.depth);
4037 
4038     checkYuvIsNotSpecified(typeQualifier.line, layoutQualifier.yuv);
4039 
4040     checkOffsetIsNotSpecified(typeQualifier.line, layoutQualifier.offset);
4041 
4042     checkStd430IsForShaderStorageBlock(typeQualifier.line, layoutQualifier.blockStorage,
4043                                        typeQualifier.qualifier);
4044 
4045     checkAdvancedBlendEquationsNotSpecified(
4046         typeQualifier.line, layoutQualifier.advancedBlendEquations, typeQualifier.qualifier);
4047 
4048     if (typeQualifier.qualifier != EvqFragmentIn)
4049     {
4050         checkEarlyFragmentTestsIsNotSpecified(typeQualifier.line,
4051                                               layoutQualifier.earlyFragmentTests);
4052     }
4053 
4054     if (typeQualifier.qualifier == EvqComputeIn)
4055     {
4056         if (mComputeShaderLocalSizeDeclared &&
4057             !layoutQualifier.isLocalSizeEqual(mComputeShaderLocalSize))
4058         {
4059             error(typeQualifier.line, "Work group size does not match the previous declaration",
4060                   "layout");
4061             return;
4062         }
4063 
4064         if (mShaderVersion < 310)
4065         {
4066             error(typeQualifier.line, "in type qualifier supported in GLSL ES 3.10 only", "layout");
4067             return;
4068         }
4069 
4070         if (!layoutQualifier.localSize.isAnyValueSet())
4071         {
4072             error(typeQualifier.line, "No local work group size specified", "layout");
4073             return;
4074         }
4075 
4076         const TVariable *maxComputeWorkGroupSize = static_cast<const TVariable *>(
4077             symbolTable.findBuiltIn(ImmutableString("gl_MaxComputeWorkGroupSize"), mShaderVersion));
4078 
4079         const TConstantUnion *maxComputeWorkGroupSizeData =
4080             maxComputeWorkGroupSize->getConstPointer();
4081 
4082         for (size_t i = 0u; i < layoutQualifier.localSize.size(); ++i)
4083         {
4084             if (layoutQualifier.localSize[i] != -1)
4085             {
4086                 mComputeShaderLocalSize[i]             = layoutQualifier.localSize[i];
4087                 const int maxComputeWorkGroupSizeValue = maxComputeWorkGroupSizeData[i].getIConst();
4088                 if (mComputeShaderLocalSize[i] < 1 ||
4089                     mComputeShaderLocalSize[i] > maxComputeWorkGroupSizeValue)
4090                 {
4091                     std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
4092                     reasonStream << "invalid value: Value must be at least 1 and no greater than "
4093                                  << maxComputeWorkGroupSizeValue;
4094                     const std::string &reason = reasonStream.str();
4095 
4096                     error(typeQualifier.line, reason.c_str(), getWorkGroupSizeString(i));
4097                     return;
4098                 }
4099             }
4100         }
4101 
4102         mComputeShaderLocalSizeDeclared = true;
4103     }
4104     else if (typeQualifier.qualifier == EvqGeometryIn)
4105     {
4106         if (mShaderVersion < 310)
4107         {
4108             error(typeQualifier.line, "in type qualifier supported in GLSL ES 3.10 only", "layout");
4109             return;
4110         }
4111 
4112         if (!parseGeometryShaderInputLayoutQualifier(typeQualifier))
4113         {
4114             return;
4115         }
4116     }
4117     else if (typeQualifier.qualifier == EvqGeometryOut)
4118     {
4119         if (mShaderVersion < 310)
4120         {
4121             error(typeQualifier.line, "out type qualifier supported in GLSL ES 3.10 only",
4122                   "layout");
4123             return;
4124         }
4125 
4126         if (!parseGeometryShaderOutputLayoutQualifier(typeQualifier))
4127         {
4128             return;
4129         }
4130     }
4131     else if (anyMultiviewExtensionAvailable() && typeQualifier.qualifier == EvqVertexIn)
4132     {
4133         // This error is only specified in WebGL, but tightens unspecified behavior in the native
4134         // specification.
4135         if (mNumViews != -1 && layoutQualifier.numViews != mNumViews)
4136         {
4137             error(typeQualifier.line, "Number of views does not match the previous declaration",
4138                   "layout");
4139             return;
4140         }
4141 
4142         if (layoutQualifier.numViews == -1)
4143         {
4144             error(typeQualifier.line, "No num_views specified", "layout");
4145             return;
4146         }
4147 
4148         if (layoutQualifier.numViews > mMaxNumViews)
4149         {
4150             error(typeQualifier.line, "num_views greater than the value of GL_MAX_VIEWS_OVR",
4151                   "layout");
4152             return;
4153         }
4154 
4155         mNumViews = layoutQualifier.numViews;
4156     }
4157     else if (typeQualifier.qualifier == EvqFragmentIn)
4158     {
4159         if (mShaderVersion < 310)
4160         {
4161             error(typeQualifier.line,
4162                   "in type qualifier without variable declaration supported in GLSL ES 3.10 and "
4163                   "after",
4164                   "layout");
4165             return;
4166         }
4167 
4168         if (!layoutQualifier.earlyFragmentTests)
4169         {
4170             error(typeQualifier.line,
4171                   "only early_fragment_tests is allowed as layout qualifier when not declaring a "
4172                   "variable",
4173                   "layout");
4174             return;
4175         }
4176 
4177         mEarlyFragmentTestsSpecified = true;
4178     }
4179     else if (typeQualifier.qualifier == EvqFragmentOut)
4180     {
4181         if (mShaderVersion < 320 && !isExtensionEnabled(TExtension::KHR_blend_equation_advanced))
4182         {
4183             error(typeQualifier.line,
4184                   "out type qualifier without variable declaration is supported in GLSL ES 3.20,"
4185                   " or if GL_KHR_blend_equation_advanced is enabled",
4186                   "layout");
4187             return;
4188         }
4189 
4190         if (!layoutQualifier.advancedBlendEquations.any())
4191         {
4192             error(typeQualifier.line,
4193                   "only blend equations are allowed as layout qualifier when not declaring a "
4194                   "variable",
4195                   "layout");
4196             return;
4197         }
4198 
4199         errorIfPLSDeclared(typeQualifier.line, PLSIllegalOperations::EnableAdvancedBlendEquation);
4200         mAdvancedBlendEquations |= layoutQualifier.advancedBlendEquations;
4201     }
4202     else if (typeQualifier.qualifier == EvqTessControlOut)
4203     {
4204         if (mShaderVersion < 310)
4205         {
4206             error(typeQualifier.line, "out type qualifier supported in GLSL ES 3.10 and after",
4207                   "layout");
4208             return;
4209         }
4210 
4211         if (!parseTessControlShaderOutputLayoutQualifier(typeQualifier))
4212         {
4213             return;
4214         }
4215     }
4216     else if (typeQualifier.qualifier == EvqTessEvaluationIn)
4217     {
4218         if (mShaderVersion < 310)
4219         {
4220             error(typeQualifier.line, "in type qualifier supported in GLSL ES 3.10 and after",
4221                   "layout");
4222             return;
4223         }
4224 
4225         if (!parseTessEvaluationShaderInputLayoutQualifier(typeQualifier))
4226         {
4227             return;
4228         }
4229     }
4230     else
4231     {
4232         if (!checkWorkGroupSizeIsNotSpecified(typeQualifier.line, layoutQualifier))
4233         {
4234             return;
4235         }
4236 
4237         if (typeQualifier.qualifier != EvqUniform && typeQualifier.qualifier != EvqBuffer)
4238         {
4239             error(typeQualifier.line, "invalid qualifier: global layout can only be set for blocks",
4240                   getQualifierString(typeQualifier.qualifier));
4241             return;
4242         }
4243 
4244         if (mShaderVersion < 300)
4245         {
4246             error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 and after",
4247                   "layout");
4248             return;
4249         }
4250 
4251         checkLocationIsNotSpecified(typeQualifier.line, layoutQualifier);
4252 
4253         if (layoutQualifier.matrixPacking != EmpUnspecified)
4254         {
4255             if (typeQualifier.qualifier == EvqUniform)
4256             {
4257                 mDefaultUniformMatrixPacking = layoutQualifier.matrixPacking;
4258             }
4259             else if (typeQualifier.qualifier == EvqBuffer)
4260             {
4261                 mDefaultBufferMatrixPacking = layoutQualifier.matrixPacking;
4262             }
4263         }
4264 
4265         if (layoutQualifier.blockStorage != EbsUnspecified)
4266         {
4267             if (typeQualifier.qualifier == EvqUniform)
4268             {
4269                 mDefaultUniformBlockStorage = layoutQualifier.blockStorage;
4270             }
4271             else if (typeQualifier.qualifier == EvqBuffer)
4272             {
4273                 mDefaultBufferBlockStorage = layoutQualifier.blockStorage;
4274             }
4275         }
4276     }
4277 }
4278 
createPrototypeNodeFromFunction(const TFunction & function,const TSourceLoc & location,bool insertParametersToSymbolTable)4279 TIntermFunctionPrototype *TParseContext::createPrototypeNodeFromFunction(
4280     const TFunction &function,
4281     const TSourceLoc &location,
4282     bool insertParametersToSymbolTable)
4283 {
4284     checkIsNotReserved(location, function.name());
4285 
4286     TIntermFunctionPrototype *prototype = new TIntermFunctionPrototype(&function);
4287     prototype->setLine(location);
4288 
4289     for (size_t i = 0; i < function.getParamCount(); i++)
4290     {
4291         const TVariable *param = function.getParam(i);
4292 
4293         // If the parameter has no name, it's not an error, just don't add it to symbol table (could
4294         // be used for unused args).
4295         if (param->symbolType() != SymbolType::Empty)
4296         {
4297             if (insertParametersToSymbolTable)
4298             {
4299                 if (!symbolTable.declare(const_cast<TVariable *>(param)))
4300                 {
4301                     error(location, "redefinition", param->name());
4302                 }
4303             }
4304             // Unsized type of a named parameter should have already been checked and sanitized.
4305             ASSERT(!param->getType().isUnsizedArray());
4306         }
4307         else
4308         {
4309             if (param->getType().isUnsizedArray())
4310             {
4311                 error(location, "function parameter array must be sized at compile time", "[]");
4312                 // We don't need to size the arrays since the parameter is unnamed and hence
4313                 // inaccessible.
4314             }
4315         }
4316     }
4317     return prototype;
4318 }
4319 
addFunctionPrototypeDeclaration(const TFunction & parsedFunction,const TSourceLoc & location)4320 TIntermFunctionPrototype *TParseContext::addFunctionPrototypeDeclaration(
4321     const TFunction &parsedFunction,
4322     const TSourceLoc &location)
4323 {
4324     // Note: function found from the symbol table could be the same as parsedFunction if this is the
4325     // first declaration. Either way the instance in the symbol table is used to track whether the
4326     // function is declared multiple times.
4327     bool hadPrototypeDeclaration = false;
4328     const TFunction *function    = symbolTable.markFunctionHasPrototypeDeclaration(
4329         parsedFunction.getMangledName(), &hadPrototypeDeclaration);
4330 
4331     if (hadPrototypeDeclaration && mShaderVersion == 100)
4332     {
4333         // ESSL 1.00.17 section 4.2.7.
4334         // Doesn't apply to ESSL 3.00.4: see section 4.2.3.
4335         error(location, "duplicate function prototype declarations are not allowed", "function");
4336     }
4337 
4338     TIntermFunctionPrototype *prototype =
4339         createPrototypeNodeFromFunction(*function, location, false);
4340 
4341     symbolTable.pop();
4342 
4343     if (!symbolTable.atGlobalLevel())
4344     {
4345         // ESSL 3.00.4 section 4.2.4.
4346         error(location, "local function prototype declarations are not allowed", "function");
4347     }
4348 
4349     return prototype;
4350 }
4351 
addFunctionDefinition(TIntermFunctionPrototype * functionPrototype,TIntermBlock * functionBody,const TSourceLoc & location)4352 TIntermFunctionDefinition *TParseContext::addFunctionDefinition(
4353     TIntermFunctionPrototype *functionPrototype,
4354     TIntermBlock *functionBody,
4355     const TSourceLoc &location)
4356 {
4357     // Undo push at end of parseFunctionDefinitionHeader() below for ESSL1.00 case
4358     if (mFunctionBodyNewScope)
4359     {
4360         mFunctionBodyNewScope = false;
4361         symbolTable.pop();
4362     }
4363 
4364     // Check that non-void functions have at least one return statement.
4365     if (mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue)
4366     {
4367         error(location,
4368               "function does not return a value:", functionPrototype->getFunction()->name());
4369     }
4370 
4371     if (functionBody == nullptr)
4372     {
4373         functionBody = new TIntermBlock();
4374         functionBody->setLine(location);
4375     }
4376     TIntermFunctionDefinition *functionNode =
4377         new TIntermFunctionDefinition(functionPrototype, functionBody);
4378     functionNode->setLine(location);
4379 
4380     symbolTable.pop();
4381     return functionNode;
4382 }
4383 
parseFunctionDefinitionHeader(const TSourceLoc & location,const TFunction * function,TIntermFunctionPrototype ** prototypeOut)4384 void TParseContext::parseFunctionDefinitionHeader(const TSourceLoc &location,
4385                                                   const TFunction *function,
4386                                                   TIntermFunctionPrototype **prototypeOut)
4387 {
4388     ASSERT(function);
4389 
4390     bool wasDefined = false;
4391     function        = symbolTable.setFunctionParameterNamesFromDefinition(function, &wasDefined);
4392     if (wasDefined)
4393     {
4394         error(location, "function already has a body", function->name());
4395     }
4396 
4397     // Remember the return type for later checking for return statements.
4398     mCurrentFunctionType  = &(function->getReturnType());
4399     mFunctionReturnsValue = false;
4400 
4401     *prototypeOut = createPrototypeNodeFromFunction(*function, location, true);
4402     setLoopNestingLevel(0);
4403 
4404     // ESSL 1.00 spec allows for variable in function body to redefine parameter
4405     if (IsSpecWithFunctionBodyNewScope(mShaderSpec, mShaderVersion))
4406     {
4407         mFunctionBodyNewScope = true;
4408         symbolTable.push();
4409     }
4410 }
4411 
parseFunctionDeclarator(const TSourceLoc & location,TFunction * function)4412 TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TFunction *function)
4413 {
4414     //
4415     // We don't know at this point whether this is a function definition or a prototype.
4416     // The definition production code will check for redefinitions.
4417     // In the case of ESSL 1.00 the prototype production code will also check for redeclarations.
4418     //
4419 
4420     for (size_t i = 0u; i < function->getParamCount(); ++i)
4421     {
4422         const TVariable *param = function->getParam(i);
4423         const TType &paramType = param->getType();
4424 
4425         if (paramType.isStructSpecifier())
4426         {
4427             // ESSL 3.00.6 section 12.10.
4428             error(location, "Function parameter type cannot be a structure definition",
4429                   function->name());
4430         }
4431 
4432         checkPrecisionSpecified(location, paramType.getPrecision(), paramType.getBasicType());
4433     }
4434 
4435     if (getShaderVersion() >= 300)
4436     {
4437         if (symbolTable.isUnmangledBuiltInName(function->name(), getShaderVersion(),
4438                                                extensionBehavior()))
4439         {
4440             // With ESSL 3.00 and above, names of built-in functions cannot be redeclared as
4441             // functions. Therefore overloading or redefining builtin functions is an error.
4442             error(location, "Name of a built-in function cannot be redeclared as function",
4443                   function->name());
4444         }
4445     }
4446     else
4447     {
4448         // ESSL 1.00.17 section 4.2.6: built-ins can be overloaded but not redefined. We assume that
4449         // this applies to redeclarations as well.
4450         const TSymbol *builtIn =
4451             symbolTable.findBuiltIn(function->getMangledName(), getShaderVersion());
4452         if (builtIn)
4453         {
4454             error(location, "built-in functions cannot be redefined", function->name());
4455         }
4456     }
4457 
4458     // Return types and parameter qualifiers must match in all redeclarations, so those are checked
4459     // here.
4460     const TFunction *prevDec =
4461         static_cast<const TFunction *>(symbolTable.findGlobal(function->getMangledName()));
4462     if (prevDec)
4463     {
4464         if (prevDec->getReturnType() != function->getReturnType())
4465         {
4466             error(location, "function must have the same return type in all of its declarations",
4467                   function->getReturnType().getBasicString());
4468         }
4469         for (size_t i = 0; i < prevDec->getParamCount(); ++i)
4470         {
4471             if (prevDec->getParam(i)->getType().getQualifier() !=
4472                 function->getParam(i)->getType().getQualifier())
4473             {
4474                 error(location,
4475                       "function must have the same parameter qualifiers in all of its declarations",
4476                       function->getParam(i)->getType().getQualifierString());
4477             }
4478         }
4479     }
4480 
4481     // Check for previously declared variables using the same name.
4482     const TSymbol *prevSym   = symbolTable.find(function->name(), getShaderVersion());
4483     bool insertUnmangledName = true;
4484     if (prevSym)
4485     {
4486         if (!prevSym->isFunction())
4487         {
4488             error(location, "redefinition of a function", function->name());
4489         }
4490         insertUnmangledName = false;
4491     }
4492     // Parsing is at the inner scope level of the function's arguments and body statement at this
4493     // point, but declareUserDefinedFunction takes care of declaring the function at the global
4494     // scope.
4495     symbolTable.declareUserDefinedFunction(function, insertUnmangledName);
4496 
4497     // Raise error message if main function takes any parameters or return anything other than void
4498     if (function->isMain())
4499     {
4500         if (function->getParamCount() > 0)
4501         {
4502             error(location, "function cannot take any parameter(s)", "main");
4503         }
4504         if (function->getReturnType().getBasicType() != EbtVoid)
4505         {
4506             error(location, "main function cannot return a value",
4507                   function->getReturnType().getBasicString());
4508         }
4509     }
4510 
4511     mDeclaringMain = function->isMain();
4512 
4513     //
4514     // If this is a redeclaration, it could also be a definition, in which case, we want to use the
4515     // variable names from this one, and not the one that's
4516     // being redeclared.  So, pass back up this declaration, not the one in the symbol table.
4517     //
4518     return function;
4519 }
4520 
parseFunctionHeader(const TPublicType & type,const ImmutableString & name,const TSourceLoc & location)4521 TFunction *TParseContext::parseFunctionHeader(const TPublicType &type,
4522                                               const ImmutableString &name,
4523                                               const TSourceLoc &location)
4524 {
4525     if (type.qualifier != EvqGlobal && type.qualifier != EvqTemporary)
4526     {
4527         error(location, "no qualifiers allowed for function return",
4528               getQualifierString(type.qualifier));
4529     }
4530     if (!type.layoutQualifier.isEmpty())
4531     {
4532         error(location, "no qualifiers allowed for function return", "layout");
4533     }
4534     // make sure an opaque type is not involved as well...
4535     std::string reason(getBasicString(type.getBasicType()));
4536     reason += "s can't be function return values";
4537     checkIsNotOpaqueType(location, type.typeSpecifierNonArray, reason.c_str());
4538     if (mShaderVersion < 300)
4539     {
4540         // Array return values are forbidden, but there's also no valid syntax for declaring array
4541         // return values in ESSL 1.00.
4542         ASSERT(!type.isArray() || mDiagnostics->numErrors() > 0);
4543 
4544         if (type.isStructureContainingArrays())
4545         {
4546             // ESSL 1.00.17 section 6.1 Function Definitions
4547             TInfoSinkBase typeString;
4548             typeString << TType(type);
4549             error(location, "structures containing arrays can't be function return values",
4550                   typeString.c_str());
4551         }
4552     }
4553 
4554     // Add the function as a prototype after parsing it (we do not support recursion)
4555     return new TFunction(&symbolTable, name, SymbolType::UserDefined, new TType(type), false);
4556 }
4557 
addNonConstructorFunc(const ImmutableString & name,const TSymbol * symbol)4558 TFunctionLookup *TParseContext::addNonConstructorFunc(const ImmutableString &name,
4559                                                       const TSymbol *symbol)
4560 {
4561     return TFunctionLookup::CreateFunctionCall(name, symbol);
4562 }
4563 
addConstructorFunc(const TPublicType & publicType)4564 TFunctionLookup *TParseContext::addConstructorFunc(const TPublicType &publicType)
4565 {
4566     if (mShaderVersion < 300 && publicType.isArray())
4567     {
4568         error(publicType.getLine(), "array constructor supported in GLSL ES 3.00 and above only",
4569               "[]");
4570     }
4571     if (publicType.isStructSpecifier())
4572     {
4573         error(publicType.getLine(), "constructor can't be a structure definition",
4574               getBasicString(publicType.getBasicType()));
4575     }
4576 
4577     TType *type = new TType(publicType);
4578     if (!type->canBeConstructed())
4579     {
4580         error(publicType.getLine(), "cannot construct this type",
4581               getBasicString(publicType.getBasicType()));
4582         type->setBasicType(EbtFloat);
4583     }
4584     return TFunctionLookup::CreateConstructor(type);
4585 }
4586 
checkIsNotUnsizedArray(const TSourceLoc & line,const char * errorMessage,const ImmutableString & token,TType * arrayType)4587 void TParseContext::checkIsNotUnsizedArray(const TSourceLoc &line,
4588                                            const char *errorMessage,
4589                                            const ImmutableString &token,
4590                                            TType *arrayType)
4591 {
4592     if (arrayType->isUnsizedArray())
4593     {
4594         error(line, errorMessage, token);
4595         arrayType->sizeUnsizedArrays(TSpan<const unsigned int>());
4596     }
4597 }
4598 
parseParameterDeclarator(TType * type,const ImmutableString & name,const TSourceLoc & nameLoc)4599 TParameter TParseContext::parseParameterDeclarator(TType *type,
4600                                                    const ImmutableString &name,
4601                                                    const TSourceLoc &nameLoc)
4602 {
4603     ASSERT(type);
4604     checkIsNotUnsizedArray(nameLoc, "function parameter array must specify a size", name, type);
4605     if (type->getBasicType() == EbtVoid)
4606     {
4607         error(nameLoc, "illegal use of type 'void'", name);
4608     }
4609     checkIsNotReserved(nameLoc, name);
4610     TParameter param = {name.data(), type};
4611     return param;
4612 }
4613 
parseParameterDeclarator(const TPublicType & publicType,const ImmutableString & name,const TSourceLoc & nameLoc)4614 TParameter TParseContext::parseParameterDeclarator(const TPublicType &publicType,
4615                                                    const ImmutableString &name,
4616                                                    const TSourceLoc &nameLoc)
4617 {
4618     TType *type = new TType(publicType);
4619     return parseParameterDeclarator(type, name, nameLoc);
4620 }
4621 
parseParameterArrayDeclarator(const ImmutableString & name,const TSourceLoc & nameLoc,const TVector<unsigned int> & arraySizes,const TSourceLoc & arrayLoc,TPublicType * elementType)4622 TParameter TParseContext::parseParameterArrayDeclarator(const ImmutableString &name,
4623                                                         const TSourceLoc &nameLoc,
4624                                                         const TVector<unsigned int> &arraySizes,
4625                                                         const TSourceLoc &arrayLoc,
4626                                                         TPublicType *elementType)
4627 {
4628     checkArrayElementIsNotArray(arrayLoc, *elementType);
4629     TType *arrayType = new TType(*elementType);
4630     arrayType->makeArrays(arraySizes);
4631     return parseParameterDeclarator(arrayType, name, nameLoc);
4632 }
4633 
checkUnsizedArrayConstructorArgumentDimensionality(const TIntermSequence & arguments,TType type,const TSourceLoc & line)4634 bool TParseContext::checkUnsizedArrayConstructorArgumentDimensionality(
4635     const TIntermSequence &arguments,
4636     TType type,
4637     const TSourceLoc &line)
4638 {
4639     if (arguments.empty())
4640     {
4641         error(line, "implicitly sized array constructor must have at least one argument", "[]");
4642         return false;
4643     }
4644     for (TIntermNode *arg : arguments)
4645     {
4646         const TIntermTyped *element = arg->getAsTyped();
4647         ASSERT(element);
4648         size_t dimensionalityFromElement = element->getType().getNumArraySizes() + 1u;
4649         if (dimensionalityFromElement > type.getNumArraySizes())
4650         {
4651             error(line, "constructing from a non-dereferenced array", "constructor");
4652             return false;
4653         }
4654         else if (dimensionalityFromElement < type.getNumArraySizes())
4655         {
4656             if (dimensionalityFromElement == 1u)
4657             {
4658                 error(line, "implicitly sized array of arrays constructor argument is not an array",
4659                       "constructor");
4660             }
4661             else
4662             {
4663                 error(line,
4664                       "implicitly sized array of arrays constructor argument dimensionality is too "
4665                       "low",
4666                       "constructor");
4667             }
4668             return false;
4669         }
4670     }
4671     return true;
4672 }
4673 
4674 // This function is used to test for the correctness of the parameters passed to various constructor
4675 // functions and also convert them to the right datatype if it is allowed and required.
4676 //
4677 // Returns a node to add to the tree regardless of if an error was generated or not.
4678 //
addConstructor(TFunctionLookup * fnCall,const TSourceLoc & line)4679 TIntermTyped *TParseContext::addConstructor(TFunctionLookup *fnCall, const TSourceLoc &line)
4680 {
4681     TType type                 = fnCall->constructorType();
4682     TIntermSequence &arguments = fnCall->arguments();
4683     if (type.isUnsizedArray())
4684     {
4685         if (!checkUnsizedArrayConstructorArgumentDimensionality(arguments, type, line))
4686         {
4687             type.sizeUnsizedArrays(TSpan<const unsigned int>());
4688             return CreateZeroNode(type);
4689         }
4690         TIntermTyped *firstElement = arguments.at(0)->getAsTyped();
4691         ASSERT(firstElement);
4692         if (type.getOutermostArraySize() == 0u)
4693         {
4694             type.sizeOutermostUnsizedArray(static_cast<unsigned int>(arguments.size()));
4695         }
4696         for (size_t i = 0; i < firstElement->getType().getNumArraySizes(); ++i)
4697         {
4698             if (type.getArraySizes()[i] == 0u)
4699             {
4700                 type.setArraySize(i, firstElement->getType().getArraySizes()[i]);
4701             }
4702         }
4703         ASSERT(!type.isUnsizedArray());
4704     }
4705 
4706     if (!checkConstructorArguments(line, arguments, type))
4707     {
4708         return CreateZeroNode(type);
4709     }
4710 
4711     TIntermAggregate *constructorNode = TIntermAggregate::CreateConstructor(type, &arguments);
4712     constructorNode->setLine(line);
4713 
4714     return constructorNode->fold(mDiagnostics);
4715 }
4716 
4717 //
4718 // Interface/uniform blocks
addInterfaceBlock(const TTypeQualifierBuilder & typeQualifierBuilder,const TSourceLoc & nameLine,const ImmutableString & blockName,TFieldList * fieldList,const ImmutableString & instanceName,const TSourceLoc & instanceLine,const TVector<unsigned int> * arraySizes,const TSourceLoc & arraySizesLine)4719 TIntermDeclaration *TParseContext::addInterfaceBlock(
4720     const TTypeQualifierBuilder &typeQualifierBuilder,
4721     const TSourceLoc &nameLine,
4722     const ImmutableString &blockName,
4723     TFieldList *fieldList,
4724     const ImmutableString &instanceName,
4725     const TSourceLoc &instanceLine,
4726     const TVector<unsigned int> *arraySizes,
4727     const TSourceLoc &arraySizesLine)
4728 {
4729     const bool isGLPerVertex = blockName == "gl_PerVertex";
4730     // gl_PerVertex is allowed to be redefined and therefore not reserved
4731     if (!isGLPerVertex)
4732     {
4733         checkIsNotReserved(nameLine, blockName);
4734     }
4735 
4736     TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
4737 
4738     const bool isUniformOrBuffer =
4739         typeQualifier.qualifier == EvqUniform || typeQualifier.qualifier == EvqBuffer;
4740     const bool isShaderIoBlock = IsShaderIoBlock(typeQualifier.qualifier);
4741 
4742     if (mShaderVersion < 310 && typeQualifier.qualifier != EvqUniform)
4743     {
4744         error(typeQualifier.line,
4745               "invalid qualifier: interface blocks must be uniform in version lower than GLSL ES "
4746               "3.10",
4747               getQualifierString(typeQualifier.qualifier));
4748     }
4749     else if (typeQualifier.qualifier == EvqPatchOut)
4750     {
4751         if ((!isExtensionEnabled(TExtension::EXT_tessellation_shader) && mShaderVersion < 320) ||
4752             mShaderType != GL_TESS_CONTROL_SHADER)
4753         {
4754             error(typeQualifier.line,
4755                   "invalid qualifier: 'patch out' requires a tessellation control shader",
4756                   getQualifierString(typeQualifier.qualifier));
4757         }
4758     }
4759     else if (typeQualifier.qualifier == EvqPatchIn)
4760     {
4761         if ((!isExtensionEnabled(TExtension::EXT_tessellation_shader) && mShaderVersion < 320) ||
4762             mShaderType != GL_TESS_EVALUATION_SHADER)
4763         {
4764             error(typeQualifier.line,
4765                   "invalid qualifier: 'patch in' requires a tessellation evaluation shader",
4766                   getQualifierString(typeQualifier.qualifier));
4767         }
4768     }
4769     else if (typeQualifier.qualifier != EvqUniform && typeQualifier.qualifier != EvqBuffer)
4770     {
4771         if (isShaderIoBlock)
4772         {
4773             if (!isExtensionEnabled(TExtension::OES_shader_io_blocks) &&
4774                 !isExtensionEnabled(TExtension::EXT_shader_io_blocks) &&
4775                 !isExtensionEnabled(TExtension::OES_geometry_shader) &&
4776                 !isExtensionEnabled(TExtension::EXT_geometry_shader) && mShaderVersion < 320)
4777             {
4778                 error(typeQualifier.line,
4779                       "invalid qualifier: shader IO blocks need shader io block extension",
4780                       getQualifierString(typeQualifier.qualifier));
4781             }
4782 
4783             // Both inputs and outputs of tessellation control shaders must be arrays.
4784             // For tessellation evaluation shaders, only inputs must necessarily be arrays.
4785             const bool isTCS = mShaderType == GL_TESS_CONTROL_SHADER;
4786             const bool isTESIn =
4787                 mShaderType == GL_TESS_EVALUATION_SHADER && IsShaderIn(typeQualifier.qualifier);
4788             if (arraySizes == nullptr && (isTCS || isTESIn))
4789             {
4790                 error(typeQualifier.line, "type must be an array", blockName);
4791             }
4792         }
4793         else
4794         {
4795             error(typeQualifier.line,
4796                   "invalid qualifier: interface blocks must be uniform or buffer",
4797                   getQualifierString(typeQualifier.qualifier));
4798         }
4799     }
4800 
4801     if (typeQualifier.invariant)
4802     {
4803         error(typeQualifier.line, "invalid qualifier on interface block", "invariant");
4804     }
4805 
4806     if (typeQualifier.qualifier != EvqBuffer)
4807     {
4808         checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
4809     }
4810 
4811     // Verify array sizes
4812     if (arraySizes)
4813     {
4814         if (isUniformOrBuffer)
4815         {
4816             if (arraySizes->size() == 0)
4817             {
4818                 error(arraySizesLine, "unsized arrays are not allowed with interface blocks", "");
4819             }
4820             if (arraySizes->size() > 1)
4821             {
4822                 error(arraySizesLine, "array of arrays are not allowed with interface blocks", "");
4823             }
4824         }
4825         else if (isShaderIoBlock)
4826         {
4827             size_t arrayDimensions = arraySizes->size();
4828 
4829             // Geometry shader inputs have a level arrayness that must be ignored.
4830             if (mShaderType == GL_GEOMETRY_SHADER_EXT && IsVaryingIn(typeQualifier.qualifier))
4831             {
4832                 ASSERT(arrayDimensions > 0);
4833                 --arrayDimensions;
4834 
4835                 // Validate that the array size of input matches the geometry layout
4836                 // declaration, if not automatic (specified as []).
4837                 const unsigned int geometryDim = arraySizes->back();
4838                 if (geometryDim > 0 && geometryDim != mGeometryInputArraySize)
4839                 {
4840                     error(arraySizesLine,
4841                           "geometry shader input block array size inconsistent "
4842                           "with primitive",
4843                           "");
4844                 }
4845             }
4846 
4847             if (arrayDimensions > 1)
4848             {
4849                 error(arraySizesLine, "array of arrays are not allowed with I/O blocks", "");
4850             }
4851         }
4852     }
4853     else if (isShaderIoBlock && mShaderType == GL_GEOMETRY_SHADER_EXT &&
4854              IsVaryingIn(typeQualifier.qualifier))
4855     {
4856         error(arraySizesLine, "geometry shader input blocks must be an array", "");
4857     }
4858 
4859     checkIndexIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.index);
4860 
4861     if (mShaderVersion < 310)
4862     {
4863         checkBindingIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.binding);
4864     }
4865     else
4866     {
4867         unsigned int arraySize =
4868             arraySizes == nullptr || arraySizes->empty() ? 0 : (*arraySizes)[0];
4869         checkBlockBindingIsValid(typeQualifier.line, typeQualifier.qualifier,
4870                                  typeQualifier.layoutQualifier.binding, arraySize);
4871     }
4872 
4873     checkDepthIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.depth);
4874     checkYuvIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.yuv);
4875     checkEarlyFragmentTestsIsNotSpecified(typeQualifier.line,
4876                                           typeQualifier.layoutQualifier.earlyFragmentTests);
4877     checkNoncoherentIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.noncoherent);
4878 
4879     TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier;
4880     if (!IsShaderIoBlock(typeQualifier.qualifier) && typeQualifier.qualifier != EvqPatchIn &&
4881         typeQualifier.qualifier != EvqPatchOut)
4882     {
4883         checkLocationIsNotSpecified(typeQualifier.line, blockLayoutQualifier);
4884     }
4885     checkStd430IsForShaderStorageBlock(typeQualifier.line, blockLayoutQualifier.blockStorage,
4886                                        typeQualifier.qualifier);
4887 
4888     if (blockLayoutQualifier.matrixPacking == EmpUnspecified)
4889     {
4890         if (typeQualifier.qualifier == EvqUniform)
4891         {
4892             blockLayoutQualifier.matrixPacking = mDefaultUniformMatrixPacking;
4893         }
4894         else if (typeQualifier.qualifier == EvqBuffer)
4895         {
4896             blockLayoutQualifier.matrixPacking = mDefaultBufferMatrixPacking;
4897         }
4898     }
4899 
4900     if (blockLayoutQualifier.blockStorage == EbsUnspecified)
4901     {
4902         if (typeQualifier.qualifier == EvqUniform)
4903         {
4904             blockLayoutQualifier.blockStorage = mDefaultUniformBlockStorage;
4905         }
4906         else if (typeQualifier.qualifier == EvqBuffer)
4907         {
4908             blockLayoutQualifier.blockStorage = mDefaultBufferBlockStorage;
4909         }
4910     }
4911 
4912     checkWorkGroupSizeIsNotSpecified(nameLine, blockLayoutQualifier);
4913 
4914     checkInternalFormatIsNotSpecified(nameLine, blockLayoutQualifier.imageInternalFormat);
4915 
4916     // check for sampler types and apply layout qualifiers
4917     for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
4918     {
4919         TField *field    = (*fieldList)[memberIndex];
4920         TType *fieldType = field->type();
4921         if (IsOpaqueType(fieldType->getBasicType()))
4922         {
4923             std::string reason("unsupported type - ");
4924             reason += fieldType->getBasicString();
4925             reason += " types are not allowed in interface blocks";
4926             error(field->line(), reason.c_str(), fieldType->getBasicString());
4927         }
4928 
4929         const TQualifier qualifier = fieldType->getQualifier();
4930         switch (qualifier)
4931         {
4932             case EvqGlobal:
4933                 break;
4934             case EvqUniform:
4935                 if (typeQualifier.qualifier == EvqBuffer)
4936                 {
4937                     error(field->line(), "invalid qualifier on shader storage block member",
4938                           getQualifierString(qualifier));
4939                 }
4940                 break;
4941             case EvqBuffer:
4942                 if (typeQualifier.qualifier == EvqUniform)
4943                 {
4944                     error(field->line(), "invalid qualifier on uniform block member",
4945                           getQualifierString(qualifier));
4946                 }
4947                 break;
4948             // a member variable in io block may have different interpolation.
4949             case EvqSmoothIn:
4950             case EvqSmoothOut:
4951             case EvqFlatIn:
4952             case EvqFlatOut:
4953             case EvqNoPerspectiveIn:
4954             case EvqNoPerspectiveOut:
4955             case EvqCentroidIn:
4956             case EvqCentroidOut:
4957             case EvqSampleIn:
4958             case EvqSampleOut:
4959             case EvqNoPerspectiveCentroidIn:
4960             case EvqNoPerspectiveCentroidOut:
4961             case EvqNoPerspectiveSampleIn:
4962             case EvqNoPerspectiveSampleOut:
4963                 break;
4964             // a member variable can have an incomplete qualifier because shader io block has either
4965             // in or out.
4966             case EvqSmooth:
4967             case EvqFlat:
4968             case EvqNoPerspective:
4969             case EvqCentroid:
4970             case EvqSample:
4971             case EvqNoPerspectiveCentroid:
4972             case EvqNoPerspectiveSample:
4973             case EvqGeometryIn:
4974             case EvqGeometryOut:
4975                 if (!IsShaderIoBlock(typeQualifier.qualifier) &&
4976                     typeQualifier.qualifier != EvqPatchIn &&
4977                     typeQualifier.qualifier != EvqPatchOut &&
4978                     typeQualifier.qualifier != EvqGeometryIn &&
4979                     typeQualifier.qualifier != EvqGeometryOut)
4980                 {
4981                     error(field->line(), "invalid qualifier on interface block member",
4982                           getQualifierString(qualifier));
4983                 }
4984                 break;
4985             default:
4986                 error(field->line(), "invalid qualifier on interface block member",
4987                       getQualifierString(qualifier));
4988                 break;
4989         }
4990 
4991         // On interface block members, invariant is only applicable to output I/O blocks.
4992         const bool isOutputShaderIoBlock = isShaderIoBlock && IsShaderOut(typeQualifier.qualifier);
4993         if (fieldType->isInvariant() && !isOutputShaderIoBlock)
4994         {
4995             error(field->line(), "invalid qualifier on interface block member", "invariant");
4996         }
4997 
4998         // check layout qualifiers
4999         TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier();
5000         checkIndexIsNotSpecified(field->line(), fieldLayoutQualifier.index);
5001         checkBindingIsNotSpecified(field->line(), fieldLayoutQualifier.binding);
5002 
5003         if (fieldLayoutQualifier.blockStorage != EbsUnspecified)
5004         {
5005             error(field->line(), "invalid layout qualifier: cannot be used here",
5006                   getBlockStorageString(fieldLayoutQualifier.blockStorage));
5007         }
5008 
5009         if (fieldLayoutQualifier.matrixPacking == EmpUnspecified)
5010         {
5011             fieldLayoutQualifier.matrixPacking = blockLayoutQualifier.matrixPacking;
5012         }
5013         else if (!fieldType->isMatrix() && fieldType->getBasicType() != EbtStruct)
5014         {
5015             warning(field->line(),
5016                     "extraneous layout qualifier: only has an effect on matrix types",
5017                     getMatrixPackingString(fieldLayoutQualifier.matrixPacking));
5018         }
5019 
5020         fieldType->setLayoutQualifier(fieldLayoutQualifier);
5021 
5022         if (mShaderVersion < 310 || memberIndex != fieldList->size() - 1u ||
5023             typeQualifier.qualifier != EvqBuffer)
5024         {
5025             // ESSL 3.10 spec section 4.1.9 allows for runtime-sized arrays.
5026             checkIsNotUnsizedArray(field->line(),
5027                                    "array members of interface blocks must specify a size",
5028                                    field->name(), field->type());
5029         }
5030 
5031         if (typeQualifier.qualifier == EvqBuffer)
5032         {
5033             // set memory qualifiers
5034             // GLSL ES 3.10 session 4.9 [Memory Access Qualifiers]. When a block declaration is
5035             // qualified with a memory qualifier, it is as if all of its members were declared with
5036             // the same memory qualifier.
5037             const TMemoryQualifier &blockMemoryQualifier = typeQualifier.memoryQualifier;
5038             TMemoryQualifier fieldMemoryQualifier        = fieldType->getMemoryQualifier();
5039             fieldMemoryQualifier.readonly |= blockMemoryQualifier.readonly;
5040             fieldMemoryQualifier.writeonly |= blockMemoryQualifier.writeonly;
5041             fieldMemoryQualifier.coherent |= blockMemoryQualifier.coherent;
5042             fieldMemoryQualifier.restrictQualifier |= blockMemoryQualifier.restrictQualifier;
5043             fieldMemoryQualifier.volatileQualifier |= blockMemoryQualifier.volatileQualifier;
5044             // TODO(jiajia.qin@intel.com): Decide whether if readonly and writeonly buffer variable
5045             // is legal. See bug https://github.com/KhronosGroup/OpenGL-API/issues/7
5046             fieldType->setMemoryQualifier(fieldMemoryQualifier);
5047         }
5048     }
5049 
5050     SymbolType instanceSymbolType = SymbolType::UserDefined;
5051     if (isGLPerVertex)
5052     {
5053         instanceSymbolType = SymbolType::BuiltIn;
5054     }
5055     TInterfaceBlock *interfaceBlock = new TInterfaceBlock(&symbolTable, blockName, fieldList,
5056                                                           blockLayoutQualifier, instanceSymbolType);
5057     if (!symbolTable.declare(interfaceBlock) && isUniformOrBuffer)
5058     {
5059         error(nameLine, "redefinition of an interface block name", blockName);
5060     }
5061 
5062     TType *interfaceBlockType =
5063         new TType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier);
5064     if (arraySizes)
5065     {
5066         interfaceBlockType->makeArrays(*arraySizes);
5067 
5068         checkGeometryShaderInputAndSetArraySize(instanceLine, instanceName, interfaceBlockType);
5069         checkTessellationShaderUnsizedArraysAndSetSize(instanceLine, instanceName,
5070                                                        interfaceBlockType);
5071     }
5072 
5073     // The instance variable gets created to refer to the interface block type from the AST
5074     // regardless of if there's an instance name. It's created as an empty symbol if there is no
5075     // instance name.
5076     TVariable *instanceVariable =
5077         new TVariable(&symbolTable, instanceName, interfaceBlockType,
5078                       instanceName.empty() ? SymbolType::Empty : SymbolType::UserDefined);
5079 
5080     if (instanceVariable->symbolType() == SymbolType::Empty)
5081     {
5082         // define symbols for the members of the interface block
5083         for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
5084         {
5085             TField *field    = (*fieldList)[memberIndex];
5086             TType *fieldType = new TType(*field->type());
5087 
5088             // set parent pointer of the field variable
5089             fieldType->setInterfaceBlockField(interfaceBlock, memberIndex);
5090 
5091             fieldType->setQualifier(typeQualifier.qualifier);
5092 
5093             SymbolType symbolType = SymbolType::UserDefined;
5094             if (field->name() == "gl_Position" || field->name() == "gl_PointSize" ||
5095                 field->name() == "gl_ClipDistance" || field->name() == "gl_CullDistance")
5096             {
5097                 // These builtins can be redefined only when used within a redefined gl_PerVertex
5098                 // block
5099                 if (interfaceBlock->name() != "gl_PerVertex")
5100                 {
5101                     error(field->line(), "redefinition in an invalid interface block",
5102                           field->name());
5103                 }
5104                 symbolType = SymbolType::BuiltIn;
5105             }
5106             TVariable *fieldVariable =
5107                 new TVariable(&symbolTable, field->name(), fieldType, symbolType);
5108             if (!symbolTable.declare(fieldVariable))
5109             {
5110                 error(field->line(), "redefinition of an interface block member name",
5111                       field->name());
5112             }
5113         }
5114     }
5115     else
5116     {
5117         checkIsNotReserved(instanceLine, instanceName);
5118 
5119         // add a symbol for this interface block
5120         if (!symbolTable.declare(instanceVariable))
5121         {
5122             error(instanceLine, "redefinition of an interface block instance name", instanceName);
5123         }
5124     }
5125 
5126     TIntermSymbol *blockSymbol = new TIntermSymbol(instanceVariable);
5127     blockSymbol->setLine(typeQualifier.line);
5128     TIntermDeclaration *declaration = new TIntermDeclaration();
5129     declaration->appendDeclarator(blockSymbol);
5130     declaration->setLine(nameLine);
5131 
5132     exitStructDeclaration();
5133     return declaration;
5134 }
5135 
enterStructDeclaration(const TSourceLoc & line,const ImmutableString & identifier)5136 void TParseContext::enterStructDeclaration(const TSourceLoc &line,
5137                                            const ImmutableString &identifier)
5138 {
5139     ++mStructNestingLevel;
5140 
5141     // Embedded structure definitions are not supported per GLSL ES spec.
5142     // ESSL 1.00.17 section 10.9. ESSL 3.00.6 section 12.11.
5143     if (mStructNestingLevel > 1)
5144     {
5145         error(line, "Embedded struct definitions are not allowed", "struct");
5146     }
5147 }
5148 
exitStructDeclaration()5149 void TParseContext::exitStructDeclaration()
5150 {
5151     --mStructNestingLevel;
5152 }
5153 
checkIsBelowStructNestingLimit(const TSourceLoc & line,const TField & field)5154 void TParseContext::checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field)
5155 {
5156     if (!sh::IsWebGLBasedSpec(mShaderSpec))
5157     {
5158         return;
5159     }
5160 
5161     if (field.type()->getBasicType() != EbtStruct)
5162     {
5163         return;
5164     }
5165 
5166     // We're already inside a structure definition at this point, so add
5167     // one to the field's struct nesting.
5168     if (1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting)
5169     {
5170         std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
5171         if (field.type()->getStruct()->symbolType() == SymbolType::Empty)
5172         {
5173             // This may happen in case there are nested struct definitions. While they are also
5174             // invalid GLSL, they don't cause a syntax error.
5175             reasonStream << "Struct nesting";
5176         }
5177         else
5178         {
5179             reasonStream << "Reference of struct type " << field.type()->getStruct()->name();
5180         }
5181         reasonStream << " exceeds maximum allowed nesting level of " << kWebGLMaxStructNesting;
5182         std::string reason = reasonStream.str();
5183         error(line, reason.c_str(), field.name());
5184         return;
5185     }
5186 }
5187 
5188 //
5189 // Parse an array index expression
5190 //
addIndexExpression(TIntermTyped * baseExpression,const TSourceLoc & location,TIntermTyped * indexExpression)5191 TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
5192                                                 const TSourceLoc &location,
5193                                                 TIntermTyped *indexExpression)
5194 {
5195     if (!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector())
5196     {
5197         if (baseExpression->getAsSymbolNode())
5198         {
5199             error(location, " left of '[' is not of type array, matrix, or vector ",
5200                   baseExpression->getAsSymbolNode()->getName());
5201         }
5202         else
5203         {
5204             error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
5205         }
5206 
5207         return CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
5208     }
5209 
5210     if (baseExpression->getQualifier() == EvqPerVertexIn)
5211     {
5212         if (mGeometryShaderInputPrimitiveType == EptUndefined &&
5213             mShaderType == GL_GEOMETRY_SHADER_EXT)
5214         {
5215             error(location, "missing input primitive declaration before indexing gl_in.", "[");
5216             return CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
5217         }
5218     }
5219 
5220     TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion();
5221 
5222     // ES3.2 or ES3.1's EXT_gpu_shader5 allow dynamically uniform expressions to be used as indices
5223     // of opaque types (samplers and atomic counters) as well as UBOs, but not SSBOs and images.
5224     bool allowUniformIndices =
5225         mShaderVersion >= 320 || isExtensionEnabled(TExtension::EXT_gpu_shader5);
5226 
5227     // ANGLE should be able to fold any constant expressions resulting in an integer - but to be
5228     // safe we don't treat "EvqConst" that's evaluated according to the spec as being sufficient
5229     // for constness. Some interpretations of the spec have allowed constant expressions with side
5230     // effects - like array length() method on a non-constant array.
5231     if (indexExpression->getQualifier() != EvqConst || indexConstantUnion == nullptr)
5232     {
5233         if (baseExpression->isInterfaceBlock())
5234         {
5235             switch (baseExpression->getQualifier())
5236             {
5237                 case EvqPerVertexIn:
5238                     break;
5239                 case EvqUniform:
5240                     if (!allowUniformIndices)
5241                     {
5242                         error(location,
5243                               "array indexes for uniform block arrays must be constant integral "
5244                               "expressions",
5245                               "[");
5246                     }
5247                     break;
5248                 case EvqBuffer:
5249                     error(location,
5250                           "array indexes for shader storage block arrays must be constant integral "
5251                           "expressions",
5252                           "[");
5253                     break;
5254                 default:
5255                     // It's ok for shader I/O blocks to be dynamically indexed
5256                     if (!IsShaderIoBlock(baseExpression->getQualifier()) &&
5257                         baseExpression->getQualifier() != EvqPatchIn &&
5258                         baseExpression->getQualifier() != EvqPatchOut)
5259                     {
5260                         // We can reach here only in error cases.
5261                         ASSERT(mDiagnostics->numErrors() > 0);
5262                     }
5263                     break;
5264             }
5265         }
5266         else if (baseExpression->getQualifier() == EvqFragmentOut ||
5267                  baseExpression->getQualifier() == EvqFragmentInOut)
5268         {
5269             error(location,
5270                   "array indexes for fragment outputs must be constant integral expressions", "[");
5271         }
5272         else if (baseExpression->getQualifier() == EvqLastFragData)
5273         {
5274             error(location,
5275                   "array indexes for gl_LastFragData must be constant integral expressions", "[");
5276         }
5277         else if (mShaderSpec == SH_WEBGL2_SPEC && baseExpression->getQualifier() == EvqFragData)
5278         {
5279             error(location, "array index for gl_FragData must be constant zero", "[");
5280         }
5281         else if (baseExpression->isArray())
5282         {
5283             TBasicType elementType = baseExpression->getType().getBasicType();
5284 
5285             // Note: In Section 12.30 of the ESSL 3.00 spec on p143-144:
5286             //
5287             //   Indexing of arrays of samplers by constant-index-expressions is
5288             //   supported in GLSL ES 1.00. A constant-index-expression is an
5289             //   expression formed from constant-expressions and certain loop indices,
5290             //   defined for a subset of loop constructs. Should this functionality be
5291             //   included in GLSL ES 3.00?
5292             //
5293             //   RESOLUTION: No. Arrays of samplers may only be indexed by constant-
5294             //   integral-expressions.
5295             if (IsSampler(elementType) && !allowUniformIndices && mShaderVersion > 100)
5296             {
5297                 error(location, "array index for samplers must be constant integral expressions",
5298                       "[");
5299             }
5300             else if (IsImage(elementType))
5301             {
5302                 error(location,
5303                       "array indexes for image arrays must be constant integral expressions", "[");
5304             }
5305         }
5306     }
5307 
5308     if (indexConstantUnion)
5309     {
5310         // If an out-of-range index is not qualified as constant, the behavior in the spec is
5311         // undefined. This applies even if ANGLE has been able to constant fold it (ANGLE may
5312         // constant fold expressions that are not constant expressions). The most compatible way to
5313         // handle this case is to report a warning instead of an error and force the index to be in
5314         // the correct range.
5315         bool outOfRangeIndexIsError = indexExpression->getQualifier() == EvqConst;
5316         int index                   = 0;
5317         if (indexConstantUnion->getBasicType() == EbtInt)
5318         {
5319             index = indexConstantUnion->getIConst(0);
5320         }
5321         else if (indexConstantUnion->getBasicType() == EbtUInt)
5322         {
5323             index = static_cast<int>(indexConstantUnion->getUConst(0));
5324         }
5325 
5326         int safeIndex = -1;
5327 
5328         if (index < 0)
5329         {
5330             outOfRangeError(outOfRangeIndexIsError, location, "index expression is negative", "[]");
5331             safeIndex = 0;
5332         }
5333 
5334         if (!baseExpression->getType().isUnsizedArray())
5335         {
5336             if (baseExpression->isArray())
5337             {
5338                 if (baseExpression->getQualifier() == EvqFragData && index > 0)
5339                 {
5340                     if (!isExtensionEnabled(TExtension::EXT_draw_buffers))
5341                     {
5342                         outOfRangeError(outOfRangeIndexIsError, location,
5343                                         "array index for gl_FragData must be zero when "
5344                                         "GL_EXT_draw_buffers is disabled",
5345                                         "[]");
5346                         safeIndex = 0;
5347                     }
5348                 }
5349             }
5350             // Only do generic out-of-range check if similar error hasn't already been reported.
5351             if (safeIndex < 0)
5352             {
5353                 if (baseExpression->isArray())
5354                 {
5355                     safeIndex = checkIndexLessThan(outOfRangeIndexIsError, location, index,
5356                                                    baseExpression->getOutermostArraySize(),
5357                                                    "array index out of range");
5358                 }
5359                 else if (baseExpression->isMatrix())
5360                 {
5361                     safeIndex = checkIndexLessThan(outOfRangeIndexIsError, location, index,
5362                                                    baseExpression->getType().getCols(),
5363                                                    "matrix field selection out of range");
5364                 }
5365                 else
5366                 {
5367                     ASSERT(baseExpression->isVector());
5368                     safeIndex = checkIndexLessThan(outOfRangeIndexIsError, location, index,
5369                                                    baseExpression->getType().getNominalSize(),
5370                                                    "vector field selection out of range");
5371                 }
5372             }
5373 
5374             ASSERT(safeIndex >= 0);
5375             // Data of constant unions can't be changed, because it may be shared with other
5376             // constant unions or even builtins, like gl_MaxDrawBuffers. Instead use a new
5377             // sanitized object.
5378             if (safeIndex != index || indexConstantUnion->getBasicType() != EbtInt)
5379             {
5380                 TConstantUnion *safeConstantUnion = new TConstantUnion();
5381                 safeConstantUnion->setIConst(safeIndex);
5382                 indexExpression =
5383                     new TIntermConstantUnion(safeConstantUnion, TType(indexExpression->getType()));
5384             }
5385 
5386             TIntermBinary *node =
5387                 new TIntermBinary(EOpIndexDirect, baseExpression, indexExpression);
5388             node->setLine(location);
5389             return expressionOrFoldedResult(node);
5390         }
5391     }
5392 
5393     markStaticReadIfSymbol(indexExpression);
5394     TIntermBinary *node = new TIntermBinary(EOpIndexIndirect, baseExpression, indexExpression);
5395     node->setLine(location);
5396     // Indirect indexing can never be constant folded.
5397     return node;
5398 }
5399 
checkIndexLessThan(bool outOfRangeIndexIsError,const TSourceLoc & location,int index,int arraySize,const char * reason)5400 int TParseContext::checkIndexLessThan(bool outOfRangeIndexIsError,
5401                                       const TSourceLoc &location,
5402                                       int index,
5403                                       int arraySize,
5404                                       const char *reason)
5405 {
5406     // Should not reach here with an unsized / runtime-sized array.
5407     ASSERT(arraySize > 0);
5408     // A negative index should already have been checked.
5409     ASSERT(index >= 0);
5410     if (index >= arraySize)
5411     {
5412         std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
5413         reasonStream << reason << " '" << index << "'";
5414         std::string token = reasonStream.str();
5415         outOfRangeError(outOfRangeIndexIsError, location, reason, "[]");
5416         return arraySize - 1;
5417     }
5418     return index;
5419 }
5420 
addFieldSelectionExpression(TIntermTyped * baseExpression,const TSourceLoc & dotLocation,const ImmutableString & fieldString,const TSourceLoc & fieldLocation)5421 TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression,
5422                                                          const TSourceLoc &dotLocation,
5423                                                          const ImmutableString &fieldString,
5424                                                          const TSourceLoc &fieldLocation)
5425 {
5426     if (baseExpression->isArray())
5427     {
5428         error(fieldLocation, "cannot apply dot operator to an array", ".");
5429         return baseExpression;
5430     }
5431 
5432     if (baseExpression->isVector())
5433     {
5434         TVector<int> fieldOffsets;
5435         if (!parseVectorFields(fieldLocation, fieldString, baseExpression->getNominalSize(),
5436                                &fieldOffsets))
5437         {
5438             fieldOffsets.resize(1);
5439             fieldOffsets[0] = 0;
5440         }
5441         TIntermSwizzle *node = new TIntermSwizzle(baseExpression, fieldOffsets);
5442         node->setLine(dotLocation);
5443 
5444         return node->fold(mDiagnostics);
5445     }
5446     else if (baseExpression->getBasicType() == EbtStruct)
5447     {
5448         const TFieldList &fields = baseExpression->getType().getStruct()->fields();
5449         if (fields.empty())
5450         {
5451             error(dotLocation, "structure has no fields", "Internal Error");
5452             return baseExpression;
5453         }
5454         else
5455         {
5456             bool fieldFound = false;
5457             unsigned int i;
5458             for (i = 0; i < fields.size(); ++i)
5459             {
5460                 if (fields[i]->name() == fieldString)
5461                 {
5462                     fieldFound = true;
5463                     break;
5464                 }
5465             }
5466             if (fieldFound)
5467             {
5468                 TIntermTyped *index = CreateIndexNode(i);
5469                 index->setLine(fieldLocation);
5470                 TIntermBinary *node =
5471                     new TIntermBinary(EOpIndexDirectStruct, baseExpression, index);
5472                 node->setLine(dotLocation);
5473                 return expressionOrFoldedResult(node);
5474             }
5475             else
5476             {
5477                 error(dotLocation, " no such field in structure", fieldString);
5478                 return baseExpression;
5479             }
5480         }
5481     }
5482     else if (baseExpression->isInterfaceBlock())
5483     {
5484         const TFieldList &fields = baseExpression->getType().getInterfaceBlock()->fields();
5485         if (fields.empty())
5486         {
5487             error(dotLocation, "interface block has no fields", "Internal Error");
5488             return baseExpression;
5489         }
5490         else
5491         {
5492             bool fieldFound = false;
5493             unsigned int i;
5494             for (i = 0; i < fields.size(); ++i)
5495             {
5496                 if (fields[i]->name() == fieldString)
5497                 {
5498                     fieldFound = true;
5499                     break;
5500                 }
5501             }
5502             if (fieldFound)
5503             {
5504                 TIntermTyped *index = CreateIndexNode(i);
5505                 index->setLine(fieldLocation);
5506                 TIntermBinary *node =
5507                     new TIntermBinary(EOpIndexDirectInterfaceBlock, baseExpression, index);
5508                 node->setLine(dotLocation);
5509                 // Indexing interface blocks can never be constant folded.
5510                 return node;
5511             }
5512             else
5513             {
5514                 error(dotLocation, " no such field in interface block", fieldString);
5515                 return baseExpression;
5516             }
5517         }
5518     }
5519     else
5520     {
5521         if (mShaderVersion < 300)
5522         {
5523             error(dotLocation, " field selection requires structure or vector on left hand side",
5524                   fieldString);
5525         }
5526         else
5527         {
5528             error(dotLocation,
5529                   " field selection requires structure, vector, or interface block on left hand "
5530                   "side",
5531                   fieldString);
5532         }
5533         return baseExpression;
5534     }
5535 }
5536 
parseLayoutQualifier(const ImmutableString & qualifierType,const TSourceLoc & qualifierTypeLine)5537 TLayoutQualifier TParseContext::parseLayoutQualifier(const ImmutableString &qualifierType,
5538                                                      const TSourceLoc &qualifierTypeLine)
5539 {
5540     TLayoutQualifier qualifier = TLayoutQualifier::Create();
5541 
5542     if (qualifierType == "shared")
5543     {
5544         if (sh::IsWebGLBasedSpec(mShaderSpec))
5545         {
5546             error(qualifierTypeLine, "Only std140 layout is allowed in WebGL", "shared");
5547         }
5548         qualifier.blockStorage = EbsShared;
5549     }
5550     else if (qualifierType == "packed")
5551     {
5552         if (sh::IsWebGLBasedSpec(mShaderSpec))
5553         {
5554             error(qualifierTypeLine, "Only std140 layout is allowed in WebGL", "packed");
5555         }
5556         qualifier.blockStorage = EbsPacked;
5557     }
5558     else if (qualifierType == "std430")
5559     {
5560         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5561         qualifier.blockStorage = EbsStd430;
5562     }
5563     else if (qualifierType == "std140")
5564     {
5565         qualifier.blockStorage = EbsStd140;
5566     }
5567     else if (qualifierType == "row_major")
5568     {
5569         qualifier.matrixPacking = EmpRowMajor;
5570     }
5571     else if (qualifierType == "column_major")
5572     {
5573         qualifier.matrixPacking = EmpColumnMajor;
5574     }
5575     else if (qualifierType == "location")
5576     {
5577         error(qualifierTypeLine, "invalid layout qualifier: location requires an argument",
5578               qualifierType);
5579     }
5580     else if (qualifierType == "yuv" && mShaderType == GL_FRAGMENT_SHADER)
5581     {
5582         if (checkCanUseExtension(qualifierTypeLine, TExtension::EXT_YUV_target))
5583         {
5584             qualifier.yuv = true;
5585         }
5586     }
5587     else if (qualifierType == "early_fragment_tests")
5588     {
5589         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5590         qualifier.earlyFragmentTests = true;
5591     }
5592     else if (qualifierType == "rgba32f")
5593     {
5594         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5595         qualifier.imageInternalFormat = EiifRGBA32F;
5596     }
5597     else if (qualifierType == "rgba16f")
5598     {
5599         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5600         qualifier.imageInternalFormat = EiifRGBA16F;
5601     }
5602     else if (qualifierType == "r32f")
5603     {
5604         if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
5605         {
5606             checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5607         }
5608         qualifier.imageInternalFormat = EiifR32F;
5609     }
5610     else if (qualifierType == "rgba8")
5611     {
5612         if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
5613         {
5614             checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5615         }
5616         qualifier.imageInternalFormat = EiifRGBA8;
5617     }
5618     else if (qualifierType == "rgba8_snorm")
5619     {
5620         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5621         qualifier.imageInternalFormat = EiifRGBA8_SNORM;
5622     }
5623     else if (qualifierType == "rgba32i")
5624     {
5625         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5626         qualifier.imageInternalFormat = EiifRGBA32I;
5627     }
5628     else if (qualifierType == "rgba16i")
5629     {
5630         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5631         qualifier.imageInternalFormat = EiifRGBA16I;
5632     }
5633     else if (qualifierType == "rgba8i")
5634     {
5635         if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
5636         {
5637             checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5638         }
5639         qualifier.imageInternalFormat = EiifRGBA8I;
5640     }
5641     else if (qualifierType == "r32i")
5642     {
5643         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5644         qualifier.imageInternalFormat = EiifR32I;
5645     }
5646     else if (qualifierType == "rgba32ui")
5647     {
5648         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5649         qualifier.imageInternalFormat = EiifRGBA32UI;
5650     }
5651     else if (qualifierType == "rgba16ui")
5652     {
5653         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5654         qualifier.imageInternalFormat = EiifRGBA16UI;
5655     }
5656     else if (qualifierType == "rgba8ui")
5657     {
5658         if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
5659         {
5660             checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5661         }
5662         qualifier.imageInternalFormat = EiifRGBA8UI;
5663     }
5664     else if (qualifierType == "r32ui")
5665     {
5666         if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
5667         {
5668             checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5669         }
5670         qualifier.imageInternalFormat = EiifR32UI;
5671     }
5672     else if (mShaderType == GL_GEOMETRY_SHADER_EXT &&
5673              (mShaderVersion >= 320 ||
5674               (checkCanUseOneOfExtensions(
5675                    qualifierTypeLine,
5676                    std::array<TExtension, 2u>{
5677                        {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}}) &&
5678                checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310))))
5679     {
5680         if (qualifierType == "points")
5681         {
5682             qualifier.primitiveType = EptPoints;
5683         }
5684         else if (qualifierType == "lines")
5685         {
5686             qualifier.primitiveType = EptLines;
5687         }
5688         else if (qualifierType == "lines_adjacency")
5689         {
5690             qualifier.primitiveType = EptLinesAdjacency;
5691         }
5692         else if (qualifierType == "triangles")
5693         {
5694             qualifier.primitiveType = EptTriangles;
5695         }
5696         else if (qualifierType == "triangles_adjacency")
5697         {
5698             qualifier.primitiveType = EptTrianglesAdjacency;
5699         }
5700         else if (qualifierType == "line_strip")
5701         {
5702             qualifier.primitiveType = EptLineStrip;
5703         }
5704         else if (qualifierType == "triangle_strip")
5705         {
5706             qualifier.primitiveType = EptTriangleStrip;
5707         }
5708         else
5709         {
5710             error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
5711         }
5712     }
5713     else if (mShaderType == GL_TESS_EVALUATION_SHADER_EXT &&
5714              (mShaderVersion >= 320 ||
5715               (checkCanUseExtension(qualifierTypeLine, TExtension::EXT_tessellation_shader) &&
5716                checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310))))
5717     {
5718         if (qualifierType == "triangles")
5719         {
5720             qualifier.tesPrimitiveType = EtetTriangles;
5721         }
5722         else if (qualifierType == "quads")
5723         {
5724             qualifier.tesPrimitiveType = EtetQuads;
5725         }
5726         else if (qualifierType == "isolines")
5727         {
5728             qualifier.tesPrimitiveType = EtetIsolines;
5729         }
5730         else if (qualifierType == "equal_spacing")
5731         {
5732             qualifier.tesVertexSpacingType = EtetEqualSpacing;
5733         }
5734         else if (qualifierType == "fractional_even_spacing")
5735         {
5736             qualifier.tesVertexSpacingType = EtetFractionalEvenSpacing;
5737         }
5738         else if (qualifierType == "fractional_odd_spacing")
5739         {
5740             qualifier.tesVertexSpacingType = EtetFractionalOddSpacing;
5741         }
5742         else if (qualifierType == "cw")
5743         {
5744             qualifier.tesOrderingType = EtetCw;
5745         }
5746         else if (qualifierType == "ccw")
5747         {
5748             qualifier.tesOrderingType = EtetCcw;
5749         }
5750         else if (qualifierType == "point_mode")
5751         {
5752             qualifier.tesPointType = EtetPointMode;
5753         }
5754         else
5755         {
5756             error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
5757         }
5758     }
5759     else if (mShaderType == GL_FRAGMENT_SHADER)
5760     {
5761         if (qualifierType == "noncoherent")
5762         {
5763             if (checkCanUseOneOfExtensions(
5764                     qualifierTypeLine,
5765                     std::array<TExtension, 2u>{
5766                         {TExtension::EXT_shader_framebuffer_fetch,
5767                          TExtension::EXT_shader_framebuffer_fetch_non_coherent}}))
5768             {
5769                 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 100);
5770                 qualifier.noncoherent = true;
5771             }
5772         }
5773         else if (qualifierType == "blend_support_multiply")
5774         {
5775             AddAdvancedBlendEquation(gl::BlendEquationType::Multiply, &qualifier);
5776         }
5777         else if (qualifierType == "blend_support_screen")
5778         {
5779             AddAdvancedBlendEquation(gl::BlendEquationType::Screen, &qualifier);
5780         }
5781         else if (qualifierType == "blend_support_overlay")
5782         {
5783             AddAdvancedBlendEquation(gl::BlendEquationType::Overlay, &qualifier);
5784         }
5785         else if (qualifierType == "blend_support_darken")
5786         {
5787             AddAdvancedBlendEquation(gl::BlendEquationType::Darken, &qualifier);
5788         }
5789         else if (qualifierType == "blend_support_lighten")
5790         {
5791             AddAdvancedBlendEquation(gl::BlendEquationType::Lighten, &qualifier);
5792         }
5793         else if (qualifierType == "blend_support_colordodge")
5794         {
5795             AddAdvancedBlendEquation(gl::BlendEquationType::Colordodge, &qualifier);
5796         }
5797         else if (qualifierType == "blend_support_colorburn")
5798         {
5799             AddAdvancedBlendEquation(gl::BlendEquationType::Colorburn, &qualifier);
5800         }
5801         else if (qualifierType == "blend_support_hardlight")
5802         {
5803             AddAdvancedBlendEquation(gl::BlendEquationType::Hardlight, &qualifier);
5804         }
5805         else if (qualifierType == "blend_support_softlight")
5806         {
5807             AddAdvancedBlendEquation(gl::BlendEquationType::Softlight, &qualifier);
5808         }
5809         else if (qualifierType == "blend_support_difference")
5810         {
5811             AddAdvancedBlendEquation(gl::BlendEquationType::Difference, &qualifier);
5812         }
5813         else if (qualifierType == "blend_support_exclusion")
5814         {
5815             AddAdvancedBlendEquation(gl::BlendEquationType::Exclusion, &qualifier);
5816         }
5817         else if (qualifierType == "blend_support_hsl_hue")
5818         {
5819             AddAdvancedBlendEquation(gl::BlendEquationType::HslHue, &qualifier);
5820         }
5821         else if (qualifierType == "blend_support_hsl_saturation")
5822         {
5823             AddAdvancedBlendEquation(gl::BlendEquationType::HslSaturation, &qualifier);
5824         }
5825         else if (qualifierType == "blend_support_hsl_color")
5826         {
5827             AddAdvancedBlendEquation(gl::BlendEquationType::HslColor, &qualifier);
5828         }
5829         else if (qualifierType == "blend_support_hsl_luminosity")
5830         {
5831             AddAdvancedBlendEquation(gl::BlendEquationType::HslLuminosity, &qualifier);
5832         }
5833         else if (qualifierType == "blend_support_all_equations")
5834         {
5835             qualifier.advancedBlendEquations.setAll();
5836         }
5837         else if (qualifierType == "depth_any")
5838         {
5839             qualifier.depth = EdAny;
5840         }
5841         else if (qualifierType == "depth_greater")
5842         {
5843             qualifier.depth = EdGreater;
5844         }
5845         else if (qualifierType == "depth_less")
5846         {
5847             qualifier.depth = EdLess;
5848         }
5849         else if (qualifierType == "depth_unchanged" && !sh::IsWebGLBasedSpec(mShaderSpec))
5850         {
5851             qualifier.depth = EdUnchanged;
5852         }
5853         else
5854         {
5855             error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
5856         }
5857 
5858         if (qualifier.advancedBlendEquations.any() && mShaderVersion < 320)
5859         {
5860             if (!checkCanUseExtension(qualifierTypeLine, TExtension::KHR_blend_equation_advanced))
5861             {
5862                 qualifier.advancedBlendEquations.reset();
5863             }
5864         }
5865     }
5866     else
5867     {
5868         error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
5869     }
5870 
5871     return qualifier;
5872 }
5873 
parseLocalSize(const ImmutableString & qualifierType,const TSourceLoc & qualifierTypeLine,int intValue,const TSourceLoc & intValueLine,const std::string & intValueString,size_t index,sh::WorkGroupSize * localSize)5874 void TParseContext::parseLocalSize(const ImmutableString &qualifierType,
5875                                    const TSourceLoc &qualifierTypeLine,
5876                                    int intValue,
5877                                    const TSourceLoc &intValueLine,
5878                                    const std::string &intValueString,
5879                                    size_t index,
5880                                    sh::WorkGroupSize *localSize)
5881 {
5882     checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5883     if (intValue < 1)
5884     {
5885         std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
5886         reasonStream << "out of range: " << getWorkGroupSizeString(index) << " must be positive";
5887         std::string reason = reasonStream.str();
5888         error(intValueLine, reason.c_str(), intValueString.c_str());
5889     }
5890     (*localSize)[index] = intValue;
5891 }
5892 
parseNumViews(int intValue,const TSourceLoc & intValueLine,const std::string & intValueString,int * numViews)5893 void TParseContext::parseNumViews(int intValue,
5894                                   const TSourceLoc &intValueLine,
5895                                   const std::string &intValueString,
5896                                   int *numViews)
5897 {
5898     // This error is only specified in WebGL, but tightens unspecified behavior in the native
5899     // specification.
5900     if (intValue < 1)
5901     {
5902         error(intValueLine, "out of range: num_views must be positive", intValueString.c_str());
5903     }
5904     *numViews = intValue;
5905 }
5906 
parseInvocations(int intValue,const TSourceLoc & intValueLine,const std::string & intValueString,int * numInvocations)5907 void TParseContext::parseInvocations(int intValue,
5908                                      const TSourceLoc &intValueLine,
5909                                      const std::string &intValueString,
5910                                      int *numInvocations)
5911 {
5912     // Although SPEC isn't clear whether invocations can be less than 1, we add this limit because
5913     // it doesn't make sense to accept invocations <= 0.
5914     if (intValue < 1 || intValue > mMaxGeometryShaderInvocations)
5915     {
5916         error(intValueLine,
5917               "out of range: invocations must be in the range of [1, "
5918               "MAX_GEOMETRY_SHADER_INVOCATIONS_OES]",
5919               intValueString.c_str());
5920     }
5921     else
5922     {
5923         *numInvocations = intValue;
5924     }
5925 }
5926 
parseMaxVertices(int intValue,const TSourceLoc & intValueLine,const std::string & intValueString,int * maxVertices)5927 void TParseContext::parseMaxVertices(int intValue,
5928                                      const TSourceLoc &intValueLine,
5929                                      const std::string &intValueString,
5930                                      int *maxVertices)
5931 {
5932     // Although SPEC isn't clear whether max_vertices can be less than 0, we add this limit because
5933     // it doesn't make sense to accept max_vertices < 0.
5934     if (intValue < 0 || intValue > mMaxGeometryShaderMaxVertices)
5935     {
5936         error(
5937             intValueLine,
5938             "out of range: max_vertices must be in the range of [0, gl_MaxGeometryOutputVertices]",
5939             intValueString.c_str());
5940     }
5941     else
5942     {
5943         *maxVertices = intValue;
5944     }
5945 }
5946 
parseVertices(int intValue,const TSourceLoc & intValueLine,const std::string & intValueString,int * vertices)5947 void TParseContext::parseVertices(int intValue,
5948                                   const TSourceLoc &intValueLine,
5949                                   const std::string &intValueString,
5950                                   int *vertices)
5951 {
5952     if (intValue < 1 || intValue > mMaxPatchVertices)
5953     {
5954         error(intValueLine,
5955               "out of range : vertices must be in the range of [1, gl_MaxPatchVertices]",
5956               intValueString.c_str());
5957     }
5958     else
5959     {
5960         *vertices = intValue;
5961     }
5962 }
5963 
parseIndexLayoutQualifier(int intValue,const TSourceLoc & intValueLine,const std::string & intValueString,int * index)5964 void TParseContext::parseIndexLayoutQualifier(int intValue,
5965                                               const TSourceLoc &intValueLine,
5966                                               const std::string &intValueString,
5967                                               int *index)
5968 {
5969     // EXT_blend_func_extended specifies that most validation should happen at link time, but since
5970     // we're validating output variable locations at compile time, it makes sense to validate that
5971     // index is 0 or 1 also at compile time. Also since we use "-1" as a placeholder for unspecified
5972     // index, we can't accept it here.
5973     if (intValue < 0 || intValue > 1)
5974     {
5975         error(intValueLine, "out of range: index layout qualifier can only be 0 or 1",
5976               intValueString.c_str());
5977     }
5978     else
5979     {
5980         *index = intValue;
5981     }
5982 }
5983 
parseLayoutQualifier(const ImmutableString & qualifierType,const TSourceLoc & qualifierTypeLine,int intValue,const TSourceLoc & intValueLine)5984 TLayoutQualifier TParseContext::parseLayoutQualifier(const ImmutableString &qualifierType,
5985                                                      const TSourceLoc &qualifierTypeLine,
5986                                                      int intValue,
5987                                                      const TSourceLoc &intValueLine)
5988 {
5989     TLayoutQualifier qualifier = TLayoutQualifier::Create();
5990 
5991     std::string intValueString = Str(intValue);
5992 
5993     if (qualifierType == "location")
5994     {
5995         // must check that location is non-negative
5996         if (intValue < 0)
5997         {
5998             error(intValueLine, "out of range: location must be non-negative",
5999                   intValueString.c_str());
6000         }
6001         else
6002         {
6003             qualifier.location           = intValue;
6004             qualifier.locationsSpecified = 1;
6005         }
6006     }
6007     else if (qualifierType == "binding")
6008     {
6009         if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
6010         {
6011             checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
6012         }
6013         if (intValue < 0)
6014         {
6015             error(intValueLine, "out of range: binding must be non-negative",
6016                   intValueString.c_str());
6017         }
6018         else
6019         {
6020             qualifier.binding = intValue;
6021         }
6022     }
6023     else if (qualifierType == "offset")
6024     {
6025         checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
6026         if (intValue < 0)
6027         {
6028             error(intValueLine, "out of range: offset must be non-negative",
6029                   intValueString.c_str());
6030         }
6031         else
6032         {
6033             qualifier.offset = intValue;
6034         }
6035     }
6036     else if (qualifierType == "local_size_x")
6037     {
6038         parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 0u,
6039                        &qualifier.localSize);
6040     }
6041     else if (qualifierType == "local_size_y")
6042     {
6043         parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 1u,
6044                        &qualifier.localSize);
6045     }
6046     else if (qualifierType == "local_size_z")
6047     {
6048         parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 2u,
6049                        &qualifier.localSize);
6050     }
6051     else if (qualifierType == "num_views" && mShaderType == GL_VERTEX_SHADER)
6052     {
6053         if (checkCanUseOneOfExtensions(
6054                 qualifierTypeLine, std::array<TExtension, 2u>{
6055                                        {TExtension::OVR_multiview, TExtension::OVR_multiview2}}))
6056         {
6057             parseNumViews(intValue, intValueLine, intValueString, &qualifier.numViews);
6058         }
6059     }
6060     else if (qualifierType == "invocations" && mShaderType == GL_GEOMETRY_SHADER_EXT &&
6061              (mShaderVersion >= 320 ||
6062               checkCanUseOneOfExtensions(
6063                   qualifierTypeLine,
6064                   std::array<TExtension, 2u>{
6065                       {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}})))
6066     {
6067         parseInvocations(intValue, intValueLine, intValueString, &qualifier.invocations);
6068     }
6069     else if (qualifierType == "max_vertices" && mShaderType == GL_GEOMETRY_SHADER_EXT &&
6070              (mShaderVersion >= 320 ||
6071               checkCanUseOneOfExtensions(
6072                   qualifierTypeLine,
6073                   std::array<TExtension, 2u>{
6074                       {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}})))
6075     {
6076         parseMaxVertices(intValue, intValueLine, intValueString, &qualifier.maxVertices);
6077     }
6078     else if (qualifierType == "index" && mShaderType == GL_FRAGMENT_SHADER &&
6079              checkCanUseExtension(qualifierTypeLine, TExtension::EXT_blend_func_extended))
6080     {
6081         parseIndexLayoutQualifier(intValue, intValueLine, intValueString, &qualifier.index);
6082         if (intValue != 0)
6083         {
6084             errorIfPLSDeclared(qualifierTypeLine, PLSIllegalOperations::FragDataIndexNonzero);
6085         }
6086     }
6087     else if (qualifierType == "vertices" && mShaderType == GL_TESS_CONTROL_SHADER_EXT &&
6088              (mShaderVersion >= 320 ||
6089               checkCanUseExtension(qualifierTypeLine, TExtension::EXT_tessellation_shader)))
6090     {
6091         parseVertices(intValue, intValueLine, intValueString, &qualifier.vertices);
6092     }
6093     else
6094     {
6095         error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
6096     }
6097 
6098     return qualifier;
6099 }
6100 
createTypeQualifierBuilder(const TSourceLoc & loc)6101 TTypeQualifierBuilder *TParseContext::createTypeQualifierBuilder(const TSourceLoc &loc)
6102 {
6103     return new TTypeQualifierBuilder(
6104         new TStorageQualifierWrapper(symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary, loc),
6105         mShaderVersion);
6106 }
6107 
parseGlobalStorageQualifier(TQualifier qualifier,const TSourceLoc & loc)6108 TStorageQualifierWrapper *TParseContext::parseGlobalStorageQualifier(TQualifier qualifier,
6109                                                                      const TSourceLoc &loc)
6110 {
6111     checkIsAtGlobalLevel(loc, getQualifierString(qualifier));
6112     return new TStorageQualifierWrapper(qualifier, loc);
6113 }
6114 
parseVaryingQualifier(const TSourceLoc & loc)6115 TStorageQualifierWrapper *TParseContext::parseVaryingQualifier(const TSourceLoc &loc)
6116 {
6117     if (getShaderType() == GL_VERTEX_SHADER)
6118     {
6119         return parseGlobalStorageQualifier(EvqVaryingOut, loc);
6120     }
6121     return parseGlobalStorageQualifier(EvqVaryingIn, loc);
6122 }
6123 
parseInQualifier(const TSourceLoc & loc)6124 TStorageQualifierWrapper *TParseContext::parseInQualifier(const TSourceLoc &loc)
6125 {
6126     if (declaringFunction())
6127     {
6128         return new TStorageQualifierWrapper(EvqParamIn, loc);
6129     }
6130 
6131     switch (getShaderType())
6132     {
6133         case GL_VERTEX_SHADER:
6134         {
6135             if (mShaderVersion < 300 && !anyMultiviewExtensionAvailable() &&
6136                 !IsDesktopGLSpec(mShaderSpec))
6137             {
6138                 error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "in");
6139             }
6140             return new TStorageQualifierWrapper(EvqVertexIn, loc);
6141         }
6142         case GL_FRAGMENT_SHADER:
6143         {
6144             if (mShaderVersion < 300 && !IsDesktopGLSpec(mShaderSpec))
6145             {
6146                 error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "in");
6147             }
6148             return new TStorageQualifierWrapper(EvqFragmentIn, loc);
6149         }
6150         case GL_COMPUTE_SHADER:
6151         {
6152             return new TStorageQualifierWrapper(EvqComputeIn, loc);
6153         }
6154         case GL_GEOMETRY_SHADER:
6155         {
6156             return new TStorageQualifierWrapper(EvqGeometryIn, loc);
6157         }
6158         case GL_TESS_CONTROL_SHADER:
6159         {
6160             return new TStorageQualifierWrapper(EvqTessControlIn, loc);
6161         }
6162         case GL_TESS_EVALUATION_SHADER:
6163         {
6164             return new TStorageQualifierWrapper(EvqTessEvaluationIn, loc);
6165         }
6166         default:
6167         {
6168             UNREACHABLE();
6169             return new TStorageQualifierWrapper(EvqLast, loc);
6170         }
6171     }
6172 }
6173 
parseOutQualifier(const TSourceLoc & loc)6174 TStorageQualifierWrapper *TParseContext::parseOutQualifier(const TSourceLoc &loc)
6175 {
6176     if (declaringFunction())
6177     {
6178         return new TStorageQualifierWrapper(EvqParamOut, loc);
6179     }
6180     switch (getShaderType())
6181     {
6182         case GL_VERTEX_SHADER:
6183         {
6184             if (mShaderVersion < 300 && !IsDesktopGLSpec(mShaderSpec))
6185             {
6186                 error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "out");
6187             }
6188             return new TStorageQualifierWrapper(EvqVertexOut, loc);
6189         }
6190         case GL_FRAGMENT_SHADER:
6191         {
6192             if (mShaderVersion < 300 && !IsDesktopGLSpec(mShaderSpec))
6193             {
6194                 error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "out");
6195             }
6196             return new TStorageQualifierWrapper(EvqFragmentOut, loc);
6197         }
6198         case GL_COMPUTE_SHADER:
6199         {
6200             error(loc, "storage qualifier isn't supported in compute shaders", "out");
6201             return new TStorageQualifierWrapper(EvqParamOut, loc);
6202         }
6203         case GL_GEOMETRY_SHADER_EXT:
6204         {
6205             return new TStorageQualifierWrapper(EvqGeometryOut, loc);
6206         }
6207         case GL_TESS_CONTROL_SHADER_EXT:
6208         {
6209             return new TStorageQualifierWrapper(EvqTessControlOut, loc);
6210         }
6211         case GL_TESS_EVALUATION_SHADER_EXT:
6212         {
6213             return new TStorageQualifierWrapper(EvqTessEvaluationOut, loc);
6214         }
6215         default:
6216         {
6217             UNREACHABLE();
6218             return new TStorageQualifierWrapper(EvqLast, loc);
6219         }
6220     }
6221 }
6222 
parseInOutQualifier(const TSourceLoc & loc)6223 TStorageQualifierWrapper *TParseContext::parseInOutQualifier(const TSourceLoc &loc)
6224 {
6225     if (!declaringFunction())
6226     {
6227         if (mShaderVersion < 300 && !IsDesktopGLSpec(mShaderSpec))
6228         {
6229             error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "inout");
6230         }
6231 
6232         if (getShaderType() != GL_FRAGMENT_SHADER)
6233         {
6234             error(loc, "storage qualifier isn't supported in non-fragment shaders", "inout");
6235         }
6236 
6237         if (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch) ||
6238             isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent))
6239         {
6240             return new TStorageQualifierWrapper(EvqFragmentInOut, loc);
6241         }
6242 
6243         error(loc,
6244               "invalid qualifier: can be used with either function parameters or the variables for "
6245               "fetching input attachment data",
6246               "inout");
6247     }
6248     return new TStorageQualifierWrapper(EvqParamInOut, loc);
6249 }
6250 
joinLayoutQualifiers(TLayoutQualifier leftQualifier,TLayoutQualifier rightQualifier,const TSourceLoc & rightQualifierLocation)6251 TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier,
6252                                                      TLayoutQualifier rightQualifier,
6253                                                      const TSourceLoc &rightQualifierLocation)
6254 {
6255     return sh::JoinLayoutQualifiers(leftQualifier, rightQualifier, rightQualifierLocation,
6256                                     mDiagnostics);
6257 }
6258 
parseStructDeclarator(const ImmutableString & identifier,const TSourceLoc & loc)6259 TDeclarator *TParseContext::parseStructDeclarator(const ImmutableString &identifier,
6260                                                   const TSourceLoc &loc)
6261 {
6262     return new TDeclarator(identifier, loc);
6263 }
6264 
parseStructArrayDeclarator(const ImmutableString & identifier,const TSourceLoc & loc,const TVector<unsigned int> * arraySizes)6265 TDeclarator *TParseContext::parseStructArrayDeclarator(const ImmutableString &identifier,
6266                                                        const TSourceLoc &loc,
6267                                                        const TVector<unsigned int> *arraySizes)
6268 {
6269     return new TDeclarator(identifier, arraySizes, loc);
6270 }
6271 
checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,const TFieldList::const_iterator end,const ImmutableString & name,const TSourceLoc & location)6272 void TParseContext::checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
6273                                                        const TFieldList::const_iterator end,
6274                                                        const ImmutableString &name,
6275                                                        const TSourceLoc &location)
6276 {
6277     for (auto fieldIter = begin; fieldIter != end; ++fieldIter)
6278     {
6279         if ((*fieldIter)->name() == name)
6280         {
6281             error(location, "duplicate field name in structure", name);
6282         }
6283     }
6284 }
6285 
addStructFieldList(TFieldList * fields,const TSourceLoc & location)6286 TFieldList *TParseContext::addStructFieldList(TFieldList *fields, const TSourceLoc &location)
6287 {
6288     for (TFieldList::const_iterator fieldIter = fields->begin(); fieldIter != fields->end();
6289          ++fieldIter)
6290     {
6291         checkDoesNotHaveDuplicateFieldName(fields->begin(), fieldIter, (*fieldIter)->name(),
6292                                            location);
6293     }
6294     return fields;
6295 }
6296 
combineStructFieldLists(TFieldList * processedFields,const TFieldList * newlyAddedFields,const TSourceLoc & location)6297 TFieldList *TParseContext::combineStructFieldLists(TFieldList *processedFields,
6298                                                    const TFieldList *newlyAddedFields,
6299                                                    const TSourceLoc &location)
6300 {
6301     for (TField *field : *newlyAddedFields)
6302     {
6303         checkDoesNotHaveDuplicateFieldName(processedFields->begin(), processedFields->end(),
6304                                            field->name(), location);
6305         processedFields->push_back(field);
6306     }
6307     return processedFields;
6308 }
6309 
addStructDeclaratorListWithQualifiers(const TTypeQualifierBuilder & typeQualifierBuilder,TPublicType * typeSpecifier,const TDeclaratorList * declaratorList)6310 TFieldList *TParseContext::addStructDeclaratorListWithQualifiers(
6311     const TTypeQualifierBuilder &typeQualifierBuilder,
6312     TPublicType *typeSpecifier,
6313     const TDeclaratorList *declaratorList)
6314 {
6315     TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
6316 
6317     typeSpecifier->qualifier       = typeQualifier.qualifier;
6318     typeSpecifier->layoutQualifier = typeQualifier.layoutQualifier;
6319     typeSpecifier->memoryQualifier = typeQualifier.memoryQualifier;
6320     typeSpecifier->invariant       = typeQualifier.invariant;
6321     typeSpecifier->precise         = typeQualifier.precise;
6322     if (typeQualifier.precision != EbpUndefined)
6323     {
6324         typeSpecifier->precision = typeQualifier.precision;
6325     }
6326     return addStructDeclaratorList(*typeSpecifier, declaratorList);
6327 }
6328 
addStructDeclaratorList(const TPublicType & typeSpecifier,const TDeclaratorList * declaratorList)6329 TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecifier,
6330                                                    const TDeclaratorList *declaratorList)
6331 {
6332     checkPrecisionSpecified(typeSpecifier.getLine(), typeSpecifier.precision,
6333                             typeSpecifier.getBasicType());
6334 
6335     checkIsNonVoid(typeSpecifier.getLine(), (*declaratorList)[0]->name(),
6336                    typeSpecifier.getBasicType());
6337 
6338     checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), typeSpecifier.layoutQualifier);
6339     checkEarlyFragmentTestsIsNotSpecified(typeSpecifier.getLine(),
6340                                           typeSpecifier.layoutQualifier.earlyFragmentTests);
6341     checkNoncoherentIsNotSpecified(typeSpecifier.getLine(),
6342                                    typeSpecifier.layoutQualifier.noncoherent);
6343 
6344     TFieldList *fieldList = new TFieldList();
6345 
6346     for (const TDeclarator *declarator : *declaratorList)
6347     {
6348         TType *type = new TType(typeSpecifier);
6349         if (declarator->isArray())
6350         {
6351             // Don't allow arrays of arrays in ESSL < 3.10.
6352             checkArrayElementIsNotArray(typeSpecifier.getLine(), typeSpecifier);
6353             type->makeArrays(*declarator->arraySizes());
6354         }
6355 
6356         SymbolType symbolType = SymbolType::UserDefined;
6357         if (declarator->name() == "gl_Position" || declarator->name() == "gl_PointSize" ||
6358             declarator->name() == "gl_ClipDistance" || declarator->name() == "gl_CullDistance")
6359         {
6360             symbolType = SymbolType::BuiltIn;
6361         }
6362         else
6363         {
6364             checkIsNotReserved(typeSpecifier.getLine(), declarator->name());
6365         }
6366         TField *field = new TField(type, declarator->name(), declarator->line(), symbolType);
6367         checkIsBelowStructNestingLimit(typeSpecifier.getLine(), *field);
6368         fieldList->push_back(field);
6369     }
6370 
6371     return fieldList;
6372 }
6373 
addStructure(const TSourceLoc & structLine,const TSourceLoc & nameLine,const ImmutableString & structName,TFieldList * fieldList)6374 TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine,
6375                                                    const TSourceLoc &nameLine,
6376                                                    const ImmutableString &structName,
6377                                                    TFieldList *fieldList)
6378 {
6379     SymbolType structSymbolType = SymbolType::UserDefined;
6380     if (structName.empty())
6381     {
6382         structSymbolType = SymbolType::Empty;
6383     }
6384     TStructure *structure = new TStructure(&symbolTable, structName, fieldList, structSymbolType);
6385 
6386     // Store a bool in the struct if we're at global scope, to allow us to
6387     // skip the local struct scoping workaround in HLSL.
6388     structure->setAtGlobalScope(symbolTable.atGlobalLevel());
6389 
6390     if (structSymbolType != SymbolType::Empty)
6391     {
6392         checkIsNotReserved(nameLine, structName);
6393         if (!symbolTable.declare(structure))
6394         {
6395             error(nameLine, "redefinition of a struct", structName);
6396         }
6397     }
6398 
6399     // ensure we do not specify any storage qualifiers on the struct members
6400     for (unsigned int typeListIndex = 0; typeListIndex < fieldList->size(); typeListIndex++)
6401     {
6402         TField &field              = *(*fieldList)[typeListIndex];
6403         const TQualifier qualifier = field.type()->getQualifier();
6404         switch (qualifier)
6405         {
6406             case EvqGlobal:
6407             case EvqTemporary:
6408                 break;
6409             default:
6410                 error(field.line(), "invalid qualifier on struct member",
6411                       getQualifierString(qualifier));
6412                 break;
6413         }
6414         if (field.type()->isInvariant())
6415         {
6416             error(field.line(), "invalid qualifier on struct member", "invariant");
6417         }
6418 
6419         const TLayoutQualifier layoutQualifier = field.type()->getLayoutQualifier();
6420         if (!layoutQualifier.isEmpty())
6421         {
6422             error(field.line(), "invalid layout qualifier on struct member", "layout");
6423         }
6424 
6425         const TMemoryQualifier memoryQualifier = field.type()->getMemoryQualifier();
6426         if (!memoryQualifier.isEmpty())
6427         {
6428             error(field.line(), "invalid memory qualifier on struct member",
6429                   memoryQualifier.getAnyQualifierString());
6430         }
6431 
6432         if (field.type()->isPrecise())
6433         {
6434             error(field.line(), "invalid precise qualifier on struct member", "precise");
6435         }
6436 
6437         // ESSL 3.10 section 4.1.8 -- atomic_uint or images are not allowed as structure member.
6438         // ANGLE_shader_pixel_local_storage also disallows PLS as struct members.
6439         if (IsImage(field.type()->getBasicType()) ||
6440             IsAtomicCounter(field.type()->getBasicType()) ||
6441             IsPixelLocal(field.type()->getBasicType()))
6442         {
6443             error(field.line(), "disallowed type in struct", field.type()->getBasicString());
6444         }
6445 
6446         checkIsNotUnsizedArray(field.line(), "array members of structs must specify a size",
6447                                field.name(), field.type());
6448 
6449         checkMemoryQualifierIsNotSpecified(field.type()->getMemoryQualifier(), field.line());
6450 
6451         checkIndexIsNotSpecified(field.line(), field.type()->getLayoutQualifier().index);
6452 
6453         checkBindingIsNotSpecified(field.line(), field.type()->getLayoutQualifier().binding);
6454 
6455         checkLocationIsNotSpecified(field.line(), field.type()->getLayoutQualifier());
6456     }
6457 
6458     TTypeSpecifierNonArray typeSpecifierNonArray;
6459     typeSpecifierNonArray.initializeStruct(structure, true, structLine);
6460     exitStructDeclaration();
6461 
6462     return typeSpecifierNonArray;
6463 }
6464 
addSwitch(TIntermTyped * init,TIntermBlock * statementList,const TSourceLoc & loc)6465 TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init,
6466                                         TIntermBlock *statementList,
6467                                         const TSourceLoc &loc)
6468 {
6469     TBasicType switchType = init->getBasicType();
6470     if ((switchType != EbtInt && switchType != EbtUInt) || init->isMatrix() || init->isArray() ||
6471         init->isVector())
6472     {
6473         error(init->getLine(), "init-expression in a switch statement must be a scalar integer",
6474               "switch");
6475         return nullptr;
6476     }
6477 
6478     ASSERT(statementList);
6479     if (!ValidateSwitchStatementList(switchType, mDiagnostics, statementList, loc))
6480     {
6481         ASSERT(mDiagnostics->numErrors() > 0);
6482         return nullptr;
6483     }
6484 
6485     markStaticReadIfSymbol(init);
6486     TIntermSwitch *node = new TIntermSwitch(init, statementList);
6487     node->setLine(loc);
6488     return node;
6489 }
6490 
addCase(TIntermTyped * condition,const TSourceLoc & loc)6491 TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &loc)
6492 {
6493     if (mSwitchNestingLevel == 0)
6494     {
6495         error(loc, "case labels need to be inside switch statements", "case");
6496         return nullptr;
6497     }
6498     if (condition == nullptr)
6499     {
6500         error(loc, "case label must have a condition", "case");
6501         return nullptr;
6502     }
6503     if ((condition->getBasicType() != EbtInt && condition->getBasicType() != EbtUInt) ||
6504         condition->isMatrix() || condition->isArray() || condition->isVector())
6505     {
6506         error(condition->getLine(), "case label must be a scalar integer", "case");
6507     }
6508     TIntermConstantUnion *conditionConst = condition->getAsConstantUnion();
6509     // ANGLE should be able to fold any EvqConst expressions resulting in an integer - but to be
6510     // safe against corner cases we still check for conditionConst. Some interpretations of the
6511     // spec have allowed constant expressions with side effects - like array length() method on a
6512     // non-constant array.
6513     if (condition->getQualifier() != EvqConst || conditionConst == nullptr)
6514     {
6515         error(condition->getLine(), "case label must be constant", "case");
6516     }
6517     TIntermCase *node = new TIntermCase(condition);
6518     node->setLine(loc);
6519     return node;
6520 }
6521 
addDefault(const TSourceLoc & loc)6522 TIntermCase *TParseContext::addDefault(const TSourceLoc &loc)
6523 {
6524     if (mSwitchNestingLevel == 0)
6525     {
6526         error(loc, "default labels need to be inside switch statements", "default");
6527         return nullptr;
6528     }
6529     TIntermCase *node = new TIntermCase(nullptr);
6530     node->setLine(loc);
6531     return node;
6532 }
6533 
createUnaryMath(TOperator op,TIntermTyped * child,const TSourceLoc & loc,const TFunction * func)6534 TIntermTyped *TParseContext::createUnaryMath(TOperator op,
6535                                              TIntermTyped *child,
6536                                              const TSourceLoc &loc,
6537                                              const TFunction *func)
6538 {
6539     ASSERT(child != nullptr);
6540 
6541     switch (op)
6542     {
6543         case EOpLogicalNot:
6544             if (child->getBasicType() != EbtBool || child->isMatrix() || child->isArray() ||
6545                 child->isVector())
6546             {
6547                 unaryOpError(loc, GetOperatorString(op), child->getType());
6548                 return nullptr;
6549             }
6550             break;
6551         case EOpBitwiseNot:
6552             if ((child->getBasicType() != EbtInt && child->getBasicType() != EbtUInt) ||
6553                 child->isMatrix() || child->isArray())
6554             {
6555                 unaryOpError(loc, GetOperatorString(op), child->getType());
6556                 return nullptr;
6557             }
6558             break;
6559         case EOpPostIncrement:
6560         case EOpPreIncrement:
6561         case EOpPostDecrement:
6562         case EOpPreDecrement:
6563         case EOpNegative:
6564         case EOpPositive:
6565             if (child->getBasicType() == EbtStruct || child->isInterfaceBlock() ||
6566                 child->getBasicType() == EbtBool || child->isArray() ||
6567                 child->getBasicType() == EbtVoid || IsOpaqueType(child->getBasicType()))
6568             {
6569                 unaryOpError(loc, GetOperatorString(op), child->getType());
6570                 return nullptr;
6571             }
6572             break;
6573         // Operators for math built-ins are already type checked against their prototype.
6574         default:
6575             break;
6576     }
6577 
6578     if (child->getMemoryQualifier().writeonly)
6579     {
6580         const char *opStr =
6581             BuiltInGroup::IsBuiltIn(op) ? func->name().data() : GetOperatorString(op);
6582         unaryOpError(loc, opStr, child->getType());
6583         return nullptr;
6584     }
6585 
6586     markStaticReadIfSymbol(child);
6587     TIntermUnary *node = new TIntermUnary(op, child, func);
6588     node->setLine(loc);
6589 
6590     return node->fold(mDiagnostics);
6591 }
6592 
addUnaryMath(TOperator op,TIntermTyped * child,const TSourceLoc & loc)6593 TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
6594 {
6595     ASSERT(op != EOpNull);
6596     TIntermTyped *node = createUnaryMath(op, child, loc, nullptr);
6597     if (node == nullptr)
6598     {
6599         return child;
6600     }
6601     return node;
6602 }
6603 
addUnaryMathLValue(TOperator op,TIntermTyped * child,const TSourceLoc & loc)6604 TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op,
6605                                                 TIntermTyped *child,
6606                                                 const TSourceLoc &loc)
6607 {
6608     checkCanBeLValue(loc, GetOperatorString(op), child);
6609     return addUnaryMath(op, child, loc);
6610 }
6611 
expressionOrFoldedResult(TIntermTyped * expression)6612 TIntermTyped *TParseContext::expressionOrFoldedResult(TIntermTyped *expression)
6613 {
6614     // If we can, we should return the folded version of the expression for subsequent parsing. This
6615     // enables folding the containing expression during parsing as well, instead of the separate
6616     // FoldExpressions() step where folding nested expressions requires multiple full AST
6617     // traversals.
6618 
6619     // Even if folding fails the fold() functions return some node representing the expression,
6620     // typically the original node. So "folded" can be assumed to be non-null.
6621     TIntermTyped *folded = expression->fold(mDiagnostics);
6622     ASSERT(folded != nullptr);
6623     if (folded->getQualifier() == expression->getQualifier())
6624     {
6625         // We need this expression to have the correct qualifier when validating the consuming
6626         // expression. So we can only return the folded node from here in case it has the same
6627         // qualifier as the original expression. In this kind of a cases the qualifier of the folded
6628         // node is EvqConst, whereas the qualifier of the expression is EvqTemporary:
6629         //  1. (true ? 1.0 : non_constant)
6630         //  2. (non_constant, 1.0)
6631         return folded;
6632     }
6633     return expression;
6634 }
6635 
binaryOpCommonCheck(TOperator op,TIntermTyped * left,TIntermTyped * right,const TSourceLoc & loc)6636 bool TParseContext::binaryOpCommonCheck(TOperator op,
6637                                         TIntermTyped *left,
6638                                         TIntermTyped *right,
6639                                         const TSourceLoc &loc)
6640 {
6641     // Check opaque types are not allowed to be operands in expressions other than array indexing
6642     // and structure member selection.
6643     if (IsOpaqueType(left->getBasicType()) || IsOpaqueType(right->getBasicType()))
6644     {
6645         switch (op)
6646         {
6647             case EOpIndexDirect:
6648             case EOpIndexIndirect:
6649                 break;
6650 
6651             default:
6652                 ASSERT(op != EOpIndexDirectStruct);
6653                 error(loc, "Invalid operation for variables with an opaque type",
6654                       GetOperatorString(op));
6655                 return false;
6656         }
6657     }
6658 
6659     if (right->getMemoryQualifier().writeonly)
6660     {
6661         error(loc, "Invalid operation for variables with writeonly", GetOperatorString(op));
6662         return false;
6663     }
6664 
6665     if (left->getMemoryQualifier().writeonly)
6666     {
6667         switch (op)
6668         {
6669             case EOpAssign:
6670             case EOpInitialize:
6671             case EOpIndexDirect:
6672             case EOpIndexIndirect:
6673             case EOpIndexDirectStruct:
6674             case EOpIndexDirectInterfaceBlock:
6675                 break;
6676             default:
6677                 error(loc, "Invalid operation for variables with writeonly", GetOperatorString(op));
6678                 return false;
6679         }
6680     }
6681 
6682     if (left->getType().getStruct() || right->getType().getStruct())
6683     {
6684         switch (op)
6685         {
6686             case EOpIndexDirectStruct:
6687                 ASSERT(left->getType().getStruct());
6688                 break;
6689             case EOpEqual:
6690             case EOpNotEqual:
6691             case EOpAssign:
6692             case EOpInitialize:
6693                 if (left->getType() != right->getType())
6694                 {
6695                     return false;
6696                 }
6697                 break;
6698             default:
6699                 error(loc, "Invalid operation for structs", GetOperatorString(op));
6700                 return false;
6701         }
6702     }
6703 
6704     if (left->isInterfaceBlock() || right->isInterfaceBlock())
6705     {
6706         switch (op)
6707         {
6708             case EOpIndexDirectInterfaceBlock:
6709                 ASSERT(left->getType().getInterfaceBlock());
6710                 break;
6711             default:
6712                 error(loc, "Invalid operation for interface blocks", GetOperatorString(op));
6713                 return false;
6714         }
6715     }
6716 
6717     if (left->isArray() != right->isArray())
6718     {
6719         error(loc, "array / non-array mismatch", GetOperatorString(op));
6720         return false;
6721     }
6722 
6723     if (left->isArray())
6724     {
6725         ASSERT(right->isArray());
6726         if (mShaderVersion < 300)
6727         {
6728             error(loc, "Invalid operation for arrays", GetOperatorString(op));
6729             return false;
6730         }
6731 
6732         switch (op)
6733         {
6734             case EOpEqual:
6735             case EOpNotEqual:
6736             case EOpAssign:
6737             case EOpInitialize:
6738                 break;
6739             default:
6740                 error(loc, "Invalid operation for arrays", GetOperatorString(op));
6741                 return false;
6742         }
6743         // At this point, size of implicitly sized arrays should be resolved.
6744         if (left->getType().getArraySizes() != right->getType().getArraySizes())
6745         {
6746             error(loc, "array size mismatch", GetOperatorString(op));
6747             return false;
6748         }
6749     }
6750 
6751     // Check ops which require integer / ivec parameters
6752     bool isBitShift = false;
6753     switch (op)
6754     {
6755         case EOpBitShiftLeft:
6756         case EOpBitShiftRight:
6757         case EOpBitShiftLeftAssign:
6758         case EOpBitShiftRightAssign:
6759             // Unsigned can be bit-shifted by signed and vice versa, but we need to
6760             // check that the basic type is an integer type.
6761             isBitShift = true;
6762             if (!IsInteger(left->getBasicType()) || !IsInteger(right->getBasicType()))
6763             {
6764                 return false;
6765             }
6766             break;
6767         case EOpBitwiseAnd:
6768         case EOpBitwiseXor:
6769         case EOpBitwiseOr:
6770         case EOpBitwiseAndAssign:
6771         case EOpBitwiseXorAssign:
6772         case EOpBitwiseOrAssign:
6773             // It is enough to check the type of only one operand, since later it
6774             // is checked that the operand types match.
6775             if (!IsInteger(left->getBasicType()))
6776             {
6777                 return false;
6778             }
6779             break;
6780         default:
6781             break;
6782     }
6783 
6784     ImplicitTypeConversion conversion = GetConversion(left->getBasicType(), right->getBasicType());
6785 
6786     // Implicit type casting only supported for GL shaders
6787     if (!isBitShift && conversion != ImplicitTypeConversion::Same &&
6788         (!IsDesktopGLSpec(mShaderSpec) || !IsValidImplicitConversion(conversion, op)))
6789     {
6790         return false;
6791     }
6792 
6793     // Check that:
6794     // 1. Type sizes match exactly on ops that require that.
6795     // 2. Restrictions for structs that contain arrays or samplers are respected.
6796     // 3. Arithmetic op type dimensionality restrictions for ops other than multiply are respected.
6797     switch (op)
6798     {
6799         case EOpAssign:
6800         case EOpInitialize:
6801         case EOpEqual:
6802         case EOpNotEqual:
6803             // ESSL 1.00 sections 5.7, 5.8, 5.9
6804             if (mShaderVersion < 300 && left->getType().isStructureContainingArrays())
6805             {
6806                 error(loc, "undefined operation for structs containing arrays",
6807                       GetOperatorString(op));
6808                 return false;
6809             }
6810             // Samplers as l-values are disallowed also in ESSL 3.00, see section 4.1.7,
6811             // we interpret the spec so that this extends to structs containing samplers,
6812             // similarly to ESSL 1.00 spec.
6813             if ((mShaderVersion < 300 || op == EOpAssign || op == EOpInitialize) &&
6814                 left->getType().isStructureContainingSamplers())
6815             {
6816                 error(loc, "undefined operation for structs containing samplers",
6817                       GetOperatorString(op));
6818                 return false;
6819             }
6820 
6821             if ((left->getNominalSize() != right->getNominalSize()) ||
6822                 (left->getSecondarySize() != right->getSecondarySize()))
6823             {
6824                 error(loc, "dimension mismatch", GetOperatorString(op));
6825                 return false;
6826             }
6827             break;
6828         case EOpLessThan:
6829         case EOpGreaterThan:
6830         case EOpLessThanEqual:
6831         case EOpGreaterThanEqual:
6832             if (!left->isScalar() || !right->isScalar())
6833             {
6834                 error(loc, "comparison operator only defined for scalars", GetOperatorString(op));
6835                 return false;
6836             }
6837             break;
6838         case EOpAdd:
6839         case EOpSub:
6840         case EOpDiv:
6841         case EOpIMod:
6842         case EOpBitShiftLeft:
6843         case EOpBitShiftRight:
6844         case EOpBitwiseAnd:
6845         case EOpBitwiseXor:
6846         case EOpBitwiseOr:
6847         case EOpAddAssign:
6848         case EOpSubAssign:
6849         case EOpDivAssign:
6850         case EOpIModAssign:
6851         case EOpBitShiftLeftAssign:
6852         case EOpBitShiftRightAssign:
6853         case EOpBitwiseAndAssign:
6854         case EOpBitwiseXorAssign:
6855         case EOpBitwiseOrAssign:
6856             if ((left->isMatrix() && right->isVector()) || (left->isVector() && right->isMatrix()))
6857             {
6858                 return false;
6859             }
6860 
6861             // Are the sizes compatible?
6862             if (left->getNominalSize() != right->getNominalSize() ||
6863                 left->getSecondarySize() != right->getSecondarySize())
6864             {
6865                 // If the nominal sizes of operands do not match:
6866                 // One of them must be a scalar.
6867                 if (!left->isScalar() && !right->isScalar())
6868                     return false;
6869 
6870                 // In the case of compound assignment other than multiply-assign,
6871                 // the right side needs to be a scalar. Otherwise a vector/matrix
6872                 // would be assigned to a scalar. A scalar can't be shifted by a
6873                 // vector either.
6874                 if (!right->isScalar() &&
6875                     (IsAssignment(op) || op == EOpBitShiftLeft || op == EOpBitShiftRight))
6876                     return false;
6877             }
6878             break;
6879         default:
6880             break;
6881     }
6882 
6883     return true;
6884 }
6885 
isMultiplicationTypeCombinationValid(TOperator op,const TType & left,const TType & right)6886 bool TParseContext::isMultiplicationTypeCombinationValid(TOperator op,
6887                                                          const TType &left,
6888                                                          const TType &right)
6889 {
6890     switch (op)
6891     {
6892         case EOpMul:
6893         case EOpMulAssign:
6894             return left.getNominalSize() == right.getNominalSize() &&
6895                    left.getSecondarySize() == right.getSecondarySize();
6896         case EOpVectorTimesScalar:
6897             return true;
6898         case EOpVectorTimesScalarAssign:
6899             ASSERT(!left.isMatrix() && !right.isMatrix());
6900             return left.isVector() && !right.isVector();
6901         case EOpVectorTimesMatrix:
6902             return left.getNominalSize() == right.getRows();
6903         case EOpVectorTimesMatrixAssign:
6904             ASSERT(!left.isMatrix() && right.isMatrix());
6905             return left.isVector() && left.getNominalSize() == right.getRows() &&
6906                    left.getNominalSize() == right.getCols();
6907         case EOpMatrixTimesVector:
6908             return left.getCols() == right.getNominalSize();
6909         case EOpMatrixTimesScalar:
6910             return true;
6911         case EOpMatrixTimesScalarAssign:
6912             ASSERT(left.isMatrix() && !right.isMatrix());
6913             return !right.isVector();
6914         case EOpMatrixTimesMatrix:
6915             return left.getCols() == right.getRows();
6916         case EOpMatrixTimesMatrixAssign:
6917             ASSERT(left.isMatrix() && right.isMatrix());
6918             // We need to check two things:
6919             // 1. The matrix multiplication step is valid.
6920             // 2. The result will have the same number of columns as the lvalue.
6921             return left.getCols() == right.getRows() && left.getCols() == right.getCols();
6922 
6923         default:
6924             UNREACHABLE();
6925             return false;
6926     }
6927 }
6928 
addBinaryMathInternal(TOperator op,TIntermTyped * left,TIntermTyped * right,const TSourceLoc & loc)6929 TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op,
6930                                                    TIntermTyped *left,
6931                                                    TIntermTyped *right,
6932                                                    const TSourceLoc &loc)
6933 {
6934     if (!binaryOpCommonCheck(op, left, right, loc))
6935         return nullptr;
6936 
6937     switch (op)
6938     {
6939         case EOpEqual:
6940         case EOpNotEqual:
6941         case EOpLessThan:
6942         case EOpGreaterThan:
6943         case EOpLessThanEqual:
6944         case EOpGreaterThanEqual:
6945             break;
6946         case EOpLogicalOr:
6947         case EOpLogicalXor:
6948         case EOpLogicalAnd:
6949             ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() &&
6950                    !right->getType().getStruct());
6951             if (left->getBasicType() != EbtBool || !left->isScalar() || !right->isScalar())
6952             {
6953                 return nullptr;
6954             }
6955             // Basic types matching should have been already checked.
6956             ASSERT(right->getBasicType() == EbtBool);
6957             break;
6958         case EOpAdd:
6959         case EOpSub:
6960         case EOpDiv:
6961         case EOpMul:
6962             ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() &&
6963                    !right->getType().getStruct());
6964             if (left->getBasicType() == EbtBool)
6965             {
6966                 return nullptr;
6967             }
6968             break;
6969         case EOpIMod:
6970             ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() &&
6971                    !right->getType().getStruct());
6972             // Note that this is only for the % operator, not for mod()
6973             if (left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat)
6974             {
6975                 return nullptr;
6976             }
6977             break;
6978         default:
6979             break;
6980     }
6981 
6982     if (op == EOpMul)
6983     {
6984         op = TIntermBinary::GetMulOpBasedOnOperands(left->getType(), right->getType());
6985         if (!isMultiplicationTypeCombinationValid(op, left->getType(), right->getType()))
6986         {
6987             return nullptr;
6988         }
6989     }
6990 
6991     TIntermBinary *node = new TIntermBinary(op, left, right);
6992     ASSERT(op != EOpAssign);
6993     markStaticReadIfSymbol(left);
6994     markStaticReadIfSymbol(right);
6995     node->setLine(loc);
6996     return expressionOrFoldedResult(node);
6997 }
6998 
addBinaryMath(TOperator op,TIntermTyped * left,TIntermTyped * right,const TSourceLoc & loc)6999 TIntermTyped *TParseContext::addBinaryMath(TOperator op,
7000                                            TIntermTyped *left,
7001                                            TIntermTyped *right,
7002                                            const TSourceLoc &loc)
7003 {
7004     TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
7005     if (node == 0)
7006     {
7007         binaryOpError(loc, GetOperatorString(op), left->getType(), right->getType());
7008         return left;
7009     }
7010     return node;
7011 }
7012 
addBinaryMathBooleanResult(TOperator op,TIntermTyped * left,TIntermTyped * right,const TSourceLoc & loc)7013 TIntermTyped *TParseContext::addBinaryMathBooleanResult(TOperator op,
7014                                                         TIntermTyped *left,
7015                                                         TIntermTyped *right,
7016                                                         const TSourceLoc &loc)
7017 {
7018     TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
7019     if (node == nullptr)
7020     {
7021         binaryOpError(loc, GetOperatorString(op), left->getType(), right->getType());
7022         node = CreateBoolNode(false);
7023         node->setLine(loc);
7024     }
7025     return node;
7026 }
7027 
addAssign(TOperator op,TIntermTyped * left,TIntermTyped * right,const TSourceLoc & loc)7028 TIntermTyped *TParseContext::addAssign(TOperator op,
7029                                        TIntermTyped *left,
7030                                        TIntermTyped *right,
7031                                        const TSourceLoc &loc)
7032 {
7033     checkCanBeLValue(loc, "assign", left);
7034     TIntermBinary *node = nullptr;
7035     if (binaryOpCommonCheck(op, left, right, loc))
7036     {
7037         TIntermBinary *lValue = left->getAsBinaryNode();
7038         if ((lValue != nullptr) &&
7039             (lValue->getOp() == EOpIndexIndirect || lValue->getOp() == EOpIndexDirect) &&
7040             IsTessellationControlShaderOutput(mShaderType, lValue->getLeft()->getQualifier()))
7041         {
7042             checkTCSOutVarIndexIsValid(lValue, loc);
7043         }
7044 
7045         if (op == EOpMulAssign)
7046         {
7047             op = TIntermBinary::GetMulAssignOpBasedOnOperands(left->getType(), right->getType());
7048             if (isMultiplicationTypeCombinationValid(op, left->getType(), right->getType()))
7049             {
7050                 node = new TIntermBinary(op, left, right);
7051             }
7052         }
7053         else
7054         {
7055             node = new TIntermBinary(op, left, right);
7056         }
7057     }
7058     if (node == nullptr)
7059     {
7060         assignError(loc, "assign", left->getType(), right->getType());
7061         return left;
7062     }
7063     if (op != EOpAssign)
7064     {
7065         markStaticReadIfSymbol(left);
7066     }
7067     markStaticReadIfSymbol(right);
7068     node->setLine(loc);
7069     return node;
7070 }
7071 
addComma(TIntermTyped * left,TIntermTyped * right,const TSourceLoc & loc)7072 TIntermTyped *TParseContext::addComma(TIntermTyped *left,
7073                                       TIntermTyped *right,
7074                                       const TSourceLoc &loc)
7075 {
7076     // WebGL2 section 5.26, the following results in an error:
7077     // "Sequence operator applied to void, arrays, or structs containing arrays"
7078     if (mShaderSpec == SH_WEBGL2_SPEC &&
7079         (left->isArray() || left->getBasicType() == EbtVoid ||
7080          left->getType().isStructureContainingArrays() || right->isArray() ||
7081          right->getBasicType() == EbtVoid || right->getType().isStructureContainingArrays()))
7082     {
7083         error(loc,
7084               "sequence operator is not allowed for void, arrays, or structs containing arrays",
7085               ",");
7086     }
7087 
7088     TIntermBinary *commaNode = TIntermBinary::CreateComma(left, right, mShaderVersion);
7089     markStaticReadIfSymbol(left);
7090     markStaticReadIfSymbol(right);
7091     commaNode->setLine(loc);
7092 
7093     return expressionOrFoldedResult(commaNode);
7094 }
7095 
addBranch(TOperator op,const TSourceLoc & loc)7096 TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc)
7097 {
7098     switch (op)
7099     {
7100         case EOpContinue:
7101             if (mLoopNestingLevel <= 0)
7102             {
7103                 error(loc, "continue statement only allowed in loops", "");
7104             }
7105             break;
7106         case EOpBreak:
7107             if (mLoopNestingLevel <= 0 && mSwitchNestingLevel <= 0)
7108             {
7109                 error(loc, "break statement only allowed in loops and switch statements", "");
7110             }
7111             break;
7112         case EOpReturn:
7113             if (mCurrentFunctionType->getBasicType() != EbtVoid)
7114             {
7115                 error(loc, "non-void function must return a value", "return");
7116             }
7117             if (mDeclaringMain)
7118             {
7119                 errorIfPLSDeclared(loc, PLSIllegalOperations::ReturnFromMain);
7120             }
7121             break;
7122         case EOpKill:
7123             if (mShaderType != GL_FRAGMENT_SHADER)
7124             {
7125                 error(loc, "discard supported in fragment shaders only", "discard");
7126             }
7127             else
7128             {
7129                 errorIfPLSDeclared(loc, PLSIllegalOperations::Discard);
7130             }
7131             mHasDiscard = true;
7132             break;
7133         default:
7134             UNREACHABLE();
7135             break;
7136     }
7137     return addBranch(op, nullptr, loc);
7138 }
7139 
addBranch(TOperator op,TIntermTyped * expression,const TSourceLoc & loc)7140 TIntermBranch *TParseContext::addBranch(TOperator op,
7141                                         TIntermTyped *expression,
7142                                         const TSourceLoc &loc)
7143 {
7144     if (expression != nullptr)
7145     {
7146         markStaticReadIfSymbol(expression);
7147         ASSERT(op == EOpReturn);
7148         mFunctionReturnsValue = true;
7149         if (mCurrentFunctionType->getBasicType() == EbtVoid)
7150         {
7151             error(loc, "void function cannot return a value", "return");
7152         }
7153         else if (*mCurrentFunctionType != expression->getType())
7154         {
7155             error(loc, "function return is not matching type:", "return");
7156         }
7157     }
7158     TIntermBranch *node = new TIntermBranch(op, expression);
7159     node->setLine(loc);
7160     return node;
7161 }
7162 
appendStatement(TIntermBlock * block,TIntermNode * statement)7163 void TParseContext::appendStatement(TIntermBlock *block, TIntermNode *statement)
7164 {
7165     if (statement != nullptr)
7166     {
7167         markStaticReadIfSymbol(statement);
7168         block->appendStatement(statement);
7169     }
7170 }
7171 
checkTextureGather(TIntermAggregate * functionCall)7172 void TParseContext::checkTextureGather(TIntermAggregate *functionCall)
7173 {
7174     const TOperator op    = functionCall->getOp();
7175     const TFunction *func = functionCall->getFunction();
7176     if (BuiltInGroup::IsTextureGather(op))
7177     {
7178         bool isTextureGatherOffsetOrOffsets =
7179             BuiltInGroup::IsTextureGatherOffset(op) || BuiltInGroup::IsTextureGatherOffsets(op);
7180         TIntermNode *componentNode = nullptr;
7181         TIntermSequence *arguments = functionCall->getSequence();
7182         ASSERT(arguments->size() >= 2u && arguments->size() <= 4u);
7183         const TIntermTyped *sampler = arguments->front()->getAsTyped();
7184         ASSERT(sampler != nullptr);
7185         switch (sampler->getBasicType())
7186         {
7187             case EbtSampler2D:
7188             case EbtISampler2D:
7189             case EbtUSampler2D:
7190             case EbtSampler2DArray:
7191             case EbtISampler2DArray:
7192             case EbtUSampler2DArray:
7193                 if ((!isTextureGatherOffsetOrOffsets && arguments->size() == 3u) ||
7194                     (isTextureGatherOffsetOrOffsets && arguments->size() == 4u))
7195                 {
7196                     componentNode = arguments->back();
7197                 }
7198                 break;
7199             case EbtSamplerCube:
7200             case EbtISamplerCube:
7201             case EbtUSamplerCube:
7202             case EbtSamplerCubeArray:
7203             case EbtISamplerCubeArray:
7204             case EbtUSamplerCubeArray:
7205                 ASSERT(!isTextureGatherOffsetOrOffsets);
7206                 if (arguments->size() == 3u)
7207                 {
7208                     componentNode = arguments->back();
7209                 }
7210                 break;
7211             case EbtSampler2DShadow:
7212             case EbtSampler2DArrayShadow:
7213             case EbtSamplerCubeShadow:
7214             case EbtSamplerCubeArrayShadow:
7215                 break;
7216             default:
7217                 UNREACHABLE();
7218                 break;
7219         }
7220         if (componentNode)
7221         {
7222             const TIntermConstantUnion *componentConstantUnion =
7223                 componentNode->getAsConstantUnion();
7224             if (componentNode->getAsTyped()->getQualifier() != EvqConst || !componentConstantUnion)
7225             {
7226                 error(functionCall->getLine(), "Texture component must be a constant expression",
7227                       func->name());
7228             }
7229             else
7230             {
7231                 int component = componentConstantUnion->getIConst(0);
7232                 if (component < 0 || component > 3)
7233                 {
7234                     error(functionCall->getLine(), "Component must be in the range [0;3]",
7235                           func->name());
7236                 }
7237             }
7238         }
7239     }
7240 }
7241 
checkTextureOffset(TIntermAggregate * functionCall)7242 void TParseContext::checkTextureOffset(TIntermAggregate *functionCall)
7243 {
7244     const TOperator op         = functionCall->getOp();
7245     const TFunction *func      = functionCall->getFunction();
7246     TIntermNode *offset        = nullptr;
7247     TIntermSequence *arguments = functionCall->getSequence();
7248 
7249     if (BuiltInGroup::IsTextureOffsetNoBias(op) || BuiltInGroup::IsTextureGatherOffsetNoComp(op) ||
7250         BuiltInGroup::IsTextureGatherOffsetsNoComp(op))
7251     {
7252         offset = arguments->back();
7253     }
7254     else if (BuiltInGroup::IsTextureOffsetBias(op) || BuiltInGroup::IsTextureGatherOffsetComp(op) ||
7255              BuiltInGroup::IsTextureGatherOffsetsComp(op))
7256     {
7257         // A bias or comp parameter follows the offset parameter.
7258         ASSERT(arguments->size() >= 3);
7259         offset = (*arguments)[2];
7260     }
7261 
7262     // If not one of the above built-ins, there's nothing to do here.
7263     if (offset == nullptr)
7264     {
7265         return;
7266     }
7267 
7268     bool isTextureGatherOffset             = BuiltInGroup::IsTextureGatherOffset(op);
7269     bool isTextureGatherOffsets            = BuiltInGroup::IsTextureGatherOffsets(op);
7270     bool useTextureGatherOffsetConstraints = isTextureGatherOffset || isTextureGatherOffsets;
7271 
7272     int minOffsetValue =
7273         useTextureGatherOffsetConstraints ? mMinProgramTextureGatherOffset : mMinProgramTexelOffset;
7274     int maxOffsetValue =
7275         useTextureGatherOffsetConstraints ? mMaxProgramTextureGatherOffset : mMaxProgramTexelOffset;
7276 
7277     if (isTextureGatherOffsets)
7278     {
7279         // If textureGatherOffsets, the offsets parameter is an array, which is expected as an
7280         // aggregate constructor node or as a symbol node with a constant value.
7281         TIntermAggregate *offsetAggregate = offset->getAsAggregate();
7282         TIntermSymbol *offsetSymbol       = offset->getAsSymbolNode();
7283 
7284         const TConstantUnion *offsetValues = offsetAggregate ? offsetAggregate->getConstantValue()
7285                                              : offsetSymbol  ? offsetSymbol->getConstantValue()
7286                                                              : nullptr;
7287 
7288         if (offsetValues == nullptr)
7289         {
7290             error(functionCall->getLine(), "Texture offsets must be a constant expression",
7291                   func->name());
7292             return;
7293         }
7294 
7295         constexpr unsigned int kOffsetsCount = 4;
7296         const TType &offsetType =
7297             offsetAggregate != nullptr ? offsetAggregate->getType() : offsetSymbol->getType();
7298         if (offsetType.getNumArraySizes() != 1 || offsetType.getArraySizes()[0] != kOffsetsCount)
7299         {
7300             error(functionCall->getLine(), "Texture offsets must be an array of 4 elements",
7301                   func->name());
7302             return;
7303         }
7304 
7305         size_t size = offsetType.getObjectSize() / kOffsetsCount;
7306         for (unsigned int i = 0; i < kOffsetsCount; ++i)
7307         {
7308             checkSingleTextureOffset(offset->getLine(), &offsetValues[i * size], size,
7309                                      minOffsetValue, maxOffsetValue);
7310         }
7311     }
7312     else
7313     {
7314         // If textureOffset or textureGatherOffset, the offset is expected to be found as a constant
7315         // union.
7316         TIntermConstantUnion *offsetConstantUnion = offset->getAsConstantUnion();
7317 
7318         // ES3.2 or ES3.1's EXT_gpu_shader5 allow non-const offsets to be passed to
7319         // textureGatherOffset.
7320         bool textureGatherOffsetMustBeConst =
7321             mShaderVersion <= 310 && !isExtensionEnabled(TExtension::EXT_gpu_shader5);
7322 
7323         bool isOffsetConst =
7324             offset->getAsTyped()->getQualifier() == EvqConst && offsetConstantUnion != nullptr;
7325         bool offsetMustBeConst = !isTextureGatherOffset || textureGatherOffsetMustBeConst;
7326 
7327         if (!isOffsetConst && offsetMustBeConst)
7328         {
7329             error(functionCall->getLine(), "Texture offset must be a constant expression",
7330                   func->name());
7331             return;
7332         }
7333 
7334         // We cannot verify non-constant offsets to textureGatherOffset.
7335         if (offsetConstantUnion == nullptr)
7336         {
7337             ASSERT(!offsetMustBeConst);
7338             return;
7339         }
7340 
7341         size_t size                  = offsetConstantUnion->getType().getObjectSize();
7342         const TConstantUnion *values = offsetConstantUnion->getConstantValue();
7343         checkSingleTextureOffset(offset->getLine(), values, size, minOffsetValue, maxOffsetValue);
7344     }
7345 }
7346 
checkSingleTextureOffset(const TSourceLoc & line,const TConstantUnion * values,size_t size,int minOffsetValue,int maxOffsetValue)7347 void TParseContext::checkSingleTextureOffset(const TSourceLoc &line,
7348                                              const TConstantUnion *values,
7349                                              size_t size,
7350                                              int minOffsetValue,
7351                                              int maxOffsetValue)
7352 {
7353     for (size_t i = 0u; i < size; ++i)
7354     {
7355         ASSERT(values[i].getType() == EbtInt);
7356         int offsetValue = values[i].getIConst();
7357         if (offsetValue > maxOffsetValue || offsetValue < minOffsetValue)
7358         {
7359             std::stringstream tokenStream = sh::InitializeStream<std::stringstream>();
7360             tokenStream << offsetValue;
7361             std::string token = tokenStream.str();
7362             error(line, "Texture offset value out of valid range", token.c_str());
7363         }
7364     }
7365 }
7366 
checkInterpolationFS(TIntermAggregate * functionCall)7367 void TParseContext::checkInterpolationFS(TIntermAggregate *functionCall)
7368 {
7369     const TFunction *func = functionCall->getFunction();
7370     if (!BuiltInGroup::IsInterpolationFS(functionCall->getOp()))
7371     {
7372         return;
7373     }
7374 
7375     TIntermTyped *arg0 = nullptr;
7376 
7377     if (functionCall->getAsAggregate())
7378     {
7379         const TIntermSequence *argp = functionCall->getSequence();
7380         if (argp->size() > 0)
7381             arg0 = (*argp)[0]->getAsTyped();
7382     }
7383     else
7384     {
7385         assert(functionCall->getAsUnaryNode());
7386         arg0 = functionCall->getAsUnaryNode()->getOperand();
7387     }
7388 
7389     // Make sure the first argument is an interpolant, or an array element of an interpolant
7390     if (!IsVaryingIn(arg0->getType().getQualifier()))
7391     {
7392         // It might still be an array element.
7393         const TIntermTyped *base = FindLValueBase(arg0);
7394 
7395         if (base == nullptr || (!IsVaryingIn(base->getType().getQualifier())))
7396             error(arg0->getLine(),
7397                   "first argument must be an interpolant, or interpolant-array element",
7398                   func->name());
7399     }
7400 }
7401 
checkAtomicMemoryBuiltinFunctions(TIntermAggregate * functionCall)7402 void TParseContext::checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall)
7403 {
7404     const TFunction *func = functionCall->getFunction();
7405     if (BuiltInGroup::IsAtomicMemory(functionCall->getOp()))
7406     {
7407         TIntermSequence *arguments = functionCall->getSequence();
7408         TIntermTyped *memNode      = (*arguments)[0]->getAsTyped();
7409 
7410         if (IsBufferOrSharedVariable(memNode))
7411         {
7412             return;
7413         }
7414 
7415         while (memNode->getAsBinaryNode() || memNode->getAsSwizzleNode())
7416         {
7417             // Child 0 is "left" if binary, and the expression being swizzled if swizzle.
7418             // Note: we don't need to check that the binary operation is one of EOp*Index*, as any
7419             // other operation will result in a temp value which cannot be passed to this
7420             // out/inout parameter anyway.
7421             memNode = memNode->getChildNode(0)->getAsTyped();
7422             if (IsBufferOrSharedVariable(memNode))
7423             {
7424                 return;
7425             }
7426         }
7427 
7428         error(memNode->getLine(),
7429               "The value passed to the mem argument of an atomic memory function does not "
7430               "correspond to a buffer or shared variable.",
7431               func->name());
7432     }
7433 }
7434 
7435 // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate * functionCall)7436 void TParseContext::checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall)
7437 {
7438     const TOperator op = functionCall->getOp();
7439 
7440     if (BuiltInGroup::IsImage(op))
7441     {
7442         TIntermSequence *arguments = functionCall->getSequence();
7443         TIntermTyped *imageNode    = (*arguments)[0]->getAsTyped();
7444 
7445         const TMemoryQualifier &memoryQualifier = imageNode->getMemoryQualifier();
7446 
7447         if (BuiltInGroup::IsImageStore(op))
7448         {
7449             if (memoryQualifier.readonly)
7450             {
7451                 error(imageNode->getLine(),
7452                       "'imageStore' cannot be used with images qualified as 'readonly'",
7453                       GetImageArgumentToken(imageNode));
7454             }
7455         }
7456         else if (BuiltInGroup::IsImageLoad(op))
7457         {
7458             if (memoryQualifier.writeonly)
7459             {
7460                 error(imageNode->getLine(),
7461                       "'imageLoad' cannot be used with images qualified as 'writeonly'",
7462                       GetImageArgumentToken(imageNode));
7463             }
7464         }
7465         else if (BuiltInGroup::IsImageAtomic(op))
7466         {
7467             if (memoryQualifier.readonly)
7468             {
7469                 error(imageNode->getLine(),
7470                       "'imageAtomic' cannot be used with images qualified as 'readonly'",
7471                       GetImageArgumentToken(imageNode));
7472             }
7473             if (memoryQualifier.writeonly)
7474             {
7475                 error(imageNode->getLine(),
7476                       "'imageAtomic' cannot be used with images qualified as 'writeonly'",
7477                       GetImageArgumentToken(imageNode));
7478             }
7479         }
7480     }
7481 }
7482 
7483 // GLSL ES 3.10 Revision 4, 13.51 Matching of Memory Qualifiers in Function Parameters
checkImageMemoryAccessForUserDefinedFunctions(const TFunction * functionDefinition,const TIntermAggregate * functionCall)7484 void TParseContext::checkImageMemoryAccessForUserDefinedFunctions(
7485     const TFunction *functionDefinition,
7486     const TIntermAggregate *functionCall)
7487 {
7488     ASSERT(functionCall->getOp() == EOpCallFunctionInAST);
7489 
7490     const TIntermSequence &arguments = *functionCall->getSequence();
7491 
7492     ASSERT(functionDefinition->getParamCount() == arguments.size());
7493 
7494     for (size_t i = 0; i < arguments.size(); ++i)
7495     {
7496         TIntermTyped *typedArgument        = arguments[i]->getAsTyped();
7497         const TType &functionArgumentType  = typedArgument->getType();
7498         const TType &functionParameterType = functionDefinition->getParam(i)->getType();
7499         ASSERT(functionArgumentType.getBasicType() == functionParameterType.getBasicType());
7500 
7501         if (IsImage(functionArgumentType.getBasicType()))
7502         {
7503             const TMemoryQualifier &functionArgumentMemoryQualifier =
7504                 functionArgumentType.getMemoryQualifier();
7505             const TMemoryQualifier &functionParameterMemoryQualifier =
7506                 functionParameterType.getMemoryQualifier();
7507             if (functionArgumentMemoryQualifier.readonly &&
7508                 !functionParameterMemoryQualifier.readonly)
7509             {
7510                 error(functionCall->getLine(),
7511                       "Function call discards the 'readonly' qualifier from image",
7512                       GetImageArgumentToken(typedArgument));
7513             }
7514 
7515             if (functionArgumentMemoryQualifier.writeonly &&
7516                 !functionParameterMemoryQualifier.writeonly)
7517             {
7518                 error(functionCall->getLine(),
7519                       "Function call discards the 'writeonly' qualifier from image",
7520                       GetImageArgumentToken(typedArgument));
7521             }
7522 
7523             if (functionArgumentMemoryQualifier.coherent &&
7524                 !functionParameterMemoryQualifier.coherent)
7525             {
7526                 error(functionCall->getLine(),
7527                       "Function call discards the 'coherent' qualifier from image",
7528                       GetImageArgumentToken(typedArgument));
7529             }
7530 
7531             if (functionArgumentMemoryQualifier.volatileQualifier &&
7532                 !functionParameterMemoryQualifier.volatileQualifier)
7533             {
7534                 error(functionCall->getLine(),
7535                       "Function call discards the 'volatile' qualifier from image",
7536                       GetImageArgumentToken(typedArgument));
7537             }
7538         }
7539     }
7540 }
7541 
addFunctionCallOrMethod(TFunctionLookup * fnCall,const TSourceLoc & loc)7542 TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunctionLookup *fnCall, const TSourceLoc &loc)
7543 {
7544     if (fnCall->thisNode() != nullptr)
7545     {
7546         return addMethod(fnCall, loc);
7547     }
7548     if (fnCall->isConstructor())
7549     {
7550         return addConstructor(fnCall, loc);
7551     }
7552     return addNonConstructorFunctionCall(fnCall, loc);
7553 }
7554 
addMethod(TFunctionLookup * fnCall,const TSourceLoc & loc)7555 TIntermTyped *TParseContext::addMethod(TFunctionLookup *fnCall, const TSourceLoc &loc)
7556 {
7557     TIntermTyped *thisNode = fnCall->thisNode();
7558     // It's possible for the name pointer in the TFunction to be null in case it gets parsed as
7559     // a constructor. But such a TFunction can't reach here, since the lexer goes into FIELDS
7560     // mode after a dot, which makes type identifiers to be parsed as FIELD_SELECTION instead.
7561     // So accessing fnCall->name() below is safe.
7562     if (fnCall->name() != "length")
7563     {
7564         error(loc, "invalid method", fnCall->name());
7565     }
7566     else if (!fnCall->arguments().empty())
7567     {
7568         error(loc, "method takes no parameters", "length");
7569     }
7570     else if (!thisNode->isArray())
7571     {
7572         error(loc, "length can only be called on arrays", "length");
7573     }
7574     else if (thisNode->getQualifier() == EvqPerVertexIn &&
7575              mGeometryShaderInputPrimitiveType == EptUndefined)
7576     {
7577         ASSERT(mShaderType == GL_GEOMETRY_SHADER_EXT);
7578         error(loc, "missing input primitive declaration before calling length on gl_in", "length");
7579     }
7580     else
7581     {
7582         TIntermUnary *node = new TIntermUnary(EOpArrayLength, thisNode, nullptr);
7583         markStaticReadIfSymbol(thisNode);
7584         node->setLine(loc);
7585         return node->fold(mDiagnostics);
7586     }
7587     return CreateZeroNode(TType(EbtInt, EbpUndefined, EvqConst));
7588 }
7589 
addNonConstructorFunctionCall(TFunctionLookup * fnCall,const TSourceLoc & loc)7590 TIntermTyped *TParseContext::addNonConstructorFunctionCall(TFunctionLookup *fnCall,
7591                                                            const TSourceLoc &loc)
7592 {
7593     // First check whether the function has been hidden by a variable name or struct typename by
7594     // using the symbol looked up in the lexical phase. If the function is not hidden, look for one
7595     // with a matching argument list.
7596     if (fnCall->symbol() != nullptr && !fnCall->symbol()->isFunction())
7597     {
7598         error(loc, "function name expected", fnCall->name());
7599     }
7600     else
7601     {
7602         // There are no inner functions, so it's enough to look for user-defined functions in the
7603         // global scope.
7604         const TSymbol *symbol = symbolTable.findGlobal(fnCall->getMangledName());
7605 
7606         if (symbol == nullptr && IsDesktopGLSpec(mShaderSpec))
7607         {
7608             // If using Desktop GL spec, need to check for implicit conversion
7609             symbol = symbolTable.findGlobalWithConversion(
7610                 fnCall->getMangledNamesForImplicitConversions());
7611         }
7612 
7613         if (symbol != nullptr)
7614         {
7615             // A user-defined function - could be an overloaded built-in as well.
7616             ASSERT(symbol->symbolType() == SymbolType::UserDefined);
7617             const TFunction *fnCandidate = static_cast<const TFunction *>(symbol);
7618             TIntermAggregate *callNode =
7619                 TIntermAggregate::CreateFunctionCall(*fnCandidate, &fnCall->arguments());
7620             callNode->setLine(loc);
7621             checkImageMemoryAccessForUserDefinedFunctions(fnCandidate, callNode);
7622             functionCallRValueLValueErrorCheck(fnCandidate, callNode);
7623             return callNode;
7624         }
7625 
7626         symbol = symbolTable.findBuiltIn(fnCall->getMangledName(), mShaderVersion);
7627 
7628         if (symbol == nullptr && IsDesktopGLSpec(mShaderSpec))
7629         {
7630             // If using Desktop GL spec, need to check for implicit conversion
7631             symbol = symbolTable.findBuiltInWithConversion(
7632                 fnCall->getMangledNamesForImplicitConversions(), mShaderVersion);
7633         }
7634 
7635         if (symbol != nullptr)
7636         {
7637             // A built-in function.
7638             ASSERT(symbol->symbolType() == SymbolType::BuiltIn);
7639             const TFunction *fnCandidate = static_cast<const TFunction *>(symbol);
7640 
7641             if (!fnCandidate->extensions().empty() &&
7642                 fnCandidate->extensions()[0] != TExtension::UNDEFINED)
7643             {
7644                 checkCanUseOneOfExtensions(loc, fnCandidate->extensions());
7645             }
7646 
7647             // All function calls are mapped to a built-in operation.
7648             TOperator op = fnCandidate->getBuiltInOp();
7649             if (BuiltInGroup::IsMath(op) && fnCandidate->getParamCount() == 1)
7650             {
7651                 // Treat it like a built-in unary operator.
7652                 TIntermNode *unaryParamNode = fnCall->arguments().front();
7653                 TIntermTyped *callNode =
7654                     createUnaryMath(op, unaryParamNode->getAsTyped(), loc, fnCandidate);
7655                 ASSERT(callNode != nullptr);
7656                 return callNode;
7657             }
7658 
7659             TIntermAggregate *callNode =
7660                 TIntermAggregate::CreateBuiltInFunctionCall(*fnCandidate, &fnCall->arguments());
7661             callNode->setLine(loc);
7662 
7663             checkAtomicMemoryBuiltinFunctions(callNode);
7664             checkTextureOffset(callNode);
7665             checkTextureGather(callNode);
7666             checkInterpolationFS(callNode);
7667             checkImageMemoryAccessForBuiltinFunctions(callNode);
7668 
7669             // Some built-in functions have out parameters too.
7670             functionCallRValueLValueErrorCheck(fnCandidate, callNode);
7671 
7672             // See if we can constant fold a built-in. Note that this may be possible
7673             // even if it is not const-qualified.
7674             return callNode->fold(mDiagnostics);
7675         }
7676         else
7677         {
7678             error(loc, "no matching overloaded function found", fnCall->name());
7679         }
7680     }
7681 
7682     // Error message was already written. Put on an unused node for error recovery.
7683     return CreateZeroNode(TType(EbtFloat, EbpMedium, EvqConst));
7684 }
7685 
addTernarySelection(TIntermTyped * cond,TIntermTyped * trueExpression,TIntermTyped * falseExpression,const TSourceLoc & loc)7686 TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond,
7687                                                  TIntermTyped *trueExpression,
7688                                                  TIntermTyped *falseExpression,
7689                                                  const TSourceLoc &loc)
7690 {
7691     if (!checkIsScalarBool(loc, cond))
7692     {
7693         return falseExpression;
7694     }
7695 
7696     if (trueExpression->getType() != falseExpression->getType())
7697     {
7698         TInfoSinkBase reasonStream;
7699         reasonStream << "mismatching ternary operator operand types '" << trueExpression->getType()
7700                      << " and '" << falseExpression->getType() << "'";
7701         error(loc, reasonStream.c_str(), "?:");
7702         return falseExpression;
7703     }
7704     if (IsOpaqueType(trueExpression->getBasicType()))
7705     {
7706         // ESSL 1.00 section 4.1.7
7707         // ESSL 3.00.6 section 4.1.7
7708         // Opaque/sampler types are not allowed in most types of expressions, including ternary.
7709         // Note that structs containing opaque types don't need to be checked as structs are
7710         // forbidden below.
7711         error(loc, "ternary operator is not allowed for opaque types", "?:");
7712         return falseExpression;
7713     }
7714 
7715     if (cond->getMemoryQualifier().writeonly || trueExpression->getMemoryQualifier().writeonly ||
7716         falseExpression->getMemoryQualifier().writeonly)
7717     {
7718         error(loc, "ternary operator is not allowed for variables with writeonly", "?:");
7719         return falseExpression;
7720     }
7721 
7722     // ESSL 1.00.17 sections 5.2 and 5.7:
7723     // Ternary operator is not among the operators allowed for structures/arrays.
7724     // ESSL 3.00.6 section 5.7:
7725     // Ternary operator support is optional for arrays. No certainty that it works across all
7726     // devices with struct either, so we err on the side of caution here. TODO (oetuaho@nvidia.com):
7727     // Would be nice to make the spec and implementation agree completely here.
7728     if (trueExpression->isArray() || trueExpression->getBasicType() == EbtStruct)
7729     {
7730         error(loc, "ternary operator is not allowed for structures or arrays", "?:");
7731         return falseExpression;
7732     }
7733     if (trueExpression->getBasicType() == EbtInterfaceBlock)
7734     {
7735         error(loc, "ternary operator is not allowed for interface blocks", "?:");
7736         return falseExpression;
7737     }
7738 
7739     // WebGL2 section 5.26, the following results in an error:
7740     // "Ternary operator applied to void, arrays, or structs containing arrays"
7741     if (mShaderSpec == SH_WEBGL2_SPEC && trueExpression->getBasicType() == EbtVoid)
7742     {
7743         error(loc, "ternary operator is not allowed for void", "?:");
7744         return falseExpression;
7745     }
7746 
7747     TIntermTernary *node = new TIntermTernary(cond, trueExpression, falseExpression);
7748     markStaticReadIfSymbol(cond);
7749     markStaticReadIfSymbol(trueExpression);
7750     markStaticReadIfSymbol(falseExpression);
7751     node->setLine(loc);
7752     return expressionOrFoldedResult(node);
7753 }
7754 
7755 //
7756 // Parse an array of strings using yyparse.
7757 //
7758 // Returns 0 for success.
7759 //
PaParseStrings(size_t count,const char * const string[],const int length[],TParseContext * context)7760 int PaParseStrings(size_t count,
7761                    const char *const string[],
7762                    const int length[],
7763                    TParseContext *context)
7764 {
7765     if ((count == 0) || (string == nullptr))
7766         return 1;
7767 
7768     if (glslang_initialize(context))
7769         return 1;
7770 
7771     int error = glslang_scan(count, string, length, context);
7772     if (!error)
7773         error = glslang_parse(context);
7774 
7775     glslang_finalize(context);
7776 
7777     return (error == 0) && (context->numErrors() == 0) ? 0 : 1;
7778 }
7779 
7780 }  // namespace sh
7781