glsl: Add ARB_arrays_of_arrays support to yacc definition and ast
Adds array specifier object to hold array information Signed-off-by: Timothy Arceri <t_arceri@yahoo.com.au> Reviewed-by: Paul Berry <stereotype441@gmail.com>
This commit is contained in:
parent
72288e0c7b
commit
bfb48750f0
|
@ -276,6 +276,43 @@ private:
|
|||
bool cons;
|
||||
};
|
||||
|
||||
class ast_array_specifier : public ast_node {
|
||||
public:
|
||||
/** Unsized array specifier ([]) */
|
||||
explicit ast_array_specifier(const struct YYLTYPE &locp)
|
||||
: dimension_count(1), is_unsized_array(true)
|
||||
{
|
||||
set_location(locp);
|
||||
}
|
||||
|
||||
/** Sized array specifier ([dim]) */
|
||||
ast_array_specifier(const struct YYLTYPE &locp, ast_expression *dim)
|
||||
: dimension_count(1), is_unsized_array(false)
|
||||
{
|
||||
set_location(locp);
|
||||
array_dimensions.push_tail(&dim->link);
|
||||
}
|
||||
|
||||
void add_dimension(ast_expression *dim)
|
||||
{
|
||||
array_dimensions.push_tail(&dim->link);
|
||||
dimension_count++;
|
||||
}
|
||||
|
||||
virtual void print(void) const;
|
||||
|
||||
/* Count including sized and unsized dimensions */
|
||||
unsigned dimension_count;
|
||||
|
||||
/* If true, this means that the array has an unsized outermost dimension. */
|
||||
bool is_unsized_array;
|
||||
|
||||
/* This list contains objects of type ast_node containing the
|
||||
* sized dimensions only, in outermost-to-innermost order.
|
||||
*/
|
||||
exec_list array_dimensions;
|
||||
};
|
||||
|
||||
/**
|
||||
* C-style aggregate initialization class
|
||||
*
|
||||
|
@ -334,14 +371,15 @@ public:
|
|||
|
||||
class ast_declaration : public ast_node {
|
||||
public:
|
||||
ast_declaration(const char *identifier, bool is_array, ast_expression *array_size,
|
||||
ast_expression *initializer);
|
||||
ast_declaration(const char *identifier, bool is_array,
|
||||
ast_array_specifier *array_specifier,
|
||||
ast_expression *initializer);
|
||||
virtual void print(void) const;
|
||||
|
||||
const char *identifier;
|
||||
|
||||
bool is_array;
|
||||
ast_expression *array_size;
|
||||
ast_array_specifier *array_specifier;
|
||||
|
||||
ast_expression *initializer;
|
||||
};
|
||||
|
@ -551,9 +589,9 @@ public:
|
|||
* be modified. Zeros the inherited ast_node's fields.
|
||||
*/
|
||||
ast_type_specifier(const ast_type_specifier *that, bool is_array,
|
||||
ast_expression *array_size)
|
||||
ast_array_specifier *array_specifier)
|
||||
: ast_node(), type_name(that->type_name), structure(that->structure),
|
||||
is_array(is_array), array_size(array_size),
|
||||
is_array(is_array), array_specifier(array_specifier),
|
||||
default_precision(that->default_precision)
|
||||
{
|
||||
/* empty */
|
||||
|
@ -562,7 +600,7 @@ public:
|
|||
/** Construct a type specifier from a type name */
|
||||
ast_type_specifier(const char *name)
|
||||
: type_name(name), structure(NULL),
|
||||
is_array(false), array_size(NULL),
|
||||
is_array(false), array_specifier(NULL),
|
||||
default_precision(ast_precision_none)
|
||||
{
|
||||
/* empty */
|
||||
|
@ -571,7 +609,7 @@ public:
|
|||
/** Construct a type specifier from a structure definition */
|
||||
ast_type_specifier(ast_struct_specifier *s)
|
||||
: type_name(s->name), structure(s),
|
||||
is_array(false), array_size(NULL),
|
||||
is_array(false), array_specifier(NULL),
|
||||
default_precision(ast_precision_none)
|
||||
{
|
||||
/* empty */
|
||||
|
@ -589,7 +627,7 @@ public:
|
|||
ast_struct_specifier *structure;
|
||||
|
||||
bool is_array;
|
||||
ast_expression *array_size;
|
||||
ast_array_specifier *array_specifier;
|
||||
|
||||
/** For precision statements, this is the given precision; otherwise none. */
|
||||
unsigned default_precision:2;
|
||||
|
@ -643,7 +681,7 @@ public:
|
|||
type(NULL),
|
||||
identifier(NULL),
|
||||
is_array(false),
|
||||
array_size(NULL),
|
||||
array_specifier(NULL),
|
||||
formal_parameter(false),
|
||||
is_void(false)
|
||||
{
|
||||
|
@ -658,7 +696,7 @@ public:
|
|||
ast_fully_specified_type *type;
|
||||
const char *identifier;
|
||||
bool is_array;
|
||||
ast_expression *array_size;
|
||||
ast_array_specifier *array_specifier;
|
||||
|
||||
static void parameters_to_hir(exec_list *ast_parameters,
|
||||
bool formal, exec_list *ir_parameters,
|
||||
|
@ -906,12 +944,12 @@ public:
|
|||
ast_interface_block(ast_type_qualifier layout,
|
||||
const char *instance_name,
|
||||
bool is_array,
|
||||
ast_expression *array_size)
|
||||
ast_array_specifier *array_specifier)
|
||||
: layout(layout), block_name(NULL), instance_name(instance_name),
|
||||
is_array(is_array), array_size(array_size)
|
||||
is_array(is_array), array_specifier(array_specifier)
|
||||
{
|
||||
if (!is_array)
|
||||
assert(array_size == NULL);
|
||||
assert(array_specifier == NULL);
|
||||
}
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
|
@ -946,7 +984,7 @@ public:
|
|||
* If the block is not declared as an array or if the block instance array
|
||||
* is unsized, this field will be \c NULL.
|
||||
*/
|
||||
ast_expression *array_size;
|
||||
ast_array_specifier *array_specifier;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -25,6 +25,19 @@
|
|||
#include "glsl_types.h"
|
||||
#include "ir.h"
|
||||
|
||||
void
|
||||
ast_array_specifier::print(void) const
|
||||
{
|
||||
if (this->is_unsized_array) {
|
||||
printf("[ ] ");
|
||||
}
|
||||
|
||||
foreach_list_typed (ast_node, array_dimension, link, &this->array_dimensions) {
|
||||
printf("[ ");
|
||||
array_dimension->print();
|
||||
printf("] ");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If \c ir is a reference to an array for which we are tracking the max array
|
||||
|
|
|
@ -1771,64 +1771,108 @@ ast_compound_statement::hir(exec_list *instructions,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the given exec_node (which should be an ast_node representing
|
||||
* a single array dimension) and return its integer value.
|
||||
*/
|
||||
static const unsigned
|
||||
process_array_size(exec_node *node,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
exec_list dummy_instructions;
|
||||
|
||||
ast_node *array_size = exec_node_data(ast_node, node, link);
|
||||
ir_rvalue *const ir = array_size->hir(& dummy_instructions,
|
||||
state);
|
||||
YYLTYPE loc = array_size->get_location();
|
||||
|
||||
if (ir == NULL) {
|
||||
_mesa_glsl_error(& loc, state,
|
||||
"array size could not be resolved");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ir->type->is_integer()) {
|
||||
_mesa_glsl_error(& loc, state,
|
||||
"array size must be integer type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ir->type->is_scalar()) {
|
||||
_mesa_glsl_error(& loc, state,
|
||||
"array size must be scalar type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ir_constant *const size = ir->constant_expression_value();
|
||||
if (size == NULL) {
|
||||
_mesa_glsl_error(& loc, state, "array size must be a "
|
||||
"constant valued expression");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (size->value.i[0] <= 0) {
|
||||
_mesa_glsl_error(& loc, state, "array size must be > 0");
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(size->type == ir->type);
|
||||
|
||||
/* If the array size is const (and we've verified that
|
||||
* it is) then no instructions should have been emitted
|
||||
* when we converted it to HIR. If they were emitted,
|
||||
* then either the array size isn't const after all, or
|
||||
* we are emitting unnecessary instructions.
|
||||
*/
|
||||
assert(dummy_instructions.is_empty());
|
||||
|
||||
return size->value.u[0];
|
||||
}
|
||||
|
||||
static const glsl_type *
|
||||
process_array_type(YYLTYPE *loc, const glsl_type *base, ast_node *array_size,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
process_array_type(YYLTYPE *loc, const glsl_type *base,
|
||||
ast_array_specifier *array_specifier,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
unsigned length = 0;
|
||||
const glsl_type *array_type = base;
|
||||
|
||||
if (base == NULL)
|
||||
return glsl_type::error_type;
|
||||
if (array_specifier != NULL) {
|
||||
if (base->is_array()) {
|
||||
|
||||
/* From page 19 (page 25) of the GLSL 1.20 spec:
|
||||
*
|
||||
* "Only one-dimensional arrays may be declared."
|
||||
*/
|
||||
if (base->is_array()) {
|
||||
_mesa_glsl_error(loc, state,
|
||||
"invalid array of `%s' (only one-dimensional arrays "
|
||||
"may be declared)",
|
||||
base->name);
|
||||
return glsl_type::error_type;
|
||||
}
|
||||
/* From page 19 (page 25) of the GLSL 1.20 spec:
|
||||
*
|
||||
* "Only one-dimensional arrays may be declared."
|
||||
*/
|
||||
if (!state->ARB_arrays_of_arrays_enable) {
|
||||
_mesa_glsl_error(loc, state,
|
||||
"invalid array of `%s'"
|
||||
"GL_ARB_arrays_of_arrays "
|
||||
"required for defining arrays of arrays",
|
||||
base->name);
|
||||
return glsl_type::error_type;
|
||||
}
|
||||
|
||||
if (array_size != NULL) {
|
||||
exec_list dummy_instructions;
|
||||
ir_rvalue *const ir = array_size->hir(& dummy_instructions, state);
|
||||
YYLTYPE loc = array_size->get_location();
|
||||
|
||||
if (ir != NULL) {
|
||||
if (!ir->type->is_integer()) {
|
||||
_mesa_glsl_error(& loc, state, "array size must be integer type");
|
||||
} else if (!ir->type->is_scalar()) {
|
||||
_mesa_glsl_error(& loc, state, "array size must be scalar type");
|
||||
} else {
|
||||
ir_constant *const size = ir->constant_expression_value();
|
||||
|
||||
if (size == NULL) {
|
||||
_mesa_glsl_error(& loc, state, "array size must be a "
|
||||
"constant valued expression");
|
||||
} else if (size->value.i[0] <= 0) {
|
||||
_mesa_glsl_error(& loc, state, "array size must be > 0");
|
||||
} else {
|
||||
assert(size->type == ir->type);
|
||||
length = size->value.u[0];
|
||||
|
||||
/* If the array size is const (and we've verified that
|
||||
* it is) then no instructions should have been emitted
|
||||
* when we converted it to HIR. If they were emitted,
|
||||
* then either the array size isn't const after all, or
|
||||
* we are emitting unnecessary instructions.
|
||||
*/
|
||||
assert(dummy_instructions.is_empty());
|
||||
}
|
||||
}
|
||||
if (base->length == 0) {
|
||||
_mesa_glsl_error(loc, state,
|
||||
"only the outermost array dimension can "
|
||||
"be unsized",
|
||||
base->name);
|
||||
return glsl_type::error_type;
|
||||
}
|
||||
}
|
||||
|
||||
for (exec_node *node = array_specifier->array_dimensions.tail_pred;
|
||||
!node->is_head_sentinel(); node = node->prev) {
|
||||
unsigned array_size = process_array_size(node, state);
|
||||
array_type = glsl_type::get_array_instance(array_type,
|
||||
array_size);
|
||||
}
|
||||
|
||||
if (array_specifier->is_unsized_array)
|
||||
array_type = glsl_type::get_array_instance(array_type, 0);
|
||||
}
|
||||
|
||||
const glsl_type *array_type = glsl_type::get_array_instance(base, length);
|
||||
return array_type != NULL ? array_type : glsl_type::error_type;
|
||||
return array_type;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1841,10 +1885,8 @@ ast_type_specifier::glsl_type(const char **name,
|
|||
type = state->symbols->get_type(this->type_name);
|
||||
*name = this->type_name;
|
||||
|
||||
if (this->is_array) {
|
||||
YYLTYPE loc = this->get_location();
|
||||
type = process_array_type(&loc, type, this->array_size, state);
|
||||
}
|
||||
YYLTYPE loc = this->get_location();
|
||||
type = process_array_type(&loc, type, this->array_specifier, state);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
@ -2831,7 +2873,7 @@ ast_declarator_list::hir(exec_list *instructions,
|
|||
|
||||
foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
|
||||
assert(!decl->is_array);
|
||||
assert(decl->array_size == NULL);
|
||||
assert(decl->array_specifier == NULL);
|
||||
assert(decl->initializer == NULL);
|
||||
|
||||
ir_variable *const earlier =
|
||||
|
@ -2966,14 +3008,8 @@ ast_declarator_list::hir(exec_list *instructions,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (decl->is_array) {
|
||||
var_type = process_array_type(&loc, decl_type, decl->array_size,
|
||||
state);
|
||||
if (var_type->is_error())
|
||||
continue;
|
||||
} else {
|
||||
var_type = decl_type;
|
||||
}
|
||||
var_type = process_array_type(&loc, decl_type, decl->array_specifier,
|
||||
state);
|
||||
|
||||
var = new(ctx) ir_variable(var_type, decl->identifier, ir_var_auto);
|
||||
|
||||
|
@ -3530,9 +3566,7 @@ ast_parameter_declarator::hir(exec_list *instructions,
|
|||
/* This only handles "vec4 foo[..]". The earlier specifier->glsl_type(...)
|
||||
* call already handled the "vec4[..] foo" case.
|
||||
*/
|
||||
if (this->is_array) {
|
||||
type = process_array_type(&loc, type, this->array_size, state);
|
||||
}
|
||||
type = process_array_type(&loc, type, this->array_specifier, state);
|
||||
|
||||
if (!type->is_error() && type->is_unsized_array()) {
|
||||
_mesa_glsl_error(&loc, state, "arrays passed as parameters must have "
|
||||
|
@ -4660,10 +4694,8 @@ ast_process_structure_or_interface_block(exec_list *instructions,
|
|||
"members");
|
||||
}
|
||||
|
||||
if (decl->is_array) {
|
||||
field_type = process_array_type(&loc, decl_type, decl->array_size,
|
||||
state);
|
||||
}
|
||||
field_type = process_array_type(&loc, decl_type,
|
||||
decl->array_specifier, state);
|
||||
fields[i].type = field_type;
|
||||
fields[i].name = decl->identifier;
|
||||
fields[i].location = -1;
|
||||
|
@ -5045,7 +5077,7 @@ ast_interface_block::hir(exec_list *instructions,
|
|||
* interface array size *doesn't* need to be specified is on a
|
||||
* geometry shader input.
|
||||
*/
|
||||
if (this->array_size == NULL &&
|
||||
if (this->array_specifier->is_unsized_array &&
|
||||
(state->stage != MESA_SHADER_GEOMETRY || !this->layout.flags.q.in)) {
|
||||
_mesa_glsl_error(&loc, state,
|
||||
"only geometry shader inputs may be unsized "
|
||||
|
@ -5054,7 +5086,7 @@ ast_interface_block::hir(exec_list *instructions,
|
|||
}
|
||||
|
||||
const glsl_type *block_array_type =
|
||||
process_array_type(&loc, block_type, this->array_size, state);
|
||||
process_array_type(&loc, block_type, this->array_specifier, state);
|
||||
|
||||
var = new(state) ir_variable(block_array_type,
|
||||
this->instance_name,
|
||||
|
|
|
@ -33,13 +33,9 @@ ast_type_specifier::print(void) const
|
|||
}
|
||||
|
||||
if (is_array) {
|
||||
printf("[ ");
|
||||
|
||||
if (array_size) {
|
||||
array_size->print();
|
||||
if (array_specifier) {
|
||||
array_specifier->print();
|
||||
}
|
||||
|
||||
printf("] ");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2,
|
|||
|
||||
ast_node *node;
|
||||
ast_type_specifier *type_specifier;
|
||||
ast_array_specifier *array_specifier;
|
||||
ast_fully_specified_type *fully_specified_type;
|
||||
ast_function *function;
|
||||
ast_parameter_declarator *parameter_declarator;
|
||||
|
@ -202,6 +203,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2,
|
|||
%type <type_qualifier> interface_qualifier
|
||||
%type <type_specifier> type_specifier
|
||||
%type <type_specifier> type_specifier_nonarray
|
||||
%type <array_specifier> array_specifier
|
||||
%type <identifier> basic_type_specifier_nonarray
|
||||
%type <fully_specified_type> fully_specified_type
|
||||
%type <function> function_prototype
|
||||
|
@ -880,7 +882,7 @@ parameter_declarator:
|
|||
$$->type->specifier = $1;
|
||||
$$->identifier = $2;
|
||||
}
|
||||
| type_specifier any_identifier '[' constant_expression ']'
|
||||
| type_specifier any_identifier array_specifier
|
||||
{
|
||||
void *ctx = state;
|
||||
$$ = new(ctx) ast_parameter_declarator();
|
||||
|
@ -889,8 +891,7 @@ parameter_declarator:
|
|||
$$->type->set_location(yylloc);
|
||||
$$->type->specifier = $1;
|
||||
$$->identifier = $2;
|
||||
$$->is_array = true;
|
||||
$$->array_size = $4;
|
||||
$$->array_specifier = $3;
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -983,40 +984,20 @@ init_declarator_list:
|
|||
$$->declarations.push_tail(&decl->link);
|
||||
state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
|
||||
}
|
||||
| init_declarator_list ',' any_identifier '[' ']'
|
||||
| init_declarator_list ',' any_identifier array_specifier
|
||||
{
|
||||
void *ctx = state;
|
||||
ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, NULL);
|
||||
ast_declaration *decl = new(ctx) ast_declaration($3, true, $4, NULL);
|
||||
decl->set_location(yylloc);
|
||||
|
||||
$$ = $1;
|
||||
$$->declarations.push_tail(&decl->link);
|
||||
state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
|
||||
}
|
||||
| init_declarator_list ',' any_identifier '[' constant_expression ']'
|
||||
| init_declarator_list ',' any_identifier array_specifier '=' initializer
|
||||
{
|
||||
void *ctx = state;
|
||||
ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, NULL);
|
||||
decl->set_location(yylloc);
|
||||
|
||||
$$ = $1;
|
||||
$$->declarations.push_tail(&decl->link);
|
||||
state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
|
||||
}
|
||||
| init_declarator_list ',' any_identifier '[' ']' '=' initializer
|
||||
{
|
||||
void *ctx = state;
|
||||
ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, $7);
|
||||
decl->set_location(yylloc);
|
||||
|
||||
$$ = $1;
|
||||
$$->declarations.push_tail(&decl->link);
|
||||
state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
|
||||
}
|
||||
| init_declarator_list ',' any_identifier '[' constant_expression ']' '=' initializer
|
||||
{
|
||||
void *ctx = state;
|
||||
ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, $8);
|
||||
ast_declaration *decl = new(ctx) ast_declaration($3, true, $4, $6);
|
||||
decl->set_location(yylloc);
|
||||
|
||||
$$ = $1;
|
||||
|
@ -1053,37 +1034,19 @@ single_declaration:
|
|||
$$->set_location(yylloc);
|
||||
$$->declarations.push_tail(&decl->link);
|
||||
}
|
||||
| fully_specified_type any_identifier '[' ']'
|
||||
| fully_specified_type any_identifier array_specifier
|
||||
{
|
||||
void *ctx = state;
|
||||
ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, NULL);
|
||||
ast_declaration *decl = new(ctx) ast_declaration($2, true, $3, NULL);
|
||||
|
||||
$$ = new(ctx) ast_declarator_list($1);
|
||||
$$->set_location(yylloc);
|
||||
$$->declarations.push_tail(&decl->link);
|
||||
}
|
||||
| fully_specified_type any_identifier '[' constant_expression ']'
|
||||
| fully_specified_type any_identifier array_specifier '=' initializer
|
||||
{
|
||||
void *ctx = state;
|
||||
ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, NULL);
|
||||
|
||||
$$ = new(ctx) ast_declarator_list($1);
|
||||
$$->set_location(yylloc);
|
||||
$$->declarations.push_tail(&decl->link);
|
||||
}
|
||||
| fully_specified_type any_identifier '[' ']' '=' initializer
|
||||
{
|
||||
void *ctx = state;
|
||||
ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, $6);
|
||||
|
||||
$$ = new(ctx) ast_declarator_list($1);
|
||||
$$->set_location(yylloc);
|
||||
$$->declarations.push_tail(&decl->link);
|
||||
}
|
||||
| fully_specified_type any_identifier '[' constant_expression ']' '=' initializer
|
||||
{
|
||||
void *ctx = state;
|
||||
ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, $7);
|
||||
ast_declaration *decl = new(ctx) ast_declaration($2, true, $3, $5);
|
||||
|
||||
$$ = new(ctx) ast_declarator_list($1);
|
||||
$$->set_location(yylloc);
|
||||
|
@ -1584,19 +1547,51 @@ storage_qualifier:
|
|||
}
|
||||
;
|
||||
|
||||
array_specifier:
|
||||
'[' ']'
|
||||
{
|
||||
void *ctx = state;
|
||||
$$ = new(ctx) ast_array_specifier(yylloc);
|
||||
}
|
||||
| '[' constant_expression ']'
|
||||
{
|
||||
void *ctx = state;
|
||||
$$ = new(ctx) ast_array_specifier(yylloc, $2);
|
||||
}
|
||||
| array_specifier '[' ']'
|
||||
{
|
||||
$$ = $1;
|
||||
|
||||
if (!state->ARB_arrays_of_arrays_enable) {
|
||||
_mesa_glsl_error(& @1, state,
|
||||
"GL_ARB_arrays_of_arrays "
|
||||
"required for defining arrays of arrays");
|
||||
} else {
|
||||
_mesa_glsl_error(& @1, state,
|
||||
"only the outermost array dimension can "
|
||||
"be unsized");
|
||||
}
|
||||
}
|
||||
| array_specifier '[' constant_expression ']'
|
||||
{
|
||||
$$ = $1;
|
||||
|
||||
if (!state->ARB_arrays_of_arrays_enable) {
|
||||
_mesa_glsl_error(& @1, state,
|
||||
"GL_ARB_arrays_of_arrays "
|
||||
"required for defining arrays of arrays");
|
||||
}
|
||||
|
||||
$$->add_dimension($3);
|
||||
}
|
||||
;
|
||||
|
||||
type_specifier:
|
||||
type_specifier_nonarray
|
||||
| type_specifier_nonarray '[' ']'
|
||||
| type_specifier_nonarray array_specifier
|
||||
{
|
||||
$$ = $1;
|
||||
$$->is_array = true;
|
||||
$$->array_size = NULL;
|
||||
}
|
||||
| type_specifier_nonarray '[' constant_expression ']'
|
||||
{
|
||||
$$ = $1;
|
||||
$$->is_array = true;
|
||||
$$->array_size = $3;
|
||||
$$->array_specifier = $2;
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -1779,16 +1774,10 @@ struct_declarator:
|
|||
$$ = new(ctx) ast_declaration($1, false, NULL, NULL);
|
||||
$$->set_location(yylloc);
|
||||
}
|
||||
| any_identifier '[' ']'
|
||||
| any_identifier array_specifier
|
||||
{
|
||||
void *ctx = state;
|
||||
$$ = new(ctx) ast_declaration($1, true, NULL, NULL);
|
||||
$$->set_location(yylloc);
|
||||
}
|
||||
| any_identifier '[' constant_expression ']'
|
||||
{
|
||||
void *ctx = state;
|
||||
$$ = new(ctx) ast_declaration($1, true, $3, NULL);
|
||||
$$ = new(ctx) ast_declaration($1, true, $2, NULL);
|
||||
$$->set_location(yylloc);
|
||||
}
|
||||
;
|
||||
|
@ -2288,15 +2277,10 @@ instance_name_opt:
|
|||
$$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
|
||||
$1, false, NULL);
|
||||
}
|
||||
| NEW_IDENTIFIER '[' constant_expression ']'
|
||||
| NEW_IDENTIFIER array_specifier
|
||||
{
|
||||
$$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
|
||||
$1, true, $3);
|
||||
}
|
||||
| NEW_IDENTIFIER '[' ']'
|
||||
{
|
||||
$$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
|
||||
$1, true, NULL);
|
||||
$1, true, $2);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -484,6 +484,7 @@ struct _mesa_glsl_extension {
|
|||
static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
|
||||
/* API availability */
|
||||
/* name GL ES supported flag */
|
||||
EXT(ARB_arrays_of_arrays, true, false, ARB_arrays_of_arrays),
|
||||
EXT(ARB_conservative_depth, true, false, ARB_conservative_depth),
|
||||
EXT(ARB_draw_buffers, true, false, dummy_true),
|
||||
EXT(ARB_draw_instanced, true, false, ARB_draw_instanced),
|
||||
|
@ -789,15 +790,11 @@ ast_node::ast_node(void)
|
|||
|
||||
|
||||
static void
|
||||
ast_opt_array_size_print(bool is_array, const ast_expression *array_size)
|
||||
ast_opt_array_dimensions_print(bool is_array, const ast_array_specifier *array_specifier)
|
||||
{
|
||||
if (is_array) {
|
||||
printf("[ ");
|
||||
|
||||
if (array_size)
|
||||
array_size->print();
|
||||
|
||||
printf("] ");
|
||||
if (array_specifier)
|
||||
array_specifier->print();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1021,7 +1018,7 @@ ast_parameter_declarator::print(void) const
|
|||
type->print();
|
||||
if (identifier)
|
||||
printf("%s ", identifier);
|
||||
ast_opt_array_size_print(is_array, array_size);
|
||||
ast_opt_array_dimensions_print(is_array, array_specifier);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1037,7 +1034,7 @@ void
|
|||
ast_declaration::print(void) const
|
||||
{
|
||||
printf("%s ", identifier);
|
||||
ast_opt_array_size_print(is_array, array_size);
|
||||
ast_opt_array_dimensions_print(is_array, array_specifier);
|
||||
|
||||
if (initializer) {
|
||||
printf("= ");
|
||||
|
@ -1047,12 +1044,12 @@ ast_declaration::print(void) const
|
|||
|
||||
|
||||
ast_declaration::ast_declaration(const char *identifier, bool is_array,
|
||||
ast_expression *array_size,
|
||||
ast_array_specifier *array_specifier,
|
||||
ast_expression *initializer)
|
||||
{
|
||||
this->identifier = identifier;
|
||||
this->is_array = is_array;
|
||||
this->array_size = array_size;
|
||||
this->array_specifier = array_specifier;
|
||||
this->initializer = initializer;
|
||||
}
|
||||
|
||||
|
|
|
@ -294,6 +294,8 @@ struct _mesa_glsl_parse_state {
|
|||
* \name Enable bits for GLSL extensions
|
||||
*/
|
||||
/*@{*/
|
||||
bool ARB_arrays_of_arrays_enable;
|
||||
bool ARB_arrays_of_arrays_warn;
|
||||
bool ARB_draw_buffers_enable;
|
||||
bool ARB_draw_buffers_warn;
|
||||
bool ARB_draw_instanced_enable;
|
||||
|
|
Loading…
Reference in New Issue