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