1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/angle/src/compiler/glslang.y Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,2014 @@ 1.4 +/* 1.5 +// 1.6 +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. 1.7 +// Use of this source code is governed by a BSD-style license that can be 1.8 +// found in the LICENSE file. 1.9 +// 1.10 + 1.11 +This file contains the Yacc grammar for GLSL ES. 1.12 +Based on ANSI C Yacc grammar: 1.13 +http://www.lysator.liu.se/c/ANSI-C-grammar-y.html 1.14 + 1.15 +IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh, 1.16 +WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). 1.17 +*/ 1.18 + 1.19 +%{ 1.20 +// 1.21 +// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. 1.22 +// Use of this source code is governed by a BSD-style license that can be 1.23 +// found in the LICENSE file. 1.24 +// 1.25 + 1.26 +// This file is auto-generated by generate_parser.sh. DO NOT EDIT! 1.27 + 1.28 +// Ignore errors in auto-generated code. 1.29 +#if defined(__GNUC__) 1.30 +#pragma GCC diagnostic ignored "-Wunused-function" 1.31 +#pragma GCC diagnostic ignored "-Wunused-variable" 1.32 +#pragma GCC diagnostic ignored "-Wswitch-enum" 1.33 +#elif defined(_MSC_VER) 1.34 +#pragma warning(disable: 4065) 1.35 +#pragma warning(disable: 4189) 1.36 +#pragma warning(disable: 4505) 1.37 +#pragma warning(disable: 4701) 1.38 +#endif 1.39 + 1.40 +#include "compiler/SymbolTable.h" 1.41 +#include "compiler/ParseHelper.h" 1.42 +#include "GLSLANG/ShaderLang.h" 1.43 + 1.44 +#define YYENABLE_NLS 0 1.45 + 1.46 +#define YYLEX_PARAM context->scanner 1.47 +%} 1.48 + 1.49 +%expect 1 /* One shift reduce conflict because of if | else */ 1.50 +%pure-parser 1.51 +%parse-param {TParseContext* context} 1.52 +%locations 1.53 + 1.54 +%code requires { 1.55 +#define YYLTYPE TSourceLoc 1.56 +#define YYLTYPE_IS_DECLARED 1 1.57 +} 1.58 + 1.59 +%union { 1.60 + struct { 1.61 + union { 1.62 + TString *string; 1.63 + float f; 1.64 + int i; 1.65 + bool b; 1.66 + }; 1.67 + TSymbol* symbol; 1.68 + } lex; 1.69 + struct { 1.70 + TOperator op; 1.71 + union { 1.72 + TIntermNode* intermNode; 1.73 + TIntermNodePair nodePair; 1.74 + TIntermTyped* intermTypedNode; 1.75 + TIntermAggregate* intermAggregate; 1.76 + }; 1.77 + union { 1.78 + TPublicType type; 1.79 + TPrecision precision; 1.80 + TQualifier qualifier; 1.81 + TFunction* function; 1.82 + TParameter param; 1.83 + TField* field; 1.84 + TFieldList* fieldList; 1.85 + }; 1.86 + } interm; 1.87 +} 1.88 + 1.89 +%{ 1.90 +extern int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, void* yyscanner); 1.91 +static void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason); 1.92 + 1.93 +#define YYLLOC_DEFAULT(Current, Rhs, N) \ 1.94 + do { \ 1.95 + if (YYID(N)) { \ 1.96 + (Current).first_file = YYRHSLOC(Rhs, 1).first_file; \ 1.97 + (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ 1.98 + (Current).last_file = YYRHSLOC(Rhs, N).last_file; \ 1.99 + (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ 1.100 + } \ 1.101 + else { \ 1.102 + (Current).first_file = YYRHSLOC(Rhs, 0).last_file; \ 1.103 + (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \ 1.104 + (Current).last_file = YYRHSLOC(Rhs, 0).last_file; \ 1.105 + (Current).last_line = YYRHSLOC(Rhs, 0).last_line; \ 1.106 + } \ 1.107 + } while (0) 1.108 + 1.109 +#define VERTEX_ONLY(S, L) { \ 1.110 + if (context->shaderType != SH_VERTEX_SHADER) { \ 1.111 + context->error(L, " supported in vertex shaders only ", S); \ 1.112 + context->recover(); \ 1.113 + } \ 1.114 +} 1.115 + 1.116 +#define FRAG_ONLY(S, L) { \ 1.117 + if (context->shaderType != SH_FRAGMENT_SHADER) { \ 1.118 + context->error(L, " supported in fragment shaders only ", S); \ 1.119 + context->recover(); \ 1.120 + } \ 1.121 +} 1.122 +%} 1.123 + 1.124 +%token <lex> INVARIANT HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION 1.125 +%token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE 1.126 +%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN 1.127 +%token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4 1.128 +%token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING 1.129 +%token <lex> STRUCT VOID_TYPE WHILE 1.130 +%token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER2DRECT 1.131 + 1.132 +%token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT BOOLCONSTANT 1.133 +%token <lex> LEFT_OP RIGHT_OP 1.134 +%token <lex> INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP 1.135 +%token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN 1.136 +%token <lex> MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN 1.137 +%token <lex> SUB_ASSIGN 1.138 + 1.139 +%token <lex> LEFT_PAREN RIGHT_PAREN LEFT_BRACKET RIGHT_BRACKET LEFT_BRACE RIGHT_BRACE DOT 1.140 +%token <lex> COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT 1.141 +%token <lex> LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION 1.142 + 1.143 +%type <lex> identifier 1.144 +%type <interm> assignment_operator unary_operator 1.145 +%type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression 1.146 +%type <interm.intermTypedNode> expression integer_expression assignment_expression 1.147 +%type <interm.intermTypedNode> unary_expression multiplicative_expression additive_expression 1.148 +%type <interm.intermTypedNode> relational_expression equality_expression 1.149 +%type <interm.intermTypedNode> conditional_expression constant_expression 1.150 +%type <interm.intermTypedNode> logical_or_expression logical_xor_expression logical_and_expression 1.151 +%type <interm.intermTypedNode> shift_expression and_expression exclusive_or_expression inclusive_or_expression 1.152 +%type <interm.intermTypedNode> function_call initializer condition conditionopt 1.153 + 1.154 +%type <interm.intermNode> translation_unit function_definition 1.155 +%type <interm.intermNode> statement simple_statement 1.156 +%type <interm.intermAggregate> statement_list compound_statement 1.157 +%type <interm.intermNode> declaration_statement selection_statement expression_statement 1.158 +%type <interm.intermNode> declaration external_declaration 1.159 +%type <interm.intermNode> for_init_statement compound_statement_no_new_scope 1.160 +%type <interm.nodePair> selection_rest_statement for_rest_statement 1.161 +%type <interm.intermNode> iteration_statement jump_statement statement_no_new_scope statement_with_scope 1.162 +%type <interm> single_declaration init_declarator_list 1.163 + 1.164 +%type <interm> parameter_declaration parameter_declarator parameter_type_specifier 1.165 +%type <interm.qualifier> parameter_qualifier 1.166 + 1.167 +%type <interm.precision> precision_qualifier 1.168 +%type <interm.type> type_qualifier fully_specified_type type_specifier 1.169 +%type <interm.type> type_specifier_no_prec type_specifier_nonarray 1.170 +%type <interm.type> struct_specifier 1.171 +%type <interm.field> struct_declarator 1.172 +%type <interm.fieldList> struct_declarator_list struct_declaration struct_declaration_list 1.173 +%type <interm.function> function_header function_declarator function_identifier 1.174 +%type <interm.function> function_header_with_parameters function_call_header 1.175 +%type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype 1.176 +%type <interm> function_call_or_method 1.177 + 1.178 +%start translation_unit 1.179 +%% 1.180 + 1.181 +identifier 1.182 + : IDENTIFIER 1.183 + | TYPE_NAME 1.184 + 1.185 +variable_identifier 1.186 + : IDENTIFIER { 1.187 + // The symbol table search was done in the lexical phase 1.188 + const TSymbol* symbol = $1.symbol; 1.189 + const TVariable* variable; 1.190 + if (symbol == 0) { 1.191 + context->error(@1, "undeclared identifier", $1.string->c_str()); 1.192 + context->recover(); 1.193 + TType type(EbtFloat, EbpUndefined); 1.194 + TVariable* fakeVariable = new TVariable($1.string, type); 1.195 + context->symbolTable.insert(*fakeVariable); 1.196 + variable = fakeVariable; 1.197 + } else { 1.198 + // This identifier can only be a variable type symbol 1.199 + if (! symbol->isVariable()) { 1.200 + context->error(@1, "variable expected", $1.string->c_str()); 1.201 + context->recover(); 1.202 + } 1.203 + 1.204 + variable = static_cast<const TVariable*>(symbol); 1.205 + 1.206 + if (context->symbolTable.findBuiltIn(variable->getName()) && 1.207 + !variable->getExtension().empty() && 1.208 + context->extensionErrorCheck(@1, variable->getExtension())) { 1.209 + context->recover(); 1.210 + } 1.211 + } 1.212 + 1.213 + // don't delete $1.string, it's used by error recovery, and the pool 1.214 + // pop will reclaim the memory 1.215 + 1.216 + if (variable->getType().getQualifier() == EvqConst ) { 1.217 + ConstantUnion* constArray = variable->getConstPointer(); 1.218 + TType t(variable->getType()); 1.219 + $$ = context->intermediate.addConstantUnion(constArray, t, @1); 1.220 + } else 1.221 + $$ = context->intermediate.addSymbol(variable->getUniqueId(), 1.222 + variable->getName(), 1.223 + variable->getType(), 1.224 + @1); 1.225 + } 1.226 + ; 1.227 + 1.228 +primary_expression 1.229 + : variable_identifier { 1.230 + $$ = $1; 1.231 + } 1.232 + | INTCONSTANT { 1.233 + // 1.234 + // INT_TYPE is only 16-bit plus sign bit for vertex/fragment shaders, 1.235 + // check for overflow for constants 1.236 + // 1.237 + if (abs($1.i) >= (1 << 16)) { 1.238 + context->error(@1, " integer constant overflow", ""); 1.239 + context->recover(); 1.240 + } 1.241 + ConstantUnion *unionArray = new ConstantUnion[1]; 1.242 + unionArray->setIConst($1.i); 1.243 + $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @1); 1.244 + } 1.245 + | FLOATCONSTANT { 1.246 + ConstantUnion *unionArray = new ConstantUnion[1]; 1.247 + unionArray->setFConst($1.f); 1.248 + $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), @1); 1.249 + } 1.250 + | BOOLCONSTANT { 1.251 + ConstantUnion *unionArray = new ConstantUnion[1]; 1.252 + unionArray->setBConst($1.b); 1.253 + $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @1); 1.254 + } 1.255 + | LEFT_PAREN expression RIGHT_PAREN { 1.256 + $$ = $2; 1.257 + } 1.258 + ; 1.259 + 1.260 +postfix_expression 1.261 + : primary_expression { 1.262 + $$ = $1; 1.263 + } 1.264 + | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET { 1.265 + $$ = context->addIndexExpression($1, @2, $3); 1.266 + } 1.267 + | function_call { 1.268 + $$ = $1; 1.269 + } 1.270 + | postfix_expression DOT identifier { 1.271 + if ($1->isArray()) { 1.272 + context->error(@3, "cannot apply dot operator to an array", "."); 1.273 + context->recover(); 1.274 + } 1.275 + 1.276 + if ($1->isVector()) { 1.277 + TVectorFields fields; 1.278 + if (! context->parseVectorFields(*$3.string, $1->getNominalSize(), fields, @3)) { 1.279 + fields.num = 1; 1.280 + fields.offsets[0] = 0; 1.281 + context->recover(); 1.282 + } 1.283 + 1.284 + if ($1->getType().getQualifier() == EvqConst) { // constant folding for vector fields 1.285 + $$ = context->addConstVectorNode(fields, $1, @3); 1.286 + if ($$ == 0) { 1.287 + context->recover(); 1.288 + $$ = $1; 1.289 + } 1.290 + else 1.291 + $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst, (int) (*$3.string).size())); 1.292 + } else { 1.293 + TString vectorString = *$3.string; 1.294 + TIntermTyped* index = context->intermediate.addSwizzle(fields, @3); 1.295 + $$ = context->intermediate.addIndex(EOpVectorSwizzle, $1, index, @2); 1.296 + $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, (int) vectorString.size())); 1.297 + } 1.298 + } else if ($1->isMatrix()) { 1.299 + TMatrixFields fields; 1.300 + if (! context->parseMatrixFields(*$3.string, $1->getNominalSize(), fields, @3)) { 1.301 + fields.wholeRow = false; 1.302 + fields.wholeCol = false; 1.303 + fields.row = 0; 1.304 + fields.col = 0; 1.305 + context->recover(); 1.306 + } 1.307 + 1.308 + if (fields.wholeRow || fields.wholeCol) { 1.309 + context->error(@2, " non-scalar fields not implemented yet", "."); 1.310 + context->recover(); 1.311 + ConstantUnion *unionArray = new ConstantUnion[1]; 1.312 + unionArray->setIConst(0); 1.313 + TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @3); 1.314 + $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, @2); 1.315 + $$->setType(TType($1->getBasicType(), $1->getPrecision(),EvqTemporary, $1->getNominalSize())); 1.316 + } else { 1.317 + ConstantUnion *unionArray = new ConstantUnion[1]; 1.318 + unionArray->setIConst(fields.col * $1->getNominalSize() + fields.row); 1.319 + TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @3); 1.320 + $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, @2); 1.321 + $$->setType(TType($1->getBasicType(), $1->getPrecision())); 1.322 + } 1.323 + } else if ($1->getBasicType() == EbtStruct) { 1.324 + bool fieldFound = false; 1.325 + const TFieldList& fields = $1->getType().getStruct()->fields(); 1.326 + unsigned int i; 1.327 + for (i = 0; i < fields.size(); ++i) { 1.328 + if (fields[i]->name() == *$3.string) { 1.329 + fieldFound = true; 1.330 + break; 1.331 + } 1.332 + } 1.333 + if (fieldFound) { 1.334 + if ($1->getType().getQualifier() == EvqConst) { 1.335 + $$ = context->addConstStruct(*$3.string, $1, @2); 1.336 + if ($$ == 0) { 1.337 + context->recover(); 1.338 + $$ = $1; 1.339 + } 1.340 + else { 1.341 + $$->setType(*fields[i]->type()); 1.342 + // change the qualifier of the return type, not of the structure field 1.343 + // as the structure definition is shared between various structures. 1.344 + $$->getTypePointer()->setQualifier(EvqConst); 1.345 + } 1.346 + } else { 1.347 + ConstantUnion *unionArray = new ConstantUnion[1]; 1.348 + unionArray->setIConst(i); 1.349 + TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *fields[i]->type(), @3); 1.350 + $$ = context->intermediate.addIndex(EOpIndexDirectStruct, $1, index, @2); 1.351 + $$->setType(*fields[i]->type()); 1.352 + } 1.353 + } else { 1.354 + context->error(@2, " no such field in structure", $3.string->c_str()); 1.355 + context->recover(); 1.356 + $$ = $1; 1.357 + } 1.358 + } else { 1.359 + context->error(@2, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str()); 1.360 + context->recover(); 1.361 + $$ = $1; 1.362 + } 1.363 + // don't delete $3.string, it's from the pool 1.364 + } 1.365 + | postfix_expression INC_OP { 1.366 + if (context->lValueErrorCheck(@2, "++", $1)) 1.367 + context->recover(); 1.368 + $$ = context->intermediate.addUnaryMath(EOpPostIncrement, $1, @2, context->symbolTable); 1.369 + if ($$ == 0) { 1.370 + context->unaryOpError(@2, "++", $1->getCompleteString()); 1.371 + context->recover(); 1.372 + $$ = $1; 1.373 + } 1.374 + } 1.375 + | postfix_expression DEC_OP { 1.376 + if (context->lValueErrorCheck(@2, "--", $1)) 1.377 + context->recover(); 1.378 + $$ = context->intermediate.addUnaryMath(EOpPostDecrement, $1, @2, context->symbolTable); 1.379 + if ($$ == 0) { 1.380 + context->unaryOpError(@2, "--", $1->getCompleteString()); 1.381 + context->recover(); 1.382 + $$ = $1; 1.383 + } 1.384 + } 1.385 + ; 1.386 + 1.387 +integer_expression 1.388 + : expression { 1.389 + if (context->integerErrorCheck($1, "[]")) 1.390 + context->recover(); 1.391 + $$ = $1; 1.392 + } 1.393 + ; 1.394 + 1.395 +function_call 1.396 + : function_call_or_method { 1.397 + TFunction* fnCall = $1.function; 1.398 + TOperator op = fnCall->getBuiltInOp(); 1.399 + 1.400 + if (op != EOpNull) 1.401 + { 1.402 + // 1.403 + // Then this should be a constructor. 1.404 + // Don't go through the symbol table for constructors. 1.405 + // Their parameters will be verified algorithmically. 1.406 + // 1.407 + TType type(EbtVoid, EbpUndefined); // use this to get the type back 1.408 + if (context->constructorErrorCheck(@1, $1.intermNode, *fnCall, op, &type)) { 1.409 + $$ = 0; 1.410 + } else { 1.411 + // 1.412 + // It's a constructor, of type 'type'. 1.413 + // 1.414 + $$ = context->addConstructor($1.intermNode, &type, op, fnCall, @1); 1.415 + } 1.416 + 1.417 + if ($$ == 0) { 1.418 + context->recover(); 1.419 + $$ = context->intermediate.setAggregateOperator(0, op, @1); 1.420 + } 1.421 + $$->setType(type); 1.422 + } else { 1.423 + // 1.424 + // Not a constructor. Find it in the symbol table. 1.425 + // 1.426 + const TFunction* fnCandidate; 1.427 + bool builtIn; 1.428 + fnCandidate = context->findFunction(@1, fnCall, &builtIn); 1.429 + if (fnCandidate) { 1.430 + // 1.431 + // A declared function. 1.432 + // 1.433 + if (builtIn && !fnCandidate->getExtension().empty() && 1.434 + context->extensionErrorCheck(@1, fnCandidate->getExtension())) { 1.435 + context->recover(); 1.436 + } 1.437 + op = fnCandidate->getBuiltInOp(); 1.438 + if (builtIn && op != EOpNull) { 1.439 + // 1.440 + // A function call mapped to a built-in operation. 1.441 + // 1.442 + if (fnCandidate->getParamCount() == 1) { 1.443 + // 1.444 + // Treat it like a built-in unary operator. 1.445 + // 1.446 + $$ = context->intermediate.addUnaryMath(op, $1.intermNode, @1, context->symbolTable); 1.447 + if ($$ == 0) { 1.448 + std::stringstream extraInfoStream; 1.449 + extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>($1.intermNode)->getCompleteString(); 1.450 + std::string extraInfo = extraInfoStream.str(); 1.451 + context->error($1.intermNode->getLine(), " wrong operand type", "Internal Error", extraInfo.c_str()); 1.452 + YYERROR; 1.453 + } 1.454 + } else { 1.455 + $$ = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1); 1.456 + } 1.457 + } else { 1.458 + // This is a real function call 1.459 + 1.460 + $$ = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1); 1.461 + $$->setType(fnCandidate->getReturnType()); 1.462 + 1.463 + // this is how we know whether the given function is a builtIn function or a user defined function 1.464 + // if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also 1.465 + // if builtIn == true, it's definitely a builtIn function with EOpNull 1.466 + if (!builtIn) 1.467 + $$->getAsAggregate()->setUserDefined(); 1.468 + $$->getAsAggregate()->setName(fnCandidate->getMangledName()); 1.469 + 1.470 + TQualifier qual; 1.471 + for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) { 1.472 + qual = fnCandidate->getParam(i).type->getQualifier(); 1.473 + if (qual == EvqOut || qual == EvqInOut) { 1.474 + if (context->lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) { 1.475 + context->error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error"); 1.476 + context->recover(); 1.477 + } 1.478 + } 1.479 + } 1.480 + } 1.481 + $$->setType(fnCandidate->getReturnType()); 1.482 + } else { 1.483 + // error message was put out by PaFindFunction() 1.484 + // Put on a dummy node for error recovery 1.485 + ConstantUnion *unionArray = new ConstantUnion[1]; 1.486 + unionArray->setFConst(0.0f); 1.487 + $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), @1); 1.488 + context->recover(); 1.489 + } 1.490 + } 1.491 + delete fnCall; 1.492 + } 1.493 + ; 1.494 + 1.495 +function_call_or_method 1.496 + : function_call_generic { 1.497 + $$ = $1; 1.498 + } 1.499 + | postfix_expression DOT function_call_generic { 1.500 + context->error(@3, "methods are not supported", ""); 1.501 + context->recover(); 1.502 + $$ = $3; 1.503 + } 1.504 + ; 1.505 + 1.506 +function_call_generic 1.507 + : function_call_header_with_parameters RIGHT_PAREN { 1.508 + $$ = $1; 1.509 + } 1.510 + | function_call_header_no_parameters RIGHT_PAREN { 1.511 + $$ = $1; 1.512 + } 1.513 + ; 1.514 + 1.515 +function_call_header_no_parameters 1.516 + : function_call_header VOID_TYPE { 1.517 + $$.function = $1; 1.518 + $$.intermNode = 0; 1.519 + } 1.520 + | function_call_header { 1.521 + $$.function = $1; 1.522 + $$.intermNode = 0; 1.523 + } 1.524 + ; 1.525 + 1.526 +function_call_header_with_parameters 1.527 + : function_call_header assignment_expression { 1.528 + TParameter param = { 0, new TType($2->getType()) }; 1.529 + $1->addParameter(param); 1.530 + $$.function = $1; 1.531 + $$.intermNode = $2; 1.532 + } 1.533 + | function_call_header_with_parameters COMMA assignment_expression { 1.534 + TParameter param = { 0, new TType($3->getType()) }; 1.535 + $1.function->addParameter(param); 1.536 + $$.function = $1.function; 1.537 + $$.intermNode = context->intermediate.growAggregate($1.intermNode, $3, @2); 1.538 + } 1.539 + ; 1.540 + 1.541 +function_call_header 1.542 + : function_identifier LEFT_PAREN { 1.543 + $$ = $1; 1.544 + } 1.545 + ; 1.546 + 1.547 +// Grammar Note: Constructors look like functions, but are recognized as types. 1.548 + 1.549 +function_identifier 1.550 + : type_specifier_nonarray { 1.551 + // 1.552 + // Constructor 1.553 + // 1.554 + TOperator op = EOpNull; 1.555 + if ($1.userDef) { 1.556 + op = EOpConstructStruct; 1.557 + } else { 1.558 + switch ($1.type) { 1.559 + case EbtFloat: 1.560 + if ($1.matrix) { 1.561 + switch($1.size) { 1.562 + case 2: op = EOpConstructMat2; break; 1.563 + case 3: op = EOpConstructMat3; break; 1.564 + case 4: op = EOpConstructMat4; break; 1.565 + } 1.566 + } else { 1.567 + switch($1.size) { 1.568 + case 1: op = EOpConstructFloat; break; 1.569 + case 2: op = EOpConstructVec2; break; 1.570 + case 3: op = EOpConstructVec3; break; 1.571 + case 4: op = EOpConstructVec4; break; 1.572 + } 1.573 + } 1.574 + break; 1.575 + case EbtInt: 1.576 + switch($1.size) { 1.577 + case 1: op = EOpConstructInt; break; 1.578 + case 2: op = EOpConstructIVec2; break; 1.579 + case 3: op = EOpConstructIVec3; break; 1.580 + case 4: op = EOpConstructIVec4; break; 1.581 + } 1.582 + break; 1.583 + case EbtBool: 1.584 + switch($1.size) { 1.585 + case 1: op = EOpConstructBool; break; 1.586 + case 2: op = EOpConstructBVec2; break; 1.587 + case 3: op = EOpConstructBVec3; break; 1.588 + case 4: op = EOpConstructBVec4; break; 1.589 + } 1.590 + break; 1.591 + default: break; 1.592 + } 1.593 + if (op == EOpNull) { 1.594 + context->error(@1, "cannot construct this type", getBasicString($1.type)); 1.595 + context->recover(); 1.596 + $1.type = EbtFloat; 1.597 + op = EOpConstructFloat; 1.598 + } 1.599 + } 1.600 + TString tempString; 1.601 + TType type($1); 1.602 + TFunction *function = new TFunction(&tempString, type, op); 1.603 + $$ = function; 1.604 + } 1.605 + | IDENTIFIER { 1.606 + if (context->reservedErrorCheck(@1, *$1.string)) 1.607 + context->recover(); 1.608 + TType type(EbtVoid, EbpUndefined); 1.609 + TFunction *function = new TFunction($1.string, type); 1.610 + $$ = function; 1.611 + } 1.612 + ; 1.613 + 1.614 +unary_expression 1.615 + : postfix_expression { 1.616 + $$ = $1; 1.617 + } 1.618 + | INC_OP unary_expression { 1.619 + if (context->lValueErrorCheck(@1, "++", $2)) 1.620 + context->recover(); 1.621 + $$ = context->intermediate.addUnaryMath(EOpPreIncrement, $2, @1, context->symbolTable); 1.622 + if ($$ == 0) { 1.623 + context->unaryOpError(@1, "++", $2->getCompleteString()); 1.624 + context->recover(); 1.625 + $$ = $2; 1.626 + } 1.627 + } 1.628 + | DEC_OP unary_expression { 1.629 + if (context->lValueErrorCheck(@1, "--", $2)) 1.630 + context->recover(); 1.631 + $$ = context->intermediate.addUnaryMath(EOpPreDecrement, $2, @1, context->symbolTable); 1.632 + if ($$ == 0) { 1.633 + context->unaryOpError(@1, "--", $2->getCompleteString()); 1.634 + context->recover(); 1.635 + $$ = $2; 1.636 + } 1.637 + } 1.638 + | unary_operator unary_expression { 1.639 + if ($1.op != EOpNull) { 1.640 + $$ = context->intermediate.addUnaryMath($1.op, $2, @1, context->symbolTable); 1.641 + if ($$ == 0) { 1.642 + const char* errorOp = ""; 1.643 + switch($1.op) { 1.644 + case EOpNegative: errorOp = "-"; break; 1.645 + case EOpLogicalNot: errorOp = "!"; break; 1.646 + default: break; 1.647 + } 1.648 + context->unaryOpError(@1, errorOp, $2->getCompleteString()); 1.649 + context->recover(); 1.650 + $$ = $2; 1.651 + } 1.652 + } else 1.653 + $$ = $2; 1.654 + } 1.655 + ; 1.656 +// Grammar Note: No traditional style type casts. 1.657 + 1.658 +unary_operator 1.659 + : PLUS { $$.op = EOpNull; } 1.660 + | DASH { $$.op = EOpNegative; } 1.661 + | BANG { $$.op = EOpLogicalNot; } 1.662 + ; 1.663 +// Grammar Note: No '*' or '&' unary ops. Pointers are not supported. 1.664 + 1.665 +multiplicative_expression 1.666 + : unary_expression { $$ = $1; } 1.667 + | multiplicative_expression STAR unary_expression { 1.668 + $$ = context->intermediate.addBinaryMath(EOpMul, $1, $3, @2, context->symbolTable); 1.669 + if ($$ == 0) { 1.670 + context->binaryOpError(@2, "*", $1->getCompleteString(), $3->getCompleteString()); 1.671 + context->recover(); 1.672 + $$ = $1; 1.673 + } 1.674 + } 1.675 + | multiplicative_expression SLASH unary_expression { 1.676 + $$ = context->intermediate.addBinaryMath(EOpDiv, $1, $3, @2, context->symbolTable); 1.677 + if ($$ == 0) { 1.678 + context->binaryOpError(@2, "/", $1->getCompleteString(), $3->getCompleteString()); 1.679 + context->recover(); 1.680 + $$ = $1; 1.681 + } 1.682 + } 1.683 + ; 1.684 + 1.685 +additive_expression 1.686 + : multiplicative_expression { $$ = $1; } 1.687 + | additive_expression PLUS multiplicative_expression { 1.688 + $$ = context->intermediate.addBinaryMath(EOpAdd, $1, $3, @2, context->symbolTable); 1.689 + if ($$ == 0) { 1.690 + context->binaryOpError(@2, "+", $1->getCompleteString(), $3->getCompleteString()); 1.691 + context->recover(); 1.692 + $$ = $1; 1.693 + } 1.694 + } 1.695 + | additive_expression DASH multiplicative_expression { 1.696 + $$ = context->intermediate.addBinaryMath(EOpSub, $1, $3, @2, context->symbolTable); 1.697 + if ($$ == 0) { 1.698 + context->binaryOpError(@2, "-", $1->getCompleteString(), $3->getCompleteString()); 1.699 + context->recover(); 1.700 + $$ = $1; 1.701 + } 1.702 + } 1.703 + ; 1.704 + 1.705 +shift_expression 1.706 + : additive_expression { $$ = $1; } 1.707 + ; 1.708 + 1.709 +relational_expression 1.710 + : shift_expression { $$ = $1; } 1.711 + | relational_expression LEFT_ANGLE shift_expression { 1.712 + $$ = context->intermediate.addBinaryMath(EOpLessThan, $1, $3, @2, context->symbolTable); 1.713 + if ($$ == 0) { 1.714 + context->binaryOpError(@2, "<", $1->getCompleteString(), $3->getCompleteString()); 1.715 + context->recover(); 1.716 + ConstantUnion *unionArray = new ConstantUnion[1]; 1.717 + unionArray->setBConst(false); 1.718 + $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2); 1.719 + } 1.720 + } 1.721 + | relational_expression RIGHT_ANGLE shift_expression { 1.722 + $$ = context->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, @2, context->symbolTable); 1.723 + if ($$ == 0) { 1.724 + context->binaryOpError(@2, ">", $1->getCompleteString(), $3->getCompleteString()); 1.725 + context->recover(); 1.726 + ConstantUnion *unionArray = new ConstantUnion[1]; 1.727 + unionArray->setBConst(false); 1.728 + $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2); 1.729 + } 1.730 + } 1.731 + | relational_expression LE_OP shift_expression { 1.732 + $$ = context->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, @2, context->symbolTable); 1.733 + if ($$ == 0) { 1.734 + context->binaryOpError(@2, "<=", $1->getCompleteString(), $3->getCompleteString()); 1.735 + context->recover(); 1.736 + ConstantUnion *unionArray = new ConstantUnion[1]; 1.737 + unionArray->setBConst(false); 1.738 + $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2); 1.739 + } 1.740 + } 1.741 + | relational_expression GE_OP shift_expression { 1.742 + $$ = context->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, @2, context->symbolTable); 1.743 + if ($$ == 0) { 1.744 + context->binaryOpError(@2, ">=", $1->getCompleteString(), $3->getCompleteString()); 1.745 + context->recover(); 1.746 + ConstantUnion *unionArray = new ConstantUnion[1]; 1.747 + unionArray->setBConst(false); 1.748 + $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2); 1.749 + } 1.750 + } 1.751 + ; 1.752 + 1.753 +equality_expression 1.754 + : relational_expression { $$ = $1; } 1.755 + | equality_expression EQ_OP relational_expression { 1.756 + $$ = context->intermediate.addBinaryMath(EOpEqual, $1, $3, @2, context->symbolTable); 1.757 + if ($$ == 0) { 1.758 + context->binaryOpError(@2, "==", $1->getCompleteString(), $3->getCompleteString()); 1.759 + context->recover(); 1.760 + ConstantUnion *unionArray = new ConstantUnion[1]; 1.761 + unionArray->setBConst(false); 1.762 + $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2); 1.763 + } 1.764 + } 1.765 + | equality_expression NE_OP relational_expression { 1.766 + $$ = context->intermediate.addBinaryMath(EOpNotEqual, $1, $3, @2, context->symbolTable); 1.767 + if ($$ == 0) { 1.768 + context->binaryOpError(@2, "!=", $1->getCompleteString(), $3->getCompleteString()); 1.769 + context->recover(); 1.770 + ConstantUnion *unionArray = new ConstantUnion[1]; 1.771 + unionArray->setBConst(false); 1.772 + $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2); 1.773 + } 1.774 + } 1.775 + ; 1.776 + 1.777 +and_expression 1.778 + : equality_expression { $$ = $1; } 1.779 + ; 1.780 + 1.781 +exclusive_or_expression 1.782 + : and_expression { $$ = $1; } 1.783 + ; 1.784 + 1.785 +inclusive_or_expression 1.786 + : exclusive_or_expression { $$ = $1; } 1.787 + ; 1.788 + 1.789 +logical_and_expression 1.790 + : inclusive_or_expression { $$ = $1; } 1.791 + | logical_and_expression AND_OP inclusive_or_expression { 1.792 + $$ = context->intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, @2, context->symbolTable); 1.793 + if ($$ == 0) { 1.794 + context->binaryOpError(@2, "&&", $1->getCompleteString(), $3->getCompleteString()); 1.795 + context->recover(); 1.796 + ConstantUnion *unionArray = new ConstantUnion[1]; 1.797 + unionArray->setBConst(false); 1.798 + $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2); 1.799 + } 1.800 + } 1.801 + ; 1.802 + 1.803 +logical_xor_expression 1.804 + : logical_and_expression { $$ = $1; } 1.805 + | logical_xor_expression XOR_OP logical_and_expression { 1.806 + $$ = context->intermediate.addBinaryMath(EOpLogicalXor, $1, $3, @2, context->symbolTable); 1.807 + if ($$ == 0) { 1.808 + context->binaryOpError(@2, "^^", $1->getCompleteString(), $3->getCompleteString()); 1.809 + context->recover(); 1.810 + ConstantUnion *unionArray = new ConstantUnion[1]; 1.811 + unionArray->setBConst(false); 1.812 + $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2); 1.813 + } 1.814 + } 1.815 + ; 1.816 + 1.817 +logical_or_expression 1.818 + : logical_xor_expression { $$ = $1; } 1.819 + | logical_or_expression OR_OP logical_xor_expression { 1.820 + $$ = context->intermediate.addBinaryMath(EOpLogicalOr, $1, $3, @2, context->symbolTable); 1.821 + if ($$ == 0) { 1.822 + context->binaryOpError(@2, "||", $1->getCompleteString(), $3->getCompleteString()); 1.823 + context->recover(); 1.824 + ConstantUnion *unionArray = new ConstantUnion[1]; 1.825 + unionArray->setBConst(false); 1.826 + $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2); 1.827 + } 1.828 + } 1.829 + ; 1.830 + 1.831 +conditional_expression 1.832 + : logical_or_expression { $$ = $1; } 1.833 + | logical_or_expression QUESTION expression COLON assignment_expression { 1.834 + if (context->boolErrorCheck(@2, $1)) 1.835 + context->recover(); 1.836 + 1.837 + $$ = context->intermediate.addSelection($1, $3, $5, @2); 1.838 + if ($3->getType() != $5->getType()) 1.839 + $$ = 0; 1.840 + 1.841 + if ($$ == 0) { 1.842 + context->binaryOpError(@2, ":", $3->getCompleteString(), $5->getCompleteString()); 1.843 + context->recover(); 1.844 + $$ = $5; 1.845 + } 1.846 + } 1.847 + ; 1.848 + 1.849 +assignment_expression 1.850 + : conditional_expression { $$ = $1; } 1.851 + | unary_expression assignment_operator assignment_expression { 1.852 + if (context->lValueErrorCheck(@2, "assign", $1)) 1.853 + context->recover(); 1.854 + $$ = context->intermediate.addAssign($2.op, $1, $3, @2); 1.855 + if ($$ == 0) { 1.856 + context->assignError(@2, "assign", $1->getCompleteString(), $3->getCompleteString()); 1.857 + context->recover(); 1.858 + $$ = $1; 1.859 + } 1.860 + } 1.861 + ; 1.862 + 1.863 +assignment_operator 1.864 + : EQUAL { $$.op = EOpAssign; } 1.865 + | MUL_ASSIGN { $$.op = EOpMulAssign; } 1.866 + | DIV_ASSIGN { $$.op = EOpDivAssign; } 1.867 + | ADD_ASSIGN { $$.op = EOpAddAssign; } 1.868 + | SUB_ASSIGN { $$.op = EOpSubAssign; } 1.869 + ; 1.870 + 1.871 +expression 1.872 + : assignment_expression { 1.873 + $$ = $1; 1.874 + } 1.875 + | expression COMMA assignment_expression { 1.876 + $$ = context->intermediate.addComma($1, $3, @2); 1.877 + if ($$ == 0) { 1.878 + context->binaryOpError(@2, ",", $1->getCompleteString(), $3->getCompleteString()); 1.879 + context->recover(); 1.880 + $$ = $3; 1.881 + } 1.882 + } 1.883 + ; 1.884 + 1.885 +constant_expression 1.886 + : conditional_expression { 1.887 + if (context->constErrorCheck($1)) 1.888 + context->recover(); 1.889 + $$ = $1; 1.890 + } 1.891 + ; 1.892 + 1.893 +declaration 1.894 + : function_prototype SEMICOLON { 1.895 + TFunction &function = *($1.function); 1.896 + 1.897 + TIntermAggregate *prototype = new TIntermAggregate; 1.898 + prototype->setType(function.getReturnType()); 1.899 + prototype->setName(function.getName()); 1.900 + 1.901 + for (size_t i = 0; i < function.getParamCount(); i++) 1.902 + { 1.903 + const TParameter ¶m = function.getParam(i); 1.904 + if (param.name != 0) 1.905 + { 1.906 + TVariable variable(param.name, *param.type); 1.907 + 1.908 + prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), @1), @1); 1.909 + } 1.910 + else 1.911 + { 1.912 + prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, @1), @1); 1.913 + } 1.914 + } 1.915 + 1.916 + prototype->setOp(EOpPrototype); 1.917 + $$ = prototype; 1.918 + 1.919 + context->symbolTable.pop(); 1.920 + } 1.921 + | init_declarator_list SEMICOLON { 1.922 + if ($1.intermAggregate) 1.923 + $1.intermAggregate->setOp(EOpDeclaration); 1.924 + $$ = $1.intermAggregate; 1.925 + } 1.926 + | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON { 1.927 + if (($2 == EbpHigh) && (context->shaderType == SH_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) { 1.928 + context->error(@1, "precision is not supported in fragment shader", "highp"); 1.929 + context->recover(); 1.930 + } 1.931 + if (!context->symbolTable.setDefaultPrecision( $3, $2 )) { 1.932 + context->error(@1, "illegal type argument for default precision qualifier", getBasicString($3.type)); 1.933 + context->recover(); 1.934 + } 1.935 + $$ = 0; 1.936 + } 1.937 + ; 1.938 + 1.939 +function_prototype 1.940 + : function_declarator RIGHT_PAREN { 1.941 + // 1.942 + // Multiple declarations of the same function are allowed. 1.943 + // 1.944 + // If this is a definition, the definition production code will check for redefinitions 1.945 + // (we don't know at this point if it's a definition or not). 1.946 + // 1.947 + // Redeclarations are allowed. But, return types and parameter qualifiers must match. 1.948 + // 1.949 + TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find($1->getMangledName())); 1.950 + if (prevDec) { 1.951 + if (prevDec->getReturnType() != $1->getReturnType()) { 1.952 + context->error(@2, "overloaded functions must have the same return type", $1->getReturnType().getBasicString()); 1.953 + context->recover(); 1.954 + } 1.955 + for (size_t i = 0; i < prevDec->getParamCount(); ++i) { 1.956 + if (prevDec->getParam(i).type->getQualifier() != $1->getParam(i).type->getQualifier()) { 1.957 + context->error(@2, "overloaded functions must have the same parameter qualifiers", $1->getParam(i).type->getQualifierString()); 1.958 + context->recover(); 1.959 + } 1.960 + } 1.961 + } 1.962 + 1.963 + // 1.964 + // Check for previously declared variables using the same name. 1.965 + // 1.966 + TSymbol *prevSym = context->symbolTable.find($1->getName()); 1.967 + if (prevSym) 1.968 + { 1.969 + if (!prevSym->isFunction()) 1.970 + { 1.971 + context->error(@2, "redefinition", $1->getName().c_str(), "function"); 1.972 + context->recover(); 1.973 + } 1.974 + } 1.975 + else 1.976 + { 1.977 + // Insert the unmangled name to detect potential future redefinition as a variable. 1.978 + context->symbolTable.getOuterLevel()->insert($1->getName(), *$1); 1.979 + } 1.980 + 1.981 + // 1.982 + // If this is a redeclaration, it could also be a definition, 1.983 + // in which case, we want to use the variable names from this one, and not the one that's 1.984 + // being redeclared. So, pass back up this declaration, not the one in the symbol table. 1.985 + // 1.986 + $$.function = $1; 1.987 + 1.988 + // We're at the inner scope level of the function's arguments and body statement. 1.989 + // Add the function prototype to the surrounding scope instead. 1.990 + context->symbolTable.getOuterLevel()->insert(*$$.function); 1.991 + } 1.992 + ; 1.993 + 1.994 +function_declarator 1.995 + : function_header { 1.996 + $$ = $1; 1.997 + } 1.998 + | function_header_with_parameters { 1.999 + $$ = $1; 1.1000 + } 1.1001 + ; 1.1002 + 1.1003 + 1.1004 +function_header_with_parameters 1.1005 + : function_header parameter_declaration { 1.1006 + // Add the parameter 1.1007 + $$ = $1; 1.1008 + if ($2.param.type->getBasicType() != EbtVoid) 1.1009 + $1->addParameter($2.param); 1.1010 + else 1.1011 + delete $2.param.type; 1.1012 + } 1.1013 + | function_header_with_parameters COMMA parameter_declaration { 1.1014 + // 1.1015 + // Only first parameter of one-parameter functions can be void 1.1016 + // The check for named parameters not being void is done in parameter_declarator 1.1017 + // 1.1018 + if ($3.param.type->getBasicType() == EbtVoid) { 1.1019 + // 1.1020 + // This parameter > first is void 1.1021 + // 1.1022 + context->error(@2, "cannot be an argument type except for '(void)'", "void"); 1.1023 + context->recover(); 1.1024 + delete $3.param.type; 1.1025 + } else { 1.1026 + // Add the parameter 1.1027 + $$ = $1; 1.1028 + $1->addParameter($3.param); 1.1029 + } 1.1030 + } 1.1031 + ; 1.1032 + 1.1033 +function_header 1.1034 + : fully_specified_type IDENTIFIER LEFT_PAREN { 1.1035 + if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary) { 1.1036 + context->error(@2, "no qualifiers allowed for function return", getQualifierString($1.qualifier)); 1.1037 + context->recover(); 1.1038 + } 1.1039 + // make sure a sampler is not involved as well... 1.1040 + if (context->structQualifierErrorCheck(@2, $1)) 1.1041 + context->recover(); 1.1042 + 1.1043 + // Add the function as a prototype after parsing it (we do not support recursion) 1.1044 + TFunction *function; 1.1045 + TType type($1); 1.1046 + function = new TFunction($2.string, type); 1.1047 + $$ = function; 1.1048 + 1.1049 + context->symbolTable.push(); 1.1050 + } 1.1051 + ; 1.1052 + 1.1053 +parameter_declarator 1.1054 + // Type + name 1.1055 + : type_specifier identifier { 1.1056 + if ($1.type == EbtVoid) { 1.1057 + context->error(@2, "illegal use of type 'void'", $2.string->c_str()); 1.1058 + context->recover(); 1.1059 + } 1.1060 + if (context->reservedErrorCheck(@2, *$2.string)) 1.1061 + context->recover(); 1.1062 + TParameter param = {$2.string, new TType($1)}; 1.1063 + $$.param = param; 1.1064 + } 1.1065 + | type_specifier identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { 1.1066 + // Check that we can make an array out of this type 1.1067 + if (context->arrayTypeErrorCheck(@3, $1)) 1.1068 + context->recover(); 1.1069 + 1.1070 + if (context->reservedErrorCheck(@2, *$2.string)) 1.1071 + context->recover(); 1.1072 + 1.1073 + int size; 1.1074 + if (context->arraySizeErrorCheck(@3, $4, size)) 1.1075 + context->recover(); 1.1076 + $1.setArray(true, size); 1.1077 + 1.1078 + TType* type = new TType($1); 1.1079 + TParameter param = { $2.string, type }; 1.1080 + $$.param = param; 1.1081 + } 1.1082 + ; 1.1083 + 1.1084 +parameter_declaration 1.1085 + // 1.1086 + // The only parameter qualifier a parameter can have are 1.1087 + // IN_QUAL, OUT_QUAL, INOUT_QUAL, or CONST. 1.1088 + // 1.1089 + 1.1090 + // 1.1091 + // Type + name 1.1092 + // 1.1093 + : type_qualifier parameter_qualifier parameter_declarator { 1.1094 + $$ = $3; 1.1095 + if (context->paramErrorCheck(@3, $1.qualifier, $2, $$.param.type)) 1.1096 + context->recover(); 1.1097 + } 1.1098 + | parameter_qualifier parameter_declarator { 1.1099 + $$ = $2; 1.1100 + if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type)) 1.1101 + context->recover(); 1.1102 + if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type)) 1.1103 + context->recover(); 1.1104 + } 1.1105 + // 1.1106 + // Only type 1.1107 + // 1.1108 + | type_qualifier parameter_qualifier parameter_type_specifier { 1.1109 + $$ = $3; 1.1110 + if (context->paramErrorCheck(@3, $1.qualifier, $2, $$.param.type)) 1.1111 + context->recover(); 1.1112 + } 1.1113 + | parameter_qualifier parameter_type_specifier { 1.1114 + $$ = $2; 1.1115 + if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type)) 1.1116 + context->recover(); 1.1117 + if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type)) 1.1118 + context->recover(); 1.1119 + } 1.1120 + ; 1.1121 + 1.1122 +parameter_qualifier 1.1123 + : /* empty */ { 1.1124 + $$ = EvqIn; 1.1125 + } 1.1126 + | IN_QUAL { 1.1127 + $$ = EvqIn; 1.1128 + } 1.1129 + | OUT_QUAL { 1.1130 + $$ = EvqOut; 1.1131 + } 1.1132 + | INOUT_QUAL { 1.1133 + $$ = EvqInOut; 1.1134 + } 1.1135 + ; 1.1136 + 1.1137 +parameter_type_specifier 1.1138 + : type_specifier { 1.1139 + TParameter param = { 0, new TType($1) }; 1.1140 + $$.param = param; 1.1141 + } 1.1142 + ; 1.1143 + 1.1144 +init_declarator_list 1.1145 + : single_declaration { 1.1146 + $$ = $1; 1.1147 + } 1.1148 + | init_declarator_list COMMA identifier { 1.1149 + if ($1.type.type == EbtInvariant && !$3.symbol) 1.1150 + { 1.1151 + context->error(@3, "undeclared identifier declared as invariant", $3.string->c_str()); 1.1152 + context->recover(); 1.1153 + } 1.1154 + 1.1155 + TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$3.string, TType($1.type), @3); 1.1156 + $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, symbol, @3); 1.1157 + 1.1158 + if (context->structQualifierErrorCheck(@3, $$.type)) 1.1159 + context->recover(); 1.1160 + 1.1161 + if (context->nonInitConstErrorCheck(@3, *$3.string, $$.type, false)) 1.1162 + context->recover(); 1.1163 + 1.1164 + TVariable* variable = 0; 1.1165 + if (context->nonInitErrorCheck(@3, *$3.string, $$.type, variable)) 1.1166 + context->recover(); 1.1167 + if (symbol && variable) 1.1168 + symbol->setId(variable->getUniqueId()); 1.1169 + } 1.1170 + | init_declarator_list COMMA identifier LEFT_BRACKET RIGHT_BRACKET { 1.1171 + if (context->structQualifierErrorCheck(@3, $1.type)) 1.1172 + context->recover(); 1.1173 + 1.1174 + if (context->nonInitConstErrorCheck(@3, *$3.string, $1.type, true)) 1.1175 + context->recover(); 1.1176 + 1.1177 + $$ = $1; 1.1178 + 1.1179 + if (context->arrayTypeErrorCheck(@4, $1.type) || context->arrayQualifierErrorCheck(@4, $1.type)) 1.1180 + context->recover(); 1.1181 + else { 1.1182 + $1.type.setArray(true); 1.1183 + TVariable* variable; 1.1184 + if (context->arrayErrorCheck(@4, *$3.string, $1.type, variable)) 1.1185 + context->recover(); 1.1186 + } 1.1187 + } 1.1188 + | init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { 1.1189 + if (context->structQualifierErrorCheck(@3, $1.type)) 1.1190 + context->recover(); 1.1191 + 1.1192 + if (context->nonInitConstErrorCheck(@3, *$3.string, $1.type, true)) 1.1193 + context->recover(); 1.1194 + 1.1195 + $$ = $1; 1.1196 + 1.1197 + if (context->arrayTypeErrorCheck(@4, $1.type) || context->arrayQualifierErrorCheck(@4, $1.type)) 1.1198 + context->recover(); 1.1199 + else { 1.1200 + int size; 1.1201 + if (context->arraySizeErrorCheck(@4, $5, size)) 1.1202 + context->recover(); 1.1203 + $1.type.setArray(true, size); 1.1204 + TVariable* variable = 0; 1.1205 + if (context->arrayErrorCheck(@4, *$3.string, $1.type, variable)) 1.1206 + context->recover(); 1.1207 + TType type = TType($1.type); 1.1208 + type.setArraySize(size); 1.1209 + $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(variable ? variable->getUniqueId() : 0, *$3.string, type, @3), @3); 1.1210 + } 1.1211 + } 1.1212 + | init_declarator_list COMMA identifier EQUAL initializer { 1.1213 + if (context->structQualifierErrorCheck(@3, $1.type)) 1.1214 + context->recover(); 1.1215 + 1.1216 + $$ = $1; 1.1217 + 1.1218 + TIntermNode* intermNode; 1.1219 + if (!context->executeInitializer(@3, *$3.string, $1.type, $5, intermNode)) { 1.1220 + // 1.1221 + // build the intermediate representation 1.1222 + // 1.1223 + if (intermNode) 1.1224 + $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, intermNode, @4); 1.1225 + else 1.1226 + $$.intermAggregate = $1.intermAggregate; 1.1227 + } else { 1.1228 + context->recover(); 1.1229 + $$.intermAggregate = 0; 1.1230 + } 1.1231 + } 1.1232 + ; 1.1233 + 1.1234 +single_declaration 1.1235 + : fully_specified_type { 1.1236 + $$.type = $1; 1.1237 + $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType($1), @1), @1); 1.1238 + } 1.1239 + | fully_specified_type identifier { 1.1240 + TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), @2); 1.1241 + $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2); 1.1242 + 1.1243 + if (context->structQualifierErrorCheck(@2, $$.type)) 1.1244 + context->recover(); 1.1245 + 1.1246 + if (context->nonInitConstErrorCheck(@2, *$2.string, $$.type, false)) 1.1247 + context->recover(); 1.1248 + 1.1249 + $$.type = $1; 1.1250 + 1.1251 + TVariable* variable = 0; 1.1252 + if (context->nonInitErrorCheck(@2, *$2.string, $$.type, variable)) 1.1253 + context->recover(); 1.1254 + if (variable && symbol) 1.1255 + symbol->setId(variable->getUniqueId()); 1.1256 + } 1.1257 + | fully_specified_type identifier LEFT_BRACKET RIGHT_BRACKET { 1.1258 + context->error(@2, "unsized array declarations not supported", $2.string->c_str()); 1.1259 + context->recover(); 1.1260 + 1.1261 + TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), @2); 1.1262 + $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2); 1.1263 + $$.type = $1; 1.1264 + } 1.1265 + | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { 1.1266 + TType type = TType($1); 1.1267 + int size; 1.1268 + if (context->arraySizeErrorCheck(@2, $4, size)) 1.1269 + context->recover(); 1.1270 + type.setArraySize(size); 1.1271 + TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, type, @2); 1.1272 + $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2); 1.1273 + 1.1274 + if (context->structQualifierErrorCheck(@2, $1)) 1.1275 + context->recover(); 1.1276 + 1.1277 + if (context->nonInitConstErrorCheck(@2, *$2.string, $1, true)) 1.1278 + context->recover(); 1.1279 + 1.1280 + $$.type = $1; 1.1281 + 1.1282 + if (context->arrayTypeErrorCheck(@3, $1) || context->arrayQualifierErrorCheck(@3, $1)) 1.1283 + context->recover(); 1.1284 + else { 1.1285 + int size; 1.1286 + if (context->arraySizeErrorCheck(@3, $4, size)) 1.1287 + context->recover(); 1.1288 + 1.1289 + $1.setArray(true, size); 1.1290 + TVariable* variable = 0; 1.1291 + if (context->arrayErrorCheck(@3, *$2.string, $1, variable)) 1.1292 + context->recover(); 1.1293 + if (variable && symbol) 1.1294 + symbol->setId(variable->getUniqueId()); 1.1295 + } 1.1296 + } 1.1297 + | fully_specified_type identifier EQUAL initializer { 1.1298 + if (context->structQualifierErrorCheck(@2, $1)) 1.1299 + context->recover(); 1.1300 + 1.1301 + $$.type = $1; 1.1302 + 1.1303 + TIntermNode* intermNode; 1.1304 + if (!context->executeInitializer(@2, *$2.string, $1, $4, intermNode)) { 1.1305 + // 1.1306 + // Build intermediate representation 1.1307 + // 1.1308 + if(intermNode) 1.1309 + $$.intermAggregate = context->intermediate.makeAggregate(intermNode, @3); 1.1310 + else 1.1311 + $$.intermAggregate = 0; 1.1312 + } else { 1.1313 + context->recover(); 1.1314 + $$.intermAggregate = 0; 1.1315 + } 1.1316 + } 1.1317 + | INVARIANT IDENTIFIER { 1.1318 + VERTEX_ONLY("invariant declaration", @1); 1.1319 + if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying")) 1.1320 + context->recover(); 1.1321 + $$.type.setBasic(EbtInvariant, EvqInvariantVaryingOut, @2); 1.1322 + if (!$2.symbol) 1.1323 + { 1.1324 + context->error(@2, "undeclared identifier declared as invariant", $2.string->c_str()); 1.1325 + context->recover(); 1.1326 + 1.1327 + $$.intermAggregate = 0; 1.1328 + } 1.1329 + else 1.1330 + { 1.1331 + TIntermSymbol *symbol = context->intermediate.addSymbol(0, *$2.string, TType($$.type), @2); 1.1332 + $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2); 1.1333 + } 1.1334 + } 1.1335 + ; 1.1336 + 1.1337 +fully_specified_type 1.1338 + : type_specifier { 1.1339 + $$ = $1; 1.1340 + 1.1341 + if ($1.array) { 1.1342 + context->error(@1, "not supported", "first-class array"); 1.1343 + context->recover(); 1.1344 + $1.setArray(false); 1.1345 + } 1.1346 + } 1.1347 + | type_qualifier type_specifier { 1.1348 + if ($2.array) { 1.1349 + context->error(@2, "not supported", "first-class array"); 1.1350 + context->recover(); 1.1351 + $2.setArray(false); 1.1352 + } 1.1353 + 1.1354 + if ($1.qualifier == EvqAttribute && 1.1355 + ($2.type == EbtBool || $2.type == EbtInt)) { 1.1356 + context->error(@2, "cannot be bool or int", getQualifierString($1.qualifier)); 1.1357 + context->recover(); 1.1358 + } 1.1359 + if (($1.qualifier == EvqVaryingIn || $1.qualifier == EvqVaryingOut) && 1.1360 + ($2.type == EbtBool || $2.type == EbtInt)) { 1.1361 + context->error(@2, "cannot be bool or int", getQualifierString($1.qualifier)); 1.1362 + context->recover(); 1.1363 + } 1.1364 + $$ = $2; 1.1365 + $$.qualifier = $1.qualifier; 1.1366 + } 1.1367 + ; 1.1368 + 1.1369 +type_qualifier 1.1370 + : CONST_QUAL { 1.1371 + $$.setBasic(EbtVoid, EvqConst, @1); 1.1372 + } 1.1373 + | ATTRIBUTE { 1.1374 + VERTEX_ONLY("attribute", @1); 1.1375 + if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "attribute")) 1.1376 + context->recover(); 1.1377 + $$.setBasic(EbtVoid, EvqAttribute, @1); 1.1378 + } 1.1379 + | VARYING { 1.1380 + if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "varying")) 1.1381 + context->recover(); 1.1382 + if (context->shaderType == SH_VERTEX_SHADER) 1.1383 + $$.setBasic(EbtVoid, EvqVaryingOut, @1); 1.1384 + else 1.1385 + $$.setBasic(EbtVoid, EvqVaryingIn, @1); 1.1386 + } 1.1387 + | INVARIANT VARYING { 1.1388 + if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying")) 1.1389 + context->recover(); 1.1390 + if (context->shaderType == SH_VERTEX_SHADER) 1.1391 + $$.setBasic(EbtVoid, EvqInvariantVaryingOut, @1); 1.1392 + else 1.1393 + $$.setBasic(EbtVoid, EvqInvariantVaryingIn, @1); 1.1394 + } 1.1395 + | UNIFORM { 1.1396 + if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "uniform")) 1.1397 + context->recover(); 1.1398 + $$.setBasic(EbtVoid, EvqUniform, @1); 1.1399 + } 1.1400 + ; 1.1401 + 1.1402 +type_specifier 1.1403 + : type_specifier_no_prec { 1.1404 + $$ = $1; 1.1405 + 1.1406 + if ($$.precision == EbpUndefined) { 1.1407 + $$.precision = context->symbolTable.getDefaultPrecision($1.type); 1.1408 + if (context->precisionErrorCheck(@1, $$.precision, $1.type)) { 1.1409 + context->recover(); 1.1410 + } 1.1411 + } 1.1412 + } 1.1413 + | precision_qualifier type_specifier_no_prec { 1.1414 + $$ = $2; 1.1415 + $$.precision = $1; 1.1416 + } 1.1417 + ; 1.1418 + 1.1419 +precision_qualifier 1.1420 + : HIGH_PRECISION { 1.1421 + $$ = EbpHigh; 1.1422 + } 1.1423 + | MEDIUM_PRECISION { 1.1424 + $$ = EbpMedium; 1.1425 + } 1.1426 + | LOW_PRECISION { 1.1427 + $$ = EbpLow; 1.1428 + } 1.1429 + ; 1.1430 + 1.1431 +type_specifier_no_prec 1.1432 + : type_specifier_nonarray { 1.1433 + $$ = $1; 1.1434 + } 1.1435 + | type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET { 1.1436 + $$ = $1; 1.1437 + 1.1438 + if (context->arrayTypeErrorCheck(@2, $1)) 1.1439 + context->recover(); 1.1440 + else { 1.1441 + int size; 1.1442 + if (context->arraySizeErrorCheck(@2, $3, size)) 1.1443 + context->recover(); 1.1444 + $$.setArray(true, size); 1.1445 + } 1.1446 + } 1.1447 + ; 1.1448 + 1.1449 +type_specifier_nonarray 1.1450 + : VOID_TYPE { 1.1451 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1452 + $$.setBasic(EbtVoid, qual, @1); 1.1453 + } 1.1454 + | FLOAT_TYPE { 1.1455 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1456 + $$.setBasic(EbtFloat, qual, @1); 1.1457 + } 1.1458 + | INT_TYPE { 1.1459 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1460 + $$.setBasic(EbtInt, qual, @1); 1.1461 + } 1.1462 + | BOOL_TYPE { 1.1463 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1464 + $$.setBasic(EbtBool, qual, @1); 1.1465 + } 1.1466 + | VEC2 { 1.1467 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1468 + $$.setBasic(EbtFloat, qual, @1); 1.1469 + $$.setAggregate(2); 1.1470 + } 1.1471 + | VEC3 { 1.1472 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1473 + $$.setBasic(EbtFloat, qual, @1); 1.1474 + $$.setAggregate(3); 1.1475 + } 1.1476 + | VEC4 { 1.1477 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1478 + $$.setBasic(EbtFloat, qual, @1); 1.1479 + $$.setAggregate(4); 1.1480 + } 1.1481 + | BVEC2 { 1.1482 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1483 + $$.setBasic(EbtBool, qual, @1); 1.1484 + $$.setAggregate(2); 1.1485 + } 1.1486 + | BVEC3 { 1.1487 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1488 + $$.setBasic(EbtBool, qual, @1); 1.1489 + $$.setAggregate(3); 1.1490 + } 1.1491 + | BVEC4 { 1.1492 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1493 + $$.setBasic(EbtBool, qual, @1); 1.1494 + $$.setAggregate(4); 1.1495 + } 1.1496 + | IVEC2 { 1.1497 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1498 + $$.setBasic(EbtInt, qual, @1); 1.1499 + $$.setAggregate(2); 1.1500 + } 1.1501 + | IVEC3 { 1.1502 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1503 + $$.setBasic(EbtInt, qual, @1); 1.1504 + $$.setAggregate(3); 1.1505 + } 1.1506 + | IVEC4 { 1.1507 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1508 + $$.setBasic(EbtInt, qual, @1); 1.1509 + $$.setAggregate(4); 1.1510 + } 1.1511 + | MATRIX2 { 1.1512 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1513 + $$.setBasic(EbtFloat, qual, @1); 1.1514 + $$.setAggregate(2, true); 1.1515 + } 1.1516 + | MATRIX3 { 1.1517 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1518 + $$.setBasic(EbtFloat, qual, @1); 1.1519 + $$.setAggregate(3, true); 1.1520 + } 1.1521 + | MATRIX4 { 1.1522 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1523 + $$.setBasic(EbtFloat, qual, @1); 1.1524 + $$.setAggregate(4, true); 1.1525 + } 1.1526 + | SAMPLER2D { 1.1527 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1528 + $$.setBasic(EbtSampler2D, qual, @1); 1.1529 + } 1.1530 + | SAMPLERCUBE { 1.1531 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1532 + $$.setBasic(EbtSamplerCube, qual, @1); 1.1533 + } 1.1534 + | SAMPLER_EXTERNAL_OES { 1.1535 + if (!context->supportsExtension("GL_OES_EGL_image_external")) { 1.1536 + context->error(@1, "unsupported type", "samplerExternalOES"); 1.1537 + context->recover(); 1.1538 + } 1.1539 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1540 + $$.setBasic(EbtSamplerExternalOES, qual, @1); 1.1541 + } 1.1542 + | SAMPLER2DRECT { 1.1543 + if (!context->supportsExtension("GL_ARB_texture_rectangle")) { 1.1544 + context->error(@1, "unsupported type", "sampler2DRect"); 1.1545 + context->recover(); 1.1546 + } 1.1547 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1548 + $$.setBasic(EbtSampler2DRect, qual, @1); 1.1549 + } 1.1550 + | struct_specifier { 1.1551 + $$ = $1; 1.1552 + $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1553 + } 1.1554 + | TYPE_NAME { 1.1555 + // 1.1556 + // This is for user defined type names. The lexical phase looked up the 1.1557 + // type. 1.1558 + // 1.1559 + TType& structure = static_cast<TVariable*>($1.symbol)->getType(); 1.1560 + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1.1561 + $$.setBasic(EbtStruct, qual, @1); 1.1562 + $$.userDef = &structure; 1.1563 + } 1.1564 + ; 1.1565 + 1.1566 +struct_specifier 1.1567 + : STRUCT identifier LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { 1.1568 + if (context->reservedErrorCheck(@2, *$2.string)) 1.1569 + context->recover(); 1.1570 + 1.1571 + TType* structure = new TType(new TStructure($2.string, $5)); 1.1572 + TVariable* userTypeDef = new TVariable($2.string, *structure, true); 1.1573 + if (! context->symbolTable.insert(*userTypeDef)) { 1.1574 + context->error(@2, "redefinition", $2.string->c_str(), "struct"); 1.1575 + context->recover(); 1.1576 + } 1.1577 + $$.setBasic(EbtStruct, EvqTemporary, @1); 1.1578 + $$.userDef = structure; 1.1579 + context->exitStructDeclaration(); 1.1580 + } 1.1581 + | STRUCT LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { 1.1582 + TType* structure = new TType(new TStructure(NewPoolTString(""), $4)); 1.1583 + $$.setBasic(EbtStruct, EvqTemporary, @1); 1.1584 + $$.userDef = structure; 1.1585 + context->exitStructDeclaration(); 1.1586 + } 1.1587 + ; 1.1588 + 1.1589 +struct_declaration_list 1.1590 + : struct_declaration { 1.1591 + $$ = $1; 1.1592 + } 1.1593 + | struct_declaration_list struct_declaration { 1.1594 + $$ = $1; 1.1595 + for (size_t i = 0; i < $2->size(); ++i) { 1.1596 + TField* field = (*$2)[i]; 1.1597 + for (size_t j = 0; j < $$->size(); ++j) { 1.1598 + if ((*$$)[j]->name() == field->name()) { 1.1599 + context->error(@2, "duplicate field name in structure:", "struct", field->name().c_str()); 1.1600 + context->recover(); 1.1601 + } 1.1602 + } 1.1603 + $$->push_back(field); 1.1604 + } 1.1605 + } 1.1606 + ; 1.1607 + 1.1608 +struct_declaration 1.1609 + : type_specifier struct_declarator_list SEMICOLON { 1.1610 + $$ = $2; 1.1611 + 1.1612 + if (context->voidErrorCheck(@1, (*$2)[0]->name(), $1)) { 1.1613 + context->recover(); 1.1614 + } 1.1615 + for (unsigned int i = 0; i < $$->size(); ++i) { 1.1616 + // 1.1617 + // Careful not to replace already known aspects of type, like array-ness 1.1618 + // 1.1619 + TType* type = (*$$)[i]->type(); 1.1620 + type->setBasicType($1.type); 1.1621 + type->setNominalSize($1.size); 1.1622 + type->setMatrix($1.matrix); 1.1623 + type->setPrecision($1.precision); 1.1624 + 1.1625 + // don't allow arrays of arrays 1.1626 + if (type->isArray()) { 1.1627 + if (context->arrayTypeErrorCheck(@1, $1)) 1.1628 + context->recover(); 1.1629 + } 1.1630 + if ($1.array) 1.1631 + type->setArraySize($1.arraySize); 1.1632 + if ($1.userDef) 1.1633 + type->setStruct($1.userDef->getStruct()); 1.1634 + 1.1635 + if (context->structNestingErrorCheck(@1, *(*$$)[i])) 1.1636 + context->recover(); 1.1637 + } 1.1638 + } 1.1639 + ; 1.1640 + 1.1641 +struct_declarator_list 1.1642 + : struct_declarator { 1.1643 + $$ = NewPoolTFieldList(); 1.1644 + $$->push_back($1); 1.1645 + } 1.1646 + | struct_declarator_list COMMA struct_declarator { 1.1647 + $$->push_back($3); 1.1648 + } 1.1649 + ; 1.1650 + 1.1651 +struct_declarator 1.1652 + : identifier { 1.1653 + if (context->reservedErrorCheck(@1, *$1.string)) 1.1654 + context->recover(); 1.1655 + 1.1656 + TType* type = new TType(EbtVoid, EbpUndefined); 1.1657 + $$ = new TField(type, $1.string); 1.1658 + } 1.1659 + | identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { 1.1660 + if (context->reservedErrorCheck(@1, *$1.string)) 1.1661 + context->recover(); 1.1662 + 1.1663 + TType* type = new TType(EbtVoid, EbpUndefined); 1.1664 + int size = 0; 1.1665 + if (context->arraySizeErrorCheck(@3, $3, size)) 1.1666 + context->recover(); 1.1667 + type->setArraySize(size); 1.1668 + 1.1669 + $$ = new TField(type, $1.string); 1.1670 + } 1.1671 + ; 1.1672 + 1.1673 +initializer 1.1674 + : assignment_expression { $$ = $1; } 1.1675 + ; 1.1676 + 1.1677 +declaration_statement 1.1678 + : declaration { $$ = $1; } 1.1679 + ; 1.1680 + 1.1681 +statement 1.1682 + : compound_statement { $$ = $1; } 1.1683 + | simple_statement { $$ = $1; } 1.1684 + ; 1.1685 + 1.1686 +// Grammar Note: No labeled statements; 'goto' is not supported. 1.1687 + 1.1688 +simple_statement 1.1689 + : declaration_statement { $$ = $1; } 1.1690 + | expression_statement { $$ = $1; } 1.1691 + | selection_statement { $$ = $1; } 1.1692 + | iteration_statement { $$ = $1; } 1.1693 + | jump_statement { $$ = $1; } 1.1694 + ; 1.1695 + 1.1696 +compound_statement 1.1697 + : LEFT_BRACE RIGHT_BRACE { $$ = 0; } 1.1698 + | LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE { 1.1699 + if ($3 != 0) { 1.1700 + $3->setOp(EOpSequence); 1.1701 + $3->setLine(@$); 1.1702 + } 1.1703 + $$ = $3; 1.1704 + } 1.1705 + ; 1.1706 + 1.1707 +statement_no_new_scope 1.1708 + : compound_statement_no_new_scope { $$ = $1; } 1.1709 + | simple_statement { $$ = $1; } 1.1710 + ; 1.1711 + 1.1712 +statement_with_scope 1.1713 + : { context->symbolTable.push(); } compound_statement_no_new_scope { context->symbolTable.pop(); $$ = $2; } 1.1714 + | { context->symbolTable.push(); } simple_statement { context->symbolTable.pop(); $$ = $2; } 1.1715 + ; 1.1716 + 1.1717 +compound_statement_no_new_scope 1.1718 + // Statement that doesn't create a new scope, for selection_statement, iteration_statement 1.1719 + : LEFT_BRACE RIGHT_BRACE { 1.1720 + $$ = 0; 1.1721 + } 1.1722 + | LEFT_BRACE statement_list RIGHT_BRACE { 1.1723 + if ($2) { 1.1724 + $2->setOp(EOpSequence); 1.1725 + $2->setLine(@$); 1.1726 + } 1.1727 + $$ = $2; 1.1728 + } 1.1729 + ; 1.1730 + 1.1731 +statement_list 1.1732 + : statement { 1.1733 + $$ = context->intermediate.makeAggregate($1, @$); 1.1734 + } 1.1735 + | statement_list statement { 1.1736 + $$ = context->intermediate.growAggregate($1, $2, @$); 1.1737 + } 1.1738 + ; 1.1739 + 1.1740 +expression_statement 1.1741 + : SEMICOLON { $$ = 0; } 1.1742 + | expression SEMICOLON { $$ = static_cast<TIntermNode*>($1); } 1.1743 + ; 1.1744 + 1.1745 +selection_statement 1.1746 + : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement { 1.1747 + if (context->boolErrorCheck(@1, $3)) 1.1748 + context->recover(); 1.1749 + $$ = context->intermediate.addSelection($3, $5, @1); 1.1750 + } 1.1751 + ; 1.1752 + 1.1753 +selection_rest_statement 1.1754 + : statement_with_scope ELSE statement_with_scope { 1.1755 + $$.node1 = $1; 1.1756 + $$.node2 = $3; 1.1757 + } 1.1758 + | statement_with_scope { 1.1759 + $$.node1 = $1; 1.1760 + $$.node2 = 0; 1.1761 + } 1.1762 + ; 1.1763 + 1.1764 +// Grammar Note: No 'switch'. Switch statements not supported. 1.1765 + 1.1766 +condition 1.1767 + // In 1996 c++ draft, conditions can include single declarations 1.1768 + : expression { 1.1769 + $$ = $1; 1.1770 + if (context->boolErrorCheck($1->getLine(), $1)) 1.1771 + context->recover(); 1.1772 + } 1.1773 + | fully_specified_type identifier EQUAL initializer { 1.1774 + TIntermNode* intermNode; 1.1775 + if (context->structQualifierErrorCheck(@2, $1)) 1.1776 + context->recover(); 1.1777 + if (context->boolErrorCheck(@2, $1)) 1.1778 + context->recover(); 1.1779 + 1.1780 + if (!context->executeInitializer(@2, *$2.string, $1, $4, intermNode)) 1.1781 + $$ = $4; 1.1782 + else { 1.1783 + context->recover(); 1.1784 + $$ = 0; 1.1785 + } 1.1786 + } 1.1787 + ; 1.1788 + 1.1789 +iteration_statement 1.1790 + : WHILE LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope { 1.1791 + context->symbolTable.pop(); 1.1792 + $$ = context->intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, @1); 1.1793 + --context->loopNestingLevel; 1.1794 + } 1.1795 + | DO { ++context->loopNestingLevel; } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON { 1.1796 + if (context->boolErrorCheck(@8, $6)) 1.1797 + context->recover(); 1.1798 + 1.1799 + $$ = context->intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, @4); 1.1800 + --context->loopNestingLevel; 1.1801 + } 1.1802 + | FOR LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope { 1.1803 + context->symbolTable.pop(); 1.1804 + $$ = context->intermediate.addLoop(ELoopFor, $4, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), $7, @1); 1.1805 + --context->loopNestingLevel; 1.1806 + } 1.1807 + ; 1.1808 + 1.1809 +for_init_statement 1.1810 + : expression_statement { 1.1811 + $$ = $1; 1.1812 + } 1.1813 + | declaration_statement { 1.1814 + $$ = $1; 1.1815 + } 1.1816 + ; 1.1817 + 1.1818 +conditionopt 1.1819 + : condition { 1.1820 + $$ = $1; 1.1821 + } 1.1822 + | /* May be null */ { 1.1823 + $$ = 0; 1.1824 + } 1.1825 + ; 1.1826 + 1.1827 +for_rest_statement 1.1828 + : conditionopt SEMICOLON { 1.1829 + $$.node1 = $1; 1.1830 + $$.node2 = 0; 1.1831 + } 1.1832 + | conditionopt SEMICOLON expression { 1.1833 + $$.node1 = $1; 1.1834 + $$.node2 = $3; 1.1835 + } 1.1836 + ; 1.1837 + 1.1838 +jump_statement 1.1839 + : CONTINUE SEMICOLON { 1.1840 + if (context->loopNestingLevel <= 0) { 1.1841 + context->error(@1, "continue statement only allowed in loops", ""); 1.1842 + context->recover(); 1.1843 + } 1.1844 + $$ = context->intermediate.addBranch(EOpContinue, @1); 1.1845 + } 1.1846 + | BREAK SEMICOLON { 1.1847 + if (context->loopNestingLevel <= 0) { 1.1848 + context->error(@1, "break statement only allowed in loops", ""); 1.1849 + context->recover(); 1.1850 + } 1.1851 + $$ = context->intermediate.addBranch(EOpBreak, @1); 1.1852 + } 1.1853 + | RETURN SEMICOLON { 1.1854 + $$ = context->intermediate.addBranch(EOpReturn, @1); 1.1855 + if (context->currentFunctionType->getBasicType() != EbtVoid) { 1.1856 + context->error(@1, "non-void function must return a value", "return"); 1.1857 + context->recover(); 1.1858 + } 1.1859 + } 1.1860 + | RETURN expression SEMICOLON { 1.1861 + $$ = context->intermediate.addBranch(EOpReturn, $2, @1); 1.1862 + context->functionReturnsValue = true; 1.1863 + if (context->currentFunctionType->getBasicType() == EbtVoid) { 1.1864 + context->error(@1, "void function cannot return a value", "return"); 1.1865 + context->recover(); 1.1866 + } else if (*(context->currentFunctionType) != $2->getType()) { 1.1867 + context->error(@1, "function return is not matching type:", "return"); 1.1868 + context->recover(); 1.1869 + } 1.1870 + } 1.1871 + | DISCARD SEMICOLON { 1.1872 + FRAG_ONLY("discard", @1); 1.1873 + $$ = context->intermediate.addBranch(EOpKill, @1); 1.1874 + } 1.1875 + ; 1.1876 + 1.1877 +// Grammar Note: No 'goto'. Gotos are not supported. 1.1878 + 1.1879 +translation_unit 1.1880 + : external_declaration { 1.1881 + $$ = $1; 1.1882 + context->treeRoot = $$; 1.1883 + } 1.1884 + | translation_unit external_declaration { 1.1885 + $$ = context->intermediate.growAggregate($1, $2, @$); 1.1886 + context->treeRoot = $$; 1.1887 + } 1.1888 + ; 1.1889 + 1.1890 +external_declaration 1.1891 + : function_definition { 1.1892 + $$ = $1; 1.1893 + } 1.1894 + | declaration { 1.1895 + $$ = $1; 1.1896 + } 1.1897 + ; 1.1898 + 1.1899 +function_definition 1.1900 + : function_prototype { 1.1901 + TFunction* function = $1.function; 1.1902 + 1.1903 + const TSymbol *builtIn = context->symbolTable.findBuiltIn(function->getMangledName()); 1.1904 + 1.1905 + if (builtIn) 1.1906 + { 1.1907 + context->error(@1, "built-in functions cannot be redefined", function->getName().c_str()); 1.1908 + context->recover(); 1.1909 + } 1.1910 + 1.1911 + TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find(function->getMangledName())); 1.1912 + // 1.1913 + // Note: 'prevDec' could be 'function' if this is the first time we've seen function 1.1914 + // as it would have just been put in the symbol table. Otherwise, we're looking up 1.1915 + // an earlier occurance. 1.1916 + // 1.1917 + if (prevDec->isDefined()) { 1.1918 + // 1.1919 + // Then this function already has a body. 1.1920 + // 1.1921 + context->error(@1, "function already has a body", function->getName().c_str()); 1.1922 + context->recover(); 1.1923 + } 1.1924 + prevDec->setDefined(); 1.1925 + 1.1926 + // 1.1927 + // Raise error message if main function takes any parameters or return anything other than void 1.1928 + // 1.1929 + if (function->getName() == "main") { 1.1930 + if (function->getParamCount() > 0) { 1.1931 + context->error(@1, "function cannot take any parameter(s)", function->getName().c_str()); 1.1932 + context->recover(); 1.1933 + } 1.1934 + if (function->getReturnType().getBasicType() != EbtVoid) { 1.1935 + context->error(@1, "", function->getReturnType().getBasicString(), "main function cannot return a value"); 1.1936 + context->recover(); 1.1937 + } 1.1938 + } 1.1939 + 1.1940 + // 1.1941 + // Remember the return type for later checking for RETURN statements. 1.1942 + // 1.1943 + context->currentFunctionType = &(prevDec->getReturnType()); 1.1944 + context->functionReturnsValue = false; 1.1945 + 1.1946 + // 1.1947 + // Insert parameters into the symbol table. 1.1948 + // If the parameter has no name, it's not an error, just don't insert it 1.1949 + // (could be used for unused args). 1.1950 + // 1.1951 + // Also, accumulate the list of parameters into the HIL, so lower level code 1.1952 + // knows where to find parameters. 1.1953 + // 1.1954 + TIntermAggregate* paramNodes = new TIntermAggregate; 1.1955 + for (size_t i = 0; i < function->getParamCount(); i++) { 1.1956 + const TParameter& param = function->getParam(i); 1.1957 + if (param.name != 0) { 1.1958 + TVariable *variable = new TVariable(param.name, *param.type); 1.1959 + // 1.1960 + // Insert the parameters with name in the symbol table. 1.1961 + // 1.1962 + if (! context->symbolTable.insert(*variable)) { 1.1963 + context->error(@1, "redefinition", variable->getName().c_str()); 1.1964 + context->recover(); 1.1965 + delete variable; 1.1966 + } 1.1967 + 1.1968 + // 1.1969 + // Add the parameter to the HIL 1.1970 + // 1.1971 + paramNodes = context->intermediate.growAggregate( 1.1972 + paramNodes, 1.1973 + context->intermediate.addSymbol(variable->getUniqueId(), 1.1974 + variable->getName(), 1.1975 + variable->getType(), 1.1976 + @1), 1.1977 + @1); 1.1978 + } else { 1.1979 + paramNodes = context->intermediate.growAggregate(paramNodes, context->intermediate.addSymbol(0, "", *param.type, @1), @1); 1.1980 + } 1.1981 + } 1.1982 + context->intermediate.setAggregateOperator(paramNodes, EOpParameters, @1); 1.1983 + $1.intermAggregate = paramNodes; 1.1984 + context->loopNestingLevel = 0; 1.1985 + } 1.1986 + compound_statement_no_new_scope { 1.1987 + //?? Check that all paths return a value if return type != void ? 1.1988 + // May be best done as post process phase on intermediate code 1.1989 + if (context->currentFunctionType->getBasicType() != EbtVoid && ! context->functionReturnsValue) { 1.1990 + context->error(@1, "function does not return a value:", "", $1.function->getName().c_str()); 1.1991 + context->recover(); 1.1992 + } 1.1993 + 1.1994 + $$ = context->intermediate.growAggregate($1.intermAggregate, $3, @$); 1.1995 + context->intermediate.setAggregateOperator($$, EOpFunction, @1); 1.1996 + $$->getAsAggregate()->setName($1.function->getMangledName().c_str()); 1.1997 + $$->getAsAggregate()->setType($1.function->getReturnType()); 1.1998 + 1.1999 + // store the pragma information for debug and optimize and other vendor specific 1.2000 + // information. This information can be queried from the parse tree 1.2001 + $$->getAsAggregate()->setOptimize(context->pragma().optimize); 1.2002 + $$->getAsAggregate()->setDebug(context->pragma().debug); 1.2003 + 1.2004 + context->symbolTable.pop(); 1.2005 + } 1.2006 + ; 1.2007 + 1.2008 +%% 1.2009 + 1.2010 +void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason) { 1.2011 + context->error(*yylloc, reason, ""); 1.2012 + context->recover(); 1.2013 +} 1.2014 + 1.2015 +int glslang_parse(TParseContext* context) { 1.2016 + return yyparse(context); 1.2017 +}