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