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