diff options
author | wolfbeast <mcwerewolf@gmail.com> | 2018-07-11 23:29:50 +0200 |
---|---|---|
committer | wolfbeast <mcwerewolf@gmail.com> | 2018-07-11 23:31:02 +0200 |
commit | 70dd5e7c66b1fe3f82e5b4db2406050baba15f05 (patch) | |
tree | 3f012200ef3c934f33db1a4ef2b790fae3141860 /gfx/angle/src/compiler/translator/glslang.y | |
parent | 3b7ffb477eec078c7036c92c6a51bb5de6de4f28 (diff) | |
parent | 8481fa25d246f1968d0a254ee3c6cdd82c60781a (diff) | |
download | UXP-70dd5e7c66b1fe3f82e5b4db2406050baba15f05.tar UXP-70dd5e7c66b1fe3f82e5b4db2406050baba15f05.tar.gz UXP-70dd5e7c66b1fe3f82e5b4db2406050baba15f05.tar.lz UXP-70dd5e7c66b1fe3f82e5b4db2406050baba15f05.tar.xz UXP-70dd5e7c66b1fe3f82e5b4db2406050baba15f05.zip |
Merge branch 'ANGLE-rollback'
This resolves #624
Note: Cherry-picked some fixes on top of the ANGLE version that we want to keep.
Diffstat (limited to 'gfx/angle/src/compiler/translator/glslang.y')
-rwxr-xr-x | gfx/angle/src/compiler/translator/glslang.y | 544 |
1 files changed, 278 insertions, 266 deletions
diff --git a/gfx/angle/src/compiler/translator/glslang.y b/gfx/angle/src/compiler/translator/glslang.y index c15dd9d6e..8604d8eb6 100755 --- a/gfx/angle/src/compiler/translator/glslang.y +++ b/gfx/angle/src/compiler/translator/glslang.y @@ -46,8 +46,6 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). #define YYENABLE_NLS 0 -using namespace sh; - %} %expect 1 /* One shift reduce conflict because of if | else */ %parse-param {TParseContext* context} @@ -74,27 +72,22 @@ using namespace sh; struct { TOperator op; union { - TIntermNode *intermNode; + TIntermNode* intermNode; TIntermNodePair nodePair; - TIntermTyped *intermTypedNode; - TIntermAggregate *intermAggregate; - TIntermBlock *intermBlock; - TIntermDeclaration *intermDeclaration; - TIntermSwitch *intermSwitch; - TIntermCase *intermCase; + TIntermTyped* intermTypedNode; + TIntermAggregate* intermAggregate; + TIntermSwitch* intermSwitch; + TIntermCase* intermCase; }; union { - TTypeSpecifierNonArray typeSpecifierNonArray; TPublicType type; TPrecision precision; TLayoutQualifier layoutQualifier; TQualifier qualifier; - TFunction *function; + TFunction* function; TParameter param; - TField *field; - TFieldList *fieldList; - TQualifierWrapperBase *qualifierWrapper; - TTypeQualifierBuilder *typeQualifierBuilder; + TField* field; + TFieldList* fieldList; }; } interm; } @@ -169,14 +162,11 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons %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> READONLY WRITEONLY COHERENT RESTRICT VOLATILE %token <lex> STRUCT VOID_TYPE WHILE %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> IMAGE2D IIMAGE2D UIMAGE2D IMAGE3D IIMAGE3D UIMAGE3D IMAGE2DARRAY IIMAGE2DARRAY UIMAGE2DARRAY -%token <lex> IMAGECUBE IIMAGECUBE UIMAGECUBE %token <lex> LAYOUT %token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT UINTCONSTANT BOOLCONSTANT @@ -202,9 +192,9 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons %type <interm.intermTypedNode> shift_expression and_expression exclusive_or_expression inclusive_or_expression %type <interm.intermTypedNode> function_call initializer condition conditionopt -%type <interm.intermBlock> translation_unit -%type <interm.intermNode> function_definition statement simple_statement -%type <interm.intermBlock> statement_list compound_statement compound_statement_no_new_scope +%type <interm.intermNode> translation_unit function_definition +%type <interm.intermNode> statement simple_statement +%type <interm.intermAggregate> statement_list compound_statement compound_statement_no_new_scope %type <interm.intermNode> declaration_statement selection_statement expression_statement %type <interm.intermNode> declaration external_declaration %type <interm.intermNode> for_init_statement @@ -215,18 +205,13 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons %type <interm> single_declaration init_declarator_list %type <interm> parameter_declaration parameter_declarator parameter_type_specifier -%type <interm.layoutQualifier> layout_qualifier_id_list layout_qualifier_id - -%type <interm.type> fully_specified_type type_specifier +%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.layoutQualifier> layout_qualifier -%type <interm.qualifier> interpolation_qualifier -%type <interm.qualifierWrapper> storage_qualifier single_type_qualifier invariant_qualifier -%type <interm.typeQualifierBuilder> type_qualifier - -%type <interm.typeSpecifierNonArray> type_specifier_nonarray struct_specifier -%type <interm.type> type_specifier_no_prec +%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 %type <interm.fieldList> struct_declarator_list struct_declaration struct_declaration_list %type <interm.function> function_header function_declarator function_identifier @@ -358,7 +343,7 @@ function_call_header_with_parameters const TType *type = new TType($2->getType()); $1->addParameter(TConstParameter(type)); $$.function = $1; - $$.nodePair.node1 = TIntermediate::MakeAggregate($2, @2); + $$.nodePair.node1 = context->intermediate.makeAggregate($2, @2); } | function_call_header_with_parameters COMMA assignment_expression { const TType *type = new TType($3->getType()); @@ -609,43 +594,41 @@ declaration $$ = context->addFunctionPrototypeDeclaration(*($1.function), @1); } | init_declarator_list SEMICOLON { - $$ = $1.intermDeclaration; + TIntermAggregate *aggNode = $1.intermAggregate; + if (aggNode && aggNode->getOp() == EOpNull) + aggNode->setOp(EOpDeclaration); + $$ = aggNode; } | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON { if (($2 == EbpHigh) && (context->getShaderType() == GL_FRAGMENT_SHADER) && !context->getFragmentPrecisionHigh()) { context->error(@1, "precision is not supported in fragment shader", "highp"); } if (!context->symbolTable.setDefaultPrecision( $3, $2 )) { - context->error(@1, "illegal type argument for default precision qualifier", getBasicString($3.getBasicType())); + context->error(@1, "illegal type argument for default precision qualifier", getBasicString($3.type)); } $$ = 0; } | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE SEMICOLON { - ES3_OR_NEWER($2.string->c_str(), @1, "interface blocks"); - $$ = context->addInterfaceBlock(*$1, @2, *$2.string, $3, NULL, @$, NULL, @$); + ES3_OR_NEWER(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_OR_NEWER($2.string->c_str(), @1, "interface blocks"); - $$ = context->addInterfaceBlock(*$1, @2, *$2.string, $3, $5.string, @5, NULL, @$); + ES3_OR_NEWER(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_OR_NEWER($2.string->c_str(), @1, "interface blocks"); - $$ = context->addInterfaceBlock(*$1, @2, *$2.string, $3, $5.string, @5, $7, @6); + ES3_OR_NEWER(getQualifierString($1.qualifier), @1, "interface blocks"); + $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, $5.string, @5, $7, @6); } | type_qualifier SEMICOLON { - context->parseGlobalLayoutQualifier(*$1); + context->parseGlobalLayoutQualifier($1); $$ = 0; } - | type_qualifier IDENTIFIER SEMICOLON // e.g. to qualify an existing variable as invariant - { - $$ = context->parseInvariantDeclaration(*$1, @2, $2.string, $2.symbol); - } ; function_prototype : function_declarator RIGHT_PAREN { $$.function = context->parseFunctionDeclarator(@2, $1); - context->exitFunctionDeclaration(); } ; @@ -692,14 +675,13 @@ function_header $$ = context->parseFunctionHeader($1, $2.string, @2); context->symbolTable.push(); - context->enterFunctionDeclaration(); } ; parameter_declarator // Type + name : type_specifier identifier { - if ($1.getBasicType() == EbtVoid) { + if ($1.type == EbtVoid) { context->error(@2, "illegal use of type 'void'", $2.string->c_str()); } context->checkIsNotReserved(@2, *$2.string); @@ -731,21 +713,41 @@ parameter_declaration // // Type + name // - : type_qualifier parameter_declarator { + : parameter_type_qualifier parameter_qualifier parameter_declarator { + $$ = $3; + context->checkIsParameterQualifierValid(@3, $1, $2, $$.param.type); + } + | parameter_qualifier parameter_declarator { $$ = $2; - context->checkIsParameterQualifierValid(@2, *$1, $2.param.type); + context->checkOutParameterIsNotSampler(@2, $1, *$2.param.type); + context->checkIsParameterQualifierValid(@2, EvqTemporary, $1, $$.param.type); } - | parameter_declarator { - $$ = $1; - $$.param.type->setQualifier(EvqIn); + // + // Only type + // + | parameter_type_qualifier parameter_qualifier parameter_type_specifier { + $$ = $3; + context->checkIsParameterQualifierValid(@3, $1, $2, $$.param.type); } - | type_qualifier parameter_type_specifier { + | parameter_qualifier parameter_type_specifier { $$ = $2; - context->checkIsParameterQualifierValid(@2, *$1, $2.param.type); + context->checkOutParameterIsNotSampler(@2, $1, *$2.param.type); + context->checkIsParameterQualifierValid(@2, EvqTemporary, $1, $$.param.type); } - | parameter_type_specifier { - $$ = $1; - $$.param.type->setQualifier(EvqIn); + ; + +parameter_qualifier + : /* empty */ { + $$ = EvqIn; + } + | IN_QUAL { + $$ = EvqIn; + } + | OUT_QUAL { + $$ = EvqOut; + } + | INOUT_QUAL { + $$ = EvqInOut; } ; @@ -762,209 +764,209 @@ init_declarator_list } | init_declarator_list COMMA identifier { $$ = $1; - context->parseDeclarator($$.type, @3, *$3.string, $$.intermDeclaration); + $$.intermAggregate = context->parseDeclarator($$.type, $1.intermAggregate, @3, *$3.string); } | init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { $$ = $1; - context->parseArrayDeclarator($$.type, @3, *$3.string, @4, $5, $$.intermDeclaration); + $$.intermAggregate = context->parseArrayDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5); } | init_declarator_list COMMA identifier LEFT_BRACKET RIGHT_BRACKET EQUAL initializer { ES3_OR_NEWER("[]", @3, "implicitly sized array"); $$ = $1; - context->parseArrayInitDeclarator($$.type, @3, *$3.string, @4, nullptr, @6, $7, $$.intermDeclaration); + $$.intermAggregate = context->parseArrayInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, nullptr, @6, $7); } | init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer { ES3_OR_NEWER("=", @7, "first-class arrays (array initializer)"); $$ = $1; - context->parseArrayInitDeclarator($$.type, @3, *$3.string, @4, $5, @7, $8, $$.intermDeclaration); + $$.intermAggregate = context->parseArrayInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5, @7, $8); } | init_declarator_list COMMA identifier EQUAL initializer { $$ = $1; - context->parseInitDeclarator($$.type, @3, *$3.string, @4, $5, $$.intermDeclaration); + $$.intermAggregate = context->parseInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5); } ; single_declaration : fully_specified_type { $$.type = $1; - $$.intermDeclaration = context->parseSingleDeclaration($$.type, @1, ""); + $$.intermAggregate = context->parseSingleDeclaration($$.type, @1, ""); } | fully_specified_type identifier { $$.type = $1; - $$.intermDeclaration = context->parseSingleDeclaration($$.type, @2, *$2.string); + $$.intermAggregate = context->parseSingleDeclaration($$.type, @2, *$2.string); } | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { $$.type = $1; - $$.intermDeclaration = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, $4); + $$.intermAggregate = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, $4); } | fully_specified_type identifier LEFT_BRACKET RIGHT_BRACKET EQUAL initializer { ES3_OR_NEWER("[]", @3, "implicitly sized array"); $$.type = $1; - $$.intermDeclaration = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, nullptr, @5, $6); + $$.intermAggregate = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, nullptr, @5, $6); } | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer { ES3_OR_NEWER("=", @6, "first-class arrays (array initializer)"); $$.type = $1; - $$.intermDeclaration = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, $4, @6, $7); + $$.intermAggregate = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, $4, @6, $7); } | fully_specified_type identifier EQUAL initializer { $$.type = $1; - $$.intermDeclaration = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4); + $$.intermAggregate = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4); + } + | INVARIANT IDENTIFIER { + // $$.type is not used in invariant declarations. + $$.intermAggregate = context->parseInvariantDeclaration(@1, @2, $2.string, $2.symbol); } ; fully_specified_type : type_specifier { - context->addFullySpecifiedType(&$1); $$ = $1; + + if ($1.array) { + ES3_OR_NEWER("[]", @1, "first-class-array"); + if (context->getShaderVersion() != 300) { + $1.clearArrayness(); + } + } } - | type_qualifier type_specifier { - $$ = context->addFullySpecifiedType(*$1, $2); + | type_qualifier type_specifier { + $$ = context->addFullySpecifiedType($1.qualifier, $1.invariant, $1.layoutQualifier, $2); } ; interpolation_qualifier : SMOOTH { - $$ = EvqSmooth; + $$.qualifier = EvqSmooth; } | FLAT { - $$ = EvqFlat; + $$.qualifier = EvqFlat; } ; -type_qualifier - : single_type_qualifier { - $$ = context->createTypeQualifierBuilder(@1); - $$->appendQualifier($1); - } - | type_qualifier single_type_qualifier { - $$ = $1; - $$->appendQualifier($2); - } - ; - -invariant_qualifier - : INVARIANT { - // empty +parameter_type_qualifier + : CONST_QUAL { + $$ = EvqConst; } ; -single_type_qualifier - : storage_qualifier { - context->checkLocalVariableConstStorageQualifier(*$1); - $$ = $1; - } - | layout_qualifier { - context->checkIsAtGlobalLevel(@1, "layout"); - $$ = new TLayoutQualifierWrapper($1, @1); - } - | precision_qualifier { - $$ = new TPrecisionQualifierWrapper($1, @1); - } - | interpolation_qualifier { - $$ = new TInterpolationQualifierWrapper($1, @1); - } - | invariant_qualifier { - context->checkIsAtGlobalLevel(@1, "invariant"); - $$ = new TInvariantQualifierWrapper(@1); - } - ; - - -storage_qualifier - : - ATTRIBUTE { +type_qualifier + : ATTRIBUTE { VERTEX_ONLY("attribute", @1); ES2_ONLY("attribute", @1); context->checkIsAtGlobalLevel(@1, "attribute"); - $$ = new TStorageQualifierWrapper(EvqAttribute, @1); + $$.setBasic(EbtVoid, EvqAttribute, @1); } | VARYING { ES2_ONLY("varying", @1); context->checkIsAtGlobalLevel(@1, "varying"); if (context->getShaderType() == GL_VERTEX_SHADER) - $$ = new TStorageQualifierWrapper(EvqVaryingOut, @1); + $$.setBasic(EbtVoid, EvqVaryingOut, @1); else - $$ = new TStorageQualifierWrapper(EvqVaryingIn, @1); + $$.setBasic(EbtVoid, EvqVaryingIn, @1); } - | CONST_QUAL { - $$ = new TStorageQualifierWrapper(EvqConst, @1); + | INVARIANT VARYING { + ES2_ONLY("varying", @1); + context->checkIsAtGlobalLevel(@1, "invariant varying"); + if (context->getShaderType() == GL_VERTEX_SHADER) + $$.setBasic(EbtVoid, EvqVaryingOut, @1); + else + $$.setBasic(EbtVoid, EvqVaryingIn, @1); + $$.invariant = true; } - | IN_QUAL { - if (context->declaringFunction()) + | storage_qualifier { + if ($1.qualifier != EvqConst && !context->symbolTable.atGlobalLevel()) { - $$ = new TStorageQualifierWrapper(EvqIn, @1); + context->error(@1, "Local variables can only use the const storage qualifier.", getQualifierString($1.qualifier)); } - else if (context->getShaderType() == GL_FRAGMENT_SHADER) + $$.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)); + + 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; + } + | INVARIANT storage_qualifier { + context->checkInvariantIsOutVariableES3($2.qualifier, @1); + $$.setBasic(EbtVoid, $2.qualifier, @2); + $$.invariant = true; + } + | INVARIANT interpolation_qualifier storage_qualifier { + context->checkInvariantIsOutVariableES3($3.qualifier, @1); + $$ = context->joinInterpolationQualifiers(@2, $2.qualifier, @3, $3.qualifier); + $$.invariant = true; + } + ; + +storage_qualifier + : CONST_QUAL { + $$.qualifier = EvqConst; + } + | IN_QUAL { + if (context->getShaderType() == GL_FRAGMENT_SHADER) { ES3_OR_NEWER("in", @1, "storage qualifier"); - $$ = new TStorageQualifierWrapper(EvqFragmentIn, @1); + $$.qualifier = EvqFragmentIn; } else if (context->getShaderType() == GL_VERTEX_SHADER) { ES3_OR_NEWER("in", @1, "storage qualifier"); - $$ = new TStorageQualifierWrapper(EvqVertexIn, @1); + $$.qualifier = EvqVertexIn; } else { - $$ = new TStorageQualifierWrapper(EvqComputeIn, @1); + $$.qualifier = EvqComputeIn; } } | OUT_QUAL { - if (context->declaringFunction()) - { - $$ = new TStorageQualifierWrapper(EvqOut, @1); - } - else - { - ES3_OR_NEWER("out", @1, "storage qualifier"); - NON_COMPUTE_ONLY("out", @1); - if (context->getShaderType() == GL_FRAGMENT_SHADER) - { - $$ = new TStorageQualifierWrapper(EvqFragmentOut, @1); - } - else - { - $$ = new TStorageQualifierWrapper(EvqVertexOut, @1); - } - } + ES3_OR_NEWER("out", @1, "storage qualifier"); + NON_COMPUTE_ONLY("out", @1); + $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut; } - | INOUT_QUAL { - if (!context->declaringFunction()) - { - context->error(@1, "invalid inout qualifier", "'inout' can be only used with function parameters"); - } - $$ = new TStorageQualifierWrapper(EvqInOut, @1); + | CENTROID IN_QUAL { + ES3_OR_NEWER("centroid in", @1, "storage qualifier"); + FRAG_ONLY("centroid in", @1); + $$.qualifier = EvqCentroidIn; } - | CENTROID { - ES3_OR_NEWER("centroid", @1, "storage qualifier"); - $$ = new TStorageQualifierWrapper(EvqCentroid, @1); + | CENTROID OUT_QUAL { + ES3_OR_NEWER("centroid out", @1, "storage qualifier"); + VERTEX_ONLY("centroid out", @1); + $$.qualifier = EvqCentroidOut; } | UNIFORM { context->checkIsAtGlobalLevel(@1, "uniform"); - $$ = new TStorageQualifierWrapper(EvqUniform, @1); - } - | READONLY { - $$ = new TMemoryQualifierWrapper(EvqReadOnly, @1); - } - | WRITEONLY { - $$ = new TMemoryQualifierWrapper(EvqWriteOnly, @1); - } - | COHERENT { - $$ = new TMemoryQualifierWrapper(EvqCoherent, @1); - } - | RESTRICT { - $$ = new TMemoryQualifierWrapper(EvqRestrict, @1); - } - | VOLATILE { - $$ = new TMemoryQualifierWrapper(EvqVolatile, @1); + $$.qualifier = EvqUniform; } ; type_specifier : type_specifier_no_prec { $$ = $1; - $$.precision = context->symbolTable.getDefaultPrecision($1.getBasicType()); + + if ($$.precision == EbpUndefined) { + $$.precision = context->symbolTable.getDefaultPrecision($1.type); + context->checkPrecisionSpecified(@1, $$.precision, $1.type); + } + } + | precision_qualifier type_specifier_no_prec { + $$ = $2; + $$.precision = $1; + + if (!SupportsPrecision($2.type)) { + context->error(@1, "illegal type for precision qualifier", getBasicString($2.type)); + } } ; @@ -1010,16 +1012,17 @@ layout_qualifier_id type_specifier_no_prec : type_specifier_nonarray { - $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary)); + $$ = $1; } | type_specifier_nonarray LEFT_BRACKET RIGHT_BRACKET { ES3_OR_NEWER("[]", @2, "implicitly sized array"); - $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary)); + $$ = $1; $$.setArraySize(0); } | type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET { - $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary)); - if (context->checkIsValidTypeForArray(@2, $$)) + $$ = $1; + + if (context->checkIsValidTypeForArray(@2, $1)) { unsigned int size = context->checkIsValidArraySize(@2, $3); $$.setArraySize(size); @@ -1029,200 +1032,208 @@ type_specifier_no_prec type_specifier_nonarray : VOID_TYPE { - $$.initialize(EbtVoid, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtVoid, qual, @1); } | FLOAT_TYPE { - $$.initialize(EbtFloat, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); } | INT_TYPE { - $$.initialize(EbtInt, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtInt, qual, @1); } | UINT_TYPE { - $$.initialize(EbtUInt, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUInt, qual, @1); } | BOOL_TYPE { - $$.initialize(EbtBool, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtBool, qual, @1); } | VEC2 { - $$.initialize(EbtFloat, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); $$.setAggregate(2); } | VEC3 { - $$.initialize(EbtFloat, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); $$.setAggregate(3); } | VEC4 { - $$.initialize(EbtFloat, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); $$.setAggregate(4); } | BVEC2 { - $$.initialize(EbtBool, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtBool, qual, @1); $$.setAggregate(2); } | BVEC3 { - $$.initialize(EbtBool, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtBool, qual, @1); $$.setAggregate(3); } | BVEC4 { - $$.initialize(EbtBool, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtBool, qual, @1); $$.setAggregate(4); } | IVEC2 { - $$.initialize(EbtInt, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtInt, qual, @1); $$.setAggregate(2); } | IVEC3 { - $$.initialize(EbtInt, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtInt, qual, @1); $$.setAggregate(3); } | IVEC4 { - $$.initialize(EbtInt, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtInt, qual, @1); $$.setAggregate(4); } | UVEC2 { - $$.initialize(EbtUInt, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUInt, qual, @1); $$.setAggregate(2); } | UVEC3 { - $$.initialize(EbtUInt, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUInt, qual, @1); $$.setAggregate(3); } | UVEC4 { - $$.initialize(EbtUInt, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUInt, qual, @1); $$.setAggregate(4); } | MATRIX2 { - $$.initialize(EbtFloat, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); $$.setMatrix(2, 2); } | MATRIX3 { - $$.initialize(EbtFloat, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); $$.setMatrix(3, 3); } | MATRIX4 { - $$.initialize(EbtFloat, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); $$.setMatrix(4, 4); } | MATRIX2x3 { - $$.initialize(EbtFloat, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); $$.setMatrix(2, 3); } | MATRIX3x2 { - $$.initialize(EbtFloat, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); $$.setMatrix(3, 2); } | MATRIX2x4 { - $$.initialize(EbtFloat, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); $$.setMatrix(2, 4); } | MATRIX4x2 { - $$.initialize(EbtFloat, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); $$.setMatrix(4, 2); } | MATRIX3x4 { - $$.initialize(EbtFloat, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); $$.setMatrix(3, 4); } | MATRIX4x3 { - $$.initialize(EbtFloat, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtFloat, qual, @1); $$.setMatrix(4, 3); } | SAMPLER2D { - $$.initialize(EbtSampler2D, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSampler2D, qual, @1); } | SAMPLER3D { - $$.initialize(EbtSampler3D, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSampler3D, qual, @1); } | SAMPLERCUBE { - $$.initialize(EbtSamplerCube, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSamplerCube, qual, @1); } | SAMPLER2DARRAY { - $$.initialize(EbtSampler2DArray, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSampler2DArray, qual, @1); } | ISAMPLER2D { - $$.initialize(EbtISampler2D, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtISampler2D, qual, @1); } | ISAMPLER3D { - $$.initialize(EbtISampler3D, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtISampler3D, qual, @1); } | ISAMPLERCUBE { - $$.initialize(EbtISamplerCube, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtISamplerCube, qual, @1); } | ISAMPLER2DARRAY { - $$.initialize(EbtISampler2DArray, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtISampler2DArray, qual, @1); } | USAMPLER2D { - $$.initialize(EbtUSampler2D, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUSampler2D, qual, @1); } | USAMPLER3D { - $$.initialize(EbtUSampler3D, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUSampler3D, qual, @1); } | USAMPLERCUBE { - $$.initialize(EbtUSamplerCube, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUSamplerCube, qual, @1); } | USAMPLER2DARRAY { - $$.initialize(EbtUSampler2DArray, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtUSampler2DArray, qual, @1); } | SAMPLER2DSHADOW { - $$.initialize(EbtSampler2DShadow, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSampler2DShadow, qual, @1); } | SAMPLERCUBESHADOW { - $$.initialize(EbtSamplerCubeShadow, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSamplerCubeShadow, qual, @1); } | SAMPLER2DARRAYSHADOW { - $$.initialize(EbtSampler2DArrayShadow, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSampler2DArrayShadow, qual, @1); } | SAMPLER_EXTERNAL_OES { if (!context->supportsExtension("GL_OES_EGL_image_external") && !context->supportsExtension("GL_NV_EGL_stream_consumer_external")) { context->error(@1, "unsupported type", "samplerExternalOES"); } - $$.initialize(EbtSamplerExternalOES, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSamplerExternalOES, qual, @1); } | SAMPLER2DRECT { if (!context->supportsExtension("GL_ARB_texture_rectangle")) { context->error(@1, "unsupported type", "sampler2DRect"); } - $$.initialize(EbtSampler2DRect, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSampler2DRect, qual, @1); } | struct_specifier { $$ = $1; - } - | IMAGE2D { - $$.initialize(EbtImage2D, @1); - } - | IIMAGE2D { - $$.initialize(EbtIImage2D, @1); - } - | UIMAGE2D { - $$.initialize(EbtUImage2D, @1); - } - | IMAGE3D { - $$.initialize(EbtImage3D, @1); - } - | IIMAGE3D { - $$.initialize(EbtIImage3D, @1); - } - | UIMAGE3D { - $$.initialize(EbtUImage3D, @1); - } - | IMAGE2DARRAY { - $$.initialize(EbtImage2DArray, @1); - } - | IIMAGE2DARRAY { - $$.initialize(EbtIImage2DArray, @1); - } - | UIMAGE2DARRAY { - $$.initialize(EbtUImage2DArray, @1); - } - | IMAGECUBE { - $$.initialize(EbtImageCube, @1); - } - | IIMAGECUBE { - $$.initialize(EbtIImageCube, @1); - } - | UIMAGECUBE { - $$.initialize(EbtUImageCube, @1); + $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; } | TYPE_NAME { // @@ -1230,7 +1241,8 @@ type_specifier_nonarray // type. // TType& structure = static_cast<TVariable*>($1.symbol)->getType(); - $$.initialize(EbtStruct, @1); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtStruct, qual, @1); $$.userDef = &structure; } ; @@ -1268,7 +1280,9 @@ struct_declaration } | type_qualifier type_specifier struct_declarator_list SEMICOLON { // ES3 Only, but errors should be handled elsewhere - $$ = context->addStructDeclaratorListWithQualifiers(*$1, &$2, $3); + $2.qualifier = $1.qualifier; + $2.layoutQualifier = $1.layoutQualifier; + $$ = context->addStructDeclaratorList($2, $3); } ; @@ -1329,6 +1343,7 @@ compound_statement : LEFT_BRACE RIGHT_BRACE { $$ = 0; } | LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE { if ($3 != 0) { + $3->setOp(EOpSequence); $3->setLine(@$); } $$ = $3; @@ -1352,6 +1367,7 @@ compound_statement_no_new_scope } | LEFT_BRACE statement_list RIGHT_BRACE { if ($2) { + $2->setOp(EOpSequence); $2->setLine(@$); } $$ = $2; @@ -1360,13 +1376,10 @@ compound_statement_no_new_scope statement_list : statement { - $$ = new TIntermBlock(); - $$->setLine(@$); - $$->appendStatement($1); + $$ = context->intermediate.makeAggregate($1, @$); } | statement_list statement { - $$ = $1; - $$->appendStatement($2); + $$ = context->intermediate.growAggregate($1, $2, @$); } ; @@ -1378,7 +1391,7 @@ expression_statement selection_statement : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement { context->checkIsScalarBool(@1, $3); - $$ = context->intermediate.addIfElse($3, $5, @1); + $$ = context->intermediate.addSelection($3, $5, @1); } ; @@ -1416,10 +1429,10 @@ condition context->checkIsScalarBool($1->getLine(), $1); } | fully_specified_type identifier EQUAL initializer { - TIntermBinary *initNode = nullptr; + TIntermNode *intermNode; context->checkIsScalarBool(@2, $1); - if (!context->executeInitializer(@2, *$2.string, $1, $4, &initNode)) + if (!context->executeInitializer(@2, *$2.string, $1, $4, &intermNode)) $$ = $4; else { $$ = 0; @@ -1498,13 +1511,12 @@ jump_statement translation_unit : external_declaration { - $$ = new TIntermBlock(); - $$->setLine(@$); - $$->appendStatement($1); + $$ = $1; context->setTreeRoot($$); } | translation_unit external_declaration { - $$->appendStatement($2); + $$ = context->intermediate.growAggregate($1, $2, @$); + context->setTreeRoot($$); } ; @@ -1519,7 +1531,7 @@ external_declaration function_definition : function_prototype { - context->parseFunctionDefinitionHeader(@1, &($1.function), &$1.intermAggregate); + context->parseFunctionPrototype(@1, $1.function, &$1.intermAggregate); } compound_statement_no_new_scope { $$ = context->addFunctionDefinition(*($1.function), $1.intermAggregate, $3, @1); |