diff options
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/glslang.y')
-rw-r--r-- | src/3rdparty/angle/src/compiler/translator/glslang.y | 757 |
1 files changed, 348 insertions, 409 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/glslang.y b/src/3rdparty/angle/src/compiler/translator/glslang.y index 7614ff3447..fb2d835368 100644 --- a/src/3rdparty/angle/src/compiler/translator/glslang.y +++ b/src/3rdparty/angle/src/compiler/translator/glslang.y @@ -1,6 +1,6 @@ /* // -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -15,7 +15,7 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). %{ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -34,6 +34,7 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). #pragma warning(disable: 4701) #endif +#include "angle_gl.h" #include "compiler/translator/SymbolTable.h" #include "compiler/translator/ParseContext.h" #include "GLSLANG/ShaderLang.h" @@ -41,8 +42,8 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). #define YYENABLE_NLS 0 #define YYLEX_PARAM context->scanner -%} +%} %expect 1 /* One shift reduce conflict because of if | else */ %pure-parser %parse-param {TParseContext* context} @@ -51,7 +52,6 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). %code requires { #define YYLTYPE TSourceLoc #define YYLTYPE_IS_DECLARED 1 -#define SH_MAX_TOKEN_LENGTH 256 // WebGL spec. } %union { @@ -60,6 +60,7 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). TString *string; float f; int i; + unsigned int u; bool b; }; TSymbol* symbol; @@ -75,6 +76,7 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). union { TPublicType type; TPrecision precision; + TLayoutQualifier layoutQualifier; TQualifier qualifier; TFunction* function; TParameter param; @@ -105,29 +107,50 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason) } while (0) #define VERTEX_ONLY(S, L) { \ - if (context->shaderType != SH_VERTEX_SHADER) { \ + if (context->shaderType != GL_VERTEX_SHADER) { \ context->error(L, " supported in vertex shaders only ", S); \ context->recover(); \ } \ } #define FRAG_ONLY(S, L) { \ - if (context->shaderType != SH_FRAGMENT_SHADER) { \ + if (context->shaderType != GL_FRAGMENT_SHADER) { \ context->error(L, " supported in fragment shaders only ", S); \ context->recover(); \ } \ } + +#define ES2_ONLY(S, L) { \ + if (context->shaderVersion != 100) { \ + context->error(L, " supported in GLSL ES 1.00 only ", S); \ + context->recover(); \ + } \ +} + +#define ES3_ONLY(TOKEN, LINE, REASON) { \ + if (context->shaderVersion != 300) { \ + context->error(LINE, REASON " supported in GLSL ES 3.00 only ", TOKEN); \ + context->recover(); \ + } \ +} %} %token <lex> INVARIANT HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION -%token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE -%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN -%token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4 +%token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE UINT_TYPE +%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT +%token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4 UVEC2 UVEC3 UVEC4 %token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING +%token <lex> MATRIX2x3 MATRIX3x2 MATRIX2x4 MATRIX4x2 MATRIX3x4 MATRIX4x3 +%token <lex> CENTROID FLAT SMOOTH %token <lex> STRUCT VOID_TYPE WHILE -%token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER2DRECT - -%token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT BOOLCONSTANT +%token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER2DRECT SAMPLER2DARRAY +%token <lex> ISAMPLER2D ISAMPLER3D ISAMPLERCUBE ISAMPLER2DARRAY +%token <lex> USAMPLER2D USAMPLER3D USAMPLERCUBE USAMPLER2DARRAY +%token <lex> SAMPLER3D SAMPLER3DRECT SAMPLER2DSHADOW SAMPLERCUBESHADOW SAMPLER2DARRAYSHADOW +%token <lex> LAYOUT + +%token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT UINTCONSTANT BOOLCONSTANT +%token <lex> FIELD_SELECTION %token <lex> LEFT_OP RIGHT_OP %token <lex> INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP %token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN @@ -160,10 +183,11 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason) %type <interm> single_declaration init_declarator_list %type <interm> parameter_declaration parameter_declarator parameter_type_specifier -%type <interm.qualifier> parameter_qualifier +%type <interm.qualifier> parameter_qualifier parameter_type_qualifier +%type <interm.layoutQualifier> layout_qualifier layout_qualifier_id_list layout_qualifier_id %type <interm.precision> precision_qualifier -%type <interm.type> type_qualifier fully_specified_type type_specifier +%type <interm.type> type_qualifier fully_specified_type type_specifier storage_qualifier interpolation_qualifier %type <interm.type> type_specifier_no_prec type_specifier_nonarray %type <interm.type> struct_specifier %type <interm.field> struct_declarator @@ -173,6 +197,8 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason) %type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype %type <interm> function_call_or_method +%type <lex> enter_struct + %start translation_unit %% @@ -200,7 +226,7 @@ variable_identifier { variable = static_cast<const TVariable*>(symbol); - if (context->symbolTable.findBuiltIn(variable->getName()) && + if (context->symbolTable.findBuiltIn(variable->getName(), context->shaderVersion) && !variable->getExtension().empty() && context->extensionErrorCheck(@1, variable->getExtension())) { @@ -212,7 +238,7 @@ variable_identifier { TType type(EbtFloat, EbpUndefined); TVariable *fakeVariable = new TVariable($1.string, type); - context->symbolTable.insert(*fakeVariable); + context->symbolTable.declare(fakeVariable); variable = fakeVariable; } @@ -244,6 +270,11 @@ primary_expression unionArray->setIConst($1.i); $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @1); } + | UINTCONSTANT { + ConstantUnion *unionArray = new ConstantUnion[1]; + unionArray->setUConst($1.u); + $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtUInt, EbpUndefined, EvqConst), @1); + } | FLOATCONSTANT { ConstantUnion *unionArray = new ConstantUnion[1]; unionArray->setFConst($1.f); @@ -270,104 +301,12 @@ postfix_expression $$ = $1; } | postfix_expression DOT identifier { - if ($1->isArray()) { - context->error(@3, "cannot apply dot operator to an array", "."); - context->recover(); - } - - if ($1->isVector()) { - TVectorFields fields; - if (! context->parseVectorFields(*$3.string, $1->getNominalSize(), fields, @3)) { - fields.num = 1; - fields.offsets[0] = 0; - context->recover(); - } - - if ($1->getType().getQualifier() == EvqConst) { // constant folding for vector fields - $$ = context->addConstVectorNode(fields, $1, @3); - if ($$ == 0) { - context->recover(); - $$ = $1; - } - else - $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst, (int) (*$3.string).size())); - } else { - TString vectorString = *$3.string; - TIntermTyped* index = context->intermediate.addSwizzle(fields, @3); - $$ = context->intermediate.addIndex(EOpVectorSwizzle, $1, index, @2); - $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, (int) vectorString.size())); - } - } else if ($1->isMatrix()) { - TMatrixFields fields; - if (! context->parseMatrixFields(*$3.string, $1->getNominalSize(), fields, @3)) { - fields.wholeRow = false; - fields.wholeCol = false; - fields.row = 0; - fields.col = 0; - context->recover(); - } - - if (fields.wholeRow || fields.wholeCol) { - context->error(@2, " non-scalar fields not implemented yet", "."); - context->recover(); - ConstantUnion *unionArray = new ConstantUnion[1]; - unionArray->setIConst(0); - TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @3); - $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, @2); - $$->setType(TType($1->getBasicType(), $1->getPrecision(),EvqTemporary, $1->getNominalSize())); - } else { - ConstantUnion *unionArray = new ConstantUnion[1]; - unionArray->setIConst(fields.col * $1->getNominalSize() + fields.row); - TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @3); - $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, @2); - $$->setType(TType($1->getBasicType(), $1->getPrecision())); - } - } else if ($1->getBasicType() == EbtStruct) { - bool fieldFound = false; - const TFieldList& fields = $1->getType().getStruct()->fields(); - unsigned int i; - for (i = 0; i < fields.size(); ++i) { - if (fields[i]->name() == *$3.string) { - fieldFound = true; - break; - } - } - if (fieldFound) { - if ($1->getType().getQualifier() == EvqConst) { - $$ = context->addConstStruct(*$3.string, $1, @2); - if ($$ == 0) { - context->recover(); - $$ = $1; - } - else { - $$->setType(*fields[i]->type()); - // change the qualifier of the return type, not of the structure field - // as the structure definition is shared between various structures. - $$->getTypePointer()->setQualifier(EvqConst); - } - } else { - ConstantUnion *unionArray = new ConstantUnion[1]; - unionArray->setIConst(i); - TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *fields[i]->type(), @3); - $$ = context->intermediate.addIndex(EOpIndexDirectStruct, $1, index, @2); - $$->setType(*fields[i]->type()); - } - } else { - context->error(@2, " no such field in structure", $3.string->c_str()); - context->recover(); - $$ = $1; - } - } else { - context->error(@2, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str()); - context->recover(); - $$ = $1; - } - // don't delete $3.string, it's from the pool + $$ = context->addFieldSelectionExpression($1, @2, *$3.string, @3); } | postfix_expression INC_OP { if (context->lValueErrorCheck(@2, "++", $1)) context->recover(); - $$ = context->intermediate.addUnaryMath(EOpPostIncrement, $1, @2, context->symbolTable); + $$ = context->intermediate.addUnaryMath(EOpPostIncrement, $1, @2); if ($$ == 0) { context->unaryOpError(@2, "++", $1->getCompleteString()); context->recover(); @@ -377,7 +316,7 @@ postfix_expression | postfix_expression DEC_OP { if (context->lValueErrorCheck(@2, "--", $1)) context->recover(); - $$ = context->intermediate.addUnaryMath(EOpPostDecrement, $1, @2, context->symbolTable); + $$ = context->intermediate.addUnaryMath(EOpPostDecrement, $1, @2); if ($$ == 0) { context->unaryOpError(@2, "--", $1->getCompleteString()); context->recover(); @@ -427,7 +366,7 @@ function_call // const TFunction* fnCandidate; bool builtIn; - fnCandidate = context->findFunction(@1, fnCall, &builtIn); + fnCandidate = context->findFunction(@1, fnCall, context->shaderVersion, &builtIn); if (fnCandidate) { // // A declared function. @@ -445,7 +384,7 @@ function_call // // Treat it like a built-in unary operator. // - $$ = context->intermediate.addUnaryMath(op, $1.intermNode, @1, context->symbolTable); + $$ = context->intermediate.addUnaryMath(op, $1.intermNode, @1); if ($$ == 0) { std::stringstream extraInfoStream; extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>($1.intermNode)->getCompleteString(); @@ -473,7 +412,7 @@ function_call for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) { qual = fnCandidate->getParam(i).type->getQualifier(); if (qual == EvqOut || qual == EvqInOut) { - if (context->lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) { + if (context->lValueErrorCheck($$->getLine(), "assign", (*($$->getAsAggregate()->getSequence()))[i]->getAsTyped())) { context->error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error"); context->recover(); } @@ -550,59 +489,7 @@ function_call_header function_identifier : type_specifier_nonarray { - // - // Constructor - // - TOperator op = EOpNull; - if ($1.userDef) { - op = EOpConstructStruct; - } else { - switch ($1.type) { - case EbtFloat: - if ($1.matrix) { - switch($1.size) { - case 2: op = EOpConstructMat2; break; - case 3: op = EOpConstructMat3; break; - case 4: op = EOpConstructMat4; break; - } - } else { - switch($1.size) { - case 1: op = EOpConstructFloat; break; - case 2: op = EOpConstructVec2; break; - case 3: op = EOpConstructVec3; break; - case 4: op = EOpConstructVec4; break; - } - } - break; - case EbtInt: - switch($1.size) { - case 1: op = EOpConstructInt; break; - case 2: op = EOpConstructIVec2; break; - case 3: op = EOpConstructIVec3; break; - case 4: op = EOpConstructIVec4; break; - } - break; - case EbtBool: - switch($1.size) { - case 1: op = EOpConstructBool; break; - case 2: op = EOpConstructBVec2; break; - case 3: op = EOpConstructBVec3; break; - case 4: op = EOpConstructBVec4; break; - } - break; - default: break; - } - if (op == EOpNull) { - context->error(@1, "cannot construct this type", getBasicString($1.type)); - context->recover(); - $1.type = EbtFloat; - op = EOpConstructFloat; - } - } - TString tempString; - TType type($1); - TFunction *function = new TFunction(&tempString, type, op); - $$ = function; + $$ = context->addConstructorFunc($1); } | IDENTIFIER { if (context->reservedErrorCheck(@1, *$1.string)) @@ -620,7 +507,7 @@ unary_expression | INC_OP unary_expression { if (context->lValueErrorCheck(@1, "++", $2)) context->recover(); - $$ = context->intermediate.addUnaryMath(EOpPreIncrement, $2, @1, context->symbolTable); + $$ = context->intermediate.addUnaryMath(EOpPreIncrement, $2, @1); if ($$ == 0) { context->unaryOpError(@1, "++", $2->getCompleteString()); context->recover(); @@ -630,7 +517,7 @@ unary_expression | DEC_OP unary_expression { if (context->lValueErrorCheck(@1, "--", $2)) context->recover(); - $$ = context->intermediate.addUnaryMath(EOpPreDecrement, $2, @1, context->symbolTable); + $$ = context->intermediate.addUnaryMath(EOpPreDecrement, $2, @1); if ($$ == 0) { context->unaryOpError(@1, "--", $2->getCompleteString()); context->recover(); @@ -639,7 +526,7 @@ unary_expression } | unary_operator unary_expression { if ($1.op != EOpNull) { - $$ = context->intermediate.addUnaryMath($1.op, $2, @1, context->symbolTable); + $$ = context->intermediate.addUnaryMath($1.op, $2, @1); if ($$ == 0) { const char* errorOp = ""; switch($1.op) { @@ -667,7 +554,7 @@ unary_operator multiplicative_expression : unary_expression { $$ = $1; } | multiplicative_expression STAR unary_expression { - $$ = context->intermediate.addBinaryMath(EOpMul, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpMul, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "*", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -675,7 +562,7 @@ multiplicative_expression } } | multiplicative_expression SLASH unary_expression { - $$ = context->intermediate.addBinaryMath(EOpDiv, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpDiv, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "/", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -687,7 +574,7 @@ multiplicative_expression additive_expression : multiplicative_expression { $$ = $1; } | additive_expression PLUS multiplicative_expression { - $$ = context->intermediate.addBinaryMath(EOpAdd, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpAdd, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "+", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -695,7 +582,7 @@ additive_expression } } | additive_expression DASH multiplicative_expression { - $$ = context->intermediate.addBinaryMath(EOpSub, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpSub, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "-", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -711,7 +598,7 @@ shift_expression relational_expression : shift_expression { $$ = $1; } | relational_expression LEFT_ANGLE shift_expression { - $$ = context->intermediate.addBinaryMath(EOpLessThan, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpLessThan, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "<", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -721,7 +608,7 @@ relational_expression } } | relational_expression RIGHT_ANGLE shift_expression { - $$ = context->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, ">", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -731,7 +618,7 @@ relational_expression } } | relational_expression LE_OP shift_expression { - $$ = context->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "<=", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -741,7 +628,7 @@ relational_expression } } | relational_expression GE_OP shift_expression { - $$ = context->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, ">=", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -755,7 +642,7 @@ relational_expression equality_expression : relational_expression { $$ = $1; } | equality_expression EQ_OP relational_expression { - $$ = context->intermediate.addBinaryMath(EOpEqual, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpEqual, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "==", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -765,7 +652,7 @@ equality_expression } } | equality_expression NE_OP relational_expression { - $$ = context->intermediate.addBinaryMath(EOpNotEqual, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpNotEqual, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "!=", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -791,7 +678,7 @@ inclusive_or_expression logical_and_expression : inclusive_or_expression { $$ = $1; } | logical_and_expression AND_OP inclusive_or_expression { - $$ = context->intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "&&", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -805,7 +692,7 @@ logical_and_expression logical_xor_expression : logical_and_expression { $$ = $1; } | logical_xor_expression XOR_OP logical_and_expression { - $$ = context->intermediate.addBinaryMath(EOpLogicalXor, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpLogicalXor, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "^^", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -819,7 +706,7 @@ logical_xor_expression logical_or_expression : logical_xor_expression { $$ = $1; } | logical_or_expression OR_OP logical_xor_expression { - $$ = context->intermediate.addBinaryMath(EOpLogicalOr, $1, $3, @2, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpLogicalOr, $1, $3, @2); if ($$ == 0) { context->binaryOpError(@2, "||", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -892,6 +779,14 @@ constant_expression } ; +enter_struct + : IDENTIFIER LEFT_BRACE { + if (context->enterStructDeclaration(@1, *$1.string)) + context->recover(); + $$ = $1; + } + ; + declaration : function_prototype SEMICOLON { TFunction &function = *($1.function); @@ -926,7 +821,7 @@ declaration $$ = $1.intermAggregate; } | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON { - if (($2 == EbpHigh) && (context->shaderType == SH_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) { + if (($2 == EbpHigh) && (context->shaderType == GL_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) { context->error(@1, "precision is not supported in fragment shader", "highp"); context->recover(); } @@ -936,6 +831,22 @@ declaration } $$ = 0; } + | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE SEMICOLON { + ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks"); + $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, NULL, @$, NULL, @$); + } + | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER SEMICOLON { + ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks"); + $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, $5.string, @5, NULL, @$); + } + | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET SEMICOLON { + ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks"); + $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, $5.string, @5, $7, @6); + } + | type_qualifier SEMICOLON { + context->parseGlobalLayoutQualifier($1); + $$ = 0; + } ; function_prototype @@ -948,7 +859,7 @@ function_prototype // // Redeclarations are allowed. But, return types and parameter qualifiers must match. // - TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find($1->getMangledName())); + TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find($1->getMangledName(), context->shaderVersion)); if (prevDec) { if (prevDec->getReturnType() != $1->getReturnType()) { context->error(@2, "overloaded functions must have the same return type", $1->getReturnType().getBasicString()); @@ -965,7 +876,7 @@ function_prototype // // Check for previously declared variables using the same name. // - TSymbol *prevSym = context->symbolTable.find($1->getName()); + TSymbol *prevSym = context->symbolTable.find($1->getName(), context->shaderVersion); if (prevSym) { if (!prevSym->isFunction()) @@ -977,7 +888,8 @@ function_prototype else { // Insert the unmangled name to detect potential future redefinition as a variable. - context->symbolTable.getOuterLevel()->insert($1->getName(), *$1); + TFunction *function = new TFunction(NewPoolTString($1->getName().c_str()), $1->getReturnType()); + context->symbolTable.getOuterLevel()->insert(function); } // @@ -989,7 +901,7 @@ function_prototype // We're at the inner scope level of the function's arguments and body statement. // Add the function prototype to the surrounding scope instead. - context->symbolTable.getOuterLevel()->insert(*$$.function); + context->symbolTable.getOuterLevel()->insert($$.function); } ; @@ -1092,9 +1004,9 @@ parameter_declaration // // Type + name // - : type_qualifier parameter_qualifier parameter_declarator { + : parameter_type_qualifier parameter_qualifier parameter_declarator { $$ = $3; - if (context->paramErrorCheck(@3, $1.qualifier, $2, $$.param.type)) + if (context->paramErrorCheck(@3, $1, $2, $$.param.type)) context->recover(); } | parameter_qualifier parameter_declarator { @@ -1107,9 +1019,9 @@ parameter_declaration // // Only type // - | type_qualifier parameter_qualifier parameter_type_specifier { + | parameter_type_qualifier parameter_qualifier parameter_type_specifier { $$ = $3; - if (context->paramErrorCheck(@3, $1.qualifier, $2, $$.param.type)) + if (context->paramErrorCheck(@3, $1, $2, $$.param.type)) context->recover(); } | parameter_qualifier parameter_type_specifier { @@ -1148,173 +1060,46 @@ init_declarator_list $$ = $1; } | init_declarator_list COMMA identifier { - if ($1.type.type == EbtInvariant && !$3.symbol) - { - context->error(@3, "undeclared identifier declared as invariant", $3.string->c_str()); - context->recover(); - } - - TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$3.string, TType($1.type), @3); - $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, symbol, @3); - - if (context->structQualifierErrorCheck(@3, $$.type)) - context->recover(); - - if (context->nonInitConstErrorCheck(@3, *$3.string, $$.type, false)) - context->recover(); - - TVariable* variable = 0; - if (context->nonInitErrorCheck(@3, *$3.string, $$.type, variable)) - context->recover(); - if (symbol && variable) - symbol->setId(variable->getUniqueId()); + $$ = $1; + $$.intermAggregate = context->parseDeclarator($$.type, $1.intermAggregate, $3.symbol, @3, *$3.string); } | init_declarator_list COMMA identifier LEFT_BRACKET RIGHT_BRACKET { - if (context->structQualifierErrorCheck(@3, $1.type)) - context->recover(); - - if (context->nonInitConstErrorCheck(@3, *$3.string, $1.type, true)) - context->recover(); - $$ = $1; - - if (context->arrayTypeErrorCheck(@4, $1.type) || context->arrayQualifierErrorCheck(@4, $1.type)) - context->recover(); - else { - $1.type.setArray(true); - TVariable* variable; - if (context->arrayErrorCheck(@4, *$3.string, $1.type, variable)) - context->recover(); - } + context->parseArrayDeclarator($$.type, @3, *$3.string, @4, NULL, NULL); } | init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { - if (context->structQualifierErrorCheck(@3, $1.type)) - context->recover(); - - if (context->nonInitConstErrorCheck(@3, *$3.string, $1.type, true)) - context->recover(); - $$ = $1; - - if (context->arrayTypeErrorCheck(@4, $1.type) || context->arrayQualifierErrorCheck(@4, $1.type)) - context->recover(); - else { - int size; - if (context->arraySizeErrorCheck(@4, $5, size)) - context->recover(); - $1.type.setArray(true, size); - TVariable* variable = 0; - if (context->arrayErrorCheck(@4, *$3.string, $1.type, variable)) - context->recover(); - TType type = TType($1.type); - type.setArraySize(size); - $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(variable ? variable->getUniqueId() : 0, *$3.string, type, @3), @3); - } + $$.intermAggregate = context->parseArrayDeclarator($$.type, @3, *$3.string, @4, $1.intermNode, $5); } | init_declarator_list COMMA identifier EQUAL initializer { - if (context->structQualifierErrorCheck(@3, $1.type)) - context->recover(); - $$ = $1; - - TIntermNode* intermNode; - if (!context->executeInitializer(@3, *$3.string, $1.type, $5, intermNode)) { - // - // build the intermediate representation - // - if (intermNode) - $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, intermNode, @4); - else - $$.intermAggregate = $1.intermAggregate; - } else { - context->recover(); - $$.intermAggregate = 0; - } + $$.intermAggregate = context->parseInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5); } ; single_declaration : fully_specified_type { $$.type = $1; - $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType($1), @1), @1); + $$.intermAggregate = context->parseSingleDeclaration($$.type, @1, ""); } | fully_specified_type identifier { - TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), @2); - $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2); - - if (context->structQualifierErrorCheck(@2, $$.type)) - context->recover(); - - if (context->nonInitConstErrorCheck(@2, *$2.string, $$.type, false)) - context->recover(); - - $$.type = $1; - - TVariable* variable = 0; - if (context->nonInitErrorCheck(@2, *$2.string, $$.type, variable)) - context->recover(); - if (variable && symbol) - symbol->setId(variable->getUniqueId()); + $$.type = $1; + $$.intermAggregate = context->parseSingleDeclaration($$.type, @2, *$2.string); } | fully_specified_type identifier LEFT_BRACKET RIGHT_BRACKET { context->error(@2, "unsized array declarations not supported", $2.string->c_str()); context->recover(); - TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), @2); - $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2); $$.type = $1; + $$.intermAggregate = context->parseSingleDeclaration($$.type, @2, *$2.string); } | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { - TType type = TType($1); - int size; - if (context->arraySizeErrorCheck(@2, $4, size)) - context->recover(); - type.setArraySize(size); - TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, type, @2); - $$.intermAggregate = context->intermediate.makeAggregate(symbol, @2); - - if (context->structQualifierErrorCheck(@2, $1)) - context->recover(); - - if (context->nonInitConstErrorCheck(@2, *$2.string, $1, true)) - context->recover(); - $$.type = $1; - - if (context->arrayTypeErrorCheck(@3, $1) || context->arrayQualifierErrorCheck(@3, $1)) - context->recover(); - else { - int size; - if (context->arraySizeErrorCheck(@3, $4, size)) - context->recover(); - - $1.setArray(true, size); - TVariable* variable = 0; - if (context->arrayErrorCheck(@3, *$2.string, $1, variable)) - context->recover(); - if (variable && symbol) - symbol->setId(variable->getUniqueId()); - } + $$.intermAggregate = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, $4); } | fully_specified_type identifier EQUAL initializer { - if (context->structQualifierErrorCheck(@2, $1)) - context->recover(); - $$.type = $1; - - TIntermNode* intermNode; - if (!context->executeInitializer(@2, *$2.string, $1, $4, intermNode)) { - // - // Build intermediate representation - // - if(intermNode) - $$.intermAggregate = context->intermediate.makeAggregate(intermNode, @3); - else - $$.intermAggregate = 0; - } else { - context->recover(); - $$.intermAggregate = 0; - } + $$.intermAggregate = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4); } | INVARIANT IDENTIFIER { VERTEX_ONLY("invariant declaration", @1); @@ -1347,57 +1132,113 @@ fully_specified_type } } | type_qualifier type_specifier { - if ($2.array) { - context->error(@2, "not supported", "first-class array"); - context->recover(); - $2.setArray(false); - } + $$ = context->addFullySpecifiedType($1.qualifier, $1.layoutQualifier, $2); + } + ; - if ($1.qualifier == EvqAttribute && - ($2.type == EbtBool || $2.type == EbtInt)) { - context->error(@2, "cannot be bool or int", getQualifierString($1.qualifier)); - context->recover(); - } - if (($1.qualifier == EvqVaryingIn || $1.qualifier == EvqVaryingOut) && - ($2.type == EbtBool || $2.type == EbtInt)) { - context->error(@2, "cannot be bool or int", getQualifierString($1.qualifier)); - context->recover(); - } - $$ = $2; - $$.qualifier = $1.qualifier; +interpolation_qualifier + : SMOOTH { + $$.qualifier = EvqSmooth; + } + | FLAT { + $$.qualifier = EvqFlat; } ; -type_qualifier +parameter_type_qualifier : CONST_QUAL { - $$.setBasic(EbtVoid, EvqConst, @1); + $$ = EvqConst; } - | ATTRIBUTE { + ; + +type_qualifier + : ATTRIBUTE { VERTEX_ONLY("attribute", @1); + ES2_ONLY("attribute", @1); if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "attribute")) context->recover(); $$.setBasic(EbtVoid, EvqAttribute, @1); } | VARYING { + ES2_ONLY("varying", @1); if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "varying")) context->recover(); - if (context->shaderType == SH_VERTEX_SHADER) + if (context->shaderType == GL_VERTEX_SHADER) $$.setBasic(EbtVoid, EvqVaryingOut, @1); else $$.setBasic(EbtVoid, EvqVaryingIn, @1); } | INVARIANT VARYING { + ES2_ONLY("varying", @1); if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying")) context->recover(); - if (context->shaderType == SH_VERTEX_SHADER) + if (context->shaderType == GL_VERTEX_SHADER) $$.setBasic(EbtVoid, EvqInvariantVaryingOut, @1); else $$.setBasic(EbtVoid, EvqInvariantVaryingIn, @1); } + | storage_qualifier { + if ($1.qualifier != EvqConst && !context->symbolTable.atGlobalLevel()) { + context->error(@1, "Local variables can only use the const storage qualifier.", getQualifierString($1.qualifier)); + context->recover(); + } else { + $$.setBasic(EbtVoid, $1.qualifier, @1); + } + } + | interpolation_qualifier storage_qualifier { + $$ = context->joinInterpolationQualifiers(@1, $1.qualifier, @2, $2.qualifier); + } + | interpolation_qualifier { + context->error(@1, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getInterpolationString($1.qualifier)); + context->recover(); + + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtVoid, qual, @1); + } + | layout_qualifier { + $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.layoutQualifier = $1; + } + | layout_qualifier storage_qualifier { + $$.setBasic(EbtVoid, $2.qualifier, @2); + $$.layoutQualifier = $1; + } + ; + +storage_qualifier + : CONST_QUAL { + $$.qualifier = EvqConst; + } + | IN_QUAL { + ES3_ONLY("in", @1, "storage qualifier"); + $$.qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn; + } + | OUT_QUAL { + ES3_ONLY("out", @1, "storage qualifier"); + $$.qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut; + } + | CENTROID IN_QUAL { + ES3_ONLY("centroid in", @1, "storage qualifier"); + if (context->shaderType == GL_VERTEX_SHADER) + { + context->error(@1, "invalid storage qualifier", "it is an error to use 'centroid in' in the vertex shader"); + context->recover(); + } + $$.qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn; + } + | CENTROID OUT_QUAL { + ES3_ONLY("centroid out", @1, "storage qualifier"); + if (context->shaderType == GL_FRAGMENT_SHADER) + { + context->error(@1, "invalid storage qualifier", "it is an error to use 'centroid out' in the fragment shader"); + context->recover(); + } + $$.qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut; + } | UNIFORM { if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "uniform")) context->recover(); - $$.setBasic(EbtVoid, EvqUniform, @1); + $$.qualifier = EvqUniform; } ; @@ -1415,6 +1256,11 @@ type_specifier | precision_qualifier type_specifier_no_prec { $$ = $2; $$.precision = $1; + + if (!SupportsPrecision($2.type)) { + context->error(@1, "illegal type for precision qualifier", getBasicString($2.type)); + context->recover(); + } } ; @@ -1430,6 +1276,34 @@ precision_qualifier } ; +layout_qualifier + : LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN { + ES3_ONLY("layout", @1, "qualifier"); + $$ = $3; + } + ; + +layout_qualifier_id_list + : layout_qualifier_id { + $$ = $1; + } + | layout_qualifier_id_list COMMA layout_qualifier_id { + $$ = context->joinLayoutQualifiers($1, $3); + } + ; + +layout_qualifier_id + : IDENTIFIER { + $$ = context->parseLayoutQualifier(*$1.string, @1); + } + | IDENTIFIER EQUAL INTCONSTANT { + $$ = context->parseLayoutQualifier(*$1.string, @1, *$3.string, $3.i, @3); + } + | IDENTIFIER EQUAL UINTCONSTANT { + $$ = context->parseLayoutQualifier(*$1.string, @1, *$3.string, $3.i, @3); + } + ; + type_specifier_no_prec : type_specifier_nonarray { $$ = $1; @@ -1461,6 +1335,10 @@ type_specifier_nonarray TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.setBasic(EbtInt, qual, @1); } + | UINT_TYPE { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUInt, qual, @1); + } | BOOL_TYPE { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.setBasic(EbtBool, qual, @1); @@ -1510,29 +1388,126 @@ type_specifier_nonarray $$.setBasic(EbtInt, qual, @1); $$.setAggregate(4); } + | UVEC2 { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUInt, qual, @1); + $$.setAggregate(2); + } + | UVEC3 { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUInt, qual, @1); + $$.setAggregate(3); + } + | UVEC4 { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUInt, qual, @1); + $$.setAggregate(4); + } | MATRIX2 { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.setBasic(EbtFloat, qual, @1); - $$.setAggregate(2, true); + $$.setMatrix(2, 2); } | MATRIX3 { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.setBasic(EbtFloat, qual, @1); - $$.setAggregate(3, true); + $$.setMatrix(3, 3); } | MATRIX4 { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.setBasic(EbtFloat, qual, @1); - $$.setAggregate(4, true); + $$.setMatrix(4, 4); + } + | MATRIX2x3 { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); + $$.setMatrix(2, 3); + } + | MATRIX3x2 { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); + $$.setMatrix(3, 2); + } + | MATRIX2x4 { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); + $$.setMatrix(2, 4); + } + | MATRIX4x2 { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); + $$.setMatrix(4, 2); + } + | MATRIX3x4 { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); + $$.setMatrix(3, 4); + } + | MATRIX4x3 { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); + $$.setMatrix(4, 3); } | SAMPLER2D { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.setBasic(EbtSampler2D, qual, @1); } + | SAMPLER3D { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSampler3D, qual, @1); + } | SAMPLERCUBE { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.setBasic(EbtSamplerCube, qual, @1); } + | SAMPLER2DARRAY { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSampler2DArray, qual, @1); + } + | ISAMPLER2D { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtISampler2D, qual, @1); + } + | ISAMPLER3D { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtISampler3D, qual, @1); + } + | ISAMPLERCUBE { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtISamplerCube, qual, @1); + } + | ISAMPLER2DARRAY { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtISampler2DArray, qual, @1); + } + | USAMPLER2D { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUSampler2D, qual, @1); + } + | USAMPLER3D { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUSampler3D, qual, @1); + } + | USAMPLERCUBE { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUSamplerCube, qual, @1); + } + | USAMPLER2DARRAY { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUSampler2DArray, qual, @1); + } + | SAMPLER2DSHADOW { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSampler2DShadow, qual, @1); + } + | SAMPLERCUBESHADOW { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSamplerCubeShadow, qual, @1); + } + | SAMPLER2DARRAYSHADOW { + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSampler2DArrayShadow, qual, @1); + } | SAMPLER_EXTERNAL_OES { if (!context->supportsExtension("GL_OES_EGL_image_external")) { context->error(@1, "unsupported type", "samplerExternalOES"); @@ -1567,24 +1542,10 @@ type_specifier_nonarray struct_specifier : STRUCT identifier LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { - if (context->reservedErrorCheck(@2, *$2.string)) - context->recover(); - - TType* structure = new TType(new TStructure($2.string, $5)); - TVariable* userTypeDef = new TVariable($2.string, *structure, true); - if (! context->symbolTable.insert(*userTypeDef)) { - context->error(@2, "redefinition", $2.string->c_str(), "struct"); - context->recover(); - } - $$.setBasic(EbtStruct, EvqTemporary, @1); - $$.userDef = structure; - context->exitStructDeclaration(); + $$ = context->addStructure(@1, @2, $2.string, $5); } | STRUCT LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { - TType* structure = new TType(new TStructure(NewPoolTString(""), $4)); - $$.setBasic(EbtStruct, EvqTemporary, @1); - $$.userDef = structure; - context->exitStructDeclaration(); + $$ = context->addStructure(@1, @$, NewPoolTString(""), $4); } ; @@ -1609,34 +1570,13 @@ struct_declaration_list struct_declaration : type_specifier struct_declarator_list SEMICOLON { - $$ = $2; - - if (context->voidErrorCheck(@1, (*$2)[0]->name(), $1)) { - context->recover(); - } - for (unsigned int i = 0; i < $$->size(); ++i) { - // - // Careful not to replace already known aspects of type, like array-ness - // - TType* type = (*$$)[i]->type(); - type->setBasicType($1.type); - type->setNominalSize($1.size); - type->setMatrix($1.matrix); - type->setPrecision($1.precision); - - // don't allow arrays of arrays - if (type->isArray()) { - if (context->arrayTypeErrorCheck(@1, $1)) - context->recover(); - } - if ($1.array) - type->setArraySize($1.arraySize); - if ($1.userDef) - type->setStruct($1.userDef->getStruct()); - - if (context->structNestingErrorCheck(@1, *(*$$)[i])) - context->recover(); - } + $$ = context->addStructDeclaratorList($1, $2); + } + | type_qualifier type_specifier struct_declarator_list SEMICOLON { + // ES3 Only, but errors should be handled elsewhere + $2.qualifier = $1.qualifier; + $2.layoutQualifier = $1.layoutQualifier; + $$ = context->addStructDeclaratorList($2, $3); } ; @@ -1656,19 +1596,19 @@ struct_declarator context->recover(); TType* type = new TType(EbtVoid, EbpUndefined); - $$ = new TField(type, $1.string); + $$ = new TField(type, $1.string, @1); } | identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { if (context->reservedErrorCheck(@1, *$1.string)) context->recover(); TType* type = new TType(EbtVoid, EbpUndefined); - int size = 0; + int size; if (context->arraySizeErrorCheck(@3, $3, size)) context->recover(); type->setArraySize(size); - $$ = new TField(type, $1.string); + $$ = new TField(type, $1.string, @1); } ; @@ -1902,7 +1842,7 @@ function_definition : function_prototype { TFunction* function = $1.function; - const TSymbol *builtIn = context->symbolTable.findBuiltIn(function->getMangledName()); + const TSymbol *builtIn = context->symbolTable.findBuiltIn(function->getMangledName(), context->shaderVersion); if (builtIn) { @@ -1910,7 +1850,7 @@ function_definition context->recover(); } - TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find(function->getMangledName())); + TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find(function->getMangledName(), context->shaderVersion)); // // Note: 'prevDec' could be 'function' if this is the first time we've seen function // as it would have just been put in the symbol table. Otherwise, we're looking up @@ -1961,7 +1901,7 @@ function_definition // // Insert the parameters with name in the symbol table. // - if (! context->symbolTable.insert(*variable)) { + if (! context->symbolTable.declare(variable)) { context->error(@1, "redefinition", variable->getName().c_str()); context->recover(); delete variable; @@ -1973,9 +1913,8 @@ function_definition paramNodes = context->intermediate.growAggregate( paramNodes, context->intermediate.addSymbol(variable->getUniqueId(), - variable->getName(), - variable->getType(), - @1), + variable->getName(), + variable->getType(), @1), @1); } else { paramNodes = context->intermediate.growAggregate(paramNodes, context->intermediate.addSymbol(0, "", *param.type, @1), @1); |