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