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