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