glsl: rename _restrict to restrict_flag
[mesa.git] / src / glsl / ast_to_hir.cpp
index 91810f985bfce63575c758c8bc6c5d3e62456d6a..6de73f4764b1dd902c07a23e4fc3d617c330cb2d 100644 (file)
@@ -77,6 +77,7 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
    state->toplevel_ir = instructions;
 
    state->gs_input_prim_type_specified = false;
+   state->cs_input_local_size_specified = false;
 
    /* Section 4.2 of the GLSL 1.20 specification states:
     * "The built-in functions are scoped in a scope outside the global scope
@@ -740,14 +741,15 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
 {
    void *ctx = state;
    bool error_emitted = (lhs->type->is_error() || rhs->type->is_error());
+   ir_rvalue *extract_channel = NULL;
 
    /* If the assignment LHS comes back as an ir_binop_vector_extract
     * expression, move it to the RHS as an ir_triop_vector_insert.
     */
    if (lhs->ir_type == ir_type_expression) {
-      ir_expression *const expr = lhs->as_expression();
+      ir_expression *const lhs_expr = lhs->as_expression();
 
-      if (unlikely(expr->operation == ir_binop_vector_extract)) {
+      if (unlikely(lhs_expr->operation == ir_binop_vector_extract)) {
          ir_rvalue *new_rhs =
             validate_assignment(state, lhs_loc, lhs->type,
                                 rhs, is_initializer);
@@ -755,12 +757,24 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
          if (new_rhs == NULL) {
             return lhs;
          } else {
+            /* This converts:
+             * - LHS: (expression float vector_extract <vec> <channel>)
+             * - RHS: <scalar>
+             * into:
+             * - LHS: <vec>
+             * - RHS: (expression vec2 vector_insert <vec> <channel> <scalar>)
+             *
+             * The LHS type is now a vector instead of a scalar.  Since GLSL
+             * allows assignments to be used as rvalues, we need to re-extract
+             * the channel from assignment_temp when returning the rvalue.
+             */
+            extract_channel = lhs_expr->operands[1];
             rhs = new(ctx) ir_expression(ir_triop_vector_insert,
-                                         expr->operands[0]->type,
-                                         expr->operands[0],
+                                         lhs_expr->operands[0]->type,
+                                         lhs_expr->operands[0],
                                          new_rhs,
-                                         expr->operands[1]);
-            lhs = expr->operands[0]->clone(ctx, NULL);
+                                         extract_channel);
+            lhs = lhs_expr->operands[0]->clone(ctx, NULL);
          }
       }
    }
@@ -830,8 +844,10 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
                                                   rhs->type->array_size());
         d->type = var->type;
       }
-      mark_whole_array_access(rhs);
-      mark_whole_array_access(lhs);
+      if (lhs->type->is_array()) {
+         mark_whole_array_access(rhs);
+         mark_whole_array_access(lhs);
+      }
    }
 
    /* Most callers of do_assignment (assign, add_assign, pre_inc/dec,
@@ -854,6 +870,11 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
    if (!error_emitted)
       instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var));
 
+   if (extract_channel) {
+      return new(ctx) ir_expression(ir_binop_vector_extract,
+                                    new(ctx) ir_dereference_variable(var),
+                                    extract_channel->clone(ctx, NULL));
+   }
    return new(ctx) ir_dereference_variable(var);
 }
 
@@ -948,6 +969,7 @@ do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
    case GLSL_TYPE_ERROR:
    case GLSL_TYPE_VOID:
    case GLSL_TYPE_SAMPLER:
+   case GLSL_TYPE_IMAGE:
    case GLSL_TYPE_INTERFACE:
    case GLSL_TYPE_ATOMIC_UINT:
       /* I assume a comparison of a struct containing a sampler just
@@ -1771,64 +1793,108 @@ ast_compound_statement::hir(exec_list *instructions,
    return NULL;
 }
 
+/**
+ * Evaluate the given exec_node (which should be an ast_node representing
+ * a single array dimension) and return its integer value.
+ */
+static const unsigned
+process_array_size(exec_node *node,
+                   struct _mesa_glsl_parse_state *state)
+{
+   exec_list dummy_instructions;
+
+   ast_node *array_size = exec_node_data(ast_node, node, link);
+   ir_rvalue *const ir = array_size->hir(& dummy_instructions,
+                                                   state);
+   YYLTYPE loc = array_size->get_location();
+
+   if (ir == NULL) {
+      _mesa_glsl_error(& loc, state,
+                       "array size could not be resolved");
+      return 0;
+   }
+
+   if (!ir->type->is_integer()) {
+      _mesa_glsl_error(& loc, state,
+                       "array size must be integer type");
+      return 0;
+   }
+
+   if (!ir->type->is_scalar()) {
+      _mesa_glsl_error(& loc, state,
+                       "array size must be scalar type");
+      return 0;
+   }
+
+   ir_constant *const size = ir->constant_expression_value();
+   if (size == NULL) {
+      _mesa_glsl_error(& loc, state, "array size must be a "
+                       "constant valued expression");
+      return 0;
+   }
+
+   if (size->value.i[0] <= 0) {
+      _mesa_glsl_error(& loc, state, "array size must be > 0");
+      return 0;
+   }
+
+   assert(size->type == ir->type);
+
+   /* If the array size is const (and we've verified that
+    * it is) then no instructions should have been emitted
+    * when we converted it to HIR. If they were emitted,
+    * then either the array size isn't const after all, or
+    * we are emitting unnecessary instructions.
+    */
+   assert(dummy_instructions.is_empty());
+
+   return size->value.u[0];
+}
 
 static const glsl_type *
-process_array_type(YYLTYPE *loc, const glsl_type *base, ast_node *array_size,
-                  struct _mesa_glsl_parse_state *state)
+process_array_type(YYLTYPE *loc, const glsl_type *base,
+                   ast_array_specifier *array_specifier,
+                   struct _mesa_glsl_parse_state *state)
 {
-   unsigned length = 0;
+   const glsl_type *array_type = base;
 
-   if (base == NULL)
-      return glsl_type::error_type;
+   if (array_specifier != NULL) {
+      if (base->is_array()) {
 
-   /* From page 19 (page 25) of the GLSL 1.20 spec:
-    *
-    *     "Only one-dimensional arrays may be declared."
-    */
-   if (base->is_array()) {
-      _mesa_glsl_error(loc, state,
-                      "invalid array of `%s' (only one-dimensional arrays "
-                      "may be declared)",
-                      base->name);
-      return glsl_type::error_type;
-   }
+         /* From page 19 (page 25) of the GLSL 1.20 spec:
+          *
+          * "Only one-dimensional arrays may be declared."
+          */
+         if (!state->ARB_arrays_of_arrays_enable) {
+            _mesa_glsl_error(loc, state,
+                             "invalid array of `%s'"
+                             "GL_ARB_arrays_of_arrays "
+                             "required for defining arrays of arrays",
+                             base->name);
+            return glsl_type::error_type;
+         }
 
-   if (array_size != NULL) {
-      exec_list dummy_instructions;
-      ir_rvalue *const ir = array_size->hir(& dummy_instructions, state);
-      YYLTYPE loc = array_size->get_location();
+         if (base->length == 0) {
+            _mesa_glsl_error(loc, state,
+                             "only the outermost array dimension can "
+                             "be unsized",
+                             base->name);
+            return glsl_type::error_type;
+         }
+      }
 
-      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];
-
-               /* If the array size is const (and we've verified that
-                * it is) then no instructions should have been emitted
-                * when we converted it to HIR.  If they were emitted,
-                * then either the array size isn't const after all, or
-                * we are emitting unnecessary instructions.
-                */
-               assert(dummy_instructions.is_empty());
-           }
-        }
+      for (exec_node *node = array_specifier->array_dimensions.tail_pred;
+           !node->is_head_sentinel(); node = node->prev) {
+         unsigned array_size = process_array_size(node, state);
+         array_type = glsl_type::get_array_instance(array_type,
+                                                    array_size);
       }
+
+      if (array_specifier->is_unsized_array)
+         array_type = glsl_type::get_array_instance(array_type, 0);
    }
 
-   const glsl_type *array_type = glsl_type::get_array_instance(base, length);
-   return array_type != NULL ? array_type : glsl_type::error_type;
+   return array_type;
 }
 
 
@@ -1841,10 +1907,8 @@ ast_type_specifier::glsl_type(const char **name,
    type = state->symbols->get_type(this->type_name);
    *name = this->type_name;
 
-   if (this->is_array) {
-      YYLTYPE loc = this->get_location();
-      type = process_array_type(&loc, type, this->array_size, state);
-   }
+   YYLTYPE loc = this->get_location();
+   type = process_array_type(&loc, type, this->array_specifier, state);
 
    return type;
 }
@@ -1860,7 +1924,7 @@ ast_fully_specified_type::glsl_type(const char **name,
 
    if (type->base_type == GLSL_TYPE_FLOAT
        && state->es_shader
-       && state->target == MESA_SHADER_FRAGMENT
+       && state->stage == MESA_SHADER_FRAGMENT
        && this->qualifier.precision == ast_precision_none
        && state->symbols->get_variable("#default precision") == NULL) {
       YYLTYPE loc = this->get_location();
@@ -1882,7 +1946,7 @@ ast_fully_specified_type::glsl_type(const char **name,
  * this function will produce undefined results.
  */
 static bool
-is_varying_var(ir_variable *var, gl_shader_type target)
+is_varying_var(ir_variable *var, gl_shader_stage target)
 {
    switch (target) {
    case MESA_SHADER_VERTEX:
@@ -1983,18 +2047,7 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state,
        *  with an array of size N, all elements of the array from binding
        *  through binding + N - 1 must be within this range."
        */
-      unsigned limit = 0;
-      switch (state->target) {
-      case MESA_SHADER_VERTEX:
-         limit = ctx->Const.VertexProgram.MaxTextureImageUnits;
-         break;
-      case MESA_SHADER_GEOMETRY:
-         limit = ctx->Const.GeometryProgram.MaxTextureImageUnits;
-         break;
-      case MESA_SHADER_FRAGMENT:
-         limit = ctx->Const.FragmentProgram.MaxTextureImageUnits;
-         break;
-      }
+      unsigned limit = ctx->Const.Program[state->stage].MaxTextureImageUnits;
 
       if (max_index >= limit) {
          _mesa_glsl_error(loc, state, "layout(binding = %d) for %d samplers "
@@ -2049,8 +2102,8 @@ interpret_interpolation_qualifier(const struct ast_type_qualifier *qual,
 
       }
 
-      if ((state->target == MESA_SHADER_VERTEX && mode == ir_var_shader_in) ||
-          (state->target == MESA_SHADER_FRAGMENT && mode == ir_var_shader_out)) {
+      if ((state->stage == MESA_SHADER_VERTEX && mode == ir_var_shader_in) ||
+          (state->stage == MESA_SHADER_FRAGMENT && mode == ir_var_shader_out)) {
          _mesa_glsl_error(loc, state,
                           "interpolation qualifier `%s' cannot be applied to "
                           "vertex shader inputs or fragment shader outputs",
@@ -2076,7 +2129,7 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
     * In the fragment shader only shader outputs can be given explicit
     * locations.
     */
-   switch (state->target) {
+   switch (state->stage) {
    case MESA_SHADER_VERTEX:
       if (var->data.mode == ir_var_shader_in) {
          if (!state->check_explicit_attrib_location_allowed(loc, var))
@@ -2104,13 +2157,19 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
 
       fail = true;
       break;
+
+   case MESA_SHADER_COMPUTE:
+      _mesa_glsl_error(loc, state,
+                       "compute shader variables cannot be given "
+                       "explicit locations");
+      return;
    };
 
    if (fail) {
       _mesa_glsl_error(loc, state,
                        "%s cannot be given an explicit location in %s shader",
                        mode_string(var),
-                      _mesa_shader_type_to_string(state->target));
+                      _mesa_shader_stage_to_string(state->stage));
    } else {
       var->data.explicit_location = true;
 
@@ -2122,7 +2181,7 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
        * ensures that negative values stay negative.
        */
       if (qual->location >= 0) {
-         var->data.location = (state->target == MESA_SHADER_VERTEX)
+         var->data.location = (state->stage == MESA_SHADER_VERTEX)
             ? (qual->location + VERT_ATTRIB_GENERIC0)
             : (qual->location + FRAG_RESULT_DATA0);
       } else {
@@ -2152,6 +2211,54 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
    return;
 }
 
+static void
+apply_image_qualifier_to_variable(const struct ast_type_qualifier *qual,
+                                  ir_variable *var,
+                                  struct _mesa_glsl_parse_state *state,
+                                  YYLTYPE *loc)
+{
+   const glsl_type *base_type =
+      (var->type->is_array() ? var->type->element_type() : var->type);
+
+   if (base_type->is_image()) {
+      if (var->data.mode != ir_var_uniform &&
+          var->data.mode != ir_var_function_in) {
+         _mesa_glsl_error(loc, state, "image variables may only be declared as "
+                          "function parameters or uniform-qualified "
+                          "global variables");
+      }
+
+      var->data.image.read_only |= qual->flags.q.read_only;
+      var->data.image.write_only |= qual->flags.q.write_only;
+      var->data.image.coherent |= qual->flags.q.coherent;
+      var->data.image._volatile |= qual->flags.q._volatile;
+      var->data.image.restrict_flag |= qual->flags.q.restrict_flag;
+      var->data.read_only = true;
+
+      if (qual->flags.q.explicit_image_format) {
+         if (var->data.mode == ir_var_function_in) {
+            _mesa_glsl_error(loc, state, "format qualifiers cannot be "
+                             "used on image function parameters");
+         }
+
+         if (qual->image_base_type != base_type->sampler_type) {
+            _mesa_glsl_error(loc, state, "format qualifier doesn't match the "
+                             "base data type of the image");
+         }
+
+         var->data.image.format = qual->image_format;
+      } else {
+         if (var->data.mode == ir_var_uniform && !qual->flags.q.write_only) {
+            _mesa_glsl_error(loc, state, "uniforms not qualified with "
+                             "`writeonly' must have a format layout "
+                             "qualifier");
+         }
+
+         var->data.image.format = GL_NONE;
+      }
+   }
+}
+
 static void
 apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
                                 ir_variable *var,
@@ -2174,7 +2281,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
 
    if (qual->flags.q.constant || qual->flags.q.attribute
        || qual->flags.q.uniform
-       || (qual->flags.q.varying && (state->target == MESA_SHADER_FRAGMENT)))
+       || (qual->flags.q.varying && (state->stage == MESA_SHADER_FRAGMENT)))
       var->data.read_only = 1;
 
    if (qual->flags.q.centroid)
@@ -2183,12 +2290,12 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
    if (qual->flags.q.sample)
       var->data.sample = 1;
 
-   if (qual->flags.q.attribute && state->target != MESA_SHADER_VERTEX) {
+   if (qual->flags.q.attribute && state->stage != MESA_SHADER_VERTEX) {
       var->type = glsl_type::error_type;
       _mesa_glsl_error(loc, state,
                       "`attribute' variables may not be declared in the "
                       "%s shader",
-                      _mesa_shader_type_to_string(state->target));
+                      _mesa_shader_stage_to_string(state->stage));
    }
 
    /* Section 6.1.1 (Function Calling Conventions) of the GLSL 1.10 spec says:
@@ -2214,16 +2321,23 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
    else if (qual->flags.q.in)
       var->data.mode = is_parameter ? ir_var_function_in : ir_var_shader_in;
    else if (qual->flags.q.attribute
-           || (qual->flags.q.varying && (state->target == MESA_SHADER_FRAGMENT)))
+           || (qual->flags.q.varying && (state->stage == MESA_SHADER_FRAGMENT)))
       var->data.mode = ir_var_shader_in;
    else if (qual->flags.q.out)
       var->data.mode = is_parameter ? ir_var_function_out : ir_var_shader_out;
-   else if (qual->flags.q.varying && (state->target == MESA_SHADER_VERTEX))
+   else if (qual->flags.q.varying && (state->stage == MESA_SHADER_VERTEX))
       var->data.mode = ir_var_shader_out;
    else if (qual->flags.q.uniform)
       var->data.mode = ir_var_uniform;
 
-   if (!is_parameter && is_varying_var(var, state->target)) {
+   if (!is_parameter && is_varying_var(var, state->stage)) {
+      /* User-defined ins/outs are not permitted in compute shaders. */
+      if (state->stage == MESA_SHADER_COMPUTE) {
+         _mesa_glsl_error(loc, state,
+                          "user-defined input and output variables are not "
+                          "permitted in compute shaders");
+      }
+
       /* This variable is being used to link data between shader stages (in
        * pre-glsl-1.30 parlance, it's a "varying").  Check that it has a type
        * that is allowed for such purposes.
@@ -2272,7 +2386,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
    }
 
    if (state->all_invariant && (state->current_function == NULL)) {
-      switch (state->target) {
+      switch (state->stage) {
       case MESA_SHADER_VERTEX:
         if (var->data.mode == ir_var_shader_out)
            var->data.invariant = true;
@@ -2286,6 +2400,9 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
         if (var->data.mode == ir_var_shader_in)
            var->data.invariant = true;
         break;
+      case MESA_SHADER_COMPUTE:
+         /* Invariance isn't meaningful in compute shaders. */
+         break;
       }
    }
 
@@ -2432,6 +2549,9 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
    if (qual->flags.q.row_major || qual->flags.q.column_major) {
       validate_matrix_layout_for_type(state, loc, var->type, var);
    }
+
+   if (var->type->contains_image())
+      apply_image_qualifier_to_variable(qual, var, state, loc);
 }
 
 /**
@@ -2591,19 +2711,32 @@ process_initializer(ir_variable *var, ast_declaration *decl,
                            "cannot initialize uniforms");
    }
 
-   if (var->type->is_sampler()) {
+   /* From section 4.1.7 of the GLSL 4.40 spec:
+    *
+    *    "Opaque variables [...] are initialized only through the
+    *     OpenGL API; they cannot be declared with an initializer in a
+    *     shader."
+    */
+   if (var->type->contains_opaque()) {
       _mesa_glsl_error(& initializer_loc, state,
-                      "cannot initialize samplers");
+                      "cannot initialize opaque variable");
    }
 
    if ((var->data.mode == ir_var_shader_in) && (state->current_function == NULL)) {
       _mesa_glsl_error(& initializer_loc, state,
                       "cannot initialize %s shader input / %s",
-                      _mesa_shader_type_to_string(state->target),
-                      (state->target == MESA_SHADER_VERTEX)
+                      _mesa_shader_stage_to_string(state->stage),
+                      (state->stage == MESA_SHADER_VERTEX)
                       ? "attribute" : "varying");
    }
 
+   /* If the initializer is an ast_aggregate_initializer, recursively store
+    * type information from the LHS into it, so that its hir() function can do
+    * type checking.
+    */
+   if (decl->initializer->oper == ast_aggregate)
+      _mesa_ast_set_aggregate_type(var->type, decl->initializer);
+
    ir_dereference *const lhs = new(state) ir_dereference_variable(var);
    ir_rvalue *rhs = decl->initializer->hir(initializer_instructions,
                                           state);
@@ -2834,8 +2967,7 @@ ast_declarator_list::hir(exec_list *instructions,
       }
 
       foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
-        assert(!decl->is_array);
-        assert(decl->array_size == NULL);
+        assert(decl->array_specifier == NULL);
         assert(decl->initializer == NULL);
 
         ir_variable *const earlier =
@@ -2844,12 +2976,12 @@ ast_declarator_list::hir(exec_list *instructions,
            _mesa_glsl_error(& loc, state,
                             "undeclared variable `%s' cannot be marked "
                             "invariant", decl->identifier);
-        } else if ((state->target == MESA_SHADER_VERTEX)
+        } else if ((state->stage == MESA_SHADER_VERTEX)
               && (earlier->data.mode != ir_var_shader_out)) {
            _mesa_glsl_error(& loc, state,
                             "`%s' cannot be marked invariant, vertex shader "
                             "outputs only", decl->identifier);
-        } else if ((state->target == MESA_SHADER_FRAGMENT)
+        } else if ((state->stage == MESA_SHADER_FRAGMENT)
               && (earlier->data.mode != ir_var_shader_in)) {
            _mesa_glsl_error(& loc, state,
                             "`%s' cannot be marked invariant, fragment shader "
@@ -2970,14 +3102,8 @@ ast_declarator_list::hir(exec_list *instructions,
         continue;
       }
 
-      if (decl->is_array) {
-        var_type = process_array_type(&loc, decl_type, decl->array_size,
-                                      state);
-        if (var_type->is_error())
-           continue;
-      } else {
-        var_type = decl_type;
-      }
+      var_type = process_array_type(&loc, decl_type, decl->array_specifier,
+                                    state);
 
       var = new(ctx) ir_variable(var_type, decl->identifier, ir_var_auto);
 
@@ -3034,12 +3160,12 @@ ast_declarator_list::hir(exec_list *instructions,
                                       & loc, false);
 
       if (this->type->qualifier.flags.q.invariant) {
-        if ((state->target == MESA_SHADER_VERTEX) &&
+        if ((state->stage == MESA_SHADER_VERTEX) &&
              var->data.mode != ir_var_shader_out) {
            _mesa_glsl_error(& loc, state,
                             "`%s' cannot be marked invariant, vertex shader "
                             "outputs only", var->name);
-        } else if ((state->target == MESA_SHADER_FRAGMENT) &&
+        } else if ((state->stage == MESA_SHADER_FRAGMENT) &&
                    var->data.mode != ir_var_shader_in) {
            /* FINISHME: Note that this doesn't work for invariant on
             * a function signature inval
@@ -3080,7 +3206,7 @@ ast_declarator_list::hir(exec_list *instructions,
       } else if (var->data.mode == ir_var_shader_in) {
          var->data.read_only = true;
 
-        if (state->target == MESA_SHADER_VERTEX) {
+        if (state->stage == MESA_SHADER_VERTEX) {
            bool error_emitted = false;
 
            /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
@@ -3109,8 +3235,9 @@ ast_declarator_list::hir(exec_list *instructions,
              *    vectors. Vertex shader inputs cannot be arrays or
              *    structures."
             */
-           const glsl_type *check_type = var->type->is_array()
-              ? var->type->fields.array : var->type;
+            const glsl_type *check_type = var->type;
+            while (check_type->is_array())
+               check_type = check_type->element_type();
 
            switch (check_type->base_type) {
            case GLSL_TYPE_FLOAT:
@@ -3135,7 +3262,7 @@ ast_declarator_list::hir(exec_list *instructions,
                                       "cannot have array type")) {
               error_emitted = true;
            }
-        } else if (state->target == MESA_SHADER_GEOMETRY) {
+        } else if (state->stage == MESA_SHADER_GEOMETRY) {
             /* From section 4.3.4 (Inputs) of the GLSL 1.50 spec:
              *
              *     Geometry shader input variables get the per-vertex values
@@ -3185,10 +3312,10 @@ ast_declarator_list::hir(exec_list *instructions,
       if (state->is_version(130, 300) &&
           var->type->contains_integer() &&
           var->data.interpolation != INTERP_QUALIFIER_FLAT &&
-          ((state->target == MESA_SHADER_FRAGMENT && var->data.mode == ir_var_shader_in)
-           || (state->target == MESA_SHADER_VERTEX && var->data.mode == ir_var_shader_out
+          ((state->stage == MESA_SHADER_FRAGMENT && var->data.mode == ir_var_shader_in)
+           || (state->stage == MESA_SHADER_VERTEX && var->data.mode == ir_var_shader_out
                && state->es_shader))) {
-         const char *var_type = (state->target == MESA_SHADER_VERTEX) ?
+         const char *var_type = (state->stage == MESA_SHADER_VERTEX) ?
             "vertex output" : "fragment input";
          _mesa_glsl_error(&loc, state, "if a %s is (or contains) "
                           "an integer, then it must be qualified with 'flat'",
@@ -3244,7 +3371,7 @@ ast_declarator_list::hir(exec_list *instructions,
          const char *i = this->type->qualifier.interpolation_string();
          assert(i != NULL);
 
-         switch (state->target) {
+         switch (state->stage) {
          case MESA_SHADER_VERTEX:
             if (this->type->qualifier.flags.q.in) {
                _mesa_glsl_error(&loc, state,
@@ -3275,13 +3402,13 @@ ast_declarator_list::hir(exec_list *instructions,
       if (state->is_version(130, 300)
           && this->type->qualifier.flags.q.centroid
           && this->type->qualifier.flags.q.in
-          && state->target == MESA_SHADER_VERTEX) {
+          && state->stage == MESA_SHADER_VERTEX) {
 
          _mesa_glsl_error(&loc, state,
                           "'centroid in' cannot be used in a vertex shader");
       }
 
-      if (state->target == MESA_SHADER_VERTEX
+      if (state->stage == MESA_SHADER_VERTEX
           && this->type->qualifier.flags.q.sample
           && this->type->qualifier.flags.q.in) {
 
@@ -3296,7 +3423,7 @@ ast_declarator_list::hir(exec_list *instructions,
        * "It is an error to use auxiliary storage qualifiers or interpolation
        *  qualifiers on an output in a fragment shader."
        */
-      if (state->target == MESA_SHADER_FRAGMENT &&
+      if (state->stage == MESA_SHADER_FRAGMENT &&
           this->type->qualifier.flags.q.out &&
           this->type->qualifier.has_auxiliary_storage()) {
          _mesa_glsl_error(&loc, state,
@@ -3352,15 +3479,15 @@ ast_declarator_list::hir(exec_list *instructions,
                           ", integer and sampler types");
       }
 
-      /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
+      /* From section 4.1.7 of the GLSL 4.40 spec:
        *
-       *    "[Sampler types] can only be declared as function
-       *    parameters or uniform variables (see Section 4.3.5
-       *    "Uniform")".
+       *    "[Opaque types] can only be declared as function
+       *     parameters or uniform-qualified variables."
        */
-      if (var_type->contains_sampler() &&
+      if (var_type->contains_opaque() &&
           !this->type->qualifier.flags.q.uniform) {
-         _mesa_glsl_error(&loc, state, "samplers must be declared uniform");
+         _mesa_glsl_error(&loc, state,
+                          "opaque variables must be declared uniform");
       }
 
       /* Process the initializer and add its instructions to a temporary
@@ -3534,9 +3661,7 @@ ast_parameter_declarator::hir(exec_list *instructions,
    /* This only handles "vec4 foo[..]".  The earlier specifier->glsl_type(...)
     * call already handled the "vec4[..] foo" case.
     */
-   if (this->is_array) {
-      type = process_array_type(&loc, type, this->array_size, state);
-   }
+   type = process_array_type(&loc, type, this->array_specifier, state);
 
    if (!type->is_error() && type->is_unsized_array()) {
       _mesa_glsl_error(&loc, state, "arrays passed as parameters must have "
@@ -3554,15 +3679,16 @@ ast_parameter_declarator::hir(exec_list *instructions,
    apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc,
                                    true);
 
-   /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
+   /* From section 4.1.7 of the GLSL 4.40 spec:
     *
-    *    "Samplers cannot be treated as l-values; hence cannot be used
-    *    as out or inout function parameters, nor can they be assigned
-    *    into."
+    *   "Opaque variables cannot be treated as l-values; hence cannot
+    *    be used as out or inout function parameters, nor can they be
+    *    assigned into."
     */
    if ((var->data.mode == ir_var_function_inout || var->data.mode == ir_var_function_out)
-       && type->contains_sampler()) {
-      _mesa_glsl_error(&loc, state, "out and inout parameters cannot contain samplers");
+       && type->contains_opaque()) {
+      _mesa_glsl_error(&loc, state, "out and inout parameters cannot "
+                       "contain opaque variables");
       type = glsl_type::error_type;
    }
 
@@ -3717,15 +3843,15 @@ ast_function::hir(exec_list *instructions,
                       "sized", name);
    }
 
-   /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
+   /* From section 4.1.7 of the GLSL 4.40 spec:
     *
-    *    "[Sampler types] can only be declared as function parameters
-    *    or uniform variables (see Section 4.3.5 "Uniform")".
+    *    "[Opaque types] can only be declared as function parameters
+    *     or uniform-qualified variables."
     */
-   if (return_type->contains_sampler()) {
+   if (return_type->contains_opaque()) {
       YYLTYPE loc = this->get_location();
       _mesa_glsl_error(&loc, state,
-                       "function `%s' return type can't contain a sampler",
+                       "function `%s' return type can't contain an opaque type",
                        name);
    }
 
@@ -3829,8 +3955,8 @@ ast_function_definition::hir(exec_list *instructions,
     * Add these to the symbol table.
     */
    state->symbols->push_scope();
-   foreach_iter(exec_list_iterator, iter, signature->parameters) {
-      ir_variable *const var = ((ir_instruction *) iter.get())->as_variable();
+   foreach_list(n, &signature->parameters) {
+      ir_variable *const var = ((ir_instruction *) n)->as_variable();
 
       assert(var != NULL);
 
@@ -3954,7 +4080,7 @@ ast_jump_statement::hir(exec_list *instructions,
    }
 
    case ast_discard:
-      if (state->target != MESA_SHADER_FRAGMENT) {
+      if (state->stage != MESA_SHADER_FRAGMENT) {
         YYLTYPE loc = this->get_location();
 
         _mesa_glsl_error(& loc, state,
@@ -3979,17 +4105,22 @@ ast_jump_statement::hir(exec_list *instructions,
         _mesa_glsl_error(& loc, state,
                          "break may only appear in a loop or a switch");
       } else {
-        /* For a loop, inline the for loop expression again,
-         * since we don't know where near the end of
-         * the loop body the normal copy of it
-         * is going to be placed.
+        /* For a loop, inline the for loop expression again, since we don't
+         * know where near the end of the loop body the normal copy of it is
+         * going to be placed.  Same goes for the condition for a do-while
+         * loop.
          */
         if (state->loop_nesting_ast != NULL &&
-            mode == ast_continue &&
-            state->loop_nesting_ast->rest_expression) {
-           state->loop_nesting_ast->rest_expression->hir(instructions,
-                                                         state);
-        }
+            mode == ast_continue) {
+            if (state->loop_nesting_ast->rest_expression) {
+               state->loop_nesting_ast->rest_expression->hir(instructions,
+                                                             state);
+            }
+            if (state->loop_nesting_ast->mode ==
+                ast_iteration_statement::ast_do_while) {
+               state->loop_nesting_ast->condition_to_hir(instructions, state);
+            }
+         }
 
         if (state->switch_state.is_switch_innermost &&
             mode == ast_break) {
@@ -4319,14 +4450,14 @@ ast_case_label::hir(exec_list *instructions,
 }
 
 void
-ast_iteration_statement::condition_to_hir(ir_loop *stmt,
+ast_iteration_statement::condition_to_hir(exec_list *instructions,
                                          struct _mesa_glsl_parse_state *state)
 {
    void *ctx = state;
 
    if (condition != NULL) {
       ir_rvalue *const cond =
-        condition->hir(& stmt->body_instructions, state);
+        condition->hir(instructions, state);
 
       if ((cond == NULL)
          || !cond->type->is_boolean() || !cond->type->is_scalar()) {
@@ -4347,7 +4478,7 @@ ast_iteration_statement::condition_to_hir(ir_loop *stmt,
            new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
 
         if_stmt->then_instructions.push_tail(break_stmt);
-        stmt->body_instructions.push_tail(if_stmt);
+        instructions->push_tail(if_stmt);
       }
    }
 }
@@ -4382,7 +4513,7 @@ ast_iteration_statement::hir(exec_list *instructions,
    state->switch_state.is_switch_innermost = false;
 
    if (mode != ast_do_while)
-      condition_to_hir(stmt, state);
+      condition_to_hir(&stmt->body_instructions, state);
 
    if (body != NULL)
       body->hir(& stmt->body_instructions, state);
@@ -4391,7 +4522,7 @@ ast_iteration_statement::hir(exec_list *instructions,
       rest_expression->hir(& stmt->body_instructions, state);
 
    if (mode == ast_do_while)
-      condition_to_hir(stmt, state);
+      condition_to_hir(&stmt->body_instructions, state);
 
    if (mode != ast_do_while)
       state->symbols->pop_scope();
@@ -4474,7 +4605,7 @@ ast_type_specifier::hir(exec_list *instructions,
          return NULL;
       }
 
-      if (this->is_array) {
+      if (this->array_specifier != NULL) {
          _mesa_glsl_error(&loc, state,
                           "default precision statements do not apply to "
                           "arrays");
@@ -4492,7 +4623,7 @@ ast_type_specifier::hir(exec_list *instructions,
 
       if (type->base_type == GLSL_TYPE_FLOAT
           && state->es_shader
-          && state->target == MESA_SHADER_FRAGMENT) {
+          && state->stage == MESA_SHADER_FRAGMENT) {
          /* Section 4.5.3 (Default Precision Qualifiers) of the GLSL ES 1.00
           * spec says:
           *
@@ -4621,12 +4752,9 @@ ast_process_structure_or_interface_block(exec_list *instructions,
          if (!allow_reserved_names)
             validate_identifier(decl->identifier, loc, state);
 
-         /* From the GL_ARB_uniform_buffer_object spec:
+         /* From section 4.3.9 of the GLSL 4.40 spec:
           *
-          *     "Sampler types are not allowed inside of uniform
-          *      blocks. All other types, arrays, and structures
-          *      allowed for uniforms are allowed within a uniform
-          *      block."
+          *    "[In interface blocks] opaque types are not allowed."
           *
           * It should be impossible for decl_type to be NULL here.  Cases that
           * might naturally lead to decl_type being NULL, especially for the
@@ -4636,10 +4764,11 @@ ast_process_structure_or_interface_block(exec_list *instructions,
          const struct glsl_type *field_type =
             decl_type != NULL ? decl_type : glsl_type::error_type;
 
-         if (is_interface && field_type->contains_sampler()) {
+         if (is_interface && field_type->contains_opaque()) {
             YYLTYPE loc = decl_list->get_location();
             _mesa_glsl_error(&loc, state,
-                             "uniform in non-default uniform block contains sampler");
+                             "uniform in non-default uniform block contains "
+                             "opaque variable");
          }
 
          if (field_type->contains_atomic()) {
@@ -4653,6 +4782,16 @@ ast_process_structure_or_interface_block(exec_list *instructions,
                              "uniform block");
          }
 
+         if (field_type->contains_image()) {
+            /* FINISHME: Same problem as with atomic counters.
+             * FINISHME: Request clarification from Khronos and add
+             * FINISHME: spec quotation here.
+             */
+            YYLTYPE loc = decl_list->get_location();
+            _mesa_glsl_error(&loc, state,
+                             "image in structure or uniform block");
+         }
+
          const struct ast_type_qualifier *const qual =
             & decl_list->type->qualifier;
          if (qual->flags.q.std140 ||
@@ -4664,10 +4803,8 @@ ast_process_structure_or_interface_block(exec_list *instructions,
                              "members");
          }
 
-        if (decl->is_array) {
-           field_type = process_array_type(&loc, decl_type, decl->array_size,
-                                           state);
-        }
+        field_type = process_array_type(&loc, decl_type,
+                                         decl->array_specifier, state);
          fields[i].type = field_type;
         fields[i].name = decl->identifier;
          fields[i].location = -1;
@@ -4890,10 +5027,10 @@ ast_interface_block::hir(exec_list *instructions,
             _mesa_glsl_error(&loc, state,
                              "redeclaration of gl_PerVertex input not allowed "
                              "in the %s shader",
-                             _mesa_shader_type_to_string(state->target));
+                             _mesa_shader_stage_to_string(state->stage));
          }
          if (this->instance_name == NULL ||
-             strcmp(this->instance_name, "gl_in") != 0 || !this->is_array) {
+             strcmp(this->instance_name, "gl_in") != 0 || this->array_specifier == NULL) {
             _mesa_glsl_error(&loc, state,
                              "gl_PerVertex input must be redeclared as "
                              "gl_in[]");
@@ -4907,7 +5044,7 @@ ast_interface_block::hir(exec_list *instructions,
             _mesa_glsl_error(&loc, state,
                              "redeclaration of gl_PerVertex output not "
                              "allowed in the %s shader",
-                             _mesa_shader_type_to_string(state->target));
+                             _mesa_shader_stage_to_string(state->stage));
          }
          if (this->instance_name != NULL) {
             _mesa_glsl_error(&loc, state,
@@ -4995,7 +5132,7 @@ ast_interface_block::hir(exec_list *instructions,
     *     variable (or input block, see interface blocks below) needs to be
     *     declared as an array.
     */
-   if (state->target == MESA_SHADER_GEOMETRY && !this->is_array &&
+   if (state->stage == MESA_SHADER_GEOMETRY && this->array_specifier == NULL &&
        var_mode == ir_var_shader_in) {
       _mesa_glsl_error(&loc, state, "geometry shader inputs must be arrays");
    }
@@ -5029,7 +5166,7 @@ ast_interface_block::hir(exec_list *instructions,
 
       ir_variable *var;
 
-      if (this->is_array) {
+      if (this->array_specifier != NULL) {
          /* Section 4.3.7 (Interface Blocks) of the GLSL 1.50 spec says:
           *
           *     For uniform blocks declared an array, each individual array
@@ -5049,8 +5186,8 @@ ast_interface_block::hir(exec_list *instructions,
           * interface array size *doesn't* need to be specified is on a
           * geometry shader input.
           */
-         if (this->array_size == NULL &&
-             (state->target != MESA_SHADER_GEOMETRY || !this->layout.flags.q.in)) {
+         if (this->array_specifier->is_unsized_array &&
+             (state->stage != MESA_SHADER_GEOMETRY || !this->layout.flags.q.in)) {
             _mesa_glsl_error(&loc, state,
                              "only geometry shader inputs may be unsized "
                              "instance block arrays");
@@ -5058,7 +5195,7 @@ ast_interface_block::hir(exec_list *instructions,
          }
 
          const glsl_type *block_array_type =
-            process_array_type(&loc, block_type, this->array_size, state);
+            process_array_type(&loc, block_type, this->array_specifier, state);
 
          var = new(state) ir_variable(block_array_type,
                                       this->instance_name,
@@ -5069,7 +5206,7 @@ ast_interface_block::hir(exec_list *instructions,
                                       var_mode);
       }
 
-      if (state->target == MESA_SHADER_GEOMETRY && var_mode == ir_var_shader_in)
+      if (state->stage == MESA_SHADER_GEOMETRY && var_mode == ir_var_shader_in)
          handle_geometry_shader_input_decl(state, loc, var);
 
       if (ir_variable *earlier =
@@ -5090,7 +5227,7 @@ ast_interface_block::hir(exec_list *instructions,
       /* In order to have an array size, the block must also be declared with
        * an instane name.
        */
-      assert(!this->is_array);
+      assert(this->array_specifier == NULL);
 
       for (unsigned i = 0; i < num_variables; i++) {
          ir_variable *var =
@@ -5241,6 +5378,84 @@ ast_gs_input_layout::hir(exec_list *instructions,
 }
 
 
+ir_rvalue *
+ast_cs_input_layout::hir(exec_list *instructions,
+                         struct _mesa_glsl_parse_state *state)
+{
+   YYLTYPE loc = this->get_location();
+
+   /* If any compute input layout declaration preceded this one, make sure it
+    * was consistent with this one.
+    */
+   if (state->cs_input_local_size_specified) {
+      for (int i = 0; i < 3; i++) {
+         if (state->cs_input_local_size[i] != this->local_size[i]) {
+            _mesa_glsl_error(&loc, state,
+                             "compute shader input layout does not match"
+                             " previous declaration");
+            return NULL;
+         }
+      }
+   }
+
+   /* From the ARB_compute_shader specification:
+    *
+    *     If the local size of the shader in any dimension is greater
+    *     than the maximum size supported by the implementation for that
+    *     dimension, a compile-time error results.
+    *
+    * It is not clear from the spec how the error should be reported if
+    * the total size of the work group exceeds
+    * MAX_COMPUTE_WORK_GROUP_INVOCATIONS, but it seems reasonable to
+    * report it at compile time as well.
+    */
+   GLuint64 total_invocations = 1;
+   for (int i = 0; i < 3; i++) {
+      if (this->local_size[i] > state->ctx->Const.MaxComputeWorkGroupSize[i]) {
+         _mesa_glsl_error(&loc, state,
+                          "local_size_%c exceeds MAX_COMPUTE_WORK_GROUP_SIZE"
+                          " (%d)", 'x' + i,
+                          state->ctx->Const.MaxComputeWorkGroupSize[i]);
+         break;
+      }
+      total_invocations *= this->local_size[i];
+      if (total_invocations >
+          state->ctx->Const.MaxComputeWorkGroupInvocations) {
+         _mesa_glsl_error(&loc, state,
+                          "product of local_sizes exceeds "
+                          "MAX_COMPUTE_WORK_GROUP_INVOCATIONS (%d)",
+                          state->ctx->Const.MaxComputeWorkGroupInvocations);
+         break;
+      }
+   }
+
+   state->cs_input_local_size_specified = true;
+   for (int i = 0; i < 3; i++)
+      state->cs_input_local_size[i] = this->local_size[i];
+
+   /* We may now declare the built-in constant gl_WorkGroupSize (see
+    * builtin_variable_generator::generate_constants() for why we didn't
+    * declare it earlier).
+    */
+   ir_variable *var = new(state->symbols)
+      ir_variable(glsl_type::ivec3_type, "gl_WorkGroupSize", ir_var_auto);
+   var->data.how_declared = ir_var_declared_implicitly;
+   var->data.read_only = true;
+   instructions->push_tail(var);
+   state->symbols->add_variable(var);
+   ir_constant_data data;
+   memset(&data, 0, sizeof(data));
+   for (int i = 0; i < 3; i++)
+      data.i[i] = this->local_size[i];
+   var->constant_value = new(var) ir_constant(glsl_type::ivec3_type, &data);
+   var->constant_initializer =
+      new(var) ir_constant(glsl_type::ivec3_type, &data);
+   var->data.has_initializer = true;
+
+   return NULL;
+}
+
+
 static void
 detect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
                               exec_list *instructions)
@@ -5265,7 +5480,7 @@ detect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
       else if (strcmp(var->name, "gl_FragData") == 0)
         gl_FragData_assigned = true;
       else if (strncmp(var->name, "gl_", 3) != 0) {
-        if (state->target == MESA_SHADER_FRAGMENT &&
+        if (state->stage == MESA_SHADER_FRAGMENT &&
             var->data.mode == ir_var_shader_out) {
            user_defined_fs_output_assigned = true;
            user_defined_fs_output = var;