diff options
author | Ian Romanick <ian.d.romanick@intel.com> | 2010-03-30 16:59:27 -0700 |
---|---|---|
committer | Ian Romanick <ian.d.romanick@intel.com> | 2010-03-30 16:59:47 -0700 |
commit | 28009cd75cd3328774bd80a5b87a255ac881a710 (patch) | |
tree | 48f4d7c63e905c8a3b64fe54a0e08f888a41dd33 /ast_to_hir.cpp | |
parent | 548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5d (diff) |
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
Diffstat (limited to 'ast_to_hir.cpp')
-rw-r--r-- | ast_to_hir.cpp | 58 |
1 files changed, 48 insertions, 10 deletions
diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp index a5fa5e112f..23021bf04c 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; } |