summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2010-04-02 17:44:39 -0700
committerIan Romanick <ian.d.romanick@intel.com>2010-04-02 17:44:39 -0700
commit0157f41e5e644632393edf903f3c1adb1cf782cd (patch)
tree4af2c6e24304e1271e4de7a7d7407e7f76be1f01
parent9d975377ca6dae7805804c0fbe625bb7c5f9e095 (diff)
Propagate sizes when assigning a whole array to an unsized array
-rw-r--r--ast_to_hir.cpp32
1 files changed, 30 insertions, 2 deletions
diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp
index c0266e9b49..f7a9ba883f 100644
--- a/ast_to_hir.cpp
+++ b/ast_to_hir.cpp
@@ -433,13 +433,23 @@ validate_assignment(const glsl_type *lhs_type, ir_rvalue *rhs)
if (rhs_type->is_error())
return rhs;
- /* FINISHME: For GLSL 1.10, check that the types are not arrays. */
-
/* If the types are identical, the assignment can trivially proceed.
*/
if (rhs_type == lhs_type)
return rhs;
+ /* If the array element types are the same and the size of the LHS is zero,
+ * the assignment is okay.
+ *
+ * Note: Whole-array assignments are not permitted in GLSL 1.10, but this
+ * is handled by ir_dereference::is_lvalue.
+ */
+ if (lhs_type->is_array() && rhs->type->is_array()
+ && (lhs_type->element_type() == rhs->type->element_type())
+ && (lhs_type->array_size() == 0)) {
+ return rhs;
+ }
+
/* FINISHME: Check for and apply automatic conversions. */
return NULL;
}
@@ -464,6 +474,24 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
_mesa_glsl_error(& lhs_loc, state, "type mismatch");
} else {
rhs = new_rhs;
+
+ /* If the LHS array was not declared with a size, it takes it size from
+ * the RHS. If the LHS is an l-value and a whole array, it must be a
+ * dereference of a variable. Any other case would require that the LHS
+ * is either not an l-value or not a whole array.
+ */
+ if (lhs->type->array_size() == 0) {
+ ir_dereference *const d = lhs->as_dereference();
+
+ assert(d != NULL);
+
+ ir_variable *const var = d->var->as_variable();
+
+ assert(var != NULL);
+
+ var->type = glsl_type::get_array_instance(lhs->type->element_type(),
+ rhs->type->array_size());
+ }
}
ir_instruction *tmp = new ir_assignment(lhs, rhs, NULL);