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