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