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