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