• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "ParseHelper.h"
16 
17 #include <limits>
18 #include <stdarg.h>
19 #include <stdio.h>
20 
21 #include "glslang.h"
22 #include "preprocessor/SourceLocation.h"
23 #include "ValidateSwitch.h"
24 
25 ///////////////////////////////////////////////////////////////////////
26 //
27 // Sub- vector and matrix fields
28 //
29 ////////////////////////////////////////////////////////////////////////
30 
31 namespace
32 {
IsVaryingOut(TQualifier qualifier)33 	bool IsVaryingOut(TQualifier qualifier)
34 	{
35 		switch(qualifier)
36 		{
37 		case EvqVaryingOut:
38 		case EvqSmoothOut:
39 		case EvqFlatOut:
40 		case EvqCentroidOut:
41 		case EvqVertexOut:
42 			return true;
43 
44 		default: break;
45 		}
46 
47 		return false;
48 	}
49 
IsVaryingIn(TQualifier qualifier)50 	bool IsVaryingIn(TQualifier qualifier)
51 	{
52 		switch(qualifier)
53 		{
54 		case EvqVaryingIn:
55 		case EvqSmoothIn:
56 		case EvqFlatIn:
57 		case EvqCentroidIn:
58 		case EvqFragmentIn:
59 			return true;
60 
61 		default: break;
62 		}
63 
64 		return false;
65 	}
66 
IsVarying(TQualifier qualifier)67 	bool IsVarying(TQualifier qualifier)
68 	{
69 		return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
70 	}
71 
IsAssignment(TOperator op)72 	bool IsAssignment(TOperator op)
73 	{
74 		switch(op)
75 		{
76 		case EOpPostIncrement:
77 		case EOpPostDecrement:
78 		case EOpPreIncrement:
79 		case EOpPreDecrement:
80 		case EOpAssign:
81 		case EOpAddAssign:
82 		case EOpSubAssign:
83 		case EOpMulAssign:
84 		case EOpVectorTimesMatrixAssign:
85 		case EOpVectorTimesScalarAssign:
86 		case EOpMatrixTimesScalarAssign:
87 		case EOpMatrixTimesMatrixAssign:
88 		case EOpDivAssign:
89 		case EOpIModAssign:
90 		case EOpBitShiftLeftAssign:
91 		case EOpBitShiftRightAssign:
92 		case EOpBitwiseAndAssign:
93 		case EOpBitwiseXorAssign:
94 		case EOpBitwiseOrAssign:
95 			return true;
96 		default:
97 			return false;
98 		}
99 	}
100 }
101 
102 //
103 // Look at a '.' field selector string and change it into offsets
104 // for a vector.
105 //
parseVectorFields(const TString & compString,int vecSize,TVectorFields & fields,const TSourceLoc & line)106 bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, const TSourceLoc &line)
107 {
108 	fields.num = (int) compString.size();
109 	if (fields.num > 4) {
110 		error(line, "illegal vector field selection", compString.c_str());
111 		return false;
112 	}
113 
114 	enum {
115 		exyzw,
116 		ergba,
117 		estpq
118 	} fieldSet[4];
119 
120 	for (int i = 0; i < fields.num; ++i) {
121 		switch (compString[i])  {
122 		case 'x':
123 			fields.offsets[i] = 0;
124 			fieldSet[i] = exyzw;
125 			break;
126 		case 'r':
127 			fields.offsets[i] = 0;
128 			fieldSet[i] = ergba;
129 			break;
130 		case 's':
131 			fields.offsets[i] = 0;
132 			fieldSet[i] = estpq;
133 			break;
134 		case 'y':
135 			fields.offsets[i] = 1;
136 			fieldSet[i] = exyzw;
137 			break;
138 		case 'g':
139 			fields.offsets[i] = 1;
140 			fieldSet[i] = ergba;
141 			break;
142 		case 't':
143 			fields.offsets[i] = 1;
144 			fieldSet[i] = estpq;
145 			break;
146 		case 'z':
147 			fields.offsets[i] = 2;
148 			fieldSet[i] = exyzw;
149 			break;
150 		case 'b':
151 			fields.offsets[i] = 2;
152 			fieldSet[i] = ergba;
153 			break;
154 		case 'p':
155 			fields.offsets[i] = 2;
156 			fieldSet[i] = estpq;
157 			break;
158 		case 'w':
159 			fields.offsets[i] = 3;
160 			fieldSet[i] = exyzw;
161 			break;
162 		case 'a':
163 			fields.offsets[i] = 3;
164 			fieldSet[i] = ergba;
165 			break;
166 		case 'q':
167 			fields.offsets[i] = 3;
168 			fieldSet[i] = estpq;
169 			break;
170 		default:
171 			error(line, "illegal vector field selection", compString.c_str());
172 			return false;
173 		}
174 	}
175 
176 	for (int i = 0; i < fields.num; ++i) {
177 		if (fields.offsets[i] >= vecSize) {
178 			error(line, "vector field selection out of range",  compString.c_str());
179 			return false;
180 		}
181 
182 		if (i > 0) {
183 			if (fieldSet[i] != fieldSet[i-1]) {
184 				error(line, "illegal - vector component fields not from the same set", compString.c_str());
185 				return false;
186 			}
187 		}
188 	}
189 
190 	return true;
191 }
192 
193 ///////////////////////////////////////////////////////////////////////
194 //
195 // Errors
196 //
197 ////////////////////////////////////////////////////////////////////////
198 
199 //
200 // Track whether errors have occurred.
201 //
recover()202 void TParseContext::recover()
203 {
204 }
205 
206 //
207 // Used by flex/bison to output all syntax and parsing errors.
208 //
error(const TSourceLoc & loc,const char * reason,const char * token,const char * extraInfo)209 void TParseContext::error(const TSourceLoc& loc,
210 						  const char* reason, const char* token,
211 						  const char* extraInfo)
212 {
213 	pp::SourceLocation srcLoc(loc.first_file, loc.first_line);
214 	mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR,
215 						   srcLoc, reason, token, extraInfo);
216 
217 }
218 
warning(const TSourceLoc & loc,const char * reason,const char * token,const char * extraInfo)219 void TParseContext::warning(const TSourceLoc& loc,
220 							const char* reason, const char* token,
221 							const char* extraInfo) {
222 	pp::SourceLocation srcLoc(loc.first_file, loc.first_line);
223 	mDiagnostics.writeInfo(pp::Diagnostics::PP_WARNING,
224 						   srcLoc, reason, token, extraInfo);
225 }
226 
info(const TSourceLoc & loc,const char * reason,const char * token,const char * extraInfo)227 void TParseContext::info(const TSourceLoc& loc,
228 							const char* reason, const char* token,
229 							const char* extraInfo) {
230 	pp::SourceLocation srcLoc(loc.first_file, loc.first_line);
231 	mDiagnostics.writeInfo(pp::Diagnostics::PP_INFO,
232 						   srcLoc, reason, token, extraInfo);
233 }
234 
trace(const char * str)235 void TParseContext::trace(const char* str)
236 {
237 	mDiagnostics.writeDebug(str);
238 }
239 
240 //
241 // Same error message for all places assignments don't work.
242 //
assignError(const TSourceLoc & line,const char * op,TString left,TString right)243 void TParseContext::assignError(const TSourceLoc &line, const char* op, TString left, TString right)
244 {
245 	std::stringstream extraInfoStream;
246 	extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'";
247 	std::string extraInfo = extraInfoStream.str();
248 	error(line, "", op, extraInfo.c_str());
249 }
250 
251 //
252 // Same error message for all places unary operations don't work.
253 //
unaryOpError(const TSourceLoc & line,const char * op,TString operand)254 void TParseContext::unaryOpError(const TSourceLoc &line, const char* op, TString operand)
255 {
256 	std::stringstream extraInfoStream;
257 	extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " << operand
258 					<< " (or there is no acceptable conversion)";
259 	std::string extraInfo = extraInfoStream.str();
260 	error(line, " wrong operand type", op, extraInfo.c_str());
261 }
262 
263 //
264 // Same error message for all binary operations don't work.
265 //
binaryOpError(const TSourceLoc & line,const char * op,TString left,TString right)266 void TParseContext::binaryOpError(const TSourceLoc &line, const char* op, TString left, TString right)
267 {
268 	std::stringstream extraInfoStream;
269 	extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" << left
270 					<< "' and a right operand of type '" << right << "' (or there is no acceptable conversion)";
271 	std::string extraInfo = extraInfoStream.str();
272 	error(line, " wrong operand types ", op, extraInfo.c_str());
273 }
274 
precisionErrorCheck(const TSourceLoc & line,TPrecision precision,TBasicType type)275 bool TParseContext::precisionErrorCheck(const TSourceLoc &line, TPrecision precision, TBasicType type){
276 	if (!mChecksPrecisionErrors)
277 		return false;
278 	switch( type ){
279 	case EbtFloat:
280 		if( precision == EbpUndefined ){
281 			error( line, "No precision specified for (float)", "" );
282 			return true;
283 		}
284 		break;
285 	case EbtInt:
286 		if( precision == EbpUndefined ){
287 			error( line, "No precision specified (int)", "" );
288 			return true;
289 		}
290 		break;
291 	default:
292 		return false;
293 	}
294 	return false;
295 }
296 
297 //
298 // Both test and if necessary, spit out an error, to see if the node is really
299 // an l-value that can be operated on this way.
300 //
301 // Returns true if the was an error.
302 //
lValueErrorCheck(const TSourceLoc & line,const char * op,TIntermTyped * node)303 bool TParseContext::lValueErrorCheck(const TSourceLoc &line, const char* op, TIntermTyped* node)
304 {
305 	TIntermSymbol* symNode = node->getAsSymbolNode();
306 	TIntermBinary* binaryNode = node->getAsBinaryNode();
307 
308 	if (binaryNode) {
309 		bool errorReturn;
310 
311 		switch(binaryNode->getOp()) {
312 		case EOpIndexDirect:
313 		case EOpIndexIndirect:
314 		case EOpIndexDirectStruct:
315 			return lValueErrorCheck(line, op, binaryNode->getLeft());
316 		case EOpVectorSwizzle:
317 			errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft());
318 			if (!errorReturn) {
319 				int offset[4] = {0,0,0,0};
320 
321 				TIntermTyped* rightNode = binaryNode->getRight();
322 				TIntermAggregate *aggrNode = rightNode->getAsAggregate();
323 
324 				for (TIntermSequence::iterator p = aggrNode->getSequence().begin();
325 											   p != aggrNode->getSequence().end(); p++) {
326 					int value = (*p)->getAsTyped()->getAsConstantUnion()->getIConst(0);
327 					offset[value]++;
328 					if (offset[value] > 1) {
329 						error(line, " l-value of swizzle cannot have duplicate components", op);
330 
331 						return true;
332 					}
333 				}
334 			}
335 
336 			return errorReturn;
337 		case EOpIndexDirectInterfaceBlock:
338 		default:
339 			break;
340 		}
341 		error(line, " l-value required", op);
342 
343 		return true;
344 	}
345 
346 
347 	const char* symbol = 0;
348 	if (symNode != 0)
349 		symbol = symNode->getSymbol().c_str();
350 
351 	const char* message = 0;
352 	switch (node->getQualifier()) {
353 	case EvqConstExpr:      message = "can't modify a const";        break;
354 	case EvqConstReadOnly:  message = "can't modify a const";        break;
355 	case EvqAttribute:      message = "can't modify an attribute";   break;
356 	case EvqFragmentIn:     message = "can't modify an input";       break;
357 	case EvqVertexIn:       message = "can't modify an input";       break;
358 	case EvqUniform:        message = "can't modify a uniform";      break;
359 	case EvqSmoothIn:
360 	case EvqFlatIn:
361 	case EvqCentroidIn:
362 	case EvqVaryingIn:      message = "can't modify a varying";      break;
363 	case EvqInput:          message = "can't modify an input";       break;
364 	case EvqFragCoord:      message = "can't modify gl_FragCoord";   break;
365 	case EvqFrontFacing:    message = "can't modify gl_FrontFacing"; break;
366 	case EvqPointCoord:     message = "can't modify gl_PointCoord";  break;
367 	case EvqInstanceID:     message = "can't modify gl_InstanceID";  break;
368 	case EvqVertexID:       message = "can't modify gl_VertexID";    break;
369 	default:
370 
371 		//
372 		// Type that can't be written to?
373 		//
374 		if(IsSampler(node->getBasicType()))
375 		{
376 			message = "can't modify a sampler";
377 		}
378 		else if(node->getBasicType() == EbtVoid)
379 		{
380 			message = "can't modify void";
381 		}
382 	}
383 
384 	if (message == 0 && binaryNode == 0 && symNode == 0) {
385 		error(line, " l-value required", op);
386 
387 		return true;
388 	}
389 
390 
391 	//
392 	// Everything else is okay, no error.
393 	//
394 	if (message == 0)
395 		return false;
396 
397 	//
398 	// If we get here, we have an error and a message.
399 	//
400 	if (symNode) {
401 		std::stringstream extraInfoStream;
402 		extraInfoStream << "\"" << symbol << "\" (" << message << ")";
403 		std::string extraInfo = extraInfoStream.str();
404 		error(line, " l-value required", op, extraInfo.c_str());
405 	}
406 	else {
407 		std::stringstream extraInfoStream;
408 		extraInfoStream << "(" << message << ")";
409 		std::string extraInfo = extraInfoStream.str();
410 		error(line, " l-value required", op, extraInfo.c_str());
411 	}
412 
413 	return true;
414 }
415 
416 //
417 // Both test, and if necessary spit out an error, to see if the node is really
418 // a constant.
419 //
420 // Returns true if the was an error.
421 //
constErrorCheck(TIntermTyped * node)422 bool TParseContext::constErrorCheck(TIntermTyped* node)
423 {
424 	if (node->getQualifier() == EvqConstExpr)
425 		return false;
426 
427 	error(node->getLine(), "constant expression required", "");
428 
429 	return true;
430 }
431 
432 //
433 // Both test, and if necessary spit out an error, to see if the node is really
434 // an integer.
435 //
436 // Returns true if the was an error.
437 //
integerErrorCheck(TIntermTyped * node,const char * token)438 bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token)
439 {
440 	if (node->isScalarInt())
441 		return false;
442 
443 	error(node->getLine(), "integer expression required", token);
444 
445 	return true;
446 }
447 
448 //
449 // Both test, and if necessary spit out an error, to see if we are currently
450 // globally scoped.
451 //
452 // Returns true if the was an error.
453 //
globalErrorCheck(const TSourceLoc & line,bool global,const char * token)454 bool TParseContext::globalErrorCheck(const TSourceLoc &line, bool global, const char* token)
455 {
456 	if (global)
457 		return false;
458 
459 	error(line, "only allowed at global scope", token);
460 
461 	return true;
462 }
463 
464 //
465 // For now, keep it simple:  if it starts "gl_", it's reserved, independent
466 // of scope.  Except, if the symbol table is at the built-in push-level,
467 // which is when we are parsing built-ins.
468 // Also checks for "webgl_" and "_webgl_" reserved identifiers if parsing a
469 // webgl shader.
470 //
471 // Returns true if there was an error.
472 //
reservedErrorCheck(const TSourceLoc & line,const TString & identifier)473 bool TParseContext::reservedErrorCheck(const TSourceLoc &line, const TString& identifier)
474 {
475 	static const char* reservedErrMsg = "reserved built-in name";
476 	if (!symbolTable.atBuiltInLevel()) {
477 		if (identifier.compare(0, 3, "gl_") == 0) {
478 			error(line, reservedErrMsg, "gl_");
479 			return true;
480 		}
481 		if (identifier.find("__") != TString::npos) {
482 			error(line, "identifiers containing two consecutive underscores (__) are reserved as possible future keywords", identifier.c_str());
483 			return true;
484 		}
485 	}
486 
487 	return false;
488 }
489 
490 //
491 // Make sure there is enough data provided to the constructor to build
492 // something of the type of the constructor.  Also returns the type of
493 // the constructor.
494 //
495 // Returns true if there was an error in construction.
496 //
constructorErrorCheck(const TSourceLoc & line,TIntermNode * node,TFunction & function,TOperator op,TType * type)497 bool TParseContext::constructorErrorCheck(const TSourceLoc &line, TIntermNode* node, TFunction& function, TOperator op, TType* type)
498 {
499 	*type = function.getReturnType();
500 
501 	bool constructingMatrix = false;
502 	switch(op) {
503 	case EOpConstructMat2:
504 	case EOpConstructMat2x3:
505 	case EOpConstructMat2x4:
506 	case EOpConstructMat3x2:
507 	case EOpConstructMat3:
508 	case EOpConstructMat3x4:
509 	case EOpConstructMat4x2:
510 	case EOpConstructMat4x3:
511 	case EOpConstructMat4:
512 		constructingMatrix = true;
513 		break;
514 	default:
515 		break;
516 	}
517 
518 	//
519 	// Note: It's okay to have too many components available, but not okay to have unused
520 	// arguments.  'full' will go to true when enough args have been seen.  If we loop
521 	// again, there is an extra argument, so 'overfull' will become true.
522 	//
523 
524 	size_t size = 0;
525 	bool full = false;
526 	bool overFull = false;
527 	bool matrixInMatrix = false;
528 	bool arrayArg = false;
529 	for (size_t i = 0; i < function.getParamCount(); ++i) {
530 		const TParameter& param = function.getParam(i);
531 		size += param.type->getObjectSize();
532 
533 		if (constructingMatrix && param.type->isMatrix())
534 			matrixInMatrix = true;
535 		if (full)
536 			overFull = true;
537 		if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize())
538 			full = true;
539 		if (param.type->isArray())
540 			arrayArg = true;
541 	}
542 
543 	if(type->isArray()) {
544 		if(type->getArraySize() == 0) {
545 			type->setArraySize(function.getParamCount());
546 		} else if(type->getArraySize() != (int)function.getParamCount()) {
547 			error(line, "array constructor needs one argument per array element", "constructor");
548 			return true;
549 		}
550 	}
551 
552 	if (arrayArg && op != EOpConstructStruct) {
553 		error(line, "constructing from a non-dereferenced array", "constructor");
554 		return true;
555 	}
556 
557 	if (matrixInMatrix && !type->isArray()) {
558 		if (function.getParamCount() != 1) {
559 		  error(line, "constructing matrix from matrix can only take one argument", "constructor");
560 		  return true;
561 		}
562 	}
563 
564 	if (overFull) {
565 		error(line, "too many arguments", "constructor");
566 		return true;
567 	}
568 
569 	if (op == EOpConstructStruct && !type->isArray() && type->getStruct()->fields().size() != function.getParamCount()) {
570 		error(line, "Number of constructor parameters does not match the number of structure fields", "constructor");
571 		return true;
572 	}
573 
574 	if (!type->isMatrix() || !matrixInMatrix) {
575 		if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) ||
576 			(op == EOpConstructStruct && size < type->getObjectSize())) {
577 			error(line, "not enough data provided for construction", "constructor");
578 			return true;
579 		}
580 	}
581 
582 	TIntermTyped *typed = node ? node->getAsTyped() : 0;
583 	if (typed == 0) {
584 		error(line, "constructor argument does not have a type", "constructor");
585 		return true;
586 	}
587 	if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) {
588 		error(line, "cannot convert a sampler", "constructor");
589 		return true;
590 	}
591 	if (typed->getBasicType() == EbtVoid) {
592 		error(line, "cannot convert a void", "constructor");
593 		return true;
594 	}
595 
596 	return false;
597 }
598 
599 // This function checks to see if a void variable has been declared and raise an error message for such a case
600 //
601 // returns true in case of an error
602 //
voidErrorCheck(const TSourceLoc & line,const TString & identifier,const TBasicType & type)603 bool TParseContext::voidErrorCheck(const TSourceLoc &line, const TString& identifier, const TBasicType& type)
604 {
605 	if(type == EbtVoid) {
606 		error(line, "illegal use of type 'void'", identifier.c_str());
607 		return true;
608 	}
609 
610 	return false;
611 }
612 
613 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
614 //
615 // returns true in case of an error
616 //
boolErrorCheck(const TSourceLoc & line,const TIntermTyped * type)617 bool TParseContext::boolErrorCheck(const TSourceLoc &line, const TIntermTyped* type)
618 {
619 	if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) {
620 		error(line, "boolean expression expected", "");
621 		return true;
622 	}
623 
624 	return false;
625 }
626 
627 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
628 //
629 // returns true in case of an error
630 //
boolErrorCheck(const TSourceLoc & line,const TPublicType & pType)631 bool TParseContext::boolErrorCheck(const TSourceLoc &line, const TPublicType& pType)
632 {
633 	if (pType.type != EbtBool || pType.array || (pType.primarySize > 1) || (pType.secondarySize > 1)) {
634 		error(line, "boolean expression expected", "");
635 		return true;
636 	}
637 
638 	return false;
639 }
640 
samplerErrorCheck(const TSourceLoc & line,const TPublicType & pType,const char * reason)641 bool TParseContext::samplerErrorCheck(const TSourceLoc &line, const TPublicType& pType, const char* reason)
642 {
643 	if (pType.type == EbtStruct) {
644 		if (containsSampler(*pType.userDef)) {
645 			error(line, reason, getBasicString(pType.type), "(structure contains a sampler)");
646 
647 			return true;
648 		}
649 
650 		return false;
651 	} else if (IsSampler(pType.type)) {
652 		error(line, reason, getBasicString(pType.type));
653 
654 		return true;
655 	}
656 
657 	return false;
658 }
659 
structQualifierErrorCheck(const TSourceLoc & line,const TPublicType & pType)660 bool TParseContext::structQualifierErrorCheck(const TSourceLoc &line, const TPublicType& pType)
661 {
662 	switch(pType.qualifier)
663 	{
664 	case EvqVaryingOut:
665 	case EvqSmooth:
666 	case EvqFlat:
667 	case EvqCentroidOut:
668 	case EvqVaryingIn:
669 	case EvqSmoothIn:
670 	case EvqFlatIn:
671 	case EvqCentroidIn:
672 	case EvqAttribute:
673 	case EvqVertexIn:
674 	case EvqFragmentOut:
675 		if(pType.type == EbtStruct)
676 		{
677 			error(line, "cannot be used with a structure", getQualifierString(pType.qualifier));
678 
679 			return true;
680 		}
681 		break;
682 	default:
683 		break;
684 	}
685 
686 	if (pType.qualifier != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform"))
687 		return true;
688 
689 	// check for layout qualifier issues
690 	if (pType.qualifier != EvqVertexIn && pType.qualifier != EvqFragmentOut &&
691 		layoutLocationErrorCheck(line, pType.layoutQualifier))
692 	{
693 		return true;
694 	}
695 
696 	return false;
697 }
698 
699 // These checks are common for all declarations starting a declarator list, and declarators that follow an empty
700 // declaration.
701 //
singleDeclarationErrorCheck(const TPublicType & publicType,const TSourceLoc & identifierLocation)702 bool TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &identifierLocation)
703 {
704 	switch(publicType.qualifier)
705 	{
706 	case EvqVaryingIn:
707 	case EvqVaryingOut:
708 	case EvqAttribute:
709 	case EvqVertexIn:
710 	case EvqFragmentOut:
711 		if(publicType.type == EbtStruct)
712 		{
713 			error(identifierLocation, "cannot be used with a structure",
714 				getQualifierString(publicType.qualifier));
715 			return true;
716 		}
717 
718 	default: break;
719 	}
720 
721 	if(publicType.qualifier != EvqUniform && samplerErrorCheck(identifierLocation, publicType,
722 		"samplers must be uniform"))
723 	{
724 		return true;
725 	}
726 
727 	// check for layout qualifier issues
728 	const TLayoutQualifier layoutQualifier = publicType.layoutQualifier;
729 
730 	if(layoutQualifier.matrixPacking != EmpUnspecified)
731 	{
732 		error(identifierLocation, "layout qualifier", getMatrixPackingString(layoutQualifier.matrixPacking),
733 			"only valid for interface blocks");
734 		return true;
735 	}
736 
737 	if(layoutQualifier.blockStorage != EbsUnspecified)
738 	{
739 		error(identifierLocation, "layout qualifier", getBlockStorageString(layoutQualifier.blockStorage),
740 			"only valid for interface blocks");
741 		return true;
742 	}
743 
744 	if(publicType.qualifier != EvqVertexIn && publicType.qualifier != EvqFragmentOut &&
745 		layoutLocationErrorCheck(identifierLocation, publicType.layoutQualifier))
746 	{
747 		return true;
748 	}
749 
750 	return false;
751 }
752 
layoutLocationErrorCheck(const TSourceLoc & location,const TLayoutQualifier & layoutQualifier)753 bool TParseContext::layoutLocationErrorCheck(const TSourceLoc &location, const TLayoutQualifier &layoutQualifier)
754 {
755 	if(layoutQualifier.location != -1)
756 	{
757 		error(location, "invalid layout qualifier:", "location", "only valid on program inputs and outputs");
758 		return true;
759 	}
760 
761 	return false;
762 }
763 
locationDeclaratorListCheck(const TSourceLoc & line,const TPublicType & pType)764 bool TParseContext::locationDeclaratorListCheck(const TSourceLoc& line, const TPublicType &pType)
765 {
766 	if(pType.layoutQualifier.location != -1)
767 	{
768 		error(line, "location must only be specified for a single input or output variable", "location");
769 		return true;
770 	}
771 
772 	return false;
773 }
774 
parameterSamplerErrorCheck(const TSourceLoc & line,TQualifier qualifier,const TType & type)775 bool TParseContext::parameterSamplerErrorCheck(const TSourceLoc &line, TQualifier qualifier, const TType& type)
776 {
777 	if ((qualifier == EvqOut || qualifier == EvqInOut) &&
778 			 type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
779 		error(line, "samplers cannot be output parameters", type.getBasicString());
780 		return true;
781 	}
782 
783 	return false;
784 }
785 
containsSampler(TType & type)786 bool TParseContext::containsSampler(TType& type)
787 {
788 	if (IsSampler(type.getBasicType()))
789 		return true;
790 
791 	if (type.getBasicType() == EbtStruct || type.isInterfaceBlock()) {
792 		for(const auto &field : type.getStruct()->fields()) {
793 			if (containsSampler(*(field->type())))
794 				return true;
795 		}
796 	}
797 
798 	return false;
799 }
800 
801 //
802 // Do size checking for an array type's size.
803 //
804 // Returns true if there was an error.
805 //
arraySizeErrorCheck(const TSourceLoc & line,TIntermTyped * expr,int & size)806 bool TParseContext::arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped* expr, int& size)
807 {
808 	TIntermConstantUnion* constant = expr->getAsConstantUnion();
809 
810 	if (expr->getQualifier() != EvqConstExpr || constant == 0 || !constant->isScalarInt())
811 	{
812 		error(line, "array size must be a constant integer expression", "");
813 		size = 1;
814 		return true;
815 	}
816 
817 	if (constant->getBasicType() == EbtUInt)
818 	{
819 		unsigned int uintSize = constant->getUConst(0);
820 		if (uintSize > static_cast<unsigned int>(std::numeric_limits<int>::max()))
821 		{
822 			error(line, "array size too large", "");
823 			size = 1;
824 			return true;
825 		}
826 
827 		size = static_cast<int>(uintSize);
828 	}
829 	else
830 	{
831 		size = constant->getIConst(0);
832 
833 		if (size < 0)
834 		{
835 			error(line, "array size must be non-negative", "");
836 			size = 1;
837 			return true;
838 		}
839 	}
840 
841 	if(size == 0)
842 	{
843 		error(line, "array size must be greater than zero", "");
844 		return true;
845 	}
846 
847 	return false;
848 }
849 
850 //
851 // See if this qualifier can be an array.
852 //
853 // Returns true if there is an error.
854 //
arrayQualifierErrorCheck(const TSourceLoc & line,TPublicType type)855 bool TParseContext::arrayQualifierErrorCheck(const TSourceLoc &line, TPublicType type)
856 {
857 	if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqVertexIn) || (type.qualifier == EvqConstExpr && mShaderVersion < 300)) {
858 		error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str());
859 		return true;
860 	}
861 
862 	return false;
863 }
864 
865 //
866 // See if this type can be an array.
867 //
868 // Returns true if there is an error.
869 //
arrayTypeErrorCheck(const TSourceLoc & line,TPublicType type)870 bool TParseContext::arrayTypeErrorCheck(const TSourceLoc &line, TPublicType type)
871 {
872 	//
873 	// Can the type be an array?
874 	//
875 	if (type.array) {
876 		error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str());
877 		return true;
878 	}
879 
880 	// In ESSL1.00 shaders, structs cannot be varying (section 4.3.5). This is checked elsewhere.
881 	// In ESSL3.00 shaders, struct inputs/outputs are allowed but not arrays of structs (section 4.3.4).
882 	if(mShaderVersion >= 300 && type.type == EbtStruct && IsVarying(type.qualifier))
883 	{
884 		error(line, "cannot declare arrays of structs of this qualifier",
885 		      TType(type).getCompleteString().c_str());
886 		return true;
887 	}
888 
889 	return false;
890 }
891 
arraySetMaxSize(TIntermSymbol * node,TType * type,int size,bool updateFlag,const TSourceLoc & line)892 bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, const TSourceLoc &line)
893 {
894 	bool builtIn = false;
895 	TSymbol* symbol = symbolTable.find(node->getSymbol(), mShaderVersion, &builtIn);
896 	if (symbol == 0) {
897 		error(line, " undeclared identifier", node->getSymbol().c_str());
898 		return true;
899 	}
900 	TVariable* variable = static_cast<TVariable*>(symbol);
901 
902 	type->setArrayInformationType(variable->getArrayInformationType());
903 	variable->updateArrayInformationType(type);
904 
905 	// special casing to test index value of gl_FragData. If the accessed index is >= gl_MaxDrawBuffers
906 	// its an error
907 	if (node->getSymbol() == "gl_FragData") {
908 		TSymbol* fragData = symbolTable.find("gl_MaxDrawBuffers", mShaderVersion, &builtIn);
909 		ASSERT(fragData);
910 
911 		int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst();
912 		if (fragDataValue <= size) {
913 			error(line, "", "[", "gl_FragData can only have a max array size of up to gl_MaxDrawBuffers");
914 			return true;
915 		}
916 	}
917 
918 	// we dont want to update the maxArraySize when this flag is not set, we just want to include this
919 	// node type in the chain of node types so that its updated when a higher maxArraySize comes in.
920 	if (!updateFlag)
921 		return false;
922 
923 	size++;
924 	variable->getType().setMaxArraySize(size);
925 	type->setMaxArraySize(size);
926 	TType* tt = type;
927 
928 	while(tt->getArrayInformationType() != 0) {
929 		tt = tt->getArrayInformationType();
930 		tt->setMaxArraySize(size);
931 	}
932 
933 	return false;
934 }
935 
936 //
937 // Enforce non-initializer type/qualifier rules.
938 //
939 // Returns true if there was an error.
940 //
nonInitConstErrorCheck(const TSourceLoc & line,TString & identifier,TPublicType & type,bool array)941 bool TParseContext::nonInitConstErrorCheck(const TSourceLoc &line, TString& identifier, TPublicType& type, bool array)
942 {
943 	if (type.qualifier == EvqConstExpr)
944 	{
945 		// Make the qualifier make sense.
946 		type.qualifier = EvqTemporary;
947 
948 		if (array)
949 		{
950 			error(line, "arrays may not be declared constant since they cannot be initialized", identifier.c_str());
951 		}
952 		else if (type.isStructureContainingArrays())
953 		{
954 			error(line, "structures containing arrays may not be declared constant since they cannot be initialized", identifier.c_str());
955 		}
956 		else
957 		{
958 			error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
959 		}
960 
961 		return true;
962 	}
963 
964 	return false;
965 }
966 
967 //
968 // Do semantic checking for a variable declaration that has no initializer,
969 // and update the symbol table.
970 //
971 // Returns true if there was an error.
972 //
nonInitErrorCheck(const TSourceLoc & line,const TString & identifier,TPublicType & type)973 bool TParseContext::nonInitErrorCheck(const TSourceLoc &line, const TString& identifier, TPublicType& type)
974 {
975 	if(type.qualifier == EvqConstExpr)
976 	{
977 		// Make the qualifier make sense.
978 		type.qualifier = EvqTemporary;
979 
980 		// Generate informative error messages for ESSL1.
981 		// In ESSL3 arrays and structures containing arrays can be constant.
982 		if(mShaderVersion < 300 && type.isStructureContainingArrays())
983 		{
984 			error(line,
985 				"structures containing arrays may not be declared constant since they cannot be initialized",
986 				identifier.c_str());
987 		}
988 		else
989 		{
990 			error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
991 		}
992 
993 		return true;
994 	}
995 	if(type.isUnsizedArray())
996 	{
997 		error(line, "implicitly sized arrays need to be initialized", identifier.c_str());
998 		return true;
999 	}
1000 	return false;
1001 }
1002 
1003 // Do some simple checks that are shared between all variable declarations,
1004 // and update the symbol table.
1005 //
1006 // Returns true if declaring the variable succeeded.
1007 //
declareVariable(const TSourceLoc & line,const TString & identifier,const TType & type,TVariable ** variable)1008 bool TParseContext::declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type,
1009 	TVariable **variable)
1010 {
1011 	ASSERT((*variable) == nullptr);
1012 
1013 	// gl_LastFragData may be redeclared with a new precision qualifier
1014 	if(type.isArray() && identifier.compare(0, 15, "gl_LastFragData") == 0)
1015 	{
1016 		const TVariable *maxDrawBuffers =
1017 			static_cast<const TVariable *>(symbolTable.findBuiltIn("gl_MaxDrawBuffers", mShaderVersion));
1018 		if(type.getArraySize() != maxDrawBuffers->getConstPointer()->getIConst())
1019 		{
1020 			error(line, "redeclaration of gl_LastFragData with size != gl_MaxDrawBuffers", identifier.c_str());
1021 			return false;
1022 		}
1023 	}
1024 
1025 	if(reservedErrorCheck(line, identifier))
1026 		return false;
1027 
1028 	(*variable) = new TVariable(&identifier, type);
1029 	if(!symbolTable.declare(*variable))
1030 	{
1031 		error(line, "redefinition", identifier.c_str());
1032 		delete (*variable);
1033 		(*variable) = nullptr;
1034 		return false;
1035 	}
1036 
1037 	if(voidErrorCheck(line, identifier, type.getBasicType()))
1038 		return false;
1039 
1040 	return true;
1041 }
1042 
paramErrorCheck(const TSourceLoc & line,TQualifier qualifier,TQualifier paramQualifier,TType * type)1043 bool TParseContext::paramErrorCheck(const TSourceLoc &line, TQualifier qualifier, TQualifier paramQualifier, TType* type)
1044 {
1045 	if (qualifier != EvqConstReadOnly && qualifier != EvqTemporary) {
1046 		error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier));
1047 		return true;
1048 	}
1049 	if (qualifier == EvqConstReadOnly && paramQualifier != EvqIn) {
1050 		error(line, "qualifier not allowed with ", getQualifierString(qualifier), getQualifierString(paramQualifier));
1051 		return true;
1052 	}
1053 
1054 	if (qualifier == EvqConstReadOnly)
1055 		type->setQualifier(EvqConstReadOnly);
1056 	else
1057 		type->setQualifier(paramQualifier);
1058 
1059 	return false;
1060 }
1061 
extensionErrorCheck(const TSourceLoc & line,const TString & extension)1062 bool TParseContext::extensionErrorCheck(const TSourceLoc &line, const TString& extension)
1063 {
1064 	const TExtensionBehavior& extBehavior = extensionBehavior();
1065 	TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str());
1066 	if (iter == extBehavior.end()) {
1067 		error(line, "extension", extension.c_str(), "is not supported");
1068 		return true;
1069 	}
1070 	// In GLSL ES, an extension's default behavior is "disable".
1071 	if (iter->second == EBhDisable || iter->second == EBhUndefined) {
1072 		error(line, "extension", extension.c_str(), "is disabled");
1073 		return true;
1074 	}
1075 	if (iter->second == EBhWarn) {
1076 		warning(line, "extension", extension.c_str(), "is being used");
1077 		return false;
1078 	}
1079 
1080 	return false;
1081 }
1082 
functionCallLValueErrorCheck(const TFunction * fnCandidate,TIntermAggregate * aggregate)1083 bool TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *aggregate)
1084 {
1085 	for(size_t i = 0; i < fnCandidate->getParamCount(); ++i)
1086 	{
1087 		TQualifier qual = fnCandidate->getParam(i).type->getQualifier();
1088 		if(qual == EvqOut || qual == EvqInOut)
1089 		{
1090 			TIntermTyped *node = (aggregate->getSequence())[i]->getAsTyped();
1091 			if(lValueErrorCheck(node->getLine(), "assign", node))
1092 			{
1093 				error(node->getLine(),
1094 					"Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
1095 				recover();
1096 				return true;
1097 			}
1098 		}
1099 	}
1100 	return false;
1101 }
1102 
es3InvariantErrorCheck(const TQualifier qualifier,const TSourceLoc & invariantLocation)1103 void TParseContext::es3InvariantErrorCheck(const TQualifier qualifier, const TSourceLoc &invariantLocation)
1104 {
1105 	switch(qualifier)
1106 	{
1107 	case EvqVaryingOut:
1108 	case EvqSmoothOut:
1109 	case EvqFlatOut:
1110 	case EvqCentroidOut:
1111 	case EvqVertexOut:
1112 	case EvqFragmentOut:
1113 		break;
1114 	default:
1115 		error(invariantLocation, "Only out variables can be invariant.", "invariant");
1116 		recover();
1117 		break;
1118 	}
1119 }
1120 
supportsExtension(const char * extension)1121 bool TParseContext::supportsExtension(const char* extension)
1122 {
1123 	const TExtensionBehavior& extbehavior = extensionBehavior();
1124 	TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
1125 	return (iter != extbehavior.end());
1126 }
1127 
handleExtensionDirective(const TSourceLoc & line,const char * extName,const char * behavior)1128 void TParseContext::handleExtensionDirective(const TSourceLoc &line, const char* extName, const char* behavior)
1129 {
1130 	pp::SourceLocation loc(line.first_file, line.first_line);
1131 	mDirectiveHandler.handleExtension(loc, extName, behavior);
1132 }
1133 
handlePragmaDirective(const TSourceLoc & line,const char * name,const char * value,bool stdgl)1134 void TParseContext::handlePragmaDirective(const TSourceLoc &line, const char* name, const char* value, bool stdgl)
1135 {
1136 	pp::SourceLocation loc(line.first_file, line.first_line);
1137 	mDirectiveHandler.handlePragma(loc, name, value, stdgl);
1138 }
1139 
1140 /////////////////////////////////////////////////////////////////////////////////
1141 //
1142 // Non-Errors.
1143 //
1144 /////////////////////////////////////////////////////////////////////////////////
1145 
getNamedVariable(const TSourceLoc & location,const TString * name,const TSymbol * symbol)1146 const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location,
1147 	const TString *name,
1148 	const TSymbol *symbol)
1149 {
1150 	const TVariable *variable = nullptr;
1151 
1152 	if(!symbol)
1153 	{
1154 		error(location, "undeclared identifier", name->c_str());
1155 		recover();
1156 	}
1157 	else if(!symbol->isVariable())
1158 	{
1159 		error(location, "variable expected", name->c_str());
1160 		recover();
1161 	}
1162 	else
1163 	{
1164 		variable = static_cast<const TVariable*>(symbol);
1165 
1166 		if(symbolTable.findBuiltIn(variable->getName(), mShaderVersion))
1167 		{
1168 			recover();
1169 		}
1170 
1171 		// Reject shaders using both gl_FragData and gl_FragColor
1172 		TQualifier qualifier = variable->getType().getQualifier();
1173 		if(qualifier == EvqFragData)
1174 		{
1175 			mUsesFragData = true;
1176 		}
1177 		else if(qualifier == EvqFragColor)
1178 		{
1179 			mUsesFragColor = true;
1180 		}
1181 
1182 		// This validation is not quite correct - it's only an error to write to
1183 		// both FragData and FragColor. For simplicity, and because users shouldn't
1184 		// be rewarded for reading from undefined variables, return an error
1185 		// if they are both referenced, rather than assigned.
1186 		if(mUsesFragData && mUsesFragColor)
1187 		{
1188 			error(location, "cannot use both gl_FragData and gl_FragColor", name->c_str());
1189 			recover();
1190 		}
1191 	}
1192 
1193 	if(!variable)
1194 	{
1195 		TType type(EbtFloat, EbpUndefined);
1196 		TVariable *fakeVariable = new TVariable(name, type);
1197 		symbolTable.declare(fakeVariable);
1198 		variable = fakeVariable;
1199 	}
1200 
1201 	return variable;
1202 }
1203 
1204 //
1205 // Look up a function name in the symbol table, and make sure it is a function.
1206 //
1207 // Return the function symbol if found, otherwise 0.
1208 //
findFunction(const TSourceLoc & line,TFunction * call,bool * builtIn)1209 const TFunction* TParseContext::findFunction(const TSourceLoc &line, TFunction* call, bool *builtIn)
1210 {
1211 	// First find by unmangled name to check whether the function name has been
1212 	// hidden by a variable name or struct typename.
1213 	const TSymbol* symbol = symbolTable.find(call->getName(), mShaderVersion, builtIn);
1214 	if (!symbol || symbol->isFunction()) {
1215 		symbol = symbolTable.find(call->getMangledName(), mShaderVersion, builtIn);
1216 	}
1217 
1218 	if (!symbol) {
1219 		error(line, "no matching overloaded function found", call->getName().c_str());
1220 		return nullptr;
1221 	}
1222 
1223 	if (!symbol->isFunction()) {
1224 		error(line, "function name expected", call->getName().c_str());
1225 		return nullptr;
1226 	}
1227 
1228 	return static_cast<const TFunction*>(symbol);
1229 }
1230 
1231 //
1232 // Initializers show up in several places in the grammar.  Have one set of
1233 // code to handle them here.
1234 //
executeInitializer(const TSourceLoc & line,const TString & identifier,const TPublicType & pType,TIntermTyped * initializer,TIntermNode ** intermNode)1235 bool TParseContext::executeInitializer(const TSourceLoc& line, const TString& identifier, const TPublicType& pType,
1236 									   TIntermTyped *initializer, TIntermNode **intermNode)
1237 {
1238 	ASSERT(intermNode != nullptr);
1239 	TType type = TType(pType);
1240 
1241 	if(type.isUnsizedArray())
1242 	{
1243 		// We have not checked yet whether the initializer actually is an array or not.
1244 		if(initializer->isArray())
1245 		{
1246 			type.setArraySize(initializer->getArraySize());
1247 		}
1248 		else
1249 		{
1250 			// Having a non-array initializer for an unsized array will result in an error later,
1251 			// so we don't generate an error message here.
1252 			type.setArraySize(1u);
1253 		}
1254 	}
1255 
1256 	TVariable *variable = nullptr;
1257 	if(!declareVariable(line, identifier, type, &variable))
1258 	{
1259 		return true;
1260 	}
1261 
1262 	if(symbolTable.atGlobalLevel() && initializer->getQualifier() != EvqConstExpr)
1263 	{
1264 		error(line, "global variable initializers must be constant expressions", "=");
1265 		return true;
1266 	}
1267 
1268 	//
1269 	// identifier must be of type constant, a global, or a temporary
1270 	//
1271 	TQualifier qualifier = type.getQualifier();
1272 	if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConstExpr)) {
1273 		error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString());
1274 		return true;
1275 	}
1276 	//
1277 	// test for and propagate constant
1278 	//
1279 
1280 	if (qualifier == EvqConstExpr) {
1281 		if (qualifier != initializer->getQualifier()) {
1282 			std::stringstream extraInfoStream;
1283 			extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
1284 			std::string extraInfo = extraInfoStream.str();
1285 			error(line, " assigning non-constant to", "=", extraInfo.c_str());
1286 			variable->getType().setQualifier(EvqTemporary);
1287 			return true;
1288 		}
1289 
1290 		if (type != initializer->getType()) {
1291 			error(line, " non-matching types for const initializer ",
1292 				variable->getType().getQualifierString());
1293 			variable->getType().setQualifier(EvqTemporary);
1294 			return true;
1295 		}
1296 
1297 		if (initializer->getAsConstantUnion()) {
1298 			variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
1299 		} else if (initializer->getAsSymbolNode()) {
1300 			const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), 0);
1301 			const TVariable* tVar = static_cast<const TVariable*>(symbol);
1302 
1303 			ConstantUnion* constArray = tVar->getConstPointer();
1304 			variable->shareConstPointer(constArray);
1305 		}
1306 	}
1307 
1308 	// Constants which aren't indexable arrays get propagated by value
1309 	// and thus don't need to initialize the symbol.
1310 	if (variable->isConstant() && !(type.isArray() && type.getArraySize() > 1))
1311 	{
1312 		*intermNode = nullptr;
1313 	}
1314 	else
1315 	{
1316 		TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
1317 		*intermNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
1318 		if(*intermNode == nullptr) {
1319 			assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
1320 			return true;
1321 		}
1322 	}
1323 
1324 	return false;
1325 }
1326 
addFullySpecifiedType(TQualifier qualifier,bool invariant,TLayoutQualifier layoutQualifier,const TPublicType & typeSpecifier)1327 TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, bool invariant, TLayoutQualifier layoutQualifier, const TPublicType &typeSpecifier)
1328 {
1329 	TPublicType returnType = typeSpecifier;
1330 	returnType.qualifier = qualifier;
1331 	returnType.invariant = invariant;
1332 	returnType.layoutQualifier = layoutQualifier;
1333 
1334 	if(mShaderVersion < 300)
1335 	{
1336 		if(typeSpecifier.array)
1337 		{
1338 			error(typeSpecifier.line, "not supported", "first-class array");
1339 			returnType.clearArrayness();
1340 		}
1341 
1342 		if(qualifier == EvqAttribute && (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt))
1343 		{
1344 			error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier));
1345 			recover();
1346 		}
1347 
1348 		if((qualifier == EvqVaryingIn || qualifier == EvqVaryingOut) &&
1349 			(typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt))
1350 		{
1351 			error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier));
1352 			recover();
1353 		}
1354 	}
1355 	else
1356 	{
1357 		if(!returnType.layoutQualifier.isEmpty())
1358 		{
1359 			globalErrorCheck(typeSpecifier.line, symbolTable.atGlobalLevel(), "layout");
1360 		}
1361 
1362 		if(IsVarying(returnType.qualifier) || returnType.qualifier == EvqVertexIn || returnType.qualifier == EvqFragmentOut)
1363 		{
1364 			checkInputOutputTypeIsValidES3(returnType.qualifier, typeSpecifier, typeSpecifier.line);
1365 		}
1366 	}
1367 
1368 	return returnType;
1369 }
1370 
checkInputOutputTypeIsValidES3(const TQualifier qualifier,const TPublicType & type,const TSourceLoc & qualifierLocation)1371 void TParseContext::checkInputOutputTypeIsValidES3(const TQualifier qualifier,
1372                                                    const TPublicType &type,
1373                                                    const TSourceLoc &qualifierLocation)
1374 {
1375 	// An input/output variable can never be bool or a sampler. Samplers are checked elsewhere.
1376 	if(type.type == EbtBool)
1377 	{
1378 		error(qualifierLocation, "cannot be bool", getQualifierString(qualifier));
1379 	}
1380 
1381 	// Specific restrictions apply for vertex shader inputs and fragment shader outputs.
1382 	switch(qualifier)
1383 	{
1384 	case EvqVertexIn:
1385 		// ESSL 3.00 section 4.3.4
1386 		if(type.array)
1387 		{
1388 			error(qualifierLocation, "cannot be array", getQualifierString(qualifier));
1389 		}
1390 		// Vertex inputs with a struct type are disallowed in singleDeclarationErrorCheck
1391 		return;
1392 	case EvqFragmentOut:
1393 		// ESSL 3.00 section 4.3.6
1394 		if(type.isMatrix())
1395 		{
1396 			error(qualifierLocation, "cannot be matrix", getQualifierString(qualifier));
1397 		}
1398 		// Fragment outputs with a struct type are disallowed in singleDeclarationErrorCheck
1399 		return;
1400 	default:
1401 		break;
1402 	}
1403 
1404 	// Vertex shader outputs / fragment shader inputs have a different, slightly more lenient set of
1405 	// restrictions.
1406 	bool typeContainsIntegers = (type.type == EbtInt || type.type == EbtUInt ||
1407 	                            type.isStructureContainingType(EbtInt) ||
1408 	                            type.isStructureContainingType(EbtUInt));
1409 	if(typeContainsIntegers && qualifier != EvqFlatIn && qualifier != EvqFlatOut)
1410 	{
1411 		error(qualifierLocation, "must use 'flat' interpolation here", getQualifierString(qualifier));
1412 	}
1413 
1414 	if(type.type == EbtStruct)
1415 	{
1416 		// ESSL 3.00 sections 4.3.4 and 4.3.6.
1417 		// These restrictions are only implied by the ESSL 3.00 spec, but
1418 		// the ESSL 3.10 spec lists these restrictions explicitly.
1419 		if(type.array)
1420 		{
1421 			error(qualifierLocation, "cannot be an array of structures", getQualifierString(qualifier));
1422 		}
1423 		if(type.isStructureContainingArrays())
1424 		{
1425 			error(qualifierLocation, "cannot be a structure containing an array", getQualifierString(qualifier));
1426 		}
1427 		if(type.isStructureContainingType(EbtStruct))
1428 		{
1429 			error(qualifierLocation, "cannot be a structure containing a structure", getQualifierString(qualifier));
1430 		}
1431 		if(type.isStructureContainingType(EbtBool))
1432 		{
1433 			error(qualifierLocation, "cannot be a structure containing a bool", getQualifierString(qualifier));
1434 		}
1435 	}
1436 }
1437 
parseSingleDeclaration(TPublicType & publicType,const TSourceLoc & identifierOrTypeLocation,const TString & identifier)1438 TIntermAggregate *TParseContext::parseSingleDeclaration(TPublicType &publicType,
1439 	const TSourceLoc &identifierOrTypeLocation,
1440 	const TString &identifier)
1441 {
1442 	TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierOrTypeLocation);
1443 
1444 	bool emptyDeclaration = (identifier == "");
1445 
1446 	mDeferredSingleDeclarationErrorCheck = emptyDeclaration;
1447 
1448 	if(emptyDeclaration)
1449 	{
1450 		if(publicType.isUnsizedArray())
1451 		{
1452 			// ESSL3 spec section 4.1.9: Array declaration which leaves the size unspecified is an error.
1453 			// It is assumed that this applies to empty declarations as well.
1454 			error(identifierOrTypeLocation, "empty array declaration needs to specify a size", identifier.c_str());
1455 		}
1456 	}
1457 	else
1458 	{
1459 		if(singleDeclarationErrorCheck(publicType, identifierOrTypeLocation))
1460 			recover();
1461 
1462 		if(nonInitErrorCheck(identifierOrTypeLocation, identifier, publicType))
1463 			recover();
1464 
1465 		TVariable *variable = nullptr;
1466 		if(!declareVariable(identifierOrTypeLocation, identifier, TType(publicType), &variable))
1467 			recover();
1468 
1469 		if(variable && symbol)
1470 			symbol->setId(variable->getUniqueId());
1471 	}
1472 
1473 	return intermediate.makeAggregate(symbol, identifierOrTypeLocation);
1474 }
1475 
parseSingleArrayDeclaration(TPublicType & publicType,const TSourceLoc & identifierLocation,const TString & identifier,const TSourceLoc & indexLocation,TIntermTyped * indexExpression)1476 TIntermAggregate *TParseContext::parseSingleArrayDeclaration(TPublicType &publicType,
1477 	const TSourceLoc &identifierLocation,
1478 	const TString &identifier,
1479 	const TSourceLoc &indexLocation,
1480 	TIntermTyped *indexExpression)
1481 {
1482 	mDeferredSingleDeclarationErrorCheck = false;
1483 
1484 	if(singleDeclarationErrorCheck(publicType, identifierLocation))
1485 		recover();
1486 
1487 	if(nonInitErrorCheck(identifierLocation, identifier, publicType))
1488 		recover();
1489 
1490 	if(arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType))
1491 	{
1492 		recover();
1493 	}
1494 
1495 	TType arrayType(publicType);
1496 
1497 	int size = 0;
1498 	if(arraySizeErrorCheck(identifierLocation, indexExpression, size))
1499 	{
1500 		recover();
1501 	}
1502 	// Make the type an array even if size check failed.
1503 	// This ensures useless error messages regarding the variable's non-arrayness won't follow.
1504 	arrayType.setArraySize(size);
1505 
1506 	TVariable *variable = nullptr;
1507 	if(!declareVariable(identifierLocation, identifier, arrayType, &variable))
1508 		recover();
1509 
1510 	TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation);
1511 	if(variable && symbol)
1512 		symbol->setId(variable->getUniqueId());
1513 
1514 	return intermediate.makeAggregate(symbol, identifierLocation);
1515 }
1516 
parseSingleInitDeclaration(const TPublicType & publicType,const TSourceLoc & identifierLocation,const TString & identifier,const TSourceLoc & initLocation,TIntermTyped * initializer)1517 TIntermAggregate *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType,
1518 	const TSourceLoc &identifierLocation,
1519 	const TString &identifier,
1520 	const TSourceLoc &initLocation,
1521 	TIntermTyped *initializer)
1522 {
1523 	mDeferredSingleDeclarationErrorCheck = false;
1524 
1525 	if(singleDeclarationErrorCheck(publicType, identifierLocation))
1526 		recover();
1527 
1528 	TIntermNode *intermNode = nullptr;
1529 	if(!executeInitializer(identifierLocation, identifier, publicType, initializer, &intermNode))
1530 	{
1531 		//
1532 		// Build intermediate representation
1533 		//
1534 		return intermNode ? intermediate.makeAggregate(intermNode, initLocation) : nullptr;
1535 	}
1536 	else
1537 	{
1538 		recover();
1539 		return nullptr;
1540 	}
1541 }
1542 
parseSingleArrayInitDeclaration(TPublicType & publicType,const TSourceLoc & identifierLocation,const TString & identifier,const TSourceLoc & indexLocation,TIntermTyped * indexExpression,const TSourceLoc & initLocation,TIntermTyped * initializer)1543 TIntermAggregate *TParseContext::parseSingleArrayInitDeclaration(TPublicType &publicType,
1544 	const TSourceLoc &identifierLocation,
1545 	const TString &identifier,
1546 	const TSourceLoc &indexLocation,
1547 	TIntermTyped *indexExpression,
1548 	const TSourceLoc &initLocation,
1549 	TIntermTyped *initializer)
1550 {
1551 	mDeferredSingleDeclarationErrorCheck = false;
1552 
1553 	if(singleDeclarationErrorCheck(publicType, identifierLocation))
1554 		recover();
1555 
1556 	if(arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType))
1557 	{
1558 		recover();
1559 	}
1560 
1561 	TPublicType arrayType(publicType);
1562 
1563 	int size = 0;
1564 	// If indexExpression is nullptr, then the array will eventually get its size implicitly from the initializer.
1565 	if(indexExpression != nullptr && arraySizeErrorCheck(identifierLocation, indexExpression, size))
1566 	{
1567 		recover();
1568 	}
1569 	// Make the type an array even if size check failed.
1570 	// This ensures useless error messages regarding the variable's non-arrayness won't follow.
1571 	arrayType.setArray(true, size);
1572 
1573 	// initNode will correspond to the whole of "type b[n] = initializer".
1574 	TIntermNode *initNode = nullptr;
1575 	if(!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
1576 	{
1577 		return initNode ? intermediate.makeAggregate(initNode, initLocation) : nullptr;
1578 	}
1579 	else
1580 	{
1581 		recover();
1582 		return nullptr;
1583 	}
1584 }
1585 
parseInvariantDeclaration(const TSourceLoc & invariantLoc,const TSourceLoc & identifierLoc,const TString * identifier,const TSymbol * symbol)1586 TIntermAggregate *TParseContext::parseInvariantDeclaration(const TSourceLoc &invariantLoc,
1587 	const TSourceLoc &identifierLoc,
1588 	const TString *identifier,
1589 	const TSymbol *symbol)
1590 {
1591 	// invariant declaration
1592 	if(globalErrorCheck(invariantLoc, symbolTable.atGlobalLevel(), "invariant varying"))
1593 	{
1594 		recover();
1595 	}
1596 
1597 	if(!symbol)
1598 	{
1599 		error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str());
1600 		recover();
1601 		return nullptr;
1602 	}
1603 	else
1604 	{
1605 		const TString kGlFrontFacing("gl_FrontFacing");
1606 		if(*identifier == kGlFrontFacing)
1607 		{
1608 			error(identifierLoc, "identifier should not be declared as invariant", identifier->c_str());
1609 			recover();
1610 			return nullptr;
1611 		}
1612 		symbolTable.addInvariantVarying(std::string(identifier->c_str()));
1613 		const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
1614 		ASSERT(variable);
1615 		const TType &type = variable->getType();
1616 		TIntermSymbol *intermSymbol = intermediate.addSymbol(variable->getUniqueId(),
1617 			*identifier, type, identifierLoc);
1618 
1619 		TIntermAggregate *aggregate = intermediate.makeAggregate(intermSymbol, identifierLoc);
1620 		aggregate->setOp(EOpInvariantDeclaration);
1621 		return aggregate;
1622 	}
1623 }
1624 
parseDeclarator(TPublicType & publicType,TIntermAggregate * aggregateDeclaration,const TSourceLoc & identifierLocation,const TString & identifier)1625 TIntermAggregate *TParseContext::parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration,
1626 	const TSourceLoc &identifierLocation, const TString &identifier)
1627 {
1628 	// If the declaration starting this declarator list was empty (example: int,), some checks were not performed.
1629 	if(mDeferredSingleDeclarationErrorCheck)
1630 	{
1631 		if(singleDeclarationErrorCheck(publicType, identifierLocation))
1632 			recover();
1633 		mDeferredSingleDeclarationErrorCheck = false;
1634 	}
1635 
1636 	if(locationDeclaratorListCheck(identifierLocation, publicType))
1637 		recover();
1638 
1639 	if(nonInitErrorCheck(identifierLocation, identifier, publicType))
1640 		recover();
1641 
1642 	TVariable *variable = nullptr;
1643 	if(!declareVariable(identifierLocation, identifier, TType(publicType), &variable))
1644 		recover();
1645 
1646 	TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation);
1647 	if(variable && symbol)
1648 		symbol->setId(variable->getUniqueId());
1649 
1650 	return intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation);
1651 }
1652 
parseArrayDeclarator(TPublicType & publicType,TIntermAggregate * aggregateDeclaration,const TSourceLoc & identifierLocation,const TString & identifier,const TSourceLoc & arrayLocation,TIntermTyped * indexExpression)1653 TIntermAggregate *TParseContext::parseArrayDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration,
1654 	const TSourceLoc &identifierLocation, const TString &identifier,
1655 	const TSourceLoc &arrayLocation, TIntermTyped *indexExpression)
1656 {
1657 	// If the declaration starting this declarator list was empty (example: int,), some checks were not performed.
1658 	if(mDeferredSingleDeclarationErrorCheck)
1659 	{
1660 		if(singleDeclarationErrorCheck(publicType, identifierLocation))
1661 			recover();
1662 		mDeferredSingleDeclarationErrorCheck = false;
1663 	}
1664 
1665 	if(locationDeclaratorListCheck(identifierLocation, publicType))
1666 		recover();
1667 
1668 	if(nonInitErrorCheck(identifierLocation, identifier, publicType))
1669 		recover();
1670 
1671 	if(arrayTypeErrorCheck(arrayLocation, publicType) || arrayQualifierErrorCheck(arrayLocation, publicType))
1672 	{
1673 		recover();
1674 	}
1675 	else
1676 	{
1677 		TType arrayType = TType(publicType);
1678 		int size = 0;
1679 		if(arraySizeErrorCheck(arrayLocation, indexExpression, size))
1680 		{
1681 			recover();
1682 		}
1683 		arrayType.setArraySize(size);
1684 
1685 		TVariable *variable = nullptr;
1686 		if(!declareVariable(identifierLocation, identifier, arrayType, &variable))
1687 			recover();
1688 
1689 		TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation);
1690 		if(variable && symbol)
1691 			symbol->setId(variable->getUniqueId());
1692 
1693 		return intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation);
1694 	}
1695 
1696 	return nullptr;
1697 }
1698 
parseInitDeclarator(const TPublicType & publicType,TIntermAggregate * aggregateDeclaration,const TSourceLoc & identifierLocation,const TString & identifier,const TSourceLoc & initLocation,TIntermTyped * initializer)1699 TIntermAggregate *TParseContext::parseInitDeclarator(const TPublicType &publicType, TIntermAggregate *aggregateDeclaration,
1700 	const TSourceLoc &identifierLocation, const TString &identifier,
1701 	const TSourceLoc &initLocation, TIntermTyped *initializer)
1702 {
1703 	// If the declaration starting this declarator list was empty (example: int,), some checks were not performed.
1704 	if(mDeferredSingleDeclarationErrorCheck)
1705 	{
1706 		if(singleDeclarationErrorCheck(publicType, identifierLocation))
1707 			recover();
1708 		mDeferredSingleDeclarationErrorCheck = false;
1709 	}
1710 
1711 	if(locationDeclaratorListCheck(identifierLocation, publicType))
1712 		recover();
1713 
1714 	TIntermNode *intermNode = nullptr;
1715 	if(!executeInitializer(identifierLocation, identifier, publicType, initializer, &intermNode))
1716 	{
1717 		//
1718 		// build the intermediate representation
1719 		//
1720 		if(intermNode)
1721 		{
1722 			return intermediate.growAggregate(aggregateDeclaration, intermNode, initLocation);
1723 		}
1724 		else
1725 		{
1726 			return aggregateDeclaration;
1727 		}
1728 	}
1729 	else
1730 	{
1731 		recover();
1732 		return nullptr;
1733 	}
1734 }
1735 
parseArrayInitDeclarator(const TPublicType & publicType,TIntermAggregate * aggregateDeclaration,const TSourceLoc & identifierLocation,const TString & identifier,const TSourceLoc & indexLocation,TIntermTyped * indexExpression,const TSourceLoc & initLocation,TIntermTyped * initializer)1736 TIntermAggregate *TParseContext::parseArrayInitDeclarator(const TPublicType &publicType,
1737 	TIntermAggregate *aggregateDeclaration,
1738 	const TSourceLoc &identifierLocation,
1739 	const TString &identifier,
1740 	const TSourceLoc &indexLocation,
1741 	TIntermTyped *indexExpression,
1742 	const TSourceLoc &initLocation, TIntermTyped *initializer)
1743 {
1744 	// If the declaration starting this declarator list was empty (example: int,), some checks were not performed.
1745 	if(mDeferredSingleDeclarationErrorCheck)
1746 	{
1747 		if(singleDeclarationErrorCheck(publicType, identifierLocation))
1748 			recover();
1749 		mDeferredSingleDeclarationErrorCheck = false;
1750 	}
1751 
1752 	if(locationDeclaratorListCheck(identifierLocation, publicType))
1753 		recover();
1754 
1755 	if(arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType))
1756 	{
1757 		recover();
1758 	}
1759 
1760 	TPublicType arrayType(publicType);
1761 
1762 	int size = 0;
1763 	// If indexExpression is nullptr, then the array will eventually get its size implicitly from the initializer.
1764 	if(indexExpression != nullptr && arraySizeErrorCheck(identifierLocation, indexExpression, size))
1765 	{
1766 		recover();
1767 	}
1768 	// Make the type an array even if size check failed.
1769 	// This ensures useless error messages regarding the variable's non-arrayness won't follow.
1770 	arrayType.setArray(true, size);
1771 
1772 	// initNode will correspond to the whole of "b[n] = initializer".
1773 	TIntermNode *initNode = nullptr;
1774 	if(!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
1775 	{
1776 		if(initNode)
1777 		{
1778 			return intermediate.growAggregate(aggregateDeclaration, initNode, initLocation);
1779 		}
1780 		else
1781 		{
1782 			return aggregateDeclaration;
1783 		}
1784 	}
1785 	else
1786 	{
1787 		recover();
1788 		return nullptr;
1789 	}
1790 }
1791 
parseGlobalLayoutQualifier(const TPublicType & typeQualifier)1792 void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier)
1793 {
1794 	if(mShaderVersion < 300)
1795 	{
1796 		error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 only", "layout");
1797 		recover();
1798 		return;
1799 	}
1800 
1801 	if(typeQualifier.qualifier != EvqUniform)
1802 	{
1803 		error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "global layout must be uniform");
1804 		recover();
1805 		return;
1806 	}
1807 
1808 	const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier;
1809 	ASSERT(!layoutQualifier.isEmpty());
1810 
1811 	if(layoutLocationErrorCheck(typeQualifier.line, typeQualifier.layoutQualifier))
1812 	{
1813 		recover();
1814 		return;
1815 	}
1816 
1817 	if(layoutQualifier.matrixPacking != EmpUnspecified)
1818 	{
1819 		mDefaultMatrixPacking = layoutQualifier.matrixPacking;
1820 	}
1821 
1822 	if(layoutQualifier.blockStorage != EbsUnspecified)
1823 	{
1824 		mDefaultBlockStorage = layoutQualifier.blockStorage;
1825 	}
1826 }
1827 
addFunctionPrototypeDeclaration(const TFunction & function,const TSourceLoc & location)1828 TIntermAggregate *TParseContext::addFunctionPrototypeDeclaration(const TFunction &function, const TSourceLoc &location)
1829 {
1830 	// Note: symbolTableFunction could be the same as function if this is the first declaration.
1831 	// Either way the instance in the symbol table is used to track whether the function is declared
1832 	// multiple times.
1833 	TFunction *symbolTableFunction =
1834 		static_cast<TFunction *>(symbolTable.find(function.getMangledName(), getShaderVersion()));
1835 	if(symbolTableFunction->hasPrototypeDeclaration() && mShaderVersion == 100)
1836 	{
1837 		// ESSL 1.00.17 section 4.2.7.
1838 		// Doesn't apply to ESSL 3.00.4: see section 4.2.3.
1839 		error(location, "duplicate function prototype declarations are not allowed", "function");
1840 		recover();
1841 	}
1842 	symbolTableFunction->setHasPrototypeDeclaration();
1843 
1844 	TIntermAggregate *prototype = new TIntermAggregate;
1845 	prototype->setType(function.getReturnType());
1846 	prototype->setName(function.getMangledName());
1847 
1848 	for(size_t i = 0; i < function.getParamCount(); i++)
1849 	{
1850 		const TParameter &param = function.getParam(i);
1851 		if(param.name != 0)
1852 		{
1853 			TVariable variable(param.name, *param.type);
1854 
1855 			TIntermSymbol *paramSymbol = intermediate.addSymbol(
1856 				variable.getUniqueId(), variable.getName(), variable.getType(), location);
1857 			prototype = intermediate.growAggregate(prototype, paramSymbol, location);
1858 		}
1859 		else
1860 		{
1861 			TIntermSymbol *paramSymbol = intermediate.addSymbol(0, "", *param.type, location);
1862 			prototype = intermediate.growAggregate(prototype, paramSymbol, location);
1863 		}
1864 	}
1865 
1866 	prototype->setOp(EOpPrototype);
1867 
1868 	symbolTable.pop();
1869 
1870 	if(!symbolTable.atGlobalLevel())
1871 	{
1872 		// ESSL 3.00.4 section 4.2.4.
1873 		error(location, "local function prototype declarations are not allowed", "function");
1874 		recover();
1875 	}
1876 
1877 	return prototype;
1878 }
1879 
addFunctionDefinition(const TFunction & function,TIntermAggregate * functionPrototype,TIntermAggregate * functionBody,const TSourceLoc & location)1880 TIntermAggregate *TParseContext::addFunctionDefinition(const TFunction &function, TIntermAggregate *functionPrototype, TIntermAggregate *functionBody, const TSourceLoc &location)
1881 {
1882 	//?? Check that all paths return a value if return type != void ?
1883 	//   May be best done as post process phase on intermediate code
1884 	if(mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue)
1885 	{
1886 		error(location, "function does not return a value:", "", function.getName().c_str());
1887 		recover();
1888 	}
1889 
1890 	TIntermAggregate *aggregate = intermediate.growAggregate(functionPrototype, functionBody, location);
1891 	intermediate.setAggregateOperator(aggregate, EOpFunction, location);
1892 	aggregate->setName(function.getMangledName().c_str());
1893 	aggregate->setType(function.getReturnType());
1894 
1895 	// store the pragma information for debug and optimize and other vendor specific
1896 	// information. This information can be queried from the parse tree
1897 	aggregate->setOptimize(pragma().optimize);
1898 	aggregate->setDebug(pragma().debug);
1899 
1900 	if(functionBody && functionBody->getAsAggregate())
1901 		aggregate->setEndLine(functionBody->getAsAggregate()->getEndLine());
1902 
1903 	symbolTable.pop();
1904 	return aggregate;
1905 }
1906 
parseFunctionPrototype(const TSourceLoc & location,TFunction * function,TIntermAggregate ** aggregateOut)1907 void TParseContext::parseFunctionPrototype(const TSourceLoc &location, TFunction *function, TIntermAggregate **aggregateOut)
1908 {
1909 	const TSymbol *builtIn = symbolTable.findBuiltIn(function->getMangledName(), getShaderVersion());
1910 
1911 	if(builtIn)
1912 	{
1913 		error(location, "built-in functions cannot be redefined", function->getName().c_str());
1914 		recover();
1915 	}
1916 
1917 	TFunction *prevDec = static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion()));
1918 	//
1919 	// Note:  'prevDec' could be 'function' if this is the first time we've seen function
1920 	// as it would have just been put in the symbol table.  Otherwise, we're looking up
1921 	// an earlier occurance.
1922 	//
1923 	if(prevDec->isDefined())
1924 	{
1925 		// Then this function already has a body.
1926 		error(location, "function already has a body", function->getName().c_str());
1927 		recover();
1928 	}
1929 	prevDec->setDefined();
1930 	//
1931 	// Overload the unique ID of the definition to be the same unique ID as the declaration.
1932 	// Eventually we will probably want to have only a single definition and just swap the
1933 	// arguments to be the definition's arguments.
1934 	//
1935 	function->setUniqueId(prevDec->getUniqueId());
1936 
1937 	// Raise error message if main function takes any parameters or return anything other than void
1938 	if(function->getName() == "main")
1939 	{
1940 		if(function->getParamCount() > 0)
1941 		{
1942 			error(location, "function cannot take any parameter(s)", function->getName().c_str());
1943 			recover();
1944 		}
1945 		if(function->getReturnType().getBasicType() != EbtVoid)
1946 		{
1947 			error(location, "", function->getReturnType().getBasicString(), "main function cannot return a value");
1948 			recover();
1949 		}
1950 	}
1951 
1952 	//
1953 	// Remember the return type for later checking for RETURN statements.
1954 	//
1955 	mCurrentFunctionType = &(prevDec->getReturnType());
1956 	mFunctionReturnsValue = false;
1957 
1958 	//
1959 	// Insert parameters into the symbol table.
1960 	// If the parameter has no name, it's not an error, just don't insert it
1961 	// (could be used for unused args).
1962 	//
1963 	// Also, accumulate the list of parameters into the HIL, so lower level code
1964 	// knows where to find parameters.
1965 	//
1966 	TIntermAggregate *paramNodes = new TIntermAggregate;
1967 	for(size_t i = 0; i < function->getParamCount(); i++)
1968 	{
1969 		const TParameter &param = function->getParam(i);
1970 		if(param.name != 0)
1971 		{
1972 			TVariable *variable = new TVariable(param.name, *param.type);
1973 			//
1974 			// Insert the parameters with name in the symbol table.
1975 			//
1976 			if(!symbolTable.declare(variable))
1977 			{
1978 				error(location, "redefinition", variable->getName().c_str());
1979 				recover();
1980 				paramNodes = intermediate.growAggregate(
1981 					paramNodes, intermediate.addSymbol(0, "", *param.type, location), location);
1982 				continue;
1983 			}
1984 
1985 			//
1986 			// Add the parameter to the HIL
1987 			//
1988 			TIntermSymbol *symbol = intermediate.addSymbol(
1989 				variable->getUniqueId(), variable->getName(), variable->getType(), location);
1990 
1991 			paramNodes = intermediate.growAggregate(paramNodes, symbol, location);
1992 		}
1993 		else
1994 		{
1995 			paramNodes = intermediate.growAggregate(
1996 				paramNodes, intermediate.addSymbol(0, "", *param.type, location), location);
1997 		}
1998 	}
1999 	intermediate.setAggregateOperator(paramNodes, EOpParameters, location);
2000 	*aggregateOut = paramNodes;
2001 	setLoopNestingLevel(0);
2002 }
2003 
parseFunctionDeclarator(const TSourceLoc & location,TFunction * function)2004 TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TFunction *function)
2005 {
2006 	//
2007 	// We don't know at this point whether this is a function definition or a prototype.
2008 	// The definition production code will check for redefinitions.
2009 	// In the case of ESSL 1.00 the prototype production code will also check for redeclarations.
2010 	//
2011 	// Return types and parameter qualifiers must match in all redeclarations, so those are checked
2012 	// here.
2013 	//
2014 	TFunction *prevDec = static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion()));
2015 	if(getShaderVersion() >= 300 && symbolTable.hasUnmangledBuiltIn(function->getName().c_str()))
2016 	{
2017 		// With ESSL 3.00, names of built-in functions cannot be redeclared as functions.
2018 		// Therefore overloading or redefining builtin functions is an error.
2019 		error(location, "Name of a built-in function cannot be redeclared as function", function->getName().c_str());
2020 	}
2021 	else if(prevDec)
2022 	{
2023 		if(prevDec->getReturnType() != function->getReturnType())
2024 		{
2025 			error(location, "overloaded functions must have the same return type",
2026 				function->getReturnType().getBasicString());
2027 			recover();
2028 		}
2029 		for(size_t i = 0; i < prevDec->getParamCount(); ++i)
2030 		{
2031 			if(prevDec->getParam(i).type->getQualifier() != function->getParam(i).type->getQualifier())
2032 			{
2033 				error(location, "overloaded functions must have the same parameter qualifiers",
2034 					function->getParam(i).type->getQualifierString());
2035 				recover();
2036 			}
2037 		}
2038 	}
2039 
2040 	//
2041 	// Check for previously declared variables using the same name.
2042 	//
2043 	TSymbol *prevSym = symbolTable.find(function->getName(), getShaderVersion());
2044 	if(prevSym)
2045 	{
2046 		if(!prevSym->isFunction())
2047 		{
2048 			error(location, "redefinition", function->getName().c_str(), "function");
2049 			recover();
2050 		}
2051 	}
2052 	else
2053 	{
2054 		// Insert the unmangled name to detect potential future redefinition as a variable.
2055 		TFunction *unmangledFunction = new TFunction(NewPoolTString(function->getName().c_str()), function->getReturnType());
2056 		symbolTable.getOuterLevel()->insertUnmangled(unmangledFunction);
2057 	}
2058 
2059 	// We're at the inner scope level of the function's arguments and body statement.
2060 	// Add the function prototype to the surrounding scope instead.
2061 	symbolTable.getOuterLevel()->insert(function);
2062 
2063 	//
2064 	// If this is a redeclaration, it could also be a definition, in which case, we want to use the
2065 	// variable names from this one, and not the one that's
2066 	// being redeclared.  So, pass back up this declaration, not the one in the symbol table.
2067 	//
2068 	return function;
2069 }
2070 
addConstructorFunc(const TPublicType & publicTypeIn)2071 TFunction *TParseContext::addConstructorFunc(const TPublicType &publicTypeIn)
2072 {
2073 	TPublicType publicType = publicTypeIn;
2074 	TOperator op = EOpNull;
2075 	if(publicType.userDef)
2076 	{
2077 		op = EOpConstructStruct;
2078 	}
2079 	else
2080 	{
2081 		op = TypeToConstructorOperator(TType(publicType));
2082 		if(op == EOpNull)
2083 		{
2084 			error(publicType.line, "cannot construct this type", getBasicString(publicType.type));
2085 			recover();
2086 			publicType.type = EbtFloat;
2087 			op = EOpConstructFloat;
2088 		}
2089 	}
2090 
2091 	TString tempString;
2092 	TType type(publicType);
2093 	return new TFunction(&tempString, type, op);
2094 }
2095 
2096 // This function is used to test for the correctness of the parameters passed to various constructor functions
2097 // and also convert them to the right datatype if it is allowed and required.
2098 //
2099 // Returns 0 for an error or the constructed node (aggregate or typed) for no error.
2100 //
addConstructor(TIntermNode * arguments,const TType * type,TOperator op,TFunction * fnCall,const TSourceLoc & line)2101 TIntermTyped* TParseContext::addConstructor(TIntermNode* arguments, const TType* type, TOperator op, TFunction* fnCall, const TSourceLoc &line)
2102 {
2103 	TIntermAggregate *aggregateArguments = arguments->getAsAggregate();
2104 
2105 	if(!aggregateArguments)
2106 	{
2107 		aggregateArguments = new TIntermAggregate;
2108 		aggregateArguments->getSequence().push_back(arguments);
2109 	}
2110 
2111 	if(type->isArray())
2112 	{
2113 		// GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of
2114 		// the array.
2115 		for(TIntermNode *&argNode : aggregateArguments->getSequence())
2116 		{
2117 			const TType &argType = argNode->getAsTyped()->getType();
2118 			// It has already been checked that the argument is not an array.
2119 			ASSERT(!argType.isArray());
2120 			if(!argType.sameElementType(*type))
2121 			{
2122 				error(line, "Array constructor argument has an incorrect type", "Error");
2123 				return nullptr;
2124 			}
2125 		}
2126 	}
2127 	else if(op == EOpConstructStruct)
2128 	{
2129 		const TFieldList &fields = type->getStruct()->fields();
2130 		TIntermSequence &args = aggregateArguments->getSequence();
2131 
2132 		for(size_t i = 0; i < fields.size(); i++)
2133 		{
2134 			if(args[i]->getAsTyped()->getType() != *fields[i]->type())
2135 			{
2136 				error(line, "Structure constructor arguments do not match structure fields", "Error");
2137 				recover();
2138 
2139 				return nullptr;
2140 			}
2141 		}
2142 	}
2143 
2144 	// Turn the argument list itself into a constructor
2145 	TIntermAggregate *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
2146 	TIntermTyped *constConstructor = foldConstConstructor(constructor, *type);
2147 	if(constConstructor)
2148 	{
2149 		return constConstructor;
2150 	}
2151 
2152 	return constructor;
2153 }
2154 
foldConstConstructor(TIntermAggregate * aggrNode,const TType & type)2155 TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, const TType& type)
2156 {
2157 	aggrNode->setType(type);
2158 	if (aggrNode->isConstantFoldable()) {
2159 		bool returnVal = false;
2160 		ConstantUnion* unionArray = new ConstantUnion[type.getObjectSize()];
2161 		if (aggrNode->getSequence().size() == 1)  {
2162 			returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type, true);
2163 		}
2164 		else {
2165 			returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type);
2166 		}
2167 		if (returnVal)
2168 			return nullptr;
2169 
2170 		return intermediate.addConstantUnion(unionArray, type, aggrNode->getLine());
2171 	}
2172 
2173 	return nullptr;
2174 }
2175 
2176 //
2177 // This function returns the tree representation for the vector field(s) being accessed from contant vector.
2178 // If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a contant node is
2179 // returned, else an aggregate node is returned (for v.xy). The input to this function could either be the symbol
2180 // node or it could be the intermediate tree representation of accessing fields in a constant structure or column of
2181 // a constant matrix.
2182 //
addConstVectorNode(TVectorFields & fields,TIntermTyped * node,const TSourceLoc & line)2183 TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, const TSourceLoc &line)
2184 {
2185 	TIntermTyped* typedNode;
2186 	TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
2187 
2188 	ConstantUnion *unionArray;
2189 	if (tempConstantNode) {
2190 		unionArray = tempConstantNode->getUnionArrayPointer();
2191 
2192 		if (!unionArray) {
2193 			return node;
2194 		}
2195 	} else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
2196 		error(line, "Cannot offset into the vector", "Error");
2197 		recover();
2198 
2199 		return nullptr;
2200 	}
2201 
2202 	ConstantUnion* constArray = new ConstantUnion[fields.num];
2203 
2204 	int objSize = static_cast<int>(node->getType().getObjectSize());
2205 	for (int i = 0; i < fields.num; i++) {
2206 		if (fields.offsets[i] >= objSize) {
2207 			std::stringstream extraInfoStream;
2208 			extraInfoStream << "vector field selection out of range '" << fields.offsets[i] << "'";
2209 			std::string extraInfo = extraInfoStream.str();
2210 			error(line, "", "[", extraInfo.c_str());
2211 			recover();
2212 			fields.offsets[i] = 0;
2213 		}
2214 
2215 		constArray[i] = unionArray[fields.offsets[i]];
2216 
2217 	}
2218 
2219 	TType type(node->getType().getBasicType(), node->getType().getPrecision(), EvqConstExpr, fields.num);
2220 	typedNode = intermediate.addConstantUnion(constArray, type, line);
2221 	return typedNode;
2222 }
2223 
2224 //
2225 // This function returns the column being accessed from a constant matrix. The values are retrieved from
2226 // the symbol table and parse-tree is built for a vector (each column of a matrix is a vector). The input
2227 // to the function could either be a symbol node (m[0] where m is a constant matrix)that represents a
2228 // constant matrix or it could be the tree representation of the constant matrix (s.m1[0] where s is a constant structure)
2229 //
addConstMatrixNode(int index,TIntermTyped * node,const TSourceLoc & line)2230 TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, const TSourceLoc &line)
2231 {
2232 	TIntermTyped* typedNode;
2233 	TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
2234 
2235 	if (index >= node->getType().getNominalSize()) {
2236 		std::stringstream extraInfoStream;
2237 		extraInfoStream << "matrix field selection out of range '" << index << "'";
2238 		std::string extraInfo = extraInfoStream.str();
2239 		error(line, "", "[", extraInfo.c_str());
2240 		recover();
2241 		index = 0;
2242 	}
2243 
2244 	if (tempConstantNode) {
2245 		 ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
2246 		 int size = tempConstantNode->getType().getNominalSize();
2247 		 typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line);
2248 	} else {
2249 		error(line, "Cannot offset into the matrix", "Error");
2250 		recover();
2251 
2252 		return nullptr;
2253 	}
2254 
2255 	return typedNode;
2256 }
2257 
2258 
2259 //
2260 // This function returns an element of an array accessed from a constant array. The values are retrieved from
2261 // the symbol table and parse-tree is built for the type of the element. The input
2262 // to the function could either be a symbol node (a[0] where a is a constant array)that represents a
2263 // constant array or it could be the tree representation of the constant array (s.a1[0] where s is a constant structure)
2264 //
addConstArrayNode(int index,TIntermTyped * node,const TSourceLoc & line)2265 TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc &line)
2266 {
2267 	TIntermTyped* typedNode;
2268 	TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
2269 	TType arrayElementType = node->getType();
2270 	arrayElementType.clearArrayness();
2271 
2272 	if (index >= node->getType().getArraySize()) {
2273 		std::stringstream extraInfoStream;
2274 		extraInfoStream << "array field selection out of range '" << index << "'";
2275 		std::string extraInfo = extraInfoStream.str();
2276 		error(line, "", "[", extraInfo.c_str());
2277 		recover();
2278 		index = 0;
2279 	}
2280 
2281 	size_t arrayElementSize = arrayElementType.getObjectSize();
2282 
2283 	if (tempConstantNode) {
2284 		 ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
2285 		 typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line);
2286 	} else {
2287 		error(line, "Cannot offset into the array", "Error");
2288 		recover();
2289 
2290 		return nullptr;
2291 	}
2292 
2293 	return typedNode;
2294 }
2295 
2296 
2297 //
2298 // This function returns the value of a particular field inside a constant structure from the symbol table.
2299 // If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr
2300 // function and returns the parse-tree with the values of the embedded/nested struct.
2301 //
addConstStruct(const TString & identifier,TIntermTyped * node,const TSourceLoc & line)2302 TIntermTyped* TParseContext::addConstStruct(const TString& identifier, TIntermTyped* node, const TSourceLoc &line)
2303 {
2304 	const TFieldList &fields = node->getType().getStruct()->fields();
2305 	TIntermTyped *typedNode;
2306 	size_t instanceSize = 0;
2307 	TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
2308 
2309 	for(const auto &field : fields) {
2310 		if (field->name() == identifier) {
2311 			break;
2312 		} else {
2313 			instanceSize += field->type()->getObjectSize();
2314 		}
2315 	}
2316 
2317 	if (tempConstantNode) {
2318 		 ConstantUnion* constArray = tempConstantNode->getUnionArrayPointer();
2319 
2320 		 typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function
2321 	} else {
2322 		error(line, "Cannot offset into the structure", "Error");
2323 		recover();
2324 
2325 		return nullptr;
2326 	}
2327 
2328 	return typedNode;
2329 }
2330 
2331 //
2332 // Interface/uniform blocks
2333 //
addInterfaceBlock(const TPublicType & typeQualifier,const TSourceLoc & nameLine,const TString & blockName,TFieldList * fieldList,const TString * instanceName,const TSourceLoc & instanceLine,TIntermTyped * arrayIndex,const TSourceLoc & arrayIndexLine)2334 TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TFieldList* fieldList,
2335 												   const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine)
2336 {
2337 	if(reservedErrorCheck(nameLine, blockName))
2338 		recover();
2339 
2340 	if(typeQualifier.qualifier != EvqUniform)
2341 	{
2342 		error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "interface blocks must be uniform");
2343 		recover();
2344 	}
2345 
2346 	TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier;
2347 	if(layoutLocationErrorCheck(typeQualifier.line, blockLayoutQualifier))
2348 	{
2349 		recover();
2350 	}
2351 
2352 	if(blockLayoutQualifier.matrixPacking == EmpUnspecified)
2353 	{
2354 		blockLayoutQualifier.matrixPacking = mDefaultMatrixPacking;
2355 	}
2356 
2357 	if(blockLayoutQualifier.blockStorage == EbsUnspecified)
2358 	{
2359 		blockLayoutQualifier.blockStorage = mDefaultBlockStorage;
2360 	}
2361 
2362 	TSymbol* blockNameSymbol = new TSymbol(&blockName);
2363 	if(!symbolTable.declare(blockNameSymbol)) {
2364 		error(nameLine, "redefinition", blockName.c_str(), "interface block name");
2365 		recover();
2366 	}
2367 
2368 	// check for sampler types and apply layout qualifiers
2369 	for(const auto &field : *fieldList) {
2370 		TType* fieldType = field->type();
2371 		if(IsSampler(fieldType->getBasicType())) {
2372 			error(field->line(), "unsupported type", fieldType->getBasicString(), "sampler types are not allowed in interface blocks");
2373 			recover();
2374 		}
2375 
2376 		const TQualifier qualifier = fieldType->getQualifier();
2377 		switch(qualifier)
2378 		{
2379 		case EvqGlobal:
2380 		case EvqUniform:
2381 			break;
2382 		default:
2383 			error(field->line(), "invalid qualifier on interface block member", getQualifierString(qualifier));
2384 			recover();
2385 			break;
2386 		}
2387 
2388 		// check layout qualifiers
2389 		TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier();
2390 		if(layoutLocationErrorCheck(field->line(), fieldLayoutQualifier))
2391 		{
2392 			recover();
2393 		}
2394 
2395 		if(fieldLayoutQualifier.blockStorage != EbsUnspecified)
2396 		{
2397 			error(field->line(), "invalid layout qualifier:", getBlockStorageString(fieldLayoutQualifier.blockStorage), "cannot be used here");
2398 			recover();
2399 		}
2400 
2401 		if(fieldLayoutQualifier.matrixPacking == EmpUnspecified)
2402 		{
2403 			fieldLayoutQualifier.matrixPacking = blockLayoutQualifier.matrixPacking;
2404 		}
2405 		else if(!fieldType->isMatrix() && (fieldType->getBasicType() != EbtStruct))
2406 		{
2407 			warning(field->line(), "extraneous layout qualifier:", getMatrixPackingString(fieldLayoutQualifier.matrixPacking), "only has an effect on matrix types");
2408 		}
2409 
2410 		fieldType->setLayoutQualifier(fieldLayoutQualifier);
2411 
2412 		// Recursively propagate the matrix packing setting down to all block/structure members
2413 		fieldType->setMatrixPackingIfUnspecified(fieldLayoutQualifier.matrixPacking);
2414 	}
2415 
2416 	// add array index
2417 	int arraySize = 0;
2418 	if(arrayIndex)
2419 	{
2420 		if(arraySizeErrorCheck(arrayIndexLine, arrayIndex, arraySize))
2421 			recover();
2422 	}
2423 
2424 	TInterfaceBlock* interfaceBlock = new TInterfaceBlock(&blockName, fieldList, instanceName, arraySize, blockLayoutQualifier);
2425 	TType interfaceBlockType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier, arraySize);
2426 
2427 	TString symbolName = "";
2428 	int symbolId = 0;
2429 
2430 	if(!instanceName)
2431 	{
2432 		// define symbols for the members of the interface block
2433 		for(const auto &field : *fieldList)
2434 		{
2435 			TType* fieldType = field->type();
2436 
2437 			// set parent pointer of the field variable
2438 			fieldType->setInterfaceBlock(interfaceBlock);
2439 
2440 			TVariable* fieldVariable = new TVariable(&field->name(), *fieldType);
2441 			fieldVariable->setQualifier(typeQualifier.qualifier);
2442 
2443 			if(!symbolTable.declare(fieldVariable)) {
2444 				error(field->line(), "redefinition", field->name().c_str(), "interface block member name");
2445 				recover();
2446 			}
2447 		}
2448 	}
2449 	else
2450 	{
2451 		if(reservedErrorCheck(nameLine, *instanceName))
2452 			recover();
2453 
2454 		// add a symbol for this interface block
2455 		TVariable* instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false);
2456 		instanceTypeDef->setQualifier(typeQualifier.qualifier);
2457 
2458 		if(!symbolTable.declare(instanceTypeDef)) {
2459 			error(instanceLine, "redefinition", instanceName->c_str(), "interface block instance name");
2460 			recover();
2461 		}
2462 
2463 		symbolId = instanceTypeDef->getUniqueId();
2464 		symbolName = instanceTypeDef->getName();
2465 	}
2466 
2467 	TIntermAggregate *aggregate = intermediate.makeAggregate(intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line), nameLine);
2468 	aggregate->setOp(EOpDeclaration);
2469 
2470 	exitStructDeclaration();
2471 	return aggregate;
2472 }
2473 
2474 //
2475 // Parse an array index expression
2476 //
addIndexExpression(TIntermTyped * baseExpression,const TSourceLoc & location,TIntermTyped * indexExpression)2477 TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc &location, TIntermTyped *indexExpression)
2478 {
2479 	TIntermTyped *indexedExpression = nullptr;
2480 
2481 	if(!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector())
2482 	{
2483 		if(baseExpression->getAsSymbolNode())
2484 		{
2485 			error(location, " left of '[' is not of type array, matrix, or vector ",
2486 				baseExpression->getAsSymbolNode()->getSymbol().c_str());
2487 		}
2488 		else
2489 		{
2490 			error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
2491 		}
2492 		recover();
2493 	}
2494 
2495 	TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion();
2496 
2497 	if(indexExpression->getQualifier() == EvqConstExpr && indexConstantUnion)   // TODO: Qualifier check redundant?
2498 	{
2499 		int index = indexConstantUnion->getIConst(0);
2500 		if(index < 0)
2501 		{
2502 			std::stringstream infoStream;
2503 			infoStream << index;
2504 			std::string info = infoStream.str();
2505 			error(location, "negative index", info.c_str());
2506 			recover();
2507 			index = 0;
2508 		}
2509 		if(baseExpression->getType().getQualifier() == EvqConstExpr && baseExpression->getAsConstantUnion())   // TODO: Qualifier check redundant?
2510 		{
2511 			if(baseExpression->isArray())
2512 			{
2513 				// constant folding for arrays
2514 				indexedExpression = addConstArrayNode(index, baseExpression, location);
2515 			}
2516 			else if(baseExpression->isVector())
2517 			{
2518 				// constant folding for vectors
2519 				TVectorFields fields;
2520 				fields.num = 1;
2521 				fields.offsets[0] = index; // need to do it this way because v.xy sends fields integer array
2522 				indexedExpression = addConstVectorNode(fields, baseExpression, location);
2523 			}
2524 			else if(baseExpression->isMatrix())
2525 			{
2526 				// constant folding for matrices
2527 				indexedExpression = addConstMatrixNode(index, baseExpression, location);
2528 			}
2529 		}
2530 		else
2531 		{
2532 			int safeIndex = -1;
2533 
2534 			if(baseExpression->isArray())
2535 			{
2536 				if(index >= baseExpression->getType().getArraySize())
2537 				{
2538 					std::stringstream extraInfoStream;
2539 					extraInfoStream << "array index out of range '" << index << "'";
2540 					std::string extraInfo = extraInfoStream.str();
2541 					error(location, "", "[", extraInfo.c_str());
2542 					recover();
2543 					safeIndex = baseExpression->getType().getArraySize() - 1;
2544 				}
2545 			}
2546 			else if((baseExpression->isVector() || baseExpression->isMatrix()) &&
2547 				baseExpression->getType().getNominalSize() <= index)
2548 			{
2549 				std::stringstream extraInfoStream;
2550 				extraInfoStream << "field selection out of range '" << index << "'";
2551 				std::string extraInfo = extraInfoStream.str();
2552 				error(location, "", "[", extraInfo.c_str());
2553 				recover();
2554 				safeIndex = baseExpression->getType().getNominalSize() - 1;
2555 			}
2556 
2557 			// Don't modify the data of the previous constant union, because it can point
2558 			// to builtins, like gl_MaxDrawBuffers. Instead use a new sanitized object.
2559 			if(safeIndex != -1)
2560 			{
2561 				ConstantUnion *safeConstantUnion = new ConstantUnion();
2562 				safeConstantUnion->setIConst(safeIndex);
2563 				indexConstantUnion->replaceConstantUnion(safeConstantUnion);
2564 			}
2565 
2566 			indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location);
2567 		}
2568 	}
2569 	else
2570 	{
2571 		if(baseExpression->isInterfaceBlock())
2572 		{
2573 			error(location, "",
2574 				"[", "array indexes for interface blocks arrays must be constant integral expressions");
2575 			recover();
2576 		}
2577 		else if(baseExpression->getQualifier() == EvqFragmentOut)
2578 		{
2579 			error(location, "", "[", "array indexes for fragment outputs must be constant integral expressions");
2580 			recover();
2581 		}
2582 
2583 		indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location);
2584 	}
2585 
2586 	if(indexedExpression == 0)
2587 	{
2588 		ConstantUnion *unionArray = new ConstantUnion[1];
2589 		unionArray->setFConst(0.0f);
2590 		indexedExpression = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConstExpr), location);
2591 	}
2592 	else if(baseExpression->isArray())
2593 	{
2594 		const TType &baseType = baseExpression->getType();
2595 		if(baseType.getStruct())
2596 		{
2597 			TType copyOfType(baseType.getStruct());
2598 			indexedExpression->setType(copyOfType);
2599 		}
2600 		else if(baseType.isInterfaceBlock())
2601 		{
2602 			TType copyOfType(baseType.getInterfaceBlock(), EvqTemporary, baseType.getLayoutQualifier(), 0);
2603 			indexedExpression->setType(copyOfType);
2604 		}
2605 		else
2606 		{
2607 			indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),
2608 				EvqTemporary, static_cast<unsigned char>(baseExpression->getNominalSize()),
2609 				static_cast<unsigned char>(baseExpression->getSecondarySize())));
2610 		}
2611 
2612 		if(baseExpression->getType().getQualifier() == EvqConstExpr)
2613 		{
2614 			indexedExpression->getTypePointer()->setQualifier(EvqConstExpr);
2615 		}
2616 	}
2617 	else if(baseExpression->isMatrix())
2618 	{
2619 		TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConstExpr ? EvqConstExpr : EvqTemporary;
2620 		indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),
2621 			qualifier, static_cast<unsigned char>(baseExpression->getSecondarySize())));
2622 	}
2623 	else if(baseExpression->isVector())
2624 	{
2625 		TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConstExpr ? EvqConstExpr : EvqTemporary;
2626 		indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier));
2627 	}
2628 	else
2629 	{
2630 		indexedExpression->setType(baseExpression->getType());
2631 	}
2632 
2633 	return indexedExpression;
2634 }
2635 
addFieldSelectionExpression(TIntermTyped * baseExpression,const TSourceLoc & dotLocation,const TString & fieldString,const TSourceLoc & fieldLocation)2636 TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc &dotLocation,
2637 	const TString &fieldString, const TSourceLoc &fieldLocation)
2638 {
2639 	TIntermTyped *indexedExpression = nullptr;
2640 
2641 	if(baseExpression->isArray())
2642 	{
2643 		error(fieldLocation, "cannot apply dot operator to an array", ".");
2644 		recover();
2645 	}
2646 
2647 	if(baseExpression->isVector())
2648 	{
2649 		TVectorFields fields;
2650 		if(!parseVectorFields(fieldString, baseExpression->getNominalSize(), fields, fieldLocation))
2651 		{
2652 			fields.num = 1;
2653 			fields.offsets[0] = 0;
2654 			recover();
2655 		}
2656 
2657 		if(baseExpression->getAsConstantUnion())
2658 		{
2659 			// constant folding for vector fields
2660 			indexedExpression = addConstVectorNode(fields, baseExpression, fieldLocation);
2661 			if(indexedExpression == 0)
2662 			{
2663 				recover();
2664 				indexedExpression = baseExpression;
2665 			}
2666 		}
2667 		else
2668 		{
2669 			TString vectorString = fieldString;
2670 			TIntermTyped *index = intermediate.addSwizzle(fields, fieldLocation);
2671 			indexedExpression = intermediate.addIndex(EOpVectorSwizzle, baseExpression, index, dotLocation);
2672 			indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),
2673 				baseExpression->getQualifier() == EvqConstExpr ? EvqConstExpr : EvqTemporary, (unsigned char)vectorString.size()));
2674 		}
2675 	}
2676 	else if(baseExpression->getBasicType() == EbtStruct)
2677 	{
2678 		bool fieldFound = false;
2679 		const TFieldList &fields = baseExpression->getType().getStruct()->fields();
2680 		if(fields.empty())
2681 		{
2682 			error(dotLocation, "structure has no fields", "Internal Error");
2683 			recover();
2684 			indexedExpression = baseExpression;
2685 		}
2686 		else
2687 		{
2688 			unsigned int i;
2689 			for(i = 0; i < fields.size(); ++i)
2690 			{
2691 				if(fields[i]->name() == fieldString)
2692 				{
2693 					fieldFound = true;
2694 					break;
2695 				}
2696 			}
2697 			if(fieldFound)
2698 			{
2699 				if(baseExpression->getType().getQualifier() == EvqConstExpr)
2700 				{
2701 					indexedExpression = addConstStruct(fieldString, baseExpression, dotLocation);
2702 					if(indexedExpression == 0)
2703 					{
2704 						recover();
2705 						indexedExpression = baseExpression;
2706 					}
2707 					else
2708 					{
2709 						indexedExpression->setType(*fields[i]->type());
2710 						// change the qualifier of the return type, not of the structure field
2711 						// as the structure definition is shared between various structures.
2712 						indexedExpression->getTypePointer()->setQualifier(EvqConstExpr);
2713 					}
2714 				}
2715 				else
2716 				{
2717 					TIntermTyped *index = TIntermTyped::CreateIndexNode(i);
2718 					index->setLine(fieldLocation);
2719 					indexedExpression = intermediate.addIndex(EOpIndexDirectStruct, baseExpression, index, dotLocation);
2720 					indexedExpression->setType(*fields[i]->type());
2721 				}
2722 			}
2723 			else
2724 			{
2725 				error(dotLocation, " no such field in structure", fieldString.c_str());
2726 				recover();
2727 				indexedExpression = baseExpression;
2728 			}
2729 		}
2730 	}
2731 	else if(baseExpression->isInterfaceBlock())
2732 	{
2733 		bool fieldFound = false;
2734 		const TFieldList &fields = baseExpression->getType().getInterfaceBlock()->fields();
2735 		if(fields.empty())
2736 		{
2737 			error(dotLocation, "interface block has no fields", "Internal Error");
2738 			recover();
2739 			indexedExpression = baseExpression;
2740 		}
2741 		else
2742 		{
2743 			unsigned int i;
2744 			for(i = 0; i < fields.size(); ++i)
2745 			{
2746 				if(fields[i]->name() == fieldString)
2747 				{
2748 					fieldFound = true;
2749 					break;
2750 				}
2751 			}
2752 			if(fieldFound)
2753 			{
2754 				ConstantUnion *unionArray = new ConstantUnion[1];
2755 				unionArray->setIConst(i);
2756 				TIntermTyped *index = intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation);
2757 				indexedExpression = intermediate.addIndex(EOpIndexDirectInterfaceBlock, baseExpression, index,
2758 					dotLocation);
2759 				indexedExpression->setType(*fields[i]->type());
2760 			}
2761 			else
2762 			{
2763 				error(dotLocation, " no such field in interface block", fieldString.c_str());
2764 				recover();
2765 				indexedExpression = baseExpression;
2766 			}
2767 		}
2768 	}
2769 	else
2770 	{
2771 		if(mShaderVersion < 300)
2772 		{
2773 			error(dotLocation, " field selection requires structure or vector on left hand side",
2774 				fieldString.c_str());
2775 		}
2776 		else
2777 		{
2778 			error(dotLocation,
2779 				" field selection requires structure, vector, or interface block on left hand side",
2780 				fieldString.c_str());
2781 		}
2782 		recover();
2783 		indexedExpression = baseExpression;
2784 	}
2785 
2786 	return indexedExpression;
2787 }
2788 
parseLayoutQualifier(const TString & qualifierType,const TSourceLoc & qualifierTypeLine)2789 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine)
2790 {
2791 	TLayoutQualifier qualifier;
2792 
2793 	qualifier.location = -1;
2794 	qualifier.matrixPacking = EmpUnspecified;
2795 	qualifier.blockStorage = EbsUnspecified;
2796 
2797 	if(qualifierType == "shared")
2798 	{
2799 		qualifier.blockStorage = EbsShared;
2800 	}
2801 	else if(qualifierType == "packed")
2802 	{
2803 		qualifier.blockStorage = EbsPacked;
2804 	}
2805 	else if(qualifierType == "std140")
2806 	{
2807 		qualifier.blockStorage = EbsStd140;
2808 	}
2809 	else if(qualifierType == "row_major")
2810 	{
2811 		qualifier.matrixPacking = EmpRowMajor;
2812 	}
2813 	else if(qualifierType == "column_major")
2814 	{
2815 		qualifier.matrixPacking = EmpColumnMajor;
2816 	}
2817 	else if(qualifierType == "location")
2818 	{
2819 		error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "location requires an argument");
2820 		recover();
2821 	}
2822 	else
2823 	{
2824 		error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
2825 		recover();
2826 	}
2827 
2828 	return qualifier;
2829 }
2830 
parseLayoutQualifier(const TString & qualifierType,const TSourceLoc & qualifierTypeLine,const TString & intValueString,int intValue,const TSourceLoc & intValueLine)2831 TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine)
2832 {
2833 	TLayoutQualifier qualifier;
2834 
2835 	qualifier.location = -1;  // -1 isn't a valid location, it means the value isn't set. Negative values are checked lower in this function.
2836 	qualifier.matrixPacking = EmpUnspecified;
2837 	qualifier.blockStorage = EbsUnspecified;
2838 
2839 	if (qualifierType != "location")
2840 	{
2841 		error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "only location may have arguments");
2842 		recover();
2843 	}
2844 	else
2845 	{
2846 		// must check that location is non-negative
2847 		if (intValue < 0)
2848 		{
2849 			error(intValueLine, "out of range:", intValueString.c_str(), "location must be non-negative");
2850 			recover();
2851 		}
2852 		else
2853 		{
2854 			qualifier.location = intValue;
2855 		}
2856 	}
2857 
2858 	return qualifier;
2859 }
2860 
joinLayoutQualifiers(TLayoutQualifier leftQualifier,TLayoutQualifier rightQualifier)2861 TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier)
2862 {
2863 	TLayoutQualifier joinedQualifier = leftQualifier;
2864 
2865 	if (rightQualifier.location != -1)
2866 	{
2867 		joinedQualifier.location = rightQualifier.location;
2868 	}
2869 	if(rightQualifier.matrixPacking != EmpUnspecified)
2870 	{
2871 		joinedQualifier.matrixPacking = rightQualifier.matrixPacking;
2872 	}
2873 	if(rightQualifier.blockStorage != EbsUnspecified)
2874 	{
2875 		joinedQualifier.blockStorage = rightQualifier.blockStorage;
2876 	}
2877 
2878 	return joinedQualifier;
2879 }
2880 
2881 
joinInterpolationQualifiers(const TSourceLoc & interpolationLoc,TQualifier interpolationQualifier,const TSourceLoc & storageLoc,TQualifier storageQualifier)2882 TPublicType TParseContext::joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier,
2883 	const TSourceLoc &storageLoc, TQualifier storageQualifier)
2884 {
2885 	TQualifier mergedQualifier = EvqSmoothIn;
2886 
2887 	if(storageQualifier == EvqFragmentIn) {
2888 		if(interpolationQualifier == EvqSmooth)
2889 			mergedQualifier = EvqSmoothIn;
2890 		else if(interpolationQualifier == EvqFlat)
2891 			mergedQualifier = EvqFlatIn;
2892 		else UNREACHABLE(interpolationQualifier);
2893 	}
2894 	else if(storageQualifier == EvqCentroidIn) {
2895 		if(interpolationQualifier == EvqSmooth)
2896 			mergedQualifier = EvqCentroidIn;
2897 		else if(interpolationQualifier == EvqFlat)
2898 			mergedQualifier = EvqFlatIn;
2899 		else UNREACHABLE(interpolationQualifier);
2900 	}
2901 	else if(storageQualifier == EvqVertexOut) {
2902 		if(interpolationQualifier == EvqSmooth)
2903 			mergedQualifier = EvqSmoothOut;
2904 		else if(interpolationQualifier == EvqFlat)
2905 			mergedQualifier = EvqFlatOut;
2906 		else UNREACHABLE(interpolationQualifier);
2907 	}
2908 	else if(storageQualifier == EvqCentroidOut) {
2909 		if(interpolationQualifier == EvqSmooth)
2910 			mergedQualifier = EvqCentroidOut;
2911 		else if(interpolationQualifier == EvqFlat)
2912 			mergedQualifier = EvqFlatOut;
2913 		else UNREACHABLE(interpolationQualifier);
2914 	}
2915 	else {
2916 		error(interpolationLoc, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getQualifierString(interpolationQualifier));
2917 		recover();
2918 
2919 		mergedQualifier = storageQualifier;
2920 	}
2921 
2922 	TPublicType type;
2923 	type.setBasic(EbtVoid, mergedQualifier, storageLoc);
2924 	return type;
2925 }
2926 
addStructDeclaratorList(const TPublicType & typeSpecifier,TFieldList * fieldList)2927 TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList)
2928 {
2929 	if(voidErrorCheck(typeSpecifier.line, (*fieldList)[0]->name(), typeSpecifier.type))
2930 	{
2931 		recover();
2932 	}
2933 
2934 	for(const auto &field : *fieldList)
2935 	{
2936 		//
2937 		// Careful not to replace already known aspects of type, like array-ness
2938 		//
2939 		TType *type = field->type();
2940 		type->setBasicType(typeSpecifier.type);
2941 		type->setNominalSize(typeSpecifier.primarySize);
2942 		type->setSecondarySize(typeSpecifier.secondarySize);
2943 		type->setPrecision(typeSpecifier.precision);
2944 		type->setQualifier(typeSpecifier.qualifier);
2945 		type->setLayoutQualifier(typeSpecifier.layoutQualifier);
2946 
2947 		// don't allow arrays of arrays
2948 		if(type->isArray())
2949 		{
2950 			if(arrayTypeErrorCheck(typeSpecifier.line, typeSpecifier))
2951 				recover();
2952 		}
2953 		if(typeSpecifier.array)
2954 			type->setArraySize(typeSpecifier.arraySize);
2955 		if(typeSpecifier.userDef)
2956 		{
2957 			type->setStruct(typeSpecifier.userDef->getStruct());
2958 		}
2959 
2960 		if(structNestingErrorCheck(typeSpecifier.line, *field))
2961 		{
2962 			recover();
2963 		}
2964 	}
2965 
2966 	return fieldList;
2967 }
2968 
addStructure(const TSourceLoc & structLine,const TSourceLoc & nameLine,const TString * structName,TFieldList * fieldList)2969 TPublicType TParseContext::addStructure(const TSourceLoc &structLine, const TSourceLoc &nameLine,
2970 	const TString *structName, TFieldList *fieldList)
2971 {
2972 	TStructure *structure = new TStructure(structName, fieldList);
2973 	TType *structureType = new TType(structure);
2974 
2975 	// Store a bool in the struct if we're at global scope, to allow us to
2976 	// skip the local struct scoping workaround in HLSL.
2977 	structure->setUniqueId(TSymbolTableLevel::nextUniqueId());
2978 	structure->setAtGlobalScope(symbolTable.atGlobalLevel());
2979 
2980 	if(!structName->empty())
2981 	{
2982 		if(reservedErrorCheck(nameLine, *structName))
2983 		{
2984 			recover();
2985 		}
2986 		TVariable *userTypeDef = new TVariable(structName, *structureType, true);
2987 		if(!symbolTable.declare(userTypeDef))
2988 		{
2989 			error(nameLine, "redefinition", structName->c_str(), "struct");
2990 			recover();
2991 		}
2992 	}
2993 
2994 	// ensure we do not specify any storage qualifiers on the struct members
2995 	for(const auto &field : *fieldList)
2996 	{
2997 		const TQualifier qualifier = field->type()->getQualifier();
2998 		switch(qualifier)
2999 		{
3000 		case EvqGlobal:
3001 		case EvqTemporary:
3002 			break;
3003 		default:
3004 			error(field->line(), "invalid qualifier on struct member", getQualifierString(qualifier));
3005 			recover();
3006 			break;
3007 		}
3008 	}
3009 
3010 	TPublicType publicType;
3011 	publicType.setBasic(EbtStruct, EvqTemporary, structLine);
3012 	publicType.userDef = structureType;
3013 	exitStructDeclaration();
3014 
3015 	return publicType;
3016 }
3017 
enterStructDeclaration(const TSourceLoc & line,const TString & identifier)3018 bool TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString& identifier)
3019 {
3020 	++mStructNestingLevel;
3021 
3022 	// Embedded structure definitions are not supported per GLSL ES spec.
3023 	// They aren't allowed in GLSL either, but we need to detect this here
3024 	// so we don't rely on the GLSL compiler to catch it.
3025 	if (mStructNestingLevel > 1) {
3026 		error(line, "", "Embedded struct definitions are not allowed");
3027 		return true;
3028 	}
3029 
3030 	return false;
3031 }
3032 
exitStructDeclaration()3033 void TParseContext::exitStructDeclaration()
3034 {
3035 	--mStructNestingLevel;
3036 }
3037 
structNestingErrorCheck(const TSourceLoc & line,const TField & field)3038 bool TParseContext::structNestingErrorCheck(const TSourceLoc &line, const TField &field)
3039 {
3040 	static const int kWebGLMaxStructNesting = 4;
3041 
3042 	if(field.type()->getBasicType() != EbtStruct)
3043 	{
3044 		return false;
3045 	}
3046 
3047 	// We're already inside a structure definition at this point, so add
3048 	// one to the field's struct nesting.
3049 	if(1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting)
3050 	{
3051 		std::stringstream reasonStream;
3052 		reasonStream << "Reference of struct type "
3053 			<< field.type()->getStruct()->name().c_str()
3054 			<< " exceeds maximum allowed nesting level of "
3055 			<< kWebGLMaxStructNesting;
3056 		std::string reason = reasonStream.str();
3057 		error(line, reason.c_str(), field.name().c_str(), "");
3058 		return true;
3059 	}
3060 
3061 	return false;
3062 }
3063 
createUnaryMath(TOperator op,TIntermTyped * child,const TSourceLoc & loc,const TType * funcReturnType)3064 TIntermTyped *TParseContext::createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc, const TType *funcReturnType)
3065 {
3066 	if(child == nullptr)
3067 	{
3068 		return nullptr;
3069 	}
3070 
3071 	switch(op)
3072 	{
3073 	case EOpLogicalNot:
3074 		if(child->getBasicType() != EbtBool ||
3075 			child->isMatrix() ||
3076 			child->isArray() ||
3077 			child->isVector())
3078 		{
3079 			return nullptr;
3080 		}
3081 		break;
3082 	case EOpBitwiseNot:
3083 		if((child->getBasicType() != EbtInt && child->getBasicType() != EbtUInt) ||
3084 			child->isMatrix() ||
3085 			child->isArray())
3086 		{
3087 			return nullptr;
3088 		}
3089 		break;
3090 	case EOpPostIncrement:
3091 	case EOpPreIncrement:
3092 	case EOpPostDecrement:
3093 	case EOpPreDecrement:
3094 	case EOpNegative:
3095 		if(child->getBasicType() == EbtStruct ||
3096 			child->getBasicType() == EbtBool ||
3097 			child->isArray())
3098 		{
3099 			return nullptr;
3100 		}
3101 		// Operators for built-ins are already type checked against their prototype.
3102 	default:
3103 		break;
3104 	}
3105 
3106 	return intermediate.addUnaryMath(op, child, loc, funcReturnType);
3107 }
3108 
addUnaryMath(TOperator op,TIntermTyped * child,const TSourceLoc & loc)3109 TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
3110 {
3111 	TIntermTyped *node = createUnaryMath(op, child, loc, nullptr);
3112 	if(node == nullptr)
3113 	{
3114 		unaryOpError(loc, getOperatorString(op), child->getCompleteString());
3115 		recover();
3116 		return child;
3117 	}
3118 	return node;
3119 }
3120 
addUnaryMathLValue(TOperator op,TIntermTyped * child,const TSourceLoc & loc)3121 TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
3122 {
3123 	if(lValueErrorCheck(loc, getOperatorString(op), child))
3124 		recover();
3125 	return addUnaryMath(op, child, loc);
3126 }
3127 
binaryOpCommonCheck(TOperator op,TIntermTyped * left,TIntermTyped * right,const TSourceLoc & loc)3128 bool TParseContext::binaryOpCommonCheck(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc)
3129 {
3130 	if(left->isArray() || right->isArray())
3131 	{
3132 		if(mShaderVersion < 300)
3133 		{
3134 			error(loc, "Invalid operation for arrays", getOperatorString(op));
3135 			return false;
3136 		}
3137 
3138 		if(left->isArray() != right->isArray())
3139 		{
3140 			error(loc, "array / non-array mismatch", getOperatorString(op));
3141 			return false;
3142 		}
3143 
3144 		switch(op)
3145 		{
3146 		case EOpEqual:
3147 		case EOpNotEqual:
3148 		case EOpAssign:
3149 		case EOpInitialize:
3150 			break;
3151 		default:
3152 			error(loc, "Invalid operation for arrays", getOperatorString(op));
3153 			return false;
3154 		}
3155 		// At this point, size of implicitly sized arrays should be resolved.
3156 		if(left->getArraySize() != right->getArraySize())
3157 		{
3158 			error(loc, "array size mismatch", getOperatorString(op));
3159 			return false;
3160 		}
3161 	}
3162 
3163 	// Check ops which require integer / ivec parameters
3164 	bool isBitShift = false;
3165 	switch(op)
3166 	{
3167 	case EOpBitShiftLeft:
3168 	case EOpBitShiftRight:
3169 	case EOpBitShiftLeftAssign:
3170 	case EOpBitShiftRightAssign:
3171 		// Unsigned can be bit-shifted by signed and vice versa, but we need to
3172 		// check that the basic type is an integer type.
3173 		isBitShift = true;
3174 		if(!IsInteger(left->getBasicType()) || !IsInteger(right->getBasicType()))
3175 		{
3176 			return false;
3177 		}
3178 		break;
3179 	case EOpBitwiseAnd:
3180 	case EOpBitwiseXor:
3181 	case EOpBitwiseOr:
3182 	case EOpBitwiseAndAssign:
3183 	case EOpBitwiseXorAssign:
3184 	case EOpBitwiseOrAssign:
3185 		// It is enough to check the type of only one operand, since later it
3186 		// is checked that the operand types match.
3187 		if(!IsInteger(left->getBasicType()))
3188 		{
3189 			return false;
3190 		}
3191 		break;
3192 	default:
3193 		break;
3194 	}
3195 
3196 	// GLSL ES 1.00 and 3.00 do not support implicit type casting.
3197 	// So the basic type should usually match.
3198 	if(!isBitShift && left->getBasicType() != right->getBasicType())
3199 	{
3200 		return false;
3201 	}
3202 
3203 	// Check that type sizes match exactly on ops that require that.
3204 	// Also check restrictions for structs that contain arrays or samplers.
3205 	switch(op)
3206 	{
3207 	case EOpAssign:
3208 	case EOpInitialize:
3209 	case EOpEqual:
3210 	case EOpNotEqual:
3211 		// ESSL 1.00 sections 5.7, 5.8, 5.9
3212 		if(mShaderVersion < 300 && left->getType().isStructureContainingArrays())
3213 		{
3214 			error(loc, "undefined operation for structs containing arrays", getOperatorString(op));
3215 			return false;
3216 		}
3217 		// Samplers as l-values are disallowed also in ESSL 3.00, see section 4.1.7,
3218 		// we interpret the spec so that this extends to structs containing samplers,
3219 		// similarly to ESSL 1.00 spec.
3220 		if((mShaderVersion < 300 || op == EOpAssign || op == EOpInitialize) &&
3221 			left->getType().isStructureContainingSamplers())
3222 		{
3223 			error(loc, "undefined operation for structs containing samplers", getOperatorString(op));
3224 			return false;
3225 		}
3226 	case EOpLessThan:
3227 	case EOpGreaterThan:
3228 	case EOpLessThanEqual:
3229 	case EOpGreaterThanEqual:
3230 		if((left->getNominalSize() != right->getNominalSize()) ||
3231 			(left->getSecondarySize() != right->getSecondarySize()))
3232 		{
3233 			return false;
3234 		}
3235 		break;
3236 	case EOpAdd:
3237 	case EOpSub:
3238 	case EOpDiv:
3239 	case EOpIMod:
3240 	case EOpBitShiftLeft:
3241 	case EOpBitShiftRight:
3242 	case EOpBitwiseAnd:
3243 	case EOpBitwiseXor:
3244 	case EOpBitwiseOr:
3245 	case EOpAddAssign:
3246 	case EOpSubAssign:
3247 	case EOpDivAssign:
3248 	case EOpIModAssign:
3249 	case EOpBitShiftLeftAssign:
3250 	case EOpBitShiftRightAssign:
3251 	case EOpBitwiseAndAssign:
3252 	case EOpBitwiseXorAssign:
3253 	case EOpBitwiseOrAssign:
3254 		if((left->isMatrix() && right->isVector()) || (left->isVector() && right->isMatrix()))
3255 		{
3256 			return false;
3257 		}
3258 
3259 		// Are the sizes compatible?
3260 		if(left->getNominalSize() != right->getNominalSize() || left->getSecondarySize() != right->getSecondarySize())
3261 		{
3262 			// If the nominal sizes of operands do not match:
3263 			// One of them must be a scalar.
3264 			if(!left->isScalar() && !right->isScalar())
3265 				return false;
3266 
3267 			// In the case of compound assignment other than multiply-assign,
3268 			// the right side needs to be a scalar. Otherwise a vector/matrix
3269 			// would be assigned to a scalar. A scalar can't be shifted by a
3270 			// vector either.
3271 			if(!right->isScalar() && (IsAssignment(op) || op == EOpBitShiftLeft || op == EOpBitShiftRight))
3272 				return false;
3273 		}
3274 		break;
3275 	default:
3276 		break;
3277 	}
3278 
3279 	return true;
3280 }
3281 
addSwitch(TIntermTyped * init,TIntermAggregate * statementList,const TSourceLoc & loc)3282 TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &loc)
3283 {
3284 	TBasicType switchType = init->getBasicType();
3285 	if((switchType != EbtInt && switchType != EbtUInt) ||
3286 	   init->isMatrix() ||
3287 	   init->isArray() ||
3288 	   init->isVector())
3289 	{
3290 		error(init->getLine(), "init-expression in a switch statement must be a scalar integer", "switch");
3291 		recover();
3292 		return nullptr;
3293 	}
3294 
3295 	if(statementList)
3296 	{
3297 		if(!ValidateSwitch::validate(switchType, this, statementList, loc))
3298 		{
3299 			recover();
3300 			return nullptr;
3301 		}
3302 	}
3303 
3304 	TIntermSwitch *node = intermediate.addSwitch(init, statementList, loc);
3305 	if(node == nullptr)
3306 	{
3307 		error(loc, "erroneous switch statement", "switch");
3308 		recover();
3309 		return nullptr;
3310 	}
3311 	return node;
3312 }
3313 
addCase(TIntermTyped * condition,const TSourceLoc & loc)3314 TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &loc)
3315 {
3316 	if(mSwitchNestingLevel == 0)
3317 	{
3318 		error(loc, "case labels need to be inside switch statements", "case");
3319 		recover();
3320 		return nullptr;
3321 	}
3322 	if(condition == nullptr)
3323 	{
3324 		error(loc, "case label must have a condition", "case");
3325 		recover();
3326 		return nullptr;
3327 	}
3328 	if((condition->getBasicType() != EbtInt && condition->getBasicType() != EbtUInt) ||
3329 	   condition->isMatrix() ||
3330 	   condition->isArray() ||
3331 	   condition->isVector())
3332 	{
3333 		error(condition->getLine(), "case label must be a scalar integer", "case");
3334 		recover();
3335 	}
3336 	TIntermConstantUnion *conditionConst = condition->getAsConstantUnion();
3337 	if(conditionConst == nullptr)
3338 	{
3339 		error(condition->getLine(), "case label must be constant", "case");
3340 		recover();
3341 	}
3342 	TIntermCase *node = intermediate.addCase(condition, loc);
3343 	if(node == nullptr)
3344 	{
3345 		error(loc, "erroneous case statement", "case");
3346 		recover();
3347 		return nullptr;
3348 	}
3349 	return node;
3350 }
3351 
addDefault(const TSourceLoc & loc)3352 TIntermCase *TParseContext::addDefault(const TSourceLoc &loc)
3353 {
3354 	if(mSwitchNestingLevel == 0)
3355 	{
3356 		error(loc, "default labels need to be inside switch statements", "default");
3357 		recover();
3358 		return nullptr;
3359 	}
3360 	TIntermCase *node = intermediate.addCase(nullptr, loc);
3361 	if(node == nullptr)
3362 	{
3363 		error(loc, "erroneous default statement", "default");
3364 		recover();
3365 		return nullptr;
3366 	}
3367 	return node;
3368 }
createAssign(TOperator op,TIntermTyped * left,TIntermTyped * right,const TSourceLoc & loc)3369 TIntermTyped *TParseContext::createAssign(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc)
3370 {
3371 	if(binaryOpCommonCheck(op, left, right, loc))
3372 	{
3373 		return intermediate.addAssign(op, left, right, loc);
3374 	}
3375 	return nullptr;
3376 }
3377 
addAssign(TOperator op,TIntermTyped * left,TIntermTyped * right,const TSourceLoc & loc)3378 TIntermTyped *TParseContext::addAssign(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc)
3379 {
3380 	TIntermTyped *node = createAssign(op, left, right, loc);
3381 	if(node == nullptr)
3382 	{
3383 		assignError(loc, "assign", left->getCompleteString(), right->getCompleteString());
3384 		recover();
3385 		return left;
3386 	}
3387 	return node;
3388 }
3389 
addBinaryMathInternal(TOperator op,TIntermTyped * left,TIntermTyped * right,const TSourceLoc & loc)3390 TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, TIntermTyped *left, TIntermTyped *right,
3391 	const TSourceLoc &loc)
3392 {
3393 	if(!binaryOpCommonCheck(op, left, right, loc))
3394 		return nullptr;
3395 
3396 	switch(op)
3397 	{
3398 	case EOpEqual:
3399 	case EOpNotEqual:
3400 		break;
3401 	case EOpLessThan:
3402 	case EOpGreaterThan:
3403 	case EOpLessThanEqual:
3404 	case EOpGreaterThanEqual:
3405 		ASSERT(!left->isArray() && !right->isArray());
3406 		if(left->isMatrix() || left->isVector() ||
3407 			left->getBasicType() == EbtStruct)
3408 		{
3409 			return nullptr;
3410 		}
3411 		break;
3412 	case EOpLogicalOr:
3413 	case EOpLogicalXor:
3414 	case EOpLogicalAnd:
3415 		ASSERT(!left->isArray() && !right->isArray());
3416 		if(left->getBasicType() != EbtBool ||
3417 			left->isMatrix() || left->isVector())
3418 		{
3419 			return nullptr;
3420 		}
3421 		break;
3422 	case EOpAdd:
3423 	case EOpSub:
3424 	case EOpDiv:
3425 	case EOpMul:
3426 		ASSERT(!left->isArray() && !right->isArray());
3427 		if(left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool)
3428 		{
3429 			return nullptr;
3430 		}
3431 		break;
3432 	case EOpIMod:
3433 		ASSERT(!left->isArray() && !right->isArray());
3434 		// Note that this is only for the % operator, not for mod()
3435 		if(left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat)
3436 		{
3437 			return nullptr;
3438 		}
3439 		break;
3440 		// Note that for bitwise ops, type checking is done in promote() to
3441 		// share code between ops and compound assignment
3442 	default:
3443 		break;
3444 	}
3445 
3446 	return intermediate.addBinaryMath(op, left, right, loc);
3447 }
3448 
addBinaryMath(TOperator op,TIntermTyped * left,TIntermTyped * right,const TSourceLoc & loc)3449 TIntermTyped *TParseContext::addBinaryMath(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc)
3450 {
3451 	TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
3452 	if(node == 0)
3453 	{
3454 		binaryOpError(loc, getOperatorString(op), left->getCompleteString(), right->getCompleteString());
3455 		recover();
3456 		return left;
3457 	}
3458 	return node;
3459 }
3460 
addBinaryMathBooleanResult(TOperator op,TIntermTyped * left,TIntermTyped * right,const TSourceLoc & loc)3461 TIntermTyped *TParseContext::addBinaryMathBooleanResult(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc)
3462 {
3463 	TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
3464 	if(node == 0)
3465 	{
3466 		binaryOpError(loc, getOperatorString(op), left->getCompleteString(), right->getCompleteString());
3467 		recover();
3468 		ConstantUnion *unionArray = new ConstantUnion[1];
3469 		unionArray->setBConst(false);
3470 		return intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConstExpr), loc);
3471 	}
3472 	return node;
3473 }
3474 
addBranch(TOperator op,const TSourceLoc & loc)3475 TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc)
3476 {
3477 	switch(op)
3478 	{
3479 	case EOpContinue:
3480 		if(mLoopNestingLevel <= 0)
3481 		{
3482 			error(loc, "continue statement only allowed in loops", "");
3483 			recover();
3484 		}
3485 		break;
3486 	case EOpBreak:
3487 		if(mLoopNestingLevel <= 0 && mSwitchNestingLevel <= 0)
3488 		{
3489 			error(loc, "break statement only allowed in loops and switch statements", "");
3490 			recover();
3491 		}
3492 		break;
3493 	case EOpReturn:
3494 		if(mCurrentFunctionType->getBasicType() != EbtVoid)
3495 		{
3496 			error(loc, "non-void function must return a value", "return");
3497 			recover();
3498 		}
3499 		break;
3500 	default:
3501 		// No checks for discard
3502 		break;
3503 	}
3504 	return intermediate.addBranch(op, loc);
3505 }
3506 
addBranch(TOperator op,TIntermTyped * returnValue,const TSourceLoc & loc)3507 TIntermBranch *TParseContext::addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc)
3508 {
3509 	ASSERT(op == EOpReturn);
3510 	mFunctionReturnsValue = true;
3511 	if(mCurrentFunctionType->getBasicType() == EbtVoid)
3512 	{
3513 		error(loc, "void function cannot return a value", "return");
3514 		recover();
3515 	}
3516 	else if(*mCurrentFunctionType != returnValue->getType())
3517 	{
3518 		error(loc, "function return is not matching type:", "return");
3519 		recover();
3520 	}
3521 	return intermediate.addBranch(op, returnValue, loc);
3522 }
3523 
addFunctionCallOrMethod(TFunction * fnCall,TIntermNode * paramNode,TIntermNode * thisNode,const TSourceLoc & loc,bool * fatalError)3524 TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, TIntermNode *paramNode, TIntermNode *thisNode, const TSourceLoc &loc, bool *fatalError)
3525 {
3526 	*fatalError = false;
3527 	TOperator op = fnCall->getBuiltInOp();
3528 	TIntermTyped *callNode = nullptr;
3529 
3530 	if(thisNode != nullptr)
3531 	{
3532 		ConstantUnion *unionArray = new ConstantUnion[1];
3533 		int arraySize = 0;
3534 		TIntermTyped *typedThis = thisNode->getAsTyped();
3535 		if(fnCall->getName() != "length")
3536 		{
3537 			error(loc, "invalid method", fnCall->getName().c_str());
3538 			recover();
3539 		}
3540 		else if(paramNode != nullptr)
3541 		{
3542 			error(loc, "method takes no parameters", "length");
3543 			recover();
3544 		}
3545 		else if(typedThis == nullptr || !typedThis->isArray())
3546 		{
3547 			error(loc, "length can only be called on arrays", "length");
3548 			recover();
3549 		}
3550 		else
3551 		{
3552 			arraySize = typedThis->getArraySize();
3553 		}
3554 		unionArray->setIConst(arraySize);
3555 		callNode = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConstExpr), loc);
3556 	}
3557 	else if(op != EOpNull)
3558 	{
3559 		//
3560 		// Then this should be a constructor.
3561 		// Don't go through the symbol table for constructors.
3562 		// Their parameters will be verified algorithmically.
3563 		//
3564 		TType type(EbtVoid, EbpUndefined);  // use this to get the type back
3565 		if(!constructorErrorCheck(loc, paramNode, *fnCall, op, &type))
3566 		{
3567 			//
3568 			// It's a constructor, of type 'type'.
3569 			//
3570 			callNode = addConstructor(paramNode, &type, op, fnCall, loc);
3571 		}
3572 
3573 		if(callNode == nullptr)
3574 		{
3575 			recover();
3576 			callNode = intermediate.setAggregateOperator(nullptr, op, loc);
3577 		}
3578 	}
3579 	else
3580 	{
3581 		//
3582 		// Not a constructor.  Find it in the symbol table.
3583 		//
3584 		const TFunction *fnCandidate;
3585 		bool builtIn;
3586 		fnCandidate = findFunction(loc, fnCall, &builtIn);
3587 		if(fnCandidate)
3588 		{
3589 			//
3590 			// A declared function.
3591 			//
3592 			if(builtIn && !fnCandidate->getExtension().empty() &&
3593 				extensionErrorCheck(loc, fnCandidate->getExtension()))
3594 			{
3595 				recover();
3596 			}
3597 			op = fnCandidate->getBuiltInOp();
3598 			if(builtIn && op != EOpNull)
3599 			{
3600 				//
3601 				// A function call mapped to a built-in operation.
3602 				//
3603 				if(fnCandidate->getParamCount() == 1)
3604 				{
3605 					//
3606 					// Treat it like a built-in unary operator.
3607 					//
3608 					TIntermNode *operand = paramNode->getAsAggregate()->getSequence()[0];
3609 					callNode = createUnaryMath(op, operand->getAsTyped(), loc, &fnCandidate->getReturnType());
3610 
3611 					if(callNode == nullptr)
3612 					{
3613 						std::stringstream extraInfoStream;
3614 						extraInfoStream << "built in unary operator function.  Type: "
3615 							<< static_cast<TIntermTyped*>(paramNode)->getCompleteString();
3616 						std::string extraInfo = extraInfoStream.str();
3617 						error(paramNode->getLine(), " wrong operand type", "Internal Error", extraInfo.c_str());
3618 						*fatalError = true;
3619 						return nullptr;
3620 					}
3621 				}
3622 				else
3623 				{
3624 					TIntermAggregate *aggregate = intermediate.setAggregateOperator(paramNode, op, loc);
3625 					aggregate->setType(fnCandidate->getReturnType());
3626 
3627 					// Some built-in functions have out parameters too.
3628 					functionCallLValueErrorCheck(fnCandidate, aggregate);
3629 
3630 					callNode = aggregate;
3631 
3632 					if(op == EOpClamp)
3633 					{
3634 						// Special case for clamp -- try to fold it as min(max(t, minVal), maxVal)
3635 						TIntermSequence &parameters = paramNode->getAsAggregate()->getSequence();
3636 						TIntermConstantUnion *valConstant = parameters[0]->getAsTyped()->getAsConstantUnion();
3637 						TIntermConstantUnion *minConstant = parameters[1]->getAsTyped()->getAsConstantUnion();
3638 						TIntermConstantUnion *maxConstant = parameters[2]->getAsTyped()->getAsConstantUnion();
3639 
3640 						if (valConstant && minConstant && maxConstant)
3641 						{
3642 							TIntermTyped *typedReturnNode = valConstant->fold(EOpMax, minConstant, infoSink());
3643 							if (typedReturnNode && typedReturnNode->getAsConstantUnion())
3644 							{
3645 								typedReturnNode = maxConstant->fold(EOpMin, typedReturnNode->getAsConstantUnion(), infoSink());
3646 							}
3647 							if (typedReturnNode)
3648 							{
3649 								callNode = typedReturnNode;
3650 							}
3651 						}
3652 					}
3653 					else
3654 					{
3655 						if(fnCandidate->getParamCount() == 2)
3656 						{
3657 							TIntermSequence &parameters = paramNode->getAsAggregate()->getSequence();
3658 							TIntermTyped *left = parameters[0]->getAsTyped();
3659 							TIntermTyped *right = parameters[1]->getAsTyped();
3660 
3661 							TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
3662 							TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
3663 							if (leftTempConstant && rightTempConstant)
3664 							{
3665 								TIntermTyped *typedReturnNode = leftTempConstant->fold(op, rightTempConstant, infoSink());
3666 
3667 								if(typedReturnNode)
3668 								{
3669 									callNode = typedReturnNode;
3670 								}
3671 							}
3672 						}
3673 					}
3674 				}
3675 			}
3676 			else
3677 			{
3678 				// This is a real function call
3679 
3680 				TIntermAggregate *aggregate = intermediate.setAggregateOperator(paramNode, EOpFunctionCall, loc);
3681 				aggregate->setType(fnCandidate->getReturnType());
3682 
3683 				// this is how we know whether the given function is a builtIn function or a user defined function
3684 				// if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also
3685 				// if builtIn == true, it's definitely a builtIn function with EOpNull
3686 				if(!builtIn)
3687 					aggregate->setUserDefined();
3688 				aggregate->setName(fnCandidate->getMangledName());
3689 
3690 				callNode = aggregate;
3691 
3692 				functionCallLValueErrorCheck(fnCandidate, aggregate);
3693 			}
3694 		}
3695 		else
3696 		{
3697 			// error message was put out by findFunction()
3698 			// Put on a dummy node for error recovery
3699 			ConstantUnion *unionArray = new ConstantUnion[1];
3700 			unionArray->setFConst(0.0f);
3701 			callNode = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConstExpr), loc);
3702 			recover();
3703 		}
3704 	}
3705 	delete fnCall;
3706 	return callNode;
3707 }
3708 
addTernarySelection(TIntermTyped * cond,TIntermTyped * trueBlock,TIntermTyped * falseBlock,const TSourceLoc & loc)3709 TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &loc)
3710 {
3711 	if(boolErrorCheck(loc, cond))
3712 		recover();
3713 
3714 	if(trueBlock->getType() != falseBlock->getType())
3715 	{
3716 		binaryOpError(loc, ":", trueBlock->getCompleteString(), falseBlock->getCompleteString());
3717 		recover();
3718 		return falseBlock;
3719 	}
3720 	// ESSL1 sections 5.2 and 5.7:
3721 	// ESSL3 section 5.7:
3722 	// Ternary operator is not among the operators allowed for structures/arrays.
3723 	if(trueBlock->isArray() || trueBlock->getBasicType() == EbtStruct)
3724 	{
3725 		error(loc, "ternary operator is not allowed for structures or arrays", ":");
3726 		recover();
3727 		return falseBlock;
3728 	}
3729 	return intermediate.addSelection(cond, trueBlock, falseBlock, loc);
3730 }
3731 
3732 //
3733 // Parse an array of strings using yyparse.
3734 //
3735 // Returns 0 for success.
3736 //
PaParseStrings(int count,const char * const string[],const int length[],TParseContext * context)3737 int PaParseStrings(int count, const char* const string[], const int length[],
3738 				   TParseContext* context) {
3739 	if ((count == 0) || !string)
3740 		return 1;
3741 
3742 	if (glslang_initialize(context))
3743 		return 1;
3744 
3745 	int error = glslang_scan(count, string, length, context);
3746 	if (!error)
3747 		error = glslang_parse(context);
3748 
3749 	glslang_finalize(context);
3750 
3751 	return (error == 0) && (context->numErrors() == 0) ? 0 : 1;
3752 }
3753 
3754 
3755 
3756