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