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