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