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