summaryrefslogtreecommitdiffstats
path: root/src/glsl/glsl_parser.yy
diff options
context:
space:
mode:
Diffstat (limited to 'src/glsl/glsl_parser.yy')
-rw-r--r--src/glsl/glsl_parser.yy55
1 files changed, 43 insertions, 12 deletions
diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy
index 81ae5d51948..154ce2d098b 100644
--- a/src/glsl/glsl_parser.yy
+++ b/src/glsl/glsl_parser.yy
@@ -79,6 +79,7 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg)
ast_case_label_list *case_label_list;
ast_case_statement *case_statement;
ast_case_statement_list *case_statement_list;
+ ast_uniform_block *uniform_block;
struct {
ast_node *cond;
@@ -112,7 +113,7 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg)
%token STRUCT VOID_TOK WHILE
%token <identifier> IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
%type <identifier> any_identifier
-%type <identifier> instance_name_opt
+%type <uniform_block> instance_name_opt
%token <real> FLOATCONSTANT
%token <n> INTCONSTANT UINTCONSTANT BOOLCONSTANT
%token <identifier> FIELD_SELECTION
@@ -221,7 +222,8 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg)
%type <node> declaration
%type <node> declaration_statement
%type <node> jump_statement
-%type <node> uniform_block basic_uniform_block
+%type <node> uniform_block
+%type <uniform_block> basic_uniform_block
%type <struct_specifier> struct_specifier
%type <declarator_list> struct_declaration_list
%type <declarator_list> struct_declaration
@@ -1891,7 +1893,7 @@ uniform_block:
}
| layout_qualifier basic_uniform_block
{
- ast_uniform_block *block = (ast_uniform_block *) $2;
+ ast_uniform_block *block = $2;
if (!block->layout.merge_qualifier(& @1, state, $1)) {
YYERROR;
}
@@ -1902,9 +1904,10 @@ uniform_block:
basic_uniform_block:
UNIFORM NEW_IDENTIFIER '{' member_list '}' instance_name_opt ';'
{
- void *ctx = state;
- $$ = new(ctx) ast_uniform_block(*state->default_uniform_qualifier,
- $2, $4, $6);
+ ast_uniform_block *const block = $6;
+
+ block->block_name = $2;
+ block->declarations.push_degenerate_list_at_head(& $4->link);
if (!state->ARB_uniform_buffer_object_enable) {
_mesa_glsl_error(& @1, state,
@@ -1915,21 +1918,49 @@ basic_uniform_block:
"#version 140 / GL_ARB_uniform_buffer_object "
"required for defining uniform blocks\n");
}
+
+ /* Since block arrays require names, and both features are added in
+ * the same language versions, we don't have to explicitly
+ * version-check both things.
+ */
+ if (block->instance_name != NULL
+ && !(state->language_version == 300 && state->es_shader)) {
+ _mesa_glsl_error(& @1, state,
+ "#version 300 es required for using uniform "
+ "blocks with an instance name\n");
+ }
+
+ $$ = block;
}
;
instance_name_opt:
/* empty */
{
- $$ = NULL;
+ $$ = new(state) ast_uniform_block(*state->default_uniform_qualifier,
+ NULL,
+ NULL);
}
| NEW_IDENTIFIER
{
- if (!(state->language_version == 300 && state->es_shader)) {
- _mesa_glsl_error(& @1, state,
- "#version 300 es required for using uniform "
- "blocks with an instance name\n");
- }
+ $$ = new(state) ast_uniform_block(*state->default_uniform_qualifier,
+ $1,
+ NULL);
+ }
+ | NEW_IDENTIFIER '[' constant_expression ']'
+ {
+ $$ = new(state) ast_uniform_block(*state->default_uniform_qualifier,
+ $1,
+ $3);
+ }
+ | NEW_IDENTIFIER '[' ']'
+ {
+ _mesa_glsl_error(& @1, state,
+ "instance block arrays must be explicitly sized\n");
+
+ $$ = new(state) ast_uniform_block(*state->default_uniform_qualifier,
+ $1,
+ NULL);
}
;