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