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