glsl: Parse interface array size

The size is parsed and stored in the AST, but it is not used yet.
Processing of the array size is added in the patch "glsl: Handle
instance array declarations"

v2: Update the commit message (suggested by Carl Worth).  Add a comment
to ast_uniform_block::array_size (suggested by Paul Berry).

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Chad Versace <chad.versace@linux.intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
Ian Romanick 2012-12-11 12:13:30 -08:00
parent 34f966bdcb
commit a39a70c8d4
2 changed files with 59 additions and 17 deletions

View file

@ -804,12 +804,12 @@ public:
class ast_uniform_block : public ast_node {
public:
ast_uniform_block(ast_type_qualifier layout,
const char *block_name,
ast_declarator_list *member_list,
const char *instance_name)
: layout(layout), block_name(block_name), instance_name(instance_name)
const char *instance_name,
ast_expression *array_size)
: layout(layout), block_name(NULL), instance_name(instance_name),
array_size(array_size)
{
declarations.push_degenerate_list_at_head(&member_list->link);
/* empty */
}
virtual ir_rvalue *hir(exec_list *instructions,
@ -828,6 +828,17 @@ public:
/** List of ast_declarator_list * */
exec_list declarations;
/**
* Declared array size of the block instance
*
* If the block is not declared as an array, this field will be \c NULL.
*
* \note
* A block can only be an array if it also has an instance name. If this
* field is not \c NULL, ::instance_name must also not be \c NULL.
*/
ast_expression *array_size;
};
/*@}*/

View file

@ -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);
}
;