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