Thu, 15 Jan 2015 15:55:04 +0100
Back out 97036ab72558 which inappropriately compared turds to third parties.
1 /*
2 //
3 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
6 //
8 This file contains the Yacc grammar for GLSL ES.
9 Based on ANSI C Yacc grammar:
10 http://www.lysator.liu.se/c/ANSI-C-grammar-y.html
12 IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh,
13 WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
14 */
16 %{
17 //
18 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
19 // Use of this source code is governed by a BSD-style license that can be
20 // found in the LICENSE file.
21 //
23 // This file is auto-generated by generate_parser.sh. DO NOT EDIT!
25 // Ignore errors in auto-generated code.
26 #if defined(__GNUC__)
27 #pragma GCC diagnostic ignored "-Wunused-function"
28 #pragma GCC diagnostic ignored "-Wunused-variable"
29 #pragma GCC diagnostic ignored "-Wswitch-enum"
30 #elif defined(_MSC_VER)
31 #pragma warning(disable: 4065)
32 #pragma warning(disable: 4189)
33 #pragma warning(disable: 4505)
34 #pragma warning(disable: 4701)
35 #endif
37 #include "compiler/SymbolTable.h"
38 #include "compiler/ParseHelper.h"
39 #include "GLSLANG/ShaderLang.h"
41 #define YYENABLE_NLS 0
43 #define YYLEX_PARAM context->scanner
44 %}
46 %expect 1 /* One shift reduce conflict because of if | else */
47 %pure-parser
48 %parse-param {TParseContext* context}
49 %locations
51 %code requires {
52 #define YYLTYPE TSourceLoc
53 #define YYLTYPE_IS_DECLARED 1
54 }
56 %union {
57 struct {
58 union {
59 TString *string;
60 float f;
61 int i;
62 bool b;
63 };
64 TSymbol* symbol;
65 } lex;
66 struct {
67 TOperator op;
68 union {
69 TIntermNode* intermNode;
70 TIntermNodePair nodePair;
71 TIntermTyped* intermTypedNode;
72 TIntermAggregate* intermAggregate;
73 };
74 union {
75 TPublicType type;
76 TPrecision precision;
77 TQualifier qualifier;
78 TFunction* function;
79 TParameter param;
80 TField* field;
81 TFieldList* fieldList;
82 };
83 } interm;
84 }
86 %{
87 extern int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, void* yyscanner);
88 static void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason);
90 #define YYLLOC_DEFAULT(Current, Rhs, N) \
91 do { \
92 if (YYID(N)) { \
93 (Current).first_file = YYRHSLOC(Rhs, 1).first_file; \
94 (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
95 (Current).last_file = YYRHSLOC(Rhs, N).last_file; \
96 (Current).last_line = YYRHSLOC(Rhs, N).last_line; \
97 } \
98 else { \
99 (Current).first_file = YYRHSLOC(Rhs, 0).last_file; \
100 (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \
101 (Current).last_file = YYRHSLOC(Rhs, 0).last_file; \
102 (Current).last_line = YYRHSLOC(Rhs, 0).last_line; \
103 } \
104 } while (0)
106 #define VERTEX_ONLY(S, L) { \
107 if (context->shaderType != SH_VERTEX_SHADER) { \
108 context->error(L, " supported in vertex shaders only ", S); \
109 context->recover(); \
110 } \
111 }
113 #define FRAG_ONLY(S, L) { \
114 if (context->shaderType != SH_FRAGMENT_SHADER) { \
115 context->error(L, " supported in fragment shaders only ", S); \
116 context->recover(); \
117 } \
118 }
119 %}
121 %token <lex> INVARIANT HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION
122 %token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE
123 %token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN
124 %token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4
125 %token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING
126 %token <lex> STRUCT VOID_TYPE WHILE
127 %token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER2DRECT
129 %token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT BOOLCONSTANT
130 %token <lex> LEFT_OP RIGHT_OP
131 %token <lex> INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP
132 %token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN
133 %token <lex> MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
134 %token <lex> SUB_ASSIGN
136 %token <lex> LEFT_PAREN RIGHT_PAREN LEFT_BRACKET RIGHT_BRACKET LEFT_BRACE RIGHT_BRACE DOT
137 %token <lex> COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT
138 %token <lex> LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION
140 %type <lex> identifier
141 %type <interm> assignment_operator unary_operator
142 %type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression
143 %type <interm.intermTypedNode> expression integer_expression assignment_expression
144 %type <interm.intermTypedNode> unary_expression multiplicative_expression additive_expression
145 %type <interm.intermTypedNode> relational_expression equality_expression
146 %type <interm.intermTypedNode> conditional_expression constant_expression
147 %type <interm.intermTypedNode> logical_or_expression logical_xor_expression logical_and_expression
148 %type <interm.intermTypedNode> shift_expression and_expression exclusive_or_expression inclusive_or_expression
149 %type <interm.intermTypedNode> function_call initializer condition conditionopt
151 %type <interm.intermNode> translation_unit function_definition
152 %type <interm.intermNode> statement simple_statement
153 %type <interm.intermAggregate> statement_list compound_statement
154 %type <interm.intermNode> declaration_statement selection_statement expression_statement
155 %type <interm.intermNode> declaration external_declaration
156 %type <interm.intermNode> for_init_statement compound_statement_no_new_scope
157 %type <interm.nodePair> selection_rest_statement for_rest_statement
158 %type <interm.intermNode> iteration_statement jump_statement statement_no_new_scope statement_with_scope
159 %type <interm> single_declaration init_declarator_list
161 %type <interm> parameter_declaration parameter_declarator parameter_type_specifier
162 %type <interm.qualifier> parameter_qualifier
164 %type <interm.precision> precision_qualifier
165 %type <interm.type> type_qualifier fully_specified_type type_specifier
166 %type <interm.type> type_specifier_no_prec type_specifier_nonarray
167 %type <interm.type> struct_specifier
168 %type <interm.field> struct_declarator
169 %type <interm.fieldList> struct_declarator_list struct_declaration struct_declaration_list
170 %type <interm.function> function_header function_declarator function_identifier
171 %type <interm.function> function_header_with_parameters function_call_header
172 %type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype
173 %type <interm> function_call_or_method
175 %start translation_unit
176 %%
178 identifier
179 : IDENTIFIER
180 | TYPE_NAME
182 variable_identifier
183 : IDENTIFIER {
184 // The symbol table search was done in the lexical phase
185 const TSymbol* symbol = $1.symbol;
186 const TVariable* variable;
187 if (symbol == 0) {
188 context->error(@1, "undeclared identifier", $1.string->c_str());
189 context->recover();
190 TType type(EbtFloat, EbpUndefined);
191 TVariable* fakeVariable = new TVariable($1.string, type);
192 context->symbolTable.insert(*fakeVariable);
193 variable = fakeVariable;
194 } else {
195 // This identifier can only be a variable type symbol
196 if (! symbol->isVariable()) {
197 context->error(@1, "variable expected", $1.string->c_str());
198 context->recover();
199 }
201 variable = static_cast<const TVariable*>(symbol);
203 if (context->symbolTable.findBuiltIn(variable->getName()) &&
204 !variable->getExtension().empty() &&
205 context->extensionErrorCheck(@1, variable->getExtension())) {
206 context->recover();
207 }
208 }
210 // don't delete $1.string, it's used by error recovery, and the pool
211 // pop will reclaim the memory
213 if (variable->getType().getQualifier() == EvqConst ) {
214 ConstantUnion* constArray = variable->getConstPointer();
215 TType t(variable->getType());
216 $$ = context->intermediate.addConstantUnion(constArray, t, @1);
217 } else
218 $$ = context->intermediate.addSymbol(variable->getUniqueId(),
219 variable->getName(),
220 variable->getType(),
221 @1);
222 }
223 ;
225 primary_expression
226 : variable_identifier {
227 $$ = $1;
228 }
229 | INTCONSTANT {
230 //
231 // INT_TYPE is only 16-bit plus sign bit for vertex/fragment shaders,
232 // check for overflow for constants
233 //
234 if (abs($1.i) >= (1 << 16)) {
235 context->error(@1, " integer constant overflow", "");
236 context->recover();
237 }
238 ConstantUnion *unionArray = new ConstantUnion[1];
239 unionArray->setIConst($1.i);
240 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @1);
241 }
242 | FLOATCONSTANT {
243 ConstantUnion *unionArray = new ConstantUnion[1];
244 unionArray->setFConst($1.f);
245 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), @1);
246 }
247 | BOOLCONSTANT {
248 ConstantUnion *unionArray = new ConstantUnion[1];
249 unionArray->setBConst($1.b);
250 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @1);
251 }
252 | LEFT_PAREN expression RIGHT_PAREN {
253 $$ = $2;
254 }
255 ;
257 postfix_expression
258 : primary_expression {
259 $$ = $1;
260 }
261 | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET {
262 $$ = context->addIndexExpression($1, @2, $3);
263 }
264 | function_call {
265 $$ = $1;
266 }
267 | postfix_expression DOT identifier {
268 if ($1->isArray()) {
269 context->error(@3, "cannot apply dot operator to an array", ".");
270 context->recover();
271 }
273 if ($1->isVector()) {
274 TVectorFields fields;
275 if (! context->parseVectorFields(*$3.string, $1->getNominalSize(), fields, @3)) {
276 fields.num = 1;
277 fields.offsets[0] = 0;
278 context->recover();
279 }
281 if ($1->getType().getQualifier() == EvqConst) { // constant folding for vector fields
282 $$ = context->addConstVectorNode(fields, $1, @3);
283 if ($$ == 0) {
284 context->recover();
285 $$ = $1;
286 }
287 else
288 $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst, (int) (*$3.string).size()));
289 } else {
290 TString vectorString = *$3.string;
291 TIntermTyped* index = context->intermediate.addSwizzle(fields, @3);
292 $$ = context->intermediate.addIndex(EOpVectorSwizzle, $1, index, @2);
293 $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, (int) vectorString.size()));
294 }
295 } else if ($1->isMatrix()) {
296 TMatrixFields fields;
297 if (! context->parseMatrixFields(*$3.string, $1->getNominalSize(), fields, @3)) {
298 fields.wholeRow = false;
299 fields.wholeCol = false;
300 fields.row = 0;
301 fields.col = 0;
302 context->recover();
303 }
305 if (fields.wholeRow || fields.wholeCol) {
306 context->error(@2, " non-scalar fields not implemented yet", ".");
307 context->recover();
308 ConstantUnion *unionArray = new ConstantUnion[1];
309 unionArray->setIConst(0);
310 TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @3);
311 $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, @2);
312 $$->setType(TType($1->getBasicType(), $1->getPrecision(),EvqTemporary, $1->getNominalSize()));
313 } else {
314 ConstantUnion *unionArray = new ConstantUnion[1];
315 unionArray->setIConst(fields.col * $1->getNominalSize() + fields.row);
316 TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @3);
317 $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, @2);
318 $$->setType(TType($1->getBasicType(), $1->getPrecision()));
319 }
320 } else if ($1->getBasicType() == EbtStruct) {
321 bool fieldFound = false;
322 const TFieldList& fields = $1->getType().getStruct()->fields();
323 unsigned int i;
324 for (i = 0; i < fields.size(); ++i) {
325 if (fields[i]->name() == *$3.string) {
326 fieldFound = true;
327 break;
328 }
329 }
330 if (fieldFound) {
331 if ($1->getType().getQualifier() == EvqConst) {
332 $$ = context->addConstStruct(*$3.string, $1, @2);
333 if ($$ == 0) {
334 context->recover();
335 $$ = $1;
336 }
337 else {
338 $$->setType(*fields[i]->type());
339 // change the qualifier of the return type, not of the structure field
340 // as the structure definition is shared between various structures.
341 $$->getTypePointer()->setQualifier(EvqConst);
342 }
343 } else {
344 ConstantUnion *unionArray = new ConstantUnion[1];
345 unionArray->setIConst(i);
346 TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *fields[i]->type(), @3);
347 $$ = context->intermediate.addIndex(EOpIndexDirectStruct, $1, index, @2);
348 $$->setType(*fields[i]->type());
349 }
350 } else {
351 context->error(@2, " no such field in structure", $3.string->c_str());
352 context->recover();
353 $$ = $1;
354 }
355 } else {
356 context->error(@2, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str());
357 context->recover();
358 $$ = $1;
359 }
360 // don't delete $3.string, it's from the pool
361 }
362 | postfix_expression INC_OP {
363 if (context->lValueErrorCheck(@2, "++", $1))
364 context->recover();
365 $$ = context->intermediate.addUnaryMath(EOpPostIncrement, $1, @2, context->symbolTable);
366 if ($$ == 0) {
367 context->unaryOpError(@2, "++", $1->getCompleteString());
368 context->recover();
369 $$ = $1;
370 }
371 }
372 | postfix_expression DEC_OP {
373 if (context->lValueErrorCheck(@2, "--", $1))
374 context->recover();
375 $$ = context->intermediate.addUnaryMath(EOpPostDecrement, $1, @2, context->symbolTable);
376 if ($$ == 0) {
377 context->unaryOpError(@2, "--", $1->getCompleteString());
378 context->recover();
379 $$ = $1;
380 }
381 }
382 ;
384 integer_expression
385 : expression {
386 if (context->integerErrorCheck($1, "[]"))
387 context->recover();
388 $$ = $1;
389 }
390 ;
392 function_call
393 : function_call_or_method {
394 TFunction* fnCall = $1.function;
395 TOperator op = fnCall->getBuiltInOp();
397 if (op != EOpNull)
398 {
399 //
400 // Then this should be a constructor.
401 // Don't go through the symbol table for constructors.
402 // Their parameters will be verified algorithmically.
403 //
404 TType type(EbtVoid, EbpUndefined); // use this to get the type back
405 if (context->constructorErrorCheck(@1, $1.intermNode, *fnCall, op, &type)) {
406 $$ = 0;
407 } else {
408 //
409 // It's a constructor, of type 'type'.
410 //
411 $$ = context->addConstructor($1.intermNode, &type, op, fnCall, @1);
412 }
414 if ($$ == 0) {
415 context->recover();
416 $$ = context->intermediate.setAggregateOperator(0, op, @1);
417 }
418 $$->setType(type);
419 } else {
420 //
421 // Not a constructor. Find it in the symbol table.
422 //
423 const TFunction* fnCandidate;
424 bool builtIn;
425 fnCandidate = context->findFunction(@1, fnCall, &builtIn);
426 if (fnCandidate) {
427 //
428 // A declared function.
429 //
430 if (builtIn && !fnCandidate->getExtension().empty() &&
431 context->extensionErrorCheck(@1, fnCandidate->getExtension())) {
432 context->recover();
433 }
434 op = fnCandidate->getBuiltInOp();
435 if (builtIn && op != EOpNull) {
436 //
437 // A function call mapped to a built-in operation.
438 //
439 if (fnCandidate->getParamCount() == 1) {
440 //
441 // Treat it like a built-in unary operator.
442 //
443 $$ = context->intermediate.addUnaryMath(op, $1.intermNode, @1, context->symbolTable);
444 if ($$ == 0) {
445 std::stringstream extraInfoStream;
446 extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>($1.intermNode)->getCompleteString();
447 std::string extraInfo = extraInfoStream.str();
448 context->error($1.intermNode->getLine(), " wrong operand type", "Internal Error", extraInfo.c_str());
449 YYERROR;
450 }
451 } else {
452 $$ = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1);
453 }
454 } else {
455 // This is a real function call
457 $$ = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1);
458 $$->setType(fnCandidate->getReturnType());
460 // this is how we know whether the given function is a builtIn function or a user defined function
461 // if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also
462 // if builtIn == true, it's definitely a builtIn function with EOpNull
463 if (!builtIn)
464 $$->getAsAggregate()->setUserDefined();
465 $$->getAsAggregate()->setName(fnCandidate->getMangledName());
467 TQualifier qual;
468 for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) {
469 qual = fnCandidate->getParam(i).type->getQualifier();
470 if (qual == EvqOut || qual == EvqInOut) {
471 if (context->lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) {
472 context->error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
473 context->recover();
474 }
475 }
476 }
477 }
478 $$->setType(fnCandidate->getReturnType());
479 } else {
480 // error message was put out by PaFindFunction()
481 // Put on a dummy node for error recovery
482 ConstantUnion *unionArray = new ConstantUnion[1];
483 unionArray->setFConst(0.0f);
484 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), @1);
485 context->recover();
486 }
487 }
488 delete fnCall;
489 }
490 ;
492 function_call_or_method
493 : function_call_generic {
494 $$ = $1;
495 }
496 | postfix_expression DOT function_call_generic {
497 context->error(@3, "methods are not supported", "");
498 context->recover();
499 $$ = $3;
500 }
501 ;
503 function_call_generic
504 : function_call_header_with_parameters RIGHT_PAREN {
505 $$ = $1;
506 }
507 | function_call_header_no_parameters RIGHT_PAREN {
508 $$ = $1;
509 }
510 ;
512 function_call_header_no_parameters
513 : function_call_header VOID_TYPE {
514 $$.function = $1;
515 $$.intermNode = 0;
516 }
517 | function_call_header {
518 $$.function = $1;
519 $$.intermNode = 0;
520 }
521 ;
523 function_call_header_with_parameters
524 : function_call_header assignment_expression {
525 TParameter param = { 0, new TType($2->getType()) };
526 $1->addParameter(param);
527 $$.function = $1;
528 $$.intermNode = $2;
529 }
530 | function_call_header_with_parameters COMMA assignment_expression {
531 TParameter param = { 0, new TType($3->getType()) };
532 $1.function->addParameter(param);
533 $$.function = $1.function;
534 $$.intermNode = context->intermediate.growAggregate($1.intermNode, $3, @2);
535 }
536 ;
538 function_call_header
539 : function_identifier LEFT_PAREN {
540 $$ = $1;
541 }
542 ;
544 // Grammar Note: Constructors look like functions, but are recognized as types.
546 function_identifier
547 : type_specifier_nonarray {
548 //
549 // Constructor
550 //
551 TOperator op = EOpNull;
552 if ($1.userDef) {
553 op = EOpConstructStruct;
554 } else {
555 switch ($1.type) {
556 case EbtFloat:
557 if ($1.matrix) {
558 switch($1.size) {
559 case 2: op = EOpConstructMat2; break;
560 case 3: op = EOpConstructMat3; break;
561 case 4: op = EOpConstructMat4; break;
562 }
563 } else {
564 switch($1.size) {
565 case 1: op = EOpConstructFloat; break;
566 case 2: op = EOpConstructVec2; break;
567 case 3: op = EOpConstructVec3; break;
568 case 4: op = EOpConstructVec4; break;
569 }
570 }
571 break;
572 case EbtInt:
573 switch($1.size) {
574 case 1: op = EOpConstructInt; break;
575 case 2: op = EOpConstructIVec2; break;
576 case 3: op = EOpConstructIVec3; break;
577 case 4: op = EOpConstructIVec4; break;
578 }
579 break;
580 case EbtBool:
581 switch($1.size) {
582 case 1: op = EOpConstructBool; break;
583 case 2: op = EOpConstructBVec2; break;
584 case 3: op = EOpConstructBVec3; break;
585 case 4: op = EOpConstructBVec4; break;
586 }
587 break;
588 default: break;
589 }
590 if (op == EOpNull) {
591 context->error(@1, "cannot construct this type", getBasicString($1.type));
592 context->recover();
593 $1.type = EbtFloat;
594 op = EOpConstructFloat;
595 }
596 }
597 TString tempString;
598 TType type($1);
599 TFunction *function = new TFunction(&tempString, type, op);
600 $$ = function;
601 }
602 | IDENTIFIER {
603 if (context->reservedErrorCheck(@1, *$1.string))
604 context->recover();
605 TType type(EbtVoid, EbpUndefined);
606 TFunction *function = new TFunction($1.string, type);
607 $$ = function;
608 }
609 ;
611 unary_expression
612 : postfix_expression {
613 $$ = $1;
614 }
615 | INC_OP unary_expression {
616 if (context->lValueErrorCheck(@1, "++", $2))
617 context->recover();
618 $$ = context->intermediate.addUnaryMath(EOpPreIncrement, $2, @1, context->symbolTable);
619 if ($$ == 0) {
620 context->unaryOpError(@1, "++", $2->getCompleteString());
621 context->recover();
622 $$ = $2;
623 }
624 }
625 | DEC_OP unary_expression {
626 if (context->lValueErrorCheck(@1, "--", $2))
627 context->recover();
628 $$ = context->intermediate.addUnaryMath(EOpPreDecrement, $2, @1, context->symbolTable);
629 if ($$ == 0) {
630 context->unaryOpError(@1, "--", $2->getCompleteString());
631 context->recover();
632 $$ = $2;
633 }
634 }
635 | unary_operator unary_expression {
636 if ($1.op != EOpNull) {
637 $$ = context->intermediate.addUnaryMath($1.op, $2, @1, context->symbolTable);
638 if ($$ == 0) {
639 const char* errorOp = "";
640 switch($1.op) {
641 case EOpNegative: errorOp = "-"; break;
642 case EOpLogicalNot: errorOp = "!"; break;
643 default: break;
644 }
645 context->unaryOpError(@1, errorOp, $2->getCompleteString());
646 context->recover();
647 $$ = $2;
648 }
649 } else
650 $$ = $2;
651 }
652 ;
653 // Grammar Note: No traditional style type casts.
655 unary_operator
656 : PLUS { $$.op = EOpNull; }
657 | DASH { $$.op = EOpNegative; }
658 | BANG { $$.op = EOpLogicalNot; }
659 ;
660 // Grammar Note: No '*' or '&' unary ops. Pointers are not supported.
662 multiplicative_expression
663 : unary_expression { $$ = $1; }
664 | multiplicative_expression STAR unary_expression {
665 $$ = context->intermediate.addBinaryMath(EOpMul, $1, $3, @2, context->symbolTable);
666 if ($$ == 0) {
667 context->binaryOpError(@2, "*", $1->getCompleteString(), $3->getCompleteString());
668 context->recover();
669 $$ = $1;
670 }
671 }
672 | multiplicative_expression SLASH unary_expression {
673 $$ = context->intermediate.addBinaryMath(EOpDiv, $1, $3, @2, context->symbolTable);
674 if ($$ == 0) {
675 context->binaryOpError(@2, "/", $1->getCompleteString(), $3->getCompleteString());
676 context->recover();
677 $$ = $1;
678 }
679 }
680 ;
682 additive_expression
683 : multiplicative_expression { $$ = $1; }
684 | additive_expression PLUS multiplicative_expression {
685 $$ = context->intermediate.addBinaryMath(EOpAdd, $1, $3, @2, context->symbolTable);
686 if ($$ == 0) {
687 context->binaryOpError(@2, "+", $1->getCompleteString(), $3->getCompleteString());
688 context->recover();
689 $$ = $1;
690 }
691 }
692 | additive_expression DASH multiplicative_expression {
693 $$ = context->intermediate.addBinaryMath(EOpSub, $1, $3, @2, context->symbolTable);
694 if ($$ == 0) {
695 context->binaryOpError(@2, "-", $1->getCompleteString(), $3->getCompleteString());
696 context->recover();
697 $$ = $1;
698 }
699 }
700 ;
702 shift_expression
703 : additive_expression { $$ = $1; }
704 ;
706 relational_expression
707 : shift_expression { $$ = $1; }
708 | relational_expression LEFT_ANGLE shift_expression {
709 $$ = context->intermediate.addBinaryMath(EOpLessThan, $1, $3, @2, context->symbolTable);
710 if ($$ == 0) {
711 context->binaryOpError(@2, "<", $1->getCompleteString(), $3->getCompleteString());
712 context->recover();
713 ConstantUnion *unionArray = new ConstantUnion[1];
714 unionArray->setBConst(false);
715 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
716 }
717 }
718 | relational_expression RIGHT_ANGLE shift_expression {
719 $$ = context->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, @2, context->symbolTable);
720 if ($$ == 0) {
721 context->binaryOpError(@2, ">", $1->getCompleteString(), $3->getCompleteString());
722 context->recover();
723 ConstantUnion *unionArray = new ConstantUnion[1];
724 unionArray->setBConst(false);
725 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
726 }
727 }
728 | relational_expression LE_OP shift_expression {
729 $$ = context->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, @2, context->symbolTable);
730 if ($$ == 0) {
731 context->binaryOpError(@2, "<=", $1->getCompleteString(), $3->getCompleteString());
732 context->recover();
733 ConstantUnion *unionArray = new ConstantUnion[1];
734 unionArray->setBConst(false);
735 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
736 }
737 }
738 | relational_expression GE_OP shift_expression {
739 $$ = context->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, @2, context->symbolTable);
740 if ($$ == 0) {
741 context->binaryOpError(@2, ">=", $1->getCompleteString(), $3->getCompleteString());
742 context->recover();
743 ConstantUnion *unionArray = new ConstantUnion[1];
744 unionArray->setBConst(false);
745 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
746 }
747 }
748 ;
750 equality_expression
751 : relational_expression { $$ = $1; }
752 | equality_expression EQ_OP relational_expression {
753 $$ = context->intermediate.addBinaryMath(EOpEqual, $1, $3, @2, context->symbolTable);
754 if ($$ == 0) {
755 context->binaryOpError(@2, "==", $1->getCompleteString(), $3->getCompleteString());
756 context->recover();
757 ConstantUnion *unionArray = new ConstantUnion[1];
758 unionArray->setBConst(false);
759 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
760 }
761 }
762 | equality_expression NE_OP relational_expression {
763 $$ = context->intermediate.addBinaryMath(EOpNotEqual, $1, $3, @2, context->symbolTable);
764 if ($$ == 0) {
765 context->binaryOpError(@2, "!=", $1->getCompleteString(), $3->getCompleteString());
766 context->recover();
767 ConstantUnion *unionArray = new ConstantUnion[1];
768 unionArray->setBConst(false);
769 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
770 }
771 }
772 ;
774 and_expression
775 : equality_expression { $$ = $1; }
776 ;
778 exclusive_or_expression
779 : and_expression { $$ = $1; }
780 ;
782 inclusive_or_expression
783 : exclusive_or_expression { $$ = $1; }
784 ;
786 logical_and_expression
787 : inclusive_or_expression { $$ = $1; }
788 | logical_and_expression AND_OP inclusive_or_expression {
789 $$ = context->intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, @2, context->symbolTable);
790 if ($$ == 0) {
791 context->binaryOpError(@2, "&&", $1->getCompleteString(), $3->getCompleteString());
792 context->recover();
793 ConstantUnion *unionArray = new ConstantUnion[1];
794 unionArray->setBConst(false);
795 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
796 }
797 }
798 ;
800 logical_xor_expression
801 : logical_and_expression { $$ = $1; }
802 | logical_xor_expression XOR_OP logical_and_expression {
803 $$ = context->intermediate.addBinaryMath(EOpLogicalXor, $1, $3, @2, context->symbolTable);
804 if ($$ == 0) {
805 context->binaryOpError(@2, "^^", $1->getCompleteString(), $3->getCompleteString());
806 context->recover();
807 ConstantUnion *unionArray = new ConstantUnion[1];
808 unionArray->setBConst(false);
809 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
810 }
811 }
812 ;
814 logical_or_expression
815 : logical_xor_expression { $$ = $1; }
816 | logical_or_expression OR_OP logical_xor_expression {
817 $$ = context->intermediate.addBinaryMath(EOpLogicalOr, $1, $3, @2, context->symbolTable);
818 if ($$ == 0) {
819 context->binaryOpError(@2, "||", $1->getCompleteString(), $3->getCompleteString());
820 context->recover();
821 ConstantUnion *unionArray = new ConstantUnion[1];
822 unionArray->setBConst(false);
823 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
824 }
825 }
826 ;
828 conditional_expression
829 : logical_or_expression { $$ = $1; }
830 | logical_or_expression QUESTION expression COLON assignment_expression {
831 if (context->boolErrorCheck(@2, $1))
832 context->recover();
834 $$ = context->intermediate.addSelection($1, $3, $5, @2);
835 if ($3->getType() != $5->getType())
836 $$ = 0;
838 if ($$ == 0) {
839 context->binaryOpError(@2, ":", $3->getCompleteString(), $5->getCompleteString());
840 context->recover();
841 $$ = $5;
842 }
843 }
844 ;
846 assignment_expression
847 : conditional_expression { $$ = $1; }
848 | unary_expression assignment_operator assignment_expression {
849 if (context->lValueErrorCheck(@2, "assign", $1))
850 context->recover();
851 $$ = context->intermediate.addAssign($2.op, $1, $3, @2);
852 if ($$ == 0) {
853 context->assignError(@2, "assign", $1->getCompleteString(), $3->getCompleteString());
854 context->recover();
855 $$ = $1;
856 }
857 }
858 ;
860 assignment_operator
861 : EQUAL { $$.op = EOpAssign; }
862 | MUL_ASSIGN { $$.op = EOpMulAssign; }
863 | DIV_ASSIGN { $$.op = EOpDivAssign; }
864 | ADD_ASSIGN { $$.op = EOpAddAssign; }
865 | SUB_ASSIGN { $$.op = EOpSubAssign; }
866 ;
868 expression
869 : assignment_expression {
870 $$ = $1;
871 }
872 | expression COMMA assignment_expression {
873 $$ = context->intermediate.addComma($1, $3, @2);
874 if ($$ == 0) {
875 context->binaryOpError(@2, ",", $1->getCompleteString(), $3->getCompleteString());
876 context->recover();
877 $$ = $3;
878 }
879 }
880 ;
882 constant_expression
883 : conditional_expression {
884 if (context->constErrorCheck($1))
885 context->recover();
886 $$ = $1;
887 }
888 ;
890 declaration
891 : function_prototype SEMICOLON {
892 TFunction &function = *($1.function);
894 TIntermAggregate *prototype = new TIntermAggregate;
895 prototype->setType(function.getReturnType());
896 prototype->setName(function.getName());
898 for (size_t i = 0; i < function.getParamCount(); i++)
899 {
900 const TParameter ¶m = function.getParam(i);
901 if (param.name != 0)
902 {
903 TVariable variable(param.name, *param.type);
905 prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), @1), @1);
906 }
907 else
908 {
909 prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, @1), @1);
910 }
911 }
913 prototype->setOp(EOpPrototype);
914 $$ = prototype;
916 context->symbolTable.pop();
917 }
918 | init_declarator_list SEMICOLON {
919 if ($1.intermAggregate)
920 $1.intermAggregate->setOp(EOpDeclaration);
921 $$ = $1.intermAggregate;
922 }
923 | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
924 if (($2 == EbpHigh) && (context->shaderType == SH_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) {
925 context->error(@1, "precision is not supported in fragment shader", "highp");
926 context->recover();
927 }
928 if (!context->symbolTable.setDefaultPrecision( $3, $2 )) {
929 context->error(@1, "illegal type argument for default precision qualifier", getBasicString($3.type));
930 context->recover();
931 }
932 $$ = 0;
933 }
934 ;
936 function_prototype
937 : function_declarator RIGHT_PAREN {
938 //
939 // Multiple declarations of the same function are allowed.
940 //
941 // If this is a definition, the definition production code will check for redefinitions
942 // (we don't know at this point if it's a definition or not).
943 //
944 // Redeclarations are allowed. But, return types and parameter qualifiers must match.
945 //
946 TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find($1->getMangledName()));
947 if (prevDec) {
948 if (prevDec->getReturnType() != $1->getReturnType()) {
949 context->error(@2, "overloaded functions must have the same return type", $1->getReturnType().getBasicString());
950 context->recover();
951 }
952 for (size_t i = 0; i < prevDec->getParamCount(); ++i) {
953 if (prevDec->getParam(i).type->getQualifier() != $1->getParam(i).type->getQualifier()) {
954 context->error(@2, "overloaded functions must have the same parameter qualifiers", $1->getParam(i).type->getQualifierString());
955 context->recover();
956 }
957 }
958 }
960 //
961 // Check for previously declared variables using the same name.
962 //
963 TSymbol *prevSym = context->symbolTable.find($1->getName());
964 if (prevSym)
965 {
966 if (!prevSym->isFunction())
967 {
968 context->error(@2, "redefinition", $1->getName().c_str(), "function");
969 context->recover();
970 }
971 }
972 else
973 {
974 // Insert the unmangled name to detect potential future redefinition as a variable.
975 context->symbolTable.getOuterLevel()->insert($1->getName(), *$1);
976 }
978 //
979 // If this is a redeclaration, it could also be a definition,
980 // in which case, we want to use the variable names from this one, and not the one that's
981 // being redeclared. So, pass back up this declaration, not the one in the symbol table.
982 //
983 $$.function = $1;
985 // We're at the inner scope level of the function's arguments and body statement.
986 // Add the function prototype to the surrounding scope instead.
987 context->symbolTable.getOuterLevel()->insert(*$$.function);
988 }
989 ;
991 function_declarator
992 : function_header {
993 $$ = $1;
994 }
995 | function_header_with_parameters {
996 $$ = $1;
997 }
998 ;
1001 function_header_with_parameters
1002 : function_header parameter_declaration {
1003 // Add the parameter
1004 $$ = $1;
1005 if ($2.param.type->getBasicType() != EbtVoid)
1006 $1->addParameter($2.param);
1007 else
1008 delete $2.param.type;
1009 }
1010 | function_header_with_parameters COMMA parameter_declaration {
1011 //
1012 // Only first parameter of one-parameter functions can be void
1013 // The check for named parameters not being void is done in parameter_declarator
1014 //
1015 if ($3.param.type->getBasicType() == EbtVoid) {
1016 //
1017 // This parameter > first is void
1018 //
1019 context->error(@2, "cannot be an argument type except for '(void)'", "void");
1020 context->recover();
1021 delete $3.param.type;
1022 } else {
1023 // Add the parameter
1024 $$ = $1;
1025 $1->addParameter($3.param);
1026 }
1027 }
1028 ;
1030 function_header
1031 : fully_specified_type IDENTIFIER LEFT_PAREN {
1032 if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary) {
1033 context->error(@2, "no qualifiers allowed for function return", getQualifierString($1.qualifier));
1034 context->recover();
1035 }
1036 // make sure a sampler is not involved as well...
1037 if (context->structQualifierErrorCheck(@2, $1))
1038 context->recover();
1040 // Add the function as a prototype after parsing it (we do not support recursion)
1041 TFunction *function;
1042 TType type($1);
1043 function = new TFunction($2.string, type);
1044 $$ = function;
1046 context->symbolTable.push();
1047 }
1048 ;
1050 parameter_declarator
1051 // Type + name
1052 : type_specifier identifier {
1053 if ($1.type == EbtVoid) {
1054 context->error(@2, "illegal use of type 'void'", $2.string->c_str());
1055 context->recover();
1056 }
1057 if (context->reservedErrorCheck(@2, *$2.string))
1058 context->recover();
1059 TParameter param = {$2.string, new TType($1)};
1060 $$.param = param;
1061 }
1062 | type_specifier identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
1063 // Check that we can make an array out of this type
1064 if (context->arrayTypeErrorCheck(@3, $1))
1065 context->recover();
1067 if (context->reservedErrorCheck(@2, *$2.string))
1068 context->recover();
1070 int size;
1071 if (context->arraySizeErrorCheck(@3, $4, size))
1072 context->recover();
1073 $1.setArray(true, size);
1075 TType* type = new TType($1);
1076 TParameter param = { $2.string, type };
1077 $$.param = param;
1078 }
1079 ;
1081 parameter_declaration
1082 //
1083 // The only parameter qualifier a parameter can have are
1084 // IN_QUAL, OUT_QUAL, INOUT_QUAL, or CONST.
1085 //
1087 //
1088 // Type + name
1089 //
1090 : type_qualifier parameter_qualifier parameter_declarator {
1091 $$ = $3;
1092 if (context->paramErrorCheck(@3, $1.qualifier, $2, $$.param.type))
1093 context->recover();
1094 }
1095 | parameter_qualifier parameter_declarator {
1096 $$ = $2;
1097 if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type))
1098 context->recover();
1099 if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type))
1100 context->recover();
1101 }
1102 //
1103 // Only type
1104 //
1105 | type_qualifier parameter_qualifier parameter_type_specifier {
1106 $$ = $3;
1107 if (context->paramErrorCheck(@3, $1.qualifier, $2, $$.param.type))
1108 context->recover();
1109 }
1110 | parameter_qualifier parameter_type_specifier {
1111 $$ = $2;
1112 if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type))
1113 context->recover();
1114 if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type))
1115 context->recover();
1116 }
1117 ;
1119 parameter_qualifier
1120 : /* empty */ {
1121 $$ = EvqIn;
1122 }
1123 | IN_QUAL {
1124 $$ = EvqIn;
1125 }
1126 | OUT_QUAL {
1127 $$ = EvqOut;
1128 }
1129 | INOUT_QUAL {
1130 $$ = EvqInOut;
1131 }
1132 ;
1134 parameter_type_specifier
1135 : type_specifier {
1136 TParameter param = { 0, new TType($1) };
1137 $$.param = param;
1138 }
1139 ;
1141 init_declarator_list
1142 : single_declaration {
1143 $$ = $1;
1144 }
1145 | init_declarator_list COMMA identifier {
1146 if ($1.type.type == EbtInvariant && !$3.symbol)
1147 {
1148 context->error(@3, "undeclared identifier declared as invariant", $3.string->c_str());
1149 context->recover();
1150 }
1152 TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$3.string, TType($1.type), @3);
1153 $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, symbol, @3);
1155 if (context->structQualifierErrorCheck(@3, $$.type))
1156 context->recover();
1158 if (context->nonInitConstErrorCheck(@3, *$3.string, $$.type, false))
1159 context->recover();
1161 TVariable* variable = 0;
1162 if (context->nonInitErrorCheck(@3, *$3.string, $$.type, variable))
1163 context->recover();
1164 if (symbol && variable)
1165 symbol->setId(variable->getUniqueId());
1166 }
1167 | init_declarator_list COMMA identifier LEFT_BRACKET RIGHT_BRACKET {
1168 if (context->structQualifierErrorCheck(@3, $1.type))
1169 context->recover();
1171 if (context->nonInitConstErrorCheck(@3, *$3.string, $1.type, true))
1172 context->recover();
1174 $$ = $1;
1176 if (context->arrayTypeErrorCheck(@4, $1.type) || context->arrayQualifierErrorCheck(@4, $1.type))
1177 context->recover();
1178 else {
1179 $1.type.setArray(true);
1180 TVariable* variable;
1181 if (context->arrayErrorCheck(@4, *$3.string, $1.type, variable))
1182 context->recover();
1183 }
1184 }
1185 | init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
1186 if (context->structQualifierErrorCheck(@3, $1.type))
1187 context->recover();
1189 if (context->nonInitConstErrorCheck(@3, *$3.string, $1.type, true))
1190 context->recover();
1192 $$ = $1;
1194 if (context->arrayTypeErrorCheck(@4, $1.type) || context->arrayQualifierErrorCheck(@4, $1.type))
1195 context->recover();
1196 else {
1197 int size;
1198 if (context->arraySizeErrorCheck(@4, $5, size))
1199 context->recover();
1200 $1.type.setArray(true, size);
1201 TVariable* variable = 0;
1202 if (context->arrayErrorCheck(@4, *$3.string, $1.type, variable))
1203 context->recover();
1204 TType type = TType($1.type);
1205 type.setArraySize(size);
1206 $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(variable ? variable->getUniqueId() : 0, *$3.string, type, @3), @3);
1207 }
1208 }
1209 | init_declarator_list COMMA identifier EQUAL initializer {
1210 if (context->structQualifierErrorCheck(@3, $1.type))
1211 context->recover();
1213 $$ = $1;
1215 TIntermNode* intermNode;
1216 if (!context->executeInitializer(@3, *$3.string, $1.type, $5, intermNode)) {
1217 //
1218 // build the intermediate representation
1219 //
1220 if (intermNode)
1221 $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, intermNode, @4);
1222 else
1223 $$.intermAggregate = $1.intermAggregate;
1224 } else {
1225 context->recover();
1226 $$.intermAggregate = 0;
1227 }
1228 }
1229 ;
1231 single_declaration
1232 : fully_specified_type {
1233 $$.type = $1;
1234 $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType($1), @1), @1);
1235 }
1236 | fully_specified_type identifier {
1237 TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), @2);
1238 $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2);
1240 if (context->structQualifierErrorCheck(@2, $$.type))
1241 context->recover();
1243 if (context->nonInitConstErrorCheck(@2, *$2.string, $$.type, false))
1244 context->recover();
1246 $$.type = $1;
1248 TVariable* variable = 0;
1249 if (context->nonInitErrorCheck(@2, *$2.string, $$.type, variable))
1250 context->recover();
1251 if (variable && symbol)
1252 symbol->setId(variable->getUniqueId());
1253 }
1254 | fully_specified_type identifier LEFT_BRACKET RIGHT_BRACKET {
1255 context->error(@2, "unsized array declarations not supported", $2.string->c_str());
1256 context->recover();
1258 TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), @2);
1259 $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2);
1260 $$.type = $1;
1261 }
1262 | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
1263 TType type = TType($1);
1264 int size;
1265 if (context->arraySizeErrorCheck(@2, $4, size))
1266 context->recover();
1267 type.setArraySize(size);
1268 TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, type, @2);
1269 $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2);
1271 if (context->structQualifierErrorCheck(@2, $1))
1272 context->recover();
1274 if (context->nonInitConstErrorCheck(@2, *$2.string, $1, true))
1275 context->recover();
1277 $$.type = $1;
1279 if (context->arrayTypeErrorCheck(@3, $1) || context->arrayQualifierErrorCheck(@3, $1))
1280 context->recover();
1281 else {
1282 int size;
1283 if (context->arraySizeErrorCheck(@3, $4, size))
1284 context->recover();
1286 $1.setArray(true, size);
1287 TVariable* variable = 0;
1288 if (context->arrayErrorCheck(@3, *$2.string, $1, variable))
1289 context->recover();
1290 if (variable && symbol)
1291 symbol->setId(variable->getUniqueId());
1292 }
1293 }
1294 | fully_specified_type identifier EQUAL initializer {
1295 if (context->structQualifierErrorCheck(@2, $1))
1296 context->recover();
1298 $$.type = $1;
1300 TIntermNode* intermNode;
1301 if (!context->executeInitializer(@2, *$2.string, $1, $4, intermNode)) {
1302 //
1303 // Build intermediate representation
1304 //
1305 if(intermNode)
1306 $$.intermAggregate = context->intermediate.makeAggregate(intermNode, @3);
1307 else
1308 $$.intermAggregate = 0;
1309 } else {
1310 context->recover();
1311 $$.intermAggregate = 0;
1312 }
1313 }
1314 | INVARIANT IDENTIFIER {
1315 VERTEX_ONLY("invariant declaration", @1);
1316 if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying"))
1317 context->recover();
1318 $$.type.setBasic(EbtInvariant, EvqInvariantVaryingOut, @2);
1319 if (!$2.symbol)
1320 {
1321 context->error(@2, "undeclared identifier declared as invariant", $2.string->c_str());
1322 context->recover();
1324 $$.intermAggregate = 0;
1325 }
1326 else
1327 {
1328 TIntermSymbol *symbol = context->intermediate.addSymbol(0, *$2.string, TType($$.type), @2);
1329 $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2);
1330 }
1331 }
1332 ;
1334 fully_specified_type
1335 : type_specifier {
1336 $$ = $1;
1338 if ($1.array) {
1339 context->error(@1, "not supported", "first-class array");
1340 context->recover();
1341 $1.setArray(false);
1342 }
1343 }
1344 | type_qualifier type_specifier {
1345 if ($2.array) {
1346 context->error(@2, "not supported", "first-class array");
1347 context->recover();
1348 $2.setArray(false);
1349 }
1351 if ($1.qualifier == EvqAttribute &&
1352 ($2.type == EbtBool || $2.type == EbtInt)) {
1353 context->error(@2, "cannot be bool or int", getQualifierString($1.qualifier));
1354 context->recover();
1355 }
1356 if (($1.qualifier == EvqVaryingIn || $1.qualifier == EvqVaryingOut) &&
1357 ($2.type == EbtBool || $2.type == EbtInt)) {
1358 context->error(@2, "cannot be bool or int", getQualifierString($1.qualifier));
1359 context->recover();
1360 }
1361 $$ = $2;
1362 $$.qualifier = $1.qualifier;
1363 }
1364 ;
1366 type_qualifier
1367 : CONST_QUAL {
1368 $$.setBasic(EbtVoid, EvqConst, @1);
1369 }
1370 | ATTRIBUTE {
1371 VERTEX_ONLY("attribute", @1);
1372 if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "attribute"))
1373 context->recover();
1374 $$.setBasic(EbtVoid, EvqAttribute, @1);
1375 }
1376 | VARYING {
1377 if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "varying"))
1378 context->recover();
1379 if (context->shaderType == SH_VERTEX_SHADER)
1380 $$.setBasic(EbtVoid, EvqVaryingOut, @1);
1381 else
1382 $$.setBasic(EbtVoid, EvqVaryingIn, @1);
1383 }
1384 | INVARIANT VARYING {
1385 if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying"))
1386 context->recover();
1387 if (context->shaderType == SH_VERTEX_SHADER)
1388 $$.setBasic(EbtVoid, EvqInvariantVaryingOut, @1);
1389 else
1390 $$.setBasic(EbtVoid, EvqInvariantVaryingIn, @1);
1391 }
1392 | UNIFORM {
1393 if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "uniform"))
1394 context->recover();
1395 $$.setBasic(EbtVoid, EvqUniform, @1);
1396 }
1397 ;
1399 type_specifier
1400 : type_specifier_no_prec {
1401 $$ = $1;
1403 if ($$.precision == EbpUndefined) {
1404 $$.precision = context->symbolTable.getDefaultPrecision($1.type);
1405 if (context->precisionErrorCheck(@1, $$.precision, $1.type)) {
1406 context->recover();
1407 }
1408 }
1409 }
1410 | precision_qualifier type_specifier_no_prec {
1411 $$ = $2;
1412 $$.precision = $1;
1413 }
1414 ;
1416 precision_qualifier
1417 : HIGH_PRECISION {
1418 $$ = EbpHigh;
1419 }
1420 | MEDIUM_PRECISION {
1421 $$ = EbpMedium;
1422 }
1423 | LOW_PRECISION {
1424 $$ = EbpLow;
1425 }
1426 ;
1428 type_specifier_no_prec
1429 : type_specifier_nonarray {
1430 $$ = $1;
1431 }
1432 | type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET {
1433 $$ = $1;
1435 if (context->arrayTypeErrorCheck(@2, $1))
1436 context->recover();
1437 else {
1438 int size;
1439 if (context->arraySizeErrorCheck(@2, $3, size))
1440 context->recover();
1441 $$.setArray(true, size);
1442 }
1443 }
1444 ;
1446 type_specifier_nonarray
1447 : VOID_TYPE {
1448 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1449 $$.setBasic(EbtVoid, qual, @1);
1450 }
1451 | FLOAT_TYPE {
1452 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1453 $$.setBasic(EbtFloat, qual, @1);
1454 }
1455 | INT_TYPE {
1456 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1457 $$.setBasic(EbtInt, qual, @1);
1458 }
1459 | BOOL_TYPE {
1460 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1461 $$.setBasic(EbtBool, qual, @1);
1462 }
1463 | VEC2 {
1464 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1465 $$.setBasic(EbtFloat, qual, @1);
1466 $$.setAggregate(2);
1467 }
1468 | VEC3 {
1469 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1470 $$.setBasic(EbtFloat, qual, @1);
1471 $$.setAggregate(3);
1472 }
1473 | VEC4 {
1474 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1475 $$.setBasic(EbtFloat, qual, @1);
1476 $$.setAggregate(4);
1477 }
1478 | BVEC2 {
1479 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1480 $$.setBasic(EbtBool, qual, @1);
1481 $$.setAggregate(2);
1482 }
1483 | BVEC3 {
1484 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1485 $$.setBasic(EbtBool, qual, @1);
1486 $$.setAggregate(3);
1487 }
1488 | BVEC4 {
1489 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1490 $$.setBasic(EbtBool, qual, @1);
1491 $$.setAggregate(4);
1492 }
1493 | IVEC2 {
1494 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1495 $$.setBasic(EbtInt, qual, @1);
1496 $$.setAggregate(2);
1497 }
1498 | IVEC3 {
1499 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1500 $$.setBasic(EbtInt, qual, @1);
1501 $$.setAggregate(3);
1502 }
1503 | IVEC4 {
1504 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1505 $$.setBasic(EbtInt, qual, @1);
1506 $$.setAggregate(4);
1507 }
1508 | MATRIX2 {
1509 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1510 $$.setBasic(EbtFloat, qual, @1);
1511 $$.setAggregate(2, true);
1512 }
1513 | MATRIX3 {
1514 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1515 $$.setBasic(EbtFloat, qual, @1);
1516 $$.setAggregate(3, true);
1517 }
1518 | MATRIX4 {
1519 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1520 $$.setBasic(EbtFloat, qual, @1);
1521 $$.setAggregate(4, true);
1522 }
1523 | SAMPLER2D {
1524 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1525 $$.setBasic(EbtSampler2D, qual, @1);
1526 }
1527 | SAMPLERCUBE {
1528 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1529 $$.setBasic(EbtSamplerCube, qual, @1);
1530 }
1531 | SAMPLER_EXTERNAL_OES {
1532 if (!context->supportsExtension("GL_OES_EGL_image_external")) {
1533 context->error(@1, "unsupported type", "samplerExternalOES");
1534 context->recover();
1535 }
1536 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1537 $$.setBasic(EbtSamplerExternalOES, qual, @1);
1538 }
1539 | SAMPLER2DRECT {
1540 if (!context->supportsExtension("GL_ARB_texture_rectangle")) {
1541 context->error(@1, "unsupported type", "sampler2DRect");
1542 context->recover();
1543 }
1544 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1545 $$.setBasic(EbtSampler2DRect, qual, @1);
1546 }
1547 | struct_specifier {
1548 $$ = $1;
1549 $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1550 }
1551 | TYPE_NAME {
1552 //
1553 // This is for user defined type names. The lexical phase looked up the
1554 // type.
1555 //
1556 TType& structure = static_cast<TVariable*>($1.symbol)->getType();
1557 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
1558 $$.setBasic(EbtStruct, qual, @1);
1559 $$.userDef = &structure;
1560 }
1561 ;
1563 struct_specifier
1564 : STRUCT identifier LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
1565 if (context->reservedErrorCheck(@2, *$2.string))
1566 context->recover();
1568 TType* structure = new TType(new TStructure($2.string, $5));
1569 TVariable* userTypeDef = new TVariable($2.string, *structure, true);
1570 if (! context->symbolTable.insert(*userTypeDef)) {
1571 context->error(@2, "redefinition", $2.string->c_str(), "struct");
1572 context->recover();
1573 }
1574 $$.setBasic(EbtStruct, EvqTemporary, @1);
1575 $$.userDef = structure;
1576 context->exitStructDeclaration();
1577 }
1578 | STRUCT LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
1579 TType* structure = new TType(new TStructure(NewPoolTString(""), $4));
1580 $$.setBasic(EbtStruct, EvqTemporary, @1);
1581 $$.userDef = structure;
1582 context->exitStructDeclaration();
1583 }
1584 ;
1586 struct_declaration_list
1587 : struct_declaration {
1588 $$ = $1;
1589 }
1590 | struct_declaration_list struct_declaration {
1591 $$ = $1;
1592 for (size_t i = 0; i < $2->size(); ++i) {
1593 TField* field = (*$2)[i];
1594 for (size_t j = 0; j < $$->size(); ++j) {
1595 if ((*$$)[j]->name() == field->name()) {
1596 context->error(@2, "duplicate field name in structure:", "struct", field->name().c_str());
1597 context->recover();
1598 }
1599 }
1600 $$->push_back(field);
1601 }
1602 }
1603 ;
1605 struct_declaration
1606 : type_specifier struct_declarator_list SEMICOLON {
1607 $$ = $2;
1609 if (context->voidErrorCheck(@1, (*$2)[0]->name(), $1)) {
1610 context->recover();
1611 }
1612 for (unsigned int i = 0; i < $$->size(); ++i) {
1613 //
1614 // Careful not to replace already known aspects of type, like array-ness
1615 //
1616 TType* type = (*$$)[i]->type();
1617 type->setBasicType($1.type);
1618 type->setNominalSize($1.size);
1619 type->setMatrix($1.matrix);
1620 type->setPrecision($1.precision);
1622 // don't allow arrays of arrays
1623 if (type->isArray()) {
1624 if (context->arrayTypeErrorCheck(@1, $1))
1625 context->recover();
1626 }
1627 if ($1.array)
1628 type->setArraySize($1.arraySize);
1629 if ($1.userDef)
1630 type->setStruct($1.userDef->getStruct());
1632 if (context->structNestingErrorCheck(@1, *(*$$)[i]))
1633 context->recover();
1634 }
1635 }
1636 ;
1638 struct_declarator_list
1639 : struct_declarator {
1640 $$ = NewPoolTFieldList();
1641 $$->push_back($1);
1642 }
1643 | struct_declarator_list COMMA struct_declarator {
1644 $$->push_back($3);
1645 }
1646 ;
1648 struct_declarator
1649 : identifier {
1650 if (context->reservedErrorCheck(@1, *$1.string))
1651 context->recover();
1653 TType* type = new TType(EbtVoid, EbpUndefined);
1654 $$ = new TField(type, $1.string);
1655 }
1656 | identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
1657 if (context->reservedErrorCheck(@1, *$1.string))
1658 context->recover();
1660 TType* type = new TType(EbtVoid, EbpUndefined);
1661 int size = 0;
1662 if (context->arraySizeErrorCheck(@3, $3, size))
1663 context->recover();
1664 type->setArraySize(size);
1666 $$ = new TField(type, $1.string);
1667 }
1668 ;
1670 initializer
1671 : assignment_expression { $$ = $1; }
1672 ;
1674 declaration_statement
1675 : declaration { $$ = $1; }
1676 ;
1678 statement
1679 : compound_statement { $$ = $1; }
1680 | simple_statement { $$ = $1; }
1681 ;
1683 // Grammar Note: No labeled statements; 'goto' is not supported.
1685 simple_statement
1686 : declaration_statement { $$ = $1; }
1687 | expression_statement { $$ = $1; }
1688 | selection_statement { $$ = $1; }
1689 | iteration_statement { $$ = $1; }
1690 | jump_statement { $$ = $1; }
1691 ;
1693 compound_statement
1694 : LEFT_BRACE RIGHT_BRACE { $$ = 0; }
1695 | LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE {
1696 if ($3 != 0) {
1697 $3->setOp(EOpSequence);
1698 $3->setLine(@$);
1699 }
1700 $$ = $3;
1701 }
1702 ;
1704 statement_no_new_scope
1705 : compound_statement_no_new_scope { $$ = $1; }
1706 | simple_statement { $$ = $1; }
1707 ;
1709 statement_with_scope
1710 : { context->symbolTable.push(); } compound_statement_no_new_scope { context->symbolTable.pop(); $$ = $2; }
1711 | { context->symbolTable.push(); } simple_statement { context->symbolTable.pop(); $$ = $2; }
1712 ;
1714 compound_statement_no_new_scope
1715 // Statement that doesn't create a new scope, for selection_statement, iteration_statement
1716 : LEFT_BRACE RIGHT_BRACE {
1717 $$ = 0;
1718 }
1719 | LEFT_BRACE statement_list RIGHT_BRACE {
1720 if ($2) {
1721 $2->setOp(EOpSequence);
1722 $2->setLine(@$);
1723 }
1724 $$ = $2;
1725 }
1726 ;
1728 statement_list
1729 : statement {
1730 $$ = context->intermediate.makeAggregate($1, @$);
1731 }
1732 | statement_list statement {
1733 $$ = context->intermediate.growAggregate($1, $2, @$);
1734 }
1735 ;
1737 expression_statement
1738 : SEMICOLON { $$ = 0; }
1739 | expression SEMICOLON { $$ = static_cast<TIntermNode*>($1); }
1740 ;
1742 selection_statement
1743 : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
1744 if (context->boolErrorCheck(@1, $3))
1745 context->recover();
1746 $$ = context->intermediate.addSelection($3, $5, @1);
1747 }
1748 ;
1750 selection_rest_statement
1751 : statement_with_scope ELSE statement_with_scope {
1752 $$.node1 = $1;
1753 $$.node2 = $3;
1754 }
1755 | statement_with_scope {
1756 $$.node1 = $1;
1757 $$.node2 = 0;
1758 }
1759 ;
1761 // Grammar Note: No 'switch'. Switch statements not supported.
1763 condition
1764 // In 1996 c++ draft, conditions can include single declarations
1765 : expression {
1766 $$ = $1;
1767 if (context->boolErrorCheck($1->getLine(), $1))
1768 context->recover();
1769 }
1770 | fully_specified_type identifier EQUAL initializer {
1771 TIntermNode* intermNode;
1772 if (context->structQualifierErrorCheck(@2, $1))
1773 context->recover();
1774 if (context->boolErrorCheck(@2, $1))
1775 context->recover();
1777 if (!context->executeInitializer(@2, *$2.string, $1, $4, intermNode))
1778 $$ = $4;
1779 else {
1780 context->recover();
1781 $$ = 0;
1782 }
1783 }
1784 ;
1786 iteration_statement
1787 : WHILE LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope {
1788 context->symbolTable.pop();
1789 $$ = context->intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, @1);
1790 --context->loopNestingLevel;
1791 }
1792 | DO { ++context->loopNestingLevel; } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
1793 if (context->boolErrorCheck(@8, $6))
1794 context->recover();
1796 $$ = context->intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, @4);
1797 --context->loopNestingLevel;
1798 }
1799 | FOR LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
1800 context->symbolTable.pop();
1801 $$ = context->intermediate.addLoop(ELoopFor, $4, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), $7, @1);
1802 --context->loopNestingLevel;
1803 }
1804 ;
1806 for_init_statement
1807 : expression_statement {
1808 $$ = $1;
1809 }
1810 | declaration_statement {
1811 $$ = $1;
1812 }
1813 ;
1815 conditionopt
1816 : condition {
1817 $$ = $1;
1818 }
1819 | /* May be null */ {
1820 $$ = 0;
1821 }
1822 ;
1824 for_rest_statement
1825 : conditionopt SEMICOLON {
1826 $$.node1 = $1;
1827 $$.node2 = 0;
1828 }
1829 | conditionopt SEMICOLON expression {
1830 $$.node1 = $1;
1831 $$.node2 = $3;
1832 }
1833 ;
1835 jump_statement
1836 : CONTINUE SEMICOLON {
1837 if (context->loopNestingLevel <= 0) {
1838 context->error(@1, "continue statement only allowed in loops", "");
1839 context->recover();
1840 }
1841 $$ = context->intermediate.addBranch(EOpContinue, @1);
1842 }
1843 | BREAK SEMICOLON {
1844 if (context->loopNestingLevel <= 0) {
1845 context->error(@1, "break statement only allowed in loops", "");
1846 context->recover();
1847 }
1848 $$ = context->intermediate.addBranch(EOpBreak, @1);
1849 }
1850 | RETURN SEMICOLON {
1851 $$ = context->intermediate.addBranch(EOpReturn, @1);
1852 if (context->currentFunctionType->getBasicType() != EbtVoid) {
1853 context->error(@1, "non-void function must return a value", "return");
1854 context->recover();
1855 }
1856 }
1857 | RETURN expression SEMICOLON {
1858 $$ = context->intermediate.addBranch(EOpReturn, $2, @1);
1859 context->functionReturnsValue = true;
1860 if (context->currentFunctionType->getBasicType() == EbtVoid) {
1861 context->error(@1, "void function cannot return a value", "return");
1862 context->recover();
1863 } else if (*(context->currentFunctionType) != $2->getType()) {
1864 context->error(@1, "function return is not matching type:", "return");
1865 context->recover();
1866 }
1867 }
1868 | DISCARD SEMICOLON {
1869 FRAG_ONLY("discard", @1);
1870 $$ = context->intermediate.addBranch(EOpKill, @1);
1871 }
1872 ;
1874 // Grammar Note: No 'goto'. Gotos are not supported.
1876 translation_unit
1877 : external_declaration {
1878 $$ = $1;
1879 context->treeRoot = $$;
1880 }
1881 | translation_unit external_declaration {
1882 $$ = context->intermediate.growAggregate($1, $2, @$);
1883 context->treeRoot = $$;
1884 }
1885 ;
1887 external_declaration
1888 : function_definition {
1889 $$ = $1;
1890 }
1891 | declaration {
1892 $$ = $1;
1893 }
1894 ;
1896 function_definition
1897 : function_prototype {
1898 TFunction* function = $1.function;
1900 const TSymbol *builtIn = context->symbolTable.findBuiltIn(function->getMangledName());
1902 if (builtIn)
1903 {
1904 context->error(@1, "built-in functions cannot be redefined", function->getName().c_str());
1905 context->recover();
1906 }
1908 TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find(function->getMangledName()));
1909 //
1910 // Note: 'prevDec' could be 'function' if this is the first time we've seen function
1911 // as it would have just been put in the symbol table. Otherwise, we're looking up
1912 // an earlier occurance.
1913 //
1914 if (prevDec->isDefined()) {
1915 //
1916 // Then this function already has a body.
1917 //
1918 context->error(@1, "function already has a body", function->getName().c_str());
1919 context->recover();
1920 }
1921 prevDec->setDefined();
1923 //
1924 // Raise error message if main function takes any parameters or return anything other than void
1925 //
1926 if (function->getName() == "main") {
1927 if (function->getParamCount() > 0) {
1928 context->error(@1, "function cannot take any parameter(s)", function->getName().c_str());
1929 context->recover();
1930 }
1931 if (function->getReturnType().getBasicType() != EbtVoid) {
1932 context->error(@1, "", function->getReturnType().getBasicString(), "main function cannot return a value");
1933 context->recover();
1934 }
1935 }
1937 //
1938 // Remember the return type for later checking for RETURN statements.
1939 //
1940 context->currentFunctionType = &(prevDec->getReturnType());
1941 context->functionReturnsValue = false;
1943 //
1944 // Insert parameters into the symbol table.
1945 // If the parameter has no name, it's not an error, just don't insert it
1946 // (could be used for unused args).
1947 //
1948 // Also, accumulate the list of parameters into the HIL, so lower level code
1949 // knows where to find parameters.
1950 //
1951 TIntermAggregate* paramNodes = new TIntermAggregate;
1952 for (size_t i = 0; i < function->getParamCount(); i++) {
1953 const TParameter& param = function->getParam(i);
1954 if (param.name != 0) {
1955 TVariable *variable = new TVariable(param.name, *param.type);
1956 //
1957 // Insert the parameters with name in the symbol table.
1958 //
1959 if (! context->symbolTable.insert(*variable)) {
1960 context->error(@1, "redefinition", variable->getName().c_str());
1961 context->recover();
1962 delete variable;
1963 }
1965 //
1966 // Add the parameter to the HIL
1967 //
1968 paramNodes = context->intermediate.growAggregate(
1969 paramNodes,
1970 context->intermediate.addSymbol(variable->getUniqueId(),
1971 variable->getName(),
1972 variable->getType(),
1973 @1),
1974 @1);
1975 } else {
1976 paramNodes = context->intermediate.growAggregate(paramNodes, context->intermediate.addSymbol(0, "", *param.type, @1), @1);
1977 }
1978 }
1979 context->intermediate.setAggregateOperator(paramNodes, EOpParameters, @1);
1980 $1.intermAggregate = paramNodes;
1981 context->loopNestingLevel = 0;
1982 }
1983 compound_statement_no_new_scope {
1984 //?? Check that all paths return a value if return type != void ?
1985 // May be best done as post process phase on intermediate code
1986 if (context->currentFunctionType->getBasicType() != EbtVoid && ! context->functionReturnsValue) {
1987 context->error(@1, "function does not return a value:", "", $1.function->getName().c_str());
1988 context->recover();
1989 }
1991 $$ = context->intermediate.growAggregate($1.intermAggregate, $3, @$);
1992 context->intermediate.setAggregateOperator($$, EOpFunction, @1);
1993 $$->getAsAggregate()->setName($1.function->getMangledName().c_str());
1994 $$->getAsAggregate()->setType($1.function->getReturnType());
1996 // store the pragma information for debug and optimize and other vendor specific
1997 // information. This information can be queried from the parse tree
1998 $$->getAsAggregate()->setOptimize(context->pragma().optimize);
1999 $$->getAsAggregate()->setDebug(context->pragma().debug);
2001 context->symbolTable.pop();
2002 }
2003 ;
2005 %%
2007 void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason) {
2008 context->error(*yylloc, reason, "");
2009 context->recover();
2010 }
2012 int glslang_parse(TParseContext* context) {
2013 return yyparse(context);
2014 }