Line data Source code
1 : //
2 : // Copyright (c) 2002-2014 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 "compiler/preprocessor/SourceLocation.h"
13 : #include "compiler/translator/Cache.h"
14 : #include "compiler/translator/glslang.h"
15 : #include "compiler/translator/ValidateSwitch.h"
16 : #include "compiler/translator/ValidateGlobalInitializer.h"
17 : #include "compiler/translator/util.h"
18 :
19 : namespace sh
20 : {
21 :
22 : ///////////////////////////////////////////////////////////////////////
23 : //
24 : // Sub- vector and matrix fields
25 : //
26 : ////////////////////////////////////////////////////////////////////////
27 :
28 : namespace
29 : {
30 :
31 : const int kWebGLMaxStructNesting = 4;
32 :
33 0 : bool ContainsSampler(const TType &type)
34 : {
35 0 : if (IsSampler(type.getBasicType()))
36 0 : return true;
37 :
38 0 : if (type.getBasicType() == EbtStruct || type.isInterfaceBlock())
39 : {
40 0 : const TFieldList &fields = type.getStruct()->fields();
41 0 : for (unsigned int i = 0; i < fields.size(); ++i)
42 : {
43 0 : if (ContainsSampler(*fields[i]->type()))
44 0 : return true;
45 : }
46 : }
47 :
48 0 : return false;
49 : }
50 :
51 0 : bool ContainsImage(const TType &type)
52 : {
53 0 : if (IsImage(type.getBasicType()))
54 0 : return true;
55 :
56 0 : if (type.getBasicType() == EbtStruct || type.isInterfaceBlock())
57 : {
58 0 : const TFieldList &fields = type.getStruct()->fields();
59 0 : for (unsigned int i = 0; i < fields.size(); ++i)
60 : {
61 0 : if (ContainsImage(*fields[i]->type()))
62 0 : return true;
63 : }
64 : }
65 :
66 0 : return false;
67 : }
68 :
69 : } // namespace
70 :
71 0 : TParseContext::TParseContext(TSymbolTable &symt,
72 : TExtensionBehavior &ext,
73 : sh::GLenum type,
74 : ShShaderSpec spec,
75 : ShCompileOptions options,
76 : bool checksPrecErrors,
77 : TInfoSink &is,
78 0 : const ShBuiltInResources &resources)
79 : : intermediate(),
80 : symbolTable(symt),
81 : mDeferredSingleDeclarationErrorCheck(false),
82 : mShaderType(type),
83 : mShaderSpec(spec),
84 : mCompileOptions(options),
85 : mShaderVersion(100),
86 : mTreeRoot(nullptr),
87 : mLoopNestingLevel(0),
88 : mStructNestingLevel(0),
89 : mSwitchNestingLevel(0),
90 : mCurrentFunctionType(nullptr),
91 : mFunctionReturnsValue(false),
92 : mChecksPrecisionErrors(checksPrecErrors),
93 : mFragmentPrecisionHighOnESSL1(false),
94 : mDefaultMatrixPacking(EmpColumnMajor),
95 0 : mDefaultBlockStorage(sh::IsWebGLBasedSpec(spec) ? EbsStd140 : EbsShared),
96 : mDiagnostics(is),
97 : mDirectiveHandler(ext,
98 : mDiagnostics,
99 : mShaderVersion,
100 : mShaderType,
101 0 : resources.WEBGL_debug_shader_precision == 1),
102 0 : mPreprocessor(&mDiagnostics, &mDirectiveHandler, pp::PreprocessorSettings()),
103 : mScanner(nullptr),
104 : mUsesFragData(false),
105 : mUsesFragColor(false),
106 : mUsesSecondaryOutputs(false),
107 0 : mMinProgramTexelOffset(resources.MinProgramTexelOffset),
108 0 : mMaxProgramTexelOffset(resources.MaxProgramTexelOffset),
109 : mComputeShaderLocalSizeDeclared(false),
110 0 : mDeclaringFunction(false)
111 : {
112 0 : mComputeShaderLocalSize.fill(-1);
113 0 : }
114 :
115 : //
116 : // Look at a '.' field selector string and change it into offsets
117 : // for a vector.
118 : //
119 0 : bool TParseContext::parseVectorFields(const TString &compString,
120 : int vecSize,
121 : TVectorFields &fields,
122 : const TSourceLoc &line)
123 : {
124 0 : fields.num = (int)compString.size();
125 0 : if (fields.num > 4)
126 : {
127 0 : error(line, "illegal vector field selection", compString.c_str());
128 0 : return false;
129 : }
130 :
131 : enum
132 : {
133 : exyzw,
134 : ergba,
135 : estpq
136 : } fieldSet[4];
137 :
138 0 : for (int i = 0; i < fields.num; ++i)
139 : {
140 0 : switch (compString[i])
141 : {
142 : case 'x':
143 0 : fields.offsets[i] = 0;
144 0 : fieldSet[i] = exyzw;
145 0 : break;
146 : case 'r':
147 0 : fields.offsets[i] = 0;
148 0 : fieldSet[i] = ergba;
149 0 : break;
150 : case 's':
151 0 : fields.offsets[i] = 0;
152 0 : fieldSet[i] = estpq;
153 0 : break;
154 : case 'y':
155 0 : fields.offsets[i] = 1;
156 0 : fieldSet[i] = exyzw;
157 0 : break;
158 : case 'g':
159 0 : fields.offsets[i] = 1;
160 0 : fieldSet[i] = ergba;
161 0 : break;
162 : case 't':
163 0 : fields.offsets[i] = 1;
164 0 : fieldSet[i] = estpq;
165 0 : break;
166 : case 'z':
167 0 : fields.offsets[i] = 2;
168 0 : fieldSet[i] = exyzw;
169 0 : break;
170 : case 'b':
171 0 : fields.offsets[i] = 2;
172 0 : fieldSet[i] = ergba;
173 0 : break;
174 : case 'p':
175 0 : fields.offsets[i] = 2;
176 0 : fieldSet[i] = estpq;
177 0 : break;
178 :
179 : case 'w':
180 0 : fields.offsets[i] = 3;
181 0 : fieldSet[i] = exyzw;
182 0 : break;
183 : case 'a':
184 0 : fields.offsets[i] = 3;
185 0 : fieldSet[i] = ergba;
186 0 : break;
187 : case 'q':
188 0 : fields.offsets[i] = 3;
189 0 : fieldSet[i] = estpq;
190 0 : break;
191 : default:
192 0 : error(line, "illegal vector field selection", compString.c_str());
193 0 : return false;
194 : }
195 : }
196 :
197 0 : for (int i = 0; i < fields.num; ++i)
198 : {
199 0 : if (fields.offsets[i] >= vecSize)
200 : {
201 0 : error(line, "vector field selection out of range", compString.c_str());
202 0 : return false;
203 : }
204 :
205 0 : if (i > 0)
206 : {
207 0 : if (fieldSet[i] != fieldSet[i - 1])
208 : {
209 0 : error(line, "illegal - vector component fields not from the same set",
210 0 : compString.c_str());
211 0 : return false;
212 : }
213 : }
214 : }
215 :
216 0 : return true;
217 : }
218 :
219 : ///////////////////////////////////////////////////////////////////////
220 : //
221 : // Errors
222 : //
223 : ////////////////////////////////////////////////////////////////////////
224 :
225 :
226 : //
227 : // Used by flex/bison to output all syntax and parsing errors.
228 : //
229 0 : void TParseContext::error(const TSourceLoc &loc,
230 : const char *reason,
231 : const char *token,
232 : const char *extraInfo)
233 : {
234 0 : mDiagnostics.error(loc, reason, token, extraInfo);
235 0 : }
236 :
237 0 : void TParseContext::warning(const TSourceLoc &loc,
238 : const char *reason,
239 : const char *token,
240 : const char *extraInfo)
241 : {
242 0 : mDiagnostics.warning(loc, reason, token, extraInfo);
243 0 : }
244 :
245 0 : void TParseContext::outOfRangeError(bool isError,
246 : const TSourceLoc &loc,
247 : const char *reason,
248 : const char *token,
249 : const char *extraInfo)
250 : {
251 0 : if (isError)
252 : {
253 0 : error(loc, reason, token, extraInfo);
254 : }
255 : else
256 : {
257 0 : warning(loc, reason, token, extraInfo);
258 : }
259 0 : }
260 :
261 : //
262 : // Same error message for all places assignments don't work.
263 : //
264 0 : void TParseContext::assignError(const TSourceLoc &line, const char *op, TString left, TString right)
265 : {
266 0 : std::stringstream extraInfoStream;
267 0 : extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'";
268 0 : std::string extraInfo = extraInfoStream.str();
269 0 : error(line, "", op, extraInfo.c_str());
270 0 : }
271 :
272 : //
273 : // Same error message for all places unary operations don't work.
274 : //
275 0 : void TParseContext::unaryOpError(const TSourceLoc &line, const char *op, TString operand)
276 : {
277 0 : std::stringstream extraInfoStream;
278 : extraInfoStream << "no operation '" << op << "' exists that takes an operand of type "
279 0 : << operand << " (or there is no acceptable conversion)";
280 0 : std::string extraInfo = extraInfoStream.str();
281 0 : error(line, " wrong operand type", op, extraInfo.c_str());
282 0 : }
283 :
284 : //
285 : // Same error message for all binary operations don't work.
286 : //
287 0 : void TParseContext::binaryOpError(const TSourceLoc &line,
288 : const char *op,
289 : TString left,
290 : TString right)
291 : {
292 0 : std::stringstream extraInfoStream;
293 : extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '"
294 : << left << "' and a right operand of type '" << right
295 0 : << "' (or there is no acceptable conversion)";
296 0 : std::string extraInfo = extraInfoStream.str();
297 0 : error(line, " wrong operand types ", op, extraInfo.c_str());
298 0 : }
299 :
300 0 : void TParseContext::checkPrecisionSpecified(const TSourceLoc &line,
301 : TPrecision precision,
302 : TBasicType type)
303 : {
304 0 : if (!mChecksPrecisionErrors)
305 0 : return;
306 :
307 0 : if (precision != EbpUndefined && !SupportsPrecision(type))
308 : {
309 0 : error(line, "illegal type for precision qualifier", getBasicString(type));
310 : }
311 :
312 0 : if (precision == EbpUndefined)
313 : {
314 0 : switch (type)
315 : {
316 : case EbtFloat:
317 0 : error(line, "No precision specified for (float)", "");
318 0 : return;
319 : case EbtInt:
320 : case EbtUInt:
321 0 : UNREACHABLE(); // there's always a predeclared qualifier
322 : error(line, "No precision specified (int)", "");
323 : return;
324 : default:
325 0 : if (IsSampler(type))
326 : {
327 0 : error(line, "No precision specified (sampler)", "");
328 0 : return;
329 : }
330 0 : if (IsImage(type))
331 : {
332 0 : error(line, "No precision specified (image)", "");
333 0 : return;
334 : }
335 : }
336 : }
337 : }
338 :
339 : // Both test and if necessary, spit out an error, to see if the node is really
340 : // an l-value that can be operated on this way.
341 0 : bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIntermTyped *node)
342 : {
343 0 : TIntermSymbol *symNode = node->getAsSymbolNode();
344 0 : TIntermBinary *binaryNode = node->getAsBinaryNode();
345 0 : TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
346 :
347 0 : if (swizzleNode)
348 : {
349 0 : bool ok = checkCanBeLValue(line, op, swizzleNode->getOperand());
350 0 : if (ok && swizzleNode->hasDuplicateOffsets())
351 : {
352 0 : error(line, " l-value of swizzle cannot have duplicate components", op);
353 0 : return false;
354 : }
355 0 : return ok;
356 : }
357 :
358 0 : if (binaryNode)
359 : {
360 0 : switch (binaryNode->getOp())
361 : {
362 : case EOpIndexDirect:
363 : case EOpIndexIndirect:
364 : case EOpIndexDirectStruct:
365 : case EOpIndexDirectInterfaceBlock:
366 0 : return checkCanBeLValue(line, op, binaryNode->getLeft());
367 : default:
368 0 : break;
369 : }
370 0 : error(line, " l-value required", op);
371 0 : return false;
372 : }
373 :
374 0 : const char *symbol = 0;
375 0 : if (symNode != 0)
376 0 : symbol = symNode->getSymbol().c_str();
377 :
378 0 : const char *message = 0;
379 0 : switch (node->getQualifier())
380 : {
381 : case EvqConst:
382 0 : message = "can't modify a const";
383 0 : break;
384 : case EvqConstReadOnly:
385 0 : message = "can't modify a const";
386 0 : break;
387 : case EvqAttribute:
388 0 : message = "can't modify an attribute";
389 0 : break;
390 : case EvqFragmentIn:
391 0 : message = "can't modify an input";
392 0 : break;
393 : case EvqVertexIn:
394 0 : message = "can't modify an input";
395 0 : break;
396 : case EvqUniform:
397 0 : message = "can't modify a uniform";
398 0 : break;
399 : case EvqVaryingIn:
400 0 : message = "can't modify a varying";
401 0 : break;
402 : case EvqFragCoord:
403 0 : message = "can't modify gl_FragCoord";
404 0 : break;
405 : case EvqFrontFacing:
406 0 : message = "can't modify gl_FrontFacing";
407 0 : break;
408 : case EvqPointCoord:
409 0 : message = "can't modify gl_PointCoord";
410 0 : break;
411 : case EvqNumWorkGroups:
412 0 : message = "can't modify gl_NumWorkGroups";
413 0 : break;
414 : case EvqWorkGroupSize:
415 0 : message = "can't modify gl_WorkGroupSize";
416 0 : break;
417 : case EvqWorkGroupID:
418 0 : message = "can't modify gl_WorkGroupID";
419 0 : break;
420 : case EvqLocalInvocationID:
421 0 : message = "can't modify gl_LocalInvocationID";
422 0 : break;
423 : case EvqGlobalInvocationID:
424 0 : message = "can't modify gl_GlobalInvocationID";
425 0 : break;
426 : case EvqLocalInvocationIndex:
427 0 : message = "can't modify gl_LocalInvocationIndex";
428 0 : break;
429 : case EvqComputeIn:
430 0 : message = "can't modify work group size variable";
431 0 : break;
432 : default:
433 : //
434 : // Type that can't be written to?
435 : //
436 0 : if (node->getBasicType() == EbtVoid)
437 : {
438 0 : message = "can't modify void";
439 : }
440 0 : if (IsSampler(node->getBasicType()))
441 : {
442 0 : message = "can't modify a sampler";
443 : }
444 0 : if (IsImage(node->getBasicType()))
445 : {
446 0 : message = "can't modify an image";
447 : }
448 : }
449 :
450 0 : if (message == 0 && binaryNode == 0 && symNode == 0)
451 : {
452 0 : error(line, " l-value required", op);
453 :
454 0 : return false;
455 : }
456 :
457 : //
458 : // Everything else is okay, no error.
459 : //
460 0 : if (message == 0)
461 0 : return true;
462 :
463 : //
464 : // If we get here, we have an error and a message.
465 : //
466 0 : if (symNode)
467 : {
468 0 : std::stringstream extraInfoStream;
469 0 : extraInfoStream << "\"" << symbol << "\" (" << message << ")";
470 0 : std::string extraInfo = extraInfoStream.str();
471 0 : error(line, " l-value required", op, extraInfo.c_str());
472 : }
473 : else
474 : {
475 0 : std::stringstream extraInfoStream;
476 0 : extraInfoStream << "(" << message << ")";
477 0 : std::string extraInfo = extraInfoStream.str();
478 0 : error(line, " l-value required", op, extraInfo.c_str());
479 : }
480 :
481 0 : return false;
482 : }
483 :
484 : // Both test, and if necessary spit out an error, to see if the node is really
485 : // a constant.
486 0 : void TParseContext::checkIsConst(TIntermTyped *node)
487 : {
488 0 : if (node->getQualifier() != EvqConst)
489 : {
490 0 : error(node->getLine(), "constant expression required", "");
491 : }
492 0 : }
493 :
494 : // Both test, and if necessary spit out an error, to see if the node is really
495 : // an integer.
496 0 : void TParseContext::checkIsScalarInteger(TIntermTyped *node, const char *token)
497 : {
498 0 : if (!node->isScalarInt())
499 : {
500 0 : error(node->getLine(), "integer expression required", token);
501 : }
502 0 : }
503 :
504 : // Both test, and if necessary spit out an error, to see if we are currently
505 : // globally scoped.
506 0 : bool TParseContext::checkIsAtGlobalLevel(const TSourceLoc &line, const char *token)
507 : {
508 0 : if (!symbolTable.atGlobalLevel())
509 : {
510 0 : error(line, "only allowed at global scope", token);
511 0 : return false;
512 : }
513 0 : return true;
514 : }
515 :
516 : // For now, keep it simple: if it starts "gl_", it's reserved, independent
517 : // of scope. Except, if the symbol table is at the built-in push-level,
518 : // which is when we are parsing built-ins.
519 : // Also checks for "webgl_" and "_webgl_" reserved identifiers if parsing a
520 : // webgl shader.
521 0 : bool TParseContext::checkIsNotReserved(const TSourceLoc &line, const TString &identifier)
522 : {
523 : static const char *reservedErrMsg = "reserved built-in name";
524 0 : if (!symbolTable.atBuiltInLevel())
525 : {
526 0 : if (identifier.compare(0, 3, "gl_") == 0)
527 : {
528 0 : error(line, reservedErrMsg, "gl_");
529 0 : return false;
530 : }
531 0 : if (sh::IsWebGLBasedSpec(mShaderSpec))
532 : {
533 0 : if (identifier.compare(0, 6, "webgl_") == 0)
534 : {
535 0 : error(line, reservedErrMsg, "webgl_");
536 0 : return false;
537 : }
538 0 : if (identifier.compare(0, 7, "_webgl_") == 0)
539 : {
540 0 : error(line, reservedErrMsg, "_webgl_");
541 0 : return false;
542 : }
543 : }
544 0 : if (identifier.find("__") != TString::npos)
545 : {
546 0 : error(line,
547 : "identifiers containing two consecutive underscores (__) are reserved as "
548 : "possible future keywords",
549 0 : identifier.c_str());
550 0 : return false;
551 : }
552 : }
553 :
554 0 : return true;
555 : }
556 :
557 : // Make sure there is enough data provided to the constructor to build
558 : // something of the type of the constructor. Also returns the type of
559 : // the constructor.
560 0 : bool TParseContext::checkConstructorArguments(const TSourceLoc &line,
561 : TIntermNode *argumentsNode,
562 : const TFunction &function,
563 : TOperator op,
564 : const TType &type)
565 : {
566 0 : bool constructingMatrix = false;
567 0 : switch (op)
568 : {
569 : case EOpConstructMat2:
570 : case EOpConstructMat2x3:
571 : case EOpConstructMat2x4:
572 : case EOpConstructMat3x2:
573 : case EOpConstructMat3:
574 : case EOpConstructMat3x4:
575 : case EOpConstructMat4x2:
576 : case EOpConstructMat4x3:
577 : case EOpConstructMat4:
578 0 : constructingMatrix = true;
579 0 : break;
580 : default:
581 0 : break;
582 : }
583 :
584 : //
585 : // Note: It's okay to have too many components available, but not okay to have unused
586 : // arguments. 'full' will go to true when enough args have been seen. If we loop
587 : // again, there is an extra argument, so 'overfull' will become true.
588 : //
589 :
590 0 : size_t size = 0;
591 0 : bool full = false;
592 0 : bool overFull = false;
593 0 : bool matrixInMatrix = false;
594 0 : bool arrayArg = false;
595 0 : for (size_t i = 0; i < function.getParamCount(); ++i)
596 : {
597 0 : const TConstParameter ¶m = function.getParam(i);
598 0 : size += param.type->getObjectSize();
599 :
600 0 : if (constructingMatrix && param.type->isMatrix())
601 0 : matrixInMatrix = true;
602 0 : if (full)
603 0 : overFull = true;
604 0 : if (op != EOpConstructStruct && !type.isArray() && size >= type.getObjectSize())
605 0 : full = true;
606 0 : if (param.type->isArray())
607 0 : arrayArg = true;
608 : }
609 :
610 0 : if (type.isArray())
611 : {
612 : // The size of an unsized constructor should already have been determined.
613 0 : ASSERT(!type.isUnsizedArray());
614 0 : if (static_cast<size_t>(type.getArraySize()) != function.getParamCount())
615 : {
616 0 : error(line, "array constructor needs one argument per array element", "constructor");
617 0 : return false;
618 : }
619 : }
620 :
621 0 : if (arrayArg && op != EOpConstructStruct)
622 : {
623 0 : error(line, "constructing from a non-dereferenced array", "constructor");
624 0 : return false;
625 : }
626 :
627 0 : if (matrixInMatrix && !type.isArray())
628 : {
629 0 : if (function.getParamCount() != 1)
630 : {
631 : error(line, "constructing matrix from matrix can only take one argument",
632 0 : "constructor");
633 0 : return false;
634 : }
635 : }
636 :
637 0 : if (overFull)
638 : {
639 0 : error(line, "too many arguments", "constructor");
640 0 : return false;
641 : }
642 :
643 0 : if (op == EOpConstructStruct && !type.isArray() &&
644 0 : type.getStruct()->fields().size() != function.getParamCount())
645 : {
646 : error(line,
647 : "Number of constructor parameters does not match the number of structure fields",
648 0 : "constructor");
649 0 : return false;
650 : }
651 :
652 0 : if (!type.isMatrix() || !matrixInMatrix)
653 : {
654 0 : if ((op != EOpConstructStruct && size != 1 && size < type.getObjectSize()) ||
655 0 : (op == EOpConstructStruct && size < type.getObjectSize()))
656 : {
657 0 : error(line, "not enough data provided for construction", "constructor");
658 0 : return false;
659 : }
660 : }
661 :
662 0 : if (argumentsNode == nullptr)
663 : {
664 0 : error(line, "constructor does not have any arguments", "constructor");
665 0 : return false;
666 : }
667 :
668 0 : TIntermAggregate *argumentsAgg = argumentsNode->getAsAggregate();
669 0 : for (TIntermNode *&argNode : *argumentsAgg->getSequence())
670 : {
671 0 : TIntermTyped *argTyped = argNode->getAsTyped();
672 0 : ASSERT(argTyped != nullptr);
673 0 : if (op != EOpConstructStruct && IsSampler(argTyped->getBasicType()))
674 : {
675 0 : error(line, "cannot convert a sampler", "constructor");
676 0 : return false;
677 : }
678 0 : if (op != EOpConstructStruct && IsImage(argTyped->getBasicType()))
679 : {
680 0 : error(line, "cannot convert an image", "constructor");
681 0 : return false;
682 : }
683 0 : if (argTyped->getBasicType() == EbtVoid)
684 : {
685 0 : error(line, "cannot convert a void", "constructor");
686 0 : return false;
687 : }
688 : }
689 :
690 0 : if (type.isArray())
691 : {
692 : // GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of
693 : // the array.
694 0 : for (TIntermNode *&argNode : *argumentsAgg->getSequence())
695 : {
696 0 : const TType &argType = argNode->getAsTyped()->getType();
697 : // It has already been checked that the argument is not an array.
698 0 : ASSERT(!argType.isArray());
699 0 : if (!argType.sameElementType(type))
700 : {
701 0 : error(line, "Array constructor argument has an incorrect type", "Error");
702 0 : return false;
703 : }
704 : }
705 : }
706 0 : else if (op == EOpConstructStruct)
707 : {
708 0 : const TFieldList &fields = type.getStruct()->fields();
709 0 : TIntermSequence *args = argumentsAgg->getSequence();
710 :
711 0 : for (size_t i = 0; i < fields.size(); i++)
712 : {
713 0 : if (i >= args->size() || (*args)[i]->getAsTyped()->getType() != *fields[i]->type())
714 : {
715 : error(line, "Structure constructor arguments do not match structure fields",
716 0 : "Error");
717 0 : return false;
718 : }
719 : }
720 : }
721 :
722 0 : return true;
723 : }
724 :
725 : // This function checks to see if a void variable has been declared and raise an error message for
726 : // such a case
727 : //
728 : // returns true in case of an error
729 : //
730 0 : bool TParseContext::checkIsNonVoid(const TSourceLoc &line,
731 : const TString &identifier,
732 : const TBasicType &type)
733 : {
734 0 : if (type == EbtVoid)
735 : {
736 0 : error(line, "illegal use of type 'void'", identifier.c_str());
737 0 : return false;
738 : }
739 :
740 0 : return true;
741 : }
742 :
743 : // This function checks to see if the node (for the expression) contains a scalar boolean expression
744 : // or not.
745 0 : void TParseContext::checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type)
746 : {
747 0 : if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector())
748 : {
749 0 : error(line, "boolean expression expected", "");
750 : }
751 0 : }
752 :
753 : // This function checks to see if the node (for the expression) contains a scalar boolean expression
754 : // or not.
755 0 : void TParseContext::checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType)
756 : {
757 0 : if (pType.getBasicType() != EbtBool || pType.isAggregate())
758 : {
759 0 : error(line, "boolean expression expected", "");
760 : }
761 0 : }
762 :
763 0 : bool TParseContext::checkIsNotSampler(const TSourceLoc &line,
764 : const TTypeSpecifierNonArray &pType,
765 : const char *reason)
766 : {
767 0 : if (pType.type == EbtStruct)
768 : {
769 0 : if (ContainsSampler(*pType.userDef))
770 : {
771 0 : error(line, reason, getBasicString(pType.type), "(structure contains a sampler)");
772 0 : return false;
773 : }
774 :
775 0 : return true;
776 : }
777 0 : else if (IsSampler(pType.type))
778 : {
779 0 : error(line, reason, getBasicString(pType.type));
780 0 : return false;
781 : }
782 :
783 0 : return true;
784 : }
785 :
786 0 : bool TParseContext::checkIsNotImage(const TSourceLoc &line,
787 : const TTypeSpecifierNonArray &pType,
788 : const char *reason)
789 : {
790 0 : if (pType.type == EbtStruct)
791 : {
792 0 : if (ContainsImage(*pType.userDef))
793 : {
794 0 : error(line, reason, getBasicString(pType.type), "(structure contains an image)");
795 :
796 0 : return false;
797 : }
798 :
799 0 : return true;
800 : }
801 0 : else if (IsImage(pType.type))
802 : {
803 0 : error(line, reason, getBasicString(pType.type));
804 :
805 0 : return false;
806 : }
807 :
808 0 : return true;
809 : }
810 :
811 0 : void TParseContext::checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line,
812 : const TPublicType &pType)
813 : {
814 0 : if (pType.layoutQualifier.location != -1)
815 : {
816 : error(line, "location must only be specified for a single input or output variable",
817 0 : "location");
818 : }
819 0 : }
820 :
821 0 : void TParseContext::checkLocationIsNotSpecified(const TSourceLoc &location,
822 : const TLayoutQualifier &layoutQualifier)
823 : {
824 0 : if (layoutQualifier.location != -1)
825 : {
826 : error(location, "invalid layout qualifier:", "location",
827 0 : "only valid on program inputs and outputs");
828 : }
829 0 : }
830 :
831 0 : void TParseContext::checkOutParameterIsNotOpaqueType(const TSourceLoc &line,
832 : TQualifier qualifier,
833 : const TType &type)
834 : {
835 0 : checkOutParameterIsNotSampler(line, qualifier, type);
836 0 : checkOutParameterIsNotImage(line, qualifier, type);
837 0 : }
838 :
839 0 : void TParseContext::checkOutParameterIsNotSampler(const TSourceLoc &line,
840 : TQualifier qualifier,
841 : const TType &type)
842 : {
843 0 : ASSERT(qualifier == EvqOut || qualifier == EvqInOut);
844 0 : if (IsSampler(type.getBasicType()))
845 : {
846 0 : error(line, "samplers cannot be output parameters", type.getBasicString());
847 : }
848 0 : }
849 :
850 0 : void TParseContext::checkOutParameterIsNotImage(const TSourceLoc &line,
851 : TQualifier qualifier,
852 : const TType &type)
853 : {
854 0 : ASSERT(qualifier == EvqOut || qualifier == EvqInOut);
855 0 : if (IsImage(type.getBasicType()))
856 : {
857 0 : error(line, "images cannot be output parameters", type.getBasicString());
858 : }
859 0 : }
860 :
861 : // Do size checking for an array type's size.
862 0 : unsigned int TParseContext::checkIsValidArraySize(const TSourceLoc &line, TIntermTyped *expr)
863 : {
864 0 : TIntermConstantUnion *constant = expr->getAsConstantUnion();
865 :
866 : // TODO(oetuaho@nvidia.com): Get rid of the constant == nullptr check here once all constant
867 : // expressions can be folded. Right now we don't allow constant expressions that ANGLE can't
868 : // fold as array size.
869 0 : if (expr->getQualifier() != EvqConst || constant == nullptr || !constant->isScalarInt())
870 : {
871 0 : error(line, "array size must be a constant integer expression", "");
872 0 : return 1u;
873 : }
874 :
875 0 : unsigned int size = 0u;
876 :
877 0 : if (constant->getBasicType() == EbtUInt)
878 : {
879 0 : size = constant->getUConst(0);
880 : }
881 : else
882 : {
883 0 : int signedSize = constant->getIConst(0);
884 :
885 0 : if (signedSize < 0)
886 : {
887 0 : error(line, "array size must be non-negative", "");
888 0 : return 1u;
889 : }
890 :
891 0 : size = static_cast<unsigned int>(signedSize);
892 : }
893 :
894 0 : if (size == 0u)
895 : {
896 0 : error(line, "array size must be greater than zero", "");
897 0 : return 1u;
898 : }
899 :
900 : // The size of arrays is restricted here to prevent issues further down the
901 : // compiler/translator/driver stack. Shader Model 5 generation hardware is limited to
902 : // 4096 registers so this should be reasonable even for aggressively optimizable code.
903 0 : const unsigned int sizeLimit = 65536;
904 :
905 0 : if (size > sizeLimit)
906 : {
907 0 : error(line, "array size too large", "");
908 0 : return 1u;
909 : }
910 :
911 0 : return size;
912 : }
913 :
914 : // See if this qualifier can be an array.
915 0 : bool TParseContext::checkIsValidQualifierForArray(const TSourceLoc &line,
916 : const TPublicType &elementQualifier)
917 : {
918 0 : if ((elementQualifier.qualifier == EvqAttribute) ||
919 0 : (elementQualifier.qualifier == EvqVertexIn) ||
920 0 : (elementQualifier.qualifier == EvqConst && mShaderVersion < 300))
921 : {
922 0 : error(line, "cannot declare arrays of this qualifier",
923 0 : TType(elementQualifier).getQualifierString());
924 0 : return false;
925 : }
926 :
927 0 : return true;
928 : }
929 :
930 : // See if this element type can be formed into an array.
931 0 : bool TParseContext::checkIsValidTypeForArray(const TSourceLoc &line, const TPublicType &elementType)
932 : {
933 : //
934 : // Can the type be an array?
935 : //
936 0 : if (elementType.array)
937 : {
938 0 : error(line, "cannot declare arrays of arrays",
939 0 : TType(elementType).getCompleteString().c_str());
940 0 : return false;
941 : }
942 : // In ESSL1.00 shaders, structs cannot be varying (section 4.3.5). This is checked elsewhere.
943 : // In ESSL3.00 shaders, struct inputs/outputs are allowed but not arrays of structs (section
944 : // 4.3.4).
945 0 : if (mShaderVersion >= 300 && elementType.getBasicType() == EbtStruct &&
946 0 : sh::IsVarying(elementType.qualifier))
947 : {
948 0 : error(line, "cannot declare arrays of structs of this qualifier",
949 0 : TType(elementType).getCompleteString().c_str());
950 0 : return false;
951 : }
952 :
953 0 : return true;
954 : }
955 :
956 : // Check if this qualified element type can be formed into an array.
957 0 : bool TParseContext::checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation,
958 : const TPublicType &elementType)
959 : {
960 0 : if (checkIsValidTypeForArray(indexLocation, elementType))
961 : {
962 0 : return checkIsValidQualifierForArray(indexLocation, elementType);
963 : }
964 0 : return false;
965 : }
966 :
967 : // Enforce non-initializer type/qualifier rules.
968 0 : void TParseContext::checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
969 : const TString &identifier,
970 : TPublicType *type)
971 : {
972 0 : ASSERT(type != nullptr);
973 0 : if (type->qualifier == EvqConst)
974 : {
975 : // Make the qualifier make sense.
976 0 : type->qualifier = EvqTemporary;
977 :
978 : // Generate informative error messages for ESSL1.
979 : // In ESSL3 arrays and structures containing arrays can be constant.
980 0 : if (mShaderVersion < 300 && type->isStructureContainingArrays())
981 : {
982 0 : error(line,
983 : "structures containing arrays may not be declared constant since they cannot be "
984 : "initialized",
985 0 : identifier.c_str());
986 : }
987 : else
988 : {
989 0 : error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
990 : }
991 0 : return;
992 : }
993 0 : if (type->isUnsizedArray())
994 : {
995 0 : error(line, "implicitly sized arrays need to be initialized", identifier.c_str());
996 : }
997 : }
998 :
999 : // Do some simple checks that are shared between all variable declarations,
1000 : // and update the symbol table.
1001 : //
1002 : // Returns true if declaring the variable succeeded.
1003 : //
1004 0 : bool TParseContext::declareVariable(const TSourceLoc &line,
1005 : const TString &identifier,
1006 : const TType &type,
1007 : TVariable **variable)
1008 : {
1009 0 : ASSERT((*variable) == nullptr);
1010 :
1011 0 : bool needsReservedCheck = true;
1012 :
1013 : // gl_LastFragData may be redeclared with a new precision qualifier
1014 0 : if (type.isArray() && identifier.compare(0, 15, "gl_LastFragData") == 0)
1015 : {
1016 : const TVariable *maxDrawBuffers = static_cast<const TVariable *>(
1017 0 : symbolTable.findBuiltIn("gl_MaxDrawBuffers", mShaderVersion));
1018 0 : if (static_cast<int>(type.getArraySize()) == maxDrawBuffers->getConstPointer()->getIConst())
1019 : {
1020 0 : if (TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion))
1021 : {
1022 0 : needsReservedCheck = !checkCanUseExtension(line, builtInSymbol->getExtension());
1023 : }
1024 : }
1025 : else
1026 : {
1027 0 : error(line, "redeclaration of gl_LastFragData with size != gl_MaxDrawBuffers",
1028 0 : identifier.c_str());
1029 0 : return false;
1030 : }
1031 : }
1032 :
1033 0 : if (needsReservedCheck && !checkIsNotReserved(line, identifier))
1034 0 : return false;
1035 :
1036 0 : (*variable) = new TVariable(&identifier, type);
1037 0 : if (!symbolTable.declare(*variable))
1038 : {
1039 0 : error(line, "redefinition", identifier.c_str());
1040 0 : *variable = nullptr;
1041 0 : return false;
1042 : }
1043 :
1044 0 : if (!checkIsNonVoid(line, identifier, type.getBasicType()))
1045 0 : return false;
1046 :
1047 0 : return true;
1048 : }
1049 :
1050 0 : void TParseContext::checkIsParameterQualifierValid(
1051 : const TSourceLoc &line,
1052 : const TTypeQualifierBuilder &typeQualifierBuilder,
1053 : TType *type)
1054 : {
1055 0 : TTypeQualifier typeQualifier = typeQualifierBuilder.getParameterTypeQualifier(&mDiagnostics);
1056 :
1057 0 : if (typeQualifier.qualifier == EvqOut || typeQualifier.qualifier == EvqInOut)
1058 : {
1059 0 : checkOutParameterIsNotOpaqueType(line, typeQualifier.qualifier, *type);
1060 : }
1061 :
1062 0 : if (!IsImage(type->getBasicType()))
1063 : {
1064 0 : checkIsMemoryQualifierNotSpecified(typeQualifier.memoryQualifier, line);
1065 : }
1066 : else
1067 : {
1068 0 : type->setMemoryQualifier(typeQualifier.memoryQualifier);
1069 : }
1070 :
1071 0 : type->setQualifier(typeQualifier.qualifier);
1072 :
1073 0 : if (typeQualifier.precision != EbpUndefined)
1074 : {
1075 0 : type->setPrecision(typeQualifier.precision);
1076 : }
1077 0 : }
1078 :
1079 0 : bool TParseContext::checkCanUseExtension(const TSourceLoc &line, const TString &extension)
1080 : {
1081 0 : const TExtensionBehavior &extBehavior = extensionBehavior();
1082 0 : TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str());
1083 0 : if (iter == extBehavior.end())
1084 : {
1085 0 : error(line, "extension", extension.c_str(), "is not supported");
1086 0 : return false;
1087 : }
1088 : // In GLSL ES, an extension's default behavior is "disable".
1089 0 : if (iter->second == EBhDisable || iter->second == EBhUndefined)
1090 : {
1091 0 : error(line, "extension", extension.c_str(), "is disabled");
1092 0 : return false;
1093 : }
1094 0 : if (iter->second == EBhWarn)
1095 : {
1096 0 : warning(line, "extension", extension.c_str(), "is being used");
1097 0 : return true;
1098 : }
1099 :
1100 0 : return true;
1101 : }
1102 :
1103 : // These checks are common for all declarations starting a declarator list, and declarators that
1104 : // follow an empty declaration.
1105 0 : void TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType,
1106 : const TSourceLoc &identifierLocation)
1107 : {
1108 0 : switch (publicType.qualifier)
1109 : {
1110 : case EvqVaryingIn:
1111 : case EvqVaryingOut:
1112 : case EvqAttribute:
1113 : case EvqVertexIn:
1114 : case EvqFragmentOut:
1115 : case EvqComputeIn:
1116 0 : if (publicType.getBasicType() == EbtStruct)
1117 : {
1118 0 : error(identifierLocation, "cannot be used with a structure",
1119 0 : getQualifierString(publicType.qualifier));
1120 0 : return;
1121 : }
1122 :
1123 : default:
1124 0 : break;
1125 : }
1126 :
1127 0 : if (publicType.qualifier != EvqUniform &&
1128 0 : !checkIsNotSampler(identifierLocation, publicType.typeSpecifierNonArray,
1129 : "samplers must be uniform"))
1130 : {
1131 0 : return;
1132 : }
1133 0 : if (publicType.qualifier != EvqUniform &&
1134 0 : !checkIsNotImage(identifierLocation, publicType.typeSpecifierNonArray,
1135 : "images must be uniform"))
1136 : {
1137 0 : return;
1138 : }
1139 :
1140 : // check for layout qualifier issues
1141 0 : const TLayoutQualifier layoutQualifier = publicType.layoutQualifier;
1142 :
1143 0 : if (layoutQualifier.matrixPacking != EmpUnspecified)
1144 : {
1145 0 : error(identifierLocation, "layout qualifier",
1146 0 : getMatrixPackingString(layoutQualifier.matrixPacking),
1147 0 : "only valid for interface blocks");
1148 0 : return;
1149 : }
1150 :
1151 0 : if (layoutQualifier.blockStorage != EbsUnspecified)
1152 : {
1153 0 : error(identifierLocation, "layout qualifier",
1154 0 : getBlockStorageString(layoutQualifier.blockStorage),
1155 0 : "only valid for interface blocks");
1156 0 : return;
1157 : }
1158 :
1159 0 : if (publicType.qualifier != EvqVertexIn && publicType.qualifier != EvqFragmentOut)
1160 : {
1161 0 : checkLocationIsNotSpecified(identifierLocation, publicType.layoutQualifier);
1162 : }
1163 :
1164 0 : if (IsImage(publicType.getBasicType()))
1165 : {
1166 :
1167 0 : switch (layoutQualifier.imageInternalFormat)
1168 : {
1169 : case EiifRGBA32F:
1170 : case EiifRGBA16F:
1171 : case EiifR32F:
1172 : case EiifRGBA8:
1173 : case EiifRGBA8_SNORM:
1174 0 : if (!IsFloatImage(publicType.getBasicType()))
1175 : {
1176 0 : error(identifierLocation,
1177 : "internal image format requires a floating image type",
1178 0 : getBasicString(publicType.getBasicType()));
1179 0 : return;
1180 : }
1181 0 : break;
1182 : case EiifRGBA32I:
1183 : case EiifRGBA16I:
1184 : case EiifRGBA8I:
1185 : case EiifR32I:
1186 0 : if (!IsIntegerImage(publicType.getBasicType()))
1187 : {
1188 0 : error(identifierLocation,
1189 : "internal image format requires an integer image type",
1190 0 : getBasicString(publicType.getBasicType()));
1191 0 : return;
1192 : }
1193 0 : break;
1194 : case EiifRGBA32UI:
1195 : case EiifRGBA16UI:
1196 : case EiifRGBA8UI:
1197 : case EiifR32UI:
1198 0 : if (!IsUnsignedImage(publicType.getBasicType()))
1199 : {
1200 0 : error(identifierLocation,
1201 : "internal image format requires an unsigned image type",
1202 0 : getBasicString(publicType.getBasicType()));
1203 0 : return;
1204 : }
1205 0 : break;
1206 : case EiifUnspecified:
1207 0 : error(identifierLocation, "layout qualifier", "No image internal format specified");
1208 0 : return;
1209 : default:
1210 0 : error(identifierLocation, "layout qualifier", "unrecognized token");
1211 0 : return;
1212 : }
1213 :
1214 : // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
1215 0 : switch (layoutQualifier.imageInternalFormat)
1216 : {
1217 : case EiifR32F:
1218 : case EiifR32I:
1219 : case EiifR32UI:
1220 0 : break;
1221 : default:
1222 0 : if (!publicType.memoryQualifier.readonly && !publicType.memoryQualifier.writeonly)
1223 : {
1224 : error(identifierLocation, "layout qualifier",
1225 : "Except for images with the r32f, r32i and r32ui format qualifiers, "
1226 0 : "image variables must be qualified readonly and/or writeonly");
1227 0 : return;
1228 : }
1229 0 : break;
1230 : }
1231 : }
1232 : else
1233 : {
1234 :
1235 0 : if (!checkInternalFormatIsNotSpecified(identifierLocation,
1236 0 : layoutQualifier.imageInternalFormat))
1237 : {
1238 0 : return;
1239 : }
1240 :
1241 0 : if (!checkIsMemoryQualifierNotSpecified(publicType.memoryQualifier, identifierLocation))
1242 : {
1243 0 : return;
1244 : }
1245 : }
1246 : }
1247 :
1248 0 : void TParseContext::checkLayoutQualifierSupported(const TSourceLoc &location,
1249 : const TString &layoutQualifierName,
1250 : int versionRequired)
1251 : {
1252 :
1253 0 : if (mShaderVersion < versionRequired)
1254 : {
1255 0 : error(location, "invalid layout qualifier:", layoutQualifierName.c_str(), "not supported");
1256 : }
1257 0 : }
1258 :
1259 0 : bool TParseContext::checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
1260 : const TLayoutQualifier &layoutQualifier)
1261 : {
1262 0 : const sh::WorkGroupSize &localSize = layoutQualifier.localSize;
1263 0 : for (size_t i = 0u; i < localSize.size(); ++i)
1264 : {
1265 0 : if (localSize[i] != -1)
1266 : {
1267 0 : error(location, "invalid layout qualifier:", getWorkGroupSizeString(i),
1268 0 : "only valid when used with 'in' in a compute shader global layout declaration");
1269 0 : return false;
1270 : }
1271 : }
1272 :
1273 0 : return true;
1274 : }
1275 :
1276 0 : bool TParseContext::checkInternalFormatIsNotSpecified(const TSourceLoc &location,
1277 : TLayoutImageInternalFormat internalFormat)
1278 : {
1279 0 : if (internalFormat != EiifUnspecified)
1280 : {
1281 0 : error(location, "invalid layout qualifier:", getImageInternalFormatString(internalFormat),
1282 0 : "only valid when used with images");
1283 0 : return false;
1284 : }
1285 0 : return true;
1286 : }
1287 :
1288 0 : void TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate,
1289 : TIntermAggregate *fnCall)
1290 : {
1291 0 : for (size_t i = 0; i < fnCandidate->getParamCount(); ++i)
1292 : {
1293 0 : TQualifier qual = fnCandidate->getParam(i).type->getQualifier();
1294 0 : if (qual == EvqOut || qual == EvqInOut)
1295 : {
1296 0 : TIntermTyped *argument = (*(fnCall->getSequence()))[i]->getAsTyped();
1297 0 : if (!checkCanBeLValue(argument->getLine(), "assign", argument))
1298 : {
1299 0 : error(argument->getLine(),
1300 0 : "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
1301 0 : return;
1302 : }
1303 : }
1304 : }
1305 : }
1306 :
1307 0 : void TParseContext::checkInvariantVariableQualifier(bool invariant,
1308 : const TQualifier qualifier,
1309 : const TSourceLoc &invariantLocation)
1310 : {
1311 0 : if (!invariant)
1312 0 : return;
1313 :
1314 0 : if (mShaderVersion < 300)
1315 : {
1316 : // input variables in the fragment shader can be also qualified as invariant
1317 0 : if (!sh::CanBeInvariantESSL1(qualifier))
1318 : {
1319 0 : error(invariantLocation, "Cannot be qualified as invariant.", "invariant");
1320 : }
1321 : }
1322 : else
1323 : {
1324 0 : if (!sh::CanBeInvariantESSL3OrGreater(qualifier))
1325 : {
1326 0 : error(invariantLocation, "Cannot be qualified as invariant.", "invariant");
1327 : }
1328 : }
1329 : }
1330 :
1331 0 : bool TParseContext::supportsExtension(const char *extension)
1332 : {
1333 0 : const TExtensionBehavior &extbehavior = extensionBehavior();
1334 0 : TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
1335 0 : return (iter != extbehavior.end());
1336 : }
1337 :
1338 0 : bool TParseContext::isExtensionEnabled(const char *extension) const
1339 : {
1340 0 : return ::IsExtensionEnabled(extensionBehavior(), extension);
1341 : }
1342 :
1343 0 : void TParseContext::handleExtensionDirective(const TSourceLoc &loc,
1344 : const char *extName,
1345 : const char *behavior)
1346 : {
1347 0 : pp::SourceLocation srcLoc;
1348 0 : srcLoc.file = loc.first_file;
1349 0 : srcLoc.line = loc.first_line;
1350 0 : mDirectiveHandler.handleExtension(srcLoc, extName, behavior);
1351 0 : }
1352 :
1353 0 : void TParseContext::handlePragmaDirective(const TSourceLoc &loc,
1354 : const char *name,
1355 : const char *value,
1356 : bool stdgl)
1357 : {
1358 0 : pp::SourceLocation srcLoc;
1359 0 : srcLoc.file = loc.first_file;
1360 0 : srcLoc.line = loc.first_line;
1361 0 : mDirectiveHandler.handlePragma(srcLoc, name, value, stdgl);
1362 0 : }
1363 :
1364 0 : sh::WorkGroupSize TParseContext::getComputeShaderLocalSize() const
1365 : {
1366 : sh::WorkGroupSize result;
1367 0 : for (size_t i = 0u; i < result.size(); ++i)
1368 : {
1369 0 : if (mComputeShaderLocalSizeDeclared && mComputeShaderLocalSize[i] == -1)
1370 : {
1371 0 : result[i] = 1;
1372 : }
1373 : else
1374 : {
1375 0 : result[i] = mComputeShaderLocalSize[i];
1376 : }
1377 : }
1378 0 : return result;
1379 : }
1380 :
1381 : /////////////////////////////////////////////////////////////////////////////////
1382 : //
1383 : // Non-Errors.
1384 : //
1385 : /////////////////////////////////////////////////////////////////////////////////
1386 :
1387 0 : const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location,
1388 : const TString *name,
1389 : const TSymbol *symbol)
1390 : {
1391 0 : const TVariable *variable = NULL;
1392 :
1393 0 : if (!symbol)
1394 : {
1395 0 : error(location, "undeclared identifier", name->c_str());
1396 : }
1397 0 : else if (!symbol->isVariable())
1398 : {
1399 0 : error(location, "variable expected", name->c_str());
1400 : }
1401 : else
1402 : {
1403 0 : variable = static_cast<const TVariable *>(symbol);
1404 :
1405 0 : if (symbolTable.findBuiltIn(variable->getName(), mShaderVersion) &&
1406 0 : !variable->getExtension().empty())
1407 : {
1408 0 : checkCanUseExtension(location, variable->getExtension());
1409 : }
1410 :
1411 : // Reject shaders using both gl_FragData and gl_FragColor
1412 0 : TQualifier qualifier = variable->getType().getQualifier();
1413 0 : if (qualifier == EvqFragData || qualifier == EvqSecondaryFragDataEXT)
1414 : {
1415 0 : mUsesFragData = true;
1416 : }
1417 0 : else if (qualifier == EvqFragColor || qualifier == EvqSecondaryFragColorEXT)
1418 : {
1419 0 : mUsesFragColor = true;
1420 : }
1421 0 : if (qualifier == EvqSecondaryFragDataEXT || qualifier == EvqSecondaryFragColorEXT)
1422 : {
1423 0 : mUsesSecondaryOutputs = true;
1424 : }
1425 :
1426 : // This validation is not quite correct - it's only an error to write to
1427 : // both FragData and FragColor. For simplicity, and because users shouldn't
1428 : // be rewarded for reading from undefined varaibles, return an error
1429 : // if they are both referenced, rather than assigned.
1430 0 : if (mUsesFragData && mUsesFragColor)
1431 : {
1432 0 : const char *errorMessage = "cannot use both gl_FragData and gl_FragColor";
1433 0 : if (mUsesSecondaryOutputs)
1434 : {
1435 0 : errorMessage =
1436 : "cannot use both output variable sets (gl_FragData, gl_SecondaryFragDataEXT)"
1437 : " and (gl_FragColor, gl_SecondaryFragColorEXT)";
1438 : }
1439 0 : error(location, errorMessage, name->c_str());
1440 : }
1441 :
1442 : // GLSL ES 3.1 Revision 4, 7.1.3 Compute Shader Special Variables
1443 0 : if (getShaderType() == GL_COMPUTE_SHADER && !mComputeShaderLocalSizeDeclared &&
1444 : qualifier == EvqWorkGroupSize)
1445 : {
1446 : error(location,
1447 : "It is an error to use gl_WorkGroupSize before declaring the local group size",
1448 0 : "gl_WorkGroupSize");
1449 : }
1450 : }
1451 :
1452 0 : if (!variable)
1453 : {
1454 0 : TType type(EbtFloat, EbpUndefined);
1455 0 : TVariable *fakeVariable = new TVariable(name, type);
1456 0 : symbolTable.declare(fakeVariable);
1457 0 : variable = fakeVariable;
1458 : }
1459 :
1460 0 : return variable;
1461 : }
1462 :
1463 0 : TIntermTyped *TParseContext::parseVariableIdentifier(const TSourceLoc &location,
1464 : const TString *name,
1465 : const TSymbol *symbol)
1466 : {
1467 0 : const TVariable *variable = getNamedVariable(location, name, symbol);
1468 :
1469 0 : if (variable->getConstPointer())
1470 : {
1471 0 : const TConstantUnion *constArray = variable->getConstPointer();
1472 0 : return intermediate.addConstantUnion(constArray, variable->getType(), location);
1473 : }
1474 0 : else if (variable->getType().getQualifier() == EvqWorkGroupSize &&
1475 0 : mComputeShaderLocalSizeDeclared)
1476 : {
1477 : // gl_WorkGroupSize can be used to size arrays according to the ESSL 3.10.4 spec, so it
1478 : // needs to be added to the AST as a constant and not as a symbol.
1479 0 : sh::WorkGroupSize workGroupSize = getComputeShaderLocalSize();
1480 0 : TConstantUnion *constArray = new TConstantUnion[3];
1481 0 : for (size_t i = 0; i < 3; ++i)
1482 : {
1483 0 : constArray[i].setUConst(static_cast<unsigned int>(workGroupSize[i]));
1484 : }
1485 :
1486 0 : ASSERT(variable->getType().getBasicType() == EbtUInt);
1487 0 : ASSERT(variable->getType().getObjectSize() == 3);
1488 :
1489 0 : TType type(variable->getType());
1490 0 : type.setQualifier(EvqConst);
1491 0 : return intermediate.addConstantUnion(constArray, type, location);
1492 : }
1493 : else
1494 : {
1495 0 : return intermediate.addSymbol(variable->getUniqueId(), variable->getName(),
1496 0 : variable->getType(), location);
1497 : }
1498 : }
1499 :
1500 : //
1501 : // Look up a function name in the symbol table, and make sure it is a function.
1502 : //
1503 : // Return the function symbol if found, otherwise 0.
1504 : //
1505 0 : const TFunction *TParseContext::findFunction(const TSourceLoc &line,
1506 : TFunction *call,
1507 : int inputShaderVersion,
1508 : bool *builtIn)
1509 : {
1510 : // First find by unmangled name to check whether the function name has been
1511 : // hidden by a variable name or struct typename.
1512 : // If a function is found, check for one with a matching argument list.
1513 0 : const TSymbol *symbol = symbolTable.find(call->getName(), inputShaderVersion, builtIn);
1514 0 : if (symbol == 0 || symbol->isFunction())
1515 : {
1516 0 : symbol = symbolTable.find(call->getMangledName(), inputShaderVersion, builtIn);
1517 : }
1518 :
1519 0 : if (symbol == 0)
1520 : {
1521 0 : error(line, "no matching overloaded function found", call->getName().c_str());
1522 0 : return 0;
1523 : }
1524 :
1525 0 : if (!symbol->isFunction())
1526 : {
1527 0 : error(line, "function name expected", call->getName().c_str());
1528 0 : return 0;
1529 : }
1530 :
1531 0 : return static_cast<const TFunction *>(symbol);
1532 : }
1533 :
1534 : //
1535 : // Initializers show up in several places in the grammar. Have one set of
1536 : // code to handle them here.
1537 : //
1538 : // Returns true on error, false if no error
1539 : //
1540 0 : bool TParseContext::executeInitializer(const TSourceLoc &line,
1541 : const TString &identifier,
1542 : const TPublicType &pType,
1543 : TIntermTyped *initializer,
1544 : TIntermBinary **initNode)
1545 : {
1546 0 : ASSERT(initNode != nullptr);
1547 0 : ASSERT(*initNode == nullptr);
1548 0 : TType type = TType(pType);
1549 :
1550 0 : TVariable *variable = nullptr;
1551 0 : if (type.isUnsizedArray())
1552 : {
1553 : // We have not checked yet whether the initializer actually is an array or not.
1554 0 : if (initializer->isArray())
1555 : {
1556 0 : type.setArraySize(initializer->getArraySize());
1557 : }
1558 : else
1559 : {
1560 : // Having a non-array initializer for an unsized array will result in an error later,
1561 : // so we don't generate an error message here.
1562 0 : type.setArraySize(1u);
1563 : }
1564 : }
1565 0 : if (!declareVariable(line, identifier, type, &variable))
1566 : {
1567 0 : return true;
1568 : }
1569 :
1570 0 : bool globalInitWarning = false;
1571 0 : if (symbolTable.atGlobalLevel() &&
1572 0 : !ValidateGlobalInitializer(initializer, this, &globalInitWarning))
1573 : {
1574 : // Error message does not completely match behavior with ESSL 1.00, but
1575 : // we want to steer developers towards only using constant expressions.
1576 0 : error(line, "global variable initializers must be constant expressions", "=");
1577 0 : return true;
1578 : }
1579 0 : if (globalInitWarning)
1580 : {
1581 : warning(
1582 : line,
1583 : "global variable initializers should be constant expressions "
1584 : "(uniforms and globals are allowed in global initializers for legacy compatibility)",
1585 0 : "=");
1586 : }
1587 :
1588 : //
1589 : // identifier must be of type constant, a global, or a temporary
1590 : //
1591 0 : TQualifier qualifier = variable->getType().getQualifier();
1592 0 : if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst))
1593 : {
1594 0 : error(line, " cannot initialize this type of qualifier ",
1595 0 : variable->getType().getQualifierString());
1596 0 : return true;
1597 : }
1598 : //
1599 : // test for and propagate constant
1600 : //
1601 :
1602 0 : if (qualifier == EvqConst)
1603 : {
1604 0 : if (qualifier != initializer->getType().getQualifier())
1605 : {
1606 0 : std::stringstream extraInfoStream;
1607 0 : extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
1608 0 : std::string extraInfo = extraInfoStream.str();
1609 0 : error(line, " assigning non-constant to", "=", extraInfo.c_str());
1610 0 : variable->getType().setQualifier(EvqTemporary);
1611 0 : return true;
1612 : }
1613 0 : if (type != initializer->getType())
1614 : {
1615 0 : error(line, " non-matching types for const initializer ",
1616 0 : variable->getType().getQualifierString());
1617 0 : variable->getType().setQualifier(EvqTemporary);
1618 0 : return true;
1619 : }
1620 :
1621 : // Save the constant folded value to the variable if possible. For example array
1622 : // initializers are not folded, since that way copying the array literal to multiple places
1623 : // in the shader is avoided.
1624 : // TODO(oetuaho@nvidia.com): Consider constant folding array initialization in cases where
1625 : // it would be beneficial.
1626 0 : if (initializer->getAsConstantUnion())
1627 : {
1628 0 : variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
1629 0 : *initNode = nullptr;
1630 0 : return false;
1631 : }
1632 0 : else if (initializer->getAsSymbolNode())
1633 : {
1634 : const TSymbol *symbol =
1635 0 : symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), 0);
1636 0 : const TVariable *tVar = static_cast<const TVariable *>(symbol);
1637 :
1638 0 : const TConstantUnion *constArray = tVar->getConstPointer();
1639 0 : if (constArray)
1640 : {
1641 0 : variable->shareConstPointer(constArray);
1642 0 : *initNode = nullptr;
1643 0 : return false;
1644 : }
1645 : }
1646 : }
1647 :
1648 0 : TIntermSymbol *intermSymbol = intermediate.addSymbol(
1649 0 : variable->getUniqueId(), variable->getName(), variable->getType(), line);
1650 0 : *initNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
1651 0 : if (*initNode == nullptr)
1652 : {
1653 0 : assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
1654 0 : return true;
1655 : }
1656 :
1657 0 : return false;
1658 : }
1659 :
1660 0 : void TParseContext::addFullySpecifiedType(TPublicType *typeSpecifier)
1661 : {
1662 0 : checkPrecisionSpecified(typeSpecifier->getLine(), typeSpecifier->precision,
1663 0 : typeSpecifier->getBasicType());
1664 :
1665 0 : if (mShaderVersion < 300 && typeSpecifier->array)
1666 : {
1667 0 : error(typeSpecifier->getLine(), "not supported", "first-class array");
1668 0 : typeSpecifier->clearArrayness();
1669 : }
1670 0 : }
1671 :
1672 0 : TPublicType TParseContext::addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
1673 : const TPublicType &typeSpecifier)
1674 : {
1675 0 : TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics);
1676 :
1677 0 : TPublicType returnType = typeSpecifier;
1678 0 : returnType.qualifier = typeQualifier.qualifier;
1679 0 : returnType.invariant = typeQualifier.invariant;
1680 0 : returnType.layoutQualifier = typeQualifier.layoutQualifier;
1681 0 : returnType.memoryQualifier = typeQualifier.memoryQualifier;
1682 0 : returnType.precision = typeSpecifier.precision;
1683 :
1684 0 : if (typeQualifier.precision != EbpUndefined)
1685 : {
1686 0 : returnType.precision = typeQualifier.precision;
1687 : }
1688 :
1689 0 : checkPrecisionSpecified(typeSpecifier.getLine(), returnType.precision,
1690 0 : typeSpecifier.getBasicType());
1691 :
1692 0 : checkInvariantVariableQualifier(returnType.invariant, returnType.qualifier,
1693 0 : typeSpecifier.getLine());
1694 :
1695 0 : checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), returnType.layoutQualifier);
1696 :
1697 0 : if (mShaderVersion < 300)
1698 : {
1699 0 : if (typeSpecifier.array)
1700 : {
1701 0 : error(typeSpecifier.getLine(), "not supported", "first-class array");
1702 0 : returnType.clearArrayness();
1703 : }
1704 :
1705 0 : if (returnType.qualifier == EvqAttribute &&
1706 0 : (typeSpecifier.getBasicType() == EbtBool || typeSpecifier.getBasicType() == EbtInt))
1707 : {
1708 0 : error(typeSpecifier.getLine(), "cannot be bool or int",
1709 0 : getQualifierString(returnType.qualifier));
1710 : }
1711 :
1712 0 : if ((returnType.qualifier == EvqVaryingIn || returnType.qualifier == EvqVaryingOut) &&
1713 0 : (typeSpecifier.getBasicType() == EbtBool || typeSpecifier.getBasicType() == EbtInt))
1714 : {
1715 0 : error(typeSpecifier.getLine(), "cannot be bool or int",
1716 0 : getQualifierString(returnType.qualifier));
1717 : }
1718 : }
1719 : else
1720 : {
1721 0 : if (!returnType.layoutQualifier.isEmpty())
1722 : {
1723 0 : checkIsAtGlobalLevel(typeSpecifier.getLine(), "layout");
1724 : }
1725 0 : if (sh::IsVarying(returnType.qualifier) || returnType.qualifier == EvqVertexIn ||
1726 0 : returnType.qualifier == EvqFragmentOut)
1727 : {
1728 0 : checkInputOutputTypeIsValidES3(returnType.qualifier, typeSpecifier,
1729 0 : typeSpecifier.getLine());
1730 : }
1731 0 : if (returnType.qualifier == EvqComputeIn)
1732 : {
1733 0 : error(typeSpecifier.getLine(), "'in' can be only used to specify the local group size",
1734 0 : "in");
1735 : }
1736 : }
1737 :
1738 0 : return returnType;
1739 : }
1740 :
1741 0 : void TParseContext::checkInputOutputTypeIsValidES3(const TQualifier qualifier,
1742 : const TPublicType &type,
1743 : const TSourceLoc &qualifierLocation)
1744 : {
1745 : // An input/output variable can never be bool or a sampler. Samplers are checked elsewhere.
1746 0 : if (type.getBasicType() == EbtBool)
1747 : {
1748 0 : error(qualifierLocation, "cannot be bool", getQualifierString(qualifier));
1749 : }
1750 :
1751 : // Specific restrictions apply for vertex shader inputs and fragment shader outputs.
1752 0 : switch (qualifier)
1753 : {
1754 : case EvqVertexIn:
1755 : // ESSL 3.00 section 4.3.4
1756 0 : if (type.array)
1757 : {
1758 0 : error(qualifierLocation, "cannot be array", getQualifierString(qualifier));
1759 : }
1760 : // Vertex inputs with a struct type are disallowed in singleDeclarationErrorCheck
1761 0 : return;
1762 : case EvqFragmentOut:
1763 : // ESSL 3.00 section 4.3.6
1764 0 : if (type.typeSpecifierNonArray.isMatrix())
1765 : {
1766 0 : error(qualifierLocation, "cannot be matrix", getQualifierString(qualifier));
1767 : }
1768 : // Fragment outputs with a struct type are disallowed in singleDeclarationErrorCheck
1769 0 : return;
1770 : default:
1771 0 : break;
1772 : }
1773 :
1774 : // Vertex shader outputs / fragment shader inputs have a different, slightly more lenient set of
1775 : // restrictions.
1776 : bool typeContainsIntegers =
1777 0 : (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt ||
1778 0 : type.isStructureContainingType(EbtInt) || type.isStructureContainingType(EbtUInt));
1779 0 : if (typeContainsIntegers && qualifier != EvqFlatIn && qualifier != EvqFlatOut)
1780 : {
1781 0 : error(qualifierLocation, "must use 'flat' interpolation here",
1782 0 : getQualifierString(qualifier));
1783 : }
1784 :
1785 0 : if (type.getBasicType() == EbtStruct)
1786 : {
1787 : // ESSL 3.00 sections 4.3.4 and 4.3.6.
1788 : // These restrictions are only implied by the ESSL 3.00 spec, but
1789 : // the ESSL 3.10 spec lists these restrictions explicitly.
1790 0 : if (type.array)
1791 : {
1792 0 : error(qualifierLocation, "cannot be an array of structures",
1793 0 : getQualifierString(qualifier));
1794 : }
1795 0 : if (type.isStructureContainingArrays())
1796 : {
1797 0 : error(qualifierLocation, "cannot be a structure containing an array",
1798 0 : getQualifierString(qualifier));
1799 : }
1800 0 : if (type.isStructureContainingType(EbtStruct))
1801 : {
1802 0 : error(qualifierLocation, "cannot be a structure containing a structure",
1803 0 : getQualifierString(qualifier));
1804 : }
1805 0 : if (type.isStructureContainingType(EbtBool))
1806 : {
1807 0 : error(qualifierLocation, "cannot be a structure containing a bool",
1808 0 : getQualifierString(qualifier));
1809 : }
1810 : }
1811 : }
1812 :
1813 0 : void TParseContext::checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier)
1814 : {
1815 0 : if (qualifier.getType() == QtStorage)
1816 : {
1817 : const TStorageQualifierWrapper &storageQualifier =
1818 0 : static_cast<const TStorageQualifierWrapper &>(qualifier);
1819 0 : if (!declaringFunction() && storageQualifier.getQualifier() != EvqConst &&
1820 0 : !symbolTable.atGlobalLevel())
1821 : {
1822 0 : error(storageQualifier.getLine(),
1823 : "Local variables can only use the const storage qualifier.",
1824 0 : storageQualifier.getQualifierString().c_str());
1825 : }
1826 : }
1827 0 : }
1828 :
1829 0 : bool TParseContext::checkIsMemoryQualifierNotSpecified(const TMemoryQualifier &memoryQualifier,
1830 : const TSourceLoc &location)
1831 : {
1832 0 : if (memoryQualifier.readonly)
1833 : {
1834 0 : error(location, "Only allowed with images.", "readonly");
1835 0 : return false;
1836 : }
1837 0 : if (memoryQualifier.writeonly)
1838 : {
1839 0 : error(location, "Only allowed with images.", "writeonly");
1840 0 : return false;
1841 : }
1842 0 : if (memoryQualifier.coherent)
1843 : {
1844 0 : error(location, "Only allowed with images.", "coherent");
1845 0 : return false;
1846 : }
1847 0 : if (memoryQualifier.restrictQualifier)
1848 : {
1849 0 : error(location, "Only allowed with images.", "restrict");
1850 0 : return false;
1851 : }
1852 0 : if (memoryQualifier.volatileQualifier)
1853 : {
1854 0 : error(location, "Only allowed with images.", "volatile");
1855 0 : return false;
1856 : }
1857 0 : return true;
1858 : }
1859 :
1860 0 : TIntermDeclaration *TParseContext::parseSingleDeclaration(
1861 : TPublicType &publicType,
1862 : const TSourceLoc &identifierOrTypeLocation,
1863 : const TString &identifier)
1864 : {
1865 0 : TType type(publicType);
1866 0 : if ((mCompileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL) &&
1867 0 : mDirectiveHandler.pragma().stdgl.invariantAll)
1868 : {
1869 0 : TQualifier qualifier = type.getQualifier();
1870 :
1871 : // The directive handler has already taken care of rejecting invalid uses of this pragma
1872 : // (for example, in ESSL 3.00 fragment shaders), so at this point, flatten it into all
1873 : // affected variable declarations:
1874 : //
1875 : // 1. Built-in special variables which are inputs to the fragment shader. (These are handled
1876 : // elsewhere, in TranslatorGLSL.)
1877 : //
1878 : // 2. Outputs from vertex shaders in ESSL 1.00 and 3.00 (EvqVaryingOut and EvqVertexOut). It
1879 : // is actually less likely that there will be bugs in the handling of ESSL 3.00 shaders, but
1880 : // the way this is currently implemented we have to enable this compiler option before
1881 : // parsing the shader and determining the shading language version it uses. If this were
1882 : // implemented as a post-pass, the workaround could be more targeted.
1883 : //
1884 : // 3. Inputs in ESSL 1.00 fragment shaders (EvqVaryingIn). This is somewhat in violation of
1885 : // the specification, but there are desktop OpenGL drivers that expect that this is the
1886 : // behavior of the #pragma when specified in ESSL 1.00 fragment shaders.
1887 0 : if (qualifier == EvqVaryingOut || qualifier == EvqVertexOut || qualifier == EvqVaryingIn)
1888 : {
1889 0 : type.setInvariant(true);
1890 : }
1891 : }
1892 :
1893 0 : TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, type, identifierOrTypeLocation);
1894 :
1895 0 : bool emptyDeclaration = (identifier == "");
1896 :
1897 0 : mDeferredSingleDeclarationErrorCheck = emptyDeclaration;
1898 :
1899 0 : TIntermDeclaration *declaration = new TIntermDeclaration();
1900 0 : declaration->setLine(identifierOrTypeLocation);
1901 :
1902 0 : if (emptyDeclaration)
1903 : {
1904 0 : if (publicType.isUnsizedArray())
1905 : {
1906 : // ESSL3 spec section 4.1.9: Array declaration which leaves the size unspecified is an
1907 : // error. It is assumed that this applies to empty declarations as well.
1908 0 : error(identifierOrTypeLocation, "empty array declaration needs to specify a size",
1909 0 : identifier.c_str());
1910 : }
1911 : }
1912 : else
1913 : {
1914 0 : singleDeclarationErrorCheck(publicType, identifierOrTypeLocation);
1915 :
1916 0 : checkCanBeDeclaredWithoutInitializer(identifierOrTypeLocation, identifier, &publicType);
1917 :
1918 0 : TVariable *variable = nullptr;
1919 0 : declareVariable(identifierOrTypeLocation, identifier, type, &variable);
1920 :
1921 0 : if (variable && symbol)
1922 : {
1923 0 : symbol->setId(variable->getUniqueId());
1924 : }
1925 : }
1926 :
1927 : // We append the symbol even if the declaration is empty, mainly because of struct declarations
1928 : // that may just declare a type.
1929 0 : declaration->appendDeclarator(symbol);
1930 :
1931 0 : return declaration;
1932 : }
1933 :
1934 0 : TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(TPublicType &publicType,
1935 : const TSourceLoc &identifierLocation,
1936 : const TString &identifier,
1937 : const TSourceLoc &indexLocation,
1938 : TIntermTyped *indexExpression)
1939 : {
1940 0 : mDeferredSingleDeclarationErrorCheck = false;
1941 :
1942 0 : singleDeclarationErrorCheck(publicType, identifierLocation);
1943 :
1944 0 : checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &publicType);
1945 :
1946 0 : checkIsValidTypeAndQualifierForArray(indexLocation, publicType);
1947 :
1948 0 : TType arrayType(publicType);
1949 :
1950 0 : unsigned int size = checkIsValidArraySize(identifierLocation, indexExpression);
1951 : // Make the type an array even if size check failed.
1952 : // This ensures useless error messages regarding the variable's non-arrayness won't follow.
1953 0 : arrayType.setArraySize(size);
1954 :
1955 0 : TVariable *variable = nullptr;
1956 0 : declareVariable(identifierLocation, identifier, arrayType, &variable);
1957 :
1958 0 : TIntermDeclaration *declaration = new TIntermDeclaration();
1959 0 : declaration->setLine(identifierLocation);
1960 :
1961 0 : TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation);
1962 0 : if (variable && symbol)
1963 : {
1964 0 : symbol->setId(variable->getUniqueId());
1965 0 : declaration->appendDeclarator(symbol);
1966 : }
1967 :
1968 0 : return declaration;
1969 : }
1970 :
1971 0 : TIntermDeclaration *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType,
1972 : const TSourceLoc &identifierLocation,
1973 : const TString &identifier,
1974 : const TSourceLoc &initLocation,
1975 : TIntermTyped *initializer)
1976 : {
1977 0 : mDeferredSingleDeclarationErrorCheck = false;
1978 :
1979 0 : singleDeclarationErrorCheck(publicType, identifierLocation);
1980 :
1981 0 : TIntermDeclaration *declaration = new TIntermDeclaration();
1982 0 : declaration->setLine(identifierLocation);
1983 :
1984 0 : TIntermBinary *initNode = nullptr;
1985 0 : if (!executeInitializer(identifierLocation, identifier, publicType, initializer, &initNode))
1986 : {
1987 0 : if (initNode)
1988 : {
1989 0 : declaration->appendDeclarator(initNode);
1990 : }
1991 : }
1992 0 : return declaration;
1993 : }
1994 :
1995 0 : TIntermDeclaration *TParseContext::parseSingleArrayInitDeclaration(
1996 : TPublicType &publicType,
1997 : const TSourceLoc &identifierLocation,
1998 : const TString &identifier,
1999 : const TSourceLoc &indexLocation,
2000 : TIntermTyped *indexExpression,
2001 : const TSourceLoc &initLocation,
2002 : TIntermTyped *initializer)
2003 : {
2004 0 : mDeferredSingleDeclarationErrorCheck = false;
2005 :
2006 0 : singleDeclarationErrorCheck(publicType, identifierLocation);
2007 :
2008 0 : checkIsValidTypeAndQualifierForArray(indexLocation, publicType);
2009 :
2010 0 : TPublicType arrayType(publicType);
2011 :
2012 0 : unsigned int size = 0u;
2013 : // If indexExpression is nullptr, then the array will eventually get its size implicitly from
2014 : // the initializer.
2015 0 : if (indexExpression != nullptr)
2016 : {
2017 0 : size = checkIsValidArraySize(identifierLocation, indexExpression);
2018 : }
2019 : // Make the type an array even if size check failed.
2020 : // This ensures useless error messages regarding the variable's non-arrayness won't follow.
2021 0 : arrayType.setArraySize(size);
2022 :
2023 0 : TIntermDeclaration *declaration = new TIntermDeclaration();
2024 0 : declaration->setLine(identifierLocation);
2025 :
2026 : // initNode will correspond to the whole of "type b[n] = initializer".
2027 0 : TIntermBinary *initNode = nullptr;
2028 0 : if (!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
2029 : {
2030 0 : if (initNode)
2031 : {
2032 0 : declaration->appendDeclarator(initNode);
2033 : }
2034 : }
2035 :
2036 0 : return declaration;
2037 : }
2038 :
2039 0 : TIntermAggregate *TParseContext::parseInvariantDeclaration(
2040 : const TTypeQualifierBuilder &typeQualifierBuilder,
2041 : const TSourceLoc &identifierLoc,
2042 : const TString *identifier,
2043 : const TSymbol *symbol)
2044 : {
2045 0 : TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics);
2046 :
2047 0 : if (!typeQualifier.invariant)
2048 : {
2049 0 : error(identifierLoc, "Expected invariant", identifier->c_str());
2050 0 : return nullptr;
2051 : }
2052 0 : if (!checkIsAtGlobalLevel(identifierLoc, "invariant varying"))
2053 : {
2054 0 : return nullptr;
2055 : }
2056 0 : if (!symbol)
2057 : {
2058 0 : error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str());
2059 0 : return nullptr;
2060 : }
2061 0 : if (!IsQualifierUnspecified(typeQualifier.qualifier))
2062 : {
2063 0 : error(identifierLoc, "invariant declaration specifies qualifier",
2064 0 : getQualifierString(typeQualifier.qualifier));
2065 : }
2066 0 : if (typeQualifier.precision != EbpUndefined)
2067 : {
2068 0 : error(identifierLoc, "invariant declaration specifies precision",
2069 0 : getPrecisionString(typeQualifier.precision));
2070 : }
2071 0 : if (!typeQualifier.layoutQualifier.isEmpty())
2072 : {
2073 0 : error(identifierLoc, "invariant declaration specifies layout", "'layout'");
2074 : }
2075 :
2076 0 : const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
2077 0 : ASSERT(variable);
2078 0 : const TType &type = variable->getType();
2079 :
2080 0 : checkInvariantVariableQualifier(typeQualifier.invariant, type.getQualifier(),
2081 0 : typeQualifier.line);
2082 0 : checkIsMemoryQualifierNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
2083 :
2084 0 : symbolTable.addInvariantVarying(std::string(identifier->c_str()));
2085 :
2086 : TIntermSymbol *intermSymbol =
2087 0 : intermediate.addSymbol(variable->getUniqueId(), *identifier, type, identifierLoc);
2088 :
2089 0 : TIntermAggregate *aggregate = TIntermediate::MakeAggregate(intermSymbol, identifierLoc);
2090 0 : aggregate->setOp(EOpInvariantDeclaration);
2091 0 : return aggregate;
2092 : }
2093 :
2094 0 : void TParseContext::parseDeclarator(TPublicType &publicType,
2095 : const TSourceLoc &identifierLocation,
2096 : const TString &identifier,
2097 : TIntermDeclaration *declarationOut)
2098 : {
2099 : // If the declaration starting this declarator list was empty (example: int,), some checks were
2100 : // not performed.
2101 0 : if (mDeferredSingleDeclarationErrorCheck)
2102 : {
2103 0 : singleDeclarationErrorCheck(publicType, identifierLocation);
2104 0 : mDeferredSingleDeclarationErrorCheck = false;
2105 : }
2106 :
2107 0 : checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
2108 :
2109 0 : checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &publicType);
2110 :
2111 0 : TVariable *variable = nullptr;
2112 0 : declareVariable(identifierLocation, identifier, TType(publicType), &variable);
2113 :
2114 : TIntermSymbol *symbol =
2115 0 : intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation);
2116 0 : if (variable && symbol)
2117 : {
2118 0 : symbol->setId(variable->getUniqueId());
2119 0 : declarationOut->appendDeclarator(symbol);
2120 : }
2121 0 : }
2122 :
2123 0 : void TParseContext::parseArrayDeclarator(TPublicType &publicType,
2124 : const TSourceLoc &identifierLocation,
2125 : const TString &identifier,
2126 : const TSourceLoc &arrayLocation,
2127 : TIntermTyped *indexExpression,
2128 : TIntermDeclaration *declarationOut)
2129 : {
2130 : // If the declaration starting this declarator list was empty (example: int,), some checks were
2131 : // not performed.
2132 0 : if (mDeferredSingleDeclarationErrorCheck)
2133 : {
2134 0 : singleDeclarationErrorCheck(publicType, identifierLocation);
2135 0 : mDeferredSingleDeclarationErrorCheck = false;
2136 : }
2137 :
2138 0 : checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
2139 :
2140 0 : checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &publicType);
2141 :
2142 0 : if (checkIsValidTypeAndQualifierForArray(arrayLocation, publicType))
2143 : {
2144 0 : TType arrayType = TType(publicType);
2145 0 : unsigned int size = checkIsValidArraySize(arrayLocation, indexExpression);
2146 0 : arrayType.setArraySize(size);
2147 :
2148 0 : TVariable *variable = nullptr;
2149 0 : declareVariable(identifierLocation, identifier, arrayType, &variable);
2150 :
2151 : TIntermSymbol *symbol =
2152 0 : intermediate.addSymbol(0, identifier, arrayType, identifierLocation);
2153 0 : if (variable && symbol)
2154 0 : symbol->setId(variable->getUniqueId());
2155 :
2156 0 : declarationOut->appendDeclarator(symbol);
2157 : }
2158 0 : }
2159 :
2160 0 : void TParseContext::parseInitDeclarator(const TPublicType &publicType,
2161 : const TSourceLoc &identifierLocation,
2162 : const TString &identifier,
2163 : const TSourceLoc &initLocation,
2164 : TIntermTyped *initializer,
2165 : TIntermDeclaration *declarationOut)
2166 : {
2167 : // If the declaration starting this declarator list was empty (example: int,), some checks were
2168 : // not performed.
2169 0 : if (mDeferredSingleDeclarationErrorCheck)
2170 : {
2171 0 : singleDeclarationErrorCheck(publicType, identifierLocation);
2172 0 : mDeferredSingleDeclarationErrorCheck = false;
2173 : }
2174 :
2175 0 : checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
2176 :
2177 0 : TIntermBinary *initNode = nullptr;
2178 0 : if (!executeInitializer(identifierLocation, identifier, publicType, initializer, &initNode))
2179 : {
2180 : //
2181 : // build the intermediate representation
2182 : //
2183 0 : if (initNode)
2184 : {
2185 0 : declarationOut->appendDeclarator(initNode);
2186 : }
2187 : }
2188 0 : }
2189 :
2190 0 : void TParseContext::parseArrayInitDeclarator(const TPublicType &publicType,
2191 : const TSourceLoc &identifierLocation,
2192 : const TString &identifier,
2193 : const TSourceLoc &indexLocation,
2194 : TIntermTyped *indexExpression,
2195 : const TSourceLoc &initLocation,
2196 : TIntermTyped *initializer,
2197 : TIntermDeclaration *declarationOut)
2198 : {
2199 : // If the declaration starting this declarator list was empty (example: int,), some checks were
2200 : // not performed.
2201 0 : if (mDeferredSingleDeclarationErrorCheck)
2202 : {
2203 0 : singleDeclarationErrorCheck(publicType, identifierLocation);
2204 0 : mDeferredSingleDeclarationErrorCheck = false;
2205 : }
2206 :
2207 0 : checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
2208 :
2209 0 : checkIsValidTypeAndQualifierForArray(indexLocation, publicType);
2210 :
2211 0 : TPublicType arrayType(publicType);
2212 :
2213 0 : unsigned int size = 0u;
2214 : // If indexExpression is nullptr, then the array will eventually get its size implicitly from
2215 : // the initializer.
2216 0 : if (indexExpression != nullptr)
2217 : {
2218 0 : size = checkIsValidArraySize(identifierLocation, indexExpression);
2219 : }
2220 : // Make the type an array even if size check failed.
2221 : // This ensures useless error messages regarding the variable's non-arrayness won't follow.
2222 0 : arrayType.setArraySize(size);
2223 :
2224 : // initNode will correspond to the whole of "b[n] = initializer".
2225 0 : TIntermBinary *initNode = nullptr;
2226 0 : if (!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
2227 : {
2228 0 : if (initNode)
2229 : {
2230 0 : declarationOut->appendDeclarator(initNode);
2231 : }
2232 : }
2233 0 : }
2234 :
2235 0 : void TParseContext::parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder)
2236 : {
2237 0 : TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics);
2238 0 : const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier;
2239 :
2240 0 : checkInvariantVariableQualifier(typeQualifier.invariant, typeQualifier.qualifier,
2241 0 : typeQualifier.line);
2242 :
2243 : // It should never be the case, but some strange parser errors can send us here.
2244 0 : if (layoutQualifier.isEmpty())
2245 : {
2246 0 : error(typeQualifier.line, "Error during layout qualifier parsing.", "?");
2247 0 : return;
2248 : }
2249 :
2250 0 : if (!layoutQualifier.isCombinationValid())
2251 : {
2252 0 : error(typeQualifier.line, "invalid combination:", "layout");
2253 0 : return;
2254 : }
2255 :
2256 0 : checkIsMemoryQualifierNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
2257 :
2258 0 : checkInternalFormatIsNotSpecified(typeQualifier.line, layoutQualifier.imageInternalFormat);
2259 :
2260 0 : if (typeQualifier.qualifier == EvqComputeIn)
2261 : {
2262 0 : if (mComputeShaderLocalSizeDeclared &&
2263 0 : !layoutQualifier.isLocalSizeEqual(mComputeShaderLocalSize))
2264 : {
2265 : error(typeQualifier.line, "Work group size does not match the previous declaration",
2266 0 : "layout");
2267 0 : return;
2268 : }
2269 :
2270 0 : if (mShaderVersion < 310)
2271 : {
2272 0 : error(typeQualifier.line, "in type qualifier supported in GLSL ES 3.10 only", "layout");
2273 0 : return;
2274 : }
2275 :
2276 0 : if (!layoutQualifier.localSize.isAnyValueSet())
2277 : {
2278 0 : error(typeQualifier.line, "No local work group size specified", "layout");
2279 0 : return;
2280 : }
2281 :
2282 : const TVariable *maxComputeWorkGroupSize = static_cast<const TVariable *>(
2283 0 : symbolTable.findBuiltIn("gl_MaxComputeWorkGroupSize", mShaderVersion));
2284 :
2285 : const TConstantUnion *maxComputeWorkGroupSizeData =
2286 0 : maxComputeWorkGroupSize->getConstPointer();
2287 :
2288 0 : for (size_t i = 0u; i < layoutQualifier.localSize.size(); ++i)
2289 : {
2290 0 : if (layoutQualifier.localSize[i] != -1)
2291 : {
2292 0 : mComputeShaderLocalSize[i] = layoutQualifier.localSize[i];
2293 0 : const int maxComputeWorkGroupSizeValue = maxComputeWorkGroupSizeData[i].getIConst();
2294 0 : if (mComputeShaderLocalSize[i] < 1 ||
2295 0 : mComputeShaderLocalSize[i] > maxComputeWorkGroupSizeValue)
2296 : {
2297 0 : std::stringstream errorMessageStream;
2298 0 : errorMessageStream << "Value must be at least 1 and no greater than "
2299 0 : << maxComputeWorkGroupSizeValue;
2300 0 : const std::string &errorMessage = errorMessageStream.str();
2301 :
2302 0 : error(typeQualifier.line, "invalid value:", getWorkGroupSizeString(i),
2303 0 : errorMessage.c_str());
2304 0 : return;
2305 : }
2306 : }
2307 : }
2308 :
2309 0 : mComputeShaderLocalSizeDeclared = true;
2310 : }
2311 : else
2312 : {
2313 :
2314 0 : if (!checkWorkGroupSizeIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier))
2315 : {
2316 0 : return;
2317 : }
2318 :
2319 0 : if (typeQualifier.qualifier != EvqUniform)
2320 : {
2321 0 : error(typeQualifier.line, "invalid qualifier:",
2322 0 : getQualifierString(typeQualifier.qualifier), "global layout must be uniform");
2323 0 : return;
2324 : }
2325 :
2326 0 : if (mShaderVersion < 300)
2327 : {
2328 : error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 and above",
2329 0 : "layout");
2330 0 : return;
2331 : }
2332 :
2333 0 : checkLocationIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier);
2334 :
2335 0 : if (layoutQualifier.matrixPacking != EmpUnspecified)
2336 : {
2337 0 : mDefaultMatrixPacking = layoutQualifier.matrixPacking;
2338 : }
2339 :
2340 0 : if (layoutQualifier.blockStorage != EbsUnspecified)
2341 : {
2342 0 : mDefaultBlockStorage = layoutQualifier.blockStorage;
2343 : }
2344 : }
2345 : }
2346 :
2347 0 : TIntermAggregate *TParseContext::addFunctionPrototypeDeclaration(const TFunction &parsedFunction,
2348 : const TSourceLoc &location)
2349 : {
2350 : // Note: function found from the symbol table could be the same as parsedFunction if this is the
2351 : // first declaration. Either way the instance in the symbol table is used to track whether the
2352 : // function is declared multiple times.
2353 : TFunction *function = static_cast<TFunction *>(
2354 0 : symbolTable.find(parsedFunction.getMangledName(), getShaderVersion()));
2355 0 : if (function->hasPrototypeDeclaration() && mShaderVersion == 100)
2356 : {
2357 : // ESSL 1.00.17 section 4.2.7.
2358 : // Doesn't apply to ESSL 3.00.4: see section 4.2.3.
2359 0 : error(location, "duplicate function prototype declarations are not allowed", "function");
2360 : }
2361 0 : function->setHasPrototypeDeclaration();
2362 :
2363 0 : TIntermAggregate *prototype = new TIntermAggregate;
2364 : // TODO(oetuaho@nvidia.com): Instead of converting the function information here, the node could
2365 : // point to the data that already exists in the symbol table.
2366 0 : prototype->setType(function->getReturnType());
2367 0 : prototype->getFunctionSymbolInfo()->setFromFunction(*function);
2368 :
2369 0 : for (size_t i = 0; i < function->getParamCount(); i++)
2370 : {
2371 0 : const TConstParameter ¶m = function->getParam(i);
2372 0 : if (param.name != 0)
2373 : {
2374 0 : TVariable variable(param.name, *param.type);
2375 :
2376 0 : TIntermSymbol *paramSymbol = intermediate.addSymbol(
2377 0 : variable.getUniqueId(), variable.getName(), variable.getType(), location);
2378 0 : prototype = intermediate.growAggregate(prototype, paramSymbol, location);
2379 : }
2380 : else
2381 : {
2382 0 : TIntermSymbol *paramSymbol = intermediate.addSymbol(0, "", *param.type, location);
2383 0 : prototype = intermediate.growAggregate(prototype, paramSymbol, location);
2384 : }
2385 : }
2386 :
2387 0 : prototype->setOp(EOpPrototype);
2388 :
2389 0 : symbolTable.pop();
2390 :
2391 0 : if (!symbolTable.atGlobalLevel())
2392 : {
2393 : // ESSL 3.00.4 section 4.2.4.
2394 0 : error(location, "local function prototype declarations are not allowed", "function");
2395 : }
2396 :
2397 0 : return prototype;
2398 : }
2399 :
2400 0 : TIntermFunctionDefinition *TParseContext::addFunctionDefinition(
2401 : const TFunction &function,
2402 : TIntermAggregate *functionParameters,
2403 : TIntermBlock *functionBody,
2404 : const TSourceLoc &location)
2405 : {
2406 : // Check that non-void functions have at least one return statement.
2407 0 : if (mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue)
2408 : {
2409 0 : error(location, "function does not return a value:", "", function.getName().c_str());
2410 : }
2411 :
2412 0 : if (functionBody == nullptr)
2413 : {
2414 0 : functionBody = new TIntermBlock();
2415 0 : functionBody->setLine(location);
2416 : }
2417 : TIntermFunctionDefinition *functionNode =
2418 0 : new TIntermFunctionDefinition(function.getReturnType(), functionParameters, functionBody);
2419 0 : functionNode->setLine(location);
2420 :
2421 0 : functionNode->getFunctionSymbolInfo()->setFromFunction(function);
2422 :
2423 0 : symbolTable.pop();
2424 0 : return functionNode;
2425 : }
2426 :
2427 0 : void TParseContext::parseFunctionDefinitionHeader(const TSourceLoc &location,
2428 : TFunction **function,
2429 : TIntermAggregate **aggregateOut)
2430 : {
2431 0 : ASSERT(function);
2432 0 : ASSERT(*function);
2433 : const TSymbol *builtIn =
2434 0 : symbolTable.findBuiltIn((*function)->getMangledName(), getShaderVersion());
2435 :
2436 0 : if (builtIn)
2437 : {
2438 0 : error(location, "built-in functions cannot be redefined", (*function)->getName().c_str());
2439 : }
2440 : else
2441 : {
2442 : TFunction *prevDec = static_cast<TFunction *>(
2443 0 : symbolTable.find((*function)->getMangledName(), getShaderVersion()));
2444 :
2445 : // Note: 'prevDec' could be 'function' if this is the first time we've seen function as it
2446 : // would have just been put in the symbol table. Otherwise, we're looking up an earlier
2447 : // occurance.
2448 0 : if (*function != prevDec)
2449 : {
2450 : // Swap the parameters of the previous declaration to the parameters of the function
2451 : // definition (parameter names may differ).
2452 0 : prevDec->swapParameters(**function);
2453 :
2454 : // The function definition will share the same symbol as any previous declaration.
2455 0 : *function = prevDec;
2456 : }
2457 :
2458 0 : if ((*function)->isDefined())
2459 : {
2460 0 : error(location, "function already has a body", (*function)->getName().c_str());
2461 : }
2462 :
2463 0 : (*function)->setDefined();
2464 : }
2465 :
2466 : // Raise error message if main function takes any parameters or return anything other than void
2467 0 : if ((*function)->getName() == "main")
2468 : {
2469 0 : if ((*function)->getParamCount() > 0)
2470 : {
2471 0 : error(location, "function cannot take any parameter(s)",
2472 0 : (*function)->getName().c_str());
2473 : }
2474 0 : if ((*function)->getReturnType().getBasicType() != EbtVoid)
2475 : {
2476 0 : error(location, "", (*function)->getReturnType().getBasicString(),
2477 0 : "main function cannot return a value");
2478 : }
2479 : }
2480 :
2481 : //
2482 : // Remember the return type for later checking for RETURN statements.
2483 : //
2484 0 : mCurrentFunctionType = &((*function)->getReturnType());
2485 0 : mFunctionReturnsValue = false;
2486 :
2487 : //
2488 : // Insert parameters into the symbol table.
2489 : // If the parameter has no name, it's not an error, just don't insert it
2490 : // (could be used for unused args).
2491 : //
2492 : // Also, accumulate the list of parameters into the HIL, so lower level code
2493 : // knows where to find parameters.
2494 : //
2495 0 : TIntermAggregate *paramNodes = new TIntermAggregate;
2496 0 : for (size_t i = 0; i < (*function)->getParamCount(); i++)
2497 : {
2498 0 : const TConstParameter ¶m = (*function)->getParam(i);
2499 0 : if (param.name != 0)
2500 : {
2501 0 : TVariable *variable = new TVariable(param.name, *param.type);
2502 : //
2503 : // Insert the parameters with name in the symbol table.
2504 : //
2505 0 : if (!symbolTable.declare(variable))
2506 : {
2507 0 : error(location, "redefinition", variable->getName().c_str());
2508 0 : paramNodes = intermediate.growAggregate(
2509 0 : paramNodes, intermediate.addSymbol(0, "", *param.type, location), location);
2510 0 : continue;
2511 : }
2512 :
2513 : //
2514 : // Add the parameter to the HIL
2515 : //
2516 0 : TIntermSymbol *symbol = intermediate.addSymbol(
2517 0 : variable->getUniqueId(), variable->getName(), variable->getType(), location);
2518 :
2519 0 : paramNodes = intermediate.growAggregate(paramNodes, symbol, location);
2520 : }
2521 : else
2522 : {
2523 0 : paramNodes = intermediate.growAggregate(
2524 0 : paramNodes, intermediate.addSymbol(0, "", *param.type, location), location);
2525 : }
2526 : }
2527 0 : intermediate.setAggregateOperator(paramNodes, EOpParameters, location);
2528 0 : *aggregateOut = paramNodes;
2529 0 : setLoopNestingLevel(0);
2530 0 : }
2531 :
2532 0 : TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TFunction *function)
2533 : {
2534 : //
2535 : // We don't know at this point whether this is a function definition or a prototype.
2536 : // The definition production code will check for redefinitions.
2537 : // In the case of ESSL 1.00 the prototype production code will also check for redeclarations.
2538 : //
2539 : // Return types and parameter qualifiers must match in all redeclarations, so those are checked
2540 : // here.
2541 : //
2542 : TFunction *prevDec =
2543 0 : static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion()));
2544 :
2545 0 : if (getShaderVersion() >= 300 && symbolTable.hasUnmangledBuiltIn(function->getName().c_str()))
2546 : {
2547 : // With ESSL 3.00, names of built-in functions cannot be redeclared as functions.
2548 : // Therefore overloading or redefining builtin functions is an error.
2549 0 : error(location, "Name of a built-in function cannot be redeclared as function",
2550 0 : function->getName().c_str());
2551 : }
2552 0 : else if (prevDec)
2553 : {
2554 0 : if (prevDec->getReturnType() != function->getReturnType())
2555 : {
2556 0 : error(location, "function must have the same return type in all of its declarations",
2557 0 : function->getReturnType().getBasicString());
2558 : }
2559 0 : for (size_t i = 0; i < prevDec->getParamCount(); ++i)
2560 : {
2561 0 : if (prevDec->getParam(i).type->getQualifier() !=
2562 0 : function->getParam(i).type->getQualifier())
2563 : {
2564 0 : error(location,
2565 : "function must have the same parameter qualifiers in all of its declarations",
2566 0 : function->getParam(i).type->getQualifierString());
2567 : }
2568 : }
2569 : }
2570 :
2571 : //
2572 : // Check for previously declared variables using the same name.
2573 : //
2574 0 : TSymbol *prevSym = symbolTable.find(function->getName(), getShaderVersion());
2575 0 : if (prevSym)
2576 : {
2577 0 : if (!prevSym->isFunction())
2578 : {
2579 0 : error(location, "redefinition", function->getName().c_str(), "function");
2580 : }
2581 : }
2582 : else
2583 : {
2584 : // Insert the unmangled name to detect potential future redefinition as a variable.
2585 0 : symbolTable.getOuterLevel()->insertUnmangled(function);
2586 : }
2587 :
2588 : // We're at the inner scope level of the function's arguments and body statement.
2589 : // Add the function prototype to the surrounding scope instead.
2590 0 : symbolTable.getOuterLevel()->insert(function);
2591 :
2592 : //
2593 : // If this is a redeclaration, it could also be a definition, in which case, we want to use the
2594 : // variable names from this one, and not the one that's
2595 : // being redeclared. So, pass back up this declaration, not the one in the symbol table.
2596 : //
2597 0 : return function;
2598 : }
2599 :
2600 0 : TFunction *TParseContext::parseFunctionHeader(const TPublicType &type,
2601 : const TString *name,
2602 : const TSourceLoc &location)
2603 : {
2604 0 : if (type.qualifier != EvqGlobal && type.qualifier != EvqTemporary)
2605 : {
2606 0 : error(location, "no qualifiers allowed for function return",
2607 0 : getQualifierString(type.qualifier));
2608 : }
2609 0 : if (!type.layoutQualifier.isEmpty())
2610 : {
2611 0 : error(location, "no qualifiers allowed for function return", "layout");
2612 : }
2613 : // make sure a sampler or an image is not involved as well...
2614 0 : checkIsNotSampler(location, type.typeSpecifierNonArray,
2615 0 : "samplers can't be function return values");
2616 0 : checkIsNotImage(location, type.typeSpecifierNonArray, "images can't be function return values");
2617 0 : if (mShaderVersion < 300)
2618 : {
2619 : // Array return values are forbidden, but there's also no valid syntax for declaring array
2620 : // return values in ESSL 1.00.
2621 0 : ASSERT(type.arraySize == 0 || mDiagnostics.numErrors() > 0);
2622 :
2623 0 : if (type.isStructureContainingArrays())
2624 : {
2625 : // ESSL 1.00.17 section 6.1 Function Definitions
2626 0 : error(location, "structures containing arrays can't be function return values",
2627 0 : TType(type).getCompleteString().c_str());
2628 : }
2629 : }
2630 :
2631 : // Add the function as a prototype after parsing it (we do not support recursion)
2632 0 : return new TFunction(name, new TType(type));
2633 : }
2634 :
2635 0 : TFunction *TParseContext::addConstructorFunc(const TPublicType &publicTypeIn)
2636 : {
2637 0 : TPublicType publicType = publicTypeIn;
2638 0 : if (publicType.isStructSpecifier())
2639 : {
2640 0 : error(publicType.getLine(), "constructor can't be a structure definition",
2641 0 : getBasicString(publicType.getBasicType()));
2642 : }
2643 :
2644 0 : TOperator op = EOpNull;
2645 0 : if (publicType.getUserDef())
2646 : {
2647 0 : op = EOpConstructStruct;
2648 : }
2649 : else
2650 : {
2651 0 : op = sh::TypeToConstructorOperator(TType(publicType));
2652 0 : if (op == EOpNull)
2653 : {
2654 0 : error(publicType.getLine(), "cannot construct this type",
2655 0 : getBasicString(publicType.getBasicType()));
2656 0 : publicType.setBasicType(EbtFloat);
2657 0 : op = EOpConstructFloat;
2658 : }
2659 : }
2660 :
2661 0 : TString tempString;
2662 0 : const TType *type = new TType(publicType);
2663 0 : return new TFunction(&tempString, type, op);
2664 : }
2665 :
2666 : // This function is used to test for the correctness of the parameters passed to various constructor
2667 : // functions and also convert them to the right datatype if it is allowed and required.
2668 : //
2669 : // Returns a node to add to the tree regardless of if an error was generated or not.
2670 : //
2671 0 : TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments,
2672 : TOperator op,
2673 : TFunction *fnCall,
2674 : const TSourceLoc &line)
2675 : {
2676 0 : TType type = fnCall->getReturnType();
2677 0 : if (type.isUnsizedArray())
2678 : {
2679 0 : if (fnCall->getParamCount() == 0)
2680 : {
2681 0 : error(line, "implicitly sized array constructor must have at least one argument", "[]");
2682 0 : type.setArraySize(1u);
2683 0 : return TIntermTyped::CreateZero(type);
2684 : }
2685 0 : type.setArraySize(static_cast<unsigned int>(fnCall->getParamCount()));
2686 : }
2687 0 : bool constType = true;
2688 0 : for (size_t i = 0; i < fnCall->getParamCount(); ++i)
2689 : {
2690 0 : const TConstParameter ¶m = fnCall->getParam(i);
2691 0 : if (param.type->getQualifier() != EvqConst)
2692 0 : constType = false;
2693 : }
2694 0 : if (constType)
2695 0 : type.setQualifier(EvqConst);
2696 :
2697 0 : if (!checkConstructorArguments(line, arguments, *fnCall, op, type))
2698 : {
2699 0 : TIntermTyped *dummyNode = intermediate.setAggregateOperator(nullptr, op, line);
2700 0 : dummyNode->setType(type);
2701 0 : return dummyNode;
2702 : }
2703 0 : TIntermAggregate *constructor = arguments->getAsAggregate();
2704 0 : ASSERT(constructor != nullptr);
2705 :
2706 : // Turn the argument list itself into a constructor
2707 0 : constructor->setOp(op);
2708 0 : constructor->setLine(line);
2709 0 : ASSERT(constructor->isConstructor());
2710 :
2711 : // Need to set type before setPrecisionFromChildren() because bool doesn't have precision.
2712 0 : constructor->setType(type);
2713 :
2714 : // Structs should not be precision qualified, the individual members may be.
2715 : // Built-in types on the other hand should be precision qualified.
2716 0 : if (op != EOpConstructStruct)
2717 : {
2718 0 : constructor->setPrecisionFromChildren();
2719 0 : type.setPrecision(constructor->getPrecision());
2720 : }
2721 :
2722 0 : constructor->setType(type);
2723 :
2724 0 : TIntermTyped *constConstructor = intermediate.foldAggregateBuiltIn(constructor, &mDiagnostics);
2725 0 : if (constConstructor)
2726 : {
2727 0 : return constConstructor;
2728 : }
2729 :
2730 0 : return constructor;
2731 : }
2732 :
2733 : //
2734 : // Interface/uniform blocks
2735 : //
2736 0 : TIntermDeclaration *TParseContext::addInterfaceBlock(
2737 : const TTypeQualifierBuilder &typeQualifierBuilder,
2738 : const TSourceLoc &nameLine,
2739 : const TString &blockName,
2740 : TFieldList *fieldList,
2741 : const TString *instanceName,
2742 : const TSourceLoc &instanceLine,
2743 : TIntermTyped *arrayIndex,
2744 : const TSourceLoc &arrayIndexLine)
2745 : {
2746 0 : checkIsNotReserved(nameLine, blockName);
2747 :
2748 0 : TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics);
2749 :
2750 0 : if (typeQualifier.qualifier != EvqUniform)
2751 : {
2752 0 : error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier),
2753 0 : "interface blocks must be uniform");
2754 : }
2755 :
2756 0 : if (typeQualifier.invariant)
2757 : {
2758 0 : error(typeQualifier.line, "invalid qualifier on interface block member", "invariant");
2759 : }
2760 :
2761 0 : checkIsMemoryQualifierNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
2762 :
2763 0 : TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier;
2764 0 : checkLocationIsNotSpecified(typeQualifier.line, blockLayoutQualifier);
2765 :
2766 0 : if (blockLayoutQualifier.matrixPacking == EmpUnspecified)
2767 : {
2768 0 : blockLayoutQualifier.matrixPacking = mDefaultMatrixPacking;
2769 : }
2770 :
2771 0 : if (blockLayoutQualifier.blockStorage == EbsUnspecified)
2772 : {
2773 0 : blockLayoutQualifier.blockStorage = mDefaultBlockStorage;
2774 : }
2775 :
2776 0 : checkWorkGroupSizeIsNotSpecified(nameLine, blockLayoutQualifier);
2777 :
2778 0 : checkInternalFormatIsNotSpecified(nameLine, blockLayoutQualifier.imageInternalFormat);
2779 :
2780 0 : TSymbol *blockNameSymbol = new TInterfaceBlockName(&blockName);
2781 0 : if (!symbolTable.declare(blockNameSymbol))
2782 : {
2783 0 : error(nameLine, "redefinition", blockName.c_str(), "interface block name");
2784 : }
2785 :
2786 : // check for sampler types and apply layout qualifiers
2787 0 : for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
2788 : {
2789 0 : TField *field = (*fieldList)[memberIndex];
2790 0 : TType *fieldType = field->type();
2791 0 : if (IsSampler(fieldType->getBasicType()))
2792 : {
2793 0 : error(field->line(), "unsupported type", fieldType->getBasicString(),
2794 0 : "sampler types are not allowed in interface blocks");
2795 : }
2796 :
2797 0 : if (IsImage(fieldType->getBasicType()))
2798 : {
2799 0 : error(field->line(), "unsupported type", fieldType->getBasicString(),
2800 0 : "image types are not allowed in interface blocks");
2801 : }
2802 :
2803 0 : const TQualifier qualifier = fieldType->getQualifier();
2804 0 : switch (qualifier)
2805 : {
2806 : case EvqGlobal:
2807 : case EvqUniform:
2808 0 : break;
2809 : default:
2810 0 : error(field->line(), "invalid qualifier on interface block member",
2811 0 : getQualifierString(qualifier));
2812 0 : break;
2813 : }
2814 :
2815 0 : if (fieldType->isInvariant())
2816 : {
2817 0 : error(field->line(), "invalid qualifier on interface block member", "invariant");
2818 : }
2819 :
2820 : // check layout qualifiers
2821 0 : TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier();
2822 0 : checkLocationIsNotSpecified(field->line(), fieldLayoutQualifier);
2823 :
2824 0 : if (fieldLayoutQualifier.blockStorage != EbsUnspecified)
2825 : {
2826 0 : error(field->line(), "invalid layout qualifier:",
2827 0 : getBlockStorageString(fieldLayoutQualifier.blockStorage), "cannot be used here");
2828 : }
2829 :
2830 0 : if (fieldLayoutQualifier.matrixPacking == EmpUnspecified)
2831 : {
2832 0 : fieldLayoutQualifier.matrixPacking = blockLayoutQualifier.matrixPacking;
2833 : }
2834 0 : else if (!fieldType->isMatrix() && fieldType->getBasicType() != EbtStruct)
2835 : {
2836 0 : warning(field->line(), "extraneous layout qualifier:",
2837 : getMatrixPackingString(fieldLayoutQualifier.matrixPacking),
2838 0 : "only has an effect on matrix types");
2839 : }
2840 :
2841 0 : fieldType->setLayoutQualifier(fieldLayoutQualifier);
2842 : }
2843 :
2844 : // add array index
2845 0 : unsigned int arraySize = 0;
2846 0 : if (arrayIndex != nullptr)
2847 : {
2848 0 : arraySize = checkIsValidArraySize(arrayIndexLine, arrayIndex);
2849 : }
2850 :
2851 : TInterfaceBlock *interfaceBlock =
2852 0 : new TInterfaceBlock(&blockName, fieldList, instanceName, arraySize, blockLayoutQualifier);
2853 : TType interfaceBlockType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier,
2854 0 : arraySize);
2855 :
2856 0 : TString symbolName = "";
2857 0 : int symbolId = 0;
2858 :
2859 0 : if (!instanceName)
2860 : {
2861 : // define symbols for the members of the interface block
2862 0 : for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
2863 : {
2864 0 : TField *field = (*fieldList)[memberIndex];
2865 0 : TType *fieldType = field->type();
2866 :
2867 : // set parent pointer of the field variable
2868 0 : fieldType->setInterfaceBlock(interfaceBlock);
2869 :
2870 0 : TVariable *fieldVariable = new TVariable(&field->name(), *fieldType);
2871 0 : fieldVariable->setQualifier(typeQualifier.qualifier);
2872 :
2873 0 : if (!symbolTable.declare(fieldVariable))
2874 : {
2875 0 : error(field->line(), "redefinition", field->name().c_str(),
2876 0 : "interface block member name");
2877 : }
2878 : }
2879 : }
2880 : else
2881 : {
2882 0 : checkIsNotReserved(instanceLine, *instanceName);
2883 :
2884 : // add a symbol for this interface block
2885 0 : TVariable *instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false);
2886 0 : instanceTypeDef->setQualifier(typeQualifier.qualifier);
2887 :
2888 0 : if (!symbolTable.declare(instanceTypeDef))
2889 : {
2890 0 : error(instanceLine, "redefinition", instanceName->c_str(),
2891 0 : "interface block instance name");
2892 : }
2893 :
2894 0 : symbolId = instanceTypeDef->getUniqueId();
2895 0 : symbolName = instanceTypeDef->getName();
2896 : }
2897 :
2898 : TIntermSymbol *blockSymbol =
2899 0 : intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line);
2900 0 : TIntermDeclaration *declaration = new TIntermDeclaration();
2901 0 : declaration->appendDeclarator(blockSymbol);
2902 0 : declaration->setLine(nameLine);
2903 :
2904 0 : exitStructDeclaration();
2905 0 : return declaration;
2906 : }
2907 :
2908 0 : void TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString &identifier)
2909 : {
2910 0 : ++mStructNestingLevel;
2911 :
2912 : // Embedded structure definitions are not supported per GLSL ES spec.
2913 : // They aren't allowed in GLSL either, but we need to detect this here
2914 : // so we don't rely on the GLSL compiler to catch it.
2915 0 : if (mStructNestingLevel > 1)
2916 : {
2917 0 : error(line, "", "Embedded struct definitions are not allowed");
2918 : }
2919 0 : }
2920 :
2921 0 : void TParseContext::exitStructDeclaration()
2922 : {
2923 0 : --mStructNestingLevel;
2924 0 : }
2925 :
2926 0 : void TParseContext::checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field)
2927 : {
2928 0 : if (!sh::IsWebGLBasedSpec(mShaderSpec))
2929 : {
2930 0 : return;
2931 : }
2932 :
2933 0 : if (field.type()->getBasicType() != EbtStruct)
2934 : {
2935 0 : return;
2936 : }
2937 :
2938 : // We're already inside a structure definition at this point, so add
2939 : // one to the field's struct nesting.
2940 0 : if (1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting)
2941 : {
2942 0 : std::stringstream reasonStream;
2943 0 : reasonStream << "Reference of struct type " << field.type()->getStruct()->name().c_str()
2944 0 : << " exceeds maximum allowed nesting level of " << kWebGLMaxStructNesting;
2945 0 : std::string reason = reasonStream.str();
2946 0 : error(line, reason.c_str(), field.name().c_str(), "");
2947 0 : return;
2948 : }
2949 : }
2950 :
2951 : //
2952 : // Parse an array index expression
2953 : //
2954 0 : TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
2955 : const TSourceLoc &location,
2956 : TIntermTyped *indexExpression)
2957 : {
2958 0 : if (!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector())
2959 : {
2960 0 : if (baseExpression->getAsSymbolNode())
2961 : {
2962 0 : error(location, " left of '[' is not of type array, matrix, or vector ",
2963 0 : baseExpression->getAsSymbolNode()->getSymbol().c_str());
2964 : }
2965 : else
2966 : {
2967 0 : error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
2968 : }
2969 :
2970 0 : TConstantUnion *unionArray = new TConstantUnion[1];
2971 0 : unionArray->setFConst(0.0f);
2972 0 : return intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst),
2973 0 : location);
2974 : }
2975 :
2976 0 : TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion();
2977 :
2978 : // TODO(oetuaho@nvidia.com): Get rid of indexConstantUnion == nullptr below once ANGLE is able
2979 : // to constant fold all constant expressions. Right now we don't allow indexing interface blocks
2980 : // or fragment outputs with expressions that ANGLE is not able to constant fold, even if the
2981 : // index is a constant expression.
2982 0 : if (indexExpression->getQualifier() != EvqConst || indexConstantUnion == nullptr)
2983 : {
2984 0 : if (baseExpression->isInterfaceBlock())
2985 : {
2986 : error(
2987 : location, "", "[",
2988 0 : "array indexes for interface blocks arrays must be constant integral expressions");
2989 : }
2990 0 : else if (baseExpression->getQualifier() == EvqFragmentOut)
2991 : {
2992 : error(location, "", "[",
2993 0 : "array indexes for fragment outputs must be constant integral expressions");
2994 : }
2995 0 : else if (mShaderSpec == SH_WEBGL2_SPEC && baseExpression->getQualifier() == EvqFragData)
2996 : {
2997 0 : error(location, "", "[", "array index for gl_FragData must be constant zero");
2998 : }
2999 : }
3000 :
3001 0 : if (indexConstantUnion)
3002 : {
3003 : // If an out-of-range index is not qualified as constant, the behavior in the spec is
3004 : // undefined. This applies even if ANGLE has been able to constant fold it (ANGLE may
3005 : // constant fold expressions that are not constant expressions). The most compatible way to
3006 : // handle this case is to report a warning instead of an error and force the index to be in
3007 : // the correct range.
3008 0 : bool outOfRangeIndexIsError = indexExpression->getQualifier() == EvqConst;
3009 0 : int index = indexConstantUnion->getIConst(0);
3010 :
3011 0 : int safeIndex = -1;
3012 :
3013 0 : if (baseExpression->isArray())
3014 : {
3015 0 : if (baseExpression->getQualifier() == EvqFragData && index > 0)
3016 : {
3017 0 : if (mShaderSpec == SH_WEBGL2_SPEC)
3018 : {
3019 : // Error has been already generated if index is not const.
3020 0 : if (indexExpression->getQualifier() == EvqConst)
3021 : {
3022 : error(location, "", "[",
3023 0 : "array index for gl_FragData must be constant zero");
3024 : }
3025 0 : safeIndex = 0;
3026 : }
3027 0 : else if (!isExtensionEnabled("GL_EXT_draw_buffers"))
3028 : {
3029 0 : outOfRangeError(outOfRangeIndexIsError, location, "", "[",
3030 : "array index for gl_FragData must be zero when "
3031 0 : "GL_EXT_draw_buffers is disabled");
3032 0 : safeIndex = 0;
3033 : }
3034 : }
3035 : // Only do generic out-of-range check if similar error hasn't already been reported.
3036 0 : if (safeIndex < 0)
3037 : {
3038 0 : safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
3039 0 : baseExpression->getArraySize(),
3040 0 : "array index out of range", "[]");
3041 : }
3042 : }
3043 0 : else if (baseExpression->isMatrix())
3044 : {
3045 0 : safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
3046 0 : baseExpression->getType().getCols(),
3047 0 : "matrix field selection out of range", "[]");
3048 : }
3049 0 : else if (baseExpression->isVector())
3050 : {
3051 0 : safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
3052 0 : baseExpression->getType().getNominalSize(),
3053 0 : "vector field selection out of range", "[]");
3054 : }
3055 :
3056 0 : ASSERT(safeIndex >= 0);
3057 : // Data of constant unions can't be changed, because it may be shared with other
3058 : // constant unions or even builtins, like gl_MaxDrawBuffers. Instead use a new
3059 : // sanitized object.
3060 0 : if (safeIndex != index)
3061 : {
3062 0 : TConstantUnion *safeConstantUnion = new TConstantUnion();
3063 0 : safeConstantUnion->setIConst(safeIndex);
3064 0 : indexConstantUnion->replaceConstantUnion(safeConstantUnion);
3065 : }
3066 :
3067 0 : return intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location,
3068 0 : &mDiagnostics);
3069 : }
3070 : else
3071 : {
3072 0 : return intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location,
3073 0 : &mDiagnostics);
3074 : }
3075 : }
3076 :
3077 0 : int TParseContext::checkIndexOutOfRange(bool outOfRangeIndexIsError,
3078 : const TSourceLoc &location,
3079 : int index,
3080 : int arraySize,
3081 : const char *reason,
3082 : const char *token)
3083 : {
3084 0 : if (index >= arraySize || index < 0)
3085 : {
3086 0 : std::stringstream extraInfoStream;
3087 0 : extraInfoStream << "'" << index << "'";
3088 0 : std::string extraInfo = extraInfoStream.str();
3089 0 : outOfRangeError(outOfRangeIndexIsError, location, reason, token, extraInfo.c_str());
3090 0 : if (index < 0)
3091 : {
3092 0 : return 0;
3093 : }
3094 : else
3095 : {
3096 0 : return arraySize - 1;
3097 : }
3098 : }
3099 0 : return index;
3100 : }
3101 :
3102 0 : TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression,
3103 : const TSourceLoc &dotLocation,
3104 : const TString &fieldString,
3105 : const TSourceLoc &fieldLocation)
3106 : {
3107 0 : if (baseExpression->isArray())
3108 : {
3109 0 : error(fieldLocation, "cannot apply dot operator to an array", ".");
3110 0 : return baseExpression;
3111 : }
3112 :
3113 0 : if (baseExpression->isVector())
3114 : {
3115 : TVectorFields fields;
3116 0 : if (!parseVectorFields(fieldString, baseExpression->getNominalSize(), fields,
3117 : fieldLocation))
3118 : {
3119 0 : fields.num = 1;
3120 0 : fields.offsets[0] = 0;
3121 : }
3122 :
3123 0 : return TIntermediate::AddSwizzle(baseExpression, fields, dotLocation);
3124 : }
3125 0 : else if (baseExpression->getBasicType() == EbtStruct)
3126 : {
3127 0 : const TFieldList &fields = baseExpression->getType().getStruct()->fields();
3128 0 : if (fields.empty())
3129 : {
3130 0 : error(dotLocation, "structure has no fields", "Internal Error");
3131 0 : return baseExpression;
3132 : }
3133 : else
3134 : {
3135 0 : bool fieldFound = false;
3136 : unsigned int i;
3137 0 : for (i = 0; i < fields.size(); ++i)
3138 : {
3139 0 : if (fields[i]->name() == fieldString)
3140 : {
3141 0 : fieldFound = true;
3142 0 : break;
3143 : }
3144 : }
3145 0 : if (fieldFound)
3146 : {
3147 0 : TIntermTyped *index = TIntermTyped::CreateIndexNode(i);
3148 0 : index->setLine(fieldLocation);
3149 0 : return intermediate.addIndex(EOpIndexDirectStruct, baseExpression, index,
3150 0 : dotLocation, &mDiagnostics);
3151 : }
3152 : else
3153 : {
3154 0 : error(dotLocation, " no such field in structure", fieldString.c_str());
3155 0 : return baseExpression;
3156 : }
3157 : }
3158 : }
3159 0 : else if (baseExpression->isInterfaceBlock())
3160 : {
3161 0 : const TFieldList &fields = baseExpression->getType().getInterfaceBlock()->fields();
3162 0 : if (fields.empty())
3163 : {
3164 0 : error(dotLocation, "interface block has no fields", "Internal Error");
3165 0 : return baseExpression;
3166 : }
3167 : else
3168 : {
3169 0 : bool fieldFound = false;
3170 : unsigned int i;
3171 0 : for (i = 0; i < fields.size(); ++i)
3172 : {
3173 0 : if (fields[i]->name() == fieldString)
3174 : {
3175 0 : fieldFound = true;
3176 0 : break;
3177 : }
3178 : }
3179 0 : if (fieldFound)
3180 : {
3181 0 : TIntermTyped *index = TIntermTyped::CreateIndexNode(i);
3182 0 : index->setLine(fieldLocation);
3183 0 : return intermediate.addIndex(EOpIndexDirectInterfaceBlock, baseExpression, index,
3184 0 : dotLocation, &mDiagnostics);
3185 : }
3186 : else
3187 : {
3188 0 : error(dotLocation, " no such field in interface block", fieldString.c_str());
3189 0 : return baseExpression;
3190 : }
3191 : }
3192 : }
3193 : else
3194 : {
3195 0 : if (mShaderVersion < 300)
3196 : {
3197 0 : error(dotLocation, " field selection requires structure or vector on left hand side",
3198 0 : fieldString.c_str());
3199 : }
3200 : else
3201 : {
3202 0 : error(dotLocation,
3203 : " field selection requires structure, vector, or interface block on left hand "
3204 : "side",
3205 0 : fieldString.c_str());
3206 : }
3207 0 : return baseExpression;
3208 : }
3209 : }
3210 :
3211 0 : TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType,
3212 : const TSourceLoc &qualifierTypeLine)
3213 : {
3214 0 : TLayoutQualifier qualifier = TLayoutQualifier::create();
3215 :
3216 0 : if (qualifierType == "shared")
3217 : {
3218 0 : if (sh::IsWebGLBasedSpec(mShaderSpec))
3219 : {
3220 0 : error(qualifierTypeLine, "Only std140 layout is allowed in WebGL", "shared");
3221 : }
3222 0 : qualifier.blockStorage = EbsShared;
3223 : }
3224 0 : else if (qualifierType == "packed")
3225 : {
3226 0 : if (sh::IsWebGLBasedSpec(mShaderSpec))
3227 : {
3228 0 : error(qualifierTypeLine, "Only std140 layout is allowed in WebGL", "packed");
3229 : }
3230 0 : qualifier.blockStorage = EbsPacked;
3231 : }
3232 0 : else if (qualifierType == "std140")
3233 : {
3234 0 : qualifier.blockStorage = EbsStd140;
3235 : }
3236 0 : else if (qualifierType == "row_major")
3237 : {
3238 0 : qualifier.matrixPacking = EmpRowMajor;
3239 : }
3240 0 : else if (qualifierType == "column_major")
3241 : {
3242 0 : qualifier.matrixPacking = EmpColumnMajor;
3243 : }
3244 0 : else if (qualifierType == "location")
3245 : {
3246 0 : error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(),
3247 0 : "location requires an argument");
3248 : }
3249 0 : else if (qualifierType == "rgba32f")
3250 : {
3251 0 : checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
3252 0 : qualifier.imageInternalFormat = EiifRGBA32F;
3253 : }
3254 0 : else if (qualifierType == "rgba16f")
3255 : {
3256 0 : checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
3257 0 : qualifier.imageInternalFormat = EiifRGBA16F;
3258 : }
3259 0 : else if (qualifierType == "r32f")
3260 : {
3261 0 : checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
3262 0 : qualifier.imageInternalFormat = EiifR32F;
3263 : }
3264 0 : else if (qualifierType == "rgba8")
3265 : {
3266 0 : checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
3267 0 : qualifier.imageInternalFormat = EiifRGBA8;
3268 : }
3269 0 : else if (qualifierType == "rgba8_snorm")
3270 : {
3271 0 : checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
3272 0 : qualifier.imageInternalFormat = EiifRGBA8_SNORM;
3273 : }
3274 0 : else if (qualifierType == "rgba32i")
3275 : {
3276 0 : checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
3277 0 : qualifier.imageInternalFormat = EiifRGBA32I;
3278 : }
3279 0 : else if (qualifierType == "rgba16i")
3280 : {
3281 0 : checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
3282 0 : qualifier.imageInternalFormat = EiifRGBA16I;
3283 : }
3284 0 : else if (qualifierType == "rgba8i")
3285 : {
3286 0 : checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
3287 0 : qualifier.imageInternalFormat = EiifRGBA8I;
3288 : }
3289 0 : else if (qualifierType == "r32i")
3290 : {
3291 0 : checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
3292 0 : qualifier.imageInternalFormat = EiifR32I;
3293 : }
3294 0 : else if (qualifierType == "rgba32ui")
3295 : {
3296 0 : checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
3297 0 : qualifier.imageInternalFormat = EiifRGBA32UI;
3298 : }
3299 0 : else if (qualifierType == "rgba16ui")
3300 : {
3301 0 : checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
3302 0 : qualifier.imageInternalFormat = EiifRGBA16UI;
3303 : }
3304 0 : else if (qualifierType == "rgba8ui")
3305 : {
3306 0 : checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
3307 0 : qualifier.imageInternalFormat = EiifRGBA8UI;
3308 : }
3309 0 : else if (qualifierType == "r32ui")
3310 : {
3311 0 : checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
3312 0 : qualifier.imageInternalFormat = EiifR32UI;
3313 : }
3314 :
3315 : else
3316 : {
3317 0 : error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
3318 : }
3319 :
3320 0 : return qualifier;
3321 : }
3322 :
3323 0 : void TParseContext::parseLocalSize(const TString &qualifierType,
3324 : const TSourceLoc &qualifierTypeLine,
3325 : int intValue,
3326 : const TSourceLoc &intValueLine,
3327 : const std::string &intValueString,
3328 : size_t index,
3329 : sh::WorkGroupSize *localSize)
3330 : {
3331 0 : checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
3332 0 : if (intValue < 1)
3333 : {
3334 0 : std::string errorMessage = std::string(getWorkGroupSizeString(index)) + " must be positive";
3335 0 : error(intValueLine, "out of range:", intValueString.c_str(), errorMessage.c_str());
3336 : }
3337 0 : (*localSize)[index] = intValue;
3338 0 : }
3339 :
3340 0 : TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType,
3341 : const TSourceLoc &qualifierTypeLine,
3342 : int intValue,
3343 : const TSourceLoc &intValueLine)
3344 : {
3345 0 : TLayoutQualifier qualifier = TLayoutQualifier::create();
3346 :
3347 0 : std::string intValueString = Str(intValue);
3348 :
3349 0 : if (qualifierType == "location")
3350 : {
3351 : // must check that location is non-negative
3352 0 : if (intValue < 0)
3353 : {
3354 0 : error(intValueLine, "out of range:", intValueString.c_str(),
3355 0 : "location must be non-negative");
3356 : }
3357 : else
3358 : {
3359 0 : qualifier.location = intValue;
3360 0 : qualifier.locationsSpecified = 1;
3361 : }
3362 : }
3363 0 : else if (qualifierType == "local_size_x")
3364 : {
3365 : parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 0u,
3366 0 : &qualifier.localSize);
3367 : }
3368 0 : else if (qualifierType == "local_size_y")
3369 : {
3370 : parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 1u,
3371 0 : &qualifier.localSize);
3372 : }
3373 0 : else if (qualifierType == "local_size_z")
3374 : {
3375 : parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 2u,
3376 0 : &qualifier.localSize);
3377 : }
3378 : else
3379 : {
3380 0 : error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
3381 : }
3382 :
3383 0 : return qualifier;
3384 : }
3385 :
3386 0 : TTypeQualifierBuilder *TParseContext::createTypeQualifierBuilder(const TSourceLoc &loc)
3387 : {
3388 : return new TTypeQualifierBuilder(
3389 0 : new TStorageQualifierWrapper(symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary, loc),
3390 0 : mShaderVersion);
3391 : }
3392 :
3393 0 : TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier,
3394 : TLayoutQualifier rightQualifier,
3395 : const TSourceLoc &rightQualifierLocation)
3396 : {
3397 : return sh::JoinLayoutQualifiers(leftQualifier, rightQualifier, rightQualifierLocation,
3398 0 : &mDiagnostics);
3399 : }
3400 :
3401 0 : TFieldList *TParseContext::addStructDeclaratorListWithQualifiers(
3402 : const TTypeQualifierBuilder &typeQualifierBuilder,
3403 : TPublicType *typeSpecifier,
3404 : TFieldList *fieldList)
3405 : {
3406 0 : TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics);
3407 :
3408 0 : typeSpecifier->qualifier = typeQualifier.qualifier;
3409 0 : typeSpecifier->layoutQualifier = typeQualifier.layoutQualifier;
3410 0 : typeSpecifier->memoryQualifier = typeQualifier.memoryQualifier;
3411 0 : typeSpecifier->invariant = typeQualifier.invariant;
3412 0 : if (typeQualifier.precision != EbpUndefined)
3413 : {
3414 0 : typeSpecifier->precision = typeQualifier.precision;
3415 : }
3416 0 : return addStructDeclaratorList(*typeSpecifier, fieldList);
3417 : }
3418 :
3419 0 : TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecifier,
3420 : TFieldList *fieldList)
3421 : {
3422 0 : checkPrecisionSpecified(typeSpecifier.getLine(), typeSpecifier.precision,
3423 0 : typeSpecifier.getBasicType());
3424 :
3425 0 : checkIsNonVoid(typeSpecifier.getLine(), (*fieldList)[0]->name(), typeSpecifier.getBasicType());
3426 :
3427 0 : checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), typeSpecifier.layoutQualifier);
3428 :
3429 0 : for (unsigned int i = 0; i < fieldList->size(); ++i)
3430 : {
3431 : //
3432 : // Careful not to replace already known aspects of type, like array-ness
3433 : //
3434 0 : TType *type = (*fieldList)[i]->type();
3435 0 : type->setBasicType(typeSpecifier.getBasicType());
3436 0 : type->setPrimarySize(typeSpecifier.getPrimarySize());
3437 0 : type->setSecondarySize(typeSpecifier.getSecondarySize());
3438 0 : type->setPrecision(typeSpecifier.precision);
3439 0 : type->setQualifier(typeSpecifier.qualifier);
3440 0 : type->setLayoutQualifier(typeSpecifier.layoutQualifier);
3441 0 : type->setMemoryQualifier(typeSpecifier.memoryQualifier);
3442 0 : type->setInvariant(typeSpecifier.invariant);
3443 :
3444 : // don't allow arrays of arrays
3445 0 : if (type->isArray())
3446 : {
3447 0 : checkIsValidTypeForArray(typeSpecifier.getLine(), typeSpecifier);
3448 : }
3449 0 : if (typeSpecifier.array)
3450 0 : type->setArraySize(static_cast<unsigned int>(typeSpecifier.arraySize));
3451 0 : if (typeSpecifier.getUserDef())
3452 : {
3453 0 : type->setStruct(typeSpecifier.getUserDef()->getStruct());
3454 : }
3455 :
3456 0 : checkIsBelowStructNestingLimit(typeSpecifier.getLine(), *(*fieldList)[i]);
3457 : }
3458 :
3459 0 : return fieldList;
3460 : }
3461 :
3462 0 : TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine,
3463 : const TSourceLoc &nameLine,
3464 : const TString *structName,
3465 : TFieldList *fieldList)
3466 : {
3467 0 : TStructure *structure = new TStructure(structName, fieldList);
3468 0 : TType *structureType = new TType(structure);
3469 :
3470 : // Store a bool in the struct if we're at global scope, to allow us to
3471 : // skip the local struct scoping workaround in HLSL.
3472 0 : structure->setAtGlobalScope(symbolTable.atGlobalLevel());
3473 :
3474 0 : if (!structName->empty())
3475 : {
3476 0 : checkIsNotReserved(nameLine, *structName);
3477 0 : TVariable *userTypeDef = new TVariable(structName, *structureType, true);
3478 0 : if (!symbolTable.declare(userTypeDef))
3479 : {
3480 0 : error(nameLine, "redefinition", structName->c_str(), "struct");
3481 : }
3482 : }
3483 :
3484 : // ensure we do not specify any storage qualifiers on the struct members
3485 0 : for (unsigned int typeListIndex = 0; typeListIndex < fieldList->size(); typeListIndex++)
3486 : {
3487 0 : const TField &field = *(*fieldList)[typeListIndex];
3488 0 : const TQualifier qualifier = field.type()->getQualifier();
3489 0 : switch (qualifier)
3490 : {
3491 : case EvqGlobal:
3492 : case EvqTemporary:
3493 0 : break;
3494 : default:
3495 0 : error(field.line(), "invalid qualifier on struct member",
3496 0 : getQualifierString(qualifier));
3497 0 : break;
3498 : }
3499 0 : if (field.type()->isInvariant())
3500 : {
3501 0 : error(field.line(), "invalid qualifier on struct member", "invariant");
3502 : }
3503 0 : if (IsImage(field.type()->getBasicType()))
3504 : {
3505 0 : error(field.line(), "disallowed type in struct", field.type()->getBasicString());
3506 : }
3507 :
3508 0 : checkIsMemoryQualifierNotSpecified(field.type()->getMemoryQualifier(), field.line());
3509 :
3510 0 : checkLocationIsNotSpecified(field.line(), field.type()->getLayoutQualifier());
3511 : }
3512 :
3513 : TTypeSpecifierNonArray typeSpecifierNonArray;
3514 0 : typeSpecifierNonArray.initialize(EbtStruct, structLine);
3515 0 : typeSpecifierNonArray.userDef = structureType;
3516 0 : typeSpecifierNonArray.isStructSpecifier = true;
3517 0 : exitStructDeclaration();
3518 :
3519 0 : return typeSpecifierNonArray;
3520 : }
3521 :
3522 0 : TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init,
3523 : TIntermBlock *statementList,
3524 : const TSourceLoc &loc)
3525 : {
3526 0 : TBasicType switchType = init->getBasicType();
3527 0 : if ((switchType != EbtInt && switchType != EbtUInt) || init->isMatrix() || init->isArray() ||
3528 0 : init->isVector())
3529 : {
3530 0 : error(init->getLine(), "init-expression in a switch statement must be a scalar integer",
3531 0 : "switch");
3532 0 : return nullptr;
3533 : }
3534 :
3535 0 : if (statementList)
3536 : {
3537 0 : if (!ValidateSwitch::validate(switchType, this, statementList, loc))
3538 : {
3539 0 : return nullptr;
3540 : }
3541 : }
3542 :
3543 0 : TIntermSwitch *node = intermediate.addSwitch(init, statementList, loc);
3544 0 : if (node == nullptr)
3545 : {
3546 0 : error(loc, "erroneous switch statement", "switch");
3547 0 : return nullptr;
3548 : }
3549 0 : return node;
3550 : }
3551 :
3552 0 : TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &loc)
3553 : {
3554 0 : if (mSwitchNestingLevel == 0)
3555 : {
3556 0 : error(loc, "case labels need to be inside switch statements", "case");
3557 0 : return nullptr;
3558 : }
3559 0 : if (condition == nullptr)
3560 : {
3561 0 : error(loc, "case label must have a condition", "case");
3562 0 : return nullptr;
3563 : }
3564 0 : if ((condition->getBasicType() != EbtInt && condition->getBasicType() != EbtUInt) ||
3565 0 : condition->isMatrix() || condition->isArray() || condition->isVector())
3566 : {
3567 0 : error(condition->getLine(), "case label must be a scalar integer", "case");
3568 : }
3569 0 : TIntermConstantUnion *conditionConst = condition->getAsConstantUnion();
3570 : // TODO(oetuaho@nvidia.com): Get rid of the conditionConst == nullptr check once all constant
3571 : // expressions can be folded. Right now we don't allow constant expressions that ANGLE can't
3572 : // fold in case labels.
3573 0 : if (condition->getQualifier() != EvqConst || conditionConst == nullptr)
3574 : {
3575 0 : error(condition->getLine(), "case label must be constant", "case");
3576 : }
3577 0 : TIntermCase *node = intermediate.addCase(condition, loc);
3578 0 : if (node == nullptr)
3579 : {
3580 0 : error(loc, "erroneous case statement", "case");
3581 0 : return nullptr;
3582 : }
3583 0 : return node;
3584 : }
3585 :
3586 0 : TIntermCase *TParseContext::addDefault(const TSourceLoc &loc)
3587 : {
3588 0 : if (mSwitchNestingLevel == 0)
3589 : {
3590 0 : error(loc, "default labels need to be inside switch statements", "default");
3591 0 : return nullptr;
3592 : }
3593 0 : TIntermCase *node = intermediate.addCase(nullptr, loc);
3594 0 : if (node == nullptr)
3595 : {
3596 0 : error(loc, "erroneous default statement", "default");
3597 0 : return nullptr;
3598 : }
3599 0 : return node;
3600 : }
3601 :
3602 0 : TIntermTyped *TParseContext::createUnaryMath(TOperator op,
3603 : TIntermTyped *child,
3604 : const TSourceLoc &loc,
3605 : const TType *funcReturnType)
3606 : {
3607 0 : if (child == nullptr)
3608 : {
3609 0 : return nullptr;
3610 : }
3611 :
3612 0 : switch (op)
3613 : {
3614 : case EOpLogicalNot:
3615 0 : if (child->getBasicType() != EbtBool || child->isMatrix() || child->isArray() ||
3616 0 : child->isVector())
3617 : {
3618 0 : return nullptr;
3619 : }
3620 0 : break;
3621 : case EOpBitwiseNot:
3622 0 : if ((child->getBasicType() != EbtInt && child->getBasicType() != EbtUInt) ||
3623 0 : child->isMatrix() || child->isArray())
3624 : {
3625 0 : return nullptr;
3626 : }
3627 0 : break;
3628 : case EOpPostIncrement:
3629 : case EOpPreIncrement:
3630 : case EOpPostDecrement:
3631 : case EOpPreDecrement:
3632 : case EOpNegative:
3633 : case EOpPositive:
3634 0 : if (child->getBasicType() == EbtStruct || child->getBasicType() == EbtBool ||
3635 0 : child->isArray() || IsOpaqueType(child->getBasicType()))
3636 : {
3637 0 : return nullptr;
3638 : }
3639 : // Operators for built-ins are already type checked against their prototype.
3640 : default:
3641 0 : break;
3642 : }
3643 :
3644 0 : TIntermUnary *node = new TIntermUnary(op, child);
3645 0 : node->setLine(loc);
3646 :
3647 0 : TIntermTyped *foldedNode = node->fold(&mDiagnostics);
3648 0 : if (foldedNode)
3649 0 : return foldedNode;
3650 :
3651 0 : return node;
3652 : }
3653 :
3654 0 : TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
3655 : {
3656 0 : TIntermTyped *node = createUnaryMath(op, child, loc, nullptr);
3657 0 : if (node == nullptr)
3658 : {
3659 0 : unaryOpError(loc, GetOperatorString(op), child->getCompleteString());
3660 0 : return child;
3661 : }
3662 0 : return node;
3663 : }
3664 :
3665 0 : TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op,
3666 : TIntermTyped *child,
3667 : const TSourceLoc &loc)
3668 : {
3669 0 : checkCanBeLValue(loc, GetOperatorString(op), child);
3670 0 : return addUnaryMath(op, child, loc);
3671 : }
3672 :
3673 0 : bool TParseContext::binaryOpCommonCheck(TOperator op,
3674 : TIntermTyped *left,
3675 : TIntermTyped *right,
3676 : const TSourceLoc &loc)
3677 : {
3678 0 : if (left->getType().getStruct() || right->getType().getStruct())
3679 : {
3680 0 : switch (op)
3681 : {
3682 : case EOpIndexDirectStruct:
3683 0 : ASSERT(left->getType().getStruct());
3684 0 : break;
3685 : case EOpEqual:
3686 : case EOpNotEqual:
3687 : case EOpAssign:
3688 : case EOpInitialize:
3689 0 : if (left->getType() != right->getType())
3690 : {
3691 0 : return false;
3692 : }
3693 0 : break;
3694 : default:
3695 0 : error(loc, "Invalid operation for structs", GetOperatorString(op));
3696 0 : return false;
3697 : }
3698 : }
3699 :
3700 0 : if (left->isArray() || right->isArray())
3701 : {
3702 0 : if (mShaderVersion < 300)
3703 : {
3704 0 : error(loc, "Invalid operation for arrays", GetOperatorString(op));
3705 0 : return false;
3706 : }
3707 :
3708 0 : if (left->isArray() != right->isArray())
3709 : {
3710 0 : error(loc, "array / non-array mismatch", GetOperatorString(op));
3711 0 : return false;
3712 : }
3713 :
3714 0 : switch (op)
3715 : {
3716 : case EOpEqual:
3717 : case EOpNotEqual:
3718 : case EOpAssign:
3719 : case EOpInitialize:
3720 0 : break;
3721 : default:
3722 0 : error(loc, "Invalid operation for arrays", GetOperatorString(op));
3723 0 : return false;
3724 : }
3725 : // At this point, size of implicitly sized arrays should be resolved.
3726 0 : if (left->getArraySize() != right->getArraySize())
3727 : {
3728 0 : error(loc, "array size mismatch", GetOperatorString(op));
3729 0 : return false;
3730 : }
3731 : }
3732 :
3733 : // Check ops which require integer / ivec parameters
3734 0 : bool isBitShift = false;
3735 0 : switch (op)
3736 : {
3737 : case EOpBitShiftLeft:
3738 : case EOpBitShiftRight:
3739 : case EOpBitShiftLeftAssign:
3740 : case EOpBitShiftRightAssign:
3741 : // Unsigned can be bit-shifted by signed and vice versa, but we need to
3742 : // check that the basic type is an integer type.
3743 0 : isBitShift = true;
3744 0 : if (!IsInteger(left->getBasicType()) || !IsInteger(right->getBasicType()))
3745 : {
3746 0 : return false;
3747 : }
3748 0 : break;
3749 : case EOpBitwiseAnd:
3750 : case EOpBitwiseXor:
3751 : case EOpBitwiseOr:
3752 : case EOpBitwiseAndAssign:
3753 : case EOpBitwiseXorAssign:
3754 : case EOpBitwiseOrAssign:
3755 : // It is enough to check the type of only one operand, since later it
3756 : // is checked that the operand types match.
3757 0 : if (!IsInteger(left->getBasicType()))
3758 : {
3759 0 : return false;
3760 : }
3761 0 : break;
3762 : default:
3763 0 : break;
3764 : }
3765 :
3766 : // GLSL ES 1.00 and 3.00 do not support implicit type casting.
3767 : // So the basic type should usually match.
3768 0 : if (!isBitShift && left->getBasicType() != right->getBasicType())
3769 : {
3770 0 : return false;
3771 : }
3772 :
3773 : // Check that:
3774 : // 1. Type sizes match exactly on ops that require that.
3775 : // 2. Restrictions for structs that contain arrays or samplers are respected.
3776 : // 3. Arithmetic op type dimensionality restrictions for ops other than multiply are respected.
3777 0 : switch (op)
3778 : {
3779 : case EOpAssign:
3780 : case EOpInitialize:
3781 : case EOpEqual:
3782 : case EOpNotEqual:
3783 : // ESSL 1.00 sections 5.7, 5.8, 5.9
3784 0 : if (mShaderVersion < 300 && left->getType().isStructureContainingArrays())
3785 : {
3786 0 : error(loc, "undefined operation for structs containing arrays",
3787 0 : GetOperatorString(op));
3788 0 : return false;
3789 : }
3790 : // Samplers as l-values are disallowed also in ESSL 3.00, see section 4.1.7,
3791 : // we interpret the spec so that this extends to structs containing samplers,
3792 : // similarly to ESSL 1.00 spec.
3793 0 : if ((mShaderVersion < 300 || op == EOpAssign || op == EOpInitialize) &&
3794 0 : left->getType().isStructureContainingSamplers())
3795 : {
3796 0 : error(loc, "undefined operation for structs containing samplers",
3797 0 : GetOperatorString(op));
3798 0 : return false;
3799 : }
3800 :
3801 0 : if ((op == EOpAssign || op == EOpInitialize) &&
3802 0 : left->getType().isStructureContainingImages())
3803 : {
3804 0 : error(loc, "undefined operation for structs containing images",
3805 0 : GetOperatorString(op));
3806 0 : return false;
3807 : }
3808 : case EOpLessThan:
3809 : case EOpGreaterThan:
3810 : case EOpLessThanEqual:
3811 : case EOpGreaterThanEqual:
3812 0 : if ((left->getNominalSize() != right->getNominalSize()) ||
3813 0 : (left->getSecondarySize() != right->getSecondarySize()))
3814 : {
3815 0 : return false;
3816 : }
3817 0 : break;
3818 : case EOpAdd:
3819 : case EOpSub:
3820 : case EOpDiv:
3821 : case EOpIMod:
3822 : case EOpBitShiftLeft:
3823 : case EOpBitShiftRight:
3824 : case EOpBitwiseAnd:
3825 : case EOpBitwiseXor:
3826 : case EOpBitwiseOr:
3827 : case EOpAddAssign:
3828 : case EOpSubAssign:
3829 : case EOpDivAssign:
3830 : case EOpIModAssign:
3831 : case EOpBitShiftLeftAssign:
3832 : case EOpBitShiftRightAssign:
3833 : case EOpBitwiseAndAssign:
3834 : case EOpBitwiseXorAssign:
3835 : case EOpBitwiseOrAssign:
3836 0 : if ((left->isMatrix() && right->isVector()) || (left->isVector() && right->isMatrix()))
3837 : {
3838 0 : return false;
3839 : }
3840 :
3841 : // Are the sizes compatible?
3842 0 : if (left->getNominalSize() != right->getNominalSize() ||
3843 0 : left->getSecondarySize() != right->getSecondarySize())
3844 : {
3845 : // If the nominal sizes of operands do not match:
3846 : // One of them must be a scalar.
3847 0 : if (!left->isScalar() && !right->isScalar())
3848 0 : return false;
3849 :
3850 : // In the case of compound assignment other than multiply-assign,
3851 : // the right side needs to be a scalar. Otherwise a vector/matrix
3852 : // would be assigned to a scalar. A scalar can't be shifted by a
3853 : // vector either.
3854 0 : if (!right->isScalar() &&
3855 0 : (IsAssignment(op) || op == EOpBitShiftLeft || op == EOpBitShiftRight))
3856 0 : return false;
3857 : }
3858 0 : break;
3859 : default:
3860 0 : break;
3861 : }
3862 :
3863 0 : return true;
3864 : }
3865 :
3866 0 : bool TParseContext::isMultiplicationTypeCombinationValid(TOperator op,
3867 : const TType &left,
3868 : const TType &right)
3869 : {
3870 0 : switch (op)
3871 : {
3872 : case EOpMul:
3873 : case EOpMulAssign:
3874 0 : return left.getNominalSize() == right.getNominalSize() &&
3875 0 : left.getSecondarySize() == right.getSecondarySize();
3876 : case EOpVectorTimesScalar:
3877 0 : return true;
3878 : case EOpVectorTimesScalarAssign:
3879 0 : ASSERT(!left.isMatrix() && !right.isMatrix());
3880 0 : return left.isVector() && !right.isVector();
3881 : case EOpVectorTimesMatrix:
3882 0 : return left.getNominalSize() == right.getRows();
3883 : case EOpVectorTimesMatrixAssign:
3884 0 : ASSERT(!left.isMatrix() && right.isMatrix());
3885 0 : return left.isVector() && left.getNominalSize() == right.getRows() &&
3886 0 : left.getNominalSize() == right.getCols();
3887 : case EOpMatrixTimesVector:
3888 0 : return left.getCols() == right.getNominalSize();
3889 : case EOpMatrixTimesScalar:
3890 0 : return true;
3891 : case EOpMatrixTimesScalarAssign:
3892 0 : ASSERT(left.isMatrix() && !right.isMatrix());
3893 0 : return !right.isVector();
3894 : case EOpMatrixTimesMatrix:
3895 0 : return left.getCols() == right.getRows();
3896 : case EOpMatrixTimesMatrixAssign:
3897 0 : ASSERT(left.isMatrix() && right.isMatrix());
3898 : // We need to check two things:
3899 : // 1. The matrix multiplication step is valid.
3900 : // 2. The result will have the same number of columns as the lvalue.
3901 0 : return left.getCols() == right.getRows() && left.getCols() == right.getCols();
3902 :
3903 : default:
3904 0 : UNREACHABLE();
3905 : return false;
3906 : }
3907 : }
3908 :
3909 0 : TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op,
3910 : TIntermTyped *left,
3911 : TIntermTyped *right,
3912 : const TSourceLoc &loc)
3913 : {
3914 0 : if (!binaryOpCommonCheck(op, left, right, loc))
3915 0 : return nullptr;
3916 :
3917 0 : switch (op)
3918 : {
3919 : case EOpEqual:
3920 : case EOpNotEqual:
3921 0 : break;
3922 : case EOpLessThan:
3923 : case EOpGreaterThan:
3924 : case EOpLessThanEqual:
3925 : case EOpGreaterThanEqual:
3926 0 : ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() &&
3927 : !right->getType().getStruct());
3928 0 : if (left->isMatrix() || left->isVector())
3929 : {
3930 0 : return nullptr;
3931 : }
3932 0 : break;
3933 : case EOpLogicalOr:
3934 : case EOpLogicalXor:
3935 : case EOpLogicalAnd:
3936 0 : ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() &&
3937 : !right->getType().getStruct());
3938 0 : if (left->getBasicType() != EbtBool || !left->isScalar() || !right->isScalar())
3939 : {
3940 0 : return nullptr;
3941 : }
3942 : // Basic types matching should have been already checked.
3943 0 : ASSERT(right->getBasicType() == EbtBool);
3944 0 : break;
3945 : case EOpAdd:
3946 : case EOpSub:
3947 : case EOpDiv:
3948 : case EOpMul:
3949 0 : ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() &&
3950 : !right->getType().getStruct());
3951 0 : if (left->getBasicType() == EbtBool)
3952 : {
3953 0 : return nullptr;
3954 : }
3955 0 : break;
3956 : case EOpIMod:
3957 0 : ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() &&
3958 : !right->getType().getStruct());
3959 : // Note that this is only for the % operator, not for mod()
3960 0 : if (left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat)
3961 : {
3962 0 : return nullptr;
3963 : }
3964 0 : break;
3965 : default:
3966 0 : break;
3967 : }
3968 :
3969 0 : if (op == EOpMul)
3970 : {
3971 0 : op = TIntermBinary::GetMulOpBasedOnOperands(left->getType(), right->getType());
3972 0 : if (!isMultiplicationTypeCombinationValid(op, left->getType(), right->getType()))
3973 : {
3974 0 : return nullptr;
3975 : }
3976 : }
3977 :
3978 0 : TIntermBinary *node = new TIntermBinary(op, left, right);
3979 0 : node->setLine(loc);
3980 :
3981 : // See if we can fold constants.
3982 0 : TIntermTyped *foldedNode = node->fold(&mDiagnostics);
3983 0 : if (foldedNode)
3984 0 : return foldedNode;
3985 :
3986 0 : return node;
3987 : }
3988 :
3989 0 : TIntermTyped *TParseContext::addBinaryMath(TOperator op,
3990 : TIntermTyped *left,
3991 : TIntermTyped *right,
3992 : const TSourceLoc &loc)
3993 : {
3994 0 : TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
3995 0 : if (node == 0)
3996 : {
3997 0 : binaryOpError(loc, GetOperatorString(op), left->getCompleteString(),
3998 0 : right->getCompleteString());
3999 0 : return left;
4000 : }
4001 0 : return node;
4002 : }
4003 :
4004 0 : TIntermTyped *TParseContext::addBinaryMathBooleanResult(TOperator op,
4005 : TIntermTyped *left,
4006 : TIntermTyped *right,
4007 : const TSourceLoc &loc)
4008 : {
4009 0 : TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
4010 0 : if (node == 0)
4011 : {
4012 0 : binaryOpError(loc, GetOperatorString(op), left->getCompleteString(),
4013 0 : right->getCompleteString());
4014 0 : TConstantUnion *unionArray = new TConstantUnion[1];
4015 0 : unionArray->setBConst(false);
4016 0 : return intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst),
4017 0 : loc);
4018 : }
4019 0 : return node;
4020 : }
4021 :
4022 0 : TIntermBinary *TParseContext::createAssign(TOperator op,
4023 : TIntermTyped *left,
4024 : TIntermTyped *right,
4025 : const TSourceLoc &loc)
4026 : {
4027 0 : if (binaryOpCommonCheck(op, left, right, loc))
4028 : {
4029 0 : if (op == EOpMulAssign)
4030 : {
4031 0 : op = TIntermBinary::GetMulAssignOpBasedOnOperands(left->getType(), right->getType());
4032 0 : if (!isMultiplicationTypeCombinationValid(op, left->getType(), right->getType()))
4033 : {
4034 0 : return nullptr;
4035 : }
4036 : }
4037 0 : TIntermBinary *node = new TIntermBinary(op, left, right);
4038 0 : node->setLine(loc);
4039 :
4040 0 : return node;
4041 : }
4042 0 : return nullptr;
4043 : }
4044 :
4045 0 : TIntermTyped *TParseContext::addAssign(TOperator op,
4046 : TIntermTyped *left,
4047 : TIntermTyped *right,
4048 : const TSourceLoc &loc)
4049 : {
4050 0 : TIntermTyped *node = createAssign(op, left, right, loc);
4051 0 : if (node == nullptr)
4052 : {
4053 0 : assignError(loc, "assign", left->getCompleteString(), right->getCompleteString());
4054 0 : return left;
4055 : }
4056 0 : return node;
4057 : }
4058 :
4059 0 : TIntermTyped *TParseContext::addComma(TIntermTyped *left,
4060 : TIntermTyped *right,
4061 : const TSourceLoc &loc)
4062 : {
4063 : // WebGL2 section 5.26, the following results in an error:
4064 : // "Sequence operator applied to void, arrays, or structs containing arrays"
4065 0 : if (mShaderSpec == SH_WEBGL2_SPEC && (left->isArray() || left->getBasicType() == EbtVoid ||
4066 0 : left->getType().isStructureContainingArrays() ||
4067 0 : right->isArray() || right->getBasicType() == EbtVoid ||
4068 0 : right->getType().isStructureContainingArrays()))
4069 : {
4070 : error(loc,
4071 : "sequence operator is not allowed for void, arrays, or structs containing arrays",
4072 0 : ",");
4073 : }
4074 :
4075 0 : return TIntermediate::AddComma(left, right, loc, mShaderVersion);
4076 : }
4077 :
4078 0 : TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc)
4079 : {
4080 0 : switch (op)
4081 : {
4082 : case EOpContinue:
4083 0 : if (mLoopNestingLevel <= 0)
4084 : {
4085 0 : error(loc, "continue statement only allowed in loops", "");
4086 : }
4087 0 : break;
4088 : case EOpBreak:
4089 0 : if (mLoopNestingLevel <= 0 && mSwitchNestingLevel <= 0)
4090 : {
4091 0 : error(loc, "break statement only allowed in loops and switch statements", "");
4092 : }
4093 0 : break;
4094 : case EOpReturn:
4095 0 : if (mCurrentFunctionType->getBasicType() != EbtVoid)
4096 : {
4097 0 : error(loc, "non-void function must return a value", "return");
4098 : }
4099 0 : break;
4100 : default:
4101 : // No checks for discard
4102 0 : break;
4103 : }
4104 0 : return intermediate.addBranch(op, loc);
4105 : }
4106 :
4107 0 : TIntermBranch *TParseContext::addBranch(TOperator op,
4108 : TIntermTyped *returnValue,
4109 : const TSourceLoc &loc)
4110 : {
4111 0 : ASSERT(op == EOpReturn);
4112 0 : mFunctionReturnsValue = true;
4113 0 : if (mCurrentFunctionType->getBasicType() == EbtVoid)
4114 : {
4115 0 : error(loc, "void function cannot return a value", "return");
4116 : }
4117 0 : else if (*mCurrentFunctionType != returnValue->getType())
4118 : {
4119 0 : error(loc, "function return is not matching type:", "return");
4120 : }
4121 0 : return intermediate.addBranch(op, returnValue, loc);
4122 : }
4123 :
4124 0 : void TParseContext::checkTextureOffsetConst(TIntermAggregate *functionCall)
4125 : {
4126 0 : ASSERT(!functionCall->isUserDefined());
4127 0 : const TString &name = functionCall->getFunctionSymbolInfo()->getName();
4128 0 : TIntermNode *offset = nullptr;
4129 0 : TIntermSequence *arguments = functionCall->getSequence();
4130 0 : if (name.compare(0, 16, "texelFetchOffset") == 0 ||
4131 0 : name.compare(0, 16, "textureLodOffset") == 0 ||
4132 0 : name.compare(0, 20, "textureProjLodOffset") == 0 ||
4133 0 : name.compare(0, 17, "textureGradOffset") == 0 ||
4134 0 : name.compare(0, 21, "textureProjGradOffset") == 0)
4135 : {
4136 0 : offset = arguments->back();
4137 : }
4138 0 : else if (name.compare(0, 13, "textureOffset") == 0 ||
4139 0 : name.compare(0, 17, "textureProjOffset") == 0)
4140 : {
4141 : // A bias parameter might follow the offset parameter.
4142 0 : ASSERT(arguments->size() >= 3);
4143 0 : offset = (*arguments)[2];
4144 : }
4145 0 : if (offset != nullptr)
4146 : {
4147 0 : TIntermConstantUnion *offsetConstantUnion = offset->getAsConstantUnion();
4148 0 : if (offset->getAsTyped()->getQualifier() != EvqConst || !offsetConstantUnion)
4149 : {
4150 0 : TString unmangledName = TFunction::unmangleName(name);
4151 0 : error(functionCall->getLine(), "Texture offset must be a constant expression",
4152 0 : unmangledName.c_str());
4153 : }
4154 : else
4155 : {
4156 0 : ASSERT(offsetConstantUnion->getBasicType() == EbtInt);
4157 0 : size_t size = offsetConstantUnion->getType().getObjectSize();
4158 0 : const TConstantUnion *values = offsetConstantUnion->getUnionArrayPointer();
4159 0 : for (size_t i = 0u; i < size; ++i)
4160 : {
4161 0 : int offsetValue = values[i].getIConst();
4162 0 : if (offsetValue > mMaxProgramTexelOffset || offsetValue < mMinProgramTexelOffset)
4163 : {
4164 0 : std::stringstream tokenStream;
4165 0 : tokenStream << offsetValue;
4166 0 : std::string token = tokenStream.str();
4167 0 : error(offset->getLine(), "Texture offset value out of valid range",
4168 0 : token.c_str());
4169 : }
4170 : }
4171 : }
4172 : }
4173 0 : }
4174 :
4175 : // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
4176 0 : void TParseContext::checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall)
4177 : {
4178 0 : ASSERT(!functionCall->isUserDefined());
4179 0 : const TString &name = functionCall->getFunctionSymbolInfo()->getName();
4180 :
4181 0 : if (name.compare(0, 5, "image") == 0)
4182 : {
4183 0 : TIntermSequence *arguments = functionCall->getSequence();
4184 0 : TIntermNode *imageNode = (*arguments)[0];
4185 0 : TIntermSymbol *imageSymbol = imageNode->getAsSymbolNode();
4186 :
4187 0 : const TMemoryQualifier &memoryQualifier = imageSymbol->getMemoryQualifier();
4188 :
4189 0 : if (name.compare(5, 5, "Store") == 0)
4190 : {
4191 0 : if (memoryQualifier.readonly)
4192 : {
4193 0 : error(imageNode->getLine(),
4194 : "'imageStore' cannot be used with images qualified as 'readonly'",
4195 0 : imageSymbol->getSymbol().c_str());
4196 : }
4197 : }
4198 0 : else if (name.compare(5, 4, "Load") == 0)
4199 : {
4200 0 : if (memoryQualifier.writeonly)
4201 : {
4202 0 : error(imageNode->getLine(),
4203 : "'imageLoad' cannot be used with images qualified as 'writeonly'",
4204 0 : imageSymbol->getSymbol().c_str());
4205 : }
4206 : }
4207 : }
4208 0 : }
4209 :
4210 : // GLSL ES 3.10 Revision 4, 13.51 Matching of Memory Qualifiers in Function Parameters
4211 0 : void TParseContext::checkImageMemoryAccessForUserDefinedFunctions(
4212 : const TFunction *functionDefinition,
4213 : const TIntermAggregate *functionCall)
4214 : {
4215 0 : ASSERT(functionCall->isUserDefined());
4216 :
4217 0 : const TIntermSequence &arguments = *functionCall->getSequence();
4218 :
4219 0 : ASSERT(functionDefinition->getParamCount() == arguments.size());
4220 :
4221 0 : for (size_t i = 0; i < arguments.size(); ++i)
4222 : {
4223 0 : const TType &functionArgumentType = arguments[i]->getAsTyped()->getType();
4224 0 : const TType &functionParameterType = *functionDefinition->getParam(i).type;
4225 0 : ASSERT(functionArgumentType.getBasicType() == functionParameterType.getBasicType());
4226 :
4227 0 : if (IsImage(functionArgumentType.getBasicType()))
4228 : {
4229 : const TMemoryQualifier &functionArgumentMemoryQualifier =
4230 0 : functionArgumentType.getMemoryQualifier();
4231 : const TMemoryQualifier &functionParameterMemoryQualifier =
4232 0 : functionParameterType.getMemoryQualifier();
4233 0 : if (functionArgumentMemoryQualifier.readonly &&
4234 0 : !functionParameterMemoryQualifier.readonly)
4235 : {
4236 0 : error(functionCall->getLine(),
4237 : "Function call discards the 'readonly' qualifier from image",
4238 0 : arguments[i]->getAsSymbolNode()->getSymbol().c_str());
4239 : }
4240 :
4241 0 : if (functionArgumentMemoryQualifier.writeonly &&
4242 0 : !functionParameterMemoryQualifier.writeonly)
4243 : {
4244 0 : error(functionCall->getLine(),
4245 : "Function call discards the 'writeonly' qualifier from image",
4246 0 : arguments[i]->getAsSymbolNode()->getSymbol().c_str());
4247 : }
4248 :
4249 0 : if (functionArgumentMemoryQualifier.coherent &&
4250 0 : !functionParameterMemoryQualifier.coherent)
4251 : {
4252 0 : error(functionCall->getLine(),
4253 : "Function call discards the 'coherent' qualifier from image",
4254 0 : arguments[i]->getAsSymbolNode()->getSymbol().c_str());
4255 : }
4256 :
4257 0 : if (functionArgumentMemoryQualifier.volatileQualifier &&
4258 0 : !functionParameterMemoryQualifier.volatileQualifier)
4259 : {
4260 0 : error(functionCall->getLine(),
4261 : "Function call discards the 'volatile' qualifier from image",
4262 0 : arguments[i]->getAsSymbolNode()->getSymbol().c_str());
4263 : }
4264 : }
4265 : }
4266 0 : }
4267 :
4268 0 : TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall,
4269 : TIntermNode *paramNode,
4270 : TIntermNode *thisNode,
4271 : const TSourceLoc &loc,
4272 : bool *fatalError)
4273 : {
4274 0 : *fatalError = false;
4275 0 : TOperator op = fnCall->getBuiltInOp();
4276 0 : TIntermTyped *callNode = nullptr;
4277 :
4278 0 : if (thisNode != nullptr)
4279 : {
4280 0 : TConstantUnion *unionArray = new TConstantUnion[1];
4281 0 : int arraySize = 0;
4282 0 : TIntermTyped *typedThis = thisNode->getAsTyped();
4283 0 : if (fnCall->getName() != "length")
4284 : {
4285 0 : error(loc, "invalid method", fnCall->getName().c_str());
4286 : }
4287 0 : else if (paramNode != nullptr)
4288 : {
4289 0 : error(loc, "method takes no parameters", "length");
4290 : }
4291 0 : else if (typedThis == nullptr || !typedThis->isArray())
4292 : {
4293 0 : error(loc, "length can only be called on arrays", "length");
4294 : }
4295 : else
4296 : {
4297 0 : arraySize = typedThis->getArraySize();
4298 0 : if (typedThis->getAsSymbolNode() == nullptr)
4299 : {
4300 : // This code path can be hit with expressions like these:
4301 : // (a = b).length()
4302 : // (func()).length()
4303 : // (int[3](0, 1, 2)).length()
4304 : // ESSL 3.00 section 5.9 defines expressions so that this is not actually a valid
4305 : // expression.
4306 : // It allows "An array name with the length method applied" in contrast to GLSL 4.4
4307 : // spec section 5.9 which allows "An array, vector or matrix expression with the
4308 : // length method applied".
4309 : error(loc, "length can only be called on array names, not on array expressions",
4310 0 : "length");
4311 : }
4312 : }
4313 0 : unionArray->setIConst(arraySize);
4314 : callNode =
4315 0 : intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), loc);
4316 : }
4317 0 : else if (op != EOpNull)
4318 : {
4319 : // Then this should be a constructor.
4320 0 : callNode = addConstructor(paramNode, op, fnCall, loc);
4321 : }
4322 : else
4323 : {
4324 : //
4325 : // Not a constructor. Find it in the symbol table.
4326 : //
4327 : const TFunction *fnCandidate;
4328 : bool builtIn;
4329 0 : fnCandidate = findFunction(loc, fnCall, mShaderVersion, &builtIn);
4330 0 : if (fnCandidate)
4331 : {
4332 : //
4333 : // A declared function.
4334 : //
4335 0 : if (builtIn && !fnCandidate->getExtension().empty())
4336 : {
4337 0 : checkCanUseExtension(loc, fnCandidate->getExtension());
4338 : }
4339 0 : op = fnCandidate->getBuiltInOp();
4340 0 : if (builtIn && op != EOpNull)
4341 : {
4342 : //
4343 : // A function call mapped to a built-in operation.
4344 : //
4345 0 : if (fnCandidate->getParamCount() == 1)
4346 : {
4347 : //
4348 : // Treat it like a built-in unary operator.
4349 : //
4350 0 : TIntermAggregate *paramAgg = paramNode->getAsAggregate();
4351 0 : paramNode = paramAgg->getSequence()->front();
4352 0 : callNode = createUnaryMath(op, paramNode->getAsTyped(), loc,
4353 0 : &fnCandidate->getReturnType());
4354 0 : if (callNode == nullptr)
4355 : {
4356 0 : std::stringstream extraInfoStream;
4357 : extraInfoStream
4358 : << "built in unary operator function. Type: "
4359 0 : << static_cast<TIntermTyped *>(paramNode)->getCompleteString();
4360 0 : std::string extraInfo = extraInfoStream.str();
4361 0 : error(paramNode->getLine(), " wrong operand type", "Internal Error",
4362 0 : extraInfo.c_str());
4363 0 : *fatalError = true;
4364 0 : return nullptr;
4365 : }
4366 : }
4367 : else
4368 : {
4369 : TIntermAggregate *aggregate =
4370 0 : intermediate.setAggregateOperator(paramNode, op, loc);
4371 0 : aggregate->setType(fnCandidate->getReturnType());
4372 0 : aggregate->setPrecisionFromChildren();
4373 0 : if (aggregate->areChildrenConstQualified())
4374 : {
4375 0 : aggregate->getTypePointer()->setQualifier(EvqConst);
4376 : }
4377 :
4378 : // Some built-in functions have out parameters too.
4379 0 : functionCallLValueErrorCheck(fnCandidate, aggregate);
4380 :
4381 : // See if we can constant fold a built-in. Note that this may be possible even
4382 : // if it is not const-qualified.
4383 : TIntermTyped *foldedNode =
4384 0 : intermediate.foldAggregateBuiltIn(aggregate, &mDiagnostics);
4385 0 : if (foldedNode)
4386 : {
4387 0 : callNode = foldedNode;
4388 : }
4389 : else
4390 : {
4391 0 : callNode = aggregate;
4392 : }
4393 0 : }
4394 : }
4395 : else
4396 : {
4397 : // This is a real function call
4398 : TIntermAggregate *aggregate =
4399 0 : intermediate.setAggregateOperator(paramNode, EOpFunctionCall, loc);
4400 0 : aggregate->setType(fnCandidate->getReturnType());
4401 :
4402 : // this is how we know whether the given function is a builtIn function or a user
4403 : // defined function
4404 : // if builtIn == false, it's a userDefined -> could be an overloaded
4405 : // builtIn function also
4406 : // if builtIn == true, it's definitely a builtIn function with EOpNull
4407 0 : if (!builtIn)
4408 0 : aggregate->setUserDefined();
4409 0 : aggregate->getFunctionSymbolInfo()->setFromFunction(*fnCandidate);
4410 :
4411 : // This needs to happen after the function info including name is set
4412 0 : if (builtIn)
4413 : {
4414 0 : aggregate->setBuiltInFunctionPrecision();
4415 :
4416 0 : checkTextureOffsetConst(aggregate);
4417 :
4418 0 : checkImageMemoryAccessForBuiltinFunctions(aggregate);
4419 : }
4420 : else
4421 : {
4422 0 : checkImageMemoryAccessForUserDefinedFunctions(fnCandidate, aggregate);
4423 : }
4424 :
4425 0 : callNode = aggregate;
4426 :
4427 0 : functionCallLValueErrorCheck(fnCandidate, aggregate);
4428 : }
4429 : }
4430 : else
4431 : {
4432 : // error message was put out by findFunction()
4433 : // Put on a dummy node for error recovery
4434 0 : TConstantUnion *unionArray = new TConstantUnion[1];
4435 0 : unionArray->setFConst(0.0f);
4436 0 : callNode = intermediate.addConstantUnion(unionArray,
4437 0 : TType(EbtFloat, EbpUndefined, EvqConst), loc);
4438 : }
4439 : }
4440 0 : return callNode;
4441 : }
4442 :
4443 0 : TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond,
4444 : TIntermTyped *trueExpression,
4445 : TIntermTyped *falseExpression,
4446 : const TSourceLoc &loc)
4447 : {
4448 0 : checkIsScalarBool(loc, cond);
4449 :
4450 0 : if (trueExpression->getType() != falseExpression->getType())
4451 : {
4452 0 : binaryOpError(loc, ":", trueExpression->getCompleteString(),
4453 0 : falseExpression->getCompleteString());
4454 0 : return falseExpression;
4455 : }
4456 0 : if (IsOpaqueType(trueExpression->getBasicType()))
4457 : {
4458 : // ESSL 1.00 section 4.1.7
4459 : // ESSL 3.00 section 4.1.7
4460 : // Opaque/sampler types are not allowed in most types of expressions, including ternary.
4461 : // Note that structs containing opaque types don't need to be checked as structs are
4462 : // forbidden below.
4463 0 : error(loc, "ternary operator is not allowed for opaque types", ":");
4464 0 : return falseExpression;
4465 : }
4466 :
4467 : // ESSL1 sections 5.2 and 5.7:
4468 : // ESSL3 section 5.7:
4469 : // Ternary operator is not among the operators allowed for structures/arrays.
4470 0 : if (trueExpression->isArray() || trueExpression->getBasicType() == EbtStruct)
4471 : {
4472 0 : error(loc, "ternary operator is not allowed for structures or arrays", ":");
4473 0 : return falseExpression;
4474 : }
4475 : // WebGL2 section 5.26, the following results in an error:
4476 : // "Ternary operator applied to void, arrays, or structs containing arrays"
4477 0 : if (mShaderSpec == SH_WEBGL2_SPEC && trueExpression->getBasicType() == EbtVoid)
4478 : {
4479 0 : error(loc, "ternary operator is not allowed for void", ":");
4480 0 : return falseExpression;
4481 : }
4482 :
4483 0 : return TIntermediate::AddTernarySelection(cond, trueExpression, falseExpression, loc);
4484 : }
4485 :
4486 : //
4487 : // Parse an array of strings using yyparse.
4488 : //
4489 : // Returns 0 for success.
4490 : //
4491 0 : int PaParseStrings(size_t count,
4492 : const char *const string[],
4493 : const int length[],
4494 : TParseContext *context)
4495 : {
4496 0 : if ((count == 0) || (string == NULL))
4497 0 : return 1;
4498 :
4499 0 : if (glslang_initialize(context))
4500 0 : return 1;
4501 :
4502 0 : int error = glslang_scan(count, string, length, context);
4503 0 : if (!error)
4504 0 : error = glslang_parse(context);
4505 :
4506 0 : glslang_finalize(context);
4507 :
4508 0 : return (error == 0) && (context->numErrors() == 0) ? 0 : 1;
4509 : }
4510 :
4511 : } // namespace sh
|