1 //
2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 #include "compiler/translator/ParseContext.h"
8
9 #include <stdarg.h>
10 #include <stdio.h>
11
12 #include "common/mathutil.h"
13 #include "common/utilities.h"
14 #include "compiler/preprocessor/SourceLocation.h"
15 #include "compiler/translator/Declarator.h"
16 #include "compiler/translator/StaticType.h"
17 #include "compiler/translator/ValidateGlobalInitializer.h"
18 #include "compiler/translator/ValidateSwitch.h"
19 #include "compiler/translator/glslang.h"
20 #include "compiler/translator/tree_util/IntermNode_util.h"
21 #include "compiler/translator/util.h"
22
23 namespace sh
24 {
25
26 ///////////////////////////////////////////////////////////////////////
27 //
28 // Sub- vector and matrix fields
29 //
30 ////////////////////////////////////////////////////////////////////////
31
32 namespace
33 {
34
35 const int kWebGLMaxStructNesting = 4;
36
37 struct IsSamplerFunc
38 {
operator ()sh::__anon9e080a080111::IsSamplerFunc39 bool operator()(TBasicType type) { return IsSampler(type); }
40 };
41 struct IsOpaqueFunc
42 {
operator ()sh::__anon9e080a080111::IsOpaqueFunc43 bool operator()(TBasicType type) { return IsOpaqueType(type); }
44 };
45
46 template <typename OpaqueFunc>
47 bool ContainsOpaque(const TStructure *structType);
48
49 template <typename OpaqueFunc>
ContainsOpaque(const TType & type)50 bool ContainsOpaque(const TType &type)
51 {
52 if (OpaqueFunc{}(type.getBasicType()))
53 {
54 return true;
55 }
56 if (type.getBasicType() == EbtStruct)
57 {
58 return ContainsOpaque<OpaqueFunc>(type.getStruct());
59 }
60
61 return false;
62 }
63
64 template <typename OpaqueFunc>
ContainsOpaque(const TStructure * structType)65 bool ContainsOpaque(const TStructure *structType)
66 {
67 for (const auto &field : structType->fields())
68 {
69 if (ContainsOpaque<OpaqueFunc>(*field->type()))
70 return true;
71 }
72 return false;
73 }
74
75 // Get a token from an image argument to use as an error message token.
GetImageArgumentToken(TIntermTyped * imageNode)76 const char *GetImageArgumentToken(TIntermTyped *imageNode)
77 {
78 ASSERT(IsImage(imageNode->getBasicType()));
79 while (imageNode->getAsBinaryNode() &&
80 (imageNode->getAsBinaryNode()->getOp() == EOpIndexIndirect ||
81 imageNode->getAsBinaryNode()->getOp() == EOpIndexDirect))
82 {
83 imageNode = imageNode->getAsBinaryNode()->getLeft();
84 }
85 TIntermSymbol *imageSymbol = imageNode->getAsSymbolNode();
86 if (imageSymbol)
87 {
88 return imageSymbol->getName().data();
89 }
90 return "image";
91 }
92
CanSetDefaultPrecisionOnType(const TPublicType & type)93 bool CanSetDefaultPrecisionOnType(const TPublicType &type)
94 {
95 if (!SupportsPrecision(type.getBasicType()))
96 {
97 return false;
98 }
99 if (type.getBasicType() == EbtUInt)
100 {
101 // ESSL 3.00.4 section 4.5.4
102 return false;
103 }
104 if (type.isAggregate())
105 {
106 // Not allowed to set for aggregate types
107 return false;
108 }
109 return true;
110 }
111
112 // Map input primitive types to input array sizes in a geometry shader.
GetGeometryShaderInputArraySize(TLayoutPrimitiveType primitiveType)113 GLuint GetGeometryShaderInputArraySize(TLayoutPrimitiveType primitiveType)
114 {
115 switch (primitiveType)
116 {
117 case EptPoints:
118 return 1u;
119 case EptLines:
120 return 2u;
121 case EptTriangles:
122 return 3u;
123 case EptLinesAdjacency:
124 return 4u;
125 case EptTrianglesAdjacency:
126 return 6u;
127 default:
128 UNREACHABLE();
129 return 0u;
130 }
131 }
132
IsBufferOrSharedVariable(TIntermTyped * var)133 bool IsBufferOrSharedVariable(TIntermTyped *var)
134 {
135 if (var->isInterfaceBlock() || var->getQualifier() == EvqBuffer ||
136 var->getQualifier() == EvqShared)
137 {
138 return true;
139 }
140 return false;
141 }
142
FindLValueBase(TIntermTyped * node)143 TIntermTyped *FindLValueBase(TIntermTyped *node)
144 {
145 do
146 {
147 const TIntermBinary *binary = node->getAsBinaryNode();
148 if (binary == nullptr)
149 {
150 return node;
151 }
152
153 TOperator op = binary->getOp();
154 if (op != EOpIndexDirect && op != EOpIndexIndirect)
155 {
156 return static_cast<TIntermTyped *>(nullptr);
157 }
158
159 node = binary->getLeft();
160 } while (true);
161 }
162
AddAdvancedBlendEquation(gl::BlendEquationType eq,TLayoutQualifier * qualifier)163 void AddAdvancedBlendEquation(gl::BlendEquationType eq, TLayoutQualifier *qualifier)
164 {
165 qualifier->advancedBlendEquations.set(static_cast<uint32_t>(eq));
166 }
167
IsValidWithPixelLocalStorage(TLayoutImageInternalFormat internalFormat)168 constexpr bool IsValidWithPixelLocalStorage(TLayoutImageInternalFormat internalFormat)
169 {
170 switch (internalFormat)
171 {
172 case EiifRGBA8:
173 case EiifRGBA8I:
174 case EiifRGBA8UI:
175 case EiifR32F:
176 case EiifR32UI:
177 return true;
178 default:
179 return false;
180 }
181 }
182
ImageFormatToPLSFormat(TLayoutImageInternalFormat format)183 constexpr ShPixelLocalStorageFormat ImageFormatToPLSFormat(TLayoutImageInternalFormat format)
184 {
185 switch (format)
186 {
187 default:
188 return ShPixelLocalStorageFormat::NotPLS;
189 case EiifRGBA8:
190 return ShPixelLocalStorageFormat::RGBA8;
191 case EiifRGBA8I:
192 return ShPixelLocalStorageFormat::RGBA8I;
193 case EiifRGBA8UI:
194 return ShPixelLocalStorageFormat::RGBA8UI;
195 case EiifR32F:
196 return ShPixelLocalStorageFormat::R32F;
197 case EiifR32UI:
198 return ShPixelLocalStorageFormat::R32UI;
199 }
200 }
201
UsesDerivatives(TIntermAggregate * functionCall)202 bool UsesDerivatives(TIntermAggregate *functionCall)
203 {
204 const TOperator op = functionCall->getOp();
205 if (BuiltInGroup::IsDerivativesFS(op))
206 {
207 return true;
208 }
209 switch (op)
210 {
211 // TextureFirstVersions with implicit LOD
212 case EOpTexture2D:
213 case EOpTexture2DProj:
214 case EOpTextureCube:
215 case EOpTexture3D:
216 case EOpTexture3DProj:
217 case EOpShadow2DEXT:
218 case EOpShadow2DProjEXT:
219 // TextureFirstVersionsBias
220 case EOpTexture2DBias:
221 case EOpTexture2DProjBias:
222 case EOpTextureCubeBias:
223 case EOpTexture3DBias:
224 case EOpTexture3DProjBias:
225 // TextureNoBias
226 case EOpTexture:
227 case EOpTextureProj:
228 // TextureBias
229 case EOpTextureBias:
230 case EOpTextureProjBias:
231 // TextureOffsetNoBias
232 case EOpTextureOffset:
233 case EOpTextureProjOffset:
234 // TextureOffsetBias
235 case EOpTextureOffsetBias:
236 case EOpTextureProjOffsetBias:
237 // TextureQueryLod
238 case EOpTextureQueryLOD:
239 return true;
240 default:
241 return false;
242 }
243 }
244 } // namespace
245
246 // This tracks each binding point's current default offset for inheritance of subsequent
247 // variables using the same binding, and keeps offsets unique and non overlapping.
248 // See GLSL ES 3.1, section 4.4.6.
249 class TParseContext::AtomicCounterBindingState
250 {
251 public:
AtomicCounterBindingState()252 AtomicCounterBindingState() : mDefaultOffset(0) {}
253 // Inserts a new span and returns -1 if overlapping, else returns the starting offset of
254 // newly inserted span.
insertSpan(int start,size_t length)255 int insertSpan(int start, size_t length)
256 {
257 gl::RangeI newSpan(start, start + static_cast<int>(length));
258 for (const auto &span : mSpans)
259 {
260 if (newSpan.intersects(span))
261 {
262 return -1;
263 }
264 }
265 mSpans.push_back(newSpan);
266 mDefaultOffset = newSpan.high();
267 return start;
268 }
269 // Inserts a new span starting from the default offset.
appendSpan(size_t length)270 int appendSpan(size_t length) { return insertSpan(mDefaultOffset, length); }
setDefaultOffset(int offset)271 void setDefaultOffset(int offset) { mDefaultOffset = offset; }
272
273 private:
274 int mDefaultOffset;
275 std::vector<gl::RangeI> mSpans;
276 };
277
TParseContext(TSymbolTable & symt,TExtensionBehavior & ext,sh::GLenum type,ShShaderSpec spec,const ShCompileOptions & options,TDiagnostics * diagnostics,const ShBuiltInResources & resources,ShShaderOutput outputType)278 TParseContext::TParseContext(TSymbolTable &symt,
279 TExtensionBehavior &ext,
280 sh::GLenum type,
281 ShShaderSpec spec,
282 const ShCompileOptions &options,
283 TDiagnostics *diagnostics,
284 const ShBuiltInResources &resources,
285 ShShaderOutput outputType)
286 : symbolTable(symt),
287 mDeferredNonEmptyDeclarationErrorCheck(false),
288 mShaderType(type),
289 mShaderSpec(spec),
290 mCompileOptions(options),
291 mShaderVersion(100),
292 mTreeRoot(nullptr),
293 mLoopNestingLevel(0),
294 mStructNestingLevel(0),
295 mSwitchNestingLevel(0),
296 mCurrentFunctionType(nullptr),
297 mFunctionReturnsValue(false),
298 mFragmentPrecisionHighOnESSL1(false),
299 mEarlyFragmentTestsSpecified(false),
300 mHasDiscard(false),
301 mSampleQualifierSpecified(false),
302 mPositionRedeclaredForSeparateShaderObject(false),
303 mPointSizeRedeclaredForSeparateShaderObject(false),
304 mPositionOrPointSizeUsedForSeparateShaderObject(false),
305 mUsesDerivatives(false),
306 mDefaultUniformMatrixPacking(EmpColumnMajor),
307 mDefaultUniformBlockStorage(sh::IsWebGLBasedSpec(spec) ? EbsStd140 : EbsShared),
308 mDefaultBufferMatrixPacking(EmpColumnMajor),
309 mDefaultBufferBlockStorage(sh::IsWebGLBasedSpec(spec) ? EbsStd140 : EbsShared),
310 mDiagnostics(diagnostics),
311 mDirectiveHandler(ext, *mDiagnostics, mShaderVersion, mShaderType),
312 mPreprocessor(mDiagnostics, &mDirectiveHandler, angle::pp::PreprocessorSettings(spec)),
313 mScanner(nullptr),
314 mMaxExpressionComplexity(static_cast<size_t>(options.limitExpressionComplexity
315 ? resources.MaxExpressionComplexity
316 : std::numeric_limits<size_t>::max())),
317 mMaxStatementDepth(static_cast<size_t>(resources.MaxStatementDepth)),
318 mMinProgramTexelOffset(resources.MinProgramTexelOffset),
319 mMaxProgramTexelOffset(resources.MaxProgramTexelOffset),
320 mMinProgramTextureGatherOffset(resources.MinProgramTextureGatherOffset),
321 mMaxProgramTextureGatherOffset(resources.MaxProgramTextureGatherOffset),
322 mComputeShaderLocalSizeDeclared(false),
323 mComputeShaderLocalSize(-1),
324 mNumViews(-1),
325 mMaxNumViews(resources.MaxViewsOVR),
326 mMaxImageUnits(resources.MaxImageUnits),
327 mMaxCombinedTextureImageUnits(resources.MaxCombinedTextureImageUnits),
328 mMaxUniformLocations(resources.MaxUniformLocations),
329 mMaxUniformBufferBindings(resources.MaxUniformBufferBindings),
330 mMaxVertexAttribs(resources.MaxVertexAttribs),
331 mMaxAtomicCounterBindings(resources.MaxAtomicCounterBindings),
332 mMaxAtomicCounterBufferSize(resources.MaxAtomicCounterBufferSize),
333 mMaxShaderStorageBufferBindings(resources.MaxShaderStorageBufferBindings),
334 mMaxPixelLocalStoragePlanes(resources.MaxPixelLocalStoragePlanes),
335 mDeclaringFunction(false),
336 mGeometryShaderInputPrimitiveType(EptUndefined),
337 mGeometryShaderOutputPrimitiveType(EptUndefined),
338 mGeometryShaderInvocations(0),
339 mGeometryShaderMaxVertices(-1),
340 mMaxGeometryShaderInvocations(resources.MaxGeometryShaderInvocations),
341 mMaxGeometryShaderMaxVertices(resources.MaxGeometryOutputVertices),
342 mGeometryInputArraySize(0),
343 mMaxPatchVertices(resources.MaxPatchVertices),
344 mTessControlShaderOutputVertices(0),
345 mTessEvaluationShaderInputPrimitiveType(EtetUndefined),
346 mTessEvaluationShaderInputVertexSpacingType(EtetUndefined),
347 mTessEvaluationShaderInputOrderingType(EtetUndefined),
348 mTessEvaluationShaderInputPointType(EtetUndefined),
349 mHasAnyPreciseType(false),
350 mAdvancedBlendEquations(0),
351 mFunctionBodyNewScope(false),
352 mOutputType(outputType)
353 {}
354
~TParseContext()355 TParseContext::~TParseContext() {}
356
anyMultiviewExtensionAvailable()357 bool TParseContext::anyMultiviewExtensionAvailable()
358 {
359 return isExtensionEnabled(TExtension::OVR_multiview) ||
360 isExtensionEnabled(TExtension::OVR_multiview2);
361 }
362
parseVectorFields(const TSourceLoc & line,const ImmutableString & compString,int vecSize,TVector<int> * fieldOffsets)363 bool TParseContext::parseVectorFields(const TSourceLoc &line,
364 const ImmutableString &compString,
365 int vecSize,
366 TVector<int> *fieldOffsets)
367 {
368 ASSERT(fieldOffsets);
369 size_t fieldCount = compString.length();
370 if (fieldCount > 4u)
371 {
372 error(line, "illegal vector field selection", compString);
373 return false;
374 }
375 fieldOffsets->resize(fieldCount);
376
377 enum
378 {
379 exyzw,
380 ergba,
381 estpq
382 } fieldSet[4];
383
384 for (unsigned int i = 0u; i < fieldOffsets->size(); ++i)
385 {
386 switch (compString[i])
387 {
388 case 'x':
389 (*fieldOffsets)[i] = 0;
390 fieldSet[i] = exyzw;
391 break;
392 case 'r':
393 (*fieldOffsets)[i] = 0;
394 fieldSet[i] = ergba;
395 break;
396 case 's':
397 (*fieldOffsets)[i] = 0;
398 fieldSet[i] = estpq;
399 break;
400 case 'y':
401 (*fieldOffsets)[i] = 1;
402 fieldSet[i] = exyzw;
403 break;
404 case 'g':
405 (*fieldOffsets)[i] = 1;
406 fieldSet[i] = ergba;
407 break;
408 case 't':
409 (*fieldOffsets)[i] = 1;
410 fieldSet[i] = estpq;
411 break;
412 case 'z':
413 (*fieldOffsets)[i] = 2;
414 fieldSet[i] = exyzw;
415 break;
416 case 'b':
417 (*fieldOffsets)[i] = 2;
418 fieldSet[i] = ergba;
419 break;
420 case 'p':
421 (*fieldOffsets)[i] = 2;
422 fieldSet[i] = estpq;
423 break;
424
425 case 'w':
426 (*fieldOffsets)[i] = 3;
427 fieldSet[i] = exyzw;
428 break;
429 case 'a':
430 (*fieldOffsets)[i] = 3;
431 fieldSet[i] = ergba;
432 break;
433 case 'q':
434 (*fieldOffsets)[i] = 3;
435 fieldSet[i] = estpq;
436 break;
437 default:
438 error(line, "illegal vector field selection", compString);
439 return false;
440 }
441 }
442
443 for (unsigned int i = 0u; i < fieldOffsets->size(); ++i)
444 {
445 if ((*fieldOffsets)[i] >= vecSize)
446 {
447 error(line, "vector field selection out of range", compString);
448 return false;
449 }
450
451 if (i > 0)
452 {
453 if (fieldSet[i] != fieldSet[i - 1])
454 {
455 error(line, "illegal - vector component fields not from the same set", compString);
456 return false;
457 }
458 }
459 }
460
461 return true;
462 }
463
464 ///////////////////////////////////////////////////////////////////////
465 //
466 // Errors
467 //
468 ////////////////////////////////////////////////////////////////////////
469
470 //
471 // Used by flex/bison to output all syntax and parsing errors.
472 //
error(const TSourceLoc & loc,const char * reason,const char * token)473 void TParseContext::error(const TSourceLoc &loc, const char *reason, const char *token)
474 {
475 mDiagnostics->error(loc, reason, token);
476 }
477
error(const TSourceLoc & loc,const char * reason,const ImmutableString & token)478 void TParseContext::error(const TSourceLoc &loc, const char *reason, const ImmutableString &token)
479 {
480 mDiagnostics->error(loc, reason, token.data());
481 }
482
warning(const TSourceLoc & loc,const char * reason,const char * token)483 void TParseContext::warning(const TSourceLoc &loc, const char *reason, const char *token)
484 {
485 mDiagnostics->warning(loc, reason, token);
486 }
487
errorIfPLSDeclared(const TSourceLoc & loc,PLSIllegalOperations op)488 void TParseContext::errorIfPLSDeclared(const TSourceLoc &loc, PLSIllegalOperations op)
489 {
490 if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
491 {
492 return;
493 }
494 if (mPLSFormats.empty())
495 {
496 // No pixel local storage uniforms have been declared yet. Remember this potential error in
497 // case PLS gets declared later.
498 mPLSPotentialErrors.emplace_back(loc, op);
499 return;
500 }
501 switch (op)
502 {
503 case PLSIllegalOperations::Discard:
504 error(loc, "illegal discard when pixel local storage is declared", "discard");
505 break;
506 case PLSIllegalOperations::ReturnFromMain:
507 error(loc, "illegal return from main when pixel local storage is declared", "return");
508 break;
509 case PLSIllegalOperations::AssignFragDepth:
510 error(loc, "value not assignable when pixel local storage is declared", "gl_FragDepth");
511 break;
512 case PLSIllegalOperations::AssignSampleMask:
513 error(loc, "value not assignable when pixel local storage is declared",
514 "gl_SampleMask");
515 break;
516 case PLSIllegalOperations::FragDataIndexNonzero:
517 error(loc, "illegal nonzero index qualifier when pixel local storage is declared",
518 "layout");
519 break;
520 case PLSIllegalOperations::EnableAdvancedBlendEquation:
521 error(loc, "illegal advanced blend equation when pixel local storage is declared",
522 "layout");
523 break;
524 }
525 }
526
outOfRangeError(bool isError,const TSourceLoc & loc,const char * reason,const char * token)527 void TParseContext::outOfRangeError(bool isError,
528 const TSourceLoc &loc,
529 const char *reason,
530 const char *token)
531 {
532 if (isError)
533 {
534 error(loc, reason, token);
535 }
536 else
537 {
538 warning(loc, reason, token);
539 }
540 }
541
setTreeRoot(TIntermBlock * treeRoot)542 void TParseContext::setTreeRoot(TIntermBlock *treeRoot)
543 {
544 mTreeRoot = treeRoot;
545 mTreeRoot->setIsTreeRoot();
546 }
547
548 //
549 // Same error message for all places assignments don't work.
550 //
assignError(const TSourceLoc & line,const char * op,const TType & left,const TType & right)551 void TParseContext::assignError(const TSourceLoc &line,
552 const char *op,
553 const TType &left,
554 const TType &right)
555 {
556 TInfoSinkBase reasonStream;
557 reasonStream << "cannot convert from '" << right << "' to '" << left << "'";
558 error(line, reasonStream.c_str(), op);
559 }
560
561 //
562 // Same error message for all places unary operations don't work.
563 //
unaryOpError(const TSourceLoc & line,const char * op,const TType & operand)564 void TParseContext::unaryOpError(const TSourceLoc &line, const char *op, const TType &operand)
565 {
566 TInfoSinkBase reasonStream;
567 reasonStream << "wrong operand type - no operation '" << op
568 << "' exists that takes an operand of type " << operand
569 << " (or there is no acceptable conversion)";
570 error(line, reasonStream.c_str(), op);
571 }
572
573 //
574 // Same error message for all binary operations don't work.
575 //
binaryOpError(const TSourceLoc & line,const char * op,const TType & left,const TType & right)576 void TParseContext::binaryOpError(const TSourceLoc &line,
577 const char *op,
578 const TType &left,
579 const TType &right)
580 {
581 TInfoSinkBase reasonStream;
582 reasonStream << "wrong operand types - no operation '" << op
583 << "' exists that takes a left-hand operand of type '" << left
584 << "' and a right operand of type '" << right
585 << "' (or there is no acceptable conversion)";
586 error(line, reasonStream.c_str(), op);
587 }
588
checkPrecisionSpecified(const TSourceLoc & line,TPrecision precision,TBasicType type)589 void TParseContext::checkPrecisionSpecified(const TSourceLoc &line,
590 TPrecision precision,
591 TBasicType type)
592 {
593 if (precision != EbpUndefined && !SupportsPrecision(type))
594 {
595 error(line, "illegal type for precision qualifier", getBasicString(type));
596 }
597
598 if (precision == EbpUndefined)
599 {
600 switch (type)
601 {
602 case EbtFloat:
603 error(line, "No precision specified for (float)", "");
604 return;
605 case EbtInt:
606 case EbtUInt:
607 UNREACHABLE(); // there's always a predeclared qualifier
608 error(line, "No precision specified (int)", "");
609 return;
610 default:
611 if (IsOpaqueType(type))
612 {
613 error(line, "No precision specified", getBasicString(type));
614 return;
615 }
616 }
617 }
618 }
619
markStaticReadIfSymbol(TIntermNode * node)620 void TParseContext::markStaticReadIfSymbol(TIntermNode *node)
621 {
622 TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
623 if (swizzleNode)
624 {
625 markStaticReadIfSymbol(swizzleNode->getOperand());
626 return;
627 }
628 TIntermBinary *binaryNode = node->getAsBinaryNode();
629 if (binaryNode)
630 {
631 switch (binaryNode->getOp())
632 {
633 case EOpIndexDirect:
634 case EOpIndexIndirect:
635 case EOpIndexDirectStruct:
636 case EOpIndexDirectInterfaceBlock:
637 markStaticReadIfSymbol(binaryNode->getLeft());
638 return;
639 default:
640 return;
641 }
642 }
643 TIntermSymbol *symbolNode = node->getAsSymbolNode();
644 if (symbolNode)
645 {
646 symbolTable.markStaticRead(symbolNode->variable());
647 }
648 }
649
650 // Both test and if necessary, spit out an error, to see if the node is really
651 // an l-value that can be operated on this way.
checkCanBeLValue(const TSourceLoc & line,const char * op,TIntermTyped * node)652 bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIntermTyped *node)
653 {
654 TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
655 if (swizzleNode)
656 {
657 bool ok = checkCanBeLValue(line, op, swizzleNode->getOperand());
658 if (ok && swizzleNode->hasDuplicateOffsets())
659 {
660 error(line, " l-value of swizzle cannot have duplicate components", op);
661 return false;
662 }
663 return ok;
664 }
665
666 TIntermBinary *binaryNode = node->getAsBinaryNode();
667 if (binaryNode)
668 {
669 switch (binaryNode->getOp())
670 {
671 case EOpIndexDirect:
672 case EOpIndexIndirect:
673 case EOpIndexDirectStruct:
674 case EOpIndexDirectInterfaceBlock:
675 if (node->getMemoryQualifier().readonly)
676 {
677 error(line, "can't modify a readonly variable", op);
678 return false;
679 }
680 return checkCanBeLValue(line, op, binaryNode->getLeft());
681 default:
682 break;
683 }
684 error(line, " l-value required", op);
685 return false;
686 }
687
688 std::string message;
689 switch (node->getQualifier())
690 {
691 case EvqConst:
692 message = "can't modify a const";
693 break;
694 case EvqParamConst:
695 message = "can't modify a const";
696 break;
697 case EvqAttribute:
698 message = "can't modify an attribute";
699 break;
700 case EvqFragmentIn:
701 case EvqVertexIn:
702 case EvqGeometryIn:
703 case EvqTessControlIn:
704 case EvqTessEvaluationIn:
705 case EvqSmoothIn:
706 case EvqFlatIn:
707 case EvqNoPerspectiveIn:
708 case EvqCentroidIn:
709 case EvqSampleIn:
710 case EvqNoPerspectiveCentroidIn:
711 case EvqNoPerspectiveSampleIn:
712 message = "can't modify an input";
713 break;
714 case EvqUniform:
715 message = "can't modify a uniform";
716 break;
717 case EvqVaryingIn:
718 message = "can't modify a varying";
719 break;
720 case EvqFragCoord:
721 message = "can't modify gl_FragCoord";
722 break;
723 case EvqFrontFacing:
724 message = "can't modify gl_FrontFacing";
725 break;
726 case EvqHelperInvocation:
727 message = "can't modify gl_HelperInvocation";
728 break;
729 case EvqPointCoord:
730 message = "can't modify gl_PointCoord";
731 break;
732 case EvqNumWorkGroups:
733 message = "can't modify gl_NumWorkGroups";
734 break;
735 case EvqWorkGroupSize:
736 message = "can't modify gl_WorkGroupSize";
737 break;
738 case EvqWorkGroupID:
739 message = "can't modify gl_WorkGroupID";
740 break;
741 case EvqLocalInvocationID:
742 message = "can't modify gl_LocalInvocationID";
743 break;
744 case EvqGlobalInvocationID:
745 message = "can't modify gl_GlobalInvocationID";
746 break;
747 case EvqLocalInvocationIndex:
748 message = "can't modify gl_LocalInvocationIndex";
749 break;
750 case EvqViewIDOVR:
751 message = "can't modify gl_ViewID_OVR";
752 break;
753 case EvqComputeIn:
754 message = "can't modify work group size variable";
755 break;
756 case EvqPerVertexIn:
757 message = "can't modify any member in gl_in";
758 break;
759 case EvqPrimitiveIDIn:
760 message = "can't modify gl_PrimitiveIDIn";
761 break;
762 case EvqInvocationID:
763 message = "can't modify gl_InvocationID";
764 break;
765 case EvqPrimitiveID:
766 if (mShaderType == GL_FRAGMENT_SHADER)
767 {
768 message = "can't modify gl_PrimitiveID in a fragment shader";
769 }
770 break;
771 case EvqLayerIn:
772 message = "can't modify gl_Layer in a fragment shader";
773 break;
774 case EvqSampleID:
775 message = "can't modify gl_SampleID";
776 break;
777 case EvqSampleMaskIn:
778 message = "can't modify gl_SampleMaskIn";
779 break;
780 case EvqSamplePosition:
781 message = "can't modify gl_SamplePosition";
782 break;
783 case EvqClipDistance:
784 if (mShaderType == GL_FRAGMENT_SHADER)
785 {
786 message = "can't modify gl_ClipDistance in a fragment shader";
787 }
788 break;
789 case EvqCullDistance:
790 if (mShaderType == GL_FRAGMENT_SHADER)
791 {
792 message = "can't modify gl_CullDistance in a fragment shader";
793 }
794 break;
795 case EvqFragDepth:
796 errorIfPLSDeclared(line, PLSIllegalOperations::AssignFragDepth);
797 break;
798 case EvqSampleMask:
799 errorIfPLSDeclared(line, PLSIllegalOperations::AssignSampleMask);
800 break;
801 default:
802 //
803 // Type that can't be written to?
804 //
805 if (node->getBasicType() == EbtVoid)
806 {
807 message = "can't modify void";
808 }
809 if (IsOpaqueType(node->getBasicType()))
810 {
811 message = "can't modify a variable with type ";
812 message += getBasicString(node->getBasicType());
813 }
814 else if (node->getMemoryQualifier().readonly)
815 {
816 message = "can't modify a readonly variable";
817 }
818 }
819
820 ASSERT(binaryNode == nullptr && swizzleNode == nullptr);
821 TIntermSymbol *symNode = node->getAsSymbolNode();
822 if (message.empty() && symNode != nullptr)
823 {
824 symbolTable.markStaticWrite(symNode->variable());
825 return true;
826 }
827
828 std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
829 reasonStream << "l-value required";
830 if (!message.empty())
831 {
832 if (symNode)
833 {
834 // Symbol inside an expression can't be nameless.
835 ASSERT(symNode->variable().symbolType() != SymbolType::Empty);
836 const ImmutableString &symbol = symNode->getName();
837 reasonStream << " (" << message << " \"" << symbol << "\")";
838 }
839 else
840 {
841 reasonStream << " (" << message << ")";
842 }
843 }
844 std::string reason = reasonStream.str();
845 error(line, reason.c_str(), op);
846
847 return false;
848 }
849
850 // Both test, and if necessary spit out an error, to see if the node is really
851 // a constant.
checkIsConst(TIntermTyped * node)852 void TParseContext::checkIsConst(TIntermTyped *node)
853 {
854 if (node->getQualifier() != EvqConst)
855 {
856 error(node->getLine(), "constant expression required", "");
857 }
858 }
859
860 // Both test, and if necessary spit out an error, to see if the node is really
861 // an integer.
checkIsScalarInteger(TIntermTyped * node,const char * token)862 void TParseContext::checkIsScalarInteger(TIntermTyped *node, const char *token)
863 {
864 if (!node->isScalarInt())
865 {
866 error(node->getLine(), "integer expression required", token);
867 }
868 }
869
870 // Both test, and if necessary spit out an error, to see if we are currently
871 // globally scoped.
checkIsAtGlobalLevel(const TSourceLoc & line,const char * token)872 bool TParseContext::checkIsAtGlobalLevel(const TSourceLoc &line, const char *token)
873 {
874 if (!symbolTable.atGlobalLevel())
875 {
876 error(line, "only allowed at global scope", token);
877 return false;
878 }
879 return true;
880 }
881
checkIsValidExpressionStatement(const TSourceLoc & line,TIntermTyped * expr)882 void TParseContext::checkIsValidExpressionStatement(const TSourceLoc &line, TIntermTyped *expr)
883 {
884 if (expr->isInterfaceBlock())
885 {
886 error(line, "expression statement is not allowed for interface blocks", "");
887 }
888 }
889
890 // ESSL 3.00.5 sections 3.8 and 3.9.
891 // If it starts "gl_" or contains two consecutive underscores, it's reserved.
892 // Also checks for "webgl_" and "_webgl_" reserved identifiers if parsing a webgl shader.
checkIsNotReserved(const TSourceLoc & line,const ImmutableString & identifier)893 bool TParseContext::checkIsNotReserved(const TSourceLoc &line, const ImmutableString &identifier)
894 {
895 static const char *reservedErrMsg = "reserved built-in name";
896 if (gl::IsBuiltInName(identifier.data()))
897 {
898 error(line, reservedErrMsg, "gl_");
899 return false;
900 }
901 if (sh::IsWebGLBasedSpec(mShaderSpec))
902 {
903 if (identifier.beginsWith("webgl_"))
904 {
905 error(line, reservedErrMsg, "webgl_");
906 return false;
907 }
908 if (identifier.beginsWith("_webgl_"))
909 {
910 error(line, reservedErrMsg, "_webgl_");
911 return false;
912 }
913 }
914 if (identifier.contains("__"))
915 {
916 if (sh::IsWebGLBasedSpec(mShaderSpec))
917 {
918 error(line,
919 "identifiers containing two consecutive underscores (__) are reserved as "
920 "possible future keywords",
921 identifier);
922 return false;
923 }
924 else
925 {
926 // Using double underscores is allowed, but may result in unintended behaviors, so a
927 // warning is issued.
928 // OpenGL ES Shader Language 3.2 specification:
929 // > 3.7. Keywords
930 // > ...
931 // > In addition, all identifiers containing two consecutive underscores (__) are
932 // > reserved for use by underlying software layers. Defining such a name in a shader
933 // > does not itself result in an error, but may result in unintended behaviors that
934 // > stem from having multiple definitions of the same name.
935 warning(line,
936 "all identifiers containing two consecutive underscores (__) are reserved - "
937 "unintented behaviors are possible",
938 identifier.data());
939 }
940 }
941 return true;
942 }
943
944 // Make sure the argument types are correct for constructing a specific type.
checkConstructorArguments(const TSourceLoc & line,const TIntermSequence & arguments,const TType & type)945 bool TParseContext::checkConstructorArguments(const TSourceLoc &line,
946 const TIntermSequence &arguments,
947 const TType &type)
948 {
949 if (arguments.empty())
950 {
951 error(line, "constructor does not have any arguments", "constructor");
952 return false;
953 }
954
955 for (TIntermNode *arg : arguments)
956 {
957 markStaticReadIfSymbol(arg);
958 const TIntermTyped *argTyped = arg->getAsTyped();
959 ASSERT(argTyped != nullptr);
960 if (type.getBasicType() != EbtStruct && IsOpaqueType(argTyped->getBasicType()))
961 {
962 std::string reason("cannot convert a variable with type ");
963 reason += getBasicString(argTyped->getBasicType());
964 error(line, reason.c_str(), "constructor");
965 return false;
966 }
967 else if (argTyped->getMemoryQualifier().writeonly)
968 {
969 error(line, "cannot convert a variable with writeonly", "constructor");
970 return false;
971 }
972 if (argTyped->getBasicType() == EbtVoid)
973 {
974 error(line, "cannot convert a void", "constructor");
975 return false;
976 }
977 }
978
979 if (type.isArray())
980 {
981 // The size of an unsized constructor should already have been determined.
982 ASSERT(!type.isUnsizedArray());
983 if (static_cast<size_t>(type.getOutermostArraySize()) != arguments.size())
984 {
985 error(line, "array constructor needs one argument per array element", "constructor");
986 return false;
987 }
988 // GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of
989 // the array.
990 for (TIntermNode *const &argNode : arguments)
991 {
992 const TType &argType = argNode->getAsTyped()->getType();
993 if (mShaderVersion < 310 && argType.isArray())
994 {
995 error(line, "constructing from a non-dereferenced array", "constructor");
996 return false;
997 }
998 if (!argType.isElementTypeOf(type))
999 {
1000 error(line, "Array constructor argument has an incorrect type", "constructor");
1001 return false;
1002 }
1003 }
1004 }
1005 else if (type.getBasicType() == EbtStruct)
1006 {
1007 const TFieldList &fields = type.getStruct()->fields();
1008 if (fields.size() != arguments.size())
1009 {
1010 error(line,
1011 "Number of constructor parameters does not match the number of structure fields",
1012 "constructor");
1013 return false;
1014 }
1015
1016 for (size_t i = 0; i < fields.size(); i++)
1017 {
1018 if (i >= arguments.size() ||
1019 arguments[i]->getAsTyped()->getType() != *fields[i]->type())
1020 {
1021 error(line, "Structure constructor arguments do not match structure fields",
1022 "constructor");
1023 return false;
1024 }
1025 }
1026 }
1027 else
1028 {
1029 // We're constructing a scalar, vector, or matrix.
1030
1031 // Note: It's okay to have too many components available, but not okay to have unused
1032 // arguments. 'full' will go to true when enough args have been seen. If we loop again,
1033 // there is an extra argument, so 'overFull' will become true.
1034
1035 size_t size = 0;
1036 bool full = false;
1037 bool overFull = false;
1038 bool matrixArg = false;
1039 for (TIntermNode *arg : arguments)
1040 {
1041 const TIntermTyped *argTyped = arg->getAsTyped();
1042 ASSERT(argTyped != nullptr);
1043
1044 if (argTyped->getBasicType() == EbtStruct)
1045 {
1046 error(line, "a struct cannot be used as a constructor argument for this type",
1047 "constructor");
1048 return false;
1049 }
1050 if (argTyped->getBasicType() == EbtInterfaceBlock)
1051 {
1052 error(line,
1053 "an interface block cannot be used as a constructor argument for this type",
1054 "constructor");
1055 return false;
1056 }
1057 if (argTyped->getType().isArray())
1058 {
1059 error(line, "constructing from a non-dereferenced array", "constructor");
1060 return false;
1061 }
1062 if (argTyped->getType().isMatrix())
1063 {
1064 matrixArg = true;
1065 }
1066
1067 size += argTyped->getType().getObjectSize();
1068 if (full)
1069 {
1070 overFull = true;
1071 }
1072 if (size >= type.getObjectSize())
1073 {
1074 full = true;
1075 }
1076 }
1077
1078 if (type.isMatrix() && matrixArg)
1079 {
1080 if (arguments.size() != 1)
1081 {
1082 error(line, "constructing matrix from matrix can only take one argument",
1083 "constructor");
1084 return false;
1085 }
1086 }
1087 else
1088 {
1089 if (size != 1 && size < type.getObjectSize())
1090 {
1091 error(line, "not enough data provided for construction", "constructor");
1092 return false;
1093 }
1094 if (overFull)
1095 {
1096 error(line, "too many arguments", "constructor");
1097 return false;
1098 }
1099 }
1100 }
1101
1102 return true;
1103 }
1104
1105 // This function checks to see if a void variable has been declared and raise an error message for
1106 // such a case
1107 //
1108 // returns true in case of an error
1109 //
checkIsNonVoid(const TSourceLoc & line,const ImmutableString & identifier,const TBasicType & type)1110 bool TParseContext::checkIsNonVoid(const TSourceLoc &line,
1111 const ImmutableString &identifier,
1112 const TBasicType &type)
1113 {
1114 if (type == EbtVoid)
1115 {
1116 error(line, "illegal use of type 'void'", identifier);
1117 return false;
1118 }
1119
1120 return true;
1121 }
1122
1123 // This function checks to see if the node (for the expression) contains a scalar boolean expression
1124 // or not.
checkIsScalarBool(const TSourceLoc & line,const TIntermTyped * type)1125 bool TParseContext::checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type)
1126 {
1127 if (type->getBasicType() != EbtBool || !type->isScalar())
1128 {
1129 error(line, "boolean expression expected", "");
1130 return false;
1131 }
1132 return true;
1133 }
1134
1135 // This function checks to see if the node (for the expression) contains a scalar boolean expression
1136 // or not.
checkIsScalarBool(const TSourceLoc & line,const TPublicType & pType)1137 void TParseContext::checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType)
1138 {
1139 if (pType.getBasicType() != EbtBool || pType.isAggregate())
1140 {
1141 error(line, "boolean expression expected", "");
1142 }
1143 }
1144
checkIsNotOpaqueType(const TSourceLoc & line,const TTypeSpecifierNonArray & pType,const char * reason)1145 bool TParseContext::checkIsNotOpaqueType(const TSourceLoc &line,
1146 const TTypeSpecifierNonArray &pType,
1147 const char *reason)
1148 {
1149 if (pType.type == EbtStruct)
1150 {
1151 if (ContainsOpaque<IsSamplerFunc>(pType.userDef))
1152 {
1153 std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
1154 reasonStream << reason << " (structure contains a sampler)";
1155 std::string reasonStr = reasonStream.str();
1156 error(line, reasonStr.c_str(), getBasicString(pType.type));
1157 return false;
1158 }
1159 // only samplers need to be checked from structs, since other opaque types can't be struct
1160 // members.
1161 return true;
1162 }
1163 else if (IsOpaqueType(pType.type))
1164 {
1165 error(line, reason, getBasicString(pType.type));
1166 return false;
1167 }
1168
1169 return true;
1170 }
1171
checkDeclaratorLocationIsNotSpecified(const TSourceLoc & line,const TPublicType & pType)1172 void TParseContext::checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line,
1173 const TPublicType &pType)
1174 {
1175 if (pType.layoutQualifier.location != -1)
1176 {
1177 error(line, "location must only be specified for a single input or output variable",
1178 "location");
1179 }
1180 }
1181
checkLocationIsNotSpecified(const TSourceLoc & location,const TLayoutQualifier & layoutQualifier)1182 void TParseContext::checkLocationIsNotSpecified(const TSourceLoc &location,
1183 const TLayoutQualifier &layoutQualifier)
1184 {
1185 if (layoutQualifier.location != -1)
1186 {
1187 const char *errorMsg = "invalid layout qualifier: only valid on program inputs and outputs";
1188 if (mShaderVersion >= 310)
1189 {
1190 errorMsg =
1191 "invalid layout qualifier: only valid on shader inputs, outputs, and uniforms";
1192 }
1193 error(location, errorMsg, "location");
1194 }
1195 }
1196
checkStd430IsForShaderStorageBlock(const TSourceLoc & location,const TLayoutBlockStorage & blockStorage,const TQualifier & qualifier)1197 void TParseContext::checkStd430IsForShaderStorageBlock(const TSourceLoc &location,
1198 const TLayoutBlockStorage &blockStorage,
1199 const TQualifier &qualifier)
1200 {
1201 if (blockStorage == EbsStd430 && qualifier != EvqBuffer)
1202 {
1203 error(location, "The std430 layout is supported only for shader storage blocks.", "std430");
1204 }
1205 }
1206
1207 // Do size checking for an array type's size.
checkIsValidArraySize(const TSourceLoc & line,TIntermTyped * expr)1208 unsigned int TParseContext::checkIsValidArraySize(const TSourceLoc &line, TIntermTyped *expr)
1209 {
1210 TIntermConstantUnion *constant = expr->getAsConstantUnion();
1211
1212 // ANGLE should be able to fold any EvqConst expressions resulting in an integer - but to be
1213 // safe against corner cases we still check for constant folding. Some interpretations of the
1214 // spec have allowed constant expressions with side effects - like array length() method on a
1215 // non-constant array.
1216 if (expr->getQualifier() != EvqConst || constant == nullptr || !constant->isScalarInt())
1217 {
1218 error(line, "array size must be a constant integer expression", "");
1219 return 1u;
1220 }
1221
1222 unsigned int size = 0u;
1223
1224 if (constant->getBasicType() == EbtUInt)
1225 {
1226 size = constant->getUConst(0);
1227 }
1228 else
1229 {
1230 int signedSize = constant->getIConst(0);
1231
1232 if (signedSize < 0)
1233 {
1234 error(line, "array size must be non-negative", "");
1235 return 1u;
1236 }
1237
1238 size = static_cast<unsigned int>(signedSize);
1239 }
1240
1241 if (size == 0u)
1242 {
1243 error(line, "array size must be greater than zero", "");
1244 return 1u;
1245 }
1246
1247 if (IsOutputHLSL(getOutputType()))
1248 {
1249 // The size of arrays is restricted here to prevent issues further down the
1250 // compiler/translator/driver stack. Shader Model 5 generation hardware is limited to
1251 // 4096 registers so this should be reasonable even for aggressively optimizable code.
1252 const unsigned int sizeLimit = 65536;
1253
1254 if (size > sizeLimit)
1255 {
1256 error(line, "array size too large", "");
1257 return 1u;
1258 }
1259 }
1260
1261 return size;
1262 }
1263
checkIsValidArrayDimension(const TSourceLoc & line,TVector<unsigned int> * arraySizes)1264 bool TParseContext::checkIsValidArrayDimension(const TSourceLoc &line,
1265 TVector<unsigned int> *arraySizes)
1266 {
1267 if (arraySizes->size() > mMaxExpressionComplexity)
1268 {
1269 error(line, "array has too many dimensions", "");
1270 return false;
1271 }
1272 return true;
1273 }
1274
1275 // See if this qualifier can be an array.
checkIsValidQualifierForArray(const TSourceLoc & line,const TPublicType & elementQualifier)1276 bool TParseContext::checkIsValidQualifierForArray(const TSourceLoc &line,
1277 const TPublicType &elementQualifier)
1278 {
1279 if ((elementQualifier.qualifier == EvqAttribute) ||
1280 (elementQualifier.qualifier == EvqVertexIn) ||
1281 (elementQualifier.qualifier == EvqConst && mShaderVersion < 300))
1282 {
1283 error(line, "cannot declare arrays of this qualifier",
1284 TType(elementQualifier).getQualifierString());
1285 return false;
1286 }
1287
1288 return true;
1289 }
1290
1291 // See if this element type can be formed into an array.
checkArrayElementIsNotArray(const TSourceLoc & line,const TPublicType & elementType)1292 bool TParseContext::checkArrayElementIsNotArray(const TSourceLoc &line,
1293 const TPublicType &elementType)
1294 {
1295 if (mShaderVersion < 310 && elementType.isArray())
1296 {
1297 TInfoSinkBase typeString;
1298 typeString << TType(elementType);
1299 error(line, "cannot declare arrays of arrays", typeString.c_str());
1300 return false;
1301 }
1302 return true;
1303 }
1304
1305 // Check for array-of-arrays being used as non-allowed shader inputs/outputs.
checkArrayOfArraysInOut(const TSourceLoc & line,const TPublicType & elementType,const TType & arrayType)1306 bool TParseContext::checkArrayOfArraysInOut(const TSourceLoc &line,
1307 const TPublicType &elementType,
1308 const TType &arrayType)
1309 {
1310 if (arrayType.isArrayOfArrays())
1311 {
1312 if (elementType.qualifier == EvqVertexOut)
1313 {
1314 error(line, "vertex shader output cannot be an array of arrays",
1315 TType(elementType).getQualifierString());
1316 return false;
1317 }
1318 if (elementType.qualifier == EvqFragmentIn)
1319 {
1320 error(line, "fragment shader input cannot be an array of arrays",
1321 TType(elementType).getQualifierString());
1322 return false;
1323 }
1324 if (elementType.qualifier == EvqFragmentOut || elementType.qualifier == EvqFragmentInOut)
1325 {
1326 error(line, "fragment shader output cannot be an array of arrays",
1327 TType(elementType).getQualifierString());
1328 return false;
1329 }
1330 }
1331 return true;
1332 }
1333
1334 // Check if this qualified element type can be formed into an array. This is only called when array
1335 // brackets are associated with an identifier in a declaration, like this:
1336 // float a[2];
1337 // Similar checks are done in addFullySpecifiedType for array declarations where the array brackets
1338 // are associated with the type, like this:
1339 // float[2] a;
checkIsValidTypeAndQualifierForArray(const TSourceLoc & indexLocation,const TPublicType & elementType)1340 bool TParseContext::checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation,
1341 const TPublicType &elementType)
1342 {
1343 if (!checkArrayElementIsNotArray(indexLocation, elementType))
1344 {
1345 return false;
1346 }
1347 // In ESSL1.00 shaders, structs cannot be varying (section 4.3.5). This is checked elsewhere.
1348 // In ESSL3.00 shaders, struct inputs/outputs are allowed but not arrays of structs (section
1349 // 4.3.4).
1350 // Geometry shader requires each user-defined input be declared as arrays or inside input
1351 // blocks declared as arrays (GL_EXT_geometry_shader section 11.1gs.4.3). For the purposes of
1352 // interface matching, such variables and blocks are treated as though they were not declared
1353 // as arrays (GL_EXT_geometry_shader section 7.4.1).
1354 if (mShaderVersion >= 300 && elementType.getBasicType() == EbtStruct &&
1355 sh::IsVarying(elementType.qualifier) &&
1356 !IsGeometryShaderInput(mShaderType, elementType.qualifier) &&
1357 !IsTessellationControlShaderInput(mShaderType, elementType.qualifier) &&
1358 !IsTessellationEvaluationShaderInput(mShaderType, elementType.qualifier) &&
1359 !IsTessellationControlShaderOutput(mShaderType, elementType.qualifier))
1360 {
1361 TInfoSinkBase typeString;
1362 typeString << TType(elementType);
1363 error(indexLocation, "cannot declare arrays of structs of this qualifier",
1364 typeString.c_str());
1365 return false;
1366 }
1367 return checkIsValidQualifierForArray(indexLocation, elementType);
1368 }
1369
checkNestingLevel(const TSourceLoc & line)1370 void TParseContext::checkNestingLevel(const TSourceLoc &line)
1371 {
1372 if (static_cast<size_t>(mLoopNestingLevel + mSwitchNestingLevel) > mMaxStatementDepth)
1373 {
1374 error(line, "statement is too deeply nested", "");
1375 }
1376 }
1377
1378 // Enforce non-initializer type/qualifier rules.
checkCanBeDeclaredWithoutInitializer(const TSourceLoc & line,const ImmutableString & identifier,TType * type)1379 void TParseContext::checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
1380 const ImmutableString &identifier,
1381 TType *type)
1382 {
1383 ASSERT(type != nullptr);
1384 if (type->getQualifier() == EvqConst)
1385 {
1386 // Make the qualifier make sense.
1387 type->setQualifier(EvqTemporary);
1388
1389 // Generate informative error messages for ESSL1.
1390 // In ESSL3 arrays and structures containing arrays can be constant.
1391 if (mShaderVersion < 300 && type->isStructureContainingArrays())
1392 {
1393 error(line,
1394 "structures containing arrays may not be declared constant since they cannot be "
1395 "initialized",
1396 identifier);
1397 }
1398 else
1399 {
1400 error(line, "variables with qualifier 'const' must be initialized", identifier);
1401 }
1402 }
1403 }
1404
checkDeclarationIsValidArraySize(const TSourceLoc & line,const ImmutableString & identifier,TType * type)1405 void TParseContext::checkDeclarationIsValidArraySize(const TSourceLoc &line,
1406 const ImmutableString &identifier,
1407 TType *type)
1408 {
1409
1410 // Implicitly declared arrays are only allowed with tessellation or geometry shader inputs
1411 if (type->isUnsizedArray() &&
1412 ((mShaderType != GL_TESS_CONTROL_SHADER && mShaderType != GL_TESS_EVALUATION_SHADER &&
1413 mShaderType != GL_GEOMETRY_SHADER) ||
1414 (mShaderType == GL_GEOMETRY_SHADER && type->getQualifier() == EvqGeometryOut)))
1415 {
1416 error(line,
1417 "implicitly sized arrays only allowed for tessellation shaders "
1418 "or geometry shader inputs",
1419 identifier);
1420 }
1421 }
1422
1423 // Do some simple checks that are shared between all variable declarations,
1424 // and update the symbol table.
1425 //
1426 // Returns true if declaring the variable succeeded.
1427 //
declareVariable(const TSourceLoc & line,const ImmutableString & identifier,const TType * type,TVariable ** variable)1428 bool TParseContext::declareVariable(const TSourceLoc &line,
1429 const ImmutableString &identifier,
1430 const TType *type,
1431 TVariable **variable)
1432 {
1433 ASSERT((*variable) == nullptr);
1434
1435 SymbolType symbolType = SymbolType::UserDefined;
1436 switch (type->getQualifier())
1437 {
1438 case EvqClipDistance:
1439 case EvqCullDistance:
1440 case EvqFragDepth:
1441 case EvqLastFragData:
1442 case EvqLastFragColor:
1443 case EvqLastFragDepth:
1444 case EvqLastFragStencil:
1445 symbolType = SymbolType::BuiltIn;
1446 break;
1447 default:
1448 break;
1449 }
1450
1451 (*variable) = new TVariable(&symbolTable, identifier, type, symbolType);
1452
1453 if (type->getQualifier() == EvqFragmentOut)
1454 {
1455 if (type->getLayoutQualifier().index != -1 && type->getLayoutQualifier().location == -1)
1456 {
1457 error(line,
1458 "If index layout qualifier is specified for a fragment output, location must "
1459 "also be specified.",
1460 "index");
1461 return false;
1462 }
1463 }
1464 else
1465 {
1466 checkIndexIsNotSpecified(line, type->getLayoutQualifier().index);
1467 }
1468
1469 if (!((identifier.beginsWith("gl_LastFragData") || type->getQualifier() == EvqFragmentInOut) &&
1470 (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch) ||
1471 isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent))))
1472 {
1473 checkNoncoherentIsNotSpecified(line, type->getLayoutQualifier().noncoherent);
1474 }
1475 else if (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent) &&
1476 !isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch))
1477 {
1478 checkNoncoherentIsSpecified(line, type->getLayoutQualifier().noncoherent);
1479 }
1480
1481 checkBindingIsValid(line, *type);
1482
1483 bool needsReservedCheck = true;
1484
1485 // gl_LastFragData may be redeclared with a new precision qualifier
1486 if (type->isArray() && identifier.beginsWith("gl_LastFragData"))
1487 {
1488 const TVariable *maxDrawBuffers = static_cast<const TVariable *>(
1489 symbolTable.findBuiltIn(ImmutableString("gl_MaxDrawBuffers"), mShaderVersion));
1490 if (type->isArrayOfArrays())
1491 {
1492 error(line, "redeclaration of gl_LastFragData as an array of arrays", identifier);
1493 return false;
1494 }
1495 else if (static_cast<int>(type->getOutermostArraySize()) ==
1496 maxDrawBuffers->getConstPointer()->getIConst())
1497 {
1498 if (const TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion))
1499 {
1500 needsReservedCheck = !checkCanUseOneOfExtensions(line, builtInSymbol->extensions());
1501 }
1502 }
1503 else
1504 {
1505 error(line, "redeclaration of gl_LastFragData with size != gl_MaxDrawBuffers",
1506 identifier);
1507 return false;
1508 }
1509 }
1510 else if (identifier.beginsWith("gl_LastFragColorARM") ||
1511 identifier.beginsWith("gl_LastFragDepthARM") ||
1512 identifier.beginsWith("gl_LastFragStencilARM"))
1513 {
1514 // gl_LastFrag{Color,Depth,Stencil}ARM may be redeclared with a new precision qualifier
1515 if (const TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion))
1516 {
1517 needsReservedCheck = !checkCanUseOneOfExtensions(line, builtInSymbol->extensions());
1518 }
1519 }
1520 else if (type->isArray() && identifier == "gl_ClipDistance")
1521 {
1522 // gl_ClipDistance can be redeclared with smaller size than gl_MaxClipDistances
1523 const TVariable *maxClipDistances = static_cast<const TVariable *>(
1524 symbolTable.findBuiltIn(ImmutableString("gl_MaxClipDistances"), mShaderVersion));
1525 if (!maxClipDistances)
1526 {
1527 // Unsupported extension
1528 needsReservedCheck = true;
1529 }
1530 else if (type->isArrayOfArrays())
1531 {
1532 error(line, "redeclaration of gl_ClipDistance as an array of arrays", identifier);
1533 return false;
1534 }
1535 else if (static_cast<int>(type->getOutermostArraySize()) <=
1536 maxClipDistances->getConstPointer()->getIConst())
1537 {
1538 const TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion);
1539 if (builtInSymbol)
1540 {
1541 needsReservedCheck = !checkCanUseOneOfExtensions(line, builtInSymbol->extensions());
1542 }
1543 }
1544 else
1545 {
1546 error(line, "redeclaration of gl_ClipDistance with size > gl_MaxClipDistances",
1547 identifier);
1548 return false;
1549 }
1550 }
1551 else if (type->isArray() && identifier == "gl_CullDistance")
1552 {
1553 // gl_CullDistance can be redeclared with smaller size than gl_MaxCullDistances
1554 const TVariable *maxCullDistances = static_cast<const TVariable *>(
1555 symbolTable.findBuiltIn(ImmutableString("gl_MaxCullDistances"), mShaderVersion));
1556 if (!maxCullDistances)
1557 {
1558 // Unsupported extension
1559 needsReservedCheck = true;
1560 }
1561 else if (type->isArrayOfArrays())
1562 {
1563 error(line, "redeclaration of gl_CullDistance as an array of arrays", identifier);
1564 return false;
1565 }
1566 else if (static_cast<int>(type->getOutermostArraySize()) <=
1567 maxCullDistances->getConstPointer()->getIConst())
1568 {
1569 if (const TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion))
1570 {
1571 needsReservedCheck = !checkCanUseOneOfExtensions(line, builtInSymbol->extensions());
1572 }
1573 }
1574 else
1575 {
1576 error(line, "redeclaration of gl_CullDistance with size > gl_MaxCullDistances",
1577 identifier);
1578 return false;
1579 }
1580 }
1581 else if (isExtensionEnabled(TExtension::EXT_conservative_depth) &&
1582 mShaderType == GL_FRAGMENT_SHADER && identifier == "gl_FragDepth")
1583 {
1584 if (type->getBasicType() != EbtFloat || type->getNominalSize() != 1 ||
1585 type->getSecondarySize() != 1 || type->isArray())
1586 {
1587 error(line, "gl_FragDepth can only be redeclared as float", identifier);
1588 return false;
1589 }
1590 needsReservedCheck = false;
1591 }
1592 else if (isExtensionEnabled(TExtension::EXT_separate_shader_objects) &&
1593 mShaderType == GL_VERTEX_SHADER)
1594 {
1595 bool isRedefiningPositionOrPointSize = false;
1596 if (identifier == "gl_Position")
1597 {
1598 if (type->getBasicType() != EbtFloat || type->getNominalSize() != 4 ||
1599 type->getSecondarySize() != 1 || type->isArray())
1600 {
1601 error(line, "gl_Position can only be redeclared as vec4", identifier);
1602 return false;
1603 }
1604 needsReservedCheck = false;
1605 mPositionRedeclaredForSeparateShaderObject = true;
1606 isRedefiningPositionOrPointSize = true;
1607 }
1608 else if (identifier == "gl_PointSize")
1609 {
1610 if (type->getBasicType() != EbtFloat || type->getNominalSize() != 1 ||
1611 type->getSecondarySize() != 1 || type->isArray())
1612 {
1613 error(line, "gl_PointSize can only be redeclared as float", identifier);
1614 return false;
1615 }
1616 needsReservedCheck = false;
1617 mPointSizeRedeclaredForSeparateShaderObject = true;
1618 isRedefiningPositionOrPointSize = true;
1619 }
1620 if (isRedefiningPositionOrPointSize && mPositionOrPointSizeUsedForSeparateShaderObject)
1621 {
1622 error(line,
1623 "When EXT_separate_shader_objects is enabled, both gl_Position and "
1624 "gl_PointSize must be redeclared before either is used",
1625 identifier);
1626 }
1627 }
1628
1629 if (needsReservedCheck && !checkIsNotReserved(line, identifier))
1630 return false;
1631
1632 if (!symbolTable.declare(*variable))
1633 {
1634 error(line, "redefinition", identifier);
1635 return false;
1636 }
1637
1638 if (!checkIsNonVoid(line, identifier, type->getBasicType()))
1639 return false;
1640
1641 return true;
1642 }
1643
parseParameterQualifier(const TSourceLoc & line,const TTypeQualifierBuilder & typeQualifierBuilder,TPublicType & type)1644 void TParseContext::parseParameterQualifier(const TSourceLoc &line,
1645 const TTypeQualifierBuilder &typeQualifierBuilder,
1646 TPublicType &type)
1647 {
1648 // The only parameter qualifiers a parameter can have are in, out, inout or const.
1649 TTypeQualifier typeQualifier =
1650 typeQualifierBuilder.getParameterTypeQualifier(type.getBasicType(), mDiagnostics);
1651
1652 if (typeQualifier.qualifier == EvqParamOut || typeQualifier.qualifier == EvqParamInOut)
1653 {
1654 if (IsOpaqueType(type.getBasicType()))
1655 {
1656 error(line, "opaque types cannot be output parameters", type.getBasicString());
1657 }
1658 }
1659
1660 if (!IsImage(type.getBasicType()))
1661 {
1662 checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, line);
1663 }
1664 else
1665 {
1666 type.setMemoryQualifier(typeQualifier.memoryQualifier);
1667 }
1668
1669 type.setQualifier(typeQualifier.qualifier);
1670
1671 if (typeQualifier.precision != EbpUndefined)
1672 {
1673 type.setPrecision(typeQualifier.precision);
1674 }
1675
1676 if (typeQualifier.precise)
1677 {
1678 type.setPrecise(true);
1679 }
1680 }
1681
1682 template <size_t size>
checkCanUseOneOfExtensions(const TSourceLoc & line,const std::array<TExtension,size> & extensions)1683 bool TParseContext::checkCanUseOneOfExtensions(const TSourceLoc &line,
1684 const std::array<TExtension, size> &extensions)
1685 {
1686 ASSERT(!extensions.empty());
1687 const TExtensionBehavior &extBehavior = extensionBehavior();
1688
1689 bool canUseWithWarning = false;
1690 bool canUseWithoutWarning = false;
1691
1692 const char *errorMsgString = "";
1693 TExtension errorMsgExtension = TExtension::UNDEFINED;
1694
1695 for (TExtension extension : extensions)
1696 {
1697 auto extIter = extBehavior.find(extension);
1698 if (canUseWithWarning)
1699 {
1700 // We already have an extension that we can use, but with a warning.
1701 // See if we can use the alternative extension without a warning.
1702 if (extIter == extBehavior.end())
1703 {
1704 continue;
1705 }
1706 if (extIter->second == EBhEnable || extIter->second == EBhRequire)
1707 {
1708 canUseWithoutWarning = true;
1709 break;
1710 }
1711 continue;
1712 }
1713 if (extension == TExtension::UNDEFINED)
1714 {
1715 continue;
1716 }
1717 else if (extIter == extBehavior.end())
1718 {
1719 errorMsgString = "extension is not supported";
1720 errorMsgExtension = extension;
1721 }
1722 else if (extIter->second == EBhUndefined || extIter->second == EBhDisable)
1723 {
1724 errorMsgString = "extension is disabled";
1725 errorMsgExtension = extension;
1726 }
1727 else if (extIter->second == EBhWarn)
1728 {
1729 errorMsgExtension = extension;
1730 canUseWithWarning = true;
1731 }
1732 else
1733 {
1734 ASSERT(extIter->second == EBhEnable || extIter->second == EBhRequire);
1735 canUseWithoutWarning = true;
1736 break;
1737 }
1738 }
1739
1740 if (canUseWithoutWarning)
1741 {
1742 return true;
1743 }
1744 if (canUseWithWarning)
1745 {
1746 warning(line, "extension is being used", GetExtensionNameString(errorMsgExtension));
1747 return true;
1748 }
1749 error(line, errorMsgString, GetExtensionNameString(errorMsgExtension));
1750 return false;
1751 }
1752
1753 template bool TParseContext::checkCanUseOneOfExtensions(
1754 const TSourceLoc &line,
1755 const std::array<TExtension, 1> &extensions);
1756 template bool TParseContext::checkCanUseOneOfExtensions(
1757 const TSourceLoc &line,
1758 const std::array<TExtension, 2> &extensions);
1759 template bool TParseContext::checkCanUseOneOfExtensions(
1760 const TSourceLoc &line,
1761 const std::array<TExtension, 3> &extensions);
1762
checkCanUseExtension(const TSourceLoc & line,TExtension extension)1763 bool TParseContext::checkCanUseExtension(const TSourceLoc &line, TExtension extension)
1764 {
1765 ASSERT(extension != TExtension::UNDEFINED);
1766 return checkCanUseOneOfExtensions(line, std::array<TExtension, 1u>{{extension}});
1767 }
1768
1769 // ESSL 3.00.6 section 4.8 Empty Declarations: "The combinations of qualifiers that cause
1770 // compile-time or link-time errors are the same whether or not the declaration is empty".
1771 // This function implements all the checks that are done on qualifiers regardless of if the
1772 // declaration is empty.
declarationQualifierErrorCheck(const sh::TQualifier qualifier,const sh::TLayoutQualifier & layoutQualifier,const TSourceLoc & location)1773 void TParseContext::declarationQualifierErrorCheck(const sh::TQualifier qualifier,
1774 const sh::TLayoutQualifier &layoutQualifier,
1775 const TSourceLoc &location)
1776 {
1777 if (qualifier == EvqShared && !layoutQualifier.isEmpty())
1778 {
1779 error(location, "Shared memory declarations cannot have layout specified", "layout");
1780 }
1781
1782 if (layoutQualifier.matrixPacking != EmpUnspecified)
1783 {
1784 error(location, "layout qualifier only valid for interface blocks",
1785 getMatrixPackingString(layoutQualifier.matrixPacking));
1786 return;
1787 }
1788
1789 if (layoutQualifier.blockStorage != EbsUnspecified)
1790 {
1791 error(location, "layout qualifier only valid for interface blocks",
1792 getBlockStorageString(layoutQualifier.blockStorage));
1793 return;
1794 }
1795
1796 if (qualifier != EvqFragDepth)
1797 {
1798 checkDepthIsNotSpecified(location, layoutQualifier.depth);
1799 }
1800
1801 if (qualifier == EvqFragmentOut)
1802 {
1803 if (layoutQualifier.location != -1 && layoutQualifier.yuv == true)
1804 {
1805 error(location, "invalid layout qualifier combination", "yuv");
1806 return;
1807 }
1808 }
1809 else
1810 {
1811 checkYuvIsNotSpecified(location, layoutQualifier.yuv);
1812 }
1813
1814 if (qualifier != EvqFragmentIn)
1815 {
1816 checkEarlyFragmentTestsIsNotSpecified(location, layoutQualifier.earlyFragmentTests);
1817 }
1818
1819 // If multiview extension is enabled, "in" qualifier is allowed in the vertex shader in previous
1820 // parsing steps. So it needs to be checked here.
1821 if (anyMultiviewExtensionAvailable() && mShaderVersion < 300 && qualifier == EvqVertexIn)
1822 {
1823 error(location, "storage qualifier supported in GLSL ES 3.00 and above only", "in");
1824 }
1825
1826 bool canHaveLocation = qualifier == EvqVertexIn || qualifier == EvqFragmentOut;
1827 if (mShaderVersion >= 300 &&
1828 (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch) ||
1829 isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent)))
1830 {
1831 // In the case of EXT_shader_framebuffer_fetch or EXT_shader_framebuffer_fetch_non_coherent
1832 // extension, the location of inout qualifier is used to set the input attachment index
1833 canHaveLocation = canHaveLocation || qualifier == EvqFragmentInOut;
1834 }
1835 if (mShaderVersion >= 310)
1836 {
1837 canHaveLocation = canHaveLocation || qualifier == EvqUniform || IsVarying(qualifier);
1838 // We're not checking whether the uniform location is in range here since that depends on
1839 // the type of the variable.
1840 // The type can only be fully determined for non-empty declarations.
1841 }
1842 if (!canHaveLocation)
1843 {
1844 checkLocationIsNotSpecified(location, layoutQualifier);
1845 }
1846 }
1847
atomicCounterQualifierErrorCheck(const TPublicType & publicType,const TSourceLoc & location)1848 void TParseContext::atomicCounterQualifierErrorCheck(const TPublicType &publicType,
1849 const TSourceLoc &location)
1850 {
1851 if (publicType.precision != EbpHigh)
1852 {
1853 error(location, "Can only be highp", "atomic counter");
1854 }
1855 // dEQP enforces compile error if location is specified. See uniform_location.test.
1856 if (publicType.layoutQualifier.location != -1)
1857 {
1858 error(location, "location must not be set for atomic_uint", "layout");
1859 }
1860 if (publicType.layoutQualifier.binding == -1)
1861 {
1862 error(location, "no binding specified", "atomic counter");
1863 }
1864 }
1865
emptyDeclarationErrorCheck(const TType & type,const TSourceLoc & location)1866 void TParseContext::emptyDeclarationErrorCheck(const TType &type, const TSourceLoc &location)
1867 {
1868 if (type.isUnsizedArray())
1869 {
1870 // ESSL3 spec section 4.1.9: Array declaration which leaves the size unspecified is an
1871 // error. It is assumed that this applies to empty declarations as well.
1872 error(location, "empty array declaration needs to specify a size", "");
1873 }
1874
1875 if (type.getQualifier() != EvqFragmentOut)
1876 {
1877 checkIndexIsNotSpecified(location, type.getLayoutQualifier().index);
1878 }
1879 }
1880
1881 // These checks are done for all declarations that are non-empty. They're done for non-empty
1882 // declarations starting a declarator list, and declarators that follow an empty declaration.
nonEmptyDeclarationErrorCheck(const TPublicType & publicType,const TSourceLoc & identifierLocation)1883 void TParseContext::nonEmptyDeclarationErrorCheck(const TPublicType &publicType,
1884 const TSourceLoc &identifierLocation)
1885 {
1886 switch (publicType.qualifier)
1887 {
1888 case EvqVaryingIn:
1889 case EvqVaryingOut:
1890 case EvqAttribute:
1891 case EvqVertexIn:
1892 case EvqFragmentOut:
1893 case EvqFragmentInOut:
1894 case EvqComputeIn:
1895 if (publicType.getBasicType() == EbtStruct)
1896 {
1897 error(identifierLocation, "cannot be used with a structure",
1898 getQualifierString(publicType.qualifier));
1899 return;
1900 }
1901 break;
1902 case EvqBuffer:
1903 if (publicType.getBasicType() != EbtInterfaceBlock)
1904 {
1905 error(identifierLocation,
1906 "cannot declare buffer variables at global scope(outside a block)",
1907 getQualifierString(publicType.qualifier));
1908 return;
1909 }
1910 break;
1911 default:
1912 break;
1913 }
1914 std::string reason(getBasicString(publicType.getBasicType()));
1915 reason += "s must be uniform";
1916 if (publicType.qualifier != EvqUniform &&
1917 !checkIsNotOpaqueType(identifierLocation, publicType.typeSpecifierNonArray, reason.c_str()))
1918 {
1919 return;
1920 }
1921
1922 if ((publicType.qualifier != EvqTemporary && publicType.qualifier != EvqGlobal &&
1923 publicType.qualifier != EvqConst) &&
1924 publicType.getBasicType() == EbtYuvCscStandardEXT)
1925 {
1926 error(identifierLocation, "cannot be used with a yuvCscStandardEXT",
1927 getQualifierString(publicType.qualifier));
1928 return;
1929 }
1930
1931 if (mShaderVersion >= 310 && publicType.qualifier == EvqUniform)
1932 {
1933 // Valid uniform declarations can't be unsized arrays since uniforms can't be initialized.
1934 // But invalid shaders may still reach here with an unsized array declaration.
1935 TType type(publicType);
1936 if (!type.isUnsizedArray())
1937 {
1938 checkUniformLocationInRange(identifierLocation, type.getLocationCount(),
1939 publicType.layoutQualifier);
1940 }
1941 }
1942
1943 if (mShaderVersion >= 300 && publicType.qualifier == EvqVertexIn)
1944 {
1945 // Valid vertex input declarations can't be unsized arrays since they can't be initialized.
1946 // But invalid shaders may still reach here with an unsized array declaration.
1947 TType type(publicType);
1948 if (!type.isUnsizedArray())
1949 {
1950 checkAttributeLocationInRange(identifierLocation, type.getLocationCount(),
1951 publicType.layoutQualifier);
1952 }
1953 }
1954
1955 // check for layout qualifier issues
1956 const TLayoutQualifier layoutQualifier = publicType.layoutQualifier;
1957
1958 if (IsImage(publicType.getBasicType()))
1959 {
1960
1961 switch (layoutQualifier.imageInternalFormat)
1962 {
1963 case EiifRGBA32F:
1964 case EiifRGBA16F:
1965 case EiifR32F:
1966 case EiifRGBA8:
1967 case EiifRGBA8_SNORM:
1968 if (!IsFloatImage(publicType.getBasicType()))
1969 {
1970 error(identifierLocation,
1971 "internal image format requires a floating image type",
1972 getBasicString(publicType.getBasicType()));
1973 return;
1974 }
1975 break;
1976 case EiifRGBA32I:
1977 case EiifRGBA16I:
1978 case EiifRGBA8I:
1979 case EiifR32I:
1980 if (!IsIntegerImage(publicType.getBasicType()))
1981 {
1982 error(identifierLocation,
1983 "internal image format requires an integer image type",
1984 getBasicString(publicType.getBasicType()));
1985 return;
1986 }
1987 break;
1988 case EiifRGBA32UI:
1989 case EiifRGBA16UI:
1990 case EiifRGBA8UI:
1991 case EiifR32UI:
1992 if (!IsUnsignedImage(publicType.getBasicType()))
1993 {
1994 error(identifierLocation,
1995 "internal image format requires an unsigned image type",
1996 getBasicString(publicType.getBasicType()));
1997 return;
1998 }
1999 break;
2000 case EiifUnspecified:
2001 error(identifierLocation, "layout qualifier", "No image internal format specified");
2002 return;
2003 default:
2004 error(identifierLocation, "layout qualifier", "unrecognized token");
2005 return;
2006 }
2007
2008 // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
2009 switch (layoutQualifier.imageInternalFormat)
2010 {
2011 case EiifR32F:
2012 case EiifR32I:
2013 case EiifR32UI:
2014 break;
2015 default:
2016 if (!publicType.memoryQualifier.readonly && !publicType.memoryQualifier.writeonly)
2017 {
2018 error(identifierLocation, "layout qualifier",
2019 "Except for images with the r32f, r32i and r32ui format qualifiers, "
2020 "image variables must be qualified readonly and/or writeonly");
2021 return;
2022 }
2023 break;
2024 }
2025 }
2026 else if (IsPixelLocal(publicType.getBasicType()))
2027 {
2028 if (getShaderType() != GL_FRAGMENT_SHADER)
2029 {
2030 error(identifierLocation,
2031 "undefined use of pixel local storage outside a fragment shader",
2032 getBasicString(publicType.getBasicType()));
2033 return;
2034 }
2035 switch (layoutQualifier.imageInternalFormat)
2036 {
2037 case EiifR32F:
2038 case EiifRGBA8:
2039 if (publicType.getBasicType() != EbtPixelLocalANGLE)
2040 {
2041 error(identifierLocation, "pixel local storage format requires pixelLocalANGLE",
2042 getImageInternalFormatString(layoutQualifier.imageInternalFormat));
2043 }
2044 break;
2045 case EiifRGBA8I:
2046 if (publicType.getBasicType() != EbtIPixelLocalANGLE)
2047 {
2048 error(identifierLocation,
2049 "pixel local storage format requires ipixelLocalANGLE",
2050 getImageInternalFormatString(layoutQualifier.imageInternalFormat));
2051 }
2052 break;
2053 case EiifR32UI:
2054 case EiifRGBA8UI:
2055 if (publicType.getBasicType() != EbtUPixelLocalANGLE)
2056 {
2057 error(identifierLocation,
2058 "pixel local storage format requires upixelLocalANGLE",
2059 getImageInternalFormatString(layoutQualifier.imageInternalFormat));
2060 }
2061 break;
2062 case EiifR32I:
2063 case EiifRGBA8_SNORM:
2064 case EiifRGBA16F:
2065 case EiifRGBA32F:
2066 case EiifRGBA16I:
2067 case EiifRGBA32I:
2068 case EiifRGBA16UI:
2069 case EiifRGBA32UI:
2070 default:
2071 ASSERT(!IsValidWithPixelLocalStorage(layoutQualifier.imageInternalFormat));
2072 error(identifierLocation, "illegal pixel local storage format",
2073 getImageInternalFormatString(layoutQualifier.imageInternalFormat));
2074 break;
2075 case EiifUnspecified:
2076 error(identifierLocation, "pixel local storage requires a format specifier",
2077 "layout qualifier");
2078 break;
2079 }
2080 checkMemoryQualifierIsNotSpecified(publicType.memoryQualifier, identifierLocation);
2081 checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
2082 }
2083 else
2084 {
2085 checkInternalFormatIsNotSpecified(identifierLocation, layoutQualifier.imageInternalFormat);
2086 checkMemoryQualifierIsNotSpecified(publicType.memoryQualifier, identifierLocation);
2087 }
2088
2089 if (IsAtomicCounter(publicType.getBasicType()))
2090 {
2091 atomicCounterQualifierErrorCheck(publicType, identifierLocation);
2092 }
2093 else
2094 {
2095 checkOffsetIsNotSpecified(identifierLocation, layoutQualifier.offset);
2096 }
2097 }
2098
checkBindingIsValid(const TSourceLoc & identifierLocation,const TType & type)2099 void TParseContext::checkBindingIsValid(const TSourceLoc &identifierLocation, const TType &type)
2100 {
2101 TLayoutQualifier layoutQualifier = type.getLayoutQualifier();
2102 // Note that the ESSL 3.10 section 4.4.5 is not particularly clear on how the binding qualifier
2103 // on arrays of arrays should be handled. We interpret the spec so that the binding value is
2104 // incremented for each element of the innermost nested arrays. This is in line with how arrays
2105 // of arrays of blocks are specified to behave in GLSL 4.50 and a conservative interpretation
2106 // when it comes to which shaders are accepted by the compiler.
2107 int arrayTotalElementCount = type.getArraySizeProduct();
2108 if (IsPixelLocal(type.getBasicType()))
2109 {
2110 checkPixelLocalStorageBindingIsValid(identifierLocation, type);
2111 }
2112 else if (mShaderVersion < 310)
2113 {
2114 checkBindingIsNotSpecified(identifierLocation, layoutQualifier.binding);
2115 }
2116 else if (IsImage(type.getBasicType()))
2117 {
2118 checkImageBindingIsValid(identifierLocation, layoutQualifier.binding,
2119 arrayTotalElementCount);
2120 }
2121 else if (IsSampler(type.getBasicType()))
2122 {
2123 checkSamplerBindingIsValid(identifierLocation, layoutQualifier.binding,
2124 arrayTotalElementCount);
2125 }
2126 else if (IsAtomicCounter(type.getBasicType()))
2127 {
2128 checkAtomicCounterBindingIsValid(identifierLocation, layoutQualifier.binding);
2129 }
2130 else
2131 {
2132 ASSERT(!IsOpaqueType(type.getBasicType()));
2133 checkBindingIsNotSpecified(identifierLocation, layoutQualifier.binding);
2134 }
2135 }
2136
checkCanUseLayoutQualifier(const TSourceLoc & location)2137 void TParseContext::checkCanUseLayoutQualifier(const TSourceLoc &location)
2138 {
2139 constexpr std::array<TExtension, 4u> extensions{
2140 {TExtension::EXT_shader_framebuffer_fetch,
2141 TExtension::EXT_shader_framebuffer_fetch_non_coherent,
2142 TExtension::KHR_blend_equation_advanced, TExtension::ANGLE_shader_pixel_local_storage}};
2143 if (getShaderVersion() < 300 && !checkCanUseOneOfExtensions(location, extensions))
2144 {
2145 error(location, "qualifier supported in GLSL ES 3.00 and above only", "layout");
2146 }
2147 }
2148
checkLayoutQualifierSupported(const TSourceLoc & location,const ImmutableString & layoutQualifierName,int versionRequired)2149 bool TParseContext::checkLayoutQualifierSupported(const TSourceLoc &location,
2150 const ImmutableString &layoutQualifierName,
2151 int versionRequired)
2152 {
2153
2154 if (mShaderVersion < versionRequired)
2155 {
2156 error(location, "invalid layout qualifier: not supported", layoutQualifierName);
2157 return false;
2158 }
2159 return true;
2160 }
2161
checkWorkGroupSizeIsNotSpecified(const TSourceLoc & location,const TLayoutQualifier & layoutQualifier)2162 bool TParseContext::checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
2163 const TLayoutQualifier &layoutQualifier)
2164 {
2165 const sh::WorkGroupSize &localSize = layoutQualifier.localSize;
2166 for (size_t i = 0u; i < localSize.size(); ++i)
2167 {
2168 if (localSize[i] != -1)
2169 {
2170 error(location,
2171 "invalid layout qualifier: only valid when used with 'in' in a compute shader "
2172 "global layout declaration",
2173 getWorkGroupSizeString(i));
2174 return false;
2175 }
2176 }
2177
2178 return true;
2179 }
2180
checkInternalFormatIsNotSpecified(const TSourceLoc & location,TLayoutImageInternalFormat internalFormat)2181 void TParseContext::checkInternalFormatIsNotSpecified(const TSourceLoc &location,
2182 TLayoutImageInternalFormat internalFormat)
2183 {
2184 if (internalFormat != EiifUnspecified)
2185 {
2186 if (mShaderVersion < 310)
2187 {
2188 if (IsValidWithPixelLocalStorage(internalFormat))
2189 {
2190 error(location,
2191 "invalid layout qualifier: not supported before GLSL ES 3.10, except pixel "
2192 "local storage",
2193 getImageInternalFormatString(internalFormat));
2194 }
2195 else
2196 {
2197 error(location, "invalid layout qualifier: not supported before GLSL ES 3.10",
2198 getImageInternalFormatString(internalFormat));
2199 }
2200 }
2201 else
2202 {
2203 if (IsValidWithPixelLocalStorage(internalFormat))
2204 {
2205 error(location,
2206 "invalid layout qualifier: only valid when used with images or pixel local "
2207 "storage ",
2208 getImageInternalFormatString(internalFormat));
2209 }
2210 else
2211 {
2212 error(location, "invalid layout qualifier: only valid when used with images",
2213 getImageInternalFormatString(internalFormat));
2214 }
2215 }
2216 }
2217 }
2218
checkIndexIsNotSpecified(const TSourceLoc & location,int index)2219 void TParseContext::checkIndexIsNotSpecified(const TSourceLoc &location, int index)
2220 {
2221 if (index != -1)
2222 {
2223 error(location,
2224 "invalid layout qualifier: only valid when used with a fragment shader output in "
2225 "ESSL version >= 3.00 and EXT_blend_func_extended is enabled",
2226 "index");
2227 }
2228 }
2229
checkBindingIsNotSpecified(const TSourceLoc & location,int binding)2230 void TParseContext::checkBindingIsNotSpecified(const TSourceLoc &location, int binding)
2231 {
2232 if (binding != -1)
2233 {
2234 if (mShaderVersion < 310)
2235 {
2236 error(location,
2237 "invalid layout qualifier: only valid when used with pixel local storage",
2238 "binding");
2239 }
2240 else
2241 {
2242 error(location,
2243 "invalid layout qualifier: only valid when used with opaque types or blocks",
2244 "binding");
2245 }
2246 }
2247 }
2248
checkOffsetIsNotSpecified(const TSourceLoc & location,int offset)2249 void TParseContext::checkOffsetIsNotSpecified(const TSourceLoc &location, int offset)
2250 {
2251 if (offset != -1)
2252 {
2253 error(location, "invalid layout qualifier: only valid when used with atomic counters",
2254 "offset");
2255 }
2256 }
2257
checkImageBindingIsValid(const TSourceLoc & location,int binding,int arrayTotalElementCount)2258 void TParseContext::checkImageBindingIsValid(const TSourceLoc &location,
2259 int binding,
2260 int arrayTotalElementCount)
2261 {
2262 // Expects arraySize to be 1 when setting binding for only a single variable.
2263 if (binding >= 0 && binding + arrayTotalElementCount > mMaxImageUnits)
2264 {
2265 error(location, "image binding greater than gl_MaxImageUnits", "binding");
2266 }
2267 }
2268
checkSamplerBindingIsValid(const TSourceLoc & location,int binding,int arrayTotalElementCount)2269 void TParseContext::checkSamplerBindingIsValid(const TSourceLoc &location,
2270 int binding,
2271 int arrayTotalElementCount)
2272 {
2273 // Expects arraySize to be 1 when setting binding for only a single variable.
2274 if (binding >= 0 && binding + arrayTotalElementCount > mMaxCombinedTextureImageUnits)
2275 {
2276 error(location, "sampler binding greater than maximum texture units", "binding");
2277 }
2278 }
2279
checkBlockBindingIsValid(const TSourceLoc & location,const TQualifier & qualifier,int binding,int arraySize)2280 void TParseContext::checkBlockBindingIsValid(const TSourceLoc &location,
2281 const TQualifier &qualifier,
2282 int binding,
2283 int arraySize)
2284 {
2285 int size = (arraySize == 0 ? 1 : arraySize);
2286 if (qualifier == EvqUniform)
2287 {
2288 if (binding + size > mMaxUniformBufferBindings)
2289 {
2290 error(location, "uniform block binding greater than MAX_UNIFORM_BUFFER_BINDINGS",
2291 "binding");
2292 }
2293 }
2294 else if (qualifier == EvqBuffer)
2295 {
2296 if (binding + size > mMaxShaderStorageBufferBindings)
2297 {
2298 error(location,
2299 "shader storage block binding greater than MAX_SHADER_STORAGE_BUFFER_BINDINGS",
2300 "binding");
2301 }
2302 }
2303 }
checkAtomicCounterBindingIsValid(const TSourceLoc & location,int binding)2304 void TParseContext::checkAtomicCounterBindingIsValid(const TSourceLoc &location, int binding)
2305 {
2306 if (binding >= mMaxAtomicCounterBindings)
2307 {
2308 error(location, "atomic counter binding greater than gl_MaxAtomicCounterBindings",
2309 "binding");
2310 }
2311 }
2312
checkPixelLocalStorageBindingIsValid(const TSourceLoc & location,const TType & type)2313 void TParseContext::checkPixelLocalStorageBindingIsValid(const TSourceLoc &location,
2314 const TType &type)
2315 {
2316 TLayoutQualifier layoutQualifier = type.getLayoutQualifier();
2317 if (type.isArray())
2318 {
2319 // PLS is not allowed in arrays.
2320 // TODO(anglebug.com/40096838): Consider allowing this once more backends are implemented.
2321 error(location, "pixel local storage handles cannot be aggregated in arrays", "array");
2322 }
2323 else if (layoutQualifier.binding < 0)
2324 {
2325 error(location, "pixel local storage requires a binding index", "layout qualifier");
2326 }
2327 // TODO(anglebug.com/40096838):
2328 else if (layoutQualifier.binding >= mMaxPixelLocalStoragePlanes)
2329 {
2330 error(location, "pixel local storage binding out of range", "layout qualifier");
2331 }
2332 else if (mPLSFormats.find(layoutQualifier.binding) != mPLSFormats.end())
2333 {
2334 error(location, "duplicate pixel local storage binding index",
2335 std::to_string(layoutQualifier.binding).c_str());
2336 }
2337 else
2338 {
2339 mPLSFormats[layoutQualifier.binding] =
2340 ImageFormatToPLSFormat(layoutQualifier.imageInternalFormat);
2341 // "mPLSFormats" is how we know whether any pixel local storage uniforms have been declared,
2342 // so flush the queue of potential errors once mPLSFormats isn't empty.
2343 if (!mPLSPotentialErrors.empty())
2344 {
2345 for (const auto &[loc, op] : mPLSPotentialErrors)
2346 {
2347 errorIfPLSDeclared(loc, op);
2348 }
2349 mPLSPotentialErrors.clear();
2350 }
2351 }
2352 }
2353
checkUniformLocationInRange(const TSourceLoc & location,int objectLocationCount,const TLayoutQualifier & layoutQualifier)2354 void TParseContext::checkUniformLocationInRange(const TSourceLoc &location,
2355 int objectLocationCount,
2356 const TLayoutQualifier &layoutQualifier)
2357 {
2358 int loc = layoutQualifier.location;
2359 if (loc >= 0) // Shader-specified location
2360 {
2361 if (loc >= mMaxUniformLocations || objectLocationCount > mMaxUniformLocations ||
2362 static_cast<unsigned int>(loc) + static_cast<unsigned int>(objectLocationCount) >
2363 static_cast<unsigned int>(mMaxUniformLocations))
2364 {
2365 error(location, "Uniform location out of range", "location");
2366 }
2367 }
2368 }
2369
checkAttributeLocationInRange(const TSourceLoc & location,int objectLocationCount,const TLayoutQualifier & layoutQualifier)2370 void TParseContext::checkAttributeLocationInRange(const TSourceLoc &location,
2371 int objectLocationCount,
2372 const TLayoutQualifier &layoutQualifier)
2373 {
2374 int loc = layoutQualifier.location;
2375 if (loc >= 0) // Shader-specified location
2376 {
2377 if (loc >= mMaxVertexAttribs || objectLocationCount > mMaxVertexAttribs ||
2378 static_cast<unsigned int>(loc) + static_cast<unsigned int>(objectLocationCount) >
2379 static_cast<unsigned int>(mMaxVertexAttribs))
2380 {
2381 error(location, "Attribute location out of range", "location");
2382 }
2383 }
2384 }
2385
checkDepthIsNotSpecified(const TSourceLoc & location,TLayoutDepth depth)2386 void TParseContext::checkDepthIsNotSpecified(const TSourceLoc &location, TLayoutDepth depth)
2387 {
2388 if (depth != EdUnspecified)
2389 {
2390 error(location, "invalid layout qualifier: only valid on gl_FragDepth",
2391 getDepthString(depth));
2392 }
2393 }
2394
checkYuvIsNotSpecified(const TSourceLoc & location,bool yuv)2395 void TParseContext::checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv)
2396 {
2397 if (yuv != false)
2398 {
2399 error(location, "invalid layout qualifier: only valid on program outputs", "yuv");
2400 }
2401 }
2402
checkEarlyFragmentTestsIsNotSpecified(const TSourceLoc & location,bool earlyFragmentTests)2403 void TParseContext::checkEarlyFragmentTestsIsNotSpecified(const TSourceLoc &location,
2404 bool earlyFragmentTests)
2405 {
2406 if (earlyFragmentTests != false)
2407 {
2408 error(location,
2409 "invalid layout qualifier: only valid when used with 'in' in a fragment shader",
2410 "early_fragment_tests");
2411 }
2412 }
2413
checkNoncoherentIsSpecified(const TSourceLoc & location,bool noncoherent)2414 void TParseContext::checkNoncoherentIsSpecified(const TSourceLoc &location, bool noncoherent)
2415 {
2416 if (noncoherent == false)
2417 {
2418 error(location,
2419 "'noncoherent' qualifier must be used when "
2420 "GL_EXT_shader_framebuffer_fetch_non_coherent extension is used",
2421 "noncoherent");
2422 }
2423 }
2424
checkNoncoherentIsNotSpecified(const TSourceLoc & location,bool noncoherent)2425 void TParseContext::checkNoncoherentIsNotSpecified(const TSourceLoc &location, bool noncoherent)
2426 {
2427 if (noncoherent != false)
2428 {
2429 error(location,
2430 "invalid layout qualifier: only valid when used with 'gl_LastFragData' or the "
2431 "variable decorated with 'inout' in a fragment shader",
2432 "noncoherent");
2433 }
2434 }
2435
checkTCSOutVarIndexIsValid(TIntermBinary * binaryExpression,const TSourceLoc & location)2436 void TParseContext::checkTCSOutVarIndexIsValid(TIntermBinary *binaryExpression,
2437 const TSourceLoc &location)
2438 {
2439 ASSERT(binaryExpression->getOp() == EOpIndexIndirect ||
2440 binaryExpression->getOp() == EOpIndexDirect);
2441 const TIntermSymbol *intermSymbol = binaryExpression->getRight()->getAsSymbolNode();
2442 if ((intermSymbol == nullptr) || (intermSymbol->getName() != "gl_InvocationID"))
2443 {
2444 error(location,
2445 "tessellation-control per-vertex output l-value must be indexed with "
2446 "gl_InvocationID",
2447 "[");
2448 }
2449 }
2450
functionCallRValueLValueErrorCheck(const TFunction * fnCandidate,TIntermAggregate * fnCall)2451 void TParseContext::functionCallRValueLValueErrorCheck(const TFunction *fnCandidate,
2452 TIntermAggregate *fnCall)
2453 {
2454 for (size_t i = 0; i < fnCandidate->getParamCount(); ++i)
2455 {
2456 TQualifier qual = fnCandidate->getParam(i)->getType().getQualifier();
2457 TIntermTyped *argument = (*(fnCall->getSequence()))[i]->getAsTyped();
2458 bool argumentIsRead = (IsQualifierUnspecified(qual) || qual == EvqParamIn ||
2459 qual == EvqParamInOut || qual == EvqParamConst);
2460 if (argumentIsRead)
2461 {
2462 markStaticReadIfSymbol(argument);
2463 if (!IsImage(argument->getBasicType()))
2464 {
2465 if (argument->getMemoryQualifier().writeonly)
2466 {
2467 error(argument->getLine(),
2468 "Writeonly value cannot be passed for 'in' or 'inout' parameters.",
2469 fnCall->functionName());
2470 return;
2471 }
2472 }
2473 }
2474 if (qual == EvqParamOut || qual == EvqParamInOut)
2475 {
2476 if (!checkCanBeLValue(argument->getLine(), "assign", argument))
2477 {
2478 error(argument->getLine(),
2479 "Constant value cannot be passed for 'out' or 'inout' parameters.",
2480 fnCall->functionName());
2481 return;
2482 }
2483 }
2484 }
2485 }
2486
checkInvariantVariableQualifier(bool invariant,const TQualifier qualifier,const TSourceLoc & invariantLocation)2487 void TParseContext::checkInvariantVariableQualifier(bool invariant,
2488 const TQualifier qualifier,
2489 const TSourceLoc &invariantLocation)
2490 {
2491 if (!invariant)
2492 return;
2493
2494 if (mShaderVersion < 300)
2495 {
2496 // input variables in the fragment shader can be also qualified as invariant
2497 if (!sh::CanBeInvariantESSL1(qualifier))
2498 {
2499 error(invariantLocation, "Cannot be qualified as invariant.", "invariant");
2500 }
2501 }
2502 else
2503 {
2504 if (!sh::CanBeInvariantESSL3OrGreater(qualifier))
2505 {
2506 error(invariantLocation, "Cannot be qualified as invariant.", "invariant");
2507 }
2508 }
2509 }
2510
checkAdvancedBlendEquationsNotSpecified(const TSourceLoc & location,const AdvancedBlendEquations & advancedBlendEquations,const TQualifier & qualifier)2511 void TParseContext::checkAdvancedBlendEquationsNotSpecified(
2512 const TSourceLoc &location,
2513 const AdvancedBlendEquations &advancedBlendEquations,
2514 const TQualifier &qualifier)
2515 {
2516 if (advancedBlendEquations.any() && qualifier != EvqFragmentOut)
2517 {
2518 error(location,
2519 "invalid layout qualifier: blending equation qualifiers are only permitted on the "
2520 "fragment 'out' qualifier ",
2521 "blend_support_qualifier");
2522 }
2523 }
2524
isExtensionEnabled(TExtension extension) const2525 bool TParseContext::isExtensionEnabled(TExtension extension) const
2526 {
2527 return IsExtensionEnabled(extensionBehavior(), extension);
2528 }
2529
handleExtensionDirective(const TSourceLoc & loc,const char * extName,const char * behavior)2530 void TParseContext::handleExtensionDirective(const TSourceLoc &loc,
2531 const char *extName,
2532 const char *behavior)
2533 {
2534 angle::pp::SourceLocation srcLoc;
2535 srcLoc.file = loc.first_file;
2536 srcLoc.line = loc.first_line;
2537 mDirectiveHandler.handleExtension(srcLoc, extName, behavior);
2538 }
2539
handlePragmaDirective(const TSourceLoc & loc,const char * name,const char * value,bool stdgl)2540 void TParseContext::handlePragmaDirective(const TSourceLoc &loc,
2541 const char *name,
2542 const char *value,
2543 bool stdgl)
2544 {
2545 angle::pp::SourceLocation srcLoc;
2546 srcLoc.file = loc.first_file;
2547 srcLoc.line = loc.first_line;
2548 mDirectiveHandler.handlePragma(srcLoc, name, value, stdgl);
2549 }
2550
getComputeShaderLocalSize() const2551 sh::WorkGroupSize TParseContext::getComputeShaderLocalSize() const
2552 {
2553 sh::WorkGroupSize result(-1);
2554 for (size_t i = 0u; i < result.size(); ++i)
2555 {
2556 if (mComputeShaderLocalSizeDeclared && mComputeShaderLocalSize[i] == -1)
2557 {
2558 result[i] = 1;
2559 }
2560 else
2561 {
2562 result[i] = mComputeShaderLocalSize[i];
2563 }
2564 }
2565 return result;
2566 }
2567
addScalarLiteral(const TConstantUnion * constantUnion,const TSourceLoc & line)2568 TIntermConstantUnion *TParseContext::addScalarLiteral(const TConstantUnion *constantUnion,
2569 const TSourceLoc &line)
2570 {
2571 TIntermConstantUnion *node = new TIntermConstantUnion(
2572 constantUnion, TType(constantUnion->getType(), EbpUndefined, EvqConst));
2573 node->setLine(line);
2574 return node;
2575 }
2576
2577 /////////////////////////////////////////////////////////////////////////////////
2578 //
2579 // Non-Errors.
2580 //
2581 /////////////////////////////////////////////////////////////////////////////////
2582
getNamedVariable(const TSourceLoc & location,const ImmutableString & name,const TSymbol * symbol)2583 const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location,
2584 const ImmutableString &name,
2585 const TSymbol *symbol)
2586 {
2587 if (!symbol)
2588 {
2589 error(location, "undeclared identifier", name);
2590 return nullptr;
2591 }
2592
2593 if (!symbol->isVariable())
2594 {
2595 error(location, "variable expected", name);
2596 return nullptr;
2597 }
2598
2599 const TVariable *variable = static_cast<const TVariable *>(symbol);
2600
2601 if (!variable->extensions().empty() && variable->extensions()[0] != TExtension::UNDEFINED)
2602 {
2603 checkCanUseOneOfExtensions(location, variable->extensions());
2604 }
2605
2606 // GLSL ES 3.1 Revision 4, 7.1.3 Compute Shader Special Variables
2607 if (getShaderType() == GL_COMPUTE_SHADER && !mComputeShaderLocalSizeDeclared &&
2608 variable->getType().getQualifier() == EvqWorkGroupSize)
2609 {
2610 error(location,
2611 "It is an error to use gl_WorkGroupSize before declaring the local group size",
2612 "gl_WorkGroupSize");
2613 }
2614
2615 // If EXT_shader_framebuffer_fetch_non_coherent is used, gl_LastFragData should be decorated
2616 // with 'layout(noncoherent)' EXT_shader_framebuffer_fetch_non_coherent spec: "Unless the
2617 // GL_EXT_shader_framebuffer_fetch extension has been enabled in addition, it's an error to use
2618 // gl_LastFragData if it hasn't been explicitly redeclared with layout(noncoherent)."
2619 if (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent) &&
2620 !isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch) &&
2621 variable->getType().getQualifier() == EvqLastFragData)
2622 {
2623 checkNoncoherentIsSpecified(location, variable->getType().getLayoutQualifier().noncoherent);
2624 }
2625
2626 // When EXT_separate_shader_objects is enabled, gl_Position and gl_PointSize must both be
2627 // redeclared before either is accessed:
2628 //
2629 // > The following vertex shader outputs may be redeclared at global scope to
2630 // > specify a built-in output interface, with or without special qualifiers:
2631 // >
2632 // > gl_Position
2633 // > gl_PointSize
2634 // >
2635 // > When compiling shaders using either of the above variables, both such
2636 // > variables must be redeclared prior to use. ((Note: This restriction
2637 // > applies only to shaders using version 300 that enable the
2638 // > EXT_separate_shader_objects extension; shaders not enabling the
2639 // > extension do not have this requirement.))
2640 //
2641 // However, there are dEQP tests that enable all extensions and don't actually redeclare these
2642 // variables. Per https://gitlab.khronos.org/opengl/API/-/issues/169, there are drivers that do
2643 // enforce this, but they fail linking instead of compilation.
2644 //
2645 // In ANGLE, we make sure that they are both redeclared before use if any is redeclared, but if
2646 // neither are redeclared, we don't fail compilation. Currently, linking also doesn't fail in
2647 // ANGLE (similarly to almost all other drivers).
2648 if (isExtensionEnabled(TExtension::EXT_separate_shader_objects) &&
2649 mShaderType == GL_VERTEX_SHADER)
2650 {
2651 if (variable->getType().getQualifier() == EvqPosition ||
2652 variable->getType().getQualifier() == EvqPointSize)
2653 {
2654 mPositionOrPointSizeUsedForSeparateShaderObject = true;
2655 const bool eitherIsRedeclared = mPositionRedeclaredForSeparateShaderObject ||
2656 mPointSizeRedeclaredForSeparateShaderObject;
2657 const bool bothAreRedeclared = mPositionRedeclaredForSeparateShaderObject &&
2658 mPointSizeRedeclaredForSeparateShaderObject;
2659
2660 if (eitherIsRedeclared && !bothAreRedeclared)
2661 {
2662 error(location,
2663 "When EXT_separate_shader_objects is enabled, both gl_Position and "
2664 "gl_PointSize must be redeclared before either is used",
2665 name);
2666 }
2667 }
2668 }
2669
2670 return variable;
2671 }
2672
parseVariableIdentifier(const TSourceLoc & location,const ImmutableString & name,const TSymbol * symbol)2673 TIntermTyped *TParseContext::parseVariableIdentifier(const TSourceLoc &location,
2674 const ImmutableString &name,
2675 const TSymbol *symbol)
2676 {
2677 const TVariable *variable = getNamedVariable(location, name, symbol);
2678
2679 if (!variable)
2680 {
2681 TIntermTyped *node = CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
2682 node->setLine(location);
2683 return node;
2684 }
2685
2686 const TType &variableType = variable->getType();
2687 TIntermTyped *node = nullptr;
2688
2689 if (variable->getConstPointer() && variableType.canReplaceWithConstantUnion())
2690 {
2691 const TConstantUnion *constArray = variable->getConstPointer();
2692 node = new TIntermConstantUnion(constArray, variableType);
2693 }
2694 else if (variableType.getQualifier() == EvqWorkGroupSize && mComputeShaderLocalSizeDeclared)
2695 {
2696 // gl_WorkGroupSize can be used to size arrays according to the ESSL 3.10.4 spec, so it
2697 // needs to be added to the AST as a constant and not as a symbol.
2698 sh::WorkGroupSize workGroupSize = getComputeShaderLocalSize();
2699 TConstantUnion *constArray = new TConstantUnion[3];
2700 for (size_t i = 0; i < 3; ++i)
2701 {
2702 constArray[i].setUConst(static_cast<unsigned int>(workGroupSize[i]));
2703 }
2704
2705 ASSERT(variableType.getBasicType() == EbtUInt);
2706 ASSERT(variableType.getObjectSize() == 3);
2707
2708 TType type(variableType);
2709 type.setQualifier(EvqConst);
2710 node = new TIntermConstantUnion(constArray, type);
2711 }
2712 else if ((mGeometryShaderInputPrimitiveType != EptUndefined) &&
2713 (variableType.getQualifier() == EvqPerVertexIn))
2714 {
2715 ASSERT(symbolTable.getGlInVariableWithArraySize() != nullptr);
2716 node = new TIntermSymbol(symbolTable.getGlInVariableWithArraySize());
2717 }
2718 else
2719 {
2720 // gl_LastFragDepthARM and gl_LastFragStencilARM cannot be accessed if early_fragment_tests
2721 // is specified.
2722 if ((variableType.getQualifier() == EvqLastFragDepth ||
2723 variableType.getQualifier() == EvqLastFragStencil) &&
2724 isEarlyFragmentTestsSpecified())
2725 {
2726 error(location,
2727 "gl_LastFragDepthARM and gl_LastFragStencilARM cannot be accessed because "
2728 "early_fragment_tests is specified",
2729 name);
2730 }
2731
2732 node = new TIntermSymbol(variable);
2733 }
2734 ASSERT(node != nullptr);
2735 node->setLine(location);
2736 return node;
2737 }
2738
adjustRedeclaredBuiltInType(const TSourceLoc & line,const ImmutableString & identifier,TType * type)2739 void TParseContext::adjustRedeclaredBuiltInType(const TSourceLoc &line,
2740 const ImmutableString &identifier,
2741 TType *type)
2742 {
2743 if (identifier == "gl_ClipDistance")
2744 {
2745 const TQualifier qualifier = type->getQualifier();
2746 if ((mShaderType == GL_VERTEX_SHADER &&
2747 !(qualifier == EvqVertexOut || qualifier == EvqVaryingOut)) ||
2748 (mShaderType == GL_FRAGMENT_SHADER && qualifier != EvqFragmentIn))
2749 {
2750 error(line, "invalid or missing storage qualifier", identifier);
2751 return;
2752 }
2753
2754 type->setQualifier(EvqClipDistance);
2755 }
2756 else if (identifier == "gl_CullDistance")
2757 {
2758 const TQualifier qualifier = type->getQualifier();
2759 if ((mShaderType == GL_VERTEX_SHADER && qualifier != EvqVertexOut) ||
2760 (mShaderType == GL_FRAGMENT_SHADER && qualifier != EvqFragmentIn))
2761 {
2762 error(line, "invalid or missing storage qualifier", identifier);
2763 return;
2764 }
2765
2766 type->setQualifier(EvqCullDistance);
2767 }
2768 else if (identifier == "gl_LastFragData")
2769 {
2770 type->setQualifier(EvqLastFragData);
2771 }
2772 else if (identifier == "gl_LastFragColorARM")
2773 {
2774 type->setQualifier(EvqLastFragColor);
2775 }
2776 else if (identifier == "gl_LastFragDepthARM")
2777 {
2778 type->setQualifier(EvqLastFragDepth);
2779 }
2780 else if (identifier == "gl_LastFragStencilARM")
2781 {
2782 type->setQualifier(EvqLastFragStencil);
2783 }
2784 else if (identifier == "gl_Position")
2785 {
2786 type->setQualifier(EvqPosition);
2787 }
2788 else if (identifier == "gl_PointSize")
2789 {
2790 type->setQualifier(EvqPointSize);
2791 }
2792 }
2793
2794 // Initializers show up in several places in the grammar. Have one set of
2795 // code to handle them here.
2796 //
2797 // Returns true on success.
executeInitializer(const TSourceLoc & line,const ImmutableString & identifier,TType * type,TIntermTyped * initializer,TIntermBinary ** initNode)2798 bool TParseContext::executeInitializer(const TSourceLoc &line,
2799 const ImmutableString &identifier,
2800 TType *type,
2801 TIntermTyped *initializer,
2802 TIntermBinary **initNode)
2803 {
2804 ASSERT(initNode != nullptr);
2805 ASSERT(*initNode == nullptr);
2806
2807 if (type->isUnsizedArray())
2808 {
2809 // In case initializer is not an array or type has more dimensions than initializer, this
2810 // will default to setting array sizes to 1. We have not checked yet whether the initializer
2811 // actually is an array or not. Having a non-array initializer for an unsized array will
2812 // result in an error later, so we don't generate an error message here.
2813 type->sizeUnsizedArrays(initializer->getType().getArraySizes());
2814 }
2815
2816 const TQualifier qualifier = type->getQualifier();
2817
2818 bool constError = false;
2819 if (qualifier == EvqConst)
2820 {
2821 if (EvqConst != initializer->getType().getQualifier())
2822 {
2823 TInfoSinkBase reasonStream;
2824 reasonStream << "assigning non-constant to '" << *type << "'";
2825 error(line, reasonStream.c_str(), "=");
2826
2827 // We're still going to declare the variable to avoid extra error messages.
2828 type->setQualifier(EvqTemporary);
2829 constError = true;
2830 }
2831 }
2832
2833 TVariable *variable = nullptr;
2834 if (!declareVariable(line, identifier, type, &variable))
2835 {
2836 return false;
2837 }
2838
2839 if (constError)
2840 {
2841 return false;
2842 }
2843
2844 bool nonConstGlobalInitializers =
2845 IsExtensionEnabled(mDirectiveHandler.extensionBehavior(),
2846 TExtension::EXT_shader_non_constant_global_initializers);
2847 bool globalInitWarning = false;
2848 if (symbolTable.atGlobalLevel() &&
2849 !ValidateGlobalInitializer(initializer, mShaderVersion, sh::IsWebGLBasedSpec(mShaderSpec),
2850 nonConstGlobalInitializers, &globalInitWarning))
2851 {
2852 // Error message does not completely match behavior with ESSL 1.00, but
2853 // we want to steer developers towards only using constant expressions.
2854 error(line, "global variable initializers must be constant expressions", "=");
2855 return false;
2856 }
2857 if (globalInitWarning)
2858 {
2859 warning(
2860 line,
2861 "global variable initializers should be constant expressions "
2862 "(uniforms and globals are allowed in global initializers for legacy compatibility)",
2863 "=");
2864 }
2865
2866 // identifier must be of type constant, a global, or a temporary
2867 if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst))
2868 {
2869 error(line, " cannot initialize this type of qualifier ",
2870 variable->getType().getQualifierString());
2871 return false;
2872 }
2873
2874 TIntermSymbol *intermSymbol = new TIntermSymbol(variable);
2875 intermSymbol->setLine(line);
2876
2877 if (!binaryOpCommonCheck(EOpInitialize, intermSymbol, initializer, line))
2878 {
2879 assignError(line, "=", variable->getType(), initializer->getType());
2880 return false;
2881 }
2882
2883 if (qualifier == EvqConst)
2884 {
2885 // Save the constant folded value to the variable if possible.
2886 const TConstantUnion *constArray = initializer->getConstantValue();
2887 if (constArray)
2888 {
2889 variable->shareConstPointer(constArray);
2890 if (initializer->getType().canReplaceWithConstantUnion())
2891 {
2892 ASSERT(*initNode == nullptr);
2893 return true;
2894 }
2895 }
2896 }
2897
2898 *initNode = new TIntermBinary(EOpInitialize, intermSymbol, initializer);
2899 markStaticReadIfSymbol(initializer);
2900 (*initNode)->setLine(line);
2901 return true;
2902 }
2903
addConditionInitializer(const TPublicType & pType,const ImmutableString & identifier,TIntermTyped * initializer,const TSourceLoc & loc)2904 TIntermNode *TParseContext::addConditionInitializer(const TPublicType &pType,
2905 const ImmutableString &identifier,
2906 TIntermTyped *initializer,
2907 const TSourceLoc &loc)
2908 {
2909 checkIsScalarBool(loc, pType);
2910 TIntermBinary *initNode = nullptr;
2911 TType *type = new TType(pType);
2912 if (executeInitializer(loc, identifier, type, initializer, &initNode))
2913 {
2914 // The initializer is valid. The init condition needs to have a node - either the
2915 // initializer node, or a constant node in case the initialized variable is const and won't
2916 // be recorded in the AST.
2917 if (initNode == nullptr)
2918 {
2919 return initializer;
2920 }
2921 else
2922 {
2923 TIntermDeclaration *declaration = new TIntermDeclaration();
2924 declaration->appendDeclarator(initNode);
2925 return declaration;
2926 }
2927 }
2928 return nullptr;
2929 }
2930
addLoop(TLoopType type,TIntermNode * init,TIntermNode * cond,TIntermTyped * expr,TIntermNode * body,const TSourceLoc & line)2931 TIntermNode *TParseContext::addLoop(TLoopType type,
2932 TIntermNode *init,
2933 TIntermNode *cond,
2934 TIntermTyped *expr,
2935 TIntermNode *body,
2936 const TSourceLoc &line)
2937 {
2938 TIntermNode *node = nullptr;
2939 TIntermTyped *typedCond = nullptr;
2940 if (cond)
2941 {
2942 markStaticReadIfSymbol(cond);
2943 typedCond = cond->getAsTyped();
2944 }
2945 if (expr)
2946 {
2947 markStaticReadIfSymbol(expr);
2948 }
2949 // In case the loop body was not parsed as a block and contains a statement that simply refers
2950 // to a variable, we need to mark it as statically used.
2951 if (body)
2952 {
2953 markStaticReadIfSymbol(body);
2954 }
2955 if (cond == nullptr || typedCond)
2956 {
2957 if (type == ELoopDoWhile && typedCond)
2958 {
2959 checkIsScalarBool(line, typedCond);
2960 }
2961 // In the case of other loops, it was checked before that the condition is a scalar boolean.
2962 ASSERT(mDiagnostics->numErrors() > 0 || typedCond == nullptr ||
2963 (typedCond->getBasicType() == EbtBool && !typedCond->isArray() &&
2964 !typedCond->isVector()));
2965
2966 node = new TIntermLoop(type, init, typedCond, expr, EnsureLoopBodyBlock(body));
2967 node->setLine(line);
2968 return node;
2969 }
2970
2971 ASSERT(type != ELoopDoWhile);
2972
2973 TIntermDeclaration *declaration = cond->getAsDeclarationNode();
2974 ASSERT(declaration);
2975 TIntermBinary *declarator = declaration->getSequence()->front()->getAsBinaryNode();
2976 ASSERT(declarator->getLeft()->getAsSymbolNode());
2977
2978 // The condition is a declaration. In the AST representation we don't support declarations as
2979 // loop conditions. Wrap the loop to a block that declares the condition variable and contains
2980 // the loop.
2981 TIntermBlock *block = new TIntermBlock();
2982
2983 TIntermDeclaration *declareCondition = new TIntermDeclaration();
2984 declareCondition->appendDeclarator(declarator->getLeft()->deepCopy());
2985 block->appendStatement(declareCondition);
2986
2987 TIntermBinary *conditionInit = new TIntermBinary(EOpAssign, declarator->getLeft()->deepCopy(),
2988 declarator->getRight()->deepCopy());
2989 TIntermLoop *loop = new TIntermLoop(type, init, conditionInit, expr, EnsureLoopBodyBlock(body));
2990 block->appendStatement(loop);
2991 loop->setLine(line);
2992 block->setLine(line);
2993 return block;
2994 }
2995
addIfElse(TIntermTyped * cond,TIntermNodePair code,const TSourceLoc & loc)2996 TIntermNode *TParseContext::addIfElse(TIntermTyped *cond,
2997 TIntermNodePair code,
2998 const TSourceLoc &loc)
2999 {
3000 bool isScalarBool = checkIsScalarBool(loc, cond);
3001 // In case the conditional statements were not parsed as blocks and contain a statement that
3002 // simply refers to a variable, we need to mark them as statically used.
3003 if (code.node1)
3004 {
3005 markStaticReadIfSymbol(code.node1);
3006 }
3007 if (code.node2)
3008 {
3009 markStaticReadIfSymbol(code.node2);
3010 }
3011
3012 // For compile time constant conditions, prune the code now.
3013 if (isScalarBool && cond->getAsConstantUnion())
3014 {
3015 if (cond->getAsConstantUnion()->getBConst(0) == true)
3016 {
3017 return EnsureBlock(code.node1);
3018 }
3019 else
3020 {
3021 return EnsureBlock(code.node2);
3022 }
3023 }
3024
3025 TIntermIfElse *node = new TIntermIfElse(cond, EnsureBlock(code.node1), EnsureBlock(code.node2));
3026 markStaticReadIfSymbol(cond);
3027 node->setLine(loc);
3028
3029 return node;
3030 }
3031
addFullySpecifiedType(TPublicType * typeSpecifier)3032 void TParseContext::addFullySpecifiedType(TPublicType *typeSpecifier)
3033 {
3034 checkPrecisionSpecified(typeSpecifier->getLine(), typeSpecifier->precision,
3035 typeSpecifier->getBasicType());
3036
3037 if (mShaderVersion < 300 && typeSpecifier->isArray())
3038 {
3039 error(typeSpecifier->getLine(), "not supported", "first-class array");
3040 typeSpecifier->clearArrayness();
3041 }
3042 }
3043
addFullySpecifiedType(const TTypeQualifierBuilder & typeQualifierBuilder,const TPublicType & typeSpecifier)3044 TPublicType TParseContext::addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
3045 const TPublicType &typeSpecifier)
3046 {
3047 TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
3048
3049 TPublicType returnType = typeSpecifier;
3050 returnType.qualifier = typeQualifier.qualifier;
3051 returnType.invariant = typeQualifier.invariant;
3052 returnType.precise = typeQualifier.precise;
3053 returnType.layoutQualifier = typeQualifier.layoutQualifier;
3054 returnType.memoryQualifier = typeQualifier.memoryQualifier;
3055 returnType.precision = typeSpecifier.precision;
3056
3057 if (typeQualifier.precision != EbpUndefined)
3058 {
3059 returnType.precision = typeQualifier.precision;
3060 }
3061
3062 checkPrecisionSpecified(typeSpecifier.getLine(), returnType.precision,
3063 typeSpecifier.getBasicType());
3064
3065 checkInvariantVariableQualifier(returnType.invariant, returnType.qualifier,
3066 typeSpecifier.getLine());
3067
3068 checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), returnType.layoutQualifier);
3069
3070 checkEarlyFragmentTestsIsNotSpecified(typeSpecifier.getLine(),
3071 returnType.layoutQualifier.earlyFragmentTests);
3072
3073 if (returnType.qualifier == EvqSampleIn || returnType.qualifier == EvqSampleOut ||
3074 returnType.qualifier == EvqNoPerspectiveSampleIn ||
3075 returnType.qualifier == EvqNoPerspectiveSampleOut)
3076 {
3077 mSampleQualifierSpecified = true;
3078 }
3079
3080 if (mShaderVersion < 300)
3081 {
3082 if (typeSpecifier.isArray())
3083 {
3084 error(typeSpecifier.getLine(), "not supported", "first-class array");
3085 returnType.clearArrayness();
3086 }
3087
3088 if (returnType.qualifier == EvqAttribute &&
3089 (typeSpecifier.getBasicType() == EbtBool || typeSpecifier.getBasicType() == EbtInt))
3090 {
3091 error(typeSpecifier.getLine(), "cannot be bool or int",
3092 getQualifierString(returnType.qualifier));
3093 }
3094
3095 if ((returnType.qualifier == EvqVaryingIn || returnType.qualifier == EvqVaryingOut) &&
3096 (typeSpecifier.getBasicType() == EbtBool || typeSpecifier.getBasicType() == EbtInt))
3097 {
3098 error(typeSpecifier.getLine(), "cannot be bool or int",
3099 getQualifierString(returnType.qualifier));
3100 }
3101 }
3102 else
3103 {
3104 if (!returnType.layoutQualifier.isEmpty())
3105 {
3106 checkIsAtGlobalLevel(typeSpecifier.getLine(), "layout");
3107 }
3108 if (sh::IsVarying(returnType.qualifier) || returnType.qualifier == EvqVertexIn ||
3109 returnType.qualifier == EvqFragmentOut || returnType.qualifier == EvqFragmentInOut)
3110 {
3111 checkInputOutputTypeIsValidES3(returnType.qualifier, typeSpecifier,
3112 typeSpecifier.getLine());
3113 }
3114 if (returnType.qualifier == EvqComputeIn)
3115 {
3116 error(typeSpecifier.getLine(), "'in' can be only used to specify the local group size",
3117 "in");
3118 }
3119 }
3120
3121 return returnType;
3122 }
3123
checkInputOutputTypeIsValidES3(const TQualifier qualifier,const TPublicType & type,const TSourceLoc & qualifierLocation)3124 void TParseContext::checkInputOutputTypeIsValidES3(const TQualifier qualifier,
3125 const TPublicType &type,
3126 const TSourceLoc &qualifierLocation)
3127 {
3128 // An input/output variable can never be bool or a sampler. Samplers are checked elsewhere.
3129 if (type.getBasicType() == EbtBool)
3130 {
3131 error(qualifierLocation, "cannot be bool", getQualifierString(qualifier));
3132 }
3133
3134 // Specific restrictions apply for vertex shader inputs and fragment shader outputs.
3135 switch (qualifier)
3136 {
3137 case EvqVertexIn:
3138 // ESSL 3.00 section 4.3.4
3139 if (type.isArray())
3140 {
3141 error(qualifierLocation, "cannot be array", getQualifierString(qualifier));
3142 }
3143 // Vertex inputs with a struct type are disallowed in nonEmptyDeclarationErrorCheck
3144 return;
3145 case EvqFragmentOut:
3146 case EvqFragmentInOut:
3147 // ESSL 3.00 section 4.3.6
3148 if (type.typeSpecifierNonArray.isMatrix())
3149 {
3150 error(qualifierLocation, "cannot be matrix", getQualifierString(qualifier));
3151 }
3152 // Fragment outputs with a struct type are disallowed in nonEmptyDeclarationErrorCheck
3153 return;
3154 default:
3155 break;
3156 }
3157
3158 // Vertex shader outputs / fragment shader inputs have a different, slightly more lenient set of
3159 // restrictions.
3160 bool typeContainsIntegers =
3161 (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt ||
3162 type.isStructureContainingType(EbtInt) || type.isStructureContainingType(EbtUInt));
3163 bool extendedShaderTypes = mShaderVersion >= 320 ||
3164 isExtensionEnabled(TExtension::EXT_geometry_shader) ||
3165 isExtensionEnabled(TExtension::OES_geometry_shader) ||
3166 isExtensionEnabled(TExtension::EXT_tessellation_shader) ||
3167 isExtensionEnabled(TExtension::OES_tessellation_shader);
3168 if (typeContainsIntegers && qualifier != EvqFlatIn && qualifier != EvqFlatOut &&
3169 (!extendedShaderTypes || mShaderType == GL_FRAGMENT_SHADER))
3170 {
3171 error(qualifierLocation, "must use 'flat' interpolation here",
3172 getQualifierString(qualifier));
3173 }
3174
3175 if (type.getBasicType() == EbtStruct)
3176 {
3177 // ESSL 3.00 sections 4.3.4 and 4.3.6.
3178 // These restrictions are only implied by the ESSL 3.00 spec, but
3179 // the ESSL 3.10 spec lists these restrictions explicitly.
3180 if (type.isArray())
3181 {
3182 error(qualifierLocation, "cannot be an array of structures",
3183 getQualifierString(qualifier));
3184 }
3185 if (type.isStructureContainingArrays())
3186 {
3187 error(qualifierLocation, "cannot be a structure containing an array",
3188 getQualifierString(qualifier));
3189 }
3190 if (type.isStructureContainingType(EbtStruct))
3191 {
3192 error(qualifierLocation, "cannot be a structure containing a structure",
3193 getQualifierString(qualifier));
3194 }
3195 if (type.isStructureContainingType(EbtBool))
3196 {
3197 error(qualifierLocation, "cannot be a structure containing a bool",
3198 getQualifierString(qualifier));
3199 }
3200 }
3201 }
3202
checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase & qualifier)3203 void TParseContext::checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier)
3204 {
3205 if (qualifier.getType() == QtStorage)
3206 {
3207 const TStorageQualifierWrapper &storageQualifier =
3208 static_cast<const TStorageQualifierWrapper &>(qualifier);
3209 if (!declaringFunction() && storageQualifier.getQualifier() != EvqConst &&
3210 !symbolTable.atGlobalLevel())
3211 {
3212 error(storageQualifier.getLine(),
3213 "Local variables can only use the const storage qualifier.",
3214 storageQualifier.getQualifierString());
3215 }
3216 }
3217 }
3218
checkMemoryQualifierIsNotSpecified(const TMemoryQualifier & memoryQualifier,const TSourceLoc & location)3219 void TParseContext::checkMemoryQualifierIsNotSpecified(const TMemoryQualifier &memoryQualifier,
3220 const TSourceLoc &location)
3221 {
3222 const std::string reason(
3223 "Only allowed with shader storage blocks, variables declared within shader storage blocks "
3224 "and variables declared as image types.");
3225 if (memoryQualifier.readonly)
3226 {
3227 error(location, reason.c_str(), "readonly");
3228 }
3229 if (memoryQualifier.writeonly)
3230 {
3231 error(location, reason.c_str(), "writeonly");
3232 }
3233 if (memoryQualifier.coherent)
3234 {
3235 error(location, reason.c_str(), "coherent");
3236 }
3237 if (memoryQualifier.restrictQualifier)
3238 {
3239 error(location, reason.c_str(), "restrict");
3240 }
3241 if (memoryQualifier.volatileQualifier)
3242 {
3243 error(location, reason.c_str(), "volatile");
3244 }
3245 }
3246
3247 // Make sure there is no offset overlapping, and store the newly assigned offset to "type" in
3248 // intermediate tree.
checkAtomicCounterOffsetDoesNotOverlap(bool forceAppend,const TSourceLoc & loc,TType * type)3249 void TParseContext::checkAtomicCounterOffsetDoesNotOverlap(bool forceAppend,
3250 const TSourceLoc &loc,
3251 TType *type)
3252 {
3253 const size_t size = type->isArray() ? kAtomicCounterArrayStride * type->getArraySizeProduct()
3254 : kAtomicCounterSize;
3255 TLayoutQualifier layoutQualifier = type->getLayoutQualifier();
3256 auto &bindingState = mAtomicCounterBindingStates[layoutQualifier.binding];
3257 int offset;
3258 if (layoutQualifier.offset == -1 || forceAppend)
3259 {
3260 offset = bindingState.appendSpan(size);
3261 }
3262 else
3263 {
3264 offset = bindingState.insertSpan(layoutQualifier.offset, size);
3265 }
3266 if (offset == -1)
3267 {
3268 error(loc, "Offset overlapping", "atomic counter");
3269 return;
3270 }
3271 layoutQualifier.offset = offset;
3272 type->setLayoutQualifier(layoutQualifier);
3273 }
3274
checkAtomicCounterOffsetAlignment(const TSourceLoc & location,const TType & type)3275 void TParseContext::checkAtomicCounterOffsetAlignment(const TSourceLoc &location, const TType &type)
3276 {
3277 TLayoutQualifier layoutQualifier = type.getLayoutQualifier();
3278
3279 // OpenGL ES 3.1 Table 6.5, Atomic counter offset must be a multiple of 4
3280 if (layoutQualifier.offset % 4 != 0)
3281 {
3282 error(location, "Offset must be multiple of 4", "atomic counter");
3283 }
3284 }
3285
checkAtomicCounterOffsetLimit(const TSourceLoc & location,const TType & type)3286 void TParseContext::checkAtomicCounterOffsetLimit(const TSourceLoc &location, const TType &type)
3287 {
3288 TLayoutQualifier layoutQualifier = type.getLayoutQualifier();
3289
3290 if (layoutQualifier.offset >= mMaxAtomicCounterBufferSize)
3291 {
3292 error(location, "Offset must not exceed the maximum atomic counter buffer size",
3293 "atomic counter");
3294 }
3295 }
3296
checkAtomicCounterOffsetIsValid(bool forceAppend,const TSourceLoc & loc,TType * type)3297 void TParseContext::checkAtomicCounterOffsetIsValid(bool forceAppend,
3298 const TSourceLoc &loc,
3299 TType *type)
3300 {
3301 checkAtomicCounterOffsetDoesNotOverlap(forceAppend, loc, type);
3302 checkAtomicCounterOffsetAlignment(loc, *type);
3303 checkAtomicCounterOffsetLimit(loc, *type);
3304 }
3305
checkGeometryShaderInputAndSetArraySize(const TSourceLoc & location,const ImmutableString & token,TType * type)3306 void TParseContext::checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location,
3307 const ImmutableString &token,
3308 TType *type)
3309 {
3310 if (IsGeometryShaderInput(mShaderType, type->getQualifier()))
3311 {
3312 if (type->isArray() && type->getOutermostArraySize() == 0u)
3313 {
3314 // Set size for the unsized geometry shader inputs if they are declared after a valid
3315 // input primitive declaration.
3316 if (mGeometryShaderInputPrimitiveType != EptUndefined)
3317 {
3318 ASSERT(symbolTable.getGlInVariableWithArraySize() != nullptr);
3319 type->sizeOutermostUnsizedArray(
3320 symbolTable.getGlInVariableWithArraySize()->getType().getOutermostArraySize());
3321 }
3322 else
3323 {
3324 // [GLSL ES 3.2 SPEC Chapter 4.4.1.2]
3325 // An input can be declared without an array size if there is a previous layout
3326 // which specifies the size.
3327 warning(location,
3328 "Missing a valid input primitive declaration before declaring an unsized "
3329 "array input",
3330 "Deferred");
3331 mDeferredArrayTypesToSize.push_back(type);
3332 }
3333 }
3334 else if (type->isArray())
3335 {
3336 setGeometryShaderInputArraySize(type->getOutermostArraySize(), location);
3337 }
3338 else
3339 {
3340 error(location, "Geometry shader input variable must be declared as an array", token);
3341 }
3342 }
3343 }
3344
checkTessellationShaderUnsizedArraysAndSetSize(const TSourceLoc & location,const ImmutableString & token,TType * type)3345 void TParseContext::checkTessellationShaderUnsizedArraysAndSetSize(const TSourceLoc &location,
3346 const ImmutableString &token,
3347 TType *type)
3348 {
3349 TQualifier qualifier = type->getQualifier();
3350 if (!IsTessellationControlShaderOutput(mShaderType, qualifier) &&
3351 !IsTessellationControlShaderInput(mShaderType, qualifier) &&
3352 !IsTessellationEvaluationShaderInput(mShaderType, qualifier))
3353 {
3354 return;
3355 }
3356
3357 // Such variables must be declared as arrays or inside output blocks declared as arrays.
3358 if (!type->isArray())
3359 {
3360 error(location, "Tessellation interface variables must be declared as an array", token);
3361 return;
3362 }
3363
3364 // If a size is specified, it must match the maximum patch size.
3365 unsigned int outermostSize = type->getOutermostArraySize();
3366 if (outermostSize == 0u)
3367 {
3368 switch (qualifier)
3369 {
3370 case EvqTessControlIn:
3371 case EvqTessEvaluationIn:
3372 case EvqSmoothIn:
3373 case EvqFlatIn:
3374 case EvqNoPerspectiveIn:
3375 case EvqCentroidIn:
3376 case EvqSampleIn:
3377 case EvqNoPerspectiveCentroidIn:
3378 case EvqNoPerspectiveSampleIn:
3379 // Declaring an array size is optional. If no size is specified, it will be taken
3380 // from the implementation-dependent maximum patch size (gl_MaxPatchVertices).
3381 ASSERT(mMaxPatchVertices > 0);
3382 type->sizeOutermostUnsizedArray(mMaxPatchVertices);
3383 break;
3384 case EvqTessControlOut:
3385 case EvqTessEvaluationOut:
3386 case EvqSmoothOut:
3387 case EvqFlatOut:
3388 case EvqNoPerspectiveOut:
3389 case EvqCentroidOut:
3390 case EvqSampleOut:
3391 case EvqNoPerspectiveCentroidOut:
3392 case EvqNoPerspectiveSampleOut:
3393 // Declaring an array size is optional. If no size is specified, it will be taken
3394 // from output patch size declared in the shader. If the patch size is not yet
3395 // declared, this is deferred until such time as it does.
3396 if (mTessControlShaderOutputVertices == 0)
3397 {
3398 mDeferredArrayTypesToSize.push_back(type);
3399 }
3400 else
3401 {
3402 type->sizeOutermostUnsizedArray(mTessControlShaderOutputVertices);
3403 }
3404 break;
3405 default:
3406 UNREACHABLE();
3407 break;
3408 }
3409 return;
3410 }
3411
3412 if (IsTessellationControlShaderInput(mShaderType, qualifier) ||
3413 IsTessellationEvaluationShaderInput(mShaderType, qualifier))
3414 {
3415 if (outermostSize != static_cast<unsigned int>(mMaxPatchVertices))
3416 {
3417 error(location,
3418 "If a size is specified for a tessellation control or evaluation user-defined "
3419 "input variable, it must match the maximum patch size (gl_MaxPatchVertices).",
3420 token);
3421 }
3422 }
3423 else if (IsTessellationControlShaderOutput(mShaderType, qualifier))
3424 {
3425 if (outermostSize != static_cast<unsigned int>(mTessControlShaderOutputVertices) &&
3426 mTessControlShaderOutputVertices != 0)
3427 {
3428 error(location,
3429 "If a size is specified for a tessellation control user-defined per-vertex "
3430 "output variable, it must match the the number of vertices in the output "
3431 "patch.",
3432 token);
3433 }
3434 }
3435 }
3436
parseSingleDeclaration(TPublicType & publicType,const TSourceLoc & identifierOrTypeLocation,const ImmutableString & identifier)3437 TIntermDeclaration *TParseContext::parseSingleDeclaration(
3438 TPublicType &publicType,
3439 const TSourceLoc &identifierOrTypeLocation,
3440 const ImmutableString &identifier)
3441 {
3442 TType *type = new TType(publicType);
3443 if (mCompileOptions.flattenPragmaSTDGLInvariantAll &&
3444 mDirectiveHandler.pragma().stdgl.invariantAll)
3445 {
3446 TQualifier qualifier = type->getQualifier();
3447
3448 // The directive handler has already taken care of rejecting invalid uses of this pragma
3449 // (for example, in ESSL 3.00 fragment shaders), so at this point, flatten it into all
3450 // affected variable declarations:
3451 //
3452 // 1. Built-in special variables which are inputs to the fragment shader. (These are handled
3453 // elsewhere, in TranslatorGLSL.)
3454 //
3455 // 2. Outputs from vertex shaders in ESSL 1.00 and 3.00 (EvqVaryingOut and EvqVertexOut). It
3456 // is actually less likely that there will be bugs in the handling of ESSL 3.00 shaders, but
3457 // the way this is currently implemented we have to enable this compiler option before
3458 // parsing the shader and determining the shading language version it uses. If this were
3459 // implemented as a post-pass, the workaround could be more targeted.
3460 if (qualifier == EvqVaryingOut || qualifier == EvqVertexOut)
3461 {
3462 type->setInvariant(true);
3463 }
3464 }
3465
3466 if (identifier == "gl_FragDepth")
3467 {
3468 if (type->getQualifier() == EvqFragmentOut)
3469 {
3470 type->setQualifier(EvqFragDepth);
3471 }
3472 else
3473 {
3474 error(identifierOrTypeLocation,
3475 "gl_FragDepth can only be redeclared as fragment output", identifier);
3476 }
3477 }
3478
3479 checkGeometryShaderInputAndSetArraySize(identifierOrTypeLocation, identifier, type);
3480 checkTessellationShaderUnsizedArraysAndSetSize(identifierOrTypeLocation, identifier, type);
3481
3482 declarationQualifierErrorCheck(type->getQualifier(), publicType.layoutQualifier,
3483 identifierOrTypeLocation);
3484
3485 bool emptyDeclaration = (identifier == "");
3486 mDeferredNonEmptyDeclarationErrorCheck = emptyDeclaration;
3487
3488 TIntermSymbol *symbol = nullptr;
3489 if (emptyDeclaration)
3490 {
3491 emptyDeclarationErrorCheck(*type, identifierOrTypeLocation);
3492 // In most cases we don't need to create a symbol node for an empty declaration.
3493 // But if the empty declaration is declaring a struct type, the symbol node will store that.
3494 if (type->getBasicType() == EbtStruct)
3495 {
3496 TVariable *emptyVariable =
3497 new TVariable(&symbolTable, kEmptyImmutableString, type, SymbolType::Empty);
3498 symbol = new TIntermSymbol(emptyVariable);
3499 }
3500 else if (IsAtomicCounter(publicType.getBasicType()))
3501 {
3502 setAtomicCounterBindingDefaultOffset(publicType, identifierOrTypeLocation);
3503 }
3504 }
3505 else
3506 {
3507 nonEmptyDeclarationErrorCheck(publicType, identifierOrTypeLocation);
3508
3509 checkCanBeDeclaredWithoutInitializer(identifierOrTypeLocation, identifier, type);
3510 checkDeclarationIsValidArraySize(identifierOrTypeLocation, identifier, type);
3511
3512 if (IsAtomicCounter(type->getBasicType()))
3513 {
3514 checkAtomicCounterOffsetIsValid(false, identifierOrTypeLocation, type);
3515 }
3516
3517 TVariable *variable = nullptr;
3518 if (declareVariable(identifierOrTypeLocation, identifier, type, &variable))
3519 {
3520 symbol = new TIntermSymbol(variable);
3521 }
3522 }
3523
3524 adjustRedeclaredBuiltInType(identifierOrTypeLocation, identifier, type);
3525
3526 TIntermDeclaration *declaration = new TIntermDeclaration();
3527 declaration->setLine(identifierOrTypeLocation);
3528 if (symbol)
3529 {
3530 symbol->setLine(identifierOrTypeLocation);
3531 declaration->appendDeclarator(symbol);
3532 }
3533 return declaration;
3534 }
3535
parseSingleArrayDeclaration(TPublicType & elementType,const TSourceLoc & identifierLocation,const ImmutableString & identifier,const TSourceLoc & indexLocation,const TVector<unsigned int> & arraySizes)3536 TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(
3537 TPublicType &elementType,
3538 const TSourceLoc &identifierLocation,
3539 const ImmutableString &identifier,
3540 const TSourceLoc &indexLocation,
3541 const TVector<unsigned int> &arraySizes)
3542 {
3543 mDeferredNonEmptyDeclarationErrorCheck = false;
3544
3545 declarationQualifierErrorCheck(elementType.qualifier, elementType.layoutQualifier,
3546 identifierLocation);
3547
3548 nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
3549
3550 checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
3551
3552 TType *arrayType = new TType(elementType);
3553 arrayType->makeArrays(arraySizes);
3554
3555 checkArrayOfArraysInOut(indexLocation, elementType, *arrayType);
3556
3557 checkGeometryShaderInputAndSetArraySize(indexLocation, identifier, arrayType);
3558 checkTessellationShaderUnsizedArraysAndSetSize(indexLocation, identifier, arrayType);
3559
3560 checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, arrayType);
3561 checkDeclarationIsValidArraySize(identifierLocation, identifier, arrayType);
3562
3563 if (IsAtomicCounter(arrayType->getBasicType()))
3564 {
3565 checkAtomicCounterOffsetIsValid(false, identifierLocation, arrayType);
3566 }
3567
3568 adjustRedeclaredBuiltInType(identifierLocation, identifier, arrayType);
3569
3570 TIntermDeclaration *declaration = new TIntermDeclaration();
3571 declaration->setLine(identifierLocation);
3572
3573 TVariable *variable = nullptr;
3574 if (declareVariable(identifierLocation, identifier, arrayType, &variable))
3575 {
3576 TIntermSymbol *symbol = new TIntermSymbol(variable);
3577 symbol->setLine(identifierLocation);
3578 declaration->appendDeclarator(symbol);
3579 }
3580
3581 return declaration;
3582 }
3583
parseSingleInitDeclaration(const TPublicType & publicType,const TSourceLoc & identifierLocation,const ImmutableString & identifier,const TSourceLoc & initLocation,TIntermTyped * initializer)3584 TIntermDeclaration *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType,
3585 const TSourceLoc &identifierLocation,
3586 const ImmutableString &identifier,
3587 const TSourceLoc &initLocation,
3588 TIntermTyped *initializer)
3589 {
3590 mDeferredNonEmptyDeclarationErrorCheck = false;
3591
3592 declarationQualifierErrorCheck(publicType.qualifier, publicType.layoutQualifier,
3593 identifierLocation);
3594
3595 nonEmptyDeclarationErrorCheck(publicType, identifierLocation);
3596
3597 TIntermDeclaration *declaration = new TIntermDeclaration();
3598 declaration->setLine(identifierLocation);
3599
3600 TIntermBinary *initNode = nullptr;
3601 TType *type = new TType(publicType);
3602 if (executeInitializer(identifierLocation, identifier, type, initializer, &initNode))
3603 {
3604 if (initNode)
3605 {
3606 declaration->appendDeclarator(initNode);
3607 }
3608 else if (publicType.isStructSpecifier())
3609 {
3610 // The initialization got constant folded. If it's a struct, declare the struct anyway.
3611 TVariable *emptyVariable =
3612 new TVariable(&symbolTable, kEmptyImmutableString, type, SymbolType::Empty);
3613 TIntermSymbol *symbol = new TIntermSymbol(emptyVariable);
3614 symbol->setLine(publicType.getLine());
3615 declaration->appendDeclarator(symbol);
3616 }
3617 }
3618 return declaration;
3619 }
3620
parseSingleArrayInitDeclaration(TPublicType & elementType,const TSourceLoc & identifierLocation,const ImmutableString & identifier,const TSourceLoc & indexLocation,const TVector<unsigned int> & arraySizes,const TSourceLoc & initLocation,TIntermTyped * initializer)3621 TIntermDeclaration *TParseContext::parseSingleArrayInitDeclaration(
3622 TPublicType &elementType,
3623 const TSourceLoc &identifierLocation,
3624 const ImmutableString &identifier,
3625 const TSourceLoc &indexLocation,
3626 const TVector<unsigned int> &arraySizes,
3627 const TSourceLoc &initLocation,
3628 TIntermTyped *initializer)
3629 {
3630 mDeferredNonEmptyDeclarationErrorCheck = false;
3631
3632 declarationQualifierErrorCheck(elementType.qualifier, elementType.layoutQualifier,
3633 identifierLocation);
3634
3635 nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
3636
3637 checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
3638
3639 TType *arrayType = new TType(elementType);
3640 arrayType->makeArrays(arraySizes);
3641
3642 TIntermDeclaration *declaration = new TIntermDeclaration();
3643 declaration->setLine(identifierLocation);
3644
3645 // initNode will correspond to the whole of "type b[n] = initializer".
3646 TIntermBinary *initNode = nullptr;
3647 if (executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
3648 {
3649 if (initNode)
3650 {
3651 declaration->appendDeclarator(initNode);
3652 }
3653 }
3654
3655 return declaration;
3656 }
3657
parseGlobalQualifierDeclaration(const TTypeQualifierBuilder & typeQualifierBuilder,const TSourceLoc & identifierLoc,const ImmutableString & identifier,const TSymbol * symbol)3658 TIntermGlobalQualifierDeclaration *TParseContext::parseGlobalQualifierDeclaration(
3659 const TTypeQualifierBuilder &typeQualifierBuilder,
3660 const TSourceLoc &identifierLoc,
3661 const ImmutableString &identifier,
3662 const TSymbol *symbol)
3663 {
3664 TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
3665
3666 if (!typeQualifier.invariant && !typeQualifier.precise)
3667 {
3668 error(identifierLoc, "Expected invariant or precise", identifier);
3669 return nullptr;
3670 }
3671 if (typeQualifier.invariant && !checkIsAtGlobalLevel(identifierLoc, "invariant varying"))
3672 {
3673 return nullptr;
3674 }
3675 if (!symbol)
3676 {
3677 error(identifierLoc, "undeclared identifier declared as invariant or precise", identifier);
3678 return nullptr;
3679 }
3680 if (!IsQualifierUnspecified(typeQualifier.qualifier))
3681 {
3682 error(identifierLoc, "invariant or precise declaration specifies qualifier",
3683 getQualifierString(typeQualifier.qualifier));
3684 }
3685 if (typeQualifier.precision != EbpUndefined)
3686 {
3687 error(identifierLoc, "invariant or precise declaration specifies precision",
3688 getPrecisionString(typeQualifier.precision));
3689 }
3690 if (!typeQualifier.layoutQualifier.isEmpty())
3691 {
3692 error(identifierLoc, "invariant or precise declaration specifies layout", "'layout'");
3693 }
3694
3695 const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
3696 if (!variable)
3697 {
3698 return nullptr;
3699 }
3700 const TType &type = variable->getType();
3701
3702 checkInvariantVariableQualifier(typeQualifier.invariant, type.getQualifier(),
3703 typeQualifier.line);
3704 checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
3705
3706 if (typeQualifier.invariant)
3707 {
3708 symbolTable.addInvariantVarying(*variable);
3709 }
3710
3711 TIntermSymbol *intermSymbol = new TIntermSymbol(variable);
3712 intermSymbol->setLine(identifierLoc);
3713
3714 return new TIntermGlobalQualifierDeclaration(intermSymbol, typeQualifier.precise,
3715 identifierLoc);
3716 }
3717
parseDeclarator(TPublicType & publicType,const TSourceLoc & identifierLocation,const ImmutableString & identifier,TIntermDeclaration * declarationOut)3718 void TParseContext::parseDeclarator(TPublicType &publicType,
3719 const TSourceLoc &identifierLocation,
3720 const ImmutableString &identifier,
3721 TIntermDeclaration *declarationOut)
3722 {
3723 // If the declaration starting this declarator list was empty (example: int,), some checks were
3724 // not performed.
3725 if (mDeferredNonEmptyDeclarationErrorCheck)
3726 {
3727 nonEmptyDeclarationErrorCheck(publicType, identifierLocation);
3728 mDeferredNonEmptyDeclarationErrorCheck = false;
3729 }
3730
3731 checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
3732
3733 TType *type = new TType(publicType);
3734
3735 checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier, type);
3736 checkTessellationShaderUnsizedArraysAndSetSize(identifierLocation, identifier, type);
3737
3738 checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, type);
3739 checkDeclarationIsValidArraySize(identifierLocation, identifier, type);
3740
3741 if (IsAtomicCounter(type->getBasicType()))
3742 {
3743 checkAtomicCounterOffsetIsValid(true, identifierLocation, type);
3744 }
3745
3746 adjustRedeclaredBuiltInType(identifierLocation, identifier, type);
3747
3748 TVariable *variable = nullptr;
3749 if (declareVariable(identifierLocation, identifier, type, &variable))
3750 {
3751 TIntermSymbol *symbol = new TIntermSymbol(variable);
3752 symbol->setLine(identifierLocation);
3753 declarationOut->appendDeclarator(symbol);
3754 }
3755 }
3756
parseArrayDeclarator(TPublicType & elementType,const TSourceLoc & identifierLocation,const ImmutableString & identifier,const TSourceLoc & arrayLocation,const TVector<unsigned int> & arraySizes,TIntermDeclaration * declarationOut)3757 void TParseContext::parseArrayDeclarator(TPublicType &elementType,
3758 const TSourceLoc &identifierLocation,
3759 const ImmutableString &identifier,
3760 const TSourceLoc &arrayLocation,
3761 const TVector<unsigned int> &arraySizes,
3762 TIntermDeclaration *declarationOut)
3763 {
3764 // If the declaration starting this declarator list was empty (example: int,), some checks were
3765 // not performed.
3766 if (mDeferredNonEmptyDeclarationErrorCheck)
3767 {
3768 nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
3769 mDeferredNonEmptyDeclarationErrorCheck = false;
3770 }
3771
3772 checkDeclaratorLocationIsNotSpecified(identifierLocation, elementType);
3773
3774 if (checkIsValidTypeAndQualifierForArray(arrayLocation, elementType))
3775 {
3776 TType *arrayType = new TType(elementType);
3777 arrayType->makeArrays(arraySizes);
3778
3779 checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier, arrayType);
3780 checkTessellationShaderUnsizedArraysAndSetSize(identifierLocation, identifier, arrayType);
3781
3782 checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, arrayType);
3783 checkDeclarationIsValidArraySize(identifierLocation, identifier, arrayType);
3784
3785 if (IsAtomicCounter(arrayType->getBasicType()))
3786 {
3787 checkAtomicCounterOffsetDoesNotOverlap(true, identifierLocation, arrayType);
3788
3789 checkAtomicCounterOffsetAlignment(identifierLocation, *arrayType);
3790 }
3791
3792 adjustRedeclaredBuiltInType(identifierLocation, identifier, arrayType);
3793
3794 TVariable *variable = nullptr;
3795 if (declareVariable(identifierLocation, identifier, arrayType, &variable))
3796 {
3797 TIntermSymbol *symbol = new TIntermSymbol(variable);
3798 symbol->setLine(identifierLocation);
3799 declarationOut->appendDeclarator(symbol);
3800 }
3801 }
3802 }
3803
parseInitDeclarator(const TPublicType & publicType,const TSourceLoc & identifierLocation,const ImmutableString & identifier,const TSourceLoc & initLocation,TIntermTyped * initializer,TIntermDeclaration * declarationOut)3804 void TParseContext::parseInitDeclarator(const TPublicType &publicType,
3805 const TSourceLoc &identifierLocation,
3806 const ImmutableString &identifier,
3807 const TSourceLoc &initLocation,
3808 TIntermTyped *initializer,
3809 TIntermDeclaration *declarationOut)
3810 {
3811 // If the declaration starting this declarator list was empty (example: int,), some checks were
3812 // not performed.
3813 if (mDeferredNonEmptyDeclarationErrorCheck)
3814 {
3815 nonEmptyDeclarationErrorCheck(publicType, identifierLocation);
3816 mDeferredNonEmptyDeclarationErrorCheck = false;
3817 }
3818
3819 checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
3820
3821 TIntermBinary *initNode = nullptr;
3822 TType *type = new TType(publicType);
3823 if (executeInitializer(identifierLocation, identifier, type, initializer, &initNode))
3824 {
3825 //
3826 // build the intermediate representation
3827 //
3828 if (initNode)
3829 {
3830 declarationOut->appendDeclarator(initNode);
3831 }
3832 }
3833 }
3834
parseArrayInitDeclarator(const TPublicType & elementType,const TSourceLoc & identifierLocation,const ImmutableString & identifier,const TSourceLoc & indexLocation,const TVector<unsigned int> & arraySizes,const TSourceLoc & initLocation,TIntermTyped * initializer,TIntermDeclaration * declarationOut)3835 void TParseContext::parseArrayInitDeclarator(const TPublicType &elementType,
3836 const TSourceLoc &identifierLocation,
3837 const ImmutableString &identifier,
3838 const TSourceLoc &indexLocation,
3839 const TVector<unsigned int> &arraySizes,
3840 const TSourceLoc &initLocation,
3841 TIntermTyped *initializer,
3842 TIntermDeclaration *declarationOut)
3843 {
3844 // If the declaration starting this declarator list was empty (example: int,), some checks were
3845 // not performed.
3846 if (mDeferredNonEmptyDeclarationErrorCheck)
3847 {
3848 nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
3849 mDeferredNonEmptyDeclarationErrorCheck = false;
3850 }
3851
3852 checkDeclaratorLocationIsNotSpecified(identifierLocation, elementType);
3853
3854 checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
3855
3856 TType *arrayType = new TType(elementType);
3857 arrayType->makeArrays(arraySizes);
3858
3859 // initNode will correspond to the whole of "b[n] = initializer".
3860 TIntermBinary *initNode = nullptr;
3861 if (executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
3862 {
3863 if (initNode)
3864 {
3865 declarationOut->appendDeclarator(initNode);
3866 }
3867 }
3868 }
3869
addEmptyStatement(const TSourceLoc & location)3870 TIntermNode *TParseContext::addEmptyStatement(const TSourceLoc &location)
3871 {
3872 // It's simpler to parse an empty statement as a constant expression rather than having a
3873 // different type of node just for empty statements, that will be pruned from the AST anyway.
3874 TIntermNode *node = CreateZeroNode(TType(EbtInt, EbpMedium));
3875 node->setLine(location);
3876 return node;
3877 }
3878
setAtomicCounterBindingDefaultOffset(const TPublicType & publicType,const TSourceLoc & location)3879 void TParseContext::setAtomicCounterBindingDefaultOffset(const TPublicType &publicType,
3880 const TSourceLoc &location)
3881 {
3882 const TLayoutQualifier &layoutQualifier = publicType.layoutQualifier;
3883 checkAtomicCounterBindingIsValid(location, layoutQualifier.binding);
3884 if (layoutQualifier.binding == -1 || layoutQualifier.offset == -1)
3885 {
3886 error(location, "Requires both binding and offset", "layout");
3887 return;
3888 }
3889 mAtomicCounterBindingStates[layoutQualifier.binding].setDefaultOffset(layoutQualifier.offset);
3890 }
3891
parseDefaultPrecisionQualifier(const TPrecision precision,const TPublicType & type,const TSourceLoc & loc)3892 void TParseContext::parseDefaultPrecisionQualifier(const TPrecision precision,
3893 const TPublicType &type,
3894 const TSourceLoc &loc)
3895 {
3896 if ((precision == EbpHigh) && (getShaderType() == GL_FRAGMENT_SHADER) &&
3897 !getFragmentPrecisionHigh())
3898 {
3899 error(loc, "precision is not supported in fragment shader", "highp");
3900 }
3901
3902 if (!CanSetDefaultPrecisionOnType(type))
3903 {
3904 error(loc, "illegal type argument for default precision qualifier",
3905 getBasicString(type.getBasicType()));
3906 return;
3907 }
3908 symbolTable.setDefaultPrecision(type.getBasicType(), precision);
3909 }
3910
checkPrimitiveTypeMatchesTypeQualifier(const TTypeQualifier & typeQualifier)3911 bool TParseContext::checkPrimitiveTypeMatchesTypeQualifier(const TTypeQualifier &typeQualifier)
3912 {
3913 switch (typeQualifier.layoutQualifier.primitiveType)
3914 {
3915 case EptLines:
3916 case EptLinesAdjacency:
3917 case EptTriangles:
3918 case EptTrianglesAdjacency:
3919 return typeQualifier.qualifier == EvqGeometryIn;
3920
3921 case EptLineStrip:
3922 case EptTriangleStrip:
3923 return typeQualifier.qualifier == EvqGeometryOut;
3924
3925 case EptPoints:
3926 return true;
3927
3928 default:
3929 UNREACHABLE();
3930 return false;
3931 }
3932 }
3933
setGeometryShaderInputArraySize(unsigned int inputArraySize,const TSourceLoc & line)3934 void TParseContext::setGeometryShaderInputArraySize(unsigned int inputArraySize,
3935 const TSourceLoc &line)
3936 {
3937 if (!symbolTable.setGlInArraySize(inputArraySize))
3938 {
3939 error(line,
3940 "Array size or input primitive declaration doesn't match the size of earlier sized "
3941 "array inputs.",
3942 "layout");
3943 }
3944 mGeometryInputArraySize = inputArraySize;
3945 }
3946
parseGeometryShaderInputLayoutQualifier(const TTypeQualifier & typeQualifier)3947 bool TParseContext::parseGeometryShaderInputLayoutQualifier(const TTypeQualifier &typeQualifier)
3948 {
3949 ASSERT(typeQualifier.qualifier == EvqGeometryIn);
3950
3951 const TLayoutQualifier &layoutQualifier = typeQualifier.layoutQualifier;
3952
3953 if (layoutQualifier.maxVertices != -1)
3954 {
3955 error(typeQualifier.line,
3956 "max_vertices can only be declared in 'out' layout in a geometry shader", "layout");
3957 return false;
3958 }
3959
3960 // Set mGeometryInputPrimitiveType if exists
3961 if (layoutQualifier.primitiveType != EptUndefined)
3962 {
3963 if (!checkPrimitiveTypeMatchesTypeQualifier(typeQualifier))
3964 {
3965 error(typeQualifier.line, "invalid primitive type for 'in' layout", "layout");
3966 return false;
3967 }
3968
3969 if (mGeometryShaderInputPrimitiveType == EptUndefined)
3970 {
3971 mGeometryShaderInputPrimitiveType = layoutQualifier.primitiveType;
3972 setGeometryShaderInputArraySize(
3973 GetGeometryShaderInputArraySize(mGeometryShaderInputPrimitiveType),
3974 typeQualifier.line);
3975 }
3976 else if (mGeometryShaderInputPrimitiveType != layoutQualifier.primitiveType)
3977 {
3978 error(typeQualifier.line, "primitive doesn't match earlier input primitive declaration",
3979 "layout");
3980 return false;
3981 }
3982
3983 // Size any implicitly sized arrays that have already been declared.
3984 for (TType *type : mDeferredArrayTypesToSize)
3985 {
3986 type->sizeOutermostUnsizedArray(
3987 symbolTable.getGlInVariableWithArraySize()->getType().getOutermostArraySize());
3988 }
3989 mDeferredArrayTypesToSize.clear();
3990 }
3991
3992 // Set mGeometryInvocations if exists
3993 if (layoutQualifier.invocations > 0)
3994 {
3995 if (mGeometryShaderInvocations == 0)
3996 {
3997 mGeometryShaderInvocations = layoutQualifier.invocations;
3998 }
3999 else if (mGeometryShaderInvocations != layoutQualifier.invocations)
4000 {
4001 error(typeQualifier.line, "invocations contradicts to the earlier declaration",
4002 "layout");
4003 return false;
4004 }
4005 }
4006
4007 return true;
4008 }
4009
parseGeometryShaderOutputLayoutQualifier(const TTypeQualifier & typeQualifier)4010 bool TParseContext::parseGeometryShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier)
4011 {
4012 ASSERT(typeQualifier.qualifier == EvqGeometryOut);
4013
4014 const TLayoutQualifier &layoutQualifier = typeQualifier.layoutQualifier;
4015
4016 if (layoutQualifier.invocations > 0)
4017 {
4018 error(typeQualifier.line,
4019 "invocations can only be declared in 'in' layout in a geometry shader", "layout");
4020 return false;
4021 }
4022
4023 // Set mGeometryOutputPrimitiveType if exists
4024 if (layoutQualifier.primitiveType != EptUndefined)
4025 {
4026 if (!checkPrimitiveTypeMatchesTypeQualifier(typeQualifier))
4027 {
4028 error(typeQualifier.line, "invalid primitive type for 'out' layout", "layout");
4029 return false;
4030 }
4031
4032 if (mGeometryShaderOutputPrimitiveType == EptUndefined)
4033 {
4034 mGeometryShaderOutputPrimitiveType = layoutQualifier.primitiveType;
4035 }
4036 else if (mGeometryShaderOutputPrimitiveType != layoutQualifier.primitiveType)
4037 {
4038 error(typeQualifier.line,
4039 "primitive doesn't match earlier output primitive declaration", "layout");
4040 return false;
4041 }
4042 }
4043
4044 // Set mGeometryMaxVertices if exists
4045 if (layoutQualifier.maxVertices > -1)
4046 {
4047 if (mGeometryShaderMaxVertices == -1)
4048 {
4049 mGeometryShaderMaxVertices = layoutQualifier.maxVertices;
4050 }
4051 else if (mGeometryShaderMaxVertices != layoutQualifier.maxVertices)
4052 {
4053 error(typeQualifier.line, "max_vertices contradicts to the earlier declaration",
4054 "layout");
4055 return false;
4056 }
4057 }
4058
4059 return true;
4060 }
4061
parseTessControlShaderOutputLayoutQualifier(const TTypeQualifier & typeQualifier)4062 bool TParseContext::parseTessControlShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier)
4063 {
4064 ASSERT(typeQualifier.qualifier == EvqTessControlOut);
4065
4066 const TLayoutQualifier &layoutQualifier = typeQualifier.layoutQualifier;
4067
4068 if (layoutQualifier.vertices == 0)
4069 {
4070 error(typeQualifier.line, "No vertices specified", "layout");
4071 return false;
4072 }
4073
4074 // Set mTessControlShaderOutputVertices if exists
4075 if (mTessControlShaderOutputVertices == 0)
4076 {
4077 mTessControlShaderOutputVertices = layoutQualifier.vertices;
4078
4079 // Size any implicitly sized arrays that have already been declared.
4080 for (TType *type : mDeferredArrayTypesToSize)
4081 {
4082 type->sizeOutermostUnsizedArray(mTessControlShaderOutputVertices);
4083 }
4084 mDeferredArrayTypesToSize.clear();
4085 }
4086 else
4087 {
4088 error(typeQualifier.line, "Duplicated vertices specified", "layout");
4089 }
4090 return true;
4091 }
4092
parseTessEvaluationShaderInputLayoutQualifier(const TTypeQualifier & typeQualifier)4093 bool TParseContext::parseTessEvaluationShaderInputLayoutQualifier(
4094 const TTypeQualifier &typeQualifier)
4095 {
4096 ASSERT(typeQualifier.qualifier == EvqTessEvaluationIn);
4097
4098 const TLayoutQualifier &layoutQualifier = typeQualifier.layoutQualifier;
4099
4100 // Set mTessEvaluationShaderInputPrimitiveType if exists
4101 if (layoutQualifier.tesPrimitiveType != EtetUndefined)
4102 {
4103 if (mTessEvaluationShaderInputPrimitiveType == EtetUndefined)
4104 {
4105 mTessEvaluationShaderInputPrimitiveType = layoutQualifier.tesPrimitiveType;
4106 }
4107 else
4108 {
4109 error(typeQualifier.line, "Duplicated primitive type declaration", "layout");
4110 }
4111 }
4112 // Set mTessEvaluationShaderVertexSpacingType if exists
4113 if (layoutQualifier.tesVertexSpacingType != EtetUndefined)
4114 {
4115 if (mTessEvaluationShaderInputVertexSpacingType == EtetUndefined)
4116 {
4117 mTessEvaluationShaderInputVertexSpacingType = layoutQualifier.tesVertexSpacingType;
4118 }
4119 else
4120 {
4121 error(typeQualifier.line, "Duplicated vertex spacing declaration", "layout");
4122 }
4123 }
4124 // Set mTessEvaluationShaderInputOrderingType if exists
4125 if (layoutQualifier.tesOrderingType != EtetUndefined)
4126 {
4127 if (mTessEvaluationShaderInputOrderingType == EtetUndefined)
4128 {
4129 mTessEvaluationShaderInputOrderingType = layoutQualifier.tesOrderingType;
4130 }
4131 else
4132 {
4133 error(typeQualifier.line, "Duplicated ordering declaration", "layout");
4134 }
4135 }
4136 // Set mTessEvaluationShaderInputPointType if exists
4137 if (layoutQualifier.tesPointType != EtetUndefined)
4138 {
4139 if (mTessEvaluationShaderInputPointType == EtetUndefined)
4140 {
4141 mTessEvaluationShaderInputPointType = layoutQualifier.tesPointType;
4142 }
4143 else
4144 {
4145 error(typeQualifier.line, "Duplicated point type declaration", "layout");
4146 }
4147 }
4148
4149 return true;
4150 }
4151
parseGlobalLayoutQualifier(const TTypeQualifierBuilder & typeQualifierBuilder)4152 void TParseContext::parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder)
4153 {
4154 TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
4155 const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier;
4156
4157 checkInvariantVariableQualifier(typeQualifier.invariant, typeQualifier.qualifier,
4158 typeQualifier.line);
4159
4160 // It should never be the case, but some strange parser errors can send us here.
4161 if (layoutQualifier.isEmpty())
4162 {
4163 error(typeQualifier.line, "Error during layout qualifier parsing.", "?");
4164 return;
4165 }
4166
4167 if (!layoutQualifier.isCombinationValid())
4168 {
4169 error(typeQualifier.line, "invalid layout qualifier combination", "layout");
4170 return;
4171 }
4172
4173 checkIndexIsNotSpecified(typeQualifier.line, layoutQualifier.index);
4174
4175 checkBindingIsNotSpecified(typeQualifier.line, layoutQualifier.binding);
4176
4177 checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
4178
4179 checkInternalFormatIsNotSpecified(typeQualifier.line, layoutQualifier.imageInternalFormat);
4180
4181 checkDepthIsNotSpecified(typeQualifier.line, layoutQualifier.depth);
4182
4183 checkYuvIsNotSpecified(typeQualifier.line, layoutQualifier.yuv);
4184
4185 checkOffsetIsNotSpecified(typeQualifier.line, layoutQualifier.offset);
4186
4187 checkStd430IsForShaderStorageBlock(typeQualifier.line, layoutQualifier.blockStorage,
4188 typeQualifier.qualifier);
4189
4190 checkAdvancedBlendEquationsNotSpecified(
4191 typeQualifier.line, layoutQualifier.advancedBlendEquations, typeQualifier.qualifier);
4192
4193 if (typeQualifier.qualifier != EvqFragmentIn)
4194 {
4195 checkEarlyFragmentTestsIsNotSpecified(typeQualifier.line,
4196 layoutQualifier.earlyFragmentTests);
4197 }
4198
4199 if (typeQualifier.qualifier == EvqComputeIn)
4200 {
4201 if (mComputeShaderLocalSizeDeclared &&
4202 !layoutQualifier.isLocalSizeEqual(mComputeShaderLocalSize))
4203 {
4204 error(typeQualifier.line, "Work group size does not match the previous declaration",
4205 "layout");
4206 return;
4207 }
4208
4209 if (mShaderVersion < 310)
4210 {
4211 error(typeQualifier.line, "in type qualifier supported in GLSL ES 3.10 only", "layout");
4212 return;
4213 }
4214
4215 if (!layoutQualifier.localSize.isAnyValueSet())
4216 {
4217 error(typeQualifier.line, "No local work group size specified", "layout");
4218 return;
4219 }
4220
4221 const TVariable *maxComputeWorkGroupSize = static_cast<const TVariable *>(
4222 symbolTable.findBuiltIn(ImmutableString("gl_MaxComputeWorkGroupSize"), mShaderVersion));
4223
4224 const TConstantUnion *maxComputeWorkGroupSizeData =
4225 maxComputeWorkGroupSize->getConstPointer();
4226
4227 for (size_t i = 0u; i < layoutQualifier.localSize.size(); ++i)
4228 {
4229 if (layoutQualifier.localSize[i] != -1)
4230 {
4231 mComputeShaderLocalSize[i] = layoutQualifier.localSize[i];
4232 const int maxComputeWorkGroupSizeValue = maxComputeWorkGroupSizeData[i].getIConst();
4233 if (mComputeShaderLocalSize[i] < 1 ||
4234 mComputeShaderLocalSize[i] > maxComputeWorkGroupSizeValue)
4235 {
4236 std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
4237 reasonStream << "invalid value: Value must be at least 1 and no greater than "
4238 << maxComputeWorkGroupSizeValue;
4239 const std::string &reason = reasonStream.str();
4240
4241 error(typeQualifier.line, reason.c_str(), getWorkGroupSizeString(i));
4242 return;
4243 }
4244 }
4245 }
4246
4247 mComputeShaderLocalSizeDeclared = true;
4248 }
4249 else if (typeQualifier.qualifier == EvqGeometryIn)
4250 {
4251 if (mShaderVersion < 310)
4252 {
4253 error(typeQualifier.line, "in type qualifier supported in GLSL ES 3.10 only", "layout");
4254 return;
4255 }
4256
4257 if (!parseGeometryShaderInputLayoutQualifier(typeQualifier))
4258 {
4259 return;
4260 }
4261 }
4262 else if (typeQualifier.qualifier == EvqGeometryOut)
4263 {
4264 if (mShaderVersion < 310)
4265 {
4266 error(typeQualifier.line, "out type qualifier supported in GLSL ES 3.10 only",
4267 "layout");
4268 return;
4269 }
4270
4271 if (!parseGeometryShaderOutputLayoutQualifier(typeQualifier))
4272 {
4273 return;
4274 }
4275 }
4276 else if (anyMultiviewExtensionAvailable() && typeQualifier.qualifier == EvqVertexIn)
4277 {
4278 // This error is only specified in WebGL, but tightens unspecified behavior in the native
4279 // specification.
4280 if (mNumViews != -1 && layoutQualifier.numViews != mNumViews)
4281 {
4282 error(typeQualifier.line, "Number of views does not match the previous declaration",
4283 "layout");
4284 return;
4285 }
4286
4287 if (layoutQualifier.numViews == -1)
4288 {
4289 error(typeQualifier.line, "No num_views specified", "layout");
4290 return;
4291 }
4292
4293 if (layoutQualifier.numViews > mMaxNumViews)
4294 {
4295 error(typeQualifier.line, "num_views greater than the value of GL_MAX_VIEWS_OVR",
4296 "layout");
4297 return;
4298 }
4299
4300 mNumViews = layoutQualifier.numViews;
4301 }
4302 else if (typeQualifier.qualifier == EvqFragmentIn)
4303 {
4304 if (mShaderVersion < 310)
4305 {
4306 error(typeQualifier.line,
4307 "in type qualifier without variable declaration supported in GLSL ES 3.10 and "
4308 "after",
4309 "layout");
4310 return;
4311 }
4312
4313 if (!layoutQualifier.earlyFragmentTests)
4314 {
4315 error(typeQualifier.line,
4316 "only early_fragment_tests is allowed as layout qualifier when not declaring a "
4317 "variable",
4318 "layout");
4319 return;
4320 }
4321
4322 mEarlyFragmentTestsSpecified = true;
4323 }
4324 else if (typeQualifier.qualifier == EvqFragmentOut)
4325 {
4326 if (mShaderVersion < 320 && !isExtensionEnabled(TExtension::KHR_blend_equation_advanced))
4327 {
4328 error(typeQualifier.line,
4329 "out type qualifier without variable declaration is supported in GLSL ES 3.20,"
4330 " or if GL_KHR_blend_equation_advanced is enabled",
4331 "layout");
4332 return;
4333 }
4334
4335 if (!layoutQualifier.advancedBlendEquations.any())
4336 {
4337 error(typeQualifier.line,
4338 "only blend equations are allowed as layout qualifier when not declaring a "
4339 "variable",
4340 "layout");
4341 return;
4342 }
4343
4344 errorIfPLSDeclared(typeQualifier.line, PLSIllegalOperations::EnableAdvancedBlendEquation);
4345 mAdvancedBlendEquations |= layoutQualifier.advancedBlendEquations;
4346 }
4347 else if (typeQualifier.qualifier == EvqTessControlOut)
4348 {
4349 if (mShaderVersion < 310)
4350 {
4351 error(typeQualifier.line, "out type qualifier supported in GLSL ES 3.10 and after",
4352 "layout");
4353 return;
4354 }
4355
4356 if (!parseTessControlShaderOutputLayoutQualifier(typeQualifier))
4357 {
4358 return;
4359 }
4360 }
4361 else if (typeQualifier.qualifier == EvqTessEvaluationIn)
4362 {
4363 if (mShaderVersion < 310)
4364 {
4365 error(typeQualifier.line, "in type qualifier supported in GLSL ES 3.10 and after",
4366 "layout");
4367 return;
4368 }
4369
4370 if (!parseTessEvaluationShaderInputLayoutQualifier(typeQualifier))
4371 {
4372 return;
4373 }
4374 }
4375 else
4376 {
4377 if (!checkWorkGroupSizeIsNotSpecified(typeQualifier.line, layoutQualifier))
4378 {
4379 return;
4380 }
4381
4382 if (typeQualifier.qualifier != EvqUniform && typeQualifier.qualifier != EvqBuffer)
4383 {
4384 error(typeQualifier.line, "invalid qualifier: global layout can only be set for blocks",
4385 getQualifierString(typeQualifier.qualifier));
4386 return;
4387 }
4388
4389 if (mShaderVersion < 300)
4390 {
4391 error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 and after",
4392 "layout");
4393 return;
4394 }
4395
4396 checkLocationIsNotSpecified(typeQualifier.line, layoutQualifier);
4397
4398 if (layoutQualifier.matrixPacking != EmpUnspecified)
4399 {
4400 if (typeQualifier.qualifier == EvqUniform)
4401 {
4402 mDefaultUniformMatrixPacking = layoutQualifier.matrixPacking;
4403 }
4404 else if (typeQualifier.qualifier == EvqBuffer)
4405 {
4406 mDefaultBufferMatrixPacking = layoutQualifier.matrixPacking;
4407 }
4408 }
4409
4410 if (layoutQualifier.blockStorage != EbsUnspecified)
4411 {
4412 if (typeQualifier.qualifier == EvqUniform)
4413 {
4414 mDefaultUniformBlockStorage = layoutQualifier.blockStorage;
4415 }
4416 else if (typeQualifier.qualifier == EvqBuffer)
4417 {
4418 mDefaultBufferBlockStorage = layoutQualifier.blockStorage;
4419 }
4420 }
4421 }
4422 }
4423
createPrototypeNodeFromFunction(const TFunction & function,const TSourceLoc & location,bool insertParametersToSymbolTable)4424 TIntermFunctionPrototype *TParseContext::createPrototypeNodeFromFunction(
4425 const TFunction &function,
4426 const TSourceLoc &location,
4427 bool insertParametersToSymbolTable)
4428 {
4429 checkIsNotReserved(location, function.name());
4430
4431 TIntermFunctionPrototype *prototype = new TIntermFunctionPrototype(&function);
4432 prototype->setLine(location);
4433
4434 for (size_t i = 0; i < function.getParamCount(); i++)
4435 {
4436 const TVariable *param = function.getParam(i);
4437
4438 // If the parameter has no name, it's not an error, just don't add it to symbol table (could
4439 // be used for unused args).
4440 if (param->symbolType() != SymbolType::Empty)
4441 {
4442 if (insertParametersToSymbolTable)
4443 {
4444 if (!symbolTable.declare(const_cast<TVariable *>(param)))
4445 {
4446 error(location, "redefinition", param->name());
4447 }
4448 }
4449 // Unsized type of a named parameter should have already been checked and sanitized.
4450 ASSERT(!param->getType().isUnsizedArray());
4451 }
4452 }
4453 return prototype;
4454 }
4455
addFunctionPrototypeDeclaration(const TFunction & parsedFunction,const TSourceLoc & location)4456 TIntermFunctionPrototype *TParseContext::addFunctionPrototypeDeclaration(
4457 const TFunction &parsedFunction,
4458 const TSourceLoc &location)
4459 {
4460 // Note: function found from the symbol table could be the same as parsedFunction if this is the
4461 // first declaration. Either way the instance in the symbol table is used to track whether the
4462 // function is declared multiple times.
4463 bool hadPrototypeDeclaration = false;
4464 const TFunction *function = symbolTable.markFunctionHasPrototypeDeclaration(
4465 parsedFunction.getMangledName(), &hadPrototypeDeclaration);
4466
4467 if (hadPrototypeDeclaration && mShaderVersion == 100)
4468 {
4469 // ESSL 1.00.17 section 4.2.7.
4470 // Doesn't apply to ESSL 3.00.4: see section 4.2.3.
4471 error(location, "duplicate function prototype declarations are not allowed", "function");
4472 }
4473
4474 TIntermFunctionPrototype *prototype =
4475 createPrototypeNodeFromFunction(*function, location, false);
4476
4477 symbolTable.pop();
4478
4479 if (!symbolTable.atGlobalLevel())
4480 {
4481 // ESSL 3.00.4 section 4.2.4.
4482 error(location, "local function prototype declarations are not allowed", "function");
4483 }
4484
4485 return prototype;
4486 }
4487
addFunctionDefinition(TIntermFunctionPrototype * functionPrototype,TIntermBlock * functionBody,const TSourceLoc & location)4488 TIntermFunctionDefinition *TParseContext::addFunctionDefinition(
4489 TIntermFunctionPrototype *functionPrototype,
4490 TIntermBlock *functionBody,
4491 const TSourceLoc &location)
4492 {
4493 // Undo push at end of parseFunctionDefinitionHeader() below for ESSL1.00 case
4494 if (mFunctionBodyNewScope)
4495 {
4496 mFunctionBodyNewScope = false;
4497 symbolTable.pop();
4498 }
4499
4500 // Check that non-void functions have at least one return statement.
4501 if (mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue)
4502 {
4503 error(location,
4504 "function does not return a value:", functionPrototype->getFunction()->name());
4505 }
4506
4507 if (functionBody == nullptr)
4508 {
4509 functionBody = new TIntermBlock();
4510 functionBody->setLine(location);
4511 }
4512 TIntermFunctionDefinition *functionNode =
4513 new TIntermFunctionDefinition(functionPrototype, functionBody);
4514 functionNode->setLine(location);
4515
4516 symbolTable.pop();
4517 return functionNode;
4518 }
4519
parseFunctionDefinitionHeader(const TSourceLoc & location,const TFunction * function,TIntermFunctionPrototype ** prototypeOut)4520 void TParseContext::parseFunctionDefinitionHeader(const TSourceLoc &location,
4521 const TFunction *function,
4522 TIntermFunctionPrototype **prototypeOut)
4523 {
4524 ASSERT(function);
4525
4526 bool wasDefined = false;
4527 function = symbolTable.setFunctionParameterNamesFromDefinition(function, &wasDefined);
4528 if (wasDefined)
4529 {
4530 error(location, "function already has a body", function->name());
4531 }
4532
4533 // Remember the return type for later checking for return statements.
4534 mCurrentFunctionType = &(function->getReturnType());
4535 mFunctionReturnsValue = false;
4536
4537 *prototypeOut = createPrototypeNodeFromFunction(*function, location, true);
4538 setLoopNestingLevel(0);
4539
4540 // ESSL 1.00 spec allows for variable in function body to redefine parameter
4541 if (IsSpecWithFunctionBodyNewScope(mShaderSpec, mShaderVersion))
4542 {
4543 mFunctionBodyNewScope = true;
4544 symbolTable.push();
4545 }
4546 }
4547
parseFunctionDeclarator(const TSourceLoc & location,TFunction * function)4548 TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TFunction *function)
4549 {
4550 //
4551 // We don't know at this point whether this is a function definition or a prototype.
4552 // The definition production code will check for redefinitions.
4553 // In the case of ESSL 1.00 the prototype production code will also check for redeclarations.
4554 //
4555
4556 for (size_t i = 0u; i < function->getParamCount(); ++i)
4557 {
4558 const TVariable *param = function->getParam(i);
4559 const TType ¶mType = param->getType();
4560
4561 checkPrecisionSpecified(location, paramType.getPrecision(), paramType.getBasicType());
4562 }
4563
4564 if (getShaderVersion() >= 300)
4565 {
4566 if (symbolTable.isUnmangledBuiltInName(function->name(), getShaderVersion(),
4567 extensionBehavior()))
4568 {
4569 // With ESSL 3.00 and above, names of built-in functions cannot be redeclared as
4570 // functions. Therefore overloading or redefining builtin functions is an error.
4571 error(location, "Name of a built-in function cannot be redeclared as function",
4572 function->name());
4573 }
4574 }
4575 else
4576 {
4577 // ESSL 1.00.17 section 4.2.6: built-ins can be overloaded but not redefined. We assume that
4578 // this applies to redeclarations as well.
4579 const TSymbol *builtIn =
4580 symbolTable.findBuiltIn(function->getMangledName(), getShaderVersion());
4581 if (builtIn)
4582 {
4583 error(location, "built-in functions cannot be redefined", function->name());
4584 }
4585 }
4586
4587 // Return types and parameter qualifiers must match in all redeclarations, so those are checked
4588 // here.
4589 const TFunction *prevDec =
4590 static_cast<const TFunction *>(symbolTable.findGlobal(function->getMangledName()));
4591 if (prevDec)
4592 {
4593 if (prevDec->getReturnType() != function->getReturnType())
4594 {
4595 error(location, "function must have the same return type in all of its declarations",
4596 function->getReturnType().getBasicString());
4597 }
4598 for (size_t i = 0; i < prevDec->getParamCount(); ++i)
4599 {
4600 if (prevDec->getParam(i)->getType().getQualifier() !=
4601 function->getParam(i)->getType().getQualifier())
4602 {
4603 error(location,
4604 "function must have the same parameter qualifiers in all of its declarations",
4605 function->getParam(i)->getType().getQualifierString());
4606 }
4607 }
4608 }
4609
4610 // Check for previously declared variables using the same name.
4611 const TSymbol *prevSym = symbolTable.find(function->name(), getShaderVersion());
4612 bool insertUnmangledName = true;
4613 if (prevSym)
4614 {
4615 if (!prevSym->isFunction())
4616 {
4617 error(location, "redefinition of a function", function->name());
4618 }
4619 insertUnmangledName = false;
4620 }
4621 // Parsing is at the inner scope level of the function's arguments and body statement at this
4622 // point, but declareUserDefinedFunction takes care of declaring the function at the global
4623 // scope.
4624 symbolTable.declareUserDefinedFunction(function, insertUnmangledName);
4625
4626 // Raise error message if main function takes any parameters or return anything other than void
4627 if (function->isMain())
4628 {
4629 if (function->getParamCount() > 0)
4630 {
4631 error(location, "function cannot take any parameter(s)", "main");
4632 }
4633 if (function->getReturnType().getBasicType() != EbtVoid)
4634 {
4635 error(location, "main function cannot return a value",
4636 function->getReturnType().getBasicString());
4637 }
4638 }
4639
4640 mDeclaringMain = function->isMain();
4641
4642 //
4643 // If this is a redeclaration, it could also be a definition, in which case, we want to use the
4644 // variable names from this one, and not the one that's
4645 // being redeclared. So, pass back up this declaration, not the one in the symbol table.
4646 //
4647 return function;
4648 }
4649
parseFunctionHeader(const TPublicType & type,const ImmutableString & name,const TSourceLoc & location)4650 TFunction *TParseContext::parseFunctionHeader(const TPublicType &type,
4651 const ImmutableString &name,
4652 const TSourceLoc &location)
4653 {
4654 if (type.qualifier != EvqGlobal && type.qualifier != EvqTemporary)
4655 {
4656 error(location, "no qualifiers allowed for function return",
4657 getQualifierString(type.qualifier));
4658 }
4659 if (!type.layoutQualifier.isEmpty())
4660 {
4661 error(location, "no qualifiers allowed for function return", "layout");
4662 }
4663 // make sure an opaque type is not involved as well...
4664 std::string reason(getBasicString(type.getBasicType()));
4665 reason += "s can't be function return values";
4666 checkIsNotOpaqueType(location, type.typeSpecifierNonArray, reason.c_str());
4667 if (mShaderVersion < 300)
4668 {
4669 // Array return values are forbidden, but there's also no valid syntax for declaring array
4670 // return values in ESSL 1.00.
4671 ASSERT(!type.isArray() || mDiagnostics->numErrors() > 0);
4672
4673 if (type.isStructureContainingArrays())
4674 {
4675 // ESSL 1.00.17 section 6.1 Function Definitions
4676 TInfoSinkBase typeString;
4677 typeString << TType(type);
4678 error(location, "structures containing arrays can't be function return values",
4679 typeString.c_str());
4680 }
4681 }
4682
4683 // Add the function as a prototype after parsing it (we do not support recursion)
4684 return new TFunction(&symbolTable, name, SymbolType::UserDefined, new TType(type), false);
4685 }
4686
addNonConstructorFunc(const ImmutableString & name,const TSymbol * symbol)4687 TFunctionLookup *TParseContext::addNonConstructorFunc(const ImmutableString &name,
4688 const TSymbol *symbol)
4689 {
4690 return TFunctionLookup::CreateFunctionCall(name, symbol);
4691 }
4692
addConstructorFunc(const TPublicType & publicType)4693 TFunctionLookup *TParseContext::addConstructorFunc(const TPublicType &publicType)
4694 {
4695 if (mShaderVersion < 300 && publicType.isArray())
4696 {
4697 error(publicType.getLine(), "array constructor supported in GLSL ES 3.00 and above only",
4698 "[]");
4699 }
4700 if (publicType.isStructSpecifier())
4701 {
4702 error(publicType.getLine(), "constructor can't be a structure definition",
4703 getBasicString(publicType.getBasicType()));
4704 }
4705
4706 TType *type = new TType(publicType);
4707 if (!type->canBeConstructed())
4708 {
4709 error(publicType.getLine(), "cannot construct this type",
4710 getBasicString(publicType.getBasicType()));
4711 type->setBasicType(EbtFloat);
4712 }
4713 return TFunctionLookup::CreateConstructor(type);
4714 }
4715
checkIsNotUnsizedArray(const TSourceLoc & line,const char * errorMessage,const ImmutableString & token,TType * arrayType)4716 void TParseContext::checkIsNotUnsizedArray(const TSourceLoc &line,
4717 const char *errorMessage,
4718 const ImmutableString &token,
4719 TType *arrayType)
4720 {
4721 if (arrayType->isUnsizedArray())
4722 {
4723 error(line, errorMessage, token);
4724 arrayType->sizeUnsizedArrays(TSpan<const unsigned int>());
4725 }
4726 }
4727
parseParameterDeclarator(const TPublicType & type,const ImmutableString & name,const TSourceLoc & nameLoc)4728 TParameter TParseContext::parseParameterDeclarator(const TPublicType &type,
4729 const ImmutableString &name,
4730 const TSourceLoc &nameLoc)
4731 {
4732 if (!name.empty())
4733 {
4734 if (type.getBasicType() == EbtVoid)
4735 {
4736 error(nameLoc, "illegal use of type 'void'", name);
4737 }
4738 }
4739 if (type.isStructSpecifier())
4740 {
4741 // ESSL 3.00.6 section 12.10.
4742 error(nameLoc, "Function parameter type cannot be a structure definition", name);
4743 }
4744 checkIsNotReserved(nameLoc, name);
4745 TParameter param{name.data(), type};
4746 if (param.type.isUnsizedArray())
4747 {
4748 error(nameLoc, "function parameter array must specify a size", name);
4749 param.type.sizeUnsizedArrays();
4750 }
4751 return param;
4752 }
4753
parseParameterArrayDeclarator(const TPublicType & elementType,const ImmutableString & name,const TSourceLoc & nameLoc,TVector<unsigned int> * arraySizes,const TSourceLoc & arrayLoc)4754 TParameter TParseContext::parseParameterArrayDeclarator(const TPublicType &elementType,
4755 const ImmutableString &name,
4756 const TSourceLoc &nameLoc,
4757 TVector<unsigned int> *arraySizes,
4758 const TSourceLoc &arrayLoc)
4759 {
4760 checkArrayElementIsNotArray(arrayLoc, elementType);
4761 TPublicType arrayType{elementType};
4762 arrayType.makeArrays(arraySizes);
4763 return parseParameterDeclarator(arrayType, name, nameLoc);
4764 }
4765
checkUnsizedArrayConstructorArgumentDimensionality(const TIntermSequence & arguments,TType type,const TSourceLoc & line)4766 bool TParseContext::checkUnsizedArrayConstructorArgumentDimensionality(
4767 const TIntermSequence &arguments,
4768 TType type,
4769 const TSourceLoc &line)
4770 {
4771 if (arguments.empty())
4772 {
4773 error(line, "implicitly sized array constructor must have at least one argument", "[]");
4774 return false;
4775 }
4776 for (TIntermNode *arg : arguments)
4777 {
4778 const TIntermTyped *element = arg->getAsTyped();
4779 ASSERT(element);
4780 if (element->getType().isUnsizedArray())
4781 {
4782 error(line, "constructing from an unsized array", "constructor");
4783 return false;
4784 }
4785 size_t dimensionalityFromElement = element->getType().getNumArraySizes() + 1u;
4786 if (dimensionalityFromElement > type.getNumArraySizes())
4787 {
4788 error(line, "constructing from a non-dereferenced array", "constructor");
4789 return false;
4790 }
4791 else if (dimensionalityFromElement < type.getNumArraySizes())
4792 {
4793 if (dimensionalityFromElement == 1u)
4794 {
4795 error(line, "implicitly sized array of arrays constructor argument is not an array",
4796 "constructor");
4797 }
4798 else
4799 {
4800 error(line,
4801 "implicitly sized array of arrays constructor argument dimensionality is too "
4802 "low",
4803 "constructor");
4804 }
4805 return false;
4806 }
4807 }
4808 return true;
4809 }
4810
4811 // This function is used to test for the correctness of the parameters passed to various constructor
4812 // functions and also convert them to the right datatype if it is allowed and required.
4813 //
4814 // Returns a node to add to the tree regardless of if an error was generated or not.
4815 //
addConstructor(TFunctionLookup * fnCall,const TSourceLoc & line)4816 TIntermTyped *TParseContext::addConstructor(TFunctionLookup *fnCall, const TSourceLoc &line)
4817 {
4818 TType type = fnCall->constructorType();
4819 TIntermSequence &arguments = fnCall->arguments();
4820 if (type.isUnsizedArray())
4821 {
4822 if (!checkUnsizedArrayConstructorArgumentDimensionality(arguments, type, line))
4823 {
4824 type.sizeUnsizedArrays(TSpan<const unsigned int>());
4825 return CreateZeroNode(type);
4826 }
4827 TIntermTyped *firstElement = arguments.at(0)->getAsTyped();
4828 ASSERT(firstElement);
4829 if (type.getOutermostArraySize() == 0u)
4830 {
4831 type.sizeOutermostUnsizedArray(static_cast<unsigned int>(arguments.size()));
4832 }
4833 for (size_t i = 0; i < firstElement->getType().getNumArraySizes(); ++i)
4834 {
4835 if (type.getArraySizes()[i] == 0u)
4836 {
4837 type.setArraySize(i, firstElement->getType().getArraySizes()[i]);
4838 }
4839 }
4840 ASSERT(!type.isUnsizedArray());
4841 }
4842
4843 if (!checkConstructorArguments(line, arguments, type))
4844 {
4845 return CreateZeroNode(type);
4846 }
4847
4848 TIntermAggregate *constructorNode = TIntermAggregate::CreateConstructor(type, &arguments);
4849 constructorNode->setLine(line);
4850
4851 return constructorNode->fold(mDiagnostics);
4852 }
4853
4854 //
4855 // Interface/uniform blocks
addInterfaceBlock(const TTypeQualifierBuilder & typeQualifierBuilder,const TSourceLoc & nameLine,const ImmutableString & blockName,TFieldList * fieldList,const ImmutableString & instanceName,const TSourceLoc & instanceLine,const TVector<unsigned int> * arraySizes,const TSourceLoc & arraySizesLine)4856 TIntermDeclaration *TParseContext::addInterfaceBlock(
4857 const TTypeQualifierBuilder &typeQualifierBuilder,
4858 const TSourceLoc &nameLine,
4859 const ImmutableString &blockName,
4860 TFieldList *fieldList,
4861 const ImmutableString &instanceName,
4862 const TSourceLoc &instanceLine,
4863 const TVector<unsigned int> *arraySizes,
4864 const TSourceLoc &arraySizesLine)
4865 {
4866 checkDoesNotHaveTooManyFields(blockName, fieldList, nameLine);
4867
4868 // Ensure there are no duplicate field names
4869 checkDoesNotHaveDuplicateFieldNames(fieldList, nameLine);
4870
4871 const bool isGLPerVertex = blockName == "gl_PerVertex";
4872 // gl_PerVertex is allowed to be redefined and therefore not reserved
4873 if (!isGLPerVertex)
4874 {
4875 checkIsNotReserved(nameLine, blockName);
4876 }
4877
4878 TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
4879
4880 const bool isUniformOrBuffer =
4881 typeQualifier.qualifier == EvqUniform || typeQualifier.qualifier == EvqBuffer;
4882 const bool isShaderIoBlock = IsShaderIoBlock(typeQualifier.qualifier);
4883
4884 if (mShaderVersion < 310 && typeQualifier.qualifier != EvqUniform)
4885 {
4886 error(typeQualifier.line,
4887 "invalid qualifier: interface blocks must be uniform in version lower than GLSL ES "
4888 "3.10",
4889 getQualifierString(typeQualifier.qualifier));
4890 }
4891 else if (typeQualifier.qualifier == EvqPatchOut)
4892 {
4893 if ((!isExtensionEnabled(TExtension::EXT_tessellation_shader) &&
4894 !isExtensionEnabled(TExtension::OES_tessellation_shader) && mShaderVersion < 320) ||
4895 mShaderType != GL_TESS_CONTROL_SHADER)
4896 {
4897 error(typeQualifier.line,
4898 "invalid qualifier: 'patch out' requires a tessellation control shader",
4899 getQualifierString(typeQualifier.qualifier));
4900 }
4901 }
4902 else if (typeQualifier.qualifier == EvqPatchIn)
4903 {
4904 if ((!isExtensionEnabled(TExtension::EXT_tessellation_shader) &&
4905 !isExtensionEnabled(TExtension::OES_tessellation_shader) && mShaderVersion < 320) ||
4906 mShaderType != GL_TESS_EVALUATION_SHADER)
4907 {
4908 error(typeQualifier.line,
4909 "invalid qualifier: 'patch in' requires a tessellation evaluation shader",
4910 getQualifierString(typeQualifier.qualifier));
4911 }
4912 }
4913 else if (typeQualifier.qualifier != EvqUniform && typeQualifier.qualifier != EvqBuffer)
4914 {
4915 if (isShaderIoBlock)
4916 {
4917 if (!isExtensionEnabled(TExtension::OES_shader_io_blocks) &&
4918 !isExtensionEnabled(TExtension::EXT_shader_io_blocks) &&
4919 !isExtensionEnabled(TExtension::OES_geometry_shader) &&
4920 !isExtensionEnabled(TExtension::EXT_geometry_shader) && mShaderVersion < 320)
4921 {
4922 error(typeQualifier.line,
4923 "invalid qualifier: shader IO blocks need shader io block extension",
4924 getQualifierString(typeQualifier.qualifier));
4925 }
4926
4927 // Both inputs and outputs of tessellation control shaders must be arrays.
4928 // For tessellation evaluation shaders, only inputs must necessarily be arrays.
4929 const bool isTCS = mShaderType == GL_TESS_CONTROL_SHADER;
4930 const bool isTESIn =
4931 mShaderType == GL_TESS_EVALUATION_SHADER && IsShaderIn(typeQualifier.qualifier);
4932 if (arraySizes == nullptr && (isTCS || isTESIn))
4933 {
4934 error(typeQualifier.line, "type must be an array", blockName);
4935 }
4936 }
4937 else
4938 {
4939 error(typeQualifier.line,
4940 "invalid qualifier: interface blocks must be uniform or buffer",
4941 getQualifierString(typeQualifier.qualifier));
4942 }
4943 }
4944
4945 if (typeQualifier.invariant)
4946 {
4947 error(typeQualifier.line, "invalid qualifier on interface block", "invariant");
4948 }
4949
4950 if (typeQualifier.qualifier != EvqBuffer)
4951 {
4952 checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
4953 }
4954
4955 // Verify array sizes
4956 if (arraySizes)
4957 {
4958 if (isUniformOrBuffer)
4959 {
4960 if (arraySizes->size() == 0)
4961 {
4962 error(arraySizesLine, "unsized arrays are not allowed with interface blocks", "");
4963 }
4964 if (arraySizes->size() > 1)
4965 {
4966 error(arraySizesLine, "array of arrays are not allowed with interface blocks", "");
4967 }
4968 }
4969 else if (isShaderIoBlock)
4970 {
4971 size_t arrayDimensions = arraySizes->size();
4972
4973 // Geometry shader inputs have a level arrayness that must be ignored.
4974 if (mShaderType == GL_GEOMETRY_SHADER_EXT && IsVaryingIn(typeQualifier.qualifier))
4975 {
4976 ASSERT(arrayDimensions > 0);
4977 --arrayDimensions;
4978
4979 // Validate that the array size of input matches the geometry layout
4980 // declaration, if not automatic (specified as []).
4981 const unsigned int geometryDim = arraySizes->back();
4982 if (geometryDim > 0 && geometryDim != mGeometryInputArraySize)
4983 {
4984 error(arraySizesLine,
4985 "geometry shader input block array size inconsistent "
4986 "with primitive",
4987 "");
4988 }
4989 }
4990
4991 if (arrayDimensions > 1)
4992 {
4993 error(arraySizesLine, "array of arrays are not allowed with I/O blocks", "");
4994 }
4995 }
4996 }
4997 else if (isShaderIoBlock && mShaderType == GL_GEOMETRY_SHADER_EXT &&
4998 IsVaryingIn(typeQualifier.qualifier))
4999 {
5000 error(arraySizesLine, "geometry shader input blocks must be an array", "");
5001 }
5002
5003 checkIndexIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.index);
5004
5005 if (mShaderVersion < 310)
5006 {
5007 checkBindingIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.binding);
5008 }
5009 else
5010 {
5011 unsigned int arraySize =
5012 arraySizes == nullptr || arraySizes->empty() ? 0 : (*arraySizes)[0];
5013 checkBlockBindingIsValid(typeQualifier.line, typeQualifier.qualifier,
5014 typeQualifier.layoutQualifier.binding, arraySize);
5015 }
5016
5017 checkDepthIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.depth);
5018 checkYuvIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.yuv);
5019 checkEarlyFragmentTestsIsNotSpecified(typeQualifier.line,
5020 typeQualifier.layoutQualifier.earlyFragmentTests);
5021 checkNoncoherentIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.noncoherent);
5022
5023 TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier;
5024 if (!IsShaderIoBlock(typeQualifier.qualifier) && typeQualifier.qualifier != EvqPatchIn &&
5025 typeQualifier.qualifier != EvqPatchOut)
5026 {
5027 checkLocationIsNotSpecified(typeQualifier.line, blockLayoutQualifier);
5028 }
5029 checkStd430IsForShaderStorageBlock(typeQualifier.line, blockLayoutQualifier.blockStorage,
5030 typeQualifier.qualifier);
5031
5032 if (blockLayoutQualifier.matrixPacking == EmpUnspecified)
5033 {
5034 if (typeQualifier.qualifier == EvqUniform)
5035 {
5036 blockLayoutQualifier.matrixPacking = mDefaultUniformMatrixPacking;
5037 }
5038 else if (typeQualifier.qualifier == EvqBuffer)
5039 {
5040 blockLayoutQualifier.matrixPacking = mDefaultBufferMatrixPacking;
5041 }
5042 }
5043
5044 if (blockLayoutQualifier.blockStorage == EbsUnspecified)
5045 {
5046 if (typeQualifier.qualifier == EvqUniform)
5047 {
5048 blockLayoutQualifier.blockStorage = mDefaultUniformBlockStorage;
5049 }
5050 else if (typeQualifier.qualifier == EvqBuffer)
5051 {
5052 blockLayoutQualifier.blockStorage = mDefaultBufferBlockStorage;
5053 }
5054 }
5055
5056 checkWorkGroupSizeIsNotSpecified(nameLine, blockLayoutQualifier);
5057
5058 checkInternalFormatIsNotSpecified(nameLine, blockLayoutQualifier.imageInternalFormat);
5059
5060 // check for sampler types and apply layout qualifiers
5061 for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
5062 {
5063 TField *field = (*fieldList)[memberIndex];
5064 TType *fieldType = field->type();
5065 if (ContainsOpaque<IsOpaqueFunc>(*fieldType))
5066 {
5067 error(field->line(), "Opaque types are not allowed in interface blocks", blockName);
5068 }
5069
5070 const TQualifier qualifier = fieldType->getQualifier();
5071 switch (qualifier)
5072 {
5073 case EvqGlobal:
5074 break;
5075 case EvqUniform:
5076 if (typeQualifier.qualifier == EvqBuffer)
5077 {
5078 error(field->line(), "invalid qualifier on shader storage block member",
5079 getQualifierString(qualifier));
5080 }
5081 break;
5082 case EvqBuffer:
5083 if (typeQualifier.qualifier == EvqUniform)
5084 {
5085 error(field->line(), "invalid qualifier on uniform block member",
5086 getQualifierString(qualifier));
5087 }
5088 break;
5089 // a member variable in io block may have different interpolation.
5090 case EvqSmoothIn:
5091 case EvqSmoothOut:
5092 case EvqFlatIn:
5093 case EvqFlatOut:
5094 case EvqNoPerspectiveIn:
5095 case EvqNoPerspectiveOut:
5096 case EvqCentroidIn:
5097 case EvqCentroidOut:
5098 case EvqSampleIn:
5099 case EvqSampleOut:
5100 case EvqNoPerspectiveCentroidIn:
5101 case EvqNoPerspectiveCentroidOut:
5102 case EvqNoPerspectiveSampleIn:
5103 case EvqNoPerspectiveSampleOut:
5104 break;
5105 // a member variable can have an incomplete qualifier because shader io block has either
5106 // in or out.
5107 case EvqSmooth:
5108 case EvqFlat:
5109 case EvqNoPerspective:
5110 case EvqCentroid:
5111 case EvqSample:
5112 case EvqNoPerspectiveCentroid:
5113 case EvqNoPerspectiveSample:
5114 case EvqGeometryIn:
5115 case EvqGeometryOut:
5116 if (!IsShaderIoBlock(typeQualifier.qualifier) &&
5117 typeQualifier.qualifier != EvqPatchIn &&
5118 typeQualifier.qualifier != EvqPatchOut &&
5119 typeQualifier.qualifier != EvqGeometryIn &&
5120 typeQualifier.qualifier != EvqGeometryOut)
5121 {
5122 error(field->line(), "invalid qualifier on interface block member",
5123 getQualifierString(qualifier));
5124 }
5125 break;
5126 default:
5127 error(field->line(), "invalid qualifier on interface block member",
5128 getQualifierString(qualifier));
5129 break;
5130 }
5131
5132 // On interface block members, invariant is only applicable to output I/O blocks.
5133 const bool isOutputShaderIoBlock = isShaderIoBlock && IsShaderOut(typeQualifier.qualifier);
5134 if (fieldType->isInvariant() && !isOutputShaderIoBlock)
5135 {
5136 error(field->line(), "invalid qualifier on interface block member", "invariant");
5137 }
5138
5139 // check layout qualifiers
5140 TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier();
5141 checkIndexIsNotSpecified(field->line(), fieldLayoutQualifier.index);
5142 checkBindingIsNotSpecified(field->line(), fieldLayoutQualifier.binding);
5143
5144 if (fieldLayoutQualifier.blockStorage != EbsUnspecified)
5145 {
5146 error(field->line(), "invalid layout qualifier: cannot be used here",
5147 getBlockStorageString(fieldLayoutQualifier.blockStorage));
5148 }
5149
5150 if (fieldLayoutQualifier.matrixPacking == EmpUnspecified)
5151 {
5152 fieldLayoutQualifier.matrixPacking = blockLayoutQualifier.matrixPacking;
5153 }
5154 else if (!fieldType->isMatrix() && fieldType->getBasicType() != EbtStruct)
5155 {
5156 warning(field->line(),
5157 "extraneous layout qualifier: only has an effect on matrix types",
5158 getMatrixPackingString(fieldLayoutQualifier.matrixPacking));
5159 }
5160
5161 fieldType->setLayoutQualifier(fieldLayoutQualifier);
5162
5163 if (mShaderVersion < 310 || memberIndex != fieldList->size() - 1u ||
5164 typeQualifier.qualifier != EvqBuffer)
5165 {
5166 // ESSL 3.10 spec section 4.1.9 allows for runtime-sized arrays.
5167 checkIsNotUnsizedArray(field->line(),
5168 "array members of interface blocks must specify a size",
5169 field->name(), field->type());
5170 }
5171
5172 if (typeQualifier.qualifier == EvqBuffer)
5173 {
5174 // set memory qualifiers
5175 // GLSL ES 3.10 session 4.9 [Memory Access Qualifiers]. When a block declaration is
5176 // qualified with a memory qualifier, it is as if all of its members were declared with
5177 // the same memory qualifier.
5178 const TMemoryQualifier &blockMemoryQualifier = typeQualifier.memoryQualifier;
5179 TMemoryQualifier fieldMemoryQualifier = fieldType->getMemoryQualifier();
5180 fieldMemoryQualifier.readonly |= blockMemoryQualifier.readonly;
5181 fieldMemoryQualifier.writeonly |= blockMemoryQualifier.writeonly;
5182 fieldMemoryQualifier.coherent |= blockMemoryQualifier.coherent;
5183 fieldMemoryQualifier.restrictQualifier |= blockMemoryQualifier.restrictQualifier;
5184 fieldMemoryQualifier.volatileQualifier |= blockMemoryQualifier.volatileQualifier;
5185 // TODO([email protected]): Decide whether if readonly and writeonly buffer variable
5186 // is legal. See bug https://github.com/KhronosGroup/OpenGL-API/issues/7
5187 fieldType->setMemoryQualifier(fieldMemoryQualifier);
5188 }
5189 }
5190
5191 SymbolType instanceSymbolType = SymbolType::UserDefined;
5192 if (isGLPerVertex)
5193 {
5194 instanceSymbolType = SymbolType::BuiltIn;
5195 }
5196 TInterfaceBlock *interfaceBlock = new TInterfaceBlock(&symbolTable, blockName, fieldList,
5197 blockLayoutQualifier, instanceSymbolType);
5198 if (!symbolTable.declare(interfaceBlock) && isUniformOrBuffer)
5199 {
5200 error(nameLine, "redefinition of an interface block name", blockName);
5201 }
5202
5203 TType *interfaceBlockType =
5204 new TType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier);
5205 if (arraySizes)
5206 {
5207 interfaceBlockType->makeArrays(*arraySizes);
5208 checkGeometryShaderInputAndSetArraySize(instanceLine, instanceName, interfaceBlockType);
5209 checkTessellationShaderUnsizedArraysAndSetSize(instanceLine, instanceName,
5210 interfaceBlockType);
5211 checkDeclarationIsValidArraySize(instanceLine, instanceName, interfaceBlockType);
5212 }
5213
5214 // The instance variable gets created to refer to the interface block type from the AST
5215 // regardless of if there's an instance name. It's created as an empty symbol if there is no
5216 // instance name.
5217 TVariable *instanceVariable =
5218 new TVariable(&symbolTable, instanceName, interfaceBlockType,
5219 instanceName.empty() ? SymbolType::Empty : SymbolType::UserDefined);
5220
5221 if (instanceVariable->symbolType() == SymbolType::Empty)
5222 {
5223 // define symbols for the members of the interface block
5224 for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
5225 {
5226 TField *field = (*fieldList)[memberIndex];
5227 TType *fieldType = new TType(*field->type());
5228
5229 // set parent pointer of the field variable
5230 fieldType->setInterfaceBlockField(interfaceBlock, memberIndex);
5231
5232 fieldType->setQualifier(typeQualifier.qualifier);
5233
5234 SymbolType symbolType = SymbolType::UserDefined;
5235 if (field->name() == "gl_Position" || field->name() == "gl_PointSize" ||
5236 field->name() == "gl_ClipDistance" || field->name() == "gl_CullDistance")
5237 {
5238 // These builtins can be redefined only when used within a redefined gl_PerVertex
5239 // block
5240 if (interfaceBlock->name() != "gl_PerVertex")
5241 {
5242 error(field->line(), "redefinition in an invalid interface block",
5243 field->name());
5244 }
5245 symbolType = SymbolType::BuiltIn;
5246 }
5247 TVariable *fieldVariable =
5248 new TVariable(&symbolTable, field->name(), fieldType, symbolType);
5249 if (!symbolTable.declare(fieldVariable))
5250 {
5251 error(field->line(), "redefinition of an interface block member name",
5252 field->name());
5253 }
5254 }
5255 }
5256 else
5257 {
5258 checkIsNotReserved(instanceLine, instanceName);
5259
5260 // add a symbol for this interface block
5261 if (!symbolTable.declare(instanceVariable))
5262 {
5263 error(instanceLine, "redefinition of an interface block instance name", instanceName);
5264 }
5265 }
5266
5267 TIntermSymbol *blockSymbol = new TIntermSymbol(instanceVariable);
5268 blockSymbol->setLine(typeQualifier.line);
5269 TIntermDeclaration *declaration = new TIntermDeclaration();
5270 declaration->appendDeclarator(blockSymbol);
5271 declaration->setLine(nameLine);
5272
5273 exitStructDeclaration();
5274 return declaration;
5275 }
5276
enterStructDeclaration(const TSourceLoc & line,const ImmutableString & identifier)5277 void TParseContext::enterStructDeclaration(const TSourceLoc &line,
5278 const ImmutableString &identifier)
5279 {
5280 ++mStructNestingLevel;
5281
5282 // Embedded structure definitions are not supported per GLSL ES spec.
5283 // ESSL 1.00.17 section 10.9. ESSL 3.00.6 section 12.11.
5284 if (mStructNestingLevel > 1)
5285 {
5286 error(line, "Embedded struct definitions are not allowed", "struct");
5287 }
5288 }
5289
exitStructDeclaration()5290 void TParseContext::exitStructDeclaration()
5291 {
5292 --mStructNestingLevel;
5293 }
5294
checkIsBelowStructNestingLimit(const TSourceLoc & line,const TField & field)5295 void TParseContext::checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field)
5296 {
5297 if (!sh::IsWebGLBasedSpec(mShaderSpec))
5298 {
5299 return;
5300 }
5301
5302 if (field.type()->getBasicType() != EbtStruct)
5303 {
5304 return;
5305 }
5306
5307 // We're already inside a structure definition at this point, so add
5308 // one to the field's struct nesting.
5309 if (1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting)
5310 {
5311 std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
5312 if (field.type()->getStruct()->symbolType() == SymbolType::Empty)
5313 {
5314 // This may happen in case there are nested struct definitions. While they are also
5315 // invalid GLSL, they don't cause a syntax error.
5316 reasonStream << "Struct nesting";
5317 }
5318 else
5319 {
5320 reasonStream << "Reference of struct type " << field.type()->getStruct()->name();
5321 }
5322 reasonStream << " exceeds maximum allowed nesting level of " << kWebGLMaxStructNesting;
5323 std::string reason = reasonStream.str();
5324 error(line, reason.c_str(), field.name());
5325 return;
5326 }
5327 }
5328
5329 //
5330 // Parse an array index expression
5331 //
addIndexExpression(TIntermTyped * baseExpression,const TSourceLoc & location,TIntermTyped * indexExpression)5332 TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
5333 const TSourceLoc &location,
5334 TIntermTyped *indexExpression)
5335 {
5336 if (!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector())
5337 {
5338 if (baseExpression->getAsSymbolNode())
5339 {
5340 error(location, " left of '[' is not of type array, matrix, or vector ",
5341 baseExpression->getAsSymbolNode()->getName());
5342 }
5343 else
5344 {
5345 error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
5346 }
5347
5348 return CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
5349 }
5350
5351 if (baseExpression->getQualifier() == EvqPerVertexIn)
5352 {
5353 if (mGeometryShaderInputPrimitiveType == EptUndefined &&
5354 mShaderType == GL_GEOMETRY_SHADER_EXT)
5355 {
5356 error(location, "missing input primitive declaration before indexing gl_in.", "[");
5357 return CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
5358 }
5359 }
5360
5361 TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion();
5362
5363 // ES3.2 or ES3.1's EXT_gpu_shader5 allow dynamically uniform expressions to be used as indices
5364 // of opaque types (samplers and atomic counters) as well as UBOs, but not SSBOs and images.
5365 bool allowUniformIndices = mShaderVersion >= 320 ||
5366 isExtensionEnabled(TExtension::EXT_gpu_shader5) ||
5367 isExtensionEnabled(TExtension::OES_gpu_shader5);
5368
5369 // ANGLE should be able to fold any constant expressions resulting in an integer - but to be
5370 // safe we don't treat "EvqConst" that's evaluated according to the spec as being sufficient
5371 // for constness. Some interpretations of the spec have allowed constant expressions with side
5372 // effects - like array length() method on a non-constant array.
5373 if (indexExpression->getQualifier() != EvqConst || indexConstantUnion == nullptr)
5374 {
5375 if (baseExpression->isInterfaceBlock())
5376 {
5377 switch (baseExpression->getQualifier())
5378 {
5379 case EvqPerVertexIn:
5380 break;
5381 case EvqUniform:
5382 if (!allowUniformIndices)
5383 {
5384 error(location,
5385 "array indexes for uniform block arrays must be constant integral "
5386 "expressions",
5387 "[");
5388 }
5389 break;
5390 case EvqBuffer:
5391 error(location,
5392 "array indexes for shader storage block arrays must be constant integral "
5393 "expressions",
5394 "[");
5395 break;
5396 default:
5397 // It's ok for shader I/O blocks to be dynamically indexed
5398 if (!IsShaderIoBlock(baseExpression->getQualifier()) &&
5399 baseExpression->getQualifier() != EvqPatchIn &&
5400 baseExpression->getQualifier() != EvqPatchOut)
5401 {
5402 // We can reach here only in error cases.
5403 ASSERT(mDiagnostics->numErrors() > 0);
5404 }
5405 break;
5406 }
5407 }
5408 else if (baseExpression->getQualifier() == EvqFragmentOut ||
5409 baseExpression->getQualifier() == EvqFragmentInOut)
5410 {
5411 error(location,
5412 "array indexes for fragment outputs must be constant integral expressions", "[");
5413 }
5414 else if (baseExpression->getQualifier() == EvqLastFragData)
5415 {
5416 error(location,
5417 "array indexes for gl_LastFragData must be constant integral expressions", "[");
5418 }
5419 else if (mShaderSpec == SH_WEBGL2_SPEC && baseExpression->getQualifier() == EvqFragData)
5420 {
5421 error(location, "array index for gl_FragData must be constant zero", "[");
5422 }
5423 else if (mShaderSpec == SH_WEBGL2_SPEC &&
5424 baseExpression->getQualifier() == EvqSecondaryFragDataEXT)
5425 {
5426 error(location, "array index for gl_SecondaryFragDataEXT must be constant zero", "[");
5427 }
5428 else if (baseExpression->isArray())
5429 {
5430 TBasicType elementType = baseExpression->getType().getBasicType();
5431
5432 // Note: In Section 12.30 of the ESSL 3.00 spec on p143-144:
5433 //
5434 // Indexing of arrays of samplers by constant-index-expressions is
5435 // supported in GLSL ES 1.00. A constant-index-expression is an
5436 // expression formed from constant-expressions and certain loop indices,
5437 // defined for a subset of loop constructs. Should this functionality be
5438 // included in GLSL ES 3.00?
5439 //
5440 // RESOLUTION: No. Arrays of samplers may only be indexed by constant-
5441 // integral-expressions.
5442 if (IsSampler(elementType) && !allowUniformIndices && mShaderVersion > 100)
5443 {
5444 error(location, "array index for samplers must be constant integral expressions",
5445 "[");
5446 }
5447 else if (IsImage(elementType))
5448 {
5449 error(location,
5450 "array indexes for image arrays must be constant integral expressions", "[");
5451 }
5452 }
5453 }
5454
5455 if (indexConstantUnion)
5456 {
5457 // If an out-of-range index is not qualified as constant, the behavior in the spec is
5458 // undefined. This applies even if ANGLE has been able to constant fold it (ANGLE may
5459 // constant fold expressions that are not constant expressions). The most compatible way to
5460 // handle this case is to report a warning instead of an error and force the index to be in
5461 // the correct range.
5462 bool outOfRangeIndexIsError = indexExpression->getQualifier() == EvqConst;
5463 int index = 0;
5464 if (indexConstantUnion->getBasicType() == EbtInt)
5465 {
5466 index = indexConstantUnion->getIConst(0);
5467 }
5468 else if (indexConstantUnion->getBasicType() == EbtUInt)
5469 {
5470 index = static_cast<int>(indexConstantUnion->getUConst(0));
5471 }
5472
5473 int safeIndex = -1;
5474
5475 if (index < 0)
5476 {
5477 outOfRangeError(outOfRangeIndexIsError, location, "index expression is negative", "[]");
5478 safeIndex = 0;
5479 }
5480
5481 if (!baseExpression->getType().isUnsizedArray())
5482 {
5483 if (baseExpression->isArray())
5484 {
5485 if (baseExpression->getQualifier() == EvqFragData && index > 0)
5486 {
5487 if (!isExtensionEnabled(TExtension::EXT_draw_buffers))
5488 {
5489 outOfRangeError(outOfRangeIndexIsError, location,
5490 "array index for gl_FragData must be zero when "
5491 "GL_EXT_draw_buffers is disabled",
5492 "[]");
5493 safeIndex = 0;
5494 }
5495 }
5496 }
5497 // Only do generic out-of-range check if similar error hasn't already been reported.
5498 if (safeIndex < 0)
5499 {
5500 if (baseExpression->isArray())
5501 {
5502 safeIndex = checkIndexLessThan(outOfRangeIndexIsError, location, index,
5503 baseExpression->getOutermostArraySize(),
5504 "array index out of range");
5505 }
5506 else if (baseExpression->isMatrix())
5507 {
5508 safeIndex = checkIndexLessThan(outOfRangeIndexIsError, location, index,
5509 baseExpression->getType().getCols(),
5510 "matrix field selection out of range");
5511 }
5512 else
5513 {
5514 ASSERT(baseExpression->isVector());
5515 safeIndex = checkIndexLessThan(outOfRangeIndexIsError, location, index,
5516 baseExpression->getType().getNominalSize(),
5517 "vector field selection out of range");
5518 }
5519 }
5520
5521 ASSERT(safeIndex >= 0);
5522 // Data of constant unions can't be changed, because it may be shared with other
5523 // constant unions or even builtins, like gl_MaxDrawBuffers. Instead use a new
5524 // sanitized object.
5525 if (safeIndex != index || indexConstantUnion->getBasicType() != EbtInt)
5526 {
5527 TConstantUnion *safeConstantUnion = new TConstantUnion();
5528 safeConstantUnion->setIConst(safeIndex);
5529 indexExpression =
5530 new TIntermConstantUnion(safeConstantUnion, TType(indexExpression->getType()));
5531 }
5532
5533 TIntermBinary *node =
5534 new TIntermBinary(EOpIndexDirect, baseExpression, indexExpression);
5535 node->setLine(location);
5536 return expressionOrFoldedResult(node);
5537 }
5538 }
5539
5540 markStaticReadIfSymbol(indexExpression);
5541 TIntermBinary *node = new TIntermBinary(EOpIndexIndirect, baseExpression, indexExpression);
5542 node->setLine(location);
5543 // Indirect indexing can never be constant folded.
5544 return node;
5545 }
5546
checkIndexLessThan(bool outOfRangeIndexIsError,const TSourceLoc & location,int index,unsigned int arraySize,const char * reason)5547 int TParseContext::checkIndexLessThan(bool outOfRangeIndexIsError,
5548 const TSourceLoc &location,
5549 int index,
5550 unsigned int arraySize,
5551 const char *reason)
5552 {
5553 // A negative index should already have been checked.
5554 ASSERT(index >= 0);
5555 if (static_cast<unsigned int>(index) >= arraySize)
5556 {
5557 std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
5558 reasonStream << reason << " '" << index << "'";
5559 std::string token = reasonStream.str();
5560 outOfRangeError(outOfRangeIndexIsError, location, reason, "[]");
5561 return arraySize - 1;
5562 }
5563 return index;
5564 }
5565
addFieldSelectionExpression(TIntermTyped * baseExpression,const TSourceLoc & dotLocation,const ImmutableString & fieldString,const TSourceLoc & fieldLocation)5566 TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression,
5567 const TSourceLoc &dotLocation,
5568 const ImmutableString &fieldString,
5569 const TSourceLoc &fieldLocation)
5570 {
5571 if (baseExpression->isArray())
5572 {
5573 error(fieldLocation, "cannot apply dot operator to an array", ".");
5574 return baseExpression;
5575 }
5576
5577 if (baseExpression->isVector())
5578 {
5579 TVector<int> fieldOffsets;
5580 if (!parseVectorFields(fieldLocation, fieldString, baseExpression->getNominalSize(),
5581 &fieldOffsets))
5582 {
5583 fieldOffsets.resize(1);
5584 fieldOffsets[0] = 0;
5585 }
5586 TIntermSwizzle *node = new TIntermSwizzle(baseExpression, fieldOffsets);
5587 node->setLine(dotLocation);
5588
5589 return node->fold(mDiagnostics);
5590 }
5591 else if (baseExpression->getBasicType() == EbtStruct)
5592 {
5593 const TFieldList &fields = baseExpression->getType().getStruct()->fields();
5594 if (fields.empty())
5595 {
5596 error(dotLocation, "structure has no fields", "Internal Error");
5597 return baseExpression;
5598 }
5599 else
5600 {
5601 bool fieldFound = false;
5602 unsigned int i;
5603 for (i = 0; i < fields.size(); ++i)
5604 {
5605 if (fields[i]->name() == fieldString)
5606 {
5607 fieldFound = true;
5608 break;
5609 }
5610 }
5611 if (fieldFound)
5612 {
5613 TIntermTyped *index = CreateIndexNode(i);
5614 index->setLine(fieldLocation);
5615 TIntermBinary *node =
5616 new TIntermBinary(EOpIndexDirectStruct, baseExpression, index);
5617 node->setLine(dotLocation);
5618 return expressionOrFoldedResult(node);
5619 }
5620 else
5621 {
5622 error(dotLocation, " no such field in structure", fieldString);
5623 return baseExpression;
5624 }
5625 }
5626 }
5627 else if (baseExpression->isInterfaceBlock())
5628 {
5629 const TFieldList &fields = baseExpression->getType().getInterfaceBlock()->fields();
5630 if (fields.empty())
5631 {
5632 error(dotLocation, "interface block has no fields", "Internal Error");
5633 return baseExpression;
5634 }
5635 else
5636 {
5637 bool fieldFound = false;
5638 unsigned int i;
5639 for (i = 0; i < fields.size(); ++i)
5640 {
5641 if (fields[i]->name() == fieldString)
5642 {
5643 fieldFound = true;
5644 break;
5645 }
5646 }
5647 if (fieldFound)
5648 {
5649 TIntermTyped *index = CreateIndexNode(i);
5650 index->setLine(fieldLocation);
5651 TIntermBinary *node =
5652 new TIntermBinary(EOpIndexDirectInterfaceBlock, baseExpression, index);
5653 node->setLine(dotLocation);
5654 // Indexing interface blocks can never be constant folded.
5655 return node;
5656 }
5657 else
5658 {
5659 error(dotLocation, " no such field in interface block", fieldString);
5660 return baseExpression;
5661 }
5662 }
5663 }
5664 else
5665 {
5666 if (mShaderVersion < 300)
5667 {
5668 error(dotLocation, " field selection requires structure or vector on left hand side",
5669 fieldString);
5670 }
5671 else
5672 {
5673 error(dotLocation,
5674 " field selection requires structure, vector, or interface block on left hand "
5675 "side",
5676 fieldString);
5677 }
5678 return baseExpression;
5679 }
5680 }
5681
parseLayoutQualifier(const ImmutableString & qualifierType,const TSourceLoc & qualifierTypeLine)5682 TLayoutQualifier TParseContext::parseLayoutQualifier(const ImmutableString &qualifierType,
5683 const TSourceLoc &qualifierTypeLine)
5684 {
5685 TLayoutQualifier qualifier = TLayoutQualifier::Create();
5686
5687 if (qualifierType == "shared")
5688 {
5689 if (sh::IsWebGLBasedSpec(mShaderSpec))
5690 {
5691 error(qualifierTypeLine, "Only std140 layout is allowed in WebGL", "shared");
5692 }
5693 qualifier.blockStorage = EbsShared;
5694 }
5695 else if (qualifierType == "packed")
5696 {
5697 if (sh::IsWebGLBasedSpec(mShaderSpec))
5698 {
5699 error(qualifierTypeLine, "Only std140 layout is allowed in WebGL", "packed");
5700 }
5701 qualifier.blockStorage = EbsPacked;
5702 }
5703 else if (qualifierType == "std430")
5704 {
5705 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5706 qualifier.blockStorage = EbsStd430;
5707 }
5708 else if (qualifierType == "std140")
5709 {
5710 qualifier.blockStorage = EbsStd140;
5711 }
5712 else if (qualifierType == "row_major")
5713 {
5714 qualifier.matrixPacking = EmpRowMajor;
5715 }
5716 else if (qualifierType == "column_major")
5717 {
5718 qualifier.matrixPacking = EmpColumnMajor;
5719 }
5720 else if (qualifierType == "location")
5721 {
5722 error(qualifierTypeLine, "invalid layout qualifier: location requires an argument",
5723 qualifierType);
5724 }
5725 else if (qualifierType == "yuv" && mShaderType == GL_FRAGMENT_SHADER)
5726 {
5727 if (checkCanUseExtension(qualifierTypeLine, TExtension::EXT_YUV_target))
5728 {
5729 qualifier.yuv = true;
5730 }
5731 }
5732 else if (qualifierType == "early_fragment_tests")
5733 {
5734 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5735 qualifier.earlyFragmentTests = true;
5736 }
5737 else if (qualifierType == "rgba32f")
5738 {
5739 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5740 qualifier.imageInternalFormat = EiifRGBA32F;
5741 }
5742 else if (qualifierType == "rgba16f")
5743 {
5744 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5745 qualifier.imageInternalFormat = EiifRGBA16F;
5746 }
5747 else if (qualifierType == "r32f")
5748 {
5749 if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
5750 {
5751 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5752 }
5753 qualifier.imageInternalFormat = EiifR32F;
5754 }
5755 else if (qualifierType == "rgba8")
5756 {
5757 if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
5758 {
5759 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5760 }
5761 qualifier.imageInternalFormat = EiifRGBA8;
5762 }
5763 else if (qualifierType == "rgba8_snorm")
5764 {
5765 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5766 qualifier.imageInternalFormat = EiifRGBA8_SNORM;
5767 }
5768 else if (qualifierType == "rgba32i")
5769 {
5770 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5771 qualifier.imageInternalFormat = EiifRGBA32I;
5772 }
5773 else if (qualifierType == "rgba16i")
5774 {
5775 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5776 qualifier.imageInternalFormat = EiifRGBA16I;
5777 }
5778 else if (qualifierType == "rgba8i")
5779 {
5780 if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
5781 {
5782 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5783 }
5784 qualifier.imageInternalFormat = EiifRGBA8I;
5785 }
5786 else if (qualifierType == "r32i")
5787 {
5788 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5789 qualifier.imageInternalFormat = EiifR32I;
5790 }
5791 else if (qualifierType == "rgba32ui")
5792 {
5793 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5794 qualifier.imageInternalFormat = EiifRGBA32UI;
5795 }
5796 else if (qualifierType == "rgba16ui")
5797 {
5798 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5799 qualifier.imageInternalFormat = EiifRGBA16UI;
5800 }
5801 else if (qualifierType == "rgba8ui")
5802 {
5803 if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
5804 {
5805 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5806 }
5807 qualifier.imageInternalFormat = EiifRGBA8UI;
5808 }
5809 else if (qualifierType == "r32ui")
5810 {
5811 if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
5812 {
5813 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
5814 }
5815 qualifier.imageInternalFormat = EiifR32UI;
5816 }
5817 else if (mShaderType == GL_GEOMETRY_SHADER_EXT &&
5818 (mShaderVersion >= 320 ||
5819 (checkCanUseOneOfExtensions(
5820 qualifierTypeLine,
5821 std::array<TExtension, 2u>{
5822 {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}}) &&
5823 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310))))
5824 {
5825 if (qualifierType == "points")
5826 {
5827 qualifier.primitiveType = EptPoints;
5828 }
5829 else if (qualifierType == "lines")
5830 {
5831 qualifier.primitiveType = EptLines;
5832 }
5833 else if (qualifierType == "lines_adjacency")
5834 {
5835 qualifier.primitiveType = EptLinesAdjacency;
5836 }
5837 else if (qualifierType == "triangles")
5838 {
5839 qualifier.primitiveType = EptTriangles;
5840 }
5841 else if (qualifierType == "triangles_adjacency")
5842 {
5843 qualifier.primitiveType = EptTrianglesAdjacency;
5844 }
5845 else if (qualifierType == "line_strip")
5846 {
5847 qualifier.primitiveType = EptLineStrip;
5848 }
5849 else if (qualifierType == "triangle_strip")
5850 {
5851 qualifier.primitiveType = EptTriangleStrip;
5852 }
5853 else
5854 {
5855 error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
5856 }
5857 }
5858 else if (mShaderType == GL_TESS_EVALUATION_SHADER_EXT &&
5859 (mShaderVersion >= 320 ||
5860 (checkCanUseOneOfExtensions(
5861 qualifierTypeLine,
5862 std::array<TExtension, 2u>{{TExtension::EXT_tessellation_shader,
5863 TExtension::OES_tessellation_shader}}) &&
5864 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310))))
5865 {
5866 if (qualifierType == "triangles")
5867 {
5868 qualifier.tesPrimitiveType = EtetTriangles;
5869 }
5870 else if (qualifierType == "quads")
5871 {
5872 qualifier.tesPrimitiveType = EtetQuads;
5873 }
5874 else if (qualifierType == "isolines")
5875 {
5876 qualifier.tesPrimitiveType = EtetIsolines;
5877 }
5878 else if (qualifierType == "equal_spacing")
5879 {
5880 qualifier.tesVertexSpacingType = EtetEqualSpacing;
5881 }
5882 else if (qualifierType == "fractional_even_spacing")
5883 {
5884 qualifier.tesVertexSpacingType = EtetFractionalEvenSpacing;
5885 }
5886 else if (qualifierType == "fractional_odd_spacing")
5887 {
5888 qualifier.tesVertexSpacingType = EtetFractionalOddSpacing;
5889 }
5890 else if (qualifierType == "cw")
5891 {
5892 qualifier.tesOrderingType = EtetCw;
5893 }
5894 else if (qualifierType == "ccw")
5895 {
5896 qualifier.tesOrderingType = EtetCcw;
5897 }
5898 else if (qualifierType == "point_mode")
5899 {
5900 qualifier.tesPointType = EtetPointMode;
5901 }
5902 else
5903 {
5904 error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
5905 }
5906 }
5907 else if (mShaderType == GL_FRAGMENT_SHADER)
5908 {
5909 if (qualifierType == "noncoherent")
5910 {
5911 if (checkCanUseOneOfExtensions(
5912 qualifierTypeLine,
5913 std::array<TExtension, 2u>{
5914 {TExtension::EXT_shader_framebuffer_fetch,
5915 TExtension::EXT_shader_framebuffer_fetch_non_coherent}}))
5916 {
5917 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 100);
5918 qualifier.noncoherent = true;
5919 }
5920 }
5921 else if (qualifierType == "blend_support_multiply")
5922 {
5923 AddAdvancedBlendEquation(gl::BlendEquationType::Multiply, &qualifier);
5924 }
5925 else if (qualifierType == "blend_support_screen")
5926 {
5927 AddAdvancedBlendEquation(gl::BlendEquationType::Screen, &qualifier);
5928 }
5929 else if (qualifierType == "blend_support_overlay")
5930 {
5931 AddAdvancedBlendEquation(gl::BlendEquationType::Overlay, &qualifier);
5932 }
5933 else if (qualifierType == "blend_support_darken")
5934 {
5935 AddAdvancedBlendEquation(gl::BlendEquationType::Darken, &qualifier);
5936 }
5937 else if (qualifierType == "blend_support_lighten")
5938 {
5939 AddAdvancedBlendEquation(gl::BlendEquationType::Lighten, &qualifier);
5940 }
5941 else if (qualifierType == "blend_support_colordodge")
5942 {
5943 AddAdvancedBlendEquation(gl::BlendEquationType::Colordodge, &qualifier);
5944 }
5945 else if (qualifierType == "blend_support_colorburn")
5946 {
5947 AddAdvancedBlendEquation(gl::BlendEquationType::Colorburn, &qualifier);
5948 }
5949 else if (qualifierType == "blend_support_hardlight")
5950 {
5951 AddAdvancedBlendEquation(gl::BlendEquationType::Hardlight, &qualifier);
5952 }
5953 else if (qualifierType == "blend_support_softlight")
5954 {
5955 AddAdvancedBlendEquation(gl::BlendEquationType::Softlight, &qualifier);
5956 }
5957 else if (qualifierType == "blend_support_difference")
5958 {
5959 AddAdvancedBlendEquation(gl::BlendEquationType::Difference, &qualifier);
5960 }
5961 else if (qualifierType == "blend_support_exclusion")
5962 {
5963 AddAdvancedBlendEquation(gl::BlendEquationType::Exclusion, &qualifier);
5964 }
5965 else if (qualifierType == "blend_support_hsl_hue")
5966 {
5967 AddAdvancedBlendEquation(gl::BlendEquationType::HslHue, &qualifier);
5968 }
5969 else if (qualifierType == "blend_support_hsl_saturation")
5970 {
5971 AddAdvancedBlendEquation(gl::BlendEquationType::HslSaturation, &qualifier);
5972 }
5973 else if (qualifierType == "blend_support_hsl_color")
5974 {
5975 AddAdvancedBlendEquation(gl::BlendEquationType::HslColor, &qualifier);
5976 }
5977 else if (qualifierType == "blend_support_hsl_luminosity")
5978 {
5979 AddAdvancedBlendEquation(gl::BlendEquationType::HslLuminosity, &qualifier);
5980 }
5981 else if (qualifierType == "blend_support_all_equations")
5982 {
5983 qualifier.advancedBlendEquations.setAll();
5984 }
5985 else if (qualifierType == "depth_any")
5986 {
5987 qualifier.depth = EdAny;
5988 }
5989 else if (qualifierType == "depth_greater")
5990 {
5991 qualifier.depth = EdGreater;
5992 }
5993 else if (qualifierType == "depth_less")
5994 {
5995 qualifier.depth = EdLess;
5996 }
5997 else if (qualifierType == "depth_unchanged" && !sh::IsWebGLBasedSpec(mShaderSpec))
5998 {
5999 qualifier.depth = EdUnchanged;
6000 }
6001 else
6002 {
6003 error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
6004 }
6005
6006 if (qualifier.advancedBlendEquations.any() && mShaderVersion < 320)
6007 {
6008 if (!checkCanUseExtension(qualifierTypeLine, TExtension::KHR_blend_equation_advanced))
6009 {
6010 qualifier.advancedBlendEquations.reset();
6011 }
6012 }
6013 }
6014 else
6015 {
6016 error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
6017 }
6018
6019 return qualifier;
6020 }
6021
parseLocalSize(const ImmutableString & qualifierType,const TSourceLoc & qualifierTypeLine,int intValue,const TSourceLoc & intValueLine,const std::string & intValueString,size_t index,sh::WorkGroupSize * localSize)6022 void TParseContext::parseLocalSize(const ImmutableString &qualifierType,
6023 const TSourceLoc &qualifierTypeLine,
6024 int intValue,
6025 const TSourceLoc &intValueLine,
6026 const std::string &intValueString,
6027 size_t index,
6028 sh::WorkGroupSize *localSize)
6029 {
6030 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
6031 if (intValue < 1)
6032 {
6033 std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
6034 reasonStream << "out of range: " << getWorkGroupSizeString(index) << " must be positive";
6035 std::string reason = reasonStream.str();
6036 error(intValueLine, reason.c_str(), intValueString.c_str());
6037 }
6038 (*localSize)[index] = intValue;
6039 }
6040
parseNumViews(int intValue,const TSourceLoc & intValueLine,const std::string & intValueString,int * numViews)6041 void TParseContext::parseNumViews(int intValue,
6042 const TSourceLoc &intValueLine,
6043 const std::string &intValueString,
6044 int *numViews)
6045 {
6046 // This error is only specified in WebGL, but tightens unspecified behavior in the native
6047 // specification.
6048 if (intValue < 1)
6049 {
6050 error(intValueLine, "out of range: num_views must be positive", intValueString.c_str());
6051 }
6052 *numViews = intValue;
6053 }
6054
parseInvocations(int intValue,const TSourceLoc & intValueLine,const std::string & intValueString,int * numInvocations)6055 void TParseContext::parseInvocations(int intValue,
6056 const TSourceLoc &intValueLine,
6057 const std::string &intValueString,
6058 int *numInvocations)
6059 {
6060 // Although SPEC isn't clear whether invocations can be less than 1, we add this limit because
6061 // it doesn't make sense to accept invocations <= 0.
6062 if (intValue < 1 || intValue > mMaxGeometryShaderInvocations)
6063 {
6064 error(intValueLine,
6065 "out of range: invocations must be in the range of [1, "
6066 "MAX_GEOMETRY_SHADER_INVOCATIONS_OES]",
6067 intValueString.c_str());
6068 }
6069 else
6070 {
6071 *numInvocations = intValue;
6072 }
6073 }
6074
parseMaxVertices(int intValue,const TSourceLoc & intValueLine,const std::string & intValueString,int * maxVertices)6075 void TParseContext::parseMaxVertices(int intValue,
6076 const TSourceLoc &intValueLine,
6077 const std::string &intValueString,
6078 int *maxVertices)
6079 {
6080 // Although SPEC isn't clear whether max_vertices can be less than 0, we add this limit because
6081 // it doesn't make sense to accept max_vertices < 0.
6082 if (intValue < 0 || intValue > mMaxGeometryShaderMaxVertices)
6083 {
6084 error(
6085 intValueLine,
6086 "out of range: max_vertices must be in the range of [0, gl_MaxGeometryOutputVertices]",
6087 intValueString.c_str());
6088 }
6089 else
6090 {
6091 *maxVertices = intValue;
6092 }
6093 }
6094
parseVertices(int intValue,const TSourceLoc & intValueLine,const std::string & intValueString,int * vertices)6095 void TParseContext::parseVertices(int intValue,
6096 const TSourceLoc &intValueLine,
6097 const std::string &intValueString,
6098 int *vertices)
6099 {
6100 if (intValue < 1 || intValue > mMaxPatchVertices)
6101 {
6102 error(intValueLine,
6103 "out of range : vertices must be in the range of [1, gl_MaxPatchVertices]",
6104 intValueString.c_str());
6105 }
6106 else
6107 {
6108 *vertices = intValue;
6109 }
6110 }
6111
parseIndexLayoutQualifier(int intValue,const TSourceLoc & intValueLine,const std::string & intValueString,int * index)6112 void TParseContext::parseIndexLayoutQualifier(int intValue,
6113 const TSourceLoc &intValueLine,
6114 const std::string &intValueString,
6115 int *index)
6116 {
6117 // EXT_blend_func_extended specifies that most validation should happen at link time, but since
6118 // we're validating output variable locations at compile time, it makes sense to validate that
6119 // index is 0 or 1 also at compile time. Also since we use "-1" as a placeholder for unspecified
6120 // index, we can't accept it here.
6121 if (intValue < 0 || intValue > 1)
6122 {
6123 error(intValueLine, "out of range: index layout qualifier can only be 0 or 1",
6124 intValueString.c_str());
6125 }
6126 else
6127 {
6128 *index = intValue;
6129 }
6130 }
6131
parseLayoutQualifier(const ImmutableString & qualifierType,const TSourceLoc & qualifierTypeLine,int intValue,const TSourceLoc & intValueLine)6132 TLayoutQualifier TParseContext::parseLayoutQualifier(const ImmutableString &qualifierType,
6133 const TSourceLoc &qualifierTypeLine,
6134 int intValue,
6135 const TSourceLoc &intValueLine)
6136 {
6137 TLayoutQualifier qualifier = TLayoutQualifier::Create();
6138
6139 std::string intValueString = Str(intValue);
6140
6141 if (qualifierType == "location")
6142 {
6143 // must check that location is non-negative
6144 if (intValue < 0)
6145 {
6146 error(intValueLine, "out of range: location must be non-negative",
6147 intValueString.c_str());
6148 }
6149 else
6150 {
6151 qualifier.location = intValue;
6152 qualifier.locationsSpecified = 1;
6153 }
6154 }
6155 else if (qualifierType == "binding")
6156 {
6157 if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
6158 {
6159 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
6160 }
6161 if (intValue < 0)
6162 {
6163 error(intValueLine, "out of range: binding must be non-negative",
6164 intValueString.c_str());
6165 }
6166 else
6167 {
6168 qualifier.binding = intValue;
6169 }
6170 }
6171 else if (qualifierType == "offset")
6172 {
6173 checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
6174 if (intValue < 0)
6175 {
6176 error(intValueLine, "out of range: offset must be non-negative",
6177 intValueString.c_str());
6178 }
6179 else
6180 {
6181 qualifier.offset = intValue;
6182 }
6183 }
6184 else if (qualifierType == "local_size_x")
6185 {
6186 parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 0u,
6187 &qualifier.localSize);
6188 }
6189 else if (qualifierType == "local_size_y")
6190 {
6191 parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 1u,
6192 &qualifier.localSize);
6193 }
6194 else if (qualifierType == "local_size_z")
6195 {
6196 parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 2u,
6197 &qualifier.localSize);
6198 }
6199 else if (qualifierType == "num_views" && mShaderType == GL_VERTEX_SHADER)
6200 {
6201 if (checkCanUseOneOfExtensions(
6202 qualifierTypeLine, std::array<TExtension, 2u>{
6203 {TExtension::OVR_multiview, TExtension::OVR_multiview2}}))
6204 {
6205 parseNumViews(intValue, intValueLine, intValueString, &qualifier.numViews);
6206 }
6207 }
6208 else if (qualifierType == "invocations" && mShaderType == GL_GEOMETRY_SHADER_EXT &&
6209 (mShaderVersion >= 320 ||
6210 checkCanUseOneOfExtensions(
6211 qualifierTypeLine,
6212 std::array<TExtension, 2u>{
6213 {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}})))
6214 {
6215 parseInvocations(intValue, intValueLine, intValueString, &qualifier.invocations);
6216 }
6217 else if (qualifierType == "max_vertices" && mShaderType == GL_GEOMETRY_SHADER_EXT &&
6218 (mShaderVersion >= 320 ||
6219 checkCanUseOneOfExtensions(
6220 qualifierTypeLine,
6221 std::array<TExtension, 2u>{
6222 {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}})))
6223 {
6224 parseMaxVertices(intValue, intValueLine, intValueString, &qualifier.maxVertices);
6225 }
6226 else if (qualifierType == "index" && mShaderType == GL_FRAGMENT_SHADER &&
6227 checkCanUseExtension(qualifierTypeLine, TExtension::EXT_blend_func_extended))
6228 {
6229 parseIndexLayoutQualifier(intValue, intValueLine, intValueString, &qualifier.index);
6230 if (intValue != 0)
6231 {
6232 errorIfPLSDeclared(qualifierTypeLine, PLSIllegalOperations::FragDataIndexNonzero);
6233 }
6234 }
6235 else if (qualifierType == "vertices" && mShaderType == GL_TESS_CONTROL_SHADER_EXT &&
6236 (mShaderVersion >= 320 ||
6237 checkCanUseOneOfExtensions(
6238 qualifierTypeLine,
6239 std::array<TExtension, 2u>{
6240 {TExtension::EXT_tessellation_shader, TExtension::OES_tessellation_shader}})))
6241 {
6242 parseVertices(intValue, intValueLine, intValueString, &qualifier.vertices);
6243 }
6244 else
6245 {
6246 error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
6247 }
6248
6249 return qualifier;
6250 }
6251
createTypeQualifierBuilder(const TSourceLoc & loc)6252 TTypeQualifierBuilder *TParseContext::createTypeQualifierBuilder(const TSourceLoc &loc)
6253 {
6254 return new TTypeQualifierBuilder(
6255 new TStorageQualifierWrapper(symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary, loc),
6256 mShaderVersion);
6257 }
6258
parseGlobalStorageQualifier(TQualifier qualifier,const TSourceLoc & loc)6259 TStorageQualifierWrapper *TParseContext::parseGlobalStorageQualifier(TQualifier qualifier,
6260 const TSourceLoc &loc)
6261 {
6262 checkIsAtGlobalLevel(loc, getQualifierString(qualifier));
6263 return new TStorageQualifierWrapper(qualifier, loc);
6264 }
6265
parseVaryingQualifier(const TSourceLoc & loc)6266 TStorageQualifierWrapper *TParseContext::parseVaryingQualifier(const TSourceLoc &loc)
6267 {
6268 if (getShaderType() == GL_VERTEX_SHADER)
6269 {
6270 return parseGlobalStorageQualifier(EvqVaryingOut, loc);
6271 }
6272 return parseGlobalStorageQualifier(EvqVaryingIn, loc);
6273 }
6274
parseInQualifier(const TSourceLoc & loc)6275 TStorageQualifierWrapper *TParseContext::parseInQualifier(const TSourceLoc &loc)
6276 {
6277 if (declaringFunction())
6278 {
6279 return new TStorageQualifierWrapper(EvqParamIn, loc);
6280 }
6281
6282 switch (getShaderType())
6283 {
6284 case GL_VERTEX_SHADER:
6285 {
6286 if (mShaderVersion < 300 && !anyMultiviewExtensionAvailable())
6287 {
6288 error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "in");
6289 }
6290 return new TStorageQualifierWrapper(EvqVertexIn, loc);
6291 }
6292 case GL_FRAGMENT_SHADER:
6293 {
6294 if (mShaderVersion < 300)
6295 {
6296 error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "in");
6297 }
6298 return new TStorageQualifierWrapper(EvqFragmentIn, loc);
6299 }
6300 case GL_COMPUTE_SHADER:
6301 {
6302 return new TStorageQualifierWrapper(EvqComputeIn, loc);
6303 }
6304 case GL_GEOMETRY_SHADER:
6305 {
6306 return new TStorageQualifierWrapper(EvqGeometryIn, loc);
6307 }
6308 case GL_TESS_CONTROL_SHADER:
6309 {
6310 return new TStorageQualifierWrapper(EvqTessControlIn, loc);
6311 }
6312 case GL_TESS_EVALUATION_SHADER:
6313 {
6314 return new TStorageQualifierWrapper(EvqTessEvaluationIn, loc);
6315 }
6316 default:
6317 {
6318 UNREACHABLE();
6319 return new TStorageQualifierWrapper(EvqLast, loc);
6320 }
6321 }
6322 }
6323
parseOutQualifier(const TSourceLoc & loc)6324 TStorageQualifierWrapper *TParseContext::parseOutQualifier(const TSourceLoc &loc)
6325 {
6326 if (declaringFunction())
6327 {
6328 return new TStorageQualifierWrapper(EvqParamOut, loc);
6329 }
6330 switch (getShaderType())
6331 {
6332 case GL_VERTEX_SHADER:
6333 {
6334 if (mShaderVersion < 300)
6335 {
6336 error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "out");
6337 }
6338 return new TStorageQualifierWrapper(EvqVertexOut, loc);
6339 }
6340 case GL_FRAGMENT_SHADER:
6341 {
6342 if (mShaderVersion < 300)
6343 {
6344 error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "out");
6345 }
6346 return new TStorageQualifierWrapper(EvqFragmentOut, loc);
6347 }
6348 case GL_COMPUTE_SHADER:
6349 {
6350 error(loc, "storage qualifier isn't supported in compute shaders", "out");
6351 return new TStorageQualifierWrapper(EvqParamOut, loc);
6352 }
6353 case GL_GEOMETRY_SHADER_EXT:
6354 {
6355 return new TStorageQualifierWrapper(EvqGeometryOut, loc);
6356 }
6357 case GL_TESS_CONTROL_SHADER_EXT:
6358 {
6359 return new TStorageQualifierWrapper(EvqTessControlOut, loc);
6360 }
6361 case GL_TESS_EVALUATION_SHADER_EXT:
6362 {
6363 return new TStorageQualifierWrapper(EvqTessEvaluationOut, loc);
6364 }
6365 default:
6366 {
6367 UNREACHABLE();
6368 return new TStorageQualifierWrapper(EvqLast, loc);
6369 }
6370 }
6371 }
6372
parseInOutQualifier(const TSourceLoc & loc)6373 TStorageQualifierWrapper *TParseContext::parseInOutQualifier(const TSourceLoc &loc)
6374 {
6375 if (!declaringFunction())
6376 {
6377 if (mShaderVersion < 300)
6378 {
6379 error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "inout");
6380 }
6381
6382 if (getShaderType() != GL_FRAGMENT_SHADER)
6383 {
6384 error(loc, "storage qualifier isn't supported in non-fragment shaders", "inout");
6385 }
6386
6387 if (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch) ||
6388 isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent))
6389 {
6390 return new TStorageQualifierWrapper(EvqFragmentInOut, loc);
6391 }
6392
6393 error(loc,
6394 "invalid qualifier: can be used with either function parameters or the variables for "
6395 "fetching input attachment data",
6396 "inout");
6397 }
6398 return new TStorageQualifierWrapper(EvqParamInOut, loc);
6399 }
6400
joinLayoutQualifiers(TLayoutQualifier leftQualifier,TLayoutQualifier rightQualifier,const TSourceLoc & rightQualifierLocation)6401 TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier,
6402 TLayoutQualifier rightQualifier,
6403 const TSourceLoc &rightQualifierLocation)
6404 {
6405 return sh::JoinLayoutQualifiers(leftQualifier, rightQualifier, rightQualifierLocation,
6406 mDiagnostics);
6407 }
6408
parseStructDeclarator(const ImmutableString & identifier,const TSourceLoc & loc)6409 TDeclarator *TParseContext::parseStructDeclarator(const ImmutableString &identifier,
6410 const TSourceLoc &loc)
6411 {
6412 return new TDeclarator(identifier, loc);
6413 }
6414
parseStructArrayDeclarator(const ImmutableString & identifier,const TSourceLoc & loc,const TVector<unsigned int> * arraySizes)6415 TDeclarator *TParseContext::parseStructArrayDeclarator(const ImmutableString &identifier,
6416 const TSourceLoc &loc,
6417 const TVector<unsigned int> *arraySizes)
6418 {
6419 return new TDeclarator(identifier, arraySizes, loc);
6420 }
6421
checkDoesNotHaveDuplicateFieldNames(const TFieldList * fields,const TSourceLoc & location)6422 void TParseContext::checkDoesNotHaveDuplicateFieldNames(const TFieldList *fields,
6423 const TSourceLoc &location)
6424 {
6425 TUnorderedMap<ImmutableString, uint32_t, ImmutableString::FowlerNollVoHash<sizeof(size_t)>>
6426 fieldNames;
6427 for (TField *field : *fields)
6428 {
6429 // Note: operator[] adds this name to the map if it doesn't already exist, and initializes
6430 // its value to 0.
6431 uint32_t count = ++fieldNames[field->name()];
6432 if (count != 1)
6433 {
6434 error(location, "Duplicate field name in structure", field->name());
6435 }
6436 }
6437 }
6438
checkDoesNotHaveTooManyFields(const ImmutableString & name,const TFieldList * fields,const TSourceLoc & location)6439 void TParseContext::checkDoesNotHaveTooManyFields(const ImmutableString &name,
6440 const TFieldList *fields,
6441 const TSourceLoc &location)
6442 {
6443 // Check that there are not too many fields. SPIR-V has a limit of 16383 fields, and it would
6444 // be reasonable to apply that limit to all outputs. For example, it was observed that 32768
6445 // fields cause the Nvidia GL driver to fail compilation, so such a limit is not too specific to
6446 // SPIR-V.
6447 constexpr size_t kMaxFieldCount = 16383;
6448 if (fields->size() > kMaxFieldCount)
6449 {
6450 error(location, "Too many fields in the struct (limit is 16383)", name);
6451 }
6452 }
6453
addStructFieldList(TFieldList * fields,const TSourceLoc & location)6454 TFieldList *TParseContext::addStructFieldList(TFieldList *fields, const TSourceLoc &location)
6455 {
6456 return fields;
6457 }
6458
combineStructFieldLists(TFieldList * processedFields,const TFieldList * newlyAddedFields,const TSourceLoc & location)6459 TFieldList *TParseContext::combineStructFieldLists(TFieldList *processedFields,
6460 const TFieldList *newlyAddedFields,
6461 const TSourceLoc &location)
6462 {
6463 processedFields->insert(processedFields->end(), newlyAddedFields->begin(),
6464 newlyAddedFields->end());
6465 return processedFields;
6466 }
6467
addStructDeclaratorListWithQualifiers(const TTypeQualifierBuilder & typeQualifierBuilder,TPublicType * typeSpecifier,const TDeclaratorList * declaratorList)6468 TFieldList *TParseContext::addStructDeclaratorListWithQualifiers(
6469 const TTypeQualifierBuilder &typeQualifierBuilder,
6470 TPublicType *typeSpecifier,
6471 const TDeclaratorList *declaratorList)
6472 {
6473 TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
6474
6475 typeSpecifier->qualifier = typeQualifier.qualifier;
6476 typeSpecifier->layoutQualifier = typeQualifier.layoutQualifier;
6477 typeSpecifier->memoryQualifier = typeQualifier.memoryQualifier;
6478 typeSpecifier->invariant = typeQualifier.invariant;
6479 typeSpecifier->precise = typeQualifier.precise;
6480 if (typeQualifier.precision != EbpUndefined)
6481 {
6482 typeSpecifier->precision = typeQualifier.precision;
6483 }
6484 return addStructDeclaratorList(*typeSpecifier, declaratorList);
6485 }
6486
addStructDeclaratorList(const TPublicType & typeSpecifier,const TDeclaratorList * declaratorList)6487 TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecifier,
6488 const TDeclaratorList *declaratorList)
6489 {
6490 checkPrecisionSpecified(typeSpecifier.getLine(), typeSpecifier.precision,
6491 typeSpecifier.getBasicType());
6492
6493 checkIsNonVoid(typeSpecifier.getLine(), (*declaratorList)[0]->name(),
6494 typeSpecifier.getBasicType());
6495
6496 checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), typeSpecifier.layoutQualifier);
6497 checkEarlyFragmentTestsIsNotSpecified(typeSpecifier.getLine(),
6498 typeSpecifier.layoutQualifier.earlyFragmentTests);
6499 checkNoncoherentIsNotSpecified(typeSpecifier.getLine(),
6500 typeSpecifier.layoutQualifier.noncoherent);
6501
6502 TFieldList *fieldList = new TFieldList();
6503
6504 for (const TDeclarator *declarator : *declaratorList)
6505 {
6506 TType *type = new TType(typeSpecifier);
6507 if (declarator->isArray())
6508 {
6509 // Don't allow arrays of arrays in ESSL < 3.10.
6510 checkArrayElementIsNotArray(typeSpecifier.getLine(), typeSpecifier);
6511 type->makeArrays(*declarator->arraySizes());
6512 }
6513
6514 SymbolType symbolType = SymbolType::UserDefined;
6515 if (declarator->name() == "gl_Position" || declarator->name() == "gl_PointSize" ||
6516 declarator->name() == "gl_ClipDistance" || declarator->name() == "gl_CullDistance")
6517 {
6518 symbolType = SymbolType::BuiltIn;
6519 }
6520 else
6521 {
6522 checkIsNotReserved(typeSpecifier.getLine(), declarator->name());
6523 }
6524 TField *field = new TField(type, declarator->name(), declarator->line(), symbolType);
6525 checkIsBelowStructNestingLimit(typeSpecifier.getLine(), *field);
6526 fieldList->push_back(field);
6527 }
6528
6529 return fieldList;
6530 }
6531
addStructure(const TSourceLoc & structLine,const TSourceLoc & nameLine,const ImmutableString & structName,TFieldList * fieldList)6532 TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine,
6533 const TSourceLoc &nameLine,
6534 const ImmutableString &structName,
6535 TFieldList *fieldList)
6536 {
6537 SymbolType structSymbolType = SymbolType::UserDefined;
6538 if (structName.empty())
6539 {
6540 structSymbolType = SymbolType::Empty;
6541 }
6542
6543 // To simplify pulling samplers out of structs, reorder the struct fields to put the samplers at
6544 // the end.
6545 TFieldList *reorderedFields = new TFieldList;
6546 for (TField *field : *fieldList)
6547 {
6548 if (!IsSampler(field->type()->getBasicType()))
6549 {
6550 reorderedFields->push_back(field);
6551 }
6552 }
6553 for (TField *field : *fieldList)
6554 {
6555 if (IsSampler(field->type()->getBasicType()))
6556 {
6557 reorderedFields->push_back(field);
6558 }
6559 }
6560
6561 TStructure *structure =
6562 new TStructure(&symbolTable, structName, reorderedFields, structSymbolType);
6563
6564 // Store a bool in the struct if we're at global scope, to allow us to
6565 // skip the local struct scoping workaround in HLSL.
6566 structure->setAtGlobalScope(symbolTable.atGlobalLevel());
6567
6568 if (structSymbolType != SymbolType::Empty)
6569 {
6570 checkIsNotReserved(nameLine, structName);
6571 if (!symbolTable.declare(structure))
6572 {
6573 error(nameLine, "redefinition of a struct", structName);
6574 }
6575 }
6576
6577 checkDoesNotHaveTooManyFields(structName, fieldList, structLine);
6578
6579 // Ensure there are no duplicate field names
6580 checkDoesNotHaveDuplicateFieldNames(fieldList, structLine);
6581
6582 // Ensure we do not specify any storage qualifiers on the struct members
6583 for (unsigned int typeListIndex = 0; typeListIndex < fieldList->size(); typeListIndex++)
6584 {
6585 TField &field = *(*fieldList)[typeListIndex];
6586 const TQualifier qualifier = field.type()->getQualifier();
6587 switch (qualifier)
6588 {
6589 case EvqGlobal:
6590 case EvqTemporary:
6591 break;
6592 default:
6593 error(field.line(), "invalid qualifier on struct member",
6594 getQualifierString(qualifier));
6595 break;
6596 }
6597 if (field.type()->isInvariant())
6598 {
6599 error(field.line(), "invalid qualifier on struct member", "invariant");
6600 }
6601
6602 const TLayoutQualifier layoutQualifier = field.type()->getLayoutQualifier();
6603 if (!layoutQualifier.isEmpty())
6604 {
6605 error(field.line(), "invalid layout qualifier on struct member", "layout");
6606 }
6607
6608 const TMemoryQualifier memoryQualifier = field.type()->getMemoryQualifier();
6609 if (!memoryQualifier.isEmpty())
6610 {
6611 error(field.line(), "invalid memory qualifier on struct member",
6612 memoryQualifier.getAnyQualifierString());
6613 }
6614
6615 if (field.type()->isPrecise())
6616 {
6617 error(field.line(), "invalid precise qualifier on struct member", "precise");
6618 }
6619
6620 // ESSL 3.10 section 4.1.8 -- atomic_uint or images are not allowed as structure member.
6621 // ANGLE_shader_pixel_local_storage also disallows PLS as struct members.
6622 if (IsImage(field.type()->getBasicType()) ||
6623 IsAtomicCounter(field.type()->getBasicType()) ||
6624 IsPixelLocal(field.type()->getBasicType()))
6625 {
6626 error(field.line(), "disallowed type in struct", field.type()->getBasicString());
6627 }
6628
6629 checkIsNotUnsizedArray(field.line(), "array members of structs must specify a size",
6630 field.name(), field.type());
6631
6632 checkMemoryQualifierIsNotSpecified(field.type()->getMemoryQualifier(), field.line());
6633
6634 checkIndexIsNotSpecified(field.line(), field.type()->getLayoutQualifier().index);
6635
6636 checkBindingIsNotSpecified(field.line(), field.type()->getLayoutQualifier().binding);
6637
6638 checkLocationIsNotSpecified(field.line(), field.type()->getLayoutQualifier());
6639 }
6640
6641 TTypeSpecifierNonArray typeSpecifierNonArray;
6642 typeSpecifierNonArray.initializeStruct(structure, true, structLine);
6643 exitStructDeclaration();
6644
6645 return typeSpecifierNonArray;
6646 }
6647
addSwitch(TIntermTyped * init,TIntermBlock * statementList,const TSourceLoc & loc)6648 TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init,
6649 TIntermBlock *statementList,
6650 const TSourceLoc &loc)
6651 {
6652 TBasicType switchType = init->getBasicType();
6653 if ((switchType != EbtInt && switchType != EbtUInt) || init->isMatrix() || init->isArray() ||
6654 init->isVector())
6655 {
6656 error(init->getLine(), "init-expression in a switch statement must be a scalar integer",
6657 "switch");
6658 return nullptr;
6659 }
6660
6661 ASSERT(statementList);
6662 if (!ValidateSwitchStatementList(switchType, mDiagnostics, statementList, loc))
6663 {
6664 ASSERT(mDiagnostics->numErrors() > 0);
6665 return nullptr;
6666 }
6667
6668 markStaticReadIfSymbol(init);
6669 TIntermSwitch *node = new TIntermSwitch(init, statementList);
6670 node->setLine(loc);
6671 return node;
6672 }
6673
addCase(TIntermTyped * condition,const TSourceLoc & loc)6674 TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &loc)
6675 {
6676 if (mSwitchNestingLevel == 0)
6677 {
6678 error(loc, "case labels need to be inside switch statements", "case");
6679 return nullptr;
6680 }
6681 if (condition == nullptr)
6682 {
6683 error(loc, "case label must have a condition", "case");
6684 return nullptr;
6685 }
6686 if ((condition->getBasicType() != EbtInt && condition->getBasicType() != EbtUInt) ||
6687 condition->isMatrix() || condition->isArray() || condition->isVector())
6688 {
6689 error(condition->getLine(), "case label must be a scalar integer", "case");
6690 }
6691 TIntermConstantUnion *conditionConst = condition->getAsConstantUnion();
6692 // ANGLE should be able to fold any EvqConst expressions resulting in an integer - but to be
6693 // safe against corner cases we still check for conditionConst. Some interpretations of the
6694 // spec have allowed constant expressions with side effects - like array length() method on a
6695 // non-constant array.
6696 if (condition->getQualifier() != EvqConst || conditionConst == nullptr)
6697 {
6698 error(condition->getLine(), "case label must be constant", "case");
6699 }
6700 TIntermCase *node = new TIntermCase(condition);
6701 node->setLine(loc);
6702 return node;
6703 }
6704
addDefault(const TSourceLoc & loc)6705 TIntermCase *TParseContext::addDefault(const TSourceLoc &loc)
6706 {
6707 if (mSwitchNestingLevel == 0)
6708 {
6709 error(loc, "default labels need to be inside switch statements", "default");
6710 return nullptr;
6711 }
6712 TIntermCase *node = new TIntermCase(nullptr);
6713 node->setLine(loc);
6714 return node;
6715 }
6716
createUnaryMath(TOperator op,TIntermTyped * child,const TSourceLoc & loc,const TFunction * func)6717 TIntermTyped *TParseContext::createUnaryMath(TOperator op,
6718 TIntermTyped *child,
6719 const TSourceLoc &loc,
6720 const TFunction *func)
6721 {
6722 ASSERT(child != nullptr);
6723
6724 switch (op)
6725 {
6726 case EOpLogicalNot:
6727 if (child->getBasicType() != EbtBool || child->isMatrix() || child->isArray() ||
6728 child->isVector())
6729 {
6730 unaryOpError(loc, GetOperatorString(op), child->getType());
6731 return nullptr;
6732 }
6733 break;
6734 case EOpBitwiseNot:
6735 if ((child->getBasicType() != EbtInt && child->getBasicType() != EbtUInt) ||
6736 child->isMatrix() || child->isArray())
6737 {
6738 unaryOpError(loc, GetOperatorString(op), child->getType());
6739 return nullptr;
6740 }
6741 break;
6742 case EOpPostIncrement:
6743 case EOpPreIncrement:
6744 case EOpPostDecrement:
6745 case EOpPreDecrement:
6746 case EOpNegative:
6747 case EOpPositive:
6748 if (child->getBasicType() == EbtStruct || child->isInterfaceBlock() ||
6749 child->getBasicType() == EbtBool || child->isArray() ||
6750 child->getBasicType() == EbtVoid || IsOpaqueType(child->getBasicType()))
6751 {
6752 unaryOpError(loc, GetOperatorString(op), child->getType());
6753 return nullptr;
6754 }
6755 break;
6756 // Operators for math built-ins are already type checked against their prototype.
6757 default:
6758 break;
6759 }
6760
6761 if (child->getMemoryQualifier().writeonly)
6762 {
6763 const char *opStr =
6764 BuiltInGroup::IsBuiltIn(op) ? func->name().data() : GetOperatorString(op);
6765 unaryOpError(loc, opStr, child->getType());
6766 return nullptr;
6767 }
6768
6769 markStaticReadIfSymbol(child);
6770 TIntermUnary *node = new TIntermUnary(op, child, func);
6771 node->setLine(loc);
6772
6773 return node->fold(mDiagnostics);
6774 }
6775
addUnaryMath(TOperator op,TIntermTyped * child,const TSourceLoc & loc)6776 TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
6777 {
6778 ASSERT(op != EOpNull);
6779 TIntermTyped *node = createUnaryMath(op, child, loc, nullptr);
6780 if (node == nullptr)
6781 {
6782 return child;
6783 }
6784 return node;
6785 }
6786
addUnaryMathLValue(TOperator op,TIntermTyped * child,const TSourceLoc & loc)6787 TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op,
6788 TIntermTyped *child,
6789 const TSourceLoc &loc)
6790 {
6791 checkCanBeLValue(loc, GetOperatorString(op), child);
6792 return addUnaryMath(op, child, loc);
6793 }
6794
expressionOrFoldedResult(TIntermTyped * expression)6795 TIntermTyped *TParseContext::expressionOrFoldedResult(TIntermTyped *expression)
6796 {
6797 // If we can, we should return the folded version of the expression for subsequent parsing. This
6798 // enables folding the containing expression during parsing as well, instead of the separate
6799 // FoldExpressions() step where folding nested expressions requires multiple full AST
6800 // traversals.
6801
6802 // Even if folding fails the fold() functions return some node representing the expression,
6803 // typically the original node. So "folded" can be assumed to be non-null.
6804 TIntermTyped *folded = expression->fold(mDiagnostics);
6805 ASSERT(folded != nullptr);
6806 if (folded->getQualifier() == expression->getQualifier())
6807 {
6808 // We need this expression to have the correct qualifier when validating the consuming
6809 // expression. So we can only return the folded node from here in case it has the same
6810 // qualifier as the original expression. In this kind of a cases the qualifier of the folded
6811 // node is EvqConst, whereas the qualifier of the expression is EvqTemporary:
6812 // 1. (true ? 1.0 : non_constant)
6813 // 2. (non_constant, 1.0)
6814 return folded;
6815 }
6816 return expression;
6817 }
6818
binaryOpCommonCheck(TOperator op,TIntermTyped * left,TIntermTyped * right,const TSourceLoc & loc)6819 bool TParseContext::binaryOpCommonCheck(TOperator op,
6820 TIntermTyped *left,
6821 TIntermTyped *right,
6822 const TSourceLoc &loc)
6823 {
6824 if (left->getBasicType() == EbtVoid || right->getBasicType() == EbtVoid)
6825 {
6826 error(loc, "operation with void operands", GetOperatorString(op));
6827 return false;
6828 }
6829 // Check opaque types are not allowed to be operands in expressions other than array indexing
6830 // and structure member selection.
6831 if (IsOpaqueType(left->getBasicType()) || IsOpaqueType(right->getBasicType()))
6832 {
6833 switch (op)
6834 {
6835 case EOpIndexDirect:
6836 case EOpIndexIndirect:
6837 break;
6838
6839 default:
6840 ASSERT(op != EOpIndexDirectStruct);
6841 error(loc, "Invalid operation for variables with an opaque type",
6842 GetOperatorString(op));
6843 return false;
6844 }
6845 }
6846
6847 if (right->getMemoryQualifier().writeonly)
6848 {
6849 error(loc, "Invalid operation for variables with writeonly", GetOperatorString(op));
6850 return false;
6851 }
6852
6853 if (left->getMemoryQualifier().writeonly)
6854 {
6855 switch (op)
6856 {
6857 case EOpAssign:
6858 case EOpInitialize:
6859 case EOpIndexDirect:
6860 case EOpIndexIndirect:
6861 case EOpIndexDirectStruct:
6862 case EOpIndexDirectInterfaceBlock:
6863 break;
6864 default:
6865 error(loc, "Invalid operation for variables with writeonly", GetOperatorString(op));
6866 return false;
6867 }
6868 }
6869
6870 if (left->getType().getStruct() || right->getType().getStruct())
6871 {
6872 switch (op)
6873 {
6874 case EOpIndexDirectStruct:
6875 ASSERT(left->getType().getStruct());
6876 break;
6877 case EOpEqual:
6878 case EOpNotEqual:
6879 case EOpAssign:
6880 case EOpInitialize:
6881 if (left->getType() != right->getType())
6882 {
6883 return false;
6884 }
6885 break;
6886 default:
6887 error(loc, "Invalid operation for structs", GetOperatorString(op));
6888 return false;
6889 }
6890 }
6891
6892 if (left->isInterfaceBlock() || right->isInterfaceBlock())
6893 {
6894 switch (op)
6895 {
6896 case EOpIndexDirectInterfaceBlock:
6897 ASSERT(left->getType().getInterfaceBlock());
6898 break;
6899 default:
6900 error(loc, "Invalid operation for interface blocks", GetOperatorString(op));
6901 return false;
6902 }
6903 }
6904
6905 if (left->isArray() != right->isArray())
6906 {
6907 error(loc, "array / non-array mismatch", GetOperatorString(op));
6908 return false;
6909 }
6910
6911 if (left->isArray())
6912 {
6913 ASSERT(right->isArray());
6914 if (mShaderVersion < 300)
6915 {
6916 error(loc, "Invalid operation for arrays", GetOperatorString(op));
6917 return false;
6918 }
6919
6920 switch (op)
6921 {
6922 case EOpEqual:
6923 case EOpNotEqual:
6924 case EOpAssign:
6925 case EOpInitialize:
6926 break;
6927 default:
6928 error(loc, "Invalid operation for arrays", GetOperatorString(op));
6929 return false;
6930 }
6931 // At this point, size of implicitly sized arrays should be resolved.
6932 if (left->getType().getArraySizes() != right->getType().getArraySizes())
6933 {
6934 error(loc, "array size mismatch", GetOperatorString(op));
6935 return false;
6936 }
6937 }
6938
6939 // Check ops which require integer / ivec parameters
6940 bool isBitShift = false;
6941 switch (op)
6942 {
6943 case EOpBitShiftLeft:
6944 case EOpBitShiftRight:
6945 case EOpBitShiftLeftAssign:
6946 case EOpBitShiftRightAssign:
6947 // Unsigned can be bit-shifted by signed and vice versa, but we need to
6948 // check that the basic type is an integer type.
6949 isBitShift = true;
6950 if (!IsInteger(left->getBasicType()) || !IsInteger(right->getBasicType()))
6951 {
6952 return false;
6953 }
6954 break;
6955 case EOpBitwiseAnd:
6956 case EOpBitwiseXor:
6957 case EOpBitwiseOr:
6958 case EOpBitwiseAndAssign:
6959 case EOpBitwiseXorAssign:
6960 case EOpBitwiseOrAssign:
6961 // It is enough to check the type of only one operand, since later it
6962 // is checked that the operand types match.
6963 if (!IsInteger(left->getBasicType()))
6964 {
6965 return false;
6966 }
6967 break;
6968 default:
6969 break;
6970 }
6971
6972 // Implicit type casting is not allowed in ESSL.
6973 if (!isBitShift && left->getBasicType() != right->getBasicType())
6974 {
6975 return false;
6976 }
6977
6978 // Check that:
6979 // 1. Type sizes match exactly on ops that require that.
6980 // 2. Restrictions for structs that contain arrays or samplers are respected.
6981 // 3. Arithmetic op type dimensionality restrictions for ops other than multiply are respected.
6982 switch (op)
6983 {
6984 case EOpAssign:
6985 case EOpInitialize:
6986 case EOpEqual:
6987 case EOpNotEqual:
6988 // ESSL 1.00 sections 5.7, 5.8, 5.9
6989 if (mShaderVersion < 300 && left->getType().isStructureContainingArrays())
6990 {
6991 error(loc, "undefined operation for structs containing arrays",
6992 GetOperatorString(op));
6993 return false;
6994 }
6995 // Samplers as l-values are disallowed also in ESSL 3.00, see section 4.1.7,
6996 // we interpret the spec so that this extends to structs containing samplers,
6997 // similarly to ESSL 1.00 spec.
6998 if ((mShaderVersion < 300 || op == EOpAssign || op == EOpInitialize) &&
6999 left->getType().isStructureContainingSamplers())
7000 {
7001 error(loc, "undefined operation for structs containing samplers",
7002 GetOperatorString(op));
7003 return false;
7004 }
7005
7006 if ((left->getNominalSize() != right->getNominalSize()) ||
7007 (left->getSecondarySize() != right->getSecondarySize()))
7008 {
7009 error(loc, "dimension mismatch", GetOperatorString(op));
7010 return false;
7011 }
7012 break;
7013 case EOpLessThan:
7014 case EOpGreaterThan:
7015 case EOpLessThanEqual:
7016 case EOpGreaterThanEqual:
7017 if (!left->isScalar() || !right->isScalar())
7018 {
7019 error(loc, "comparison operator only defined for scalars", GetOperatorString(op));
7020 return false;
7021 }
7022 break;
7023 case EOpAdd:
7024 case EOpSub:
7025 case EOpDiv:
7026 case EOpIMod:
7027 case EOpBitShiftLeft:
7028 case EOpBitShiftRight:
7029 case EOpBitwiseAnd:
7030 case EOpBitwiseXor:
7031 case EOpBitwiseOr:
7032 case EOpAddAssign:
7033 case EOpSubAssign:
7034 case EOpDivAssign:
7035 case EOpIModAssign:
7036 case EOpBitShiftLeftAssign:
7037 case EOpBitShiftRightAssign:
7038 case EOpBitwiseAndAssign:
7039 case EOpBitwiseXorAssign:
7040 case EOpBitwiseOrAssign:
7041 if ((left->isMatrix() && right->isVector()) || (left->isVector() && right->isMatrix()))
7042 {
7043 return false;
7044 }
7045
7046 // Are the sizes compatible?
7047 if (left->getNominalSize() != right->getNominalSize() ||
7048 left->getSecondarySize() != right->getSecondarySize())
7049 {
7050 // If the nominal sizes of operands do not match:
7051 // One of them must be a scalar.
7052 if (!left->isScalar() && !right->isScalar())
7053 return false;
7054
7055 // In the case of compound assignment other than multiply-assign,
7056 // the right side needs to be a scalar. Otherwise a vector/matrix
7057 // would be assigned to a scalar. A scalar can't be shifted by a
7058 // vector either.
7059 if (!right->isScalar() &&
7060 (IsAssignment(op) || op == EOpBitShiftLeft || op == EOpBitShiftRight))
7061 return false;
7062 }
7063 break;
7064 default:
7065 break;
7066 }
7067
7068 return true;
7069 }
7070
isMultiplicationTypeCombinationValid(TOperator op,const TType & left,const TType & right)7071 bool TParseContext::isMultiplicationTypeCombinationValid(TOperator op,
7072 const TType &left,
7073 const TType &right)
7074 {
7075 switch (op)
7076 {
7077 case EOpMul:
7078 case EOpMulAssign:
7079 return left.getNominalSize() == right.getNominalSize() &&
7080 left.getSecondarySize() == right.getSecondarySize();
7081 case EOpVectorTimesScalar:
7082 return true;
7083 case EOpVectorTimesScalarAssign:
7084 ASSERT(!left.isMatrix() && !right.isMatrix());
7085 return left.isVector() && !right.isVector();
7086 case EOpVectorTimesMatrix:
7087 return left.getNominalSize() == right.getRows();
7088 case EOpVectorTimesMatrixAssign:
7089 ASSERT(!left.isMatrix() && right.isMatrix());
7090 return left.isVector() && left.getNominalSize() == right.getRows() &&
7091 left.getNominalSize() == right.getCols();
7092 case EOpMatrixTimesVector:
7093 return left.getCols() == right.getNominalSize();
7094 case EOpMatrixTimesScalar:
7095 return true;
7096 case EOpMatrixTimesScalarAssign:
7097 ASSERT(left.isMatrix() && !right.isMatrix());
7098 return !right.isVector();
7099 case EOpMatrixTimesMatrix:
7100 return left.getCols() == right.getRows();
7101 case EOpMatrixTimesMatrixAssign:
7102 ASSERT(left.isMatrix() && right.isMatrix());
7103 // We need to check two things:
7104 // 1. The matrix multiplication step is valid.
7105 // 2. The result will have the same number of columns as the lvalue.
7106 return left.getCols() == right.getRows() && left.getCols() == right.getCols();
7107
7108 default:
7109 UNREACHABLE();
7110 return false;
7111 }
7112 }
7113
addBinaryMathInternal(TOperator op,TIntermTyped * left,TIntermTyped * right,const TSourceLoc & loc)7114 TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op,
7115 TIntermTyped *left,
7116 TIntermTyped *right,
7117 const TSourceLoc &loc)
7118 {
7119 if (!binaryOpCommonCheck(op, left, right, loc))
7120 return nullptr;
7121
7122 switch (op)
7123 {
7124 case EOpEqual:
7125 case EOpNotEqual:
7126 case EOpLessThan:
7127 case EOpGreaterThan:
7128 case EOpLessThanEqual:
7129 case EOpGreaterThanEqual:
7130 break;
7131 case EOpLogicalOr:
7132 case EOpLogicalXor:
7133 case EOpLogicalAnd:
7134 ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() &&
7135 !right->getType().getStruct());
7136 if (left->getBasicType() != EbtBool || !left->isScalar() || !right->isScalar())
7137 {
7138 return nullptr;
7139 }
7140 // Basic types matching should have been already checked.
7141 ASSERT(right->getBasicType() == EbtBool);
7142 break;
7143 case EOpAdd:
7144 case EOpSub:
7145 case EOpDiv:
7146 case EOpMul:
7147 ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() &&
7148 !right->getType().getStruct());
7149 if (left->getBasicType() == EbtBool)
7150 {
7151 return nullptr;
7152 }
7153 break;
7154 case EOpIMod:
7155 ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() &&
7156 !right->getType().getStruct());
7157 // Note that this is only for the % operator, not for mod()
7158 if (left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat)
7159 {
7160 return nullptr;
7161 }
7162 break;
7163 default:
7164 break;
7165 }
7166
7167 if (op == EOpMul)
7168 {
7169 op = TIntermBinary::GetMulOpBasedOnOperands(left->getType(), right->getType());
7170 if (!isMultiplicationTypeCombinationValid(op, left->getType(), right->getType()))
7171 {
7172 return nullptr;
7173 }
7174 }
7175
7176 TIntermBinary *node = new TIntermBinary(op, left, right);
7177 ASSERT(op != EOpAssign);
7178 markStaticReadIfSymbol(left);
7179 markStaticReadIfSymbol(right);
7180 node->setLine(loc);
7181 return expressionOrFoldedResult(node);
7182 }
7183
addBinaryMath(TOperator op,TIntermTyped * left,TIntermTyped * right,const TSourceLoc & loc)7184 TIntermTyped *TParseContext::addBinaryMath(TOperator op,
7185 TIntermTyped *left,
7186 TIntermTyped *right,
7187 const TSourceLoc &loc)
7188 {
7189 TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
7190 if (node == 0)
7191 {
7192 binaryOpError(loc, GetOperatorString(op), left->getType(), right->getType());
7193 return left;
7194 }
7195 return node;
7196 }
7197
addBinaryMathBooleanResult(TOperator op,TIntermTyped * left,TIntermTyped * right,const TSourceLoc & loc)7198 TIntermTyped *TParseContext::addBinaryMathBooleanResult(TOperator op,
7199 TIntermTyped *left,
7200 TIntermTyped *right,
7201 const TSourceLoc &loc)
7202 {
7203 TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
7204 if (node == nullptr)
7205 {
7206 binaryOpError(loc, GetOperatorString(op), left->getType(), right->getType());
7207 node = CreateBoolNode(false);
7208 node->setLine(loc);
7209 }
7210 return node;
7211 }
7212
addAssign(TOperator op,TIntermTyped * left,TIntermTyped * right,const TSourceLoc & loc)7213 TIntermTyped *TParseContext::addAssign(TOperator op,
7214 TIntermTyped *left,
7215 TIntermTyped *right,
7216 const TSourceLoc &loc)
7217 {
7218 checkCanBeLValue(loc, "assign", left);
7219 TIntermBinary *node = nullptr;
7220 if (binaryOpCommonCheck(op, left, right, loc))
7221 {
7222 TIntermBinary *lValue = left->getAsBinaryNode();
7223 if ((lValue != nullptr) &&
7224 (lValue->getOp() == EOpIndexIndirect || lValue->getOp() == EOpIndexDirect) &&
7225 IsTessellationControlShaderOutput(mShaderType, lValue->getLeft()->getQualifier()))
7226 {
7227 checkTCSOutVarIndexIsValid(lValue, loc);
7228 }
7229
7230 if (op == EOpMulAssign)
7231 {
7232 op = TIntermBinary::GetMulAssignOpBasedOnOperands(left->getType(), right->getType());
7233 if (isMultiplicationTypeCombinationValid(op, left->getType(), right->getType()))
7234 {
7235 node = new TIntermBinary(op, left, right);
7236 }
7237 }
7238 else
7239 {
7240 node = new TIntermBinary(op, left, right);
7241 }
7242 }
7243 if (node == nullptr)
7244 {
7245 assignError(loc, "assign", left->getType(), right->getType());
7246 return left;
7247 }
7248 if (op != EOpAssign)
7249 {
7250 markStaticReadIfSymbol(left);
7251 }
7252 markStaticReadIfSymbol(right);
7253 node->setLine(loc);
7254 return node;
7255 }
7256
addComma(TIntermTyped * left,TIntermTyped * right,const TSourceLoc & loc)7257 TIntermTyped *TParseContext::addComma(TIntermTyped *left,
7258 TIntermTyped *right,
7259 const TSourceLoc &loc)
7260 {
7261 // WebGL2 section 5.26, the following results in an error:
7262 // "Sequence operator applied to void, arrays, or structs containing arrays"
7263 if (mShaderSpec == SH_WEBGL2_SPEC &&
7264 (left->isArray() || left->getBasicType() == EbtVoid ||
7265 left->getType().isStructureContainingArrays() || right->isArray() ||
7266 right->getBasicType() == EbtVoid || right->getType().isStructureContainingArrays()))
7267 {
7268 error(loc,
7269 "sequence operator is not allowed for void, arrays, or structs containing arrays",
7270 ",");
7271 }
7272 if (left->isInterfaceBlock() || right->isInterfaceBlock())
7273 {
7274 error(loc, "sequence operator is not allowed for interface blocks", ",");
7275 }
7276
7277 TIntermBinary *commaNode = TIntermBinary::CreateComma(left, right, mShaderVersion);
7278 markStaticReadIfSymbol(left);
7279 markStaticReadIfSymbol(right);
7280 commaNode->setLine(loc);
7281
7282 return expressionOrFoldedResult(commaNode);
7283 }
7284
addBranch(TOperator op,const TSourceLoc & loc)7285 TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc)
7286 {
7287 switch (op)
7288 {
7289 case EOpContinue:
7290 if (mLoopNestingLevel <= 0)
7291 {
7292 error(loc, "continue statement only allowed in loops", "");
7293 }
7294 break;
7295 case EOpBreak:
7296 if (mLoopNestingLevel <= 0 && mSwitchNestingLevel <= 0)
7297 {
7298 error(loc, "break statement only allowed in loops and switch statements", "");
7299 }
7300 break;
7301 case EOpReturn:
7302 if (mCurrentFunctionType->getBasicType() != EbtVoid)
7303 {
7304 error(loc, "non-void function must return a value", "return");
7305 }
7306 if (mDeclaringMain)
7307 {
7308 errorIfPLSDeclared(loc, PLSIllegalOperations::ReturnFromMain);
7309 }
7310 break;
7311 case EOpKill:
7312 if (mShaderType != GL_FRAGMENT_SHADER)
7313 {
7314 error(loc, "discard supported in fragment shaders only", "discard");
7315 }
7316 else
7317 {
7318 errorIfPLSDeclared(loc, PLSIllegalOperations::Discard);
7319 }
7320 mHasDiscard = true;
7321 break;
7322 default:
7323 UNREACHABLE();
7324 break;
7325 }
7326 return addBranch(op, nullptr, loc);
7327 }
7328
addBranch(TOperator op,TIntermTyped * expression,const TSourceLoc & loc)7329 TIntermBranch *TParseContext::addBranch(TOperator op,
7330 TIntermTyped *expression,
7331 const TSourceLoc &loc)
7332 {
7333 if (expression != nullptr)
7334 {
7335 markStaticReadIfSymbol(expression);
7336 ASSERT(op == EOpReturn);
7337 mFunctionReturnsValue = true;
7338 if (mCurrentFunctionType->getBasicType() == EbtVoid)
7339 {
7340 error(loc, "void function cannot return a value", "return");
7341 }
7342 else if (*mCurrentFunctionType != expression->getType())
7343 {
7344 error(loc, "function return is not matching type:", "return");
7345 }
7346 }
7347 TIntermBranch *node = new TIntermBranch(op, expression);
7348 node->setLine(loc);
7349 return node;
7350 }
7351
appendStatement(TIntermBlock * block,TIntermNode * statement)7352 void TParseContext::appendStatement(TIntermBlock *block, TIntermNode *statement)
7353 {
7354 if (statement != nullptr)
7355 {
7356 markStaticReadIfSymbol(statement);
7357 block->appendStatement(statement);
7358 }
7359 }
7360
checkTextureGather(TIntermAggregate * functionCall)7361 void TParseContext::checkTextureGather(TIntermAggregate *functionCall)
7362 {
7363 const TOperator op = functionCall->getOp();
7364 const TFunction *func = functionCall->getFunction();
7365 if (BuiltInGroup::IsTextureGather(op))
7366 {
7367 bool isTextureGatherOffsetOrOffsets =
7368 BuiltInGroup::IsTextureGatherOffset(op) || BuiltInGroup::IsTextureGatherOffsets(op);
7369 TIntermNode *componentNode = nullptr;
7370 TIntermSequence *arguments = functionCall->getSequence();
7371 ASSERT(arguments->size() >= 2u && arguments->size() <= 4u);
7372 const TIntermTyped *sampler = arguments->front()->getAsTyped();
7373 ASSERT(sampler != nullptr);
7374 switch (sampler->getBasicType())
7375 {
7376 case EbtSampler2D:
7377 case EbtISampler2D:
7378 case EbtUSampler2D:
7379 case EbtSampler2DArray:
7380 case EbtISampler2DArray:
7381 case EbtUSampler2DArray:
7382 if ((!isTextureGatherOffsetOrOffsets && arguments->size() == 3u) ||
7383 (isTextureGatherOffsetOrOffsets && arguments->size() == 4u))
7384 {
7385 componentNode = arguments->back();
7386 }
7387 break;
7388 case EbtSamplerCube:
7389 case EbtISamplerCube:
7390 case EbtUSamplerCube:
7391 case EbtSamplerCubeArray:
7392 case EbtISamplerCubeArray:
7393 case EbtUSamplerCubeArray:
7394 ASSERT(!isTextureGatherOffsetOrOffsets);
7395 if (arguments->size() == 3u)
7396 {
7397 componentNode = arguments->back();
7398 }
7399 break;
7400 case EbtSampler2DShadow:
7401 case EbtSampler2DArrayShadow:
7402 case EbtSamplerCubeShadow:
7403 case EbtSamplerCubeArrayShadow:
7404 break;
7405 default:
7406 UNREACHABLE();
7407 break;
7408 }
7409 if (componentNode)
7410 {
7411 const TIntermConstantUnion *componentConstantUnion =
7412 componentNode->getAsConstantUnion();
7413 if (componentNode->getAsTyped()->getQualifier() != EvqConst || !componentConstantUnion)
7414 {
7415 error(functionCall->getLine(), "Texture component must be a constant expression",
7416 func->name());
7417 }
7418 else
7419 {
7420 int component = componentConstantUnion->getIConst(0);
7421 if (component < 0 || component > 3)
7422 {
7423 error(functionCall->getLine(), "Component must be in the range [0;3]",
7424 func->name());
7425 }
7426 }
7427 }
7428 }
7429 }
7430
checkTextureOffset(TIntermAggregate * functionCall)7431 void TParseContext::checkTextureOffset(TIntermAggregate *functionCall)
7432 {
7433 const TOperator op = functionCall->getOp();
7434 const TFunction *func = functionCall->getFunction();
7435 TIntermNode *offset = nullptr;
7436 TIntermSequence *arguments = functionCall->getSequence();
7437
7438 if (BuiltInGroup::IsTextureOffsetNoBias(op) || BuiltInGroup::IsTextureGatherOffsetNoComp(op) ||
7439 BuiltInGroup::IsTextureGatherOffsetsNoComp(op))
7440 {
7441 offset = arguments->back();
7442 }
7443 else if (BuiltInGroup::IsTextureOffsetBias(op) || BuiltInGroup::IsTextureGatherOffsetComp(op) ||
7444 BuiltInGroup::IsTextureGatherOffsetsComp(op))
7445 {
7446 // A bias or comp parameter follows the offset parameter.
7447 ASSERT(arguments->size() >= 3);
7448 offset = (*arguments)[2];
7449 }
7450
7451 // If not one of the above built-ins, there's nothing to do here.
7452 if (offset == nullptr)
7453 {
7454 return;
7455 }
7456
7457 bool isTextureGatherOffset = BuiltInGroup::IsTextureGatherOffset(op);
7458 bool isTextureGatherOffsets = BuiltInGroup::IsTextureGatherOffsets(op);
7459 bool useTextureGatherOffsetConstraints = isTextureGatherOffset || isTextureGatherOffsets;
7460
7461 int minOffsetValue =
7462 useTextureGatherOffsetConstraints ? mMinProgramTextureGatherOffset : mMinProgramTexelOffset;
7463 int maxOffsetValue =
7464 useTextureGatherOffsetConstraints ? mMaxProgramTextureGatherOffset : mMaxProgramTexelOffset;
7465
7466 if (isTextureGatherOffsets)
7467 {
7468 // If textureGatherOffsets, the offsets parameter is an array, which is expected as an
7469 // aggregate constructor node or as a symbol node with a constant value.
7470 TIntermAggregate *offsetAggregate = offset->getAsAggregate();
7471 TIntermSymbol *offsetSymbol = offset->getAsSymbolNode();
7472
7473 const TConstantUnion *offsetValues = offsetAggregate ? offsetAggregate->getConstantValue()
7474 : offsetSymbol ? offsetSymbol->getConstantValue()
7475 : nullptr;
7476
7477 if (offsetValues == nullptr)
7478 {
7479 error(functionCall->getLine(), "Texture offsets must be a constant expression",
7480 func->name());
7481 return;
7482 }
7483
7484 constexpr unsigned int kOffsetsCount = 4;
7485 const TType &offsetType =
7486 offsetAggregate != nullptr ? offsetAggregate->getType() : offsetSymbol->getType();
7487 if (offsetType.getNumArraySizes() != 1 || offsetType.getArraySizes()[0] != kOffsetsCount)
7488 {
7489 error(functionCall->getLine(), "Texture offsets must be an array of 4 elements",
7490 func->name());
7491 return;
7492 }
7493
7494 size_t size = offsetType.getObjectSize() / kOffsetsCount;
7495 for (unsigned int i = 0; i < kOffsetsCount; ++i)
7496 {
7497 checkSingleTextureOffset(offset->getLine(), &offsetValues[i * size], size,
7498 minOffsetValue, maxOffsetValue);
7499 }
7500 }
7501 else
7502 {
7503 // If textureOffset or textureGatherOffset, the offset is expected to be found as a constant
7504 // union.
7505 TIntermConstantUnion *offsetConstantUnion = offset->getAsConstantUnion();
7506
7507 // ES3.2 or ES3.1's EXT_gpu_shader5 allow non-const offsets to be passed to
7508 // textureGatherOffset.
7509 bool textureGatherOffsetMustBeConst = mShaderVersion <= 310 &&
7510 !isExtensionEnabled(TExtension::EXT_gpu_shader5) &&
7511 !isExtensionEnabled(TExtension::OES_gpu_shader5);
7512
7513 bool isOffsetConst =
7514 offset->getAsTyped()->getQualifier() == EvqConst && offsetConstantUnion != nullptr;
7515 bool offsetMustBeConst = !isTextureGatherOffset || textureGatherOffsetMustBeConst;
7516
7517 if (!isOffsetConst && offsetMustBeConst)
7518 {
7519 error(functionCall->getLine(), "Texture offset must be a constant expression",
7520 func->name());
7521 return;
7522 }
7523
7524 // We cannot verify non-constant offsets to textureGatherOffset.
7525 if (offsetConstantUnion == nullptr)
7526 {
7527 ASSERT(!offsetMustBeConst);
7528 return;
7529 }
7530
7531 size_t size = offsetConstantUnion->getType().getObjectSize();
7532 const TConstantUnion *values = offsetConstantUnion->getConstantValue();
7533 checkSingleTextureOffset(offset->getLine(), values, size, minOffsetValue, maxOffsetValue);
7534 }
7535 }
7536
checkSingleTextureOffset(const TSourceLoc & line,const TConstantUnion * values,size_t size,int minOffsetValue,int maxOffsetValue)7537 void TParseContext::checkSingleTextureOffset(const TSourceLoc &line,
7538 const TConstantUnion *values,
7539 size_t size,
7540 int minOffsetValue,
7541 int maxOffsetValue)
7542 {
7543 for (size_t i = 0u; i < size; ++i)
7544 {
7545 ASSERT(values[i].getType() == EbtInt);
7546 int offsetValue = values[i].getIConst();
7547 if (offsetValue > maxOffsetValue || offsetValue < minOffsetValue)
7548 {
7549 std::stringstream tokenStream = sh::InitializeStream<std::stringstream>();
7550 tokenStream << offsetValue;
7551 std::string token = tokenStream.str();
7552 error(line, "Texture offset value out of valid range", token.c_str());
7553 }
7554 }
7555 }
7556
checkInterpolationFS(TIntermAggregate * functionCall)7557 void TParseContext::checkInterpolationFS(TIntermAggregate *functionCall)
7558 {
7559 const TFunction *func = functionCall->getFunction();
7560 if (!BuiltInGroup::IsInterpolationFS(functionCall->getOp()))
7561 {
7562 return;
7563 }
7564
7565 TIntermTyped *arg0 = nullptr;
7566
7567 if (functionCall->getAsAggregate())
7568 {
7569 const TIntermSequence *argp = functionCall->getSequence();
7570 if (argp->size() > 0)
7571 arg0 = (*argp)[0]->getAsTyped();
7572 }
7573 else
7574 {
7575 assert(functionCall->getAsUnaryNode());
7576 arg0 = functionCall->getAsUnaryNode()->getOperand();
7577 }
7578
7579 // Make sure the first argument is an interpolant, or an array element of an interpolant
7580 if (!IsVaryingIn(arg0->getType().getQualifier()))
7581 {
7582 // It might still be an array element.
7583 const TIntermTyped *base = FindLValueBase(arg0);
7584
7585 if (base == nullptr || (!IsVaryingIn(base->getType().getQualifier())))
7586 error(arg0->getLine(),
7587 "first argument must be an interpolant, or interpolant-array element",
7588 func->name());
7589 }
7590 }
7591
checkAtomicMemoryBuiltinFunctions(TIntermAggregate * functionCall)7592 void TParseContext::checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall)
7593 {
7594 const TFunction *func = functionCall->getFunction();
7595 if (BuiltInGroup::IsAtomicMemory(functionCall->getOp()))
7596 {
7597 TIntermSequence *arguments = functionCall->getSequence();
7598 TIntermTyped *memNode = (*arguments)[0]->getAsTyped();
7599
7600 if (IsBufferOrSharedVariable(memNode))
7601 {
7602 return;
7603 }
7604
7605 while (memNode->getAsBinaryNode() || memNode->getAsSwizzleNode())
7606 {
7607 // Child 0 is "left" if binary, and the expression being swizzled if swizzle.
7608 // Note: we don't need to check that the binary operation is one of EOp*Index*, as any
7609 // other operation will result in a temp value which cannot be passed to this
7610 // out/inout parameter anyway.
7611 memNode = memNode->getChildNode(0)->getAsTyped();
7612 if (IsBufferOrSharedVariable(memNode))
7613 {
7614 return;
7615 }
7616 }
7617
7618 error(memNode->getLine(),
7619 "The value passed to the mem argument of an atomic memory function does not "
7620 "correspond to a buffer or shared variable.",
7621 func->name());
7622 }
7623 }
7624
7625 // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate * functionCall)7626 void TParseContext::checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall)
7627 {
7628 const TOperator op = functionCall->getOp();
7629
7630 if (BuiltInGroup::IsImage(op))
7631 {
7632 TIntermSequence *arguments = functionCall->getSequence();
7633 TIntermTyped *imageNode = (*arguments)[0]->getAsTyped();
7634
7635 const TMemoryQualifier &memoryQualifier = imageNode->getMemoryQualifier();
7636
7637 if (BuiltInGroup::IsImageStore(op))
7638 {
7639 if (memoryQualifier.readonly)
7640 {
7641 error(imageNode->getLine(),
7642 "'imageStore' cannot be used with images qualified as 'readonly'",
7643 GetImageArgumentToken(imageNode));
7644 }
7645 }
7646 else if (BuiltInGroup::IsImageLoad(op))
7647 {
7648 if (memoryQualifier.writeonly)
7649 {
7650 error(imageNode->getLine(),
7651 "'imageLoad' cannot be used with images qualified as 'writeonly'",
7652 GetImageArgumentToken(imageNode));
7653 }
7654 }
7655 else if (BuiltInGroup::IsImageAtomic(op))
7656 {
7657 if (memoryQualifier.readonly)
7658 {
7659 error(imageNode->getLine(),
7660 "'imageAtomic' cannot be used with images qualified as 'readonly'",
7661 GetImageArgumentToken(imageNode));
7662 }
7663 if (memoryQualifier.writeonly)
7664 {
7665 error(imageNode->getLine(),
7666 "'imageAtomic' cannot be used with images qualified as 'writeonly'",
7667 GetImageArgumentToken(imageNode));
7668 }
7669 }
7670 }
7671 }
7672
7673 // GLSL ES 3.10 Revision 4, 13.51 Matching of Memory Qualifiers in Function Parameters
checkImageMemoryAccessForUserDefinedFunctions(const TFunction * functionDefinition,const TIntermAggregate * functionCall)7674 void TParseContext::checkImageMemoryAccessForUserDefinedFunctions(
7675 const TFunction *functionDefinition,
7676 const TIntermAggregate *functionCall)
7677 {
7678 ASSERT(functionCall->getOp() == EOpCallFunctionInAST);
7679
7680 const TIntermSequence &arguments = *functionCall->getSequence();
7681
7682 ASSERT(functionDefinition->getParamCount() == arguments.size());
7683
7684 for (size_t i = 0; i < arguments.size(); ++i)
7685 {
7686 TIntermTyped *typedArgument = arguments[i]->getAsTyped();
7687 const TType &functionArgumentType = typedArgument->getType();
7688 const TType &functionParameterType = functionDefinition->getParam(i)->getType();
7689 ASSERT(functionArgumentType.getBasicType() == functionParameterType.getBasicType());
7690
7691 if (IsImage(functionArgumentType.getBasicType()))
7692 {
7693 const TMemoryQualifier &functionArgumentMemoryQualifier =
7694 functionArgumentType.getMemoryQualifier();
7695 const TMemoryQualifier &functionParameterMemoryQualifier =
7696 functionParameterType.getMemoryQualifier();
7697 if (functionArgumentMemoryQualifier.readonly &&
7698 !functionParameterMemoryQualifier.readonly)
7699 {
7700 error(functionCall->getLine(),
7701 "Function call discards the 'readonly' qualifier from image",
7702 GetImageArgumentToken(typedArgument));
7703 }
7704
7705 if (functionArgumentMemoryQualifier.writeonly &&
7706 !functionParameterMemoryQualifier.writeonly)
7707 {
7708 error(functionCall->getLine(),
7709 "Function call discards the 'writeonly' qualifier from image",
7710 GetImageArgumentToken(typedArgument));
7711 }
7712
7713 if (functionArgumentMemoryQualifier.coherent &&
7714 !functionParameterMemoryQualifier.coherent)
7715 {
7716 error(functionCall->getLine(),
7717 "Function call discards the 'coherent' qualifier from image",
7718 GetImageArgumentToken(typedArgument));
7719 }
7720
7721 if (functionArgumentMemoryQualifier.volatileQualifier &&
7722 !functionParameterMemoryQualifier.volatileQualifier)
7723 {
7724 error(functionCall->getLine(),
7725 "Function call discards the 'volatile' qualifier from image",
7726 GetImageArgumentToken(typedArgument));
7727 }
7728 }
7729 }
7730 }
7731
addFunctionCallOrMethod(TFunctionLookup * fnCall,const TSourceLoc & loc)7732 TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunctionLookup *fnCall, const TSourceLoc &loc)
7733 {
7734 if (fnCall->thisNode() != nullptr)
7735 {
7736 return addMethod(fnCall, loc);
7737 }
7738 if (fnCall->isConstructor())
7739 {
7740 return addConstructor(fnCall, loc);
7741 }
7742 return addNonConstructorFunctionCall(fnCall, loc);
7743 }
7744
addMethod(TFunctionLookup * fnCall,const TSourceLoc & loc)7745 TIntermTyped *TParseContext::addMethod(TFunctionLookup *fnCall, const TSourceLoc &loc)
7746 {
7747 TIntermTyped *thisNode = fnCall->thisNode();
7748 // It's possible for the name pointer in the TFunction to be null in case it gets parsed as
7749 // a constructor. But such a TFunction can't reach here, since the lexer goes into FIELDS
7750 // mode after a dot, which makes type identifiers to be parsed as FIELD_SELECTION instead.
7751 // So accessing fnCall->name() below is safe.
7752 if (fnCall->name() != "length")
7753 {
7754 error(loc, "invalid method", fnCall->name());
7755 }
7756 else if (!fnCall->arguments().empty())
7757 {
7758 error(loc, "method takes no parameters", "length");
7759 }
7760 else if (!thisNode->isArray())
7761 {
7762 error(loc, "length can only be called on arrays", "length");
7763 }
7764 else if (thisNode->getQualifier() == EvqPerVertexIn &&
7765 mGeometryShaderInputPrimitiveType == EptUndefined)
7766 {
7767 ASSERT(mShaderType == GL_GEOMETRY_SHADER_EXT);
7768 error(loc, "missing input primitive declaration before calling length on gl_in", "length");
7769 }
7770 else
7771 {
7772 TIntermUnary *node = new TIntermUnary(EOpArrayLength, thisNode, nullptr);
7773 markStaticReadIfSymbol(thisNode);
7774 node->setLine(loc);
7775 return node->fold(mDiagnostics);
7776 }
7777 return CreateZeroNode(TType(EbtInt, EbpUndefined, EvqConst));
7778 }
7779
addNonConstructorFunctionCallImpl(TFunctionLookup * fnCall,const TSourceLoc & loc)7780 TIntermTyped *TParseContext::addNonConstructorFunctionCallImpl(TFunctionLookup *fnCall,
7781 const TSourceLoc &loc)
7782 {
7783 // First check whether the function has been hidden by a variable name or struct typename by
7784 // using the symbol looked up in the lexical phase. If the function is not hidden, look for one
7785 // with a matching argument list.
7786 if (fnCall->symbol() != nullptr && !fnCall->symbol()->isFunction())
7787 {
7788 error(loc, "function name expected", fnCall->name());
7789 }
7790 else
7791 {
7792 // There are no inner functions, so it's enough to look for user-defined functions in the
7793 // global scope.
7794 const TSymbol *symbol = symbolTable.findGlobal(fnCall->getMangledName());
7795
7796 if (symbol != nullptr)
7797 {
7798 // A user-defined function - could be an overloaded built-in as well.
7799 ASSERT(symbol->symbolType() == SymbolType::UserDefined);
7800 const TFunction *fnCandidate = static_cast<const TFunction *>(symbol);
7801 TIntermAggregate *callNode =
7802 TIntermAggregate::CreateFunctionCall(*fnCandidate, &fnCall->arguments());
7803 callNode->setLine(loc);
7804 checkImageMemoryAccessForUserDefinedFunctions(fnCandidate, callNode);
7805 functionCallRValueLValueErrorCheck(fnCandidate, callNode);
7806 return callNode;
7807 }
7808
7809 symbol = symbolTable.findBuiltIn(fnCall->getMangledName(), mShaderVersion);
7810
7811 if (symbol != nullptr)
7812 {
7813 // A built-in function.
7814 ASSERT(symbol->symbolType() == SymbolType::BuiltIn);
7815 const TFunction *fnCandidate = static_cast<const TFunction *>(symbol);
7816
7817 if (!fnCandidate->extensions().empty() &&
7818 fnCandidate->extensions()[0] != TExtension::UNDEFINED)
7819 {
7820 checkCanUseOneOfExtensions(loc, fnCandidate->extensions());
7821 }
7822
7823 // All function calls are mapped to a built-in operation.
7824 TOperator op = fnCandidate->getBuiltInOp();
7825 if (BuiltInGroup::IsMath(op) && fnCandidate->getParamCount() == 1)
7826 {
7827 // Treat it like a built-in unary operator.
7828 TIntermNode *unaryParamNode = fnCall->arguments().front();
7829 return createUnaryMath(op, unaryParamNode->getAsTyped(), loc, fnCandidate);
7830 }
7831
7832 TIntermAggregate *callNode =
7833 TIntermAggregate::CreateBuiltInFunctionCall(*fnCandidate, &fnCall->arguments());
7834 callNode->setLine(loc);
7835
7836 if (UsesDerivatives(callNode))
7837 {
7838 mUsesDerivatives = true;
7839 }
7840
7841 checkAtomicMemoryBuiltinFunctions(callNode);
7842 checkTextureOffset(callNode);
7843 checkTextureGather(callNode);
7844 checkInterpolationFS(callNode);
7845 checkImageMemoryAccessForBuiltinFunctions(callNode);
7846
7847 // Some built-in functions have out parameters too.
7848 functionCallRValueLValueErrorCheck(fnCandidate, callNode);
7849
7850 // See if we can constant fold a built-in. Note that this may be possible
7851 // even if it is not const-qualified.
7852 return callNode->fold(mDiagnostics);
7853 }
7854 else
7855 {
7856 error(loc, "no matching overloaded function found", fnCall->name());
7857 }
7858 }
7859 return nullptr;
7860 }
7861
addNonConstructorFunctionCall(TFunctionLookup * fnCall,const TSourceLoc & loc)7862 TIntermTyped *TParseContext::addNonConstructorFunctionCall(TFunctionLookup *fnCall,
7863 const TSourceLoc &loc)
7864 {
7865 TIntermTyped *result = addNonConstructorFunctionCallImpl(fnCall, loc);
7866 if (result != nullptr)
7867 {
7868 return result;
7869 }
7870 // Error message was already written. Put on an unused node for error recovery.
7871 return CreateZeroNode(TType(EbtFloat, EbpMedium, EvqConst));
7872 }
7873
addTernarySelection(TIntermTyped * cond,TIntermTyped * trueExpression,TIntermTyped * falseExpression,const TSourceLoc & loc)7874 TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond,
7875 TIntermTyped *trueExpression,
7876 TIntermTyped *falseExpression,
7877 const TSourceLoc &loc)
7878 {
7879 if (!checkIsScalarBool(loc, cond))
7880 {
7881 return falseExpression;
7882 }
7883
7884 if (trueExpression->getType() != falseExpression->getType())
7885 {
7886 TInfoSinkBase reasonStream;
7887 reasonStream << "mismatching ternary operator operand types '" << trueExpression->getType()
7888 << " and '" << falseExpression->getType() << "'";
7889 error(loc, reasonStream.c_str(), "?:");
7890 return falseExpression;
7891 }
7892 if (IsOpaqueType(trueExpression->getBasicType()))
7893 {
7894 // ESSL 1.00 section 4.1.7
7895 // ESSL 3.00.6 section 4.1.7
7896 // Opaque/sampler types are not allowed in most types of expressions, including ternary.
7897 // Note that structs containing opaque types don't need to be checked as structs are
7898 // forbidden below.
7899 error(loc, "ternary operator is not allowed for opaque types", "?:");
7900 return falseExpression;
7901 }
7902
7903 if (cond->getMemoryQualifier().writeonly || trueExpression->getMemoryQualifier().writeonly ||
7904 falseExpression->getMemoryQualifier().writeonly)
7905 {
7906 error(loc, "ternary operator is not allowed for variables with writeonly", "?:");
7907 return falseExpression;
7908 }
7909
7910 // ESSL 1.00.17 sections 5.2 and 5.7:
7911 // Ternary operator is not among the operators allowed for structures/arrays.
7912 // ESSL 3.00 and ESSL 3.10 section 5.7:
7913 // Ternary operator supports structs, but array support is optional for arrays.
7914 // ESSL 3.20 section 5.7:
7915 // Ternary operator supports structs and arrays unconditionally.
7916 // In WebGL2 section 5.26, ternary is banned for both arrays and structs.
7917 if ((mShaderVersion < 300 || mShaderSpec == SH_WEBGL2_SPEC) && trueExpression->isArray())
7918 {
7919 error(loc, "ternary operator is not allowed for arrays in ESSL 1.0 and webgl", "?:");
7920 return falseExpression;
7921 }
7922 if ((mShaderVersion < 300 || mShaderSpec == SH_WEBGL2_SPEC) &&
7923 trueExpression->getBasicType() == EbtStruct)
7924 {
7925 error(loc, "ternary operator is not allowed for structures in ESSL 1.0 and webgl", "?:");
7926 return falseExpression;
7927 }
7928 if (trueExpression->getBasicType() == EbtInterfaceBlock)
7929 {
7930 error(loc, "ternary operator is not allowed for interface blocks", "?:");
7931 return falseExpression;
7932 }
7933
7934 // WebGL2 section 5.26, the following results in an error:
7935 // "Ternary operator applied to void, arrays, or structs containing arrays"
7936 if (mShaderSpec == SH_WEBGL2_SPEC && trueExpression->getBasicType() == EbtVoid)
7937 {
7938 error(loc, "ternary operator is not allowed for void", "?:");
7939 return falseExpression;
7940 }
7941
7942 TIntermTernary *node = new TIntermTernary(cond, trueExpression, falseExpression);
7943 markStaticReadIfSymbol(cond);
7944 markStaticReadIfSymbol(trueExpression);
7945 markStaticReadIfSymbol(falseExpression);
7946 node->setLine(loc);
7947 return expressionOrFoldedResult(node);
7948 }
7949
7950 //
7951 // Parse an array of strings using yyparse.
7952 //
7953 // Returns 0 for success.
7954 //
PaParseStrings(size_t count,const char * const string[],const int length[],TParseContext * context)7955 int PaParseStrings(size_t count,
7956 const char *const string[],
7957 const int length[],
7958 TParseContext *context)
7959 {
7960 if ((count == 0) || (string == nullptr))
7961 return 1;
7962
7963 if (glslang_initialize(context))
7964 return 1;
7965
7966 int error = glslang_scan(count, string, length, context);
7967 if (!error)
7968 error = glslang_parse(context);
7969
7970 glslang_finalize(context);
7971
7972 return (error == 0) && (context->numErrors() == 0) ? 0 : 1;
7973 }
7974
7975 } // namespace sh
7976