summaryrefslogtreecommitdiff
path: root/ast_to_hir.cpp
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2010-03-30 16:59:27 -0700
committerIan Romanick <ian.d.romanick@intel.com>2010-03-30 16:59:47 -0700
commit28009cd75cd3328774bd80a5b87a255ac881a710 (patch)
tree48f4d7c63e905c8a3b64fe54a0e08f888a41dd33 /ast_to_hir.cpp
parent548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5d (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.cpp58
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;
}