From 28009cd75cd3328774bd80a5b87a255ac881a710 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 30 Mar 2010 16:59:27 -0700 Subject: [PATCH] Begin handling array declarations This causes the following tests to pass: glslparsertest/shaders/array4.frag glslparsertest/shaders/array5.frag This causes the following tests to fail. These shaders were previously failing to compile, but they were all failing for the wrong reasons. glslparsertest/shaders/array3.frag --- ast_to_hir.cpp | 58 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp index a5fa5e112f6..23021bf04cf 100644 --- a/ast_to_hir.cpp +++ b/ast_to_hir.cpp @@ -994,12 +994,55 @@ ast_compound_statement::hir(exec_list *instructions, } +static const glsl_type * +process_array_type(const glsl_type *base, ast_node *array_size, + struct _mesa_glsl_parse_state *state) +{ + unsigned length = 0; + + /* FINISHME: Reject delcarations of multidimensional arrays. */ + + if (array_size != NULL) { + exec_list dummy_instructions; + ir_rvalue *const ir = array_size->hir(& dummy_instructions, state); + YYLTYPE loc = array_size->get_location(); + + /* FINISHME: Verify that the grammar forbids side-effects in array + * FINISHME: sizes. i.e., 'vec4 [x = 12] data' + */ + assert(dummy_instructions.is_empty()); + + 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]; + } + } + } + } + + return glsl_type::get_array_instance(base, length); +} + + static const struct glsl_type * type_specifier_to_glsl_type(const struct ast_type_specifier *spec, const char **name, struct _mesa_glsl_parse_state *state) { - struct glsl_type *type; + const glsl_type *type; if (spec->type_specifier == ast_struct) { /* FINISHME: Handle annonymous structures. */ @@ -1008,9 +1051,9 @@ type_specifier_to_glsl_type(const struct ast_type_specifier *spec, type = state->symbols->get_type(spec->type_name); *name = spec->type_name; - /* FINISHME: Handle array declarations. Note that this requires complete - * FINISHME: handling of constant expressions. - */ + if (spec->is_array) { + type = process_array_type(type, spec->array_size, state); + } } return type; @@ -1103,12 +1146,7 @@ ast_declarator_list::hir(exec_list *instructions, } if (decl->is_array) { - /* FINISHME: Handle array declarations. Note that this requires - * FINISHME: complete handling of constant expressions. - */ - var_type = glsl_type::error_type; - - /* FINISHME: Reject delcarations of multidimensional arrays. */ + var_type = process_array_type(decl_type, decl->array_size, state); } else { var_type = decl_type; } -- 2.30.2