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