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