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