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