glsl: Don't allow vertex shader input arrays until GLSL 1.50.
[mesa.git] / src / glsl / glsl_parser.yy
index baac84568cae00dfcc7c0d7559cfef3833e405ae..78f5bf6f4f2038e318e09f2b27a9c4713136b278 100644 (file)
@@ -221,6 +221,7 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg)
 %type <declarator_list> init_declarator_list
 %type <declarator_list> single_declaration
 %type <expression> initializer
+%type <expression> initializer_list
 %type <node> declaration
 %type <node> declaration_statement
 %type <node> jump_statement
@@ -267,10 +268,16 @@ version_statement:
        | VERSION_TOK INTCONSTANT EOL
        {
            state->process_version_directive(&@2, $2, NULL);
+          if (state->error) {
+             YYERROR;
+          }
        }
         | VERSION_TOK INTCONSTANT any_identifier EOL
         {
            state->process_version_directive(&@2, $2, $3);
+          if (state->error) {
+             YYERROR;
+          }
         }
        ;
 
@@ -955,6 +962,11 @@ init_declarator_list:
           $$ = $1;
           $$->declarations.push_tail(&decl->link);
           state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
+          if ($7->oper == ast_aggregate) {
+             ast_aggregate_initializer *ai = (ast_aggregate_initializer *)$7;
+             ast_type_specifier *type = new(ctx) ast_type_specifier($1->type->specifier, true, NULL);
+             _mesa_ast_set_aggregate_type(type, ai, state);
+          }
        }
        | init_declarator_list ',' any_identifier '[' constant_expression ']' '=' initializer
        {
@@ -965,6 +977,11 @@ init_declarator_list:
           $$ = $1;
           $$->declarations.push_tail(&decl->link);
           state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
+          if ($8->oper == ast_aggregate) {
+             ast_aggregate_initializer *ai = (ast_aggregate_initializer *)$8;
+             ast_type_specifier *type = new(ctx) ast_type_specifier($1->type->specifier, true, $5);
+             _mesa_ast_set_aggregate_type(type, ai, state);
+          }
        }
        | init_declarator_list ',' any_identifier '=' initializer
        {
@@ -975,6 +992,10 @@ init_declarator_list:
           $$ = $1;
           $$->declarations.push_tail(&decl->link);
           state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
+          if ($5->oper == ast_aggregate) {
+             ast_aggregate_initializer *ai = (ast_aggregate_initializer *)$5;
+             _mesa_ast_set_aggregate_type($1->type->specifier, ai, state);
+          }
        }
        ;
 
@@ -1022,6 +1043,11 @@ single_declaration:
           $$ = new(ctx) ast_declarator_list($1);
           $$->set_location(yylloc);
           $$->declarations.push_tail(&decl->link);
+          if ($6->oper == ast_aggregate) {
+             ast_aggregate_initializer *ai = (ast_aggregate_initializer *)$6;
+             ast_type_specifier *type = new(ctx) ast_type_specifier($1->specifier, true, NULL);
+             _mesa_ast_set_aggregate_type(type, ai, state);
+          }
        }
        | fully_specified_type any_identifier '[' constant_expression ']' '=' initializer
        {
@@ -1031,6 +1057,11 @@ single_declaration:
           $$ = new(ctx) ast_declarator_list($1);
           $$->set_location(yylloc);
           $$->declarations.push_tail(&decl->link);
+          if ($7->oper == ast_aggregate) {
+             ast_aggregate_initializer *ai = (ast_aggregate_initializer *)$7;
+             ast_type_specifier *type = new(ctx) ast_type_specifier($1->specifier, true, $4);
+             _mesa_ast_set_aggregate_type(type, ai, state);
+          }
        }
        | fully_specified_type any_identifier '=' initializer
        {
@@ -1040,6 +1071,9 @@ single_declaration:
           $$ = new(ctx) ast_declarator_list($1);
           $$->set_location(yylloc);
           $$->declarations.push_tail(&decl->link);
+          if ($4->oper == ast_aggregate) {
+              _mesa_ast_set_aggregate_type($1->specifier, $4, state);
+          }
        }
        | INVARIANT variable_identifier // Vertex only.
        {
@@ -1149,6 +1183,12 @@ layout_qualifier_id:
                 $$.flags.q.shared = 1;
              } else if (strcmp($1, "column_major") == 0) {
                 $$.flags.q.column_major = 1;
+             /* "row_major" is a reserved word in GLSL 1.30+. Its token is parsed
+              * below in the interface_block_layout_qualifier rule.
+              *
+              * It is not a reserved word in GLSL ES 3.00, so it's handled here as
+              * an identifier.
+              */
              } else if (strcmp($1, "row_major") == 0) {
                 $$.flags.q.row_major = 1;
              }
@@ -1171,9 +1211,6 @@ layout_qualifier_id:
           memset(& $$, 0, sizeof($$));
 
           if (state->ARB_explicit_attrib_location_enable) {
-             /* FINISHME: Handle 'index' once GL_ARB_blend_func_exteneded and
-              * FINISHME: GLSL 1.30 (or later) are supported.
-              */
              if (strcmp("location", $1) == 0) {
                 $$.flags.q.explicit_location = 1;
 
@@ -1497,6 +1534,7 @@ struct_specifier:
           $$ = new(ctx) ast_struct_specifier($2, $4);
           $$->set_location(yylloc);
           state->symbols->add_type($2, glsl_type::void_type);
+           state->symbols->add_type_ast($2, new(ctx) ast_type_specifier($$));
        }
        | STRUCT '{' struct_declaration_list '}'
        {
@@ -1564,6 +1602,28 @@ struct_declarator:
 
 initializer:
        assignment_expression
+       | '{' initializer_list '}'
+       {
+          $$ = $2;
+       }
+       | '{' initializer_list ',' '}'
+       {
+          $$ = $2;
+       }
+       ;
+
+initializer_list:
+       initializer
+       {
+          void *ctx = state;
+          $$ = new(ctx) ast_aggregate_initializer();
+          $$->set_location(yylloc);
+          $$->expressions.push_tail(& $1->link);
+       }
+       | initializer_list ',' initializer
+       {
+          $1->expressions.push_tail(& $3->link);
+       }
        ;
 
 declaration_statement:
@@ -2067,41 +2127,28 @@ member_list:
        }
        ;
 
-/* Specifying "uniform" inside of a uniform block is redundant. */
-uniformopt:
-       /* nothing */
-       | UNIFORM
-       ;
-
 member_declaration:
-       layout_qualifier uniformopt type_specifier struct_declarator_list ';'
+       fully_specified_type struct_declarator_list ';'
        {
           void *ctx = state;
-          ast_fully_specified_type *type = new(ctx) ast_fully_specified_type();
+          ast_fully_specified_type *type = $1;
           type->set_location(yylloc);
 
-          type->qualifier = $1;
-          type->qualifier.flags.q.uniform = true;
-          type->specifier = $3;
-          $$ = new(ctx) ast_declarator_list(type);
-          $$->set_location(yylloc);
-          $$->ubo_qualifiers_valid = true;
-
-          $$->declarations.push_degenerate_list_at_head(& $4->link);
-       }
-       | uniformopt type_specifier struct_declarator_list ';'
-       {
-          void *ctx = state;
-          ast_fully_specified_type *type = new(ctx) ast_fully_specified_type();
-          type->set_location(yylloc);
+          if (type->qualifier.flags.q.attribute) {
+             _mesa_glsl_error(& @1, state,
+                             "keyword 'attribute' cannot be used with "
+                             "interface block member\n");
+          } else if (type->qualifier.flags.q.varying) {
+             _mesa_glsl_error(& @1, state,
+                             "keyword 'varying' cannot be used with "
+                             "interface block member\n");
+          }
 
-          type->qualifier.flags.q.uniform = true;
-          type->specifier = $2;
           $$ = new(ctx) ast_declarator_list(type);
           $$->set_location(yylloc);
           $$->ubo_qualifiers_valid = true;
 
-          $$->declarations.push_degenerate_list_at_head(& $3->link);
+          $$->declarations.push_degenerate_list_at_head(& $2->link);
        }
        ;