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