glsl: A shader cannot redefine or overload built-in functions in GLSL ES 3.00
[mesa.git] / src / glsl / ast_to_hir.cpp
index f35d8679e70e0d7414f48c586b55f4369f1ea6b4..acb5c763c43c0cab7fb9aa0f7f24ed3bfe9f546f 100644 (file)
  * parser (and lexer) sources.
  */
 
-#include "main/core.h" /* for struct gl_extensions */
 #include "glsl_symbol_table.h"
 #include "glsl_parser_extras.h"
 #include "ast.h"
 #include "glsl_types.h"
 #include "program/hash_table.h"
 #include "ir.h"
+#include "ir_builder.h"
+
+using namespace ir_builder;
 
 static void
 detect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
@@ -77,6 +79,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
@@ -109,8 +112,8 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
     * applications depend on this behavior, and it matches what nearly all
     * other drivers do.
     */
-   foreach_list_safe(node, instructions) {
-      ir_variable *const var = ((ir_instruction *) node)->as_variable();
+   foreach_in_list_safe(ir_instruction, node, instructions) {
+      ir_variable *const var = node->as_variable();
 
       if (var == NULL)
          continue;
@@ -119,6 +122,11 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
       instructions->push_head(var);
    }
 
+   /* Figure out if gl_FragCoord is actually used in fragment shader */
+   ir_variable *const var = state->symbols->get_variable("gl_FragCoord");
+   if (var != NULL)
+      state->fs_uses_gl_fragcoord = var->data.used;
+
    /* From section 7.1 (Built-In Language Variables) of the GLSL 4.10 spec:
     *
     *     If multiple shaders using members of a built-in block belonging to
@@ -155,6 +163,42 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
 }
 
 
+static ir_expression_operation
+get_conversion_operation(const glsl_type *to, const glsl_type *from,
+                         struct _mesa_glsl_parse_state *state)
+{
+   switch (to->base_type) {
+   case GLSL_TYPE_FLOAT:
+      switch (from->base_type) {
+      case GLSL_TYPE_INT: return ir_unop_i2f;
+      case GLSL_TYPE_UINT: return ir_unop_u2f;
+      case GLSL_TYPE_DOUBLE: return ir_unop_d2f;
+      default: return (ir_expression_operation)0;
+      }
+
+   case GLSL_TYPE_UINT:
+      if (!state->is_version(400, 0) && !state->ARB_gpu_shader5_enable)
+         return (ir_expression_operation)0;
+      switch (from->base_type) {
+         case GLSL_TYPE_INT: return ir_unop_i2u;
+         default: return (ir_expression_operation)0;
+      }
+
+   case GLSL_TYPE_DOUBLE:
+      if (!state->has_double())
+         return (ir_expression_operation)0;
+      switch (from->base_type) {
+      case GLSL_TYPE_INT: return ir_unop_i2d;
+      case GLSL_TYPE_UINT: return ir_unop_u2d;
+      case GLSL_TYPE_FLOAT: return ir_unop_f2d;
+      default: return (ir_expression_operation)0;
+      }
+
+   default: return (ir_expression_operation)0;
+   }
+}
+
+
 /**
  * If a conversion is available, convert one operand to a different type
  *
@@ -170,15 +214,13 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
  */
 bool
 apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from,
-                         struct _mesa_glsl_parse_state *state)
+                          struct _mesa_glsl_parse_state *state)
 {
    void *ctx = state;
    if (to->base_type == from->type->base_type)
       return true;
 
-   /* This conversion was added in GLSL 1.20.  If the compilation mode is
-    * GLSL 1.10, the conversion is skipped.
-    */
+   /* Prior to GLSL 1.20, there are no implicit conversions */
    if (!state->is_version(120, 0))
       return false;
 
@@ -186,43 +228,32 @@ apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from,
     *
     *    "There are no implicit array or structure conversions. For
     *    example, an array of int cannot be implicitly converted to an
-    *    array of float. There are no implicit conversions between
-    *    signed and unsigned integers."
-    */
-   /* FINISHME: The above comment is partially a lie.  There is int/uint
-    * FINISHME: conversion for immediate constants.
+    *    array of float.
     */
-   if (!to->is_float() || !from->type->is_numeric())
+   if (!to->is_numeric() || !from->type->is_numeric())
       return false;
 
-   /* Convert to a floating point type with the same number of components
-    * as the original type - i.e. int to float, not int to vec4.
+   /* We don't actually want the specific type `to`, we want a type
+    * with the same base type as `to`, but the same vector width as
+    * `from`.
     */
-   to = glsl_type::get_instance(GLSL_TYPE_FLOAT, from->type->vector_elements,
-                               from->type->matrix_columns);
+   to = glsl_type::get_instance(to->base_type, from->type->vector_elements,
+                                from->type->matrix_columns);
 
-   switch (from->type->base_type) {
-   case GLSL_TYPE_INT:
-      from = new(ctx) ir_expression(ir_unop_i2f, to, from, NULL);
-      break;
-   case GLSL_TYPE_UINT:
-      from = new(ctx) ir_expression(ir_unop_u2f, to, from, NULL);
-      break;
-   case GLSL_TYPE_BOOL:
-      from = new(ctx) ir_expression(ir_unop_b2f, to, from, NULL);
-      break;
-   default:
-      assert(0);
+   ir_expression_operation op = get_conversion_operation(to, from->type, state);
+   if (op) {
+      from = new(ctx) ir_expression(op, to, from, NULL);
+      return true;
+   } else {
+      return false;
    }
-
-   return true;
 }
 
 
 static const struct glsl_type *
 arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
-                      bool multiply,
-                      struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+                       bool multiply,
+                       struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
 {
    const glsl_type *type_a = value_a->type;
    const glsl_type *type_b = value_b->type;
@@ -235,7 +266,7 @@ arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
     */
    if (!type_a->is_numeric() || !type_b->is_numeric()) {
       _mesa_glsl_error(loc, state,
-                      "operands to arithmetic operators must be numeric");
+                       "operands to arithmetic operators must be numeric");
       return glsl_type::error_type;
    }
 
@@ -247,8 +278,8 @@ arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
    if (!apply_implicit_conversion(type_a, value_b, state)
        && !apply_implicit_conversion(type_b, value_a, state)) {
       _mesa_glsl_error(loc, state,
-                      "could not implicitly convert operands to "
-                      "arithmetic operator");
+                       "could not implicitly convert operands to "
+                       "arithmetic operator");
       return glsl_type::error_type;
    }
    type_a = value_a->type;
@@ -265,7 +296,7 @@ arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
     */
    if (type_a->base_type != type_b->base_type) {
       _mesa_glsl_error(loc, state,
-                      "base type mismatch for arithmetic operator");
+                       "base type mismatch for arithmetic operator");
       return glsl_type::error_type;
    }
 
@@ -287,7 +318,7 @@ arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
     */
    if (type_a->is_scalar()) {
       if (!type_b->is_scalar())
-        return type_b;
+         return type_b;
    } else if (type_b->is_scalar()) {
       return type_a;
    }
@@ -305,11 +336,11 @@ arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
     */
    if (type_a->is_vector() && type_b->is_vector()) {
       if (type_a == type_b) {
-        return type_a;
+         return type_a;
       } else {
-        _mesa_glsl_error(loc, state,
-                         "vector size mismatch for arithmetic operator");
-        return glsl_type::error_type;
+         _mesa_glsl_error(loc, state,
+                          "vector size mismatch for arithmetic operator");
+         return glsl_type::error_type;
       }
    }
 
@@ -320,8 +351,10 @@ arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
     * type of both operands must be float.
     */
    assert(type_a->is_matrix() || type_b->is_matrix());
-   assert(type_a->base_type == GLSL_TYPE_FLOAT);
-   assert(type_b->base_type == GLSL_TYPE_FLOAT);
+   assert(type_a->base_type == GLSL_TYPE_FLOAT ||
+          type_a->base_type == GLSL_TYPE_DOUBLE);
+   assert(type_b->base_type == GLSL_TYPE_FLOAT ||
+          type_b->base_type == GLSL_TYPE_DOUBLE);
 
    /*   "* The operator is add (+), subtract (-), or divide (/), and the
     *      operands are matrices with the same number of rows and the same
@@ -340,64 +373,64 @@ arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
     */
    if (! multiply) {
       if (type_a == type_b)
-        return type_a;
+         return type_a;
    } else {
       if (type_a->is_matrix() && type_b->is_matrix()) {
-        /* Matrix multiply.  The columns of A must match the rows of B.  Given
-         * the other previously tested constraints, this means the vector type
-         * of a row from A must be the same as the vector type of a column from
-         * B.
-         */
-        if (type_a->row_type() == type_b->column_type()) {
-           /* The resulting matrix has the number of columns of matrix B and
-            * the number of rows of matrix A.  We get the row count of A by
-            * looking at the size of a vector that makes up a column.  The
-            * transpose (size of a row) is done for B.
-            */
-           const glsl_type *const type =
-              glsl_type::get_instance(type_a->base_type,
-                                      type_a->column_type()->vector_elements,
-                                      type_b->row_type()->vector_elements);
-           assert(type != glsl_type::error_type);
-
-           return type;
-        }
+         /* Matrix multiply.  The columns of A must match the rows of B.  Given
+          * the other previously tested constraints, this means the vector type
+          * of a row from A must be the same as the vector type of a column from
+          * B.
+          */
+         if (type_a->row_type() == type_b->column_type()) {
+            /* The resulting matrix has the number of columns of matrix B and
+             * the number of rows of matrix A.  We get the row count of A by
+             * looking at the size of a vector that makes up a column.  The
+             * transpose (size of a row) is done for B.
+             */
+            const glsl_type *const type =
+               glsl_type::get_instance(type_a->base_type,
+                                       type_a->column_type()->vector_elements,
+                                       type_b->row_type()->vector_elements);
+            assert(type != glsl_type::error_type);
+
+            return type;
+         }
       } else if (type_a->is_matrix()) {
-        /* A is a matrix and B is a column vector.  Columns of A must match
-         * rows of B.  Given the other previously tested constraints, this
-         * means the vector type of a row from A must be the same as the
-         * vector the type of B.
-         */
-        if (type_a->row_type() == type_b) {
-           /* The resulting vector has a number of elements equal to
-            * the number of rows of matrix A. */
-           const glsl_type *const type =
-              glsl_type::get_instance(type_a->base_type,
-                                      type_a->column_type()->vector_elements,
-                                      1);
-           assert(type != glsl_type::error_type);
-
-           return type;
-        }
+         /* A is a matrix and B is a column vector.  Columns of A must match
+          * rows of B.  Given the other previously tested constraints, this
+          * means the vector type of a row from A must be the same as the
+          * vector the type of B.
+          */
+         if (type_a->row_type() == type_b) {
+            /* The resulting vector has a number of elements equal to
+             * the number of rows of matrix A. */
+            const glsl_type *const type =
+               glsl_type::get_instance(type_a->base_type,
+                                       type_a->column_type()->vector_elements,
+                                       1);
+            assert(type != glsl_type::error_type);
+
+            return type;
+         }
       } else {
-        assert(type_b->is_matrix());
-
-        /* A is a row vector and B is a matrix.  Columns of A must match rows
-         * of B.  Given the other previously tested constraints, this means
-         * the type of A must be the same as the vector type of a column from
-         * B.
-         */
-        if (type_a == type_b->column_type()) {
-           /* The resulting vector has a number of elements equal to
-            * the number of columns of matrix B. */
-           const glsl_type *const type =
-              glsl_type::get_instance(type_a->base_type,
-                                      type_b->row_type()->vector_elements,
-                                      1);
-           assert(type != glsl_type::error_type);
-
-           return type;
-        }
+         assert(type_b->is_matrix());
+
+         /* A is a row vector and B is a matrix.  Columns of A must match rows
+          * of B.  Given the other previously tested constraints, this means
+          * the type of A must be the same as the vector type of a column from
+          * B.
+          */
+         if (type_a == type_b->column_type()) {
+            /* The resulting vector has a number of elements equal to
+             * the number of columns of matrix B. */
+            const glsl_type *const type =
+               glsl_type::get_instance(type_a->base_type,
+                                       type_b->row_type()->vector_elements,
+                                       1);
+            assert(type != glsl_type::error_type);
+
+            return type;
+         }
       }
 
       _mesa_glsl_error(loc, state, "size mismatch for matrix multiplication");
@@ -414,7 +447,7 @@ arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
 
 static const struct glsl_type *
 unary_arithmetic_result_type(const struct glsl_type *type,
-                            struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+                             struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
 {
    /* From GLSL 1.50 spec, page 57:
     *
@@ -426,7 +459,7 @@ unary_arithmetic_result_type(const struct glsl_type *type,
     */
    if (!type->is_numeric()) {
       _mesa_glsl_error(loc, state,
-                      "operands to arithmetic operators must be numeric");
+                       "operands to arithmetic operators must be numeric");
       return glsl_type::error_type;
    }
 
@@ -500,8 +533,8 @@ bit_logic_result_type(const struct glsl_type *type_a,
 
 static const struct glsl_type *
 modulus_result_type(const struct glsl_type *type_a,
-                   const struct glsl_type *type_b,
-                   struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+                    const struct glsl_type *type_b,
+                    struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
 {
    if (!state->check_version(130, 300, loc, "operator '%%' is reserved")) {
       return glsl_type::error_type;
@@ -522,7 +555,7 @@ modulus_result_type(const struct glsl_type *type_a,
    }
    if (type_a->base_type != type_b->base_type) {
       _mesa_glsl_error(loc, state,
-                      "operands of %% must have the same base type");
+                       "operands of %% must have the same base type");
       return glsl_type::error_type;
    }
 
@@ -533,8 +566,8 @@ modulus_result_type(const struct glsl_type *type_a,
     */
    if (type_a->is_vector()) {
       if (!type_b->is_vector()
-         || (type_a->vector_elements == type_b->vector_elements))
-        return type_a;
+          || (type_a->vector_elements == type_b->vector_elements))
+      return type_a;
    } else
       return type_b;
 
@@ -548,7 +581,7 @@ modulus_result_type(const struct glsl_type *type_a,
 
 static const struct glsl_type *
 relational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
-                      struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+                       struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
 {
    const glsl_type *type_a = value_a->type;
    const glsl_type *type_b = value_b->type;
@@ -563,8 +596,8 @@ relational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
        || !type_a->is_scalar()
        || !type_b->is_scalar()) {
       _mesa_glsl_error(loc, state,
-                      "operands to relational operators must be scalar and "
-                      "numeric");
+                       "operands to relational operators must be scalar and "
+                       "numeric");
       return glsl_type::error_type;
    }
 
@@ -575,8 +608,8 @@ relational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
    if (!apply_implicit_conversion(type_a, value_b, state)
        && !apply_implicit_conversion(type_b, value_a, state)) {
       _mesa_glsl_error(loc, state,
-                      "could not implicitly convert operands to "
-                      "relational operator");
+                       "could not implicitly convert operands to "
+                       "relational operator");
       return glsl_type::error_type;
    }
    type_a = value_a->type;
@@ -619,13 +652,13 @@ shift_result_type(const struct glsl_type *type_a,
     */
    if (!type_a->is_integer()) {
       _mesa_glsl_error(loc, state, "LHS of operator %s must be an integer or "
-              "integer vector", ast_expression::operator_string(op));
+                       "integer vector", ast_expression::operator_string(op));
      return glsl_type::error_type;
 
    }
    if (!type_b->is_integer()) {
       _mesa_glsl_error(loc, state, "RHS of operator %s must be an integer or "
-              "integer vector", ast_expression::operator_string(op));
+                       "integer vector", ast_expression::operator_string(op));
      return glsl_type::error_type;
    }
 
@@ -634,8 +667,8 @@ shift_result_type(const struct glsl_type *type_a,
     */
    if (type_a->is_scalar() && !type_b->is_scalar()) {
       _mesa_glsl_error(loc, state, "if the first operand of %s is scalar, the "
-              "second must be scalar as well",
-              ast_expression::operator_string(op));
+                       "second must be scalar as well",
+                       ast_expression::operator_string(op));
      return glsl_type::error_type;
    }
 
@@ -646,8 +679,8 @@ shift_result_type(const struct glsl_type *type_a,
       type_b->is_vector() &&
       type_a->vector_elements != type_b->vector_elements) {
       _mesa_glsl_error(loc, state, "vector operands to operator %s must "
-              "have same number of elements",
-              ast_expression::operator_string(op));
+                       "have same number of elements",
+                       ast_expression::operator_string(op));
      return glsl_type::error_type;
    }
 
@@ -728,26 +761,29 @@ mark_whole_array_access(ir_rvalue *access)
    ir_dereference_variable *deref = access->as_dereference_variable();
 
    if (deref && deref->var) {
-      deref->var->max_array_access = deref->type->length - 1;
+      deref->var->data.max_array_access = deref->type->length - 1;
    }
 }
 
-ir_rvalue *
+static bool
 do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
-             const char *non_lvalue_description,
-             ir_rvalue *lhs, ir_rvalue *rhs, bool is_initializer,
-             YYLTYPE lhs_loc)
+              const char *non_lvalue_description,
+              ir_rvalue *lhs, ir_rvalue *rhs,
+              ir_rvalue **out_rvalue, bool needs_rvalue,
+              bool is_initializer,
+              YYLTYPE lhs_loc)
 {
    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,48 +791,58 @@ 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);
          }
       }
    }
 
    ir_variable *lhs_var = lhs->variable_referenced();
    if (lhs_var)
-      lhs_var->assigned = true;
+      lhs_var->data.assigned = true;
 
    if (!error_emitted) {
       if (non_lvalue_description != NULL) {
          _mesa_glsl_error(&lhs_loc, state,
                           "assignment to %s",
-                         non_lvalue_description);
-        error_emitted = true;
-      } else if (lhs->variable_referenced() != NULL
-                && lhs->variable_referenced()->read_only) {
+                          non_lvalue_description);
+         error_emitted = true;
+      } else if (lhs_var != NULL && lhs_var->data.read_only) {
          _mesa_glsl_error(&lhs_loc, state,
                           "assignment to read-only variable '%s'",
-                          lhs->variable_referenced()->name);
+                          lhs_var->name);
          error_emitted = true;
-
       } else if (lhs->type->is_array() &&
                  !state->check_version(120, 300, &lhs_loc,
                                        "whole array assignment forbidden")) {
-        /* From page 32 (page 38 of the PDF) of the GLSL 1.10 spec:
-         *
-         *    "Other binary or unary expressions, non-dereferenced
-         *     arrays, function names, swizzles with repeated fields,
-         *     and constants cannot be l-values."
+         /* From page 32 (page 38 of the PDF) of the GLSL 1.10 spec:
+          *
+          *    "Other binary or unary expressions, non-dereferenced
+          *     arrays, function names, swizzles with repeated fields,
+          *     and constants cannot be l-values."
           *
           * The restriction on arrays is lifted in GLSL 1.20 and GLSL ES 3.00.
-         */
-        error_emitted = true;
+          */
+         error_emitted = true;
       } else if (!lhs->is_lvalue()) {
-        _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment");
-        error_emitted = true;
+         _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment");
+         error_emitted = true;
       }
    }
 
@@ -811,27 +857,29 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
        * is either not an l-value or not a whole array.
        */
       if (lhs->type->is_unsized_array()) {
-        ir_dereference *const d = lhs->as_dereference();
+         ir_dereference *const d = lhs->as_dereference();
 
-        assert(d != NULL);
+         assert(d != NULL);
 
-        ir_variable *const var = d->variable_referenced();
+         ir_variable *const var = d->variable_referenced();
 
-        assert(var != NULL);
+         assert(var != NULL);
 
-        if (var->max_array_access >= unsigned(rhs->type->array_size())) {
-           /* FINISHME: This should actually log the location of the RHS. */
-           _mesa_glsl_error(& lhs_loc, state, "array size must be > %u due to "
-                            "previous access",
-                            var->max_array_access);
-        }
+         if (var->data.max_array_access >= unsigned(rhs->type->array_size())) {
+            /* FINISHME: This should actually log the location of the RHS. */
+            _mesa_glsl_error(& lhs_loc, state, "array size must be > %u due to "
+                             "previous access",
+                             var->data.max_array_access);
+         }
 
-        var->type = glsl_type::get_array_instance(lhs->type->element_type(),
-                                                  rhs->type->array_size());
-        d->type = var->type;
+         var->type = glsl_type::get_array_instance(lhs->type->element_type(),
+                                                   rhs->type->array_size());
+         d->type = var->type;
+      }
+      if (lhs->type->is_array()) {
+         mark_whole_array_access(rhs);
+         mark_whole_array_access(lhs);
       }
-      mark_whole_array_access(rhs);
-      mark_whole_array_access(lhs);
    }
 
    /* Most callers of do_assignment (assign, add_assign, pre_inc/dec,
@@ -839,22 +887,33 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
     * to handle things like:
     *
     * i = j += 1;
-    *
-    * So we always just store the computed value being assigned to a
-    * temporary and return a deref of that temporary.  If the rvalue
-    * ends up not being used, the temp will get copy-propagated out.
     */
-   ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp",
-                                          ir_var_temporary);
-   ir_dereference_variable *deref_var = new(ctx) ir_dereference_variable(var);
-   instructions->push_tail(var);
-   instructions->push_tail(new(ctx) ir_assignment(deref_var, rhs));
-   deref_var = new(ctx) ir_dereference_variable(var);
+   if (needs_rvalue) {
+      ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp",
+                                              ir_var_temporary);
+      instructions->push_tail(var);
+      instructions->push_tail(assign(var, rhs));
+
+      if (!error_emitted) {
+         ir_dereference_variable *deref_var = new(ctx) ir_dereference_variable(var);
+         instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var));
+      }
+      ir_rvalue *rvalue = new(ctx) ir_dereference_variable(var);
 
-   if (!error_emitted)
-      instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var));
+      if (extract_channel) {
+         rvalue = new(ctx) ir_expression(ir_binop_vector_extract,
+                                         rvalue,
+                                         extract_channel->clone(ctx, NULL));
+      }
 
-   return new(ctx) ir_dereference_variable(var);
+      *out_rvalue = rvalue;
+   } else {
+      if (!error_emitted)
+         instructions->push_tail(new(ctx) ir_assignment(lhs, rhs));
+      *out_rvalue = NULL;
+   }
+
+   return error_emitted;
 }
 
 static ir_rvalue *
@@ -866,7 +925,6 @@ get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue)
    var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp",
                              ir_var_temporary);
    instructions->push_tail(var);
-   var->mode = ir_var_auto;
 
    instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
                                                  lvalue));
@@ -876,8 +934,7 @@ get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue)
 
 
 ir_rvalue *
-ast_node::hir(exec_list *instructions,
-             struct _mesa_glsl_parse_state *state)
+ast_node::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
 {
    (void) instructions;
    (void) state;
@@ -885,6 +942,20 @@ ast_node::hir(exec_list *instructions,
    return NULL;
 }
 
+void
+ast_function_expression::hir_no_rvalue(exec_list *instructions,
+                                       struct _mesa_glsl_parse_state *state)
+{
+   (void)hir(instructions, state);
+}
+
+void
+ast_aggregate_initializer::hir_no_rvalue(exec_list *instructions,
+                                         struct _mesa_glsl_parse_state *state)
+{
+   (void)hir(instructions, state);
+}
+
 static ir_rvalue *
 do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
 {
@@ -901,23 +972,24 @@ do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
    case GLSL_TYPE_UINT:
    case GLSL_TYPE_INT:
    case GLSL_TYPE_BOOL:
+   case GLSL_TYPE_DOUBLE:
       return new(mem_ctx) ir_expression(operation, op0, op1);
 
    case GLSL_TYPE_ARRAY: {
       for (unsigned int i = 0; i < op0->type->length; i++) {
-        ir_rvalue *e0, *e1, *result;
-
-        e0 = new(mem_ctx) ir_dereference_array(op0->clone(mem_ctx, NULL),
-                                               new(mem_ctx) ir_constant(i));
-        e1 = new(mem_ctx) ir_dereference_array(op1->clone(mem_ctx, NULL),
-                                               new(mem_ctx) ir_constant(i));
-        result = do_comparison(mem_ctx, operation, e0, e1);
-
-        if (cmp) {
-           cmp = new(mem_ctx) ir_expression(join_op, cmp, result);
-        } else {
-           cmp = result;
-        }
+         ir_rvalue *e0, *e1, *result;
+
+         e0 = new(mem_ctx) ir_dereference_array(op0->clone(mem_ctx, NULL),
+                                                new(mem_ctx) ir_constant(i));
+         e1 = new(mem_ctx) ir_dereference_array(op1->clone(mem_ctx, NULL),
+                                                new(mem_ctx) ir_constant(i));
+         result = do_comparison(mem_ctx, operation, e0, e1);
+
+         if (cmp) {
+            cmp = new(mem_ctx) ir_expression(join_op, cmp, result);
+         } else {
+            cmp = result;
+         }
       }
 
       mark_whole_array_access(op0);
@@ -927,20 +999,20 @@ do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
 
    case GLSL_TYPE_STRUCT: {
       for (unsigned int i = 0; i < op0->type->length; i++) {
-        ir_rvalue *e0, *e1, *result;
-        const char *field_name = op0->type->fields.structure[i].name;
-
-        e0 = new(mem_ctx) ir_dereference_record(op0->clone(mem_ctx, NULL),
-                                                field_name);
-        e1 = new(mem_ctx) ir_dereference_record(op1->clone(mem_ctx, NULL),
-                                                field_name);
-        result = do_comparison(mem_ctx, operation, e0, e1);
-
-        if (cmp) {
-           cmp = new(mem_ctx) ir_expression(join_op, cmp, result);
-        } else {
-           cmp = result;
-        }
+         ir_rvalue *e0, *e1, *result;
+         const char *field_name = op0->type->fields.structure[i].name;
+
+         e0 = new(mem_ctx) ir_dereference_record(op0->clone(mem_ctx, NULL),
+                                                 field_name);
+         e1 = new(mem_ctx) ir_dereference_record(op1->clone(mem_ctx, NULL),
+                                                 field_name);
+         result = do_comparison(mem_ctx, operation, e0, e1);
+
+         if (cmp) {
+            cmp = new(mem_ctx) ir_expression(join_op, cmp, result);
+         } else {
+            cmp = result;
+         }
       }
       break;
    }
@@ -948,6 +1020,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
@@ -984,8 +1057,8 @@ get_scalar_boolean_operand(exec_list *instructions,
    if (!*error_emitted) {
       YYLTYPE loc = expr->get_location();
       _mesa_glsl_error(&loc, state, "%s of `%s' must be scalar boolean",
-                      operand_name,
-                      parent_expr->operator_string(parent_expr->oper));
+                       operand_name,
+                       parent_expr->operator_string(parent_expr->oper));
       *error_emitted = true;
    }
 
@@ -1051,7 +1124,22 @@ constant_one_for_inc_dec(void *ctx, const glsl_type *type)
 
 ir_rvalue *
 ast_expression::hir(exec_list *instructions,
-                   struct _mesa_glsl_parse_state *state)
+                    struct _mesa_glsl_parse_state *state)
+{
+   return do_hir(instructions, state, true);
+}
+
+void
+ast_expression::hir_no_rvalue(exec_list *instructions,
+                              struct _mesa_glsl_parse_state *state)
+{
+   do_hir(instructions, state, false);
+}
+
+ir_rvalue *
+ast_expression::do_hir(exec_list *instructions,
+                       struct _mesa_glsl_parse_state *state,
+                       bool needs_rvalue)
 {
    void *ctx = state;
    static const int operations[AST_NUM_OPERATORS] = {
@@ -1119,18 +1207,18 @@ ast_expression::hir(exec_list *instructions,
 
    switch (this->oper) {
    case ast_aggregate:
-         assert(!"ast_aggregate: Should never get here.");
-         break;
+      assert(!"ast_aggregate: Should never get here.");
+      break;
 
    case ast_assign: {
       op[0] = this->subexpressions[0]->hir(instructions, state);
       op[1] = this->subexpressions[1]->hir(instructions, state);
 
-      result = do_assignment(instructions, state,
-                            this->subexpressions[0]->non_lvalue_description,
-                            op[0], op[1], false,
-                            this->subexpressions[0]->get_location());
-      error_emitted = result->type->is_error();
+      error_emitted =
+         do_assignment(instructions, state,
+                       this->subexpressions[0]->non_lvalue_description,
+                       op[0], op[1], &result, needs_rvalue, false,
+                       this->subexpressions[0]->get_location());
       break;
    }
 
@@ -1152,7 +1240,7 @@ ast_expression::hir(exec_list *instructions,
       error_emitted = type->is_error();
 
       result = new(ctx) ir_expression(operations[this->oper], type,
-                                     op[0], NULL);
+                                      op[0], NULL);
       break;
 
    case ast_add:
@@ -1163,12 +1251,12 @@ ast_expression::hir(exec_list *instructions,
       op[1] = this->subexpressions[1]->hir(instructions, state);
 
       type = arithmetic_result_type(op[0], op[1],
-                                   (this->oper == ast_mul),
-                                   state, & loc);
+                                    (this->oper == ast_mul),
+                                    state, & loc);
       error_emitted = type->is_error();
 
       result = new(ctx) ir_expression(operations[this->oper], type,
-                                     op[0], op[1]);
+                                      op[0], op[1]);
       break;
 
    case ast_mod:
@@ -1180,7 +1268,7 @@ ast_expression::hir(exec_list *instructions,
       assert(operations[this->oper] == ir_binop_mod);
 
       result = new(ctx) ir_expression(operations[this->oper], type,
-                                     op[0], op[1]);
+                                      op[0], op[1]);
       error_emitted = type->is_error();
       break;
 
@@ -1216,7 +1304,7 @@ ast_expression::hir(exec_list *instructions,
                 && type->is_scalar()));
 
       result = new(ctx) ir_expression(operations[this->oper], type,
-                                     op[0], op[1]);
+                                      op[0], op[1]);
       error_emitted = type->is_error();
       break;
 
@@ -1235,15 +1323,15 @@ ast_expression::hir(exec_list *instructions,
        *    case this conversion is done."
        */
       if ((!apply_implicit_conversion(op[0]->type, op[1], state)
-          && !apply_implicit_conversion(op[1]->type, op[0], state))
-         || (op[0]->type != op[1]->type)) {
-        _mesa_glsl_error(& loc, state, "operands of `%s' must have the same "
-                         "type", (this->oper == ast_equal) ? "==" : "!=");
-        error_emitted = true;
+           && !apply_implicit_conversion(op[1]->type, op[0], state))
+          || (op[0]->type != op[1]->type)) {
+         _mesa_glsl_error(& loc, state, "operands of `%s' must have the same "
+                          "type", (this->oper == ast_equal) ? "==" : "!=");
+         error_emitted = true;
       } else if ((op[0]->type->is_array() || op[1]->type->is_array()) &&
                  !state->check_version(120, 300, &loc,
                                        "array comparisons forbidden")) {
-        error_emitted = true;
+         error_emitted = true;
       } else if ((op[0]->type->contains_opaque() ||
                   op[1]->type->contains_opaque())) {
          _mesa_glsl_error(&loc, state, "opaque type comparisons forbidden");
@@ -1251,10 +1339,10 @@ ast_expression::hir(exec_list *instructions,
       }
 
       if (error_emitted) {
-        result = new(ctx) ir_constant(false);
+         result = new(ctx) ir_constant(false);
       } else {
-        result = do_comparison(ctx, operations[this->oper], op[0], op[1]);
-        assert(result->type == glsl_type::bool_type);
+         result = do_comparison(ctx, operations[this->oper], op[0], op[1]);
+         assert(result->type == glsl_type::bool_type);
       }
       break;
 
@@ -1266,7 +1354,7 @@ ast_expression::hir(exec_list *instructions,
       type = bit_logic_result_type(op[0]->type, op[1]->type, this->oper,
                                    state, &loc);
       result = new(ctx) ir_expression(operations[this->oper], type,
-                                     op[0], op[1]);
+                                      op[0], op[1]);
       error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
       break;
 
@@ -1274,12 +1362,12 @@ ast_expression::hir(exec_list *instructions,
       op[0] = this->subexpressions[0]->hir(instructions, state);
 
       if (!state->check_bitwise_operations_allowed(&loc)) {
-        error_emitted = true;
+         error_emitted = true;
       }
 
       if (!op[0]->type->is_integer()) {
-        _mesa_glsl_error(&loc, state, "operand of `~' must be an integer");
-        error_emitted = true;
+         _mesa_glsl_error(&loc, state, "operand of `~' must be an integer");
+         error_emitted = true;
       }
 
       type = error_emitted ? glsl_type::error_type : op[0]->type;
@@ -1289,35 +1377,35 @@ ast_expression::hir(exec_list *instructions,
    case ast_logic_and: {
       exec_list rhs_instructions;
       op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
-                                        "LHS", &error_emitted);
+                                         "LHS", &error_emitted);
       op[1] = get_scalar_boolean_operand(&rhs_instructions, state, this, 1,
-                                        "RHS", &error_emitted);
+                                         "RHS", &error_emitted);
 
       if (rhs_instructions.is_empty()) {
-        result = new(ctx) ir_expression(ir_binop_logic_and, op[0], op[1]);
-        type = result->type;
+         result = new(ctx) ir_expression(ir_binop_logic_and, op[0], op[1]);
+         type = result->type;
       } else {
-        ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
-                                                      "and_tmp",
-                                                      ir_var_temporary);
-        instructions->push_tail(tmp);
-
-        ir_if *const stmt = new(ctx) ir_if(op[0]);
-        instructions->push_tail(stmt);
-
-        stmt->then_instructions.append_list(&rhs_instructions);
-        ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
-        ir_assignment *const then_assign =
-           new(ctx) ir_assignment(then_deref, op[1]);
-        stmt->then_instructions.push_tail(then_assign);
-
-        ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
-        ir_assignment *const else_assign =
-           new(ctx) ir_assignment(else_deref, new(ctx) ir_constant(false));
-        stmt->else_instructions.push_tail(else_assign);
-
-        result = new(ctx) ir_dereference_variable(tmp);
-        type = tmp->type;
+         ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
+                                                       "and_tmp",
+                                                       ir_var_temporary);
+         instructions->push_tail(tmp);
+
+         ir_if *const stmt = new(ctx) ir_if(op[0]);
+         instructions->push_tail(stmt);
+
+         stmt->then_instructions.append_list(&rhs_instructions);
+         ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
+         ir_assignment *const then_assign =
+            new(ctx) ir_assignment(then_deref, op[1]);
+         stmt->then_instructions.push_tail(then_assign);
+
+         ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
+         ir_assignment *const else_assign =
+            new(ctx) ir_assignment(else_deref, new(ctx) ir_constant(false));
+         stmt->else_instructions.push_tail(else_assign);
+
+         result = new(ctx) ir_dereference_variable(tmp);
+         type = tmp->type;
       }
       break;
    }
@@ -1325,35 +1413,35 @@ ast_expression::hir(exec_list *instructions,
    case ast_logic_or: {
       exec_list rhs_instructions;
       op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
-                                        "LHS", &error_emitted);
+                                         "LHS", &error_emitted);
       op[1] = get_scalar_boolean_operand(&rhs_instructions, state, this, 1,
-                                        "RHS", &error_emitted);
+                                         "RHS", &error_emitted);
 
       if (rhs_instructions.is_empty()) {
-        result = new(ctx) ir_expression(ir_binop_logic_or, op[0], op[1]);
-        type = result->type;
+         result = new(ctx) ir_expression(ir_binop_logic_or, op[0], op[1]);
+         type = result->type;
       } else {
-        ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
-                                                      "or_tmp",
-                                                      ir_var_temporary);
-        instructions->push_tail(tmp);
-
-        ir_if *const stmt = new(ctx) ir_if(op[0]);
-        instructions->push_tail(stmt);
-
-        ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
-        ir_assignment *const then_assign =
-           new(ctx) ir_assignment(then_deref, new(ctx) ir_constant(true));
-        stmt->then_instructions.push_tail(then_assign);
-
-        stmt->else_instructions.append_list(&rhs_instructions);
-        ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
-        ir_assignment *const else_assign =
-           new(ctx) ir_assignment(else_deref, op[1]);
-        stmt->else_instructions.push_tail(else_assign);
-
-        result = new(ctx) ir_dereference_variable(tmp);
-        type = tmp->type;
+         ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
+                                                       "or_tmp",
+                                                       ir_var_temporary);
+         instructions->push_tail(tmp);
+
+         ir_if *const stmt = new(ctx) ir_if(op[0]);
+         instructions->push_tail(stmt);
+
+         ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
+         ir_assignment *const then_assign =
+            new(ctx) ir_assignment(then_deref, new(ctx) ir_constant(true));
+         stmt->then_instructions.push_tail(then_assign);
+
+         stmt->else_instructions.append_list(&rhs_instructions);
+         ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
+         ir_assignment *const else_assign =
+            new(ctx) ir_assignment(else_deref, op[1]);
+         stmt->else_instructions.push_tail(else_assign);
+
+         result = new(ctx) ir_dereference_variable(tmp);
+         type = tmp->type;
       }
       break;
    }
@@ -1366,20 +1454,20 @@ ast_expression::hir(exec_list *instructions,
        *     expressions and result in a Boolean expression."
        */
       op[0] = get_scalar_boolean_operand(instructions, state, this, 0, "LHS",
-                                        &error_emitted);
+                                         &error_emitted);
       op[1] = get_scalar_boolean_operand(instructions, state, this, 1, "RHS",
-                                        &error_emitted);
+                                         &error_emitted);
 
       result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
-                                     op[0], op[1]);
+                                      op[0], op[1]);
       break;
 
    case ast_logic_not:
       op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
-                                        "operand", &error_emitted);
+                                         "operand", &error_emitted);
 
       result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
-                                     op[0], NULL);
+                                      op[0], NULL);
       break;
 
    case ast_mul_assign:
@@ -1390,17 +1478,18 @@ ast_expression::hir(exec_list *instructions,
       op[1] = this->subexpressions[1]->hir(instructions, state);
 
       type = arithmetic_result_type(op[0], op[1],
-                                   (this->oper == ast_mul_assign),
-                                   state, & loc);
+                                    (this->oper == ast_mul_assign),
+                                    state, & loc);
 
       ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
-                                                  op[0], op[1]);
+                                                   op[0], op[1]);
 
-      result = do_assignment(instructions, state,
-                            this->subexpressions[0]->non_lvalue_description,
-                            op[0]->clone(ctx, NULL), temp_rhs, false,
-                            this->subexpressions[0]->get_location());
-      error_emitted = (op[0]->type->is_error());
+      error_emitted =
+         do_assignment(instructions, state,
+                       this->subexpressions[0]->non_lvalue_description,
+                       op[0]->clone(ctx, NULL), temp_rhs,
+                       &result, needs_rvalue, false,
+                       this->subexpressions[0]->get_location());
 
       /* GLSL 1.10 does not allow array assignment.  However, we don't have to
        * explicitly test for this because none of the binary expression
@@ -1420,13 +1509,14 @@ ast_expression::hir(exec_list *instructions,
 
       ir_rvalue *temp_rhs;
       temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
-                                       op[0], op[1]);
-
-      result = do_assignment(instructions, state,
-                            this->subexpressions[0]->non_lvalue_description,
-                            op[0]->clone(ctx, NULL), temp_rhs, false,
-                            this->subexpressions[0]->get_location());
-      error_emitted = type->is_error();
+                                        op[0], op[1]);
+
+      error_emitted =
+         do_assignment(instructions, state,
+                       this->subexpressions[0]->non_lvalue_description,
+                       op[0]->clone(ctx, NULL), temp_rhs,
+                       &result, needs_rvalue, false,
+                       this->subexpressions[0]->get_location());
       break;
    }
 
@@ -1438,11 +1528,12 @@ ast_expression::hir(exec_list *instructions,
                                &loc);
       ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper],
                                                    type, op[0], op[1]);
-      result = do_assignment(instructions, state,
-                            this->subexpressions[0]->non_lvalue_description,
-                            op[0]->clone(ctx, NULL), temp_rhs, false,
-                             this->subexpressions[0]->get_location());
-      error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
+      error_emitted =
+         do_assignment(instructions, state,
+                       this->subexpressions[0]->non_lvalue_description,
+                       op[0]->clone(ctx, NULL), temp_rhs,
+                       &result, needs_rvalue, false,
+                       this->subexpressions[0]->get_location());
       break;
    }
 
@@ -1455,11 +1546,12 @@ ast_expression::hir(exec_list *instructions,
                                    state, &loc);
       ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper],
                                                    type, op[0], op[1]);
-      result = do_assignment(instructions, state,
-                            this->subexpressions[0]->non_lvalue_description,
-                            op[0]->clone(ctx, NULL), temp_rhs, false,
-                             this->subexpressions[0]->get_location());
-      error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
+      error_emitted =
+         do_assignment(instructions, state,
+                       this->subexpressions[0]->non_lvalue_description,
+                       op[0]->clone(ctx, NULL), temp_rhs,
+                       &result, needs_rvalue, false,
+                       this->subexpressions[0]->get_location());
       break;
    }
 
@@ -1471,7 +1563,7 @@ ast_expression::hir(exec_list *instructions,
        *    first expression, which must result in a scalar Boolean."
        */
       op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
-                                        "condition", &error_emitted);
+                                         "condition", &error_emitted);
 
       /* The :? operator is implemented by generating an anonymous temporary
        * followed by an if-statement.  The last instruction in each branch of
@@ -1494,16 +1586,16 @@ ast_expression::hir(exec_list *instructions,
        *     expression."
        */
       if ((!apply_implicit_conversion(op[1]->type, op[2], state)
-          && !apply_implicit_conversion(op[2]->type, op[1], state))
-         || (op[1]->type != op[2]->type)) {
-        YYLTYPE loc = this->subexpressions[1]->get_location();
-
-        _mesa_glsl_error(& loc, state, "second and third operands of ?: "
-                         "operator must have matching types");
-        error_emitted = true;
-        type = glsl_type::error_type;
+          && !apply_implicit_conversion(op[2]->type, op[1], state))
+          || (op[1]->type != op[2]->type)) {
+         YYLTYPE loc = this->subexpressions[1]->get_location();
+
+         _mesa_glsl_error(& loc, state, "second and third operands of ?: "
+                          "operator must have matching types");
+         error_emitted = true;
+         type = glsl_type::error_type;
       } else {
-        type = op[1]->type;
+         type = op[1]->type;
       }
 
       /* From page 33 (page 39 of the PDF) of the GLSL 1.10 spec:
@@ -1515,40 +1607,38 @@ ast_expression::hir(exec_list *instructions,
           !state->check_version(120, 300, &loc,
                                 "second and third operands of ?: operator "
                                 "cannot be arrays")) {
-        error_emitted = true;
+         error_emitted = true;
       }
 
       ir_constant *cond_val = op[0]->constant_expression_value();
-      ir_constant *then_val = op[1]->constant_expression_value();
-      ir_constant *else_val = op[2]->constant_expression_value();
 
       if (then_instructions.is_empty()
-         && else_instructions.is_empty()
-         && (cond_val != NULL) && (then_val != NULL) && (else_val != NULL)) {
-        result = (cond_val->value.b[0]) ? then_val : else_val;
+          && else_instructions.is_empty()
+          && cond_val != NULL) {
+         result = cond_val->value.b[0] ? op[1] : op[2];
       } else {
-        ir_variable *const tmp =
-           new(ctx) ir_variable(type, "conditional_tmp", ir_var_temporary);
-        instructions->push_tail(tmp);
-
-        ir_if *const stmt = new(ctx) ir_if(op[0]);
-        instructions->push_tail(stmt);
-
-        then_instructions.move_nodes_to(& stmt->then_instructions);
-        ir_dereference *const then_deref =
-           new(ctx) ir_dereference_variable(tmp);
-        ir_assignment *const then_assign =
-           new(ctx) ir_assignment(then_deref, op[1]);
-        stmt->then_instructions.push_tail(then_assign);
-
-        else_instructions.move_nodes_to(& stmt->else_instructions);
-        ir_dereference *const else_deref =
-           new(ctx) ir_dereference_variable(tmp);
-        ir_assignment *const else_assign =
-           new(ctx) ir_assignment(else_deref, op[2]);
-        stmt->else_instructions.push_tail(else_assign);
-
-        result = new(ctx) ir_dereference_variable(tmp);
+         ir_variable *const tmp =
+            new(ctx) ir_variable(type, "conditional_tmp", ir_var_temporary);
+         instructions->push_tail(tmp);
+
+         ir_if *const stmt = new(ctx) ir_if(op[0]);
+         instructions->push_tail(stmt);
+
+         then_instructions.move_nodes_to(& stmt->then_instructions);
+         ir_dereference *const then_deref =
+            new(ctx) ir_dereference_variable(tmp);
+         ir_assignment *const then_assign =
+            new(ctx) ir_assignment(then_deref, op[1]);
+         stmt->then_instructions.push_tail(then_assign);
+
+         else_instructions.move_nodes_to(& stmt->else_instructions);
+         ir_dereference *const else_deref =
+            new(ctx) ir_dereference_variable(tmp);
+         ir_assignment *const else_assign =
+            new(ctx) ir_assignment(else_deref, op[2]);
+         stmt->else_instructions.push_tail(else_assign);
+
+         result = new(ctx) ir_dereference_variable(tmp);
       }
       break;
    }
@@ -1556,7 +1646,7 @@ ast_expression::hir(exec_list *instructions,
    case ast_pre_inc:
    case ast_pre_dec: {
       this->non_lvalue_description = (this->oper == ast_pre_inc)
-        ? "pre-increment operation" : "pre-decrement operation";
+         ? "pre-increment operation" : "pre-decrement operation";
 
       op[0] = this->subexpressions[0]->hir(instructions, state);
       op[1] = constant_one_for_inc_dec(ctx, op[0]->type);
@@ -1565,20 +1655,21 @@ ast_expression::hir(exec_list *instructions,
 
       ir_rvalue *temp_rhs;
       temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
-                                       op[0], op[1]);
-
-      result = do_assignment(instructions, state,
-                            this->subexpressions[0]->non_lvalue_description,
-                            op[0]->clone(ctx, NULL), temp_rhs, false,
-                            this->subexpressions[0]->get_location());
-      error_emitted = op[0]->type->is_error();
+                                        op[0], op[1]);
+
+      error_emitted =
+         do_assignment(instructions, state,
+                       this->subexpressions[0]->non_lvalue_description,
+                       op[0]->clone(ctx, NULL), temp_rhs,
+                       &result, needs_rvalue, false,
+                       this->subexpressions[0]->get_location());
       break;
    }
 
    case ast_post_inc:
    case ast_post_dec: {
       this->non_lvalue_description = (this->oper == ast_post_inc)
-        ? "post-increment operation" : "post-decrement operation";
+         ? "post-increment operation" : "post-decrement operation";
       op[0] = this->subexpressions[0]->hir(instructions, state);
       op[1] = constant_one_for_inc_dec(ctx, op[0]->type);
 
@@ -1588,19 +1679,21 @@ ast_expression::hir(exec_list *instructions,
 
       ir_rvalue *temp_rhs;
       temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
-                                       op[0], op[1]);
+                                        op[0], op[1]);
 
       /* Get a temporary of a copy of the lvalue before it's modified.
        * This may get thrown away later.
        */
       result = get_lvalue_copy(instructions, op[0]->clone(ctx, NULL));
 
-      (void)do_assignment(instructions, state,
-                         this->subexpressions[0]->non_lvalue_description,
-                         op[0]->clone(ctx, NULL), temp_rhs, false,
-                         this->subexpressions[0]->get_location());
+      ir_rvalue *junk_rvalue;
+      error_emitted =
+         do_assignment(instructions, state,
+                       this->subexpressions[0]->non_lvalue_description,
+                       op[0]->clone(ctx, NULL), temp_rhs,
+                       &junk_rvalue, false, false,
+                       this->subexpressions[0]->get_location());
 
-      error_emitted = op[0]->type->is_error();
       break;
    }
 
@@ -1615,10 +1708,10 @@ ast_expression::hir(exec_list *instructions,
       op[1] = subexpressions[1]->hir(instructions, state);
 
       result = _mesa_ast_array_index_to_hir(ctx, state, op[0], op[1],
-                                           loc, index_loc);
+                                            loc, index_loc);
 
       if (result->type->is_error())
-        error_emitted = true;
+         error_emitted = true;
 
       break;
    }
@@ -1636,17 +1729,17 @@ ast_expression::hir(exec_list *instructions,
        * as 'variable_identifier'.
        */
       ir_variable *var = 
-        state->symbols->get_variable(this->primary_expression.identifier);
+         state->symbols->get_variable(this->primary_expression.identifier);
 
       if (var != NULL) {
-        var->used = true;
-        result = new(ctx) ir_dereference_variable(var);
+         var->data.used = true;
+         result = new(ctx) ir_dereference_variable(var);
       } else {
-        _mesa_glsl_error(& loc, state, "`%s' undeclared",
-                         this->primary_expression.identifier);
+         _mesa_glsl_error(& loc, state, "`%s' undeclared",
+                          this->primary_expression.identifier);
 
-        result = ir_rvalue::error_value(ctx);
-        error_emitted = true;
+         result = ir_rvalue::error_value(ctx);
+         error_emitted = true;
       }
       break;
    }
@@ -1667,6 +1760,10 @@ ast_expression::hir(exec_list *instructions,
       result = new(ctx) ir_constant(bool(this->primary_expression.bool_constant));
       break;
 
+   case ast_double_constant:
+      result = new(ctx) ir_constant(this->primary_expression.double_constant);
+      break;
+
    case ast_sequence: {
       /* It should not be possible to generate a sequence in the AST without
        * any expressions in it.
@@ -1682,37 +1779,37 @@ ast_expression::hir(exec_list *instructions,
       YYLTYPE previous_operand_loc = loc;
 
       foreach_list_typed (ast_node, ast, link, &this->expressions) {
-        /* If one of the operands of comma operator does not generate any
-         * code, we want to emit a warning.  At each pass through the loop
-         * previous_tail_pred will point to the last instruction in the
-         * stream *before* processing the previous operand.  Naturally,
-         * instructions->tail_pred will point to the last instruction in the
-         * stream *after* processing the previous operand.  If the two
-         * pointers match, then the previous operand had no effect.
-         *
-         * The warning behavior here differs slightly from GCC.  GCC will
-         * only emit a warning if none of the left-hand operands have an
-         * effect.  However, it will emit a warning for each.  I believe that
-         * there are some cases in C (especially with GCC extensions) where
-         * it is useful to have an intermediate step in a sequence have no
-         * effect, but I don't think these cases exist in GLSL.  Either way,
-         * it would be a giant hassle to replicate that behavior.
-         */
-        if (previous_tail_pred == instructions->tail_pred) {
-           _mesa_glsl_warning(&previous_operand_loc, state,
-                              "left-hand operand of comma expression has "
-                              "no effect");
-        }
-
-        /* tail_pred is directly accessed instead of using the get_tail()
-         * method for performance reasons.  get_tail() has extra code to
-         * return NULL when the list is empty.  We don't care about that
-         * here, so using tail_pred directly is fine.
-         */
-        previous_tail_pred = instructions->tail_pred;
-        previous_operand_loc = ast->get_location();
-
-        result = ast->hir(instructions, state);
+         /* If one of the operands of comma operator does not generate any
+          * code, we want to emit a warning.  At each pass through the loop
+          * previous_tail_pred will point to the last instruction in the
+          * stream *before* processing the previous operand.  Naturally,
+          * instructions->tail_pred will point to the last instruction in the
+          * stream *after* processing the previous operand.  If the two
+          * pointers match, then the previous operand had no effect.
+          *
+          * The warning behavior here differs slightly from GCC.  GCC will
+          * only emit a warning if none of the left-hand operands have an
+          * effect.  However, it will emit a warning for each.  I believe that
+          * there are some cases in C (especially with GCC extensions) where
+          * it is useful to have an intermediate step in a sequence have no
+          * effect, but I don't think these cases exist in GLSL.  Either way,
+          * it would be a giant hassle to replicate that behavior.
+          */
+         if (previous_tail_pred == instructions->tail_pred) {
+            _mesa_glsl_warning(&previous_operand_loc, state,
+                               "left-hand operand of comma expression has "
+                               "no effect");
+         }
+
+         /* tail_pred is directly accessed instead of using the get_tail()
+          * method for performance reasons.  get_tail() has extra code to
+          * return NULL when the list is empty.  We don't care about that
+          * here, so using tail_pred directly is fine.
+          */
+         previous_tail_pred = instructions->tail_pred;
+         previous_operand_loc = ast->get_location();
+
+         result = ast->hir(instructions, state);
       }
 
       /* Any errors should have already been emitted in the loop above.
@@ -1722,9 +1819,9 @@ ast_expression::hir(exec_list *instructions,
    }
    }
    type = NULL; /* use result->type, not type. */
-   assert(result != NULL);
+   assert(result != NULL || !needs_rvalue);
 
-   if (result->type->is_error() && !error_emitted)
+   if (result && result->type->is_error() && !error_emitted)
       _mesa_glsl_error(& loc, state, "type mismatch");
 
    return result;
@@ -1733,7 +1830,7 @@ ast_expression::hir(exec_list *instructions,
 
 ir_rvalue *
 ast_expression_statement::hir(exec_list *instructions,
-                             struct _mesa_glsl_parse_state *state)
+                              struct _mesa_glsl_parse_state *state)
 {
    /* It is possible to have expression statements that don't have an
     * expression.  This is the solitary semicolon:
@@ -1745,7 +1842,7 @@ ast_expression_statement::hir(exec_list *instructions,
     * anything in that case.
     */
    if (expression != NULL)
-      expression->hir(instructions, state);
+      expression->hir_no_rvalue(instructions, state);
 
    /* Statements do not have r-values.
     */
@@ -1755,7 +1852,7 @@ ast_expression_statement::hir(exec_list *instructions,
 
 ir_rvalue *
 ast_compound_statement::hir(exec_list *instructions,
-                           struct _mesa_glsl_parse_state *state)
+                            struct _mesa_glsl_parse_state *state)
 {
    if (new_scope)
       state->symbols->push_scope();
@@ -1771,80 +1868,120 @@ 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 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 (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());
-           }
-        }
+         if (base->length == 0) {
+            _mesa_glsl_error(loc, state,
+                             "only the outermost array dimension can "
+                             "be unsized",
+                             base->name);
+            return glsl_type::error_type;
+         }
+      }
+
+      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;
 }
 
 
 const glsl_type *
 ast_type_specifier::glsl_type(const char **name,
-                             struct _mesa_glsl_parse_state *state) const
+                              struct _mesa_glsl_parse_state *state) const
 {
    const struct glsl_type *type;
 
    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 +1997,7 @@ ast_fully_specified_type::glsl_type(const char **name,
 
    if (type->base_type == GLSL_TYPE_FLOAT
        && state->es_shader
-       && state->target == fragment_shader
+       && state->stage == MESA_SHADER_FRAGMENT
        && this->qualifier.precision == ast_precision_none
        && state->symbols->get_variable("#default precision") == NULL) {
       YYLTYPE loc = this->get_location();
@@ -1882,15 +2019,15 @@ ast_fully_specified_type::glsl_type(const char **name,
  * this function will produce undefined results.
  */
 static bool
-is_varying_var(ir_variable *var, _mesa_glsl_parser_targets target)
+is_varying_var(ir_variable *var, gl_shader_stage target)
 {
    switch (target) {
-   case vertex_shader:
-      return var->mode == ir_var_shader_out;
-   case fragment_shader:
-      return var->mode == ir_var_shader_in;
+   case MESA_SHADER_VERTEX:
+      return var->data.mode == ir_var_shader_out;
+   case MESA_SHADER_FRAGMENT:
+      return var->data.mode == ir_var_shader_in;
    default:
-      return var->mode == ir_var_shader_out || var->mode == ir_var_shader_in;
+      return var->data.mode == ir_var_shader_out || var->data.mode == ir_var_shader_in;
    }
 }
 
@@ -1900,7 +2037,7 @@ is_varying_var(ir_variable *var, _mesa_glsl_parser_targets target)
  */
 static void
 validate_matrix_layout_for_type(struct _mesa_glsl_parse_state *state,
-                               YYLTYPE *loc,
+                                YYLTYPE *loc,
                                 const glsl_type *type,
                                 ir_variable *var)
 {
@@ -1941,7 +2078,7 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state,
                            ir_variable *var,
                            const ast_type_qualifier *qual)
 {
-   if (var->mode != ir_var_uniform) {
+   if (var->data.mode != ir_var_uniform) {
       _mesa_glsl_error(loc, state,
                        "the \"binding\" qualifier only applies to uniforms");
       return false;
@@ -1983,18 +2120,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 vertex_shader:
-         limit = ctx->Const.VertexProgram.MaxTextureImageUnits;
-         break;
-      case geometry_shader:
-         limit = ctx->Const.GeometryProgram.MaxTextureImageUnits;
-         break;
-      case fragment_shader:
-         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 +2175,8 @@ interpret_interpolation_qualifier(const struct ast_type_qualifier *qual,
 
       }
 
-      if ((state->target == vertex_shader && mode == ir_var_shader_in) ||
-          (state->target == fragment_shader && 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",
@@ -2070,32 +2196,91 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
 {
    bool fail = false;
 
-   /* In the vertex shader only shader inputs can be given explicit
-    * locations.
+   /* Checks for GL_ARB_explicit_uniform_location. */
+   if (qual->flags.q.uniform) {
+      if (!state->check_explicit_uniform_location_allowed(loc, var))
+         return;
+
+      const struct gl_context *const ctx = state->ctx;
+      unsigned max_loc = qual->location + var->type->uniform_locations() - 1;
+
+      /* ARB_explicit_uniform_location specification states:
+       *
+       *     "The explicitly defined locations and the generated locations
+       *     must be in the range of 0 to MAX_UNIFORM_LOCATIONS minus one."
+       *
+       *     "Valid locations for default-block uniform variable locations
+       *     are in the range of 0 to the implementation-defined maximum
+       *     number of uniform locations."
+       */
+      if (qual->location < 0) {
+         _mesa_glsl_error(loc, state,
+                          "explicit location < 0 for uniform %s", var->name);
+         return;
+      }
+
+      if (max_loc >= ctx->Const.MaxUserAssignableUniformLocations) {
+         _mesa_glsl_error(loc, state, "location(s) consumed by uniform %s "
+                          ">= MAX_UNIFORM_LOCATIONS (%u)", var->name,
+                          ctx->Const.MaxUserAssignableUniformLocations);
+         return;
+      }
+
+      var->data.explicit_location = true;
+      var->data.location = qual->location;
+      return;
+   }
+
+   /* Between GL_ARB_explicit_attrib_location an
+    * GL_ARB_separate_shader_objects, the inputs and outputs of any shader
+    * stage can be assigned explicit locations.  The checking here associates
+    * the correct extension with the correct stage's input / output:
     *
-    * In the fragment shader only shader outputs can be given explicit
-    * locations.
+    *                     input            output
+    *                     -----            ------
+    * vertex              explicit_loc     sso
+    * geometry            sso              sso
+    * fragment            sso              explicit_loc
     */
-   switch (state->target) {
-   case vertex_shader:
-      if (var->mode == ir_var_shader_in) {
+   switch (state->stage) {
+   case MESA_SHADER_VERTEX:
+      if (var->data.mode == ir_var_shader_in) {
          if (!state->check_explicit_attrib_location_allowed(loc, var))
             return;
 
          break;
       }
 
+      if (var->data.mode == ir_var_shader_out) {
+         if (!state->check_separate_shader_objects_allowed(loc, var))
+            return;
+
+         break;
+      }
+
       fail = true;
       break;
 
-   case geometry_shader:
-      _mesa_glsl_error(loc, state,
-                       "geometry shader variables cannot be given "
-                       "explicit locations");
-      return;
+   case MESA_SHADER_GEOMETRY:
+      if (var->data.mode == ir_var_shader_in || var->data.mode == ir_var_shader_out) {
+         if (!state->check_separate_shader_objects_allowed(loc, var))
+            return;
+
+         break;
+      }
+
+      fail = true;
+      break;
+
+   case MESA_SHADER_FRAGMENT:
+      if (var->data.mode == ir_var_shader_in) {
+         if (!state->check_separate_shader_objects_allowed(loc, var))
+            return;
+
+         break;
+      }
 
-   case fragment_shader:
-      if (var->mode == ir_var_shader_out) {
+      if (var->data.mode == ir_var_shader_out) {
          if (!state->check_explicit_attrib_location_allowed(loc, var))
             return;
 
@@ -2104,15 +2289,21 @@ 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_glsl_shader_target_name(state->target));
+      _mesa_shader_stage_to_string(state->stage));
    } else {
-      var->explicit_location = true;
+      var->data.explicit_location = true;
 
       /* This bit of silliness is needed because invalid explicit locations
        * are supposed to be flagged during linking.  Small negative values
@@ -2122,11 +2313,28 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
        * ensures that negative values stay negative.
        */
       if (qual->location >= 0) {
-         var->location = (state->target == vertex_shader)
-            ? (qual->location + VERT_ATTRIB_GENERIC0)
-            : (qual->location + FRAG_RESULT_DATA0);
+         switch (state->stage) {
+         case MESA_SHADER_VERTEX:
+            var->data.location = (var->data.mode == ir_var_shader_in)
+               ? (qual->location + VERT_ATTRIB_GENERIC0)
+               : (qual->location + VARYING_SLOT_VAR0);
+            break;
+
+         case MESA_SHADER_GEOMETRY:
+            var->data.location = qual->location + VARYING_SLOT_VAR0;
+            break;
+
+         case MESA_SHADER_FRAGMENT:
+            var->data.location = (var->data.mode == ir_var_shader_out)
+               ? (qual->location + FRAG_RESULT_DATA0)
+               : (qual->location + VARYING_SLOT_VAR0);
+            break;
+         case MESA_SHADER_COMPUTE:
+            assert(!"Unexpected shader type");
+            break;
+         }
       } else {
-         var->location = qual->location;
+         var->data.location = qual->location;
       }
 
       if (qual->flags.q.explicit_index) {
@@ -2143,52 +2351,149 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
             _mesa_glsl_error(loc, state,
                              "explicit index may only be 0 or 1");
          } else {
-            var->explicit_index = true;
-            var->index = qual->index;
+            var->data.explicit_index = true;
+            var->data.index = qual->index;
+         }
+      }
+   }
+}
+
+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 |= 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 inline const char*
+get_layout_qualifier_string(bool origin_upper_left, bool pixel_center_integer)
+{
+   if (origin_upper_left && pixel_center_integer)
+      return "origin_upper_left, pixel_center_integer";
+   else if (origin_upper_left)
+      return "origin_upper_left";
+   else if (pixel_center_integer)
+      return "pixel_center_integer";
+   else
+      return " ";
+}
+
+static inline bool
+is_conflicting_fragcoord_redeclaration(struct _mesa_glsl_parse_state *state,
+                                       const struct ast_type_qualifier *qual)
+{
+   /* If gl_FragCoord was previously declared, and the qualifiers were
+    * different in any way, return true.
+    */
+   if (state->fs_redeclares_gl_fragcoord) {
+      return (state->fs_pixel_center_integer != qual->flags.q.pixel_center_integer
+         || state->fs_origin_upper_left != qual->flags.q.origin_upper_left);
+   }
 
-   return;
+   return false;
 }
 
 static void
 apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
-                                ir_variable *var,
-                                struct _mesa_glsl_parse_state *state,
-                                YYLTYPE *loc,
+                                 ir_variable *var,
+                                 struct _mesa_glsl_parse_state *state,
+                                 YYLTYPE *loc,
                                  bool is_parameter)
 {
    STATIC_ASSERT(sizeof(qual->flags.q) <= sizeof(qual->flags.i));
 
    if (qual->flags.q.invariant) {
-      if (var->used) {
-        _mesa_glsl_error(loc, state,
-                         "variable `%s' may not be redeclared "
-                         "`invariant' after being used",
-                         var->name);
+      if (var->data.used) {
+         _mesa_glsl_error(loc, state,
+                          "variable `%s' may not be redeclared "
+                          "`invariant' after being used",
+                          var->name);
       } else {
-        var->invariant = 1;
+         var->data.invariant = 1;
+      }
+   }
+
+   if (qual->flags.q.precise) {
+      if (var->data.used) {
+         _mesa_glsl_error(loc, state,
+                          "variable `%s' may not be redeclared "
+                          "`precise' after being used",
+                          var->name);
+      } else {
+         var->data.precise = 1;
       }
    }
 
    if (qual->flags.q.constant || qual->flags.q.attribute
        || qual->flags.q.uniform
-       || (qual->flags.q.varying && (state->target == fragment_shader)))
-      var->read_only = 1;
+       || (qual->flags.q.varying && (state->stage == MESA_SHADER_FRAGMENT)))
+      var->data.read_only = 1;
 
    if (qual->flags.q.centroid)
-      var->centroid = 1;
+      var->data.centroid = 1;
 
    if (qual->flags.q.sample)
-      var->sample = 1;
+      var->data.sample = 1;
+
+   if (state->stage == MESA_SHADER_GEOMETRY &&
+       qual->flags.q.out && qual->flags.q.stream) {
+      var->data.stream = qual->stream;
+   }
 
-   if (qual->flags.q.attribute && state->target != vertex_shader) {
+   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_glsl_shader_target_name(state->target));
+                       "`attribute' variables may not be declared in the "
+                       "%s shader",
+                       _mesa_shader_stage_to_string(state->stage));
+   }
+
+   /* Disallow layout qualifiers which may only appear on layout declarations. */
+   if (qual->flags.q.prim_type) {
+      _mesa_glsl_error(loc, state,
+                       "Primitive type may only be specified on GS input or output "
+                       "layout declaration, not on variables.");
    }
 
    /* Section 6.1.1 (Function Calling Conventions) of the GLSL 1.10 spec says:
@@ -2209,21 +2514,29 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
    /* If there is no qualifier that changes the mode of the variable, leave
     * the setting alone.
     */
+   assert(var->data.mode != ir_var_temporary);
    if (qual->flags.q.in && qual->flags.q.out)
-      var->mode = ir_var_function_inout;
+      var->data.mode = ir_var_function_inout;
    else if (qual->flags.q.in)
-      var->mode = is_parameter ? ir_var_function_in : ir_var_shader_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 == fragment_shader)))
-      var->mode = ir_var_shader_in;
+           || (qual->flags.q.varying && (state->stage == MESA_SHADER_FRAGMENT)))
+      var->data.mode = ir_var_shader_in;
    else if (qual->flags.q.out)
-      var->mode = is_parameter ? ir_var_function_out : ir_var_shader_out;
-   else if (qual->flags.q.varying && (state->target == vertex_shader))
-      var->mode = ir_var_shader_out;
+      var->data.mode = is_parameter ? ir_var_function_out : ir_var_shader_out;
+   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->mode = ir_var_uniform;
+      var->data.mode = ir_var_uniform;
+
+   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");
+      }
 
-   if (!is_parameter && is_varying_var(var, state->target)) {
       /* 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.
@@ -2265,6 +2578,8 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
          _mesa_glsl_error(loc, state,
                           "varying variables may not be of type struct");
          break;
+      case GLSL_TYPE_DOUBLE:
+         break;
       default:
          _mesa_glsl_error(loc, state, "illegal type for a varying variable");
          break;
@@ -2272,33 +2587,36 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
    }
 
    if (state->all_invariant && (state->current_function == NULL)) {
-      switch (state->target) {
-      case vertex_shader:
-        if (var->mode == ir_var_shader_out)
-           var->invariant = true;
-        break;
-      case geometry_shader:
-        if ((var->mode == ir_var_shader_in)
-             || (var->mode == ir_var_shader_out))
-           var->invariant = true;
-        break;
-      case fragment_shader:
-        if (var->mode == ir_var_shader_in)
-           var->invariant = true;
-        break;
+      switch (state->stage) {
+      case MESA_SHADER_VERTEX:
+         if (var->data.mode == ir_var_shader_out)
+            var->data.invariant = true;
+             break;
+      case MESA_SHADER_GEOMETRY:
+         if ((var->data.mode == ir_var_shader_in)
+             || (var->data.mode == ir_var_shader_out))
+            var->data.invariant = true;
+         break;
+      case MESA_SHADER_FRAGMENT:
+         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;
       }
    }
 
-   var->interpolation =
-      interpret_interpolation_qualifier(qual, (ir_variable_mode) var->mode,
+   var->data.interpolation =
+      interpret_interpolation_qualifier(qual, (ir_variable_mode) var->data.mode,
                                         state, loc);
 
-   var->pixel_center_integer = qual->flags.q.pixel_center_integer;
-   var->origin_upper_left = qual->flags.q.origin_upper_left;
+   var->data.pixel_center_integer = qual->flags.q.pixel_center_integer;
+   var->data.origin_upper_left = qual->flags.q.origin_upper_left;
    if ((qual->flags.q.origin_upper_left || qual->flags.q.pixel_center_integer)
        && (strcmp(var->name, "gl_FragCoord") != 0)) {
       const char *const qual_string = (qual->flags.q.origin_upper_left)
-        ? "origin_upper_left" : "pixel_center_integer";
+         ? "origin_upper_left" : "pixel_center_integer";
 
       _mesa_glsl_error(loc, state,
                       "layout qualifier `%s' can only be applied to "
@@ -2306,36 +2624,83 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
                       qual_string);
    }
 
-   if (qual->flags.q.explicit_location) {
-      validate_explicit_location(qual, var, state, loc);
-   } else if (qual->flags.q.explicit_index) {
-        _mesa_glsl_error(loc, state,
-                         "explicit index requires explicit location");
-   }
+   if (var->name != NULL && strcmp(var->name, "gl_FragCoord") == 0) {
 
-   if (qual->flags.q.explicit_binding &&
-       validate_binding_qualifier(state, loc, var, qual)) {
-      var->explicit_binding = true;
-      var->binding = qual->binding;
+      /* Section 4.3.8.1, page 39 of GLSL 1.50 spec says:
+       *
+       *    "Within any shader, the first redeclarations of gl_FragCoord
+       *     must appear before any use of gl_FragCoord."
+       *
+       * Generate a compiler error if above condition is not met by the
+       * fragment shader.
+       */
+      ir_variable *earlier = state->symbols->get_variable("gl_FragCoord");
+      if (earlier != NULL &&
+          earlier->data.used &&
+          !state->fs_redeclares_gl_fragcoord) {
+         _mesa_glsl_error(loc, state,
+                          "gl_FragCoord used before its first redeclaration "
+                          "in fragment shader");
+      }
+
+      /* Make sure all gl_FragCoord redeclarations specify the same layout
+       * qualifiers.
+       */
+      if (is_conflicting_fragcoord_redeclaration(state, qual)) {
+         const char *const qual_string =
+            get_layout_qualifier_string(qual->flags.q.origin_upper_left,
+                                        qual->flags.q.pixel_center_integer);
+
+         const char *const state_string =
+            get_layout_qualifier_string(state->fs_origin_upper_left,
+                                        state->fs_pixel_center_integer);
+
+         _mesa_glsl_error(loc, state,
+                          "gl_FragCoord redeclared with different layout "
+                          "qualifiers (%s) and (%s) ",
+                          state_string,
+                          qual_string);
+      }
+      state->fs_origin_upper_left = qual->flags.q.origin_upper_left;
+      state->fs_pixel_center_integer = qual->flags.q.pixel_center_integer;
+      state->fs_redeclares_gl_fragcoord_with_no_layout_qualifiers =
+         !qual->flags.q.origin_upper_left && !qual->flags.q.pixel_center_integer;
+      state->fs_redeclares_gl_fragcoord =
+         state->fs_origin_upper_left ||
+         state->fs_pixel_center_integer ||
+         state->fs_redeclares_gl_fragcoord_with_no_layout_qualifiers;
+   }
+
+   if (qual->flags.q.explicit_location) {
+      validate_explicit_location(qual, var, state, loc);
+   } else if (qual->flags.q.explicit_index) {
+      _mesa_glsl_error(loc, state, "explicit index requires explicit location");
+   }
+
+   if (qual->flags.q.explicit_binding &&
+       validate_binding_qualifier(state, loc, var, qual)) {
+      var->data.explicit_binding = true;
+      var->data.binding = qual->binding;
    }
 
    if (var->type->contains_atomic()) {
-      if (var->mode == ir_var_uniform) {
-         if (var->explicit_binding) {
-            unsigned *offset = &state->atomic_counter_offsets[var->binding];
+      if (var->data.mode == ir_var_uniform) {
+         if (var->data.explicit_binding) {
+            unsigned *offset =
+               &state->atomic_counter_offsets[var->data.binding];
 
             if (*offset % ATOMIC_COUNTER_SIZE)
                _mesa_glsl_error(loc, state,
                                 "misaligned atomic counter offset");
 
-            var->atomic.offset = *offset;
+            var->data.atomic.offset = *offset;
             *offset += var->type->atomic_size();
 
          } else {
             _mesa_glsl_error(loc, state,
                              "atomic counters require explicit binding point");
          }
-      } else if (var->mode != ir_var_function_in) {
+      } else if (var->data.mode != ir_var_function_in) {
          _mesa_glsl_error(loc, state, "atomic counters may only be declared as "
                           "function parameters or uniform-qualified "
                           "global variables");
@@ -2348,6 +2713,36 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
    const bool uses_deprecated_qualifier = qual->flags.q.attribute
       || qual->flags.q.varying;
 
+
+   /* Validate auxiliary storage qualifiers */
+
+   /* From section 4.3.4 of the GLSL 1.30 spec:
+    *    "It is an error to use centroid in in a vertex shader."
+    *
+    * From section 4.3.4 of the GLSL ES 3.00 spec:
+    *    "It is an error to use centroid in or interpolation qualifiers in
+    *    a vertex shader input."
+    */
+
+   /* Section 4.3.6 of the GLSL 1.30 specification states:
+    * "It is an error to use centroid out in a fragment shader."
+    *
+    * The GL_ARB_shading_language_420pack extension specification states:
+    * "It is an error to use auxiliary storage qualifiers or interpolation
+    *  qualifiers on an output in a fragment shader."
+    */
+   if (qual->flags.q.sample && (!is_varying_var(var, state->stage) || uses_deprecated_qualifier)) {
+      _mesa_glsl_error(loc, state,
+                       "sample qualifier may only be used on `in` or `out` "
+                       "variables between shader stages");
+   }
+   if (qual->flags.q.centroid && !is_varying_var(var, state->stage)) {
+      _mesa_glsl_error(loc, state,
+                       "centroid qualifier may only be used with `in', "
+                       "`out' or `varying' variables between shader stages");
+   }
+
+
    /* Is the 'layout' keyword used with parameters that allow relaxed checking.
     * Many implementations of GL_ARB_fragment_coord_conventions_enable and some
     * implementations (only Mesa?) GL_ARB_explicit_attrib_location_enable
@@ -2373,13 +2768,13 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
 
    if (qual->has_layout() && uses_deprecated_qualifier) {
       if (relaxed_layout_qualifier_checking) {
-        _mesa_glsl_warning(loc, state,
-                           "`layout' qualifier may not be used with "
-                           "`attribute' or `varying'");
+         _mesa_glsl_warning(loc, state,
+                            "`layout' qualifier may not be used with "
+                            "`attribute' or `varying'");
       } else {
-        _mesa_glsl_error(loc, state,
-                         "`layout' qualifier may not be used with "
-                         "`attribute' or `varying'");
+         _mesa_glsl_error(loc, state,
+                          "`layout' qualifier may not be used with "
+                          "`attribute' or `varying'");
       }
    }
 
@@ -2396,7 +2791,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
        _mesa_glsl_error(loc, state,
                         "extension GL_AMD_conservative_depth or "
                         "GL_ARB_conservative_depth must be enabled "
-                       "to use depth layout qualifiers");
+                        "to use depth layout qualifiers");
    } else if (depth_layout_count > 0
               && strcmp(var->name, "gl_FragDepth") != 0) {
        _mesa_glsl_error(loc, state,
@@ -2409,28 +2804,31 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
                        "gl_FragDepth");
    }
    if (qual->flags.q.depth_any)
-      var->depth_layout = ir_depth_layout_any;
+      var->data.depth_layout = ir_depth_layout_any;
    else if (qual->flags.q.depth_greater)
-      var->depth_layout = ir_depth_layout_greater;
+      var->data.depth_layout = ir_depth_layout_greater;
    else if (qual->flags.q.depth_less)
-      var->depth_layout = ir_depth_layout_less;
+      var->data.depth_layout = ir_depth_layout_less;
    else if (qual->flags.q.depth_unchanged)
-       var->depth_layout = ir_depth_layout_unchanged;
+       var->data.depth_layout = ir_depth_layout_unchanged;
    else
-       var->depth_layout = ir_depth_layout_none;
+       var->data.depth_layout = ir_depth_layout_none;
 
    if (qual->flags.q.std140 ||
        qual->flags.q.packed ||
        qual->flags.q.shared) {
       _mesa_glsl_error(loc, state,
                        "uniform block layout qualifiers std140, packed, and "
-                      "shared can only be applied to uniform blocks, not "
-                      "members");
+                       "shared can only be applied to uniform blocks, not "
+                       "members");
    }
 
    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);
 }
 
 /**
@@ -2458,7 +2856,7 @@ get_variable_being_redeclared(ir_variable *var, YYLTYPE loc,
    ir_variable *earlier = state->symbols->get_variable(var->name);
    if (earlier == NULL ||
        (state->current_function != NULL &&
-       !state->symbols->name_declared_this_scope(var->name))) {
+       !state->symbols->name_declared_this_scope(var->name))) {
       return NULL;
    }
 
@@ -2478,25 +2876,25 @@ get_variable_being_redeclared(ir_variable *var, YYLTYPE loc,
 
       const unsigned size = unsigned(var->type->array_size());
       check_builtin_array_max_size(var->name, size, loc, state);
-      if ((size > 0) && (size <= earlier->max_array_access)) {
-        _mesa_glsl_error(& loc, state, "array size must be > %u due to "
-                         "previous access",
-                         earlier->max_array_access);
+      if ((size > 0) && (size <= earlier->data.max_array_access)) {
+         _mesa_glsl_error(& loc, state, "array size must be > %u due to "
+                          "previous access",
+                          earlier->data.max_array_access);
       }
 
       earlier->type = var->type;
       delete var;
       var = NULL;
    } else if ((state->ARB_fragment_coord_conventions_enable ||
-               state->is_version(150, 0))
-             && strcmp(var->name, "gl_FragCoord") == 0
-             && earlier->type == var->type
-             && earlier->mode == var->mode) {
+              state->is_version(150, 0))
+              && strcmp(var->name, "gl_FragCoord") == 0
+              && earlier->type == var->type
+              && earlier->data.mode == var->data.mode) {
       /* Allow redeclaration of gl_FragCoord for ARB_fcc layout
        * qualifiers.
        */
-      earlier->origin_upper_left = var->origin_upper_left;
-      earlier->pixel_center_integer = var->pixel_center_integer;
+      earlier->data.origin_upper_left = var->data.origin_upper_left;
+      earlier->data.pixel_center_integer = var->data.pixel_center_integer;
 
       /* According to section 4.3.7 of the GLSL 1.30 spec,
        * the following built-in varaibles can be redeclared with an
@@ -2509,48 +2907,48 @@ get_variable_being_redeclared(ir_variable *var, YYLTYPE loc,
        *    * gl_SecondaryColor
        */
    } else if (state->is_version(130, 0)
-             && (strcmp(var->name, "gl_FrontColor") == 0
-                 || strcmp(var->name, "gl_BackColor") == 0
-                 || strcmp(var->name, "gl_FrontSecondaryColor") == 0
-                 || strcmp(var->name, "gl_BackSecondaryColor") == 0
-                 || strcmp(var->name, "gl_Color") == 0
-                 || strcmp(var->name, "gl_SecondaryColor") == 0)
-             && earlier->type == var->type
-             && earlier->mode == var->mode) {
-      earlier->interpolation = var->interpolation;
+              && (strcmp(var->name, "gl_FrontColor") == 0
+                  || strcmp(var->name, "gl_BackColor") == 0
+                  || strcmp(var->name, "gl_FrontSecondaryColor") == 0
+                  || strcmp(var->name, "gl_BackSecondaryColor") == 0
+                  || strcmp(var->name, "gl_Color") == 0
+                  || strcmp(var->name, "gl_SecondaryColor") == 0)
+              && earlier->type == var->type
+              && earlier->data.mode == var->data.mode) {
+      earlier->data.interpolation = var->data.interpolation;
 
       /* Layout qualifiers for gl_FragDepth. */
    } else if ((state->AMD_conservative_depth_enable ||
                state->ARB_conservative_depth_enable)
-             && strcmp(var->name, "gl_FragDepth") == 0
-             && earlier->type == var->type
-             && earlier->mode == var->mode) {
+              && strcmp(var->name, "gl_FragDepth") == 0
+              && earlier->type == var->type
+              && earlier->data.mode == var->data.mode) {
 
       /** From the AMD_conservative_depth spec:
        *     Within any shader, the first redeclarations of gl_FragDepth
        *     must appear before any use of gl_FragDepth.
        */
-      if (earlier->used) {
-        _mesa_glsl_error(&loc, state,
-                         "the first redeclaration of gl_FragDepth "
-                         "must appear before any use of gl_FragDepth");
+      if (earlier->data.used) {
+         _mesa_glsl_error(&loc, state,
+                          "the first redeclaration of gl_FragDepth "
+                          "must appear before any use of gl_FragDepth");
       }
 
       /* Prevent inconsistent redeclaration of depth layout qualifier. */
-      if (earlier->depth_layout != ir_depth_layout_none
-         && earlier->depth_layout != var->depth_layout) {
-        _mesa_glsl_error(&loc, state,
-                         "gl_FragDepth: depth layout is declared here "
-                         "as '%s, but it was previously declared as "
-                         "'%s'",
-                         depth_layout_string(var->depth_layout),
-                         depth_layout_string(earlier->depth_layout));
+      if (earlier->data.depth_layout != ir_depth_layout_none
+          && earlier->data.depth_layout != var->data.depth_layout) {
+            _mesa_glsl_error(&loc, state,
+                             "gl_FragDepth: depth layout is declared here "
+                             "as '%s, but it was previously declared as "
+                             "'%s'",
+                             depth_layout_string(var->data.depth_layout),
+                             depth_layout_string(earlier->data.depth_layout));
       }
 
-      earlier->depth_layout = var->depth_layout;
+      earlier->data.depth_layout = var->data.depth_layout;
 
    } else if (allow_all_redeclarations) {
-      if (earlier->mode != var->mode) {
+      if (earlier->data.mode != var->data.mode) {
          _mesa_glsl_error(&loc, state,
                           "redeclaration of `%s' with incorrect qualifiers",
                           var->name);
@@ -2585,27 +2983,39 @@ process_initializer(ir_variable *var, ast_declaration *decl,
     *    directly by an application via API commands, or indirectly by
     *    OpenGL."
     */
-   if (var->mode == ir_var_uniform) {
+   if (var->data.mode == ir_var_uniform) {
       state->check_version(120, 0, &initializer_loc,
                            "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->mode == ir_var_shader_in) && (state->current_function == NULL)) {
+   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_glsl_shader_target_name(state->target),
-                      (state->target == vertex_shader)
+                      _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);
+   ir_rvalue *rhs = decl->initializer->hir(initializer_instructions, state);
 
    /* Calculate the constant value if this is a const or uniform
     * declaration.
@@ -2615,10 +3025,10 @@ process_initializer(ir_variable *var, ast_declaration *decl,
       ir_rvalue *new_rhs = validate_assignment(state, initializer_loc,
                                                var->type, rhs, true);
       if (new_rhs != NULL) {
-        rhs = new_rhs;
+         rhs = new_rhs;
 
-        ir_constant *constant_value = rhs->constant_expression_value();
-        if (!constant_value) {
+         ir_constant *constant_value = rhs->constant_expression_value();
+         if (!constant_value) {
             /* If ARB_shading_language_420pack is enabled, initializers of
              * const-qualified local variables do not have to be constant
              * expressions. Const-qualified global variables must still be
@@ -2638,36 +3048,38 @@ process_initializer(ir_variable *var, ast_declaration *decl,
                }
             }
          } else {
-           rhs = constant_value;
-           var->constant_value = constant_value;
-        }
+            rhs = constant_value;
+            var->constant_value = constant_value;
+         }
       } else {
-        if (var->type->is_numeric()) {
-           /* Reduce cascading errors. */
-           var->constant_value = ir_constant::zero(state, var->type);
-        }
+         if (var->type->is_numeric()) {
+            /* Reduce cascading errors. */
+            var->constant_value = ir_constant::zero(state, var->type);
+         }
       }
    }
 
    if (rhs && !rhs->type->is_error()) {
-      bool temp = var->read_only;
+      bool temp = var->data.read_only;
       if (type->qualifier.flags.q.constant)
-        var->read_only = false;
+         var->data.read_only = false;
 
       /* Never emit code to initialize a uniform.
        */
       const glsl_type *initializer_type;
       if (!type->qualifier.flags.q.uniform) {
-        result = do_assignment(initializer_instructions, state,
-                               NULL,
-                               lhs, rhs, true,
-                               type->get_location());
-        initializer_type = result->type;
+         do_assignment(initializer_instructions, state,
+                       NULL,
+                       lhs, rhs,
+                       &result, true,
+                       true,
+                       type->get_location());
+         initializer_type = result->type;
       } else
-        initializer_type = rhs->type;
+         initializer_type = rhs->type;
 
       var->constant_initializer = rhs->constant_expression_value();
-      var->has_initializer = true;
+      var->data.has_initializer = true;
 
       /* If the declared variable is an unsized array, it must inherrit
        * its full type from the initializer.  A declaration such as
@@ -2691,7 +3103,7 @@ process_initializer(ir_variable *var, ast_declaration *decl,
        */
       var->type = initializer_type;
 
-      var->read_only = temp;
+      var->data.read_only = temp;
    }
 
    return result;
@@ -2708,7 +3120,7 @@ handle_geometry_shader_input_decl(struct _mesa_glsl_parse_state *state,
 {
    unsigned num_vertices = 0;
    if (state->gs_input_prim_type_specified) {
-      num_vertices = vertices_per_prim(state->gs_input_prim_type);
+      num_vertices = vertices_per_prim(state->in_qualifier->prim_type);
    }
 
    /* Geometry shader input variables must be arrays.  Caller should have
@@ -2783,7 +3195,7 @@ validate_identifier(const char *identifier, YYLTYPE loc,
     *   OpenGL, and may not be declared in a shader as either a
     *   variable or a function."
     */
-   if (strncmp(identifier, "gl_", 3) == 0) {
+   if (is_gl_identifier(identifier)) {
       _mesa_glsl_error(&loc, state,
                        "identifier `%s' uses reserved `gl_' prefix",
                        identifier);
@@ -2794,17 +3206,59 @@ validate_identifier(const char *identifier, YYLTYPE loc,
        *     "In addition, all identifiers containing two
        *      consecutive underscores (__) are reserved as
        *      possible future keywords."
+       *
+       * The intention is that names containing __ are reserved for internal
+       * use by the implementation, and names prefixed with GL_ are reserved
+       * for use by Khronos.  Names simply containing __ are dangerous to use,
+       * but should be allowed.
+       *
+       * A future version of the GLSL specification will clarify this.
        */
-      _mesa_glsl_error(&loc, state,
-                       "identifier `%s' uses reserved `__' string",
-                       identifier);
+      _mesa_glsl_warning(&loc, state,
+                         "identifier `%s' uses reserved `__' string",
+                         identifier);
    }
 }
 
+static bool
+precision_qualifier_allowed(const glsl_type *type)
+{
+   /* Precision qualifiers apply to floating point, integer and sampler
+    * types.
+    *
+    * Section 4.5.2 (Precision Qualifiers) of the GLSL 1.30 spec says:
+    *    "Any floating point or any integer declaration can have the type
+    *    preceded by one of these precision qualifiers [...] Literal
+    *    constants do not have precision qualifiers. Neither do Boolean
+    *    variables.
+    *
+    * Section 4.5 (Precision and Precision Qualifiers) of the GLSL 1.30
+    * spec also says:
+    *
+    *     "Precision qualifiers are added for code portability with OpenGL
+    *     ES, not for functionality. They have the same syntax as in OpenGL
+    *     ES."
+    *
+    * Section 8 (Built-In Functions) of the GLSL ES 1.00 spec says:
+    *
+    *     "uniform lowp sampler2D sampler;
+    *     highp vec2 coord;
+    *     ...
+    *     lowp vec4 col = texture2D (sampler, coord);
+    *                                            // texture2D returns lowp"
+    *
+    * From this, we infer that GLSL 1.30 (and later) should allow precision
+    * qualifiers on sampler types just like float and integer types.
+    */
+   return type->is_float()
+       || type->is_integer()
+       || type->is_record()
+       || type->is_sampler();
+}
 
 ir_rvalue *
 ast_declarator_list::hir(exec_list *instructions,
-                        struct _mesa_glsl_parse_state *state)
+                         struct _mesa_glsl_parse_state *state)
 {
    void *ctx = state;
    const struct glsl_type *decl_type;
@@ -2827,40 +3281,33 @@ ast_declarator_list::hir(exec_list *instructions,
       assert(this->type == NULL);
 
       if (state->current_function != NULL) {
-        _mesa_glsl_error(& loc, state,
-                         "all uses of `invariant' keyword must be at global "
-                         "scope");
+         _mesa_glsl_error(& loc, state,
+                          "all uses of `invariant' keyword must be at global "
+                          "scope");
       }
 
       foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
-        assert(!decl->is_array);
-        assert(decl->array_size == NULL);
-        assert(decl->initializer == NULL);
-
-        ir_variable *const earlier =
-           state->symbols->get_variable(decl->identifier);
-        if (earlier == NULL) {
-           _mesa_glsl_error(& loc, state,
-                            "undeclared variable `%s' cannot be marked "
-                            "invariant", decl->identifier);
-        } else if ((state->target == vertex_shader)
-              && (earlier->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 == fragment_shader)
-              && (earlier->mode != ir_var_shader_in)) {
-           _mesa_glsl_error(& loc, state,
-                            "`%s' cannot be marked invariant, fragment shader "
-                            "inputs only", decl->identifier);
-        } else if (earlier->used) {
-           _mesa_glsl_error(& loc, state,
-                            "variable `%s' may not be redeclared "
-                            "`invariant' after being used",
-                            earlier->name);
-        } else {
-           earlier->invariant = true;
-        }
+         assert(decl->array_specifier == NULL);
+         assert(decl->initializer == NULL);
+
+         ir_variable *const earlier =
+            state->symbols->get_variable(decl->identifier);
+         if (earlier == NULL) {
+            _mesa_glsl_error(& loc, state,
+                             "undeclared variable `%s' cannot be marked "
+                             "invariant", decl->identifier);
+         } else if (!is_varying_var(earlier, state->stage)) {
+            _mesa_glsl_error(&loc, state,
+                             "`%s' cannot be marked invariant; interfaces between "
+                             "shader stages only.", decl->identifier);
+         } else if (earlier->data.used) {
+            _mesa_glsl_error(& loc, state,
+                            "variable `%s' may not be redeclared "
+                            "`invariant' after being used",
+                            earlier->name);
+         } else {
+            earlier->data.invariant = true;
+         }
       }
 
       /* Invariant redeclarations do not have r-values.
@@ -2868,8 +3315,45 @@ ast_declarator_list::hir(exec_list *instructions,
       return NULL;
    }
 
+   if (this->precise) {
+      assert(this->type == NULL);
+
+      foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
+         assert(decl->array_specifier == NULL);
+         assert(decl->initializer == NULL);
+
+         ir_variable *const earlier =
+            state->symbols->get_variable(decl->identifier);
+         if (earlier == NULL) {
+            _mesa_glsl_error(& loc, state,
+                             "undeclared variable `%s' cannot be marked "
+                             "precise", decl->identifier);
+         } else if (state->current_function != NULL &&
+                    !state->symbols->name_declared_this_scope(decl->identifier)) {
+            /* Note: we have to check if we're in a function, since
+             * builtins are treated as having come from another scope.
+             */
+            _mesa_glsl_error(& loc, state,
+                             "variable `%s' from an outer scope may not be "
+                             "redeclared `precise' in this scope",
+                             earlier->name);
+         } else if (earlier->data.used) {
+            _mesa_glsl_error(& loc, state,
+                             "variable `%s' may not be redeclared "
+                             "`precise' after being used",
+                             earlier->name);
+         } else {
+            earlier->data.precise = true;
+         }
+      }
+
+      /* Precise redeclarations do not have r-values either. */
+      return NULL;
+   }
+
    assert(this->type != NULL);
    assert(!this->invariant);
+   assert(!this->precise);
 
    /* The type specifier may contain a structure definition.  Process that
     * before any of the variable declarations.
@@ -2957,26 +3441,20 @@ ast_declarator_list::hir(exec_list *instructions,
        */
 
       if ((decl_type == NULL) || decl_type->is_void()) {
-        if (type_name != NULL) {
-           _mesa_glsl_error(& loc, state,
-                            "invalid type `%s' in declaration of `%s'",
-                            type_name, decl->identifier);
-        } else {
-           _mesa_glsl_error(& loc, state,
-                            "invalid type in declaration of `%s'",
-                            decl->identifier);
-        }
-        continue;
+         if (type_name != NULL) {
+            _mesa_glsl_error(& loc, state,
+                             "invalid type `%s' in declaration of `%s'",
+                             type_name, decl->identifier);
+         } else {
+            _mesa_glsl_error(& loc, state,
+                             "invalid type in declaration of `%s'",
+                             decl->identifier);
+         }
+         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);
 
@@ -3003,7 +3481,7 @@ ast_declarator_list::hir(exec_list *instructions,
       /* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification;
        *
        *     "Global variables can only use the qualifiers const,
-       *     attribute, uni form, or varying. Only one may be
+       *     attribute, uniform, or varying. Only one may be
        *     specified.
        *
        *     Local variables can only use the qualifier const."
@@ -3012,94 +3490,86 @@ ast_declarator_list::hir(exec_list *instructions,
        * any extension that adds the 'layout' keyword.
        */
       if (!state->is_version(130, 300)
-         && !state->has_explicit_attrib_location()
-         && !state->ARB_fragment_coord_conventions_enable) {
-        if (this->type->qualifier.flags.q.out) {
-           _mesa_glsl_error(& loc, state,
-                            "`out' qualifier in declaration of `%s' "
-                            "only valid for function parameters in %s",
-                            decl->identifier, state->get_version_string());
-        }
-        if (this->type->qualifier.flags.q.in) {
-           _mesa_glsl_error(& loc, state,
-                            "`in' qualifier in declaration of `%s' "
-                            "only valid for function parameters in %s",
-                            decl->identifier, state->get_version_string());
-        }
-        /* FINISHME: Test for other invalid qualifiers. */
+          && !state->has_explicit_attrib_location()
+          && !state->has_separate_shader_objects()
+          && !state->ARB_fragment_coord_conventions_enable) {
+         if (this->type->qualifier.flags.q.out) {
+            _mesa_glsl_error(& loc, state,
+                             "`out' qualifier in declaration of `%s' "
+                             "only valid for function parameters in %s",
+                             decl->identifier, state->get_version_string());
+         }
+         if (this->type->qualifier.flags.q.in) {
+            _mesa_glsl_error(& loc, state,
+                             "`in' qualifier in declaration of `%s' "
+                             "only valid for function parameters in %s",
+                             decl->identifier, state->get_version_string());
+         }
+         /* FINISHME: Test for other invalid qualifiers. */
       }
 
       apply_type_qualifier_to_variable(& this->type->qualifier, var, state,
                                       & loc, false);
 
       if (this->type->qualifier.flags.q.invariant) {
-        if ((state->target == vertex_shader) &&
-             var->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 == fragment_shader) &&
-                   var->mode != ir_var_shader_in) {
-           /* FINISHME: Note that this doesn't work for invariant on
-            * a function signature inval
-            */
-           _mesa_glsl_error(& loc, state,
-                            "`%s' cannot be marked invariant, fragment shader "
-                            "inputs only", var->name);
-        }
+         if (!is_varying_var(var, state->stage)) {
+            _mesa_glsl_error(&loc, state,
+                             "`%s' cannot be marked invariant; interfaces between "
+                             "shader stages only", var->name);
+         }
       }
 
       if (state->current_function != NULL) {
-        const char *mode = NULL;
-        const char *extra = "";
-
-        /* There is no need to check for 'inout' here because the parser will
-         * only allow that in function parameter lists.
-         */
-        if (this->type->qualifier.flags.q.attribute) {
-           mode = "attribute";
-        } else if (this->type->qualifier.flags.q.uniform) {
-           mode = "uniform";
-        } else if (this->type->qualifier.flags.q.varying) {
-           mode = "varying";
-        } else if (this->type->qualifier.flags.q.in) {
-           mode = "in";
-           extra = " or in function parameter list";
-        } else if (this->type->qualifier.flags.q.out) {
-           mode = "out";
-           extra = " or in function parameter list";
-        }
-
-        if (mode) {
-           _mesa_glsl_error(& loc, state,
-                            "%s variable `%s' must be declared at "
-                            "global scope%s",
-                            mode, var->name, extra);
-        }
-      } else if (var->mode == ir_var_shader_in) {
-         var->read_only = true;
-
-        if (state->target == vertex_shader) {
-           bool error_emitted = false;
-
-           /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
-            *
-            *    "Vertex shader inputs can only be float, floating-point
-            *    vectors, matrices, signed and unsigned integers and integer
-            *    vectors. Vertex shader inputs can also form arrays of these
-            *    types, but not structures."
-            *
-            * From page 31 (page 27 of the PDF) of the GLSL 1.30 spec:
-            *
-            *    "Vertex shader inputs can only be float, floating-point
-            *    vectors, matrices, signed and unsigned integers and integer
-            *    vectors. They cannot be arrays or structures."
-            *
-            * From page 23 (page 29 of the PDF) of the GLSL 1.20 spec:
-            *
-            *    "The attribute qualifier can be used only with float,
-            *    floating-point vectors, and matrices. Attribute variables
-            *    cannot be declared as arrays or structures."
+         const char *mode = NULL;
+         const char *extra = "";
+
+         /* There is no need to check for 'inout' here because the parser will
+          * only allow that in function parameter lists.
+          */
+         if (this->type->qualifier.flags.q.attribute) {
+            mode = "attribute";
+         } else if (this->type->qualifier.flags.q.uniform) {
+            mode = "uniform";
+         } else if (this->type->qualifier.flags.q.varying) {
+            mode = "varying";
+         } else if (this->type->qualifier.flags.q.in) {
+            mode = "in";
+            extra = " or in function parameter list";
+         } else if (this->type->qualifier.flags.q.out) {
+            mode = "out";
+            extra = " or in function parameter list";
+         }
+
+         if (mode) {
+            _mesa_glsl_error(& loc, state,
+                             "%s variable `%s' must be declared at "
+                             "global scope%s",
+                             mode, var->name, extra);
+         }
+      } else if (var->data.mode == ir_var_shader_in) {
+         var->data.read_only = true;
+
+         if (state->stage == MESA_SHADER_VERTEX) {
+            bool error_emitted = false;
+
+            /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
+             *
+             *    "Vertex shader inputs can only be float, floating-point
+             *    vectors, matrices, signed and unsigned integers and integer
+             *    vectors. Vertex shader inputs can also form arrays of these
+             *    types, but not structures."
+             *
+             * From page 31 (page 27 of the PDF) of the GLSL 1.30 spec:
+             *
+             *    "Vertex shader inputs can only be float, floating-point
+             *    vectors, matrices, signed and unsigned integers and integer
+             *    vectors. They cannot be arrays or structures."
+             *
+             * From page 23 (page 29 of the PDF) of the GLSL 1.20 spec:
+             *
+             *    "The attribute qualifier can be used only with float,
+             *    floating-point vectors, and matrices. Attribute variables
+             *    cannot be declared as arrays or structures."
              *
              * From page 33 (page 39 of the PDF) of the GLSL ES 3.00 spec:
              *
@@ -3107,34 +3577,35 @@ ast_declarator_list::hir(exec_list *instructions,
              *    vectors, matrices, signed and unsigned integers and integer
              *    vectors. Vertex shader inputs cannot be arrays or
              *    structures."
-            */
-           const glsl_type *check_type = var->type->is_array()
-              ? var->type->fields.array : var->type;
-
-           switch (check_type->base_type) {
-           case GLSL_TYPE_FLOAT:
-              break;
-           case GLSL_TYPE_UINT:
-           case GLSL_TYPE_INT:
-              if (state->is_version(120, 300))
-                 break;
-              /* FALLTHROUGH */
-           default:
-              _mesa_glsl_error(& loc, state,
-                               "vertex shader input / attribute cannot have "
-                               "type %s`%s'",
-                               var->type->is_array() ? "array of " : "",
-                               check_type->name);
-              error_emitted = true;
-           }
-
-           if (!error_emitted && var->type->is_array() &&
+             */
+            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:
+            break;
+            case GLSL_TYPE_UINT:
+            case GLSL_TYPE_INT:
+               if (state->is_version(120, 300))
+                  break;
+            /* FALLTHROUGH */
+            default:
+               _mesa_glsl_error(& loc, state,
+                                "vertex shader input / attribute cannot have "
+                                "type %s`%s'",
+                                var->type->is_array() ? "array of " : "",
+                                check_type->name);
+               error_emitted = true;
+            }
+
+            if (!error_emitted && var->type->is_array() &&
                 !state->check_version(150, 0, &loc,
                                       "vertex shader input / attribute "
                                       "cannot have array type")) {
-              error_emitted = true;
-           }
-        } else if (state->target == geometry_shader) {
+               error_emitted = true;
+            }
+         } 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
@@ -3150,6 +3621,51 @@ ast_declarator_list::hir(exec_list *instructions,
 
             handle_geometry_shader_input_decl(state, loc, var);
          }
+      } else if (var->data.mode == ir_var_shader_out) {
+         const glsl_type *check_type = var->type->without_array();
+
+         /* From section 4.3.6 (Output variables) of the GLSL 4.40 spec:
+          *
+          *     It is a compile-time error to declare a vertex, tessellation
+          *     evaluation, tessellation control, or geometry shader output
+          *     that contains any of the following:
+          *
+          *     * A Boolean type (bool, bvec2 ...)
+          *     * An opaque type
+          */
+         if (check_type->is_boolean() || check_type->contains_opaque())
+            _mesa_glsl_error(&loc, state,
+                             "%s shader output cannot have type %s",
+                             _mesa_shader_stage_to_string(state->stage),
+                             check_type->name);
+
+         /* From section 4.3.6 (Output variables) of the GLSL 4.40 spec:
+          *
+          *     It is a compile-time error to declare a fragment shader output
+          *     that contains any of the following:
+          *
+          *     * A Boolean type (bool, bvec2 ...)
+          *     * A double-precision scalar or vector (double, dvec2 ...)
+          *     * An opaque type
+          *     * Any matrix type
+          *     * A structure
+          */
+         if (state->stage == MESA_SHADER_FRAGMENT) {
+            if (check_type->is_record() || check_type->is_matrix())
+               _mesa_glsl_error(&loc, state,
+                                "fragment shader output "
+                                "cannot have struct or array type");
+            switch (check_type->base_type) {
+            case GLSL_TYPE_UINT:
+            case GLSL_TYPE_INT:
+            case GLSL_TYPE_FLOAT:
+               break;
+            default:
+               _mesa_glsl_error(&loc, state,
+                                "fragment shader output cannot have "
+                                "type %s", check_type->name);
+            }
+         }
       }
 
       /* Integer fragment inputs must be qualified with 'flat'.  In GLSL ES,
@@ -3183,17 +3699,26 @@ ast_declarator_list::hir(exec_list *instructions,
        */
       if (state->is_version(130, 300) &&
           var->type->contains_integer() &&
-          var->interpolation != INTERP_QUALIFIER_FLAT &&
-          ((state->target == fragment_shader && var->mode == ir_var_shader_in)
-           || (state->target == vertex_shader && var->mode == ir_var_shader_out
+          var->data.interpolation != INTERP_QUALIFIER_FLAT &&
+          ((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 == vertex_shader) ?
+         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'",
                           var_type);
       }
 
+      /* Double fragment inputs must be qualified with 'flat'. */
+      if (var->type->contains_double() &&
+          var->data.interpolation != INTERP_QUALIFIER_FLAT &&
+          state->stage == MESA_SHADER_FRAGMENT &&
+          var->data.mode == ir_var_shader_in) {
+         _mesa_glsl_error(&loc, state, "if a fragment input is (or contains) "
+                          "a double, then it must be qualified with 'flat'",
+                          var_type);
+      }
 
       /* Interpolation qualifiers cannot be applied to 'centroid' and
        * 'centroid varying'.
@@ -3243,15 +3768,15 @@ ast_declarator_list::hir(exec_list *instructions,
          const char *i = this->type->qualifier.interpolation_string();
          assert(i != NULL);
 
-         switch (state->target) {
-         case vertex_shader:
+         switch (state->stage) {
+         case MESA_SHADER_VERTEX:
             if (this->type->qualifier.flags.q.in) {
                _mesa_glsl_error(&loc, state,
                                 "qualifier '%s' cannot be applied to vertex "
                                 "shader inputs", i);
             }
             break;
-         case fragment_shader:
+         case MESA_SHADER_FRAGMENT:
             if (this->type->qualifier.flags.q.out) {
                _mesa_glsl_error(&loc, state,
                                 "qualifier '%s' cannot be applied to fragment "
@@ -3264,45 +3789,6 @@ ast_declarator_list::hir(exec_list *instructions,
       }
 
 
-      /* From section 4.3.4 of the GLSL 1.30 spec:
-       *    "It is an error to use centroid in in a vertex shader."
-       *
-       * From section 4.3.4 of the GLSL ES 3.00 spec:
-       *    "It is an error to use centroid in or interpolation qualifiers in
-       *    a vertex shader input."
-       */
-      if (state->is_version(130, 300)
-          && this->type->qualifier.flags.q.centroid
-          && this->type->qualifier.flags.q.in
-          && state->target == vertex_shader) {
-
-         _mesa_glsl_error(&loc, state,
-                          "'centroid in' cannot be used in a vertex shader");
-      }
-
-      if (state->target == vertex_shader
-          && this->type->qualifier.flags.q.sample
-          && this->type->qualifier.flags.q.in) {
-
-         _mesa_glsl_error(&loc, state,
-                        "'sample in' cannot be used in a vertex shader");
-      }
-
-      /* Section 4.3.6 of the GLSL 1.30 specification states:
-       * "It is an error to use centroid out in a fragment shader."
-       *
-       * The GL_ARB_shading_language_420pack extension specification states:
-       * "It is an error to use auxiliary storage qualifiers or interpolation
-       *  qualifiers on an output in a fragment shader."
-       */
-      if (state->target == fragment_shader &&
-          this->type->qualifier.flags.q.out &&
-          this->type->qualifier.has_auxiliary_storage()) {
-         _mesa_glsl_error(&loc, state,
-                          "auxiliary storage qualifiers cannot be used on "
-                          "fragment shader outputs");
-      }
-
       /* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30.
        */
       if (this->type->qualifier.precision != ast_precision_none) {
@@ -3310,56 +3796,28 @@ ast_declarator_list::hir(exec_list *instructions,
       }
 
 
-      /* Precision qualifiers apply to floating point, integer and sampler
-       * types.
-       *
-       * Section 4.5.2 (Precision Qualifiers) of the GLSL 1.30 spec says:
-       *    "Any floating point or any integer declaration can have the type
-       *    preceded by one of these precision qualifiers [...] Literal
-       *    constants do not have precision qualifiers. Neither do Boolean
-       *    variables.
-       *
-       * Section 4.5 (Precision and Precision Qualifiers) of the GLSL 1.30
-       * spec also says:
-       *
-       *     "Precision qualifiers are added for code portability with OpenGL
-       *     ES, not for functionality. They have the same syntax as in OpenGL
-       *     ES."
-       *
-       * Section 8 (Built-In Functions) of the GLSL ES 1.00 spec says:
-       *
-       *     "uniform lowp sampler2D sampler;
-       *     highp vec2 coord;
-       *     ...
-       *     lowp vec4 col = texture2D (sampler, coord);
-       *                                            // texture2D returns lowp"
-       *
-       * From this, we infer that GLSL 1.30 (and later) should allow precision
-       * qualifiers on sampler types just like float and integer types.
+      /* If a precision qualifier is allowed on a type, it is allowed on
+       * an array of that type.
        */
-      if (this->type->qualifier.precision != ast_precision_none
-          && !var->type->is_float()
-          && !var->type->is_integer()
-          && !var->type->is_record()
-          && !var->type->is_sampler()
-          && !(var->type->is_array()
-               && (var->type->fields.array->is_float()
-                   || var->type->fields.array->is_integer()))) {
+      if (!(this->type->qualifier.precision == ast_precision_none
+          || precision_qualifier_allowed(var->type)
+          || (var->type->is_array()
+             && precision_qualifier_allowed(var->type->fields.array)))) {
 
          _mesa_glsl_error(&loc, state,
                           "precision qualifiers apply only to floating point"
                           ", 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
@@ -3369,23 +3827,27 @@ ast_declarator_list::hir(exec_list *instructions,
        * instruction stream.
        */
       exec_list initializer_instructions;
+
+      /* Examine var name here since var may get deleted in the next call */
+      bool var_is_gl_id = is_gl_identifier(var->name);
+
       ir_variable *earlier =
          get_variable_being_redeclared(var, decl->get_location(), state,
                                        false /* allow_all_redeclarations */);
       if (earlier != NULL) {
-         if (strncmp(var->name, "gl_", 3) == 0 &&
-             earlier->how_declared == ir_var_declared_in_block) {
+         if (var_is_gl_id &&
+             earlier->data.how_declared == ir_var_declared_in_block) {
             _mesa_glsl_error(&loc, state,
                              "`%s' has already been redeclared using "
-                             "gl_PerVertex", var->name);
+                             "gl_PerVertex", earlier->name);
          }
-         earlier->how_declared = ir_var_declared_normally;
+         earlier->data.how_declared = ir_var_declared_normally;
       }
 
       if (decl->initializer != NULL) {
-        result = process_initializer((earlier == NULL) ? var : earlier,
-                                     decl, this->type,
-                                     &initializer_instructions, state);
+         result = process_initializer((earlier == NULL) ? var : earlier,
+                                      decl, this->type,
+                                      &initializer_instructions, state);
       }
 
       /* From page 23 (page 29 of the PDF) of the GLSL 1.10 spec:
@@ -3395,14 +3857,14 @@ ast_declarator_list::hir(exec_list *instructions,
        *      declared."
        */
       if (this->type->qualifier.flags.q.constant && decl->initializer == NULL) {
-        _mesa_glsl_error(& loc, state,
-                         "const declaration of `%s' must be initialized",
-                         decl->identifier);
+         _mesa_glsl_error(& loc, state,
+                          "const declaration of `%s' must be initialized",
+                          decl->identifier);
       }
 
       if (state->es_shader) {
-        const glsl_type *const t = (earlier == NULL)
-           ? var->type : earlier->type;
+         const glsl_type *const t = (earlier == NULL)
+            ? var->type : earlier->type;
 
          if (t->is_unsized_array())
             /* Section 10.17 of the GLSL ES 1.00 specification states that
@@ -3434,32 +3896,32 @@ ast_declarator_list::hir(exec_list *instructions,
       if (earlier == NULL) {
          validate_identifier(decl->identifier, loc, state);
 
-        /* Add the variable to the symbol table.  Note that the initializer's
-         * IR was already processed earlier (though it hasn't been emitted
-         * yet), without the variable in scope.
-         *
-         * This differs from most C-like languages, but it follows the GLSL
-         * specification.  From page 28 (page 34 of the PDF) of the GLSL 1.50
-         * spec:
-         *
-         *     "Within a declaration, the scope of a name starts immediately
-         *     after the initializer if present or immediately after the name
-         *     being declared if not."
-         */
-        if (!state->symbols->add_variable(var)) {
-           YYLTYPE loc = this->get_location();
-           _mesa_glsl_error(&loc, state, "name `%s' already taken in the "
-                            "current scope", decl->identifier);
-           continue;
-        }
-
-        /* Push the variable declaration to the top.  It means that all the
-         * variable declarations will appear in a funny last-to-first order,
-         * but otherwise we run into trouble if a function is prototyped, a
-         * global var is decled, then the function is defined with usage of
-         * the global var.  See glslparsertest's CorrectModule.frag.
-         */
-        instructions->push_head(var);
+         /* Add the variable to the symbol table.  Note that the initializer's
+          * IR was already processed earlier (though it hasn't been emitted
+          * yet), without the variable in scope.
+          *
+          * This differs from most C-like languages, but it follows the GLSL
+          * specification.  From page 28 (page 34 of the PDF) of the GLSL 1.50
+          * spec:
+          *
+          *     "Within a declaration, the scope of a name starts immediately
+          *     after the initializer if present or immediately after the name
+          *     being declared if not."
+          */
+         if (!state->symbols->add_variable(var)) {
+            YYLTYPE loc = this->get_location();
+            _mesa_glsl_error(&loc, state, "name `%s' already taken in the "
+                             "current scope", decl->identifier);
+            continue;
+         }
+
+         /* Push the variable declaration to the top.  It means that all the
+          * variable declarations will appear in a funny last-to-first order,
+          * but otherwise we run into trouble if a function is prototyped, a
+          * global var is decled, then the function is defined with usage of
+          * the global var.  See glslparsertest's CorrectModule.frag.
+          */
+         instructions->push_head(var);
       }
 
       instructions->append_list(&initializer_instructions);
@@ -3481,7 +3943,7 @@ ast_declarator_list::hir(exec_list *instructions,
 
 ir_rvalue *
 ast_parameter_declarator::hir(exec_list *instructions,
-                             struct _mesa_glsl_parse_state *state)
+                              struct _mesa_glsl_parse_state *state)
 {
    void *ctx = state;
    const struct glsl_type *type;
@@ -3492,13 +3954,13 @@ ast_parameter_declarator::hir(exec_list *instructions,
 
    if (type == NULL) {
       if (name != NULL) {
-        _mesa_glsl_error(& loc, state,
-                         "invalid type `%s' in declaration of `%s'",
-                         name, this->identifier);
+         _mesa_glsl_error(& loc, state,
+                          "invalid type `%s' in declaration of `%s'",
+                          name, this->identifier);
       } else {
-        _mesa_glsl_error(& loc, state,
-                         "invalid type in declaration of `%s'",
-                         this->identifier);
+         _mesa_glsl_error(& loc, state,
+                          "invalid type in declaration of `%s'",
+                          this->identifier);
       }
 
       type = glsl_type::error_type;
@@ -3518,8 +3980,8 @@ ast_parameter_declarator::hir(exec_list *instructions,
     */
    if (type->is_void()) {
       if (this->identifier != NULL)
-        _mesa_glsl_error(& loc, state,
-                         "named parameter cannot have type `void'");
+         _mesa_glsl_error(& loc, state,
+                          "named parameter cannot have type `void'");
 
       is_void = true;
       return NULL;
@@ -3533,13 +3995,11 @@ 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 "
-                      "a declared size");
+                       "a declared size");
       type = glsl_type::error_type;
    }
 
@@ -3551,17 +4011,18 @@ ast_parameter_declarator::hir(exec_list *instructions,
     * for function parameters the default mode is 'in'.
     */
    apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc,
-                                   true);
+                                    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->mode == ir_var_function_inout || var->mode == ir_var_function_out)
-       && type->contains_sampler()) {
-      _mesa_glsl_error(&loc, state, "out and inout parameters cannot contain samplers");
+   if ((var->data.mode == ir_var_function_inout || var->data.mode == ir_var_function_out)
+       && type->contains_opaque()) {
+      _mesa_glsl_error(&loc, state, "out and inout parameters cannot "
+                       "contain opaque variables");
       type = glsl_type::error_type;
    }
 
@@ -3579,7 +4040,7 @@ ast_parameter_declarator::hir(exec_list *instructions,
     * So for GLSL 1.10, passing an array as an out or inout parameter is not
     * allowed.  This restriction is removed in GLSL 1.20, and in GLSL ES.
     */
-   if ((var->mode == ir_var_function_inout || var->mode == ir_var_function_out)
+   if ((var->data.mode == ir_var_function_inout || var->data.mode == ir_var_function_out)
        && type->is_array()
        && !state->check_version(120, 100, &loc,
                                 "arrays cannot be out or inout parameters")) {
@@ -3596,9 +4057,9 @@ ast_parameter_declarator::hir(exec_list *instructions,
 
 void
 ast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters,
-                                           bool formal,
-                                           exec_list *ir_parameters,
-                                           _mesa_glsl_parse_state *state)
+                                            bool formal,
+                                            exec_list *ir_parameters,
+                                            _mesa_glsl_parse_state *state)
 {
    ast_parameter_declarator *void_param = NULL;
    unsigned count = 0;
@@ -3608,7 +4069,7 @@ ast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters,
       param->hir(ir_parameters, state);
 
       if (param->is_void)
-        void_param = param;
+         void_param = param;
 
       count++;
    }
@@ -3617,7 +4078,7 @@ ast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters,
       YYLTYPE loc = void_param->get_location();
 
       _mesa_glsl_error(& loc, state,
-                      "`void' parameter must be only parameter");
+                       "`void' parameter must be only parameter");
    }
 }
 
@@ -3638,7 +4099,7 @@ emit_function(_mesa_glsl_parse_state *state, ir_function *f)
 
 ir_rvalue *
 ast_function::hir(exec_list *instructions,
-                 struct _mesa_glsl_parse_state *state)
+                  struct _mesa_glsl_parse_state *state)
 {
    void *ctx = state;
    ir_function *f = NULL;
@@ -3680,8 +4141,8 @@ ast_function::hir(exec_list *instructions,
     * signatures for functions with the same name.
     */
    ast_parameter_declarator::parameters_to_hir(& this->parameters,
-                                              is_definition,
-                                              & hir_parameters, state);
+                                               is_definition,
+                                               & hir_parameters, state);
 
    const char *return_type_name;
    const glsl_type *return_type =
@@ -3690,8 +4151,8 @@ ast_function::hir(exec_list *instructions,
    if (!return_type) {
       YYLTYPE loc = this->get_location();
       _mesa_glsl_error(&loc, state,
-                      "function `%s' has undeclared return type `%s'",
-                      name, return_type_name);
+                       "function `%s' has undeclared return type `%s'",
+                       name, return_type_name);
       return_type = glsl_type::error_type;
    }
 
@@ -3701,7 +4162,7 @@ ast_function::hir(exec_list *instructions,
    if (this->return_type->has_qualifiers()) {
       YYLTYPE loc = this->get_location();
       _mesa_glsl_error(& loc, state,
-                      "function `%s' return type has qualifiers", name);
+                       "function `%s' return type has qualifiers", name);
    }
 
    /* Section 6.1 (Function Definitions) of the GLSL 1.20 spec says:
@@ -3712,44 +4173,80 @@ ast_function::hir(exec_list *instructions,
    if (return_type->is_unsized_array()) {
       YYLTYPE loc = this->get_location();
       _mesa_glsl_error(& loc, state,
-                      "function `%s' return type array must be explicitly "
-                      "sized", name);
+                       "function `%s' return type array must be explicitly "
+                       "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);
    }
 
+   /* Create an ir_function if one doesn't already exist. */
+   f = state->symbols->get_function(name);
+   if (f == NULL) {
+      f = new(ctx) ir_function(name);
+      if (!state->symbols->add_function(f)) {
+         /* This function name shadows a non-function use of the same name. */
+         YYLTYPE loc = this->get_location();
+
+         _mesa_glsl_error(&loc, state, "function name `%s' conflicts with "
+                          "non-function", name);
+         return NULL;
+      }
+
+      emit_function(state, f);
+   }
+
+   /* From GLSL ES 3.0 spec, chapter 6.1 "Function Definitions", page 71:
+    *
+    * "A shader cannot redefine or overload built-in functions."
+    *
+    * While in GLSL ES 1.0 specification, chapter 8 "Built-in Functions":
+    *
+    * "User code can overload the built-in functions but cannot redefine
+    * them."
+    */
+   if (state->es_shader && state->language_version >= 300) {
+      /* Local shader has no exact candidates; check the built-ins. */
+      _mesa_glsl_initialize_builtin_functions();
+      if (_mesa_glsl_find_builtin_function_by_name(state, name)) {
+         YYLTYPE loc = this->get_location();
+         _mesa_glsl_error(& loc, state,
+                          "A shader cannot redefine or overload built-in "
+                          "function `%s' in GLSL ES 3.00", name);
+         return NULL;
+      }
+   }
+
    /* Verify that this function's signature either doesn't match a previously
     * seen signature for a function with the same name, or, if a match is found,
     * that the previously seen signature does not have an associated definition.
     */
-   f = state->symbols->get_function(name);
-   if (f != NULL && (state->es_shader || f->has_user_signature())) {
+   if (state->es_shader || f->has_user_signature()) {
       sig = f->exact_matching_signature(state, &hir_parameters);
       if (sig != NULL) {
-        const char *badvar = sig->qualifiers_match(&hir_parameters);
-        if (badvar != NULL) {
-           YYLTYPE loc = this->get_location();
+         const char *badvar = sig->qualifiers_match(&hir_parameters);
+         if (badvar != NULL) {
+            YYLTYPE loc = this->get_location();
 
-           _mesa_glsl_error(&loc, state, "function `%s' parameter `%s' "
-                            "qualifiers don't match prototype", name, badvar);
-        }
+            _mesa_glsl_error(&loc, state, "function `%s' parameter `%s' "
+                             "qualifiers don't match prototype", name, badvar);
+         }
 
-        if (sig->return_type != return_type) {
-           YYLTYPE loc = this->get_location();
+         if (sig->return_type != return_type) {
+            YYLTYPE loc = this->get_location();
 
-           _mesa_glsl_error(&loc, state, "function `%s' return type doesn't "
-                            "match prototype", name);
-        }
+            _mesa_glsl_error(&loc, state, "function `%s' return type doesn't "
+                             "match prototype", name);
+         }
 
          if (sig->is_defined) {
             if (is_definition) {
@@ -3762,34 +4259,22 @@ ast_function::hir(exec_list *instructions,
                 */
                return NULL;
             }
-        }
-      }
-   } else {
-      f = new(ctx) ir_function(name);
-      if (!state->symbols->add_function(f)) {
-        /* This function name shadows a non-function use of the same name. */
-        YYLTYPE loc = this->get_location();
-
-        _mesa_glsl_error(&loc, state, "function name `%s' conflicts with "
-                         "non-function", name);
-        return NULL;
+         }
       }
-
-      emit_function(state, f);
    }
 
    /* Verify the return type of main() */
    if (strcmp(name, "main") == 0) {
       if (! return_type->is_void()) {
-        YYLTYPE loc = this->get_location();
+         YYLTYPE loc = this->get_location();
 
-        _mesa_glsl_error(& loc, state, "main() must return void");
+         _mesa_glsl_error(& loc, state, "main() must return void");
       }
 
       if (!hir_parameters.is_empty()) {
-        YYLTYPE loc = this->get_location();
+         YYLTYPE loc = this->get_location();
 
-        _mesa_glsl_error(& loc, state, "main() must not take any parameters");
+         _mesa_glsl_error(& loc, state, "main() must not take any parameters");
       }
    }
 
@@ -3811,7 +4296,7 @@ ast_function::hir(exec_list *instructions,
 
 ir_rvalue *
 ast_function_definition::hir(exec_list *instructions,
-                            struct _mesa_glsl_parse_state *state)
+                             struct _mesa_glsl_parse_state *state)
 {
    prototype->is_definition = true;
    prototype->hir(instructions, state);
@@ -3828,20 +4313,18 @@ 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();
-
-      assert(var != NULL);
+   foreach_in_list(ir_variable, var, &signature->parameters) {
+      assert(var->as_variable() != NULL);
 
       /* The only way a parameter would "exist" is if two parameters have
        * the same name.
        */
       if (state->symbols->name_declared_this_scope(var->name)) {
-        YYLTYPE loc = this->get_location();
+         YYLTYPE loc = this->get_location();
 
-        _mesa_glsl_error(& loc, state, "parameter `%s' redeclared", var->name);
+         _mesa_glsl_error(& loc, state, "parameter `%s' redeclared", var->name);
       } else {
-        state->symbols->add_variable(var);
+         state->symbols->add_variable(var);
       }
    }
 
@@ -3857,9 +4340,9 @@ ast_function_definition::hir(exec_list *instructions,
    if (!signature->return_type->is_void() && !state->found_return) {
       YYLTYPE loc = this->get_location();
       _mesa_glsl_error(& loc, state, "function `%s' has non-void return type "
-                      "%s, but no return statement",
-                      signature->function_name(),
-                      signature->return_type->name);
+                       "%s, but no return statement",
+                       signature->function_name(),
+                       signature->return_type->name);
    }
 
    /* Function definitions do not have r-values.
@@ -3870,7 +4353,7 @@ ast_function_definition::hir(exec_list *instructions,
 
 ir_rvalue *
 ast_jump_statement::hir(exec_list *instructions,
-                       struct _mesa_glsl_parse_state *state)
+                        struct _mesa_glsl_parse_state *state)
 {
    void *ctx = state;
 
@@ -3880,23 +4363,23 @@ ast_jump_statement::hir(exec_list *instructions,
       assert(state->current_function);
 
       if (opt_return_value) {
-        ir_rvalue *ret = opt_return_value->hir(instructions, state);
-
-        /* The value of the return type can be NULL if the shader says
-         * 'return foo();' and foo() is a function that returns void.
-         *
-         * NOTE: The GLSL spec doesn't say that this is an error.  The type
-         * of the return value is void.  If the return type of the function is
-         * also void, then this should compile without error.  Seriously.
-         */
-        const glsl_type *const ret_type =
-           (ret == NULL) ? glsl_type::void_type : ret->type;
+         ir_rvalue *ret = opt_return_value->hir(instructions, state);
+
+         /* The value of the return type can be NULL if the shader says
+          * 'return foo();' and foo() is a function that returns void.
+          *
+          * NOTE: The GLSL spec doesn't say that this is an error.  The type
+          * of the return value is void.  If the return type of the function is
+          * also void, then this should compile without error.  Seriously.
+          */
+         const glsl_type *const ret_type =
+            (ret == NULL) ? glsl_type::void_type : ret->type;
 
          /* Implicit conversions are not allowed for return values prior to
           * ARB_shading_language_420pack.
           */
          if (state->current_function->return_type != ret_type) {
-           YYLTYPE loc = this->get_location();
+            YYLTYPE loc = this->get_location();
 
             if (state->ARB_shading_language_420pack_enable) {
                if (!apply_implicit_conversion(state->current_function->return_type,
@@ -3933,18 +4416,18 @@ ast_jump_statement::hir(exec_list *instructions,
                              "return argument");
          }
 
-        inst = new(ctx) ir_return(ret);
+         inst = new(ctx) ir_return(ret);
       } else {
-        if (state->current_function->return_type->base_type !=
-            GLSL_TYPE_VOID) {
-           YYLTYPE loc = this->get_location();
-
-           _mesa_glsl_error(& loc, state,
-                            "`return' with no value, in function %s returning "
-                            "non-void",
-                            state->current_function->function_name());
-        }
-        inst = new(ctx) ir_return;
+         if (state->current_function->return_type->base_type !=
+             GLSL_TYPE_VOID) {
+            YYLTYPE loc = this->get_location();
+
+            _mesa_glsl_error(& loc, state,
+                             "`return' with no value, in function %s returning "
+                             "non-void",
+            state->current_function->function_name());
+         }
+         inst = new(ctx) ir_return;
       }
 
       state->found_return = true;
@@ -3953,11 +4436,11 @@ ast_jump_statement::hir(exec_list *instructions,
    }
 
    case ast_discard:
-      if (state->target != fragment_shader) {
-        YYLTYPE loc = this->get_location();
+      if (state->stage != MESA_SHADER_FRAGMENT) {
+         YYLTYPE loc = this->get_location();
 
-        _mesa_glsl_error(& loc, state,
-                         "`discard' may only appear in a fragment shader");
+         _mesa_glsl_error(& loc, state,
+                          "`discard' may only appear in a fragment shader");
       }
       instructions->push_tail(new(ctx) ir_discard);
       break;
@@ -3965,51 +4448,63 @@ ast_jump_statement::hir(exec_list *instructions,
    case ast_break:
    case ast_continue:
       if (mode == ast_continue &&
-         state->loop_nesting_ast == NULL) {
-        YYLTYPE loc = this->get_location();
+          state->loop_nesting_ast == NULL) {
+         YYLTYPE loc = this->get_location();
 
-        _mesa_glsl_error(& loc, state,
-                         "continue may only appear in a loop");
+         _mesa_glsl_error(& loc, state, "continue may only appear in a loop");
       } else if (mode == ast_break &&
-                state->loop_nesting_ast == NULL &&
-                state->switch_state.switch_nesting_ast == NULL) {
-        YYLTYPE loc = this->get_location();
+         state->loop_nesting_ast == NULL &&
+         state->switch_state.switch_nesting_ast == NULL) {
+         YYLTYPE loc = this->get_location();
 
-        _mesa_glsl_error(& loc, state,
-                         "break may only appear in a loop or a switch");
+         _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.
-         */
-        if (state->loop_nesting_ast != NULL &&
-            mode == ast_continue &&
-            state->loop_nesting_ast->rest_expression) {
-           state->loop_nesting_ast->rest_expression->hir(instructions,
-                                                         state);
-        }
-
-        if (state->switch_state.is_switch_innermost &&
-            mode == ast_break) {
-           /* Force break out of switch by setting is_break switch state.
-            */
-           ir_variable *const is_break_var = state->switch_state.is_break_var;
-           ir_dereference_variable *const deref_is_break_var =
-              new(ctx) ir_dereference_variable(is_break_var);
-           ir_constant *const true_val = new(ctx) ir_constant(true);
-           ir_assignment *const set_break_var =
-              new(ctx) ir_assignment(deref_is_break_var, true_val);
-           
-           instructions->push_tail(set_break_var);
-        }
-        else {
-           ir_loop_jump *const jump = 
-              new(ctx) ir_loop_jump((mode == ast_break)
-                                    ? ir_loop_jump::jump_break
-                                    : ir_loop_jump::jump_continue);
-           instructions->push_tail(jump);
-        }
+         /* 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->switch_state.is_switch_innermost) {
+            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_continue) {
+            /* Set 'continue_inside' to true. */
+            ir_rvalue *const true_val = new (ctx) ir_constant(true);
+            ir_dereference_variable *deref_continue_inside_var =
+               new(ctx) ir_dereference_variable(state->switch_state.continue_inside);
+            instructions->push_tail(new(ctx) ir_assignment(deref_continue_inside_var,
+                                                           true_val));
+
+            /* Break out from the switch, continue for the loop will
+             * be called right after switch. */
+            ir_loop_jump *const jump =
+               new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
+            instructions->push_tail(jump);
+
+         } else if (state->switch_state.is_switch_innermost &&
+             mode == ast_break) {
+            /* Force break out of switch by inserting a break. */
+            ir_loop_jump *const jump =
+               new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
+            instructions->push_tail(jump);
+         } else {
+            ir_loop_jump *const jump =
+               new(ctx) ir_loop_jump((mode == ast_break)
+                  ? ir_loop_jump::jump_break
+                  : ir_loop_jump::jump_continue);
+            instructions->push_tail(jump);
+         }
       }
 
       break;
@@ -4023,7 +4518,7 @@ ast_jump_statement::hir(exec_list *instructions,
 
 ir_rvalue *
 ast_selection_statement::hir(exec_list *instructions,
-                            struct _mesa_glsl_parse_state *state)
+                             struct _mesa_glsl_parse_state *state)
 {
    void *ctx = state;
 
@@ -4042,7 +4537,7 @@ ast_selection_statement::hir(exec_list *instructions,
       YYLTYPE loc = this->condition->get_location();
 
       _mesa_glsl_error(& loc, state, "if-statement condition must be scalar "
-                      "boolean");
+                       "boolean");
    }
 
    ir_if *const stmt = new(ctx) ir_if(condition);
@@ -4069,7 +4564,7 @@ ast_selection_statement::hir(exec_list *instructions,
 
 ir_rvalue *
 ast_switch_statement::hir(exec_list *instructions,
-                         struct _mesa_glsl_parse_state *state)
+                          struct _mesa_glsl_parse_state *state)
 {
    void *ctx = state;
 
@@ -4086,9 +4581,9 @@ ast_switch_statement::hir(exec_list *instructions,
       YYLTYPE loc = this->test_expression->get_location();
 
       _mesa_glsl_error(& loc,
-                      state,
-                      "switch-statement expression must be scalar "
-                      "integer");
+                       state,
+                       "switch-statement expression must be scalar "
+                       "integer");
    }
 
    /* Track the switch-statement nesting in a stack-like manner.
@@ -4106,35 +4601,71 @@ ast_switch_statement::hir(exec_list *instructions,
    ir_rvalue *const is_fallthru_val = new (ctx) ir_constant(false);
    state->switch_state.is_fallthru_var =
       new(ctx) ir_variable(glsl_type::bool_type,
-                          "switch_is_fallthru_tmp",
-                          ir_var_temporary);
+                           "switch_is_fallthru_tmp",
+                           ir_var_temporary);
    instructions->push_tail(state->switch_state.is_fallthru_var);
 
    ir_dereference_variable *deref_is_fallthru_var =
       new(ctx) ir_dereference_variable(state->switch_state.is_fallthru_var);
    instructions->push_tail(new(ctx) ir_assignment(deref_is_fallthru_var,
-                                                 is_fallthru_val));
+                                                  is_fallthru_val));
 
-   /* Initalize is_break state to false.
+   /* Initialize continue_inside state to false.
     */
-   ir_rvalue *const is_break_val = new (ctx) ir_constant(false);
-   state->switch_state.is_break_var = new(ctx) ir_variable(glsl_type::bool_type,
-                                                          "switch_is_break_tmp",
-                                                          ir_var_temporary);
-   instructions->push_tail(state->switch_state.is_break_var);
+   state->switch_state.continue_inside =
+      new(ctx) ir_variable(glsl_type::bool_type,
+                           "continue_inside_tmp",
+                           ir_var_temporary);
+   instructions->push_tail(state->switch_state.continue_inside);
 
-   ir_dereference_variable *deref_is_break_var =
-      new(ctx) ir_dereference_variable(state->switch_state.is_break_var);
-   instructions->push_tail(new(ctx) ir_assignment(deref_is_break_var,
-                                                 is_break_val));
+   ir_rvalue *const false_val = new (ctx) ir_constant(false);
+   ir_dereference_variable *deref_continue_inside_var =
+      new(ctx) ir_dereference_variable(state->switch_state.continue_inside);
+   instructions->push_tail(new(ctx) ir_assignment(deref_continue_inside_var,
+                                                  false_val));
+
+   state->switch_state.run_default =
+      new(ctx) ir_variable(glsl_type::bool_type,
+                             "run_default_tmp",
+                             ir_var_temporary);
+   instructions->push_tail(state->switch_state.run_default);
+
+   /* Loop around the switch is used for flow control. */
+   ir_loop * loop = new(ctx) ir_loop();
+   instructions->push_tail(loop);
 
    /* Cache test expression.
     */
-   test_to_hir(instructions, state);
+   test_to_hir(&loop->body_instructions, state);
 
    /* Emit code for body of switch stmt.
     */
-   body->hir(instructions, state);
+   body->hir(&loop->body_instructions, state);
+
+   /* Insert a break at the end to exit loop. */
+   ir_loop_jump *jump = new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
+   loop->body_instructions.push_tail(jump);
+
+   /* If we are inside loop, check if continue got called inside switch. */
+   if (state->loop_nesting_ast != NULL) {
+      ir_dereference_variable *deref_continue_inside =
+         new(ctx) ir_dereference_variable(state->switch_state.continue_inside);
+      ir_if *irif = new(ctx) ir_if(deref_continue_inside);
+      ir_loop_jump *jump = new(ctx) ir_loop_jump(ir_loop_jump::jump_continue);
+
+      if (state->loop_nesting_ast != NULL) {
+         if (state->loop_nesting_ast->rest_expression) {
+            state->loop_nesting_ast->rest_expression->hir(&irif->then_instructions,
+                                                          state);
+         }
+         if (state->loop_nesting_ast->mode ==
+             ast_iteration_statement::ast_do_while) {
+            state->loop_nesting_ast->condition_to_hir(&irif->then_instructions, state);
+         }
+      }
+      irif->then_instructions.push_tail(jump);
+      instructions->push_tail(irif);
+   }
 
    hash_table_dtor(state->switch_state.labels_ht);
 
@@ -4147,7 +4678,7 @@ ast_switch_statement::hir(exec_list *instructions,
 
 void
 ast_switch_statement::test_to_hir(exec_list *instructions,
-                                 struct _mesa_glsl_parse_state *state)
+                                  struct _mesa_glsl_parse_state *state)
 {
    void *ctx = state;
 
@@ -4157,8 +4688,8 @@ ast_switch_statement::test_to_hir(exec_list *instructions,
                           state);
 
    state->switch_state.test_var = new(ctx) ir_variable(test_val->type,
-                                                      "switch_test_tmp",
-                                                      ir_var_temporary);
+                                                       "switch_test_tmp",
+                                                       ir_var_temporary);
    ir_dereference_variable *deref_test_var =
       new(ctx) ir_dereference_variable(state->switch_state.test_var);
 
@@ -4169,7 +4700,7 @@ ast_switch_statement::test_to_hir(exec_list *instructions,
 
 ir_rvalue *
 ast_switch_body::hir(exec_list *instructions,
-                    struct _mesa_glsl_parse_state *state)
+                     struct _mesa_glsl_parse_state *state)
 {
    if (stmts != NULL)
       stmts->hir(instructions, state);
@@ -4180,10 +4711,73 @@ ast_switch_body::hir(exec_list *instructions,
 
 ir_rvalue *
 ast_case_statement_list::hir(exec_list *instructions,
-                            struct _mesa_glsl_parse_state *state)
+                             struct _mesa_glsl_parse_state *state)
 {
-   foreach_list_typed (ast_case_statement, case_stmt, link, & this->cases)
-      case_stmt->hir(instructions, state);
+   exec_list default_case, after_default, tmp;
+
+   foreach_list_typed (ast_case_statement, case_stmt, link, & this->cases) {
+      case_stmt->hir(&tmp, state);
+
+      /* Default case. */
+      if (state->switch_state.previous_default && default_case.is_empty()) {
+         default_case.append_list(&tmp);
+         continue;
+      }
+
+      /* If default case found, append 'after_default' list. */
+      if (!default_case.is_empty())
+         after_default.append_list(&tmp);
+      else
+         instructions->append_list(&tmp);
+   }
+
+   /* Handle the default case. This is done here because default might not be
+    * the last case. We need to add checks against following cases first to see
+    * if default should be chosen or not.
+    */
+   if (!default_case.is_empty()) {
+
+      ir_rvalue *const true_val = new (state) ir_constant(true);
+      ir_dereference_variable *deref_run_default_var =
+         new(state) ir_dereference_variable(state->switch_state.run_default);
+
+      /* Choose to run default case initially, following conditional
+       * assignments might change this.
+       */
+      ir_assignment *const init_var =
+         new(state) ir_assignment(deref_run_default_var, true_val);
+      instructions->push_tail(init_var);
+
+      /* Default case was the last one, no checks required. */
+      if (after_default.is_empty()) {
+         instructions->append_list(&default_case);
+         return NULL;
+      }
+
+      foreach_in_list(ir_instruction, ir, &after_default) {
+         ir_assignment *assign = ir->as_assignment();
+
+         if (!assign)
+            continue;
+
+         /* Clone the check between case label and init expression. */
+         ir_expression *exp = (ir_expression*) assign->condition;
+         ir_expression *clone = exp->clone(state, NULL);
+
+         ir_dereference_variable *deref_var =
+            new(state) ir_dereference_variable(state->switch_state.run_default);
+         ir_rvalue *const false_val = new (state) ir_constant(false);
+
+         ir_assignment *const set_false =
+            new(state) ir_assignment(deref_var, false_val, clone);
+
+         instructions->push_tail(set_false);
+      }
+
+      /* Append default case and all cases after it. */
+      instructions->append_list(&default_case);
+      instructions->append_list(&after_default);
+   }
 
    /* Case statements do not have r-values. */
    return NULL;
@@ -4191,22 +4785,10 @@ ast_case_statement_list::hir(exec_list *instructions,
 
 ir_rvalue *
 ast_case_statement::hir(exec_list *instructions,
-                       struct _mesa_glsl_parse_state *state)
+                        struct _mesa_glsl_parse_state *state)
 {
    labels->hir(instructions, state);
 
-   /* Conditionally set fallthru state based on break state. */
-   ir_constant *const false_val = new(state) ir_constant(false);
-   ir_dereference_variable *const deref_is_fallthru_var =
-      new(state) ir_dereference_variable(state->switch_state.is_fallthru_var);
-   ir_dereference_variable *const deref_is_break_var =
-      new(state) ir_dereference_variable(state->switch_state.is_break_var);
-   ir_assignment *const reset_fallthru_on_break =
-      new(state) ir_assignment(deref_is_fallthru_var,
-                              false_val,
-                              deref_is_break_var);
-   instructions->push_tail(reset_fallthru_on_break);
-
    /* Guard case statements depending on fallthru state. */
    ir_dereference_variable *const deref_fallthru_guard =
       new(state) ir_dereference_variable(state->switch_state.is_fallthru_var);
@@ -4224,7 +4806,7 @@ ast_case_statement::hir(exec_list *instructions,
 
 ir_rvalue *
 ast_case_label_list::hir(exec_list *instructions,
-                        struct _mesa_glsl_parse_state *state)
+                         struct _mesa_glsl_parse_state *state)
 {
    foreach_list_typed (ast_case_label, label, link, & this->labels)
       label->hir(instructions, state);
@@ -4235,7 +4817,7 @@ ast_case_label_list::hir(exec_list *instructions,
 
 ir_rvalue *
 ast_case_label::hir(exec_list *instructions,
-                   struct _mesa_glsl_parse_state *state)
+                    struct _mesa_glsl_parse_state *state)
 {
    void *ctx = state;
 
@@ -4253,62 +4835,107 @@ ast_case_label::hir(exec_list *instructions,
       ir_constant *label_const = label_rval->constant_expression_value();
 
       if (!label_const) {
-        YYLTYPE loc = this->test_value->get_location();
+         YYLTYPE loc = this->test_value->get_location();
 
-        _mesa_glsl_error(& loc, state,
-                         "switch statement case label must be a "
-                         "constant expression");
+         _mesa_glsl_error(& loc, state,
+                          "switch statement case label must be a "
+                          "constant expression");
 
-        /* Stuff a dummy value in to allow processing to continue. */
-        label_const = new(ctx) ir_constant(0);
+         /* Stuff a dummy value in to allow processing to continue. */
+         label_const = new(ctx) ir_constant(0);
       } else {
-        ast_expression *previous_label = (ast_expression *)
-           hash_table_find(state->switch_state.labels_ht,
-                           (void *)(uintptr_t)label_const->value.u[0]);
-
-        if (previous_label) {
-           YYLTYPE loc = this->test_value->get_location();
-           _mesa_glsl_error(& loc, state,
-                            "duplicate case value");
-
-           loc = previous_label->get_location();
-           _mesa_glsl_error(& loc, state,
-                            "this is the previous case label");
-        } else {
-           hash_table_insert(state->switch_state.labels_ht,
-                             this->test_value,
-                             (void *)(uintptr_t)label_const->value.u[0]);
-        }
+         ast_expression *previous_label = (ast_expression *)
+         hash_table_find(state->switch_state.labels_ht,
+                         (void *)(uintptr_t)label_const->value.u[0]);
+
+         if (previous_label) {
+            YYLTYPE loc = this->test_value->get_location();
+            _mesa_glsl_error(& loc, state, "duplicate case value");
+
+            loc = previous_label->get_location();
+            _mesa_glsl_error(& loc, state, "this is the previous case label");
+         } else {
+            hash_table_insert(state->switch_state.labels_ht,
+                              this->test_value,
+                              (void *)(uintptr_t)label_const->value.u[0]);
+         }
       }
 
       ir_dereference_variable *deref_test_var =
-        new(ctx) ir_dereference_variable(state->switch_state.test_var);
+         new(ctx) ir_dereference_variable(state->switch_state.test_var);
 
-      ir_rvalue *const test_cond = new(ctx) ir_expression(ir_binop_all_equal,
-                                                         label_const,
-                                                         deref_test_var);
+      ir_expression *test_cond = new(ctx) ir_expression(ir_binop_all_equal,
+                                                        label_const,
+                                                        deref_test_var);
+
+      /*
+       * From GLSL 4.40 specification section 6.2 ("Selection"):
+       *
+       *     "The type of the init-expression value in a switch statement must
+       *     be a scalar int or uint. The type of the constant-expression value
+       *     in a case label also must be a scalar int or uint. When any pair
+       *     of these values is tested for "equal value" and the types do not
+       *     match, an implicit conversion will be done to convert the int to a
+       *     uint (see section 4.1.10 “Implicit Conversions”) before the compare
+       *     is done."
+       */
+      if (label_const->type != state->switch_state.test_var->type) {
+         YYLTYPE loc = this->test_value->get_location();
+
+         const glsl_type *type_a = label_const->type;
+         const glsl_type *type_b = state->switch_state.test_var->type;
+
+         /* Check if int->uint implicit conversion is supported. */
+         bool integer_conversion_supported =
+            glsl_type::int_type->can_implicitly_convert_to(glsl_type::uint_type,
+                                                           state);
+
+         if ((!type_a->is_integer() || !type_b->is_integer()) ||
+              !integer_conversion_supported) {
+            _mesa_glsl_error(&loc, state, "type mismatch with switch "
+                             "init-expression and case label (%s != %s)",
+                             type_a->name, type_b->name);
+         } else {
+            /* Conversion of the case label. */
+            if (type_a->base_type == GLSL_TYPE_INT) {
+               if (!apply_implicit_conversion(glsl_type::uint_type,
+                                              test_cond->operands[0], state))
+                  _mesa_glsl_error(&loc, state, "implicit type conversion error");
+            } else {
+               /* Conversion of the init-expression value. */
+               if (!apply_implicit_conversion(glsl_type::uint_type,
+                                              test_cond->operands[1], state))
+                  _mesa_glsl_error(&loc, state, "implicit type conversion error");
+            }
+         }
+      }
 
       ir_assignment *set_fallthru_on_test =
-        new(ctx) ir_assignment(deref_fallthru_var,
-                               true_val,
-                               test_cond);
+         new(ctx) ir_assignment(deref_fallthru_var, true_val, test_cond);
 
       instructions->push_tail(set_fallthru_on_test);
    } else { /* default case */
       if (state->switch_state.previous_default) {
-        YYLTYPE loc = this->get_location();
-        _mesa_glsl_error(& loc, state,
-                         "multiple default labels in one switch");
+         YYLTYPE loc = this->get_location();
+         _mesa_glsl_error(& loc, state,
+                          "multiple default labels in one switch");
 
-        loc = state->switch_state.previous_default->get_location();
-        _mesa_glsl_error(& loc, state,
-                         "this is the first default label");
+         loc = state->switch_state.previous_default->get_location();
+         _mesa_glsl_error(& loc, state, "this is the first default label");
       }
       state->switch_state.previous_default = this;
 
+      /* Set fallthru condition on 'run_default' bool. */
+      ir_dereference_variable *deref_run_default =
+         new(ctx) ir_dereference_variable(state->switch_state.run_default);
+      ir_rvalue *const cond_true = new(ctx) ir_constant(true);
+      ir_expression *test_cond = new(ctx) ir_expression(ir_binop_all_equal,
+                                                        cond_true,
+                                                        deref_run_default);
+
       /* Set falltrhu state. */
       ir_assignment *set_fallthru =
-        new(ctx) ir_assignment(deref_fallthru_var, true_val);
+         new(ctx) ir_assignment(deref_fallthru_var, true_val, test_cond);
 
       instructions->push_tail(set_fallthru);
    }
@@ -4318,35 +4945,35 @@ ast_case_label::hir(exec_list *instructions,
 }
 
 void
-ast_iteration_statement::condition_to_hir(ir_loop *stmt,
-                                         struct _mesa_glsl_parse_state *state)
+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()) {
-        YYLTYPE loc = condition->get_location();
+          || !cond->type->is_boolean() || !cond->type->is_scalar()) {
+         YYLTYPE loc = condition->get_location();
 
-        _mesa_glsl_error(& loc, state,
-                         "loop condition must be scalar boolean");
+         _mesa_glsl_error(& loc, state,
+                          "loop condition must be scalar boolean");
       } else {
-        /* As the first code in the loop body, generate a block that looks
-         * like 'if (!condition) break;' as the loop termination condition.
-         */
-        ir_rvalue *const not_cond =
-           new(ctx) ir_expression(ir_unop_logic_not, cond);
+         /* As the first code in the loop body, generate a block that looks
+          * like 'if (!condition) break;' as the loop termination condition.
+          */
+         ir_rvalue *const not_cond =
+            new(ctx) ir_expression(ir_unop_logic_not, cond);
 
-        ir_if *const if_stmt = new(ctx) ir_if(not_cond);
+         ir_if *const if_stmt = new(ctx) ir_if(not_cond);
 
-        ir_jump *const break_stmt =
-           new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
+         ir_jump *const break_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);
+         if_stmt->then_instructions.push_tail(break_stmt);
+         instructions->push_tail(if_stmt);
       }
    }
 }
@@ -4354,7 +4981,7 @@ ast_iteration_statement::condition_to_hir(ir_loop *stmt,
 
 ir_rvalue *
 ast_iteration_statement::hir(exec_list *instructions,
-                            struct _mesa_glsl_parse_state *state)
+                             struct _mesa_glsl_parse_state *state)
 {
    void *ctx = state;
 
@@ -4381,7 +5008,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);
@@ -4390,7 +5017,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();
@@ -4446,7 +5073,7 @@ is_valid_default_precision_type(const struct glsl_type *const type)
 
 ir_rvalue *
 ast_type_specifier::hir(exec_list *instructions,
-                         struct _mesa_glsl_parse_state *state)
+                        struct _mesa_glsl_parse_state *state)
 {
    if (this->default_precision == ast_precision_none && this->structure == NULL)
       return NULL;
@@ -4473,7 +5100,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");
@@ -4491,7 +5118,7 @@ ast_type_specifier::hir(exec_list *instructions,
 
       if (type->base_type == GLSL_TYPE_FLOAT
           && state->es_shader
-          && state->target == fragment_shader) {
+          && state->stage == MESA_SHADER_FRAGMENT) {
          /* Section 4.5.3 (Default Precision Qualifiers) of the GLSL ES 1.00
           * spec says:
           *
@@ -4522,7 +5149,7 @@ ast_type_specifier::hir(exec_list *instructions,
           */
          ir_variable *const junk =
             new(state) ir_variable(type, "#default precision",
-                                   ir_var_temporary);
+                                   ir_var_auto);
 
          state->symbols->add_variable(junk);
       }
@@ -4568,12 +5195,12 @@ ast_type_specifier::hir(exec_list *instructions,
  */
 unsigned
 ast_process_structure_or_interface_block(exec_list *instructions,
-                                        struct _mesa_glsl_parse_state *state,
-                                        exec_list *declarations,
-                                        YYLTYPE &loc,
-                                        glsl_struct_field **fields_ret,
+                                         struct _mesa_glsl_parse_state *state,
+                                         exec_list *declarations,
+                                         YYLTYPE &loc,
+                                         glsl_struct_field **fields_ret,
                                          bool is_interface,
-                                         bool block_row_major,
+                                         enum glsl_matrix_layout matrix_layout,
                                          bool allow_reserved_names,
                                          ir_variable_mode var_mode)
 {
@@ -4585,9 +5212,7 @@ ast_process_structure_or_interface_block(exec_list *instructions,
     * 'declarations' list in each of the elements.
     */
    foreach_list_typed (ast_declarator_list, decl_list, link, declarations) {
-      foreach_list_const (decl_ptr, & decl_list->declarations) {
-        decl_count++;
-      }
+      decl_count += decl_list->declarations.length();
    }
 
    /* Allocate storage for the fields and process the field
@@ -4596,7 +5221,7 @@ ast_process_structure_or_interface_block(exec_list *instructions,
     * other structure definitions or in interface blocks are processed.
     */
    glsl_struct_field *const fields = ralloc_array(state, glsl_struct_field,
-                                                 decl_count);
+                                                  decl_count);
 
    unsigned i = 0;
    foreach_list_typed (ast_declarator_list, decl_list, link, declarations) {
@@ -4608,24 +5233,21 @@ ast_process_structure_or_interface_block(exec_list *instructions,
        * embedded structure definitions have been removed from the language.
        */
       if (state->es_shader && decl_list->type->specifier->structure != NULL) {
-        _mesa_glsl_error(&loc, state, "embedded structure definitions are "
-                         "not allowed in GLSL ES 1.00");
+         _mesa_glsl_error(&loc, state, "embedded structure definitions are "
+                          "not allowed in GLSL ES 1.00");
       }
 
       const glsl_type *decl_type =
          decl_list->type->glsl_type(& type_name, state);
 
       foreach_list_typed (ast_declaration, decl, link,
-                         &decl_list->declarations) {
+                          &decl_list->declarations) {
          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
@@ -4635,10 +5257,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()) {
@@ -4652,6 +5275,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 ||
@@ -4663,18 +5296,26 @@ 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);
-        }
+         if (qual->flags.q.constant) {
+            YYLTYPE loc = decl_list->get_location();
+            _mesa_glsl_error(&loc, state,
+                             "const storage qualifier cannot be applied "
+                             "to struct or interface block members");
+         }
+
+         field_type = process_array_type(&loc, decl_type,
+                                         decl->array_specifier, state);
          fields[i].type = field_type;
-        fields[i].name = decl->identifier;
+         fields[i].name = decl->identifier;
          fields[i].location = -1;
          fields[i].interpolation =
             interpret_interpolation_qualifier(qual, var_mode, state, &loc);
          fields[i].centroid = qual->flags.q.centroid ? 1 : 0;
          fields[i].sample = qual->flags.q.sample ? 1 : 0;
 
+         /* Only save explicitly defined streams in block's field */
+         fields[i].stream = qual->flags.q.explicit_stream ? qual->stream : -1;
+
          if (qual->flags.q.row_major || qual->flags.q.column_major) {
             if (!qual->flags.q.uniform) {
                _mesa_glsl_error(&loc, state,
@@ -4690,16 +5331,39 @@ ast_process_structure_or_interface_block(exec_list *instructions,
                              "with uniform interface blocks");
          }
 
-         if (field_type->is_matrix() ||
-             (field_type->is_array() && field_type->fields.array->is_matrix())) {
-            fields[i].row_major = block_row_major;
+         if ((qual->flags.q.uniform || !is_interface) &&
+             qual->has_auxiliary_storage()) {
+            _mesa_glsl_error(&loc, state,
+                             "auxiliary storage qualifiers cannot be used "
+                             "in uniform blocks or structures.");
+         }
+
+         /* Propogate row- / column-major information down the fields of the
+          * structure or interface block.  Structures need this data because
+          * the structure may contain a structure that contains ... a matrix
+          * that need the proper layout.
+          */
+         if (field_type->without_array()->is_matrix()
+             || field_type->without_array()->is_record()) {
+            /* If no layout is specified for the field, inherit the layout
+             * from the block.
+             */
+            fields[i].matrix_layout = matrix_layout;
+
             if (qual->flags.q.row_major)
-               fields[i].row_major = true;
+               fields[i].matrix_layout = GLSL_MATRIX_LAYOUT_ROW_MAJOR;
             else if (qual->flags.q.column_major)
-               fields[i].row_major = false;
+               fields[i].matrix_layout = GLSL_MATRIX_LAYOUT_COLUMN_MAJOR;
+
+            /* If we're processing an interface block, the matrix layout must
+             * be decided by this point.
+             */
+            assert(!is_interface
+                   || fields[i].matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR
+                   || fields[i].matrix_layout == GLSL_MATRIX_LAYOUT_COLUMN_MAJOR);
          }
 
-        i++;
+         i++;
       }
    }
 
@@ -4712,7 +5376,7 @@ ast_process_structure_or_interface_block(exec_list *instructions,
 
 ir_rvalue *
 ast_struct_specifier::hir(exec_list *instructions,
-                         struct _mesa_glsl_parse_state *state)
+                          struct _mesa_glsl_parse_state *state)
 {
    YYLTYPE loc = this->get_location();
 
@@ -4739,19 +5403,19 @@ ast_struct_specifier::hir(exec_list *instructions,
     */
    if (state->language_version != 110 && state->struct_specifier_depth != 0)
       _mesa_glsl_error(&loc, state,
-                      "embedded structure declartions are not allowed");
+                      "embedded structure declarations are not allowed");
 
    state->struct_specifier_depth++;
 
    glsl_struct_field *fields;
    unsigned decl_count =
       ast_process_structure_or_interface_block(instructions,
-                                              state,
-                                              &this->declarations,
-                                              loc,
-                                              &fields,
-                                               false,
+                                               state,
+                                               &this->declarations,
+                                               loc,
+                                               &fields,
                                                false,
+                                               GLSL_MATRIX_LAYOUT_INHERITED,
                                                false /* allow_reserved_names */,
                                                ir_var_auto);
 
@@ -4764,12 +5428,12 @@ ast_struct_specifier::hir(exec_list *instructions,
       _mesa_glsl_error(& loc, state, "struct `%s' previously defined", name);
    } else {
       const glsl_type **s = reralloc(state, state->user_structures,
-                                    const glsl_type *,
-                                    state->num_user_structures + 1);
+                                     const glsl_type *,
+                                     state->num_user_structures + 1);
       if (s != NULL) {
-        s[state->num_user_structures] = t;
-        state->user_structures = s;
-        state->num_user_structures++;
+         s[state->num_user_structures] = t;
+         state->user_structures = s;
+         state->num_user_structures++;
       }
    }
 
@@ -4794,7 +5458,7 @@ public:
 
    virtual ir_visitor_status visit(ir_dereference_variable *ir)
    {
-      if (ir->var->mode == mode && ir->var->get_interface_type() == block) {
+      if (ir->var->data.mode == mode && ir->var->get_interface_type() == block) {
          found = true;
          return visit_stop;
       }
@@ -4815,10 +5479,18 @@ private:
 
 ir_rvalue *
 ast_interface_block::hir(exec_list *instructions,
-                         struct _mesa_glsl_parse_state *state)
+                         struct _mesa_glsl_parse_state *state)
 {
    YYLTYPE loc = this->get_location();
 
+   /* Interface blocks must be declared at global scope */
+   if (state->current_function != NULL) {
+      _mesa_glsl_error(&loc, state,
+                       "Interface block `%s' must be declared "
+                       "at global scope",
+                       this->block_name);
+   }
+
    /* The ast_interface_block has a list of ast_declarator_lists.  We
     * need to turn those into ir_variables with an association
     * with this uniform block.
@@ -4851,10 +5523,21 @@ ast_interface_block::hir(exec_list *instructions,
       assert(!"interface block layout qualifier not found!");
    }
 
+   enum glsl_matrix_layout matrix_layout = GLSL_MATRIX_LAYOUT_INHERITED;
+   if (this->layout.flags.q.row_major)
+      matrix_layout = GLSL_MATRIX_LAYOUT_ROW_MAJOR;
+   else if (this->layout.flags.q.column_major)
+      matrix_layout = GLSL_MATRIX_LAYOUT_COLUMN_MAJOR;
+
    bool redeclaring_per_vertex = strcmp(this->block_name, "gl_PerVertex") == 0;
-   bool block_row_major = this->layout.flags.q.row_major;
    exec_list declared_variables;
    glsl_struct_field *fields;
+
+   /* Treat an interface block as one level of nesting, so that embedded struct
+    * specifiers will be disallowed.
+    */
+   state->struct_specifier_depth++;
+
    unsigned int num_variables =
       ast_process_structure_or_interface_block(&declared_variables,
                                                state,
@@ -4862,13 +5545,29 @@ ast_interface_block::hir(exec_list *instructions,
                                                loc,
                                                &fields,
                                                true,
-                                               block_row_major,
+                                               matrix_layout,
                                                redeclaring_per_vertex,
                                                var_mode);
 
-   if (!redeclaring_per_vertex)
+   state->struct_specifier_depth--;
+
+   if (!redeclaring_per_vertex) {
       validate_identifier(this->block_name, loc, state);
 
+      /* From section 4.3.9 ("Interface Blocks") of the GLSL 4.50 spec:
+       *
+       *     "Block names have no other use within a shader beyond interface
+       *     matching; it is a compile-time error to use a block name at global
+       *     scope for anything other than as a block name."
+       */
+      ir_variable *var = state->symbols->get_variable(this->block_name);
+      if (var && !var->type->is_interface()) {
+         _mesa_glsl_error(&loc, state, "Block name `%s' is "
+                          "already used in the scope.",
+                          this->block_name);
+      }
+   }
+
    const glsl_type *earlier_per_vertex = NULL;
    if (redeclaring_per_vertex) {
       /* Find the previous declaration of gl_PerVertex.  If we're redeclaring
@@ -4889,10 +5588,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_glsl_shader_target_name(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[]");
@@ -4906,11 +5605,11 @@ ast_interface_block::hir(exec_list *instructions,
             _mesa_glsl_error(&loc, state,
                              "redeclaration of gl_PerVertex output not "
                              "allowed in the %s shader",
-                             _mesa_glsl_shader_target_name(state->target));
+                             _mesa_shader_stage_to_string(state->stage));
          }
          if (this->instance_name != NULL) {
             _mesa_glsl_error(&loc, state,
-                             "gl_PerVertex input may not be redeclared with "
+                             "gl_PerVertex output may not be redeclared with "
                              "an instance name");
          }
          break;
@@ -4994,7 +5693,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 == geometry_shader && !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");
    }
@@ -5028,7 +5727,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
@@ -5048,8 +5747,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 != geometry_shader || !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");
@@ -5057,7 +5756,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,
@@ -5068,7 +5767,10 @@ ast_interface_block::hir(exec_list *instructions,
                                       var_mode);
       }
 
-      if (state->target == geometry_shader && var_mode == ir_var_shader_in)
+      var->data.matrix_layout = matrix_layout == GLSL_MATRIX_LAYOUT_INHERITED
+         ? GLSL_MATRIX_LAYOUT_COLUMN_MAJOR : matrix_layout;
+
+      if (state->stage == MESA_SHADER_GEOMETRY && var_mode == ir_var_shader_in)
          handle_geometry_shader_input_decl(state, loc, var);
 
       if (ir_variable *earlier =
@@ -5077,43 +5779,72 @@ ast_interface_block::hir(exec_list *instructions,
             _mesa_glsl_error(&loc, state, "`%s' redeclared",
                              this->instance_name);
          }
-         earlier->how_declared = ir_var_declared_normally;
+         earlier->data.how_declared = ir_var_declared_normally;
          earlier->type = var->type;
          earlier->reinit_interface_type(block_type);
          delete var;
       } else {
+         /* Propagate the "binding" keyword into this UBO's fields;
+          * the UBO declaration itself doesn't get an ir_variable unless it
+          * has an instance name.  This is ugly.
+          */
+         var->data.explicit_binding = this->layout.flags.q.explicit_binding;
+         var->data.binding = this->layout.binding;
+
          state->symbols->add_variable(var);
          instructions->push_tail(var);
       }
    } else {
       /* In order to have an array size, the block must also be declared with
-       * an instane name.
+       * an instance name.
        */
-      assert(!this->is_array);
+      assert(this->array_specifier == NULL);
 
       for (unsigned i = 0; i < num_variables; i++) {
          ir_variable *var =
             new(state) ir_variable(fields[i].type,
                                    ralloc_strdup(state, fields[i].name),
                                    var_mode);
-         var->interpolation = fields[i].interpolation;
-         var->centroid = fields[i].centroid;
-         var->sample = fields[i].sample;
+         var->data.interpolation = fields[i].interpolation;
+         var->data.centroid = fields[i].centroid;
+         var->data.sample = fields[i].sample;
          var->init_interface_type(block_type);
 
+         if (fields[i].matrix_layout == GLSL_MATRIX_LAYOUT_INHERITED) {
+            var->data.matrix_layout = matrix_layout == GLSL_MATRIX_LAYOUT_INHERITED
+               ? GLSL_MATRIX_LAYOUT_COLUMN_MAJOR : matrix_layout;
+         } else {
+            var->data.matrix_layout = fields[i].matrix_layout;
+         }
+
+         if (fields[i].stream != -1 &&
+             ((unsigned)fields[i].stream) != this->layout.stream) {
+            _mesa_glsl_error(&loc, state,
+                             "stream layout qualifier on "
+                             "interface block member `%s' does not match "
+                             "the interface block (%d vs %d)",
+                             var->name, fields[i].stream, this->layout.stream);
+         }
+
+         var->data.stream = this->layout.stream;
+
+         /* Examine var name here since var may get deleted in the next call */
+         bool var_is_gl_id = is_gl_identifier(var->name);
+
          if (redeclaring_per_vertex) {
             ir_variable *earlier =
                get_variable_being_redeclared(var, loc, state,
                                              true /* allow_all_redeclarations */);
-            if (strncmp(var->name, "gl_", 3) != 0 || earlier == NULL) {
+            if (!var_is_gl_id || earlier == NULL) {
                _mesa_glsl_error(&loc, state,
                                 "redeclaration of gl_PerVertex can only "
                                 "include built-in variables");
-            } else if (earlier->how_declared == ir_var_declared_normally) {
+            } else if (earlier->data.how_declared == ir_var_declared_normally) {
                _mesa_glsl_error(&loc, state,
-                                "`%s' has already been redeclared", var->name);
+                                "`%s' has already been redeclared",
+                                earlier->name);
             } else {
-               earlier->how_declared = ir_var_declared_in_block;
+               earlier->data.how_declared = ir_var_declared_in_block;
                earlier->reinit_interface_type(block_type);
             }
             continue;
@@ -5126,8 +5857,8 @@ ast_interface_block::hir(exec_list *instructions,
           * the UBO declaration itself doesn't get an ir_variable unless it
           * has an instance name.  This is ugly.
           */
-         var->explicit_binding = this->layout.flags.q.explicit_binding;
-         var->binding = this->layout.binding;
+         var->data.explicit_binding = this->layout.flags.q.explicit_binding;
+         var->data.binding = this->layout.binding;
 
          state->symbols->add_variable(var);
          instructions->push_tail(var);
@@ -5155,12 +5886,12 @@ ast_interface_block::hir(exec_list *instructions,
           * thinking there are conflicting definitions of gl_PerVertex in the
           * shader.
           */
-         foreach_list_safe(node, instructions) {
-            ir_variable *const var = ((ir_instruction *) node)->as_variable();
+         foreach_in_list_safe(ir_instruction, node, instructions) {
+            ir_variable *const var = node->as_variable();
             if (var != NULL &&
                 var->get_interface_type() == earlier_per_vertex &&
-                var->mode == var_mode) {
-               if (var->how_declared == ir_var_declared_normally) {
+                var->data.mode == var_mode) {
+               if (var->data.how_declared == ir_var_declared_normally) {
                   _mesa_glsl_error(&loc, state,
                                    "redeclaration of gl_PerVertex cannot "
                                    "follow a redeclaration of `%s'",
@@ -5187,7 +5918,7 @@ ast_gs_input_layout::hir(exec_list *instructions,
     * was consistent with this one.
     */
    if (state->gs_input_prim_type_specified &&
-       state->gs_input_prim_type != this->prim_type) {
+       state->in_qualifier->prim_type != this->prim_type) {
       _mesa_glsl_error(&loc, state,
                        "geometry shader input layout does not match"
                        " previous declaration");
@@ -5208,14 +5939,13 @@ ast_gs_input_layout::hir(exec_list *instructions,
    }
 
    state->gs_input_prim_type_specified = true;
-   state->gs_input_prim_type = this->prim_type;
 
    /* If any shader inputs occurred before this declaration and did not
     * specify an array size, their size is determined now.
     */
-   foreach_list (node, instructions) {
-      ir_variable *var = ((ir_instruction *) node)->as_variable();
-      if (var == NULL || var->mode != ir_var_shader_in)
+   foreach_in_list(ir_instruction, node, instructions) {
+      ir_variable *var = node->as_variable();
+      if (var == NULL || var->data.mode != ir_var_shader_in)
          continue;
 
       /* Note: gl_PrimitiveIDIn has mode ir_var_shader_in, but it's not an
@@ -5223,12 +5953,12 @@ ast_gs_input_layout::hir(exec_list *instructions,
        */
 
       if (var->type->is_unsized_array()) {
-         if (var->max_array_access >= num_vertices) {
+         if (var->data.max_array_access >= num_vertices) {
             _mesa_glsl_error(&loc, state,
                              "this geometry shader input layout implies %u"
                              " vertices, but an access to element %u of input"
                              " `%s' already exists", num_vertices,
-                             var->max_array_access, var->name);
+                             var->data.max_array_access, var->name);
          } else {
             var->type = glsl_type::get_array_instance(var->type->fields.array,
                                                       num_vertices);
@@ -5240,9 +5970,87 @@ 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::uvec3_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.u[i] = this->local_size[i];
+   var->constant_value = new(var) ir_constant(glsl_type::uvec3_type, &data);
+   var->constant_initializer =
+      new(var) ir_constant(glsl_type::uvec3_type, &data);
+   var->data.has_initializer = true;
+
+   return NULL;
+}
+
+
 static void
 detect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
-                              exec_list *instructions)
+                               exec_list *instructions)
 {
    bool gl_FragColor_assigned = false;
    bool gl_FragData_assigned = false;
@@ -5253,22 +6061,22 @@ detect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
    YYLTYPE loc;
    memset(&loc, 0, sizeof(loc));
 
-   foreach_list(node, instructions) {
-      ir_variable *var = ((ir_instruction *)node)->as_variable();
+   foreach_in_list(ir_instruction, node, instructions) {
+      ir_variable *var = node->as_variable();
 
-      if (!var || !var->assigned)
-        continue;
+      if (!var || !var->data.assigned)
+         continue;
 
       if (strcmp(var->name, "gl_FragColor") == 0)
-        gl_FragColor_assigned = true;
+         gl_FragColor_assigned = true;
       else if (strcmp(var->name, "gl_FragData") == 0)
-        gl_FragData_assigned = true;
-      else if (strncmp(var->name, "gl_", 3) != 0) {
-        if (state->target == fragment_shader &&
-            var->mode == ir_var_shader_out) {
-           user_defined_fs_output_assigned = true;
-           user_defined_fs_output = var;
-        }
+         gl_FragData_assigned = true;
+      else if (!is_gl_identifier(var->name)) {
+         if (state->stage == MESA_SHADER_FRAGMENT &&
+             var->data.mode == ir_var_shader_out) {
+            user_defined_fs_output_assigned = true;
+            user_defined_fs_output = var;
+         }
       }
    }
 
@@ -5289,15 +6097,15 @@ detect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
     */
    if (gl_FragColor_assigned && gl_FragData_assigned) {
       _mesa_glsl_error(&loc, state, "fragment shader writes to both "
-                      "`gl_FragColor' and `gl_FragData'");
+                       "`gl_FragColor' and `gl_FragData'");
    } else if (gl_FragColor_assigned && user_defined_fs_output_assigned) {
       _mesa_glsl_error(&loc, state, "fragment shader writes to both "
-                      "`gl_FragColor' and `%s'",
-                      user_defined_fs_output->name);
+                       "`gl_FragColor' and `%s'",
+                       user_defined_fs_output->name);
    } else if (gl_FragData_assigned && user_defined_fs_output_assigned) {
       _mesa_glsl_error(&loc, state, "fragment shader writes to both "
-                      "`gl_FragData' and `%s'",
-                      user_defined_fs_output->name);
+                       "`gl_FragData' and `%s'",
+                       user_defined_fs_output->name);
    }
 }
 
@@ -5343,10 +6151,10 @@ remove_per_vertex_blocks(exec_list *instructions,
    /* Remove any ir_variable declarations that refer to the interface block
     * we're removing.
     */
-   foreach_list_safe(node, instructions) {
-      ir_variable *const var = ((ir_instruction *) node)->as_variable();
+   foreach_in_list_safe(ir_instruction, node, instructions) {
+      ir_variable *const var = node->as_variable();
       if (var != NULL && var->get_interface_type() == per_vertex &&
-          var->mode == mode) {
+          var->data.mode == mode) {
          state->symbols->disable_variable(var->name);
          var->remove();
       }