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