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