glsl: Add check for unsized arrays to glsl types
authorTimothy Arceri <t_arceri@yahoo.com.au>
Wed, 23 Oct 2013 10:31:27 +0000 (21:31 +1100)
committerPaul Berry <stereotype441@gmail.com>
Mon, 28 Oct 2013 13:06:04 +0000 (06:06 -0700)
The main purpose of this patch is to increase readability of
the array code by introducing is_unsized_array() to glsl_types.
Some redundent is_array() checks are also removed, and small number
of other related clean ups.

The introduction of is_unsized_array() should also make the
ARB_arrays_of_arrays code simpler and more readable when it arrives.

V2: Also replace code that checks for unsized arrays directly with the
length variable

Signed-off-by: Timothy Arceri <t_arceri@yahoo.com.au>
v3 (Paul Berry <stereotype441@gmail.com>): clean up formatting.
Separate whitespace cleanups to their own patch.

Reviewed-by: Paul Berry <stereotype441@gmail.com>
src/glsl/ast_array_index.cpp
src/glsl/ast_function.cpp
src/glsl/ast_to_hir.cpp
src/glsl/glsl_types.h
src/glsl/hir_field_selection.cpp
src/glsl/linker.cpp
src/glsl/opt_array_splitting.cpp

index 107c29e2e983993c7e6505a15c724a269cd17595..f7b5e8350a4a95dac6dfa5c6b1dbb76a5f6f06b9 100644 (file)
@@ -165,7 +165,7 @@ _mesa_ast_array_index_to_hir(void *mem_ctx,
       if (array->type->is_array())
          update_max_array_access(array, idx, &loc, state);
    } else if (const_index == NULL && array->type->is_array()) {
-      if (array->type->array_size() == 0) {
+      if (array->type->is_unsized_array()) {
         _mesa_glsl_error(&loc, state, "unsized array index must be constant");
       } else if (array->type->fields.array->is_interface()
                  && array->variable_referenced()->mode == ir_var_uniform) {
index 02aad4f8f85810587c5db062d4cc876b315792b3..2707522ef54ae0d74bd0597528799d05fa52287f 100644 (file)
@@ -732,21 +732,21 @@ process_array_constructor(exec_list *instructions,
    exec_list actual_parameters;
    const unsigned parameter_count =
       process_parameters(instructions, &actual_parameters, parameters, state);
+   bool is_unsized_array = constructor_type->is_unsized_array();
 
-   if ((parameter_count == 0)
-       || ((constructor_type->length != 0)
-          && (constructor_type->length != parameter_count))) {
-      const unsigned min_param = (constructor_type->length == 0)
-        ? 1 : constructor_type->length;
+   if ((parameter_count == 0) ||
+       (!is_unsized_array && (constructor_type->length != parameter_count))) {
+      const unsigned min_param = is_unsized_array
+         ? 1 : constructor_type->length;
 
       _mesa_glsl_error(loc, state, "array constructor must have %s %u "
                       "parameter%s",
-                      (constructor_type->length == 0) ? "at least" : "exactly",
+                      is_unsized_array ? "at least" : "exactly",
                       min_param, (min_param <= 1) ? "" : "s");
       return ir_rvalue::error_value(ctx);
    }
 
-   if (constructor_type->length == 0) {
+   if (is_unsized_array) {
       constructor_type =
         glsl_type::get_array_instance(constructor_type->element_type(),
                                       parameter_count);
index 561d942cc25ed548479c682eee0c9faaacadacc7..3cc44a07089e1db6342ad2a803e3798394b0396b 100644 (file)
@@ -689,16 +689,15 @@ validate_assignment(struct _mesa_glsl_parse_state *state,
    if (rhs->type == lhs_type)
       return rhs;
 
-   /* If the array element types are the same and the size of the LHS is zero,
+   /* If the array element types are the same and the LHS is unsized,
     * the assignment is okay for initializers embedded in variable
     * declarations.
     *
     * Note: Whole-array assignments are not permitted in GLSL 1.10, but this
     * is handled by ir_dereference::is_lvalue.
     */
-   if (is_initializer && lhs_type->is_array() && rhs->type->is_array()
-       && (lhs_type->element_type() == rhs->type->element_type())
-       && (lhs_type->array_size() == 0)) {
+   if (is_initializer && lhs_type->is_unsized_array() && rhs->type->is_array()
+       && (lhs_type->element_type() == rhs->type->element_type())) {
       return rhs;
    }
 
@@ -805,7 +804,7 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
        * 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) {
+      if (lhs->type->is_unsized_array()) {
         ir_dereference *const d = lhs->as_dereference();
 
         assert(d != NULL);
@@ -2407,8 +2406,7 @@ get_variable_being_redeclared(ir_variable *var, YYLTYPE loc,
     *  later re-declare the same name as an array of the same
     *  type and specify a size."
     */
-   if ((earlier->type->array_size() == 0)
-       && var->type->is_array()
+   if (earlier->type->is_unsized_array() && var->type->is_array()
        && (var->type->element_type() == earlier->type->element_type())) {
       /* FINISHME: This doesn't match the qualifiers on the two
        * FINISHME: declarations.  It's not 100% clear whether this is
@@ -2660,7 +2658,7 @@ handle_geometry_shader_input_decl(struct _mesa_glsl_parse_state *state,
       return;
    }
 
-   if (var->type->length == 0) {
+   if (var->type->is_unsized_array()) {
       /* Section 4.3.8.1 (Input Layout Qualifiers) of the GLSL 1.50 spec says:
        *
        *   All geometry shader input unsized array declarations will be
@@ -3309,7 +3307,7 @@ ast_declarator_list::hir(exec_list *instructions,
         const glsl_type *const t = (earlier == NULL)
            ? var->type : earlier->type;
 
-         if (t->is_array() && t->length == 0)
+         if (t->is_unsized_array())
             /* Section 10.17 of the GLSL ES 1.00 specification states that
              * unsized array declarations have been removed from the language.
              * Arrays that are sized using an initializer are still explicitly
@@ -3442,7 +3440,7 @@ ast_parameter_declarator::hir(exec_list *instructions,
       type = process_array_type(&loc, type, this->array_size, state);
    }
 
-   if (!type->is_error() && type->array_size() == 0) {
+   if (!type->is_error() && type->is_unsized_array()) {
       _mesa_glsl_error(&loc, state, "arrays passed as parameters must have "
                       "a declared size");
       type = glsl_type::error_type;
@@ -3614,7 +3612,7 @@ ast_function::hir(exec_list *instructions,
     *     "Arrays are allowed as arguments and as the return type. In both
     *     cases, the array must be explicitly sized."
     */
-   if (return_type->is_array() && return_type->length == 0) {
+   if (return_type->is_unsized_array()) {
       YYLTYPE loc = this->get_location();
       _mesa_glsl_error(& loc, state,
                       "function `%s' return type array must be explicitly "
@@ -5100,10 +5098,8 @@ ast_gs_input_layout::hir(exec_list *instructions,
       /* Note: gl_PrimitiveIDIn has mode ir_var_shader_in, but it's not an
        * array; skip it.
        */
-      if (!var->type->is_array())
-         continue;
 
-      if (var->type->length == 0) {
+      if (var->type->is_unsized_array()) {
          if (var->max_array_access >= num_vertices) {
             _mesa_glsl_error(&loc, state,
                              "this geometry shader input layout implies %u"
index a0dbde1e23bfc6e760368428fecde02f5964e785..b1050078d1733c0997b84cfb62936302bf3f1b17 100644 (file)
@@ -495,6 +495,14 @@ struct glsl_type {
       return is_array() ? length : -1;
    }
 
+   /**
+    * Query whether the array size for all dimensions has been declared.
+    */
+   bool is_unsized_array() const
+   {
+      return is_array() && length == 0;
+   }
+
    /**
     * Return the number of coordinate components needed for this sampler type.
     *
index 08be7436532a2b6abb72ee045ffb27a852b3f7f2..1e92c89aef4c8076aeb97328bc30925c7375d2ac 100644 (file)
@@ -72,7 +72,7 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
             _mesa_glsl_error(&loc, state, "length method takes no arguments");
 
          if (op->type->is_array()) {
-            if (op->type->array_size() == 0)
+            if (op->type->is_unsized_array())
                _mesa_glsl_error(&loc, state, "length called on unsized array");
 
             result = new(ctx) ir_constant(op->type->array_size());
index d8f655c39397b4cbe905afc111ed734e7a5c381c..495a2abe2802cc0b0275da232cca89b98e9dfa17 100644 (file)
@@ -1108,7 +1108,7 @@ private:
     */
    static void fixup_type(const glsl_type **type, unsigned max_array_access)
    {
-      if ((*type)->is_array() && (*type)->length == 0) {
+      if ((*type)->is_unsized_array()) {
          *type = glsl_type::get_array_instance((*type)->fields.array,
                                                max_array_access + 1);
          assert(*type != NULL);
@@ -1123,7 +1123,7 @@ private:
    {
       for (unsigned i = 0; i < type->length; i++) {
          const glsl_type *elem_type = type->fields.structure[i].type;
-         if (elem_type->is_array() && elem_type->length == 0)
+         if (elem_type->is_unsized_array())
             return true;
       }
       return false;
index 34ac836ae5cfc78b1d44e855a4d9df7e61659c95..c7c5f6712659c554d4ee8bd250dfc340c1c7a7e1 100644 (file)
@@ -132,7 +132,7 @@ ir_array_reference_visitor::get_variable_entry(ir_variable *var)
    /* If the array hasn't been sized yet, we can't split it.  After
     * linking, this should be resolved.
     */
-   if (var->type->is_array() && var->type->length == 0)
+   if (var->type->is_unsized_array())
       return NULL;
 
    foreach_iter(exec_list_iterator, iter, this->variable_list) {