glsl: Skip processing of expression trees in discard simplification.
[mesa.git] / src / glsl / ast_to_hir.cpp
index 762f802c2b76ddeb08f56062e7d28fb44a533542..651fae808e623f7171828600c0b685fbbb7286df 100644 (file)
@@ -60,7 +60,9 @@ void
 _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
 {
    _mesa_glsl_initialize_variables(instructions, state);
-   _mesa_glsl_initialize_functions(instructions, state);
+   _mesa_glsl_initialize_functions(state);
+
+   state->symbols->language_version = state->language_version;
 
    state->current_function = NULL;
 
@@ -362,12 +364,84 @@ unary_arithmetic_result_type(const struct glsl_type *type,
    return type;
 }
 
+/**
+ * \brief Return the result type of a bit-logic operation.
+ *
+ * If the given types to the bit-logic operator are invalid, return
+ * glsl_type::error_type.
+ *
+ * \param type_a Type of LHS of bit-logic op
+ * \param type_b Type of RHS of bit-logic op
+ */
+static const struct glsl_type *
+bit_logic_result_type(const struct glsl_type *type_a,
+                      const struct glsl_type *type_b,
+                      ast_operators op,
+                      struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+{
+    if (state->language_version < 130) {
+       _mesa_glsl_error(loc, state, "bit operations require GLSL 1.30");
+       return glsl_type::error_type;
+    }
+
+    /* From page 50 (page 56 of PDF) of GLSL 1.30 spec:
+     *
+     *     "The bitwise operators and (&), exclusive-or (^), and inclusive-or
+     *     (|). The operands must be of type signed or unsigned integers or
+     *     integer vectors."
+     */
+    if (!type_a->is_integer()) {
+       _mesa_glsl_error(loc, state, "LHS of `%s' must be an integer",
+                         ast_expression::operator_string(op));
+       return glsl_type::error_type;
+    }
+    if (!type_b->is_integer()) {
+       _mesa_glsl_error(loc, state, "RHS of `%s' must be an integer",
+                        ast_expression::operator_string(op));
+       return glsl_type::error_type;
+    }
+
+    /*     "The fundamental types of the operands (signed or unsigned) must
+     *     match,"
+     */
+    if (type_a->base_type != type_b->base_type) {
+       _mesa_glsl_error(loc, state, "operands of `%s' must have the same "
+                        "base type", ast_expression::operator_string(op));
+       return glsl_type::error_type;
+    }
+
+    /*     "The operands cannot be vectors of differing size." */
+    if (type_a->is_vector() &&
+        type_b->is_vector() &&
+        type_a->vector_elements != type_b->vector_elements) {
+       _mesa_glsl_error(loc, state, "operands of `%s' cannot be vectors of "
+                        "different sizes", ast_expression::operator_string(op));
+       return glsl_type::error_type;
+    }
+
+    /*     "If one operand is a scalar and the other a vector, the scalar is
+     *     applied component-wise to the vector, resulting in the same type as
+     *     the vector. The fundamental types of the operands [...] will be the
+     *     resulting fundamental type."
+     */
+    if (type_a->is_scalar())
+        return type_b;
+    else
+        return 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)
 {
+   if (state->language_version < 130) {
+      _mesa_glsl_error(loc, state,
+                       "operator '%%' is reserved in %s",
+                       state->version_string);
+      return glsl_type::error_type;
+   }
+
    /* From GLSL 1.50 spec, page 56:
     *    "The operator modulus (%) operates on signed or unsigned integers or
     *    integer vectors. The operand types must both be signed or both be
@@ -445,6 +519,71 @@ relational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
    return glsl_type::bool_type;
 }
 
+/**
+ * \brief Return the result type of a bit-shift operation.
+ *
+ * If the given types to the bit-shift operator are invalid, return
+ * glsl_type::error_type.
+ *
+ * \param type_a Type of LHS of bit-shift op
+ * \param type_b Type of RHS of bit-shift op
+ */
+static const struct glsl_type *
+shift_result_type(const struct glsl_type *type_a,
+                  const struct glsl_type *type_b,
+                  ast_operators op,
+                  struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+{
+   if (state->language_version < 130) {
+      _mesa_glsl_error(loc, state, "bit operations require GLSL 1.30");
+      return glsl_type::error_type;
+   }
+
+   /* From page 50 (page 56 of the PDF) of the GLSL 1.30 spec:
+    *
+    *     "The shift operators (<<) and (>>). For both operators, the operands
+    *     must be signed or unsigned integers or integer vectors. One operand
+    *     can be signed while the other is unsigned."
+    */
+   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));
+     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));
+     return glsl_type::error_type;
+   }
+
+   /*     "If the first operand is a scalar, the second operand has to be
+    *     a scalar as well."
+    */
+   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));
+     return glsl_type::error_type;
+   }
+
+   /* If both operands are vectors, check that they have same number of
+    * elements.
+    */
+   if (type_a->is_vector() &&
+      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));
+     return glsl_type::error_type;
+   }
+
+   /*     "In all cases, the resulting type will be the same type as the left
+    *     operand."
+    */
+   return type_a;
+}
 
 /**
  * Validates that a value can be assigned to a location with a specified type
@@ -466,17 +605,15 @@ ir_rvalue *
 validate_assignment(struct _mesa_glsl_parse_state *state,
                    const glsl_type *lhs_type, ir_rvalue *rhs)
 {
-   const glsl_type *rhs_type = rhs->type;
-
    /* If there is already some error in the RHS, just return it.  Anything
     * else will lead to an avalanche of error message back to the user.
     */
-   if (rhs_type->is_error())
+   if (rhs->type->is_error())
       return rhs;
 
    /* If the types are identical, the assignment can trivially proceed.
     */
-   if (rhs_type == lhs_type)
+   if (rhs->type == lhs_type)
       return rhs;
 
    /* If the array element types are the same and the size of the LHS is zero,
@@ -493,8 +630,7 @@ validate_assignment(struct _mesa_glsl_parse_state *state,
 
    /* Check for implicit conversion in GLSL 1.20 */
    if (apply_implicit_conversion(lhs_type, rhs, state)) {
-      rhs_type = rhs->type;
-      if (rhs_type == lhs_type)
+      if (rhs->type == lhs_type)
         return rhs;
    }
 
@@ -510,10 +646,23 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
    bool error_emitted = (lhs->type->is_error() || rhs->type->is_error());
 
    if (!error_emitted) {
-      if (!lhs->is_lvalue()) {
+      if (lhs->variable_referenced() != NULL
+          && lhs->variable_referenced()->read_only) {
+         _mesa_glsl_error(&lhs_loc, state,
+                          "assignment to read-only variable '%s'",
+                          lhs->variable_referenced()->name);
+         error_emitted = true;
+
+      } else if (!lhs->is_lvalue()) {
         _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment");
         error_emitted = true;
       }
+
+      if (state->es_shader && lhs->type->is_array()) {
+        _mesa_glsl_error(&lhs_loc, state, "whole array assignment is not "
+                         "allowed in GLSL ES 1.00.");
+        error_emitted = true;
+      }
    }
 
    ir_rvalue *new_rhs = validate_assignment(state, lhs->type, rhs);
@@ -577,7 +726,7 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
 static ir_rvalue *
 get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue)
 {
-   void *ctx = talloc_parent(lvalue);
+   void *ctx = ralloc_parent(lvalue);
    ir_variable *var;
 
    var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp",
@@ -607,6 +756,94 @@ ast_node::hir(exec_list *instructions,
    return NULL;
 }
 
+static void
+mark_whole_array_access(ir_rvalue *access)
+{
+   ir_dereference_variable *deref = access->as_dereference_variable();
+
+   if (deref) {
+      deref->var->max_array_access = deref->type->length - 1;
+   }
+}
+
+static ir_rvalue *
+do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
+{
+   int join_op;
+   ir_rvalue *cmp = NULL;
+
+   if (operation == ir_binop_all_equal)
+      join_op = ir_binop_logic_and;
+   else
+      join_op = ir_binop_logic_or;
+
+   switch (op0->type->base_type) {
+   case GLSL_TYPE_FLOAT:
+   case GLSL_TYPE_UINT:
+   case GLSL_TYPE_INT:
+   case GLSL_TYPE_BOOL:
+      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;
+        }
+      }
+
+      mark_whole_array_access(op0);
+      mark_whole_array_access(op1);
+      break;
+   }
+
+   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;
+        }
+      }
+      break;
+   }
+
+   case GLSL_TYPE_ERROR:
+   case GLSL_TYPE_VOID:
+   case GLSL_TYPE_SAMPLER:
+      /* I assume a comparison of a struct containing a sampler just
+       * ignores the sampler present in the type.
+       */
+      break;
+
+   default:
+      assert(!"Should not get here.");
+      break;
+   }
+
+   if (cmp == NULL)
+      cmp = new(mem_ctx) ir_constant(true);
+
+   return cmp;
+}
 
 ir_rvalue *
 ast_expression::hir(exec_list *instructions,
@@ -628,8 +865,8 @@ ast_expression::hir(exec_list *instructions,
       ir_binop_greater,
       ir_binop_lequal,
       ir_binop_gequal,
-      ir_binop_equal,
-      ir_binop_nequal,
+      ir_binop_all_equal,
+      ir_binop_any_nequal,
       ir_binop_bit_and,
       ir_binop_bit_xor,
       ir_binop_bit_or,
@@ -740,9 +977,20 @@ ast_expression::hir(exec_list *instructions,
 
    case ast_lshift:
    case ast_rshift:
-      _mesa_glsl_error(& loc, state, "FINISHME: implement bit-shift operators");
-      error_emitted = true;
-      break;
+       if (state->language_version < 130) {
+          _mesa_glsl_error(&loc, state, "operator %s requires GLSL 1.30",
+              operator_string(this->oper));
+          error_emitted = true;
+       }
+
+       op[0] = this->subexpressions[0]->hir(instructions, state);
+       op[1] = this->subexpressions[1]->hir(instructions, state);
+       type = shift_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]);
+       error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
+       break;
 
    case ast_less:
    case ast_greater:
@@ -792,11 +1040,10 @@ ast_expression::hir(exec_list *instructions,
         error_emitted = true;
       }
 
-      result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
-                                     op[0], op[1]);
+      result = do_comparison(ctx, operations[this->oper], op[0], op[1]);
       type = glsl_type::bool_type;
 
-      assert(result->type == glsl_type::bool_type);
+      assert(error_emitted || (result->type == glsl_type::bool_type));
       break;
 
    case ast_bit_and:
@@ -804,38 +1051,8 @@ ast_expression::hir(exec_list *instructions,
    case ast_bit_or:
       op[0] = this->subexpressions[0]->hir(instructions, state);
       op[1] = this->subexpressions[1]->hir(instructions, state);
-
-      if (state->language_version < 130) {
-        _mesa_glsl_error(&loc, state, "bit-wise operations require GLSL 1.30");
-        error_emitted = true;
-      }
-
-      if (!op[0]->type->is_integer()) {
-        _mesa_glsl_error(&loc, state, "LHS of `%s' must be an integer",
-                         operator_string(this->oper));
-        error_emitted = true;
-      }
-
-      if (!op[1]->type->is_integer()) {
-        _mesa_glsl_error(&loc, state, "RHS of `%s' must be an integer",
-                         operator_string(this->oper));
-        error_emitted = true;
-      }
-
-      if (op[0]->type->base_type != op[1]->type->base_type) {
-        _mesa_glsl_error(&loc, state, "operands of `%s' must have the same "
-                         "base type", operator_string(this->oper));
-        error_emitted = true;
-      }
-
-      if (op[0]->type->is_vector() && op[1]->type->is_vector()
-         && op[0]->type->vector_elements != op[1]->type->vector_elements) {
-        _mesa_glsl_error(&loc, state, "operands of `%s' cannot be vectors of "
-                         "different sizes", operator_string(this->oper));
-        error_emitted = true;
-      }
-
-      type = op[0]->type->is_scalar() ? op[1]->type : op[0]->type;
+      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]);
       error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
@@ -1062,19 +1279,35 @@ ast_expression::hir(exec_list *instructions,
    }
 
    case ast_ls_assign:
-   case ast_rs_assign:
-      _mesa_glsl_error(& loc, state,
-                      "FINISHME: implement bit-shift assignment operators");
-      error_emitted = true;
+   case ast_rs_assign: {
+      op[0] = this->subexpressions[0]->hir(instructions, state);
+      op[1] = this->subexpressions[1]->hir(instructions, state);
+      type = shift_result_type(op[0]->type, op[1]->type, this->oper, state,
+                               &loc);
+      ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper],
+                                                   type, op[0], op[1]);
+      result = do_assignment(instructions, state, op[0]->clone(ctx, NULL),
+                             temp_rhs,
+                             this->subexpressions[0]->get_location());
+      error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
       break;
+   }
 
    case ast_and_assign:
    case ast_xor_assign:
-   case ast_or_assign:
-      _mesa_glsl_error(& loc, state,
-                      "FINISHME: implement logic assignment operators");
-      error_emitted = true;
+   case ast_or_assign: {
+      op[0] = this->subexpressions[0]->hir(instructions, state);
+      op[1] = this->subexpressions[1]->hir(instructions, state);
+      type = bit_logic_result_type(op[0]->type, op[1]->type, this->oper,
+                                   state, &loc);
+      ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper],
+                                                   type, op[0], op[1]);
+      result = do_assignment(instructions, state, op[0]->clone(ctx, NULL),
+                             temp_rhs,
+                             this->subexpressions[0]->get_location());
+      error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
       break;
+   }
 
    case ast_conditional: {
       op[0] = this->subexpressions[0]->hir(instructions, state);
@@ -1125,6 +1358,17 @@ ast_expression::hir(exec_list *instructions,
         type = op[1]->type;
       }
 
+      /* From page 33 (page 39 of the PDF) of the GLSL 1.10 spec:
+       *
+       *    "The second and third expressions must be the same type, but can
+       *    be of any type other than an array."
+       */
+      if ((state->language_version <= 110) && type->is_array()) {
+        _mesa_glsl_error(& loc, state, "Second and third operands of ?: "
+                         "operator must not be arrays.");
+        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();
@@ -1334,6 +1578,40 @@ ast_expression::hir(exec_list *instructions,
         }
       }
 
+      /* From page 23 (29 of the PDF) of the GLSL 1.30 spec:
+       *
+       *    "Samplers aggregated into arrays within a shader (using square
+       *    brackets [ ]) can only be indexed with integral constant
+       *    expressions [...]."
+       *
+       * This restriction was added in GLSL 1.30.  Shaders using earlier version
+       * of the language should not be rejected by the compiler front-end for
+       * using this construct.  This allows useful things such as using a loop
+       * counter as the index to an array of samplers.  If the loop in unrolled,
+       * the code should compile correctly.  Instead, emit a warning.
+       */
+      if (array->type->is_array() &&
+          array->type->element_type()->is_sampler() &&
+          const_index == NULL) {
+
+        if (state->language_version == 100) {
+           _mesa_glsl_warning(&loc, state,
+                              "sampler arrays indexed with non-constant "
+                              "expressions is optional in GLSL ES 1.00");
+        } else if (state->language_version < 130) {
+           _mesa_glsl_warning(&loc, state,
+                              "sampler arrays indexed with non-constant "
+                              "expressions is forbidden in GLSL 1.30 and "
+                              "later");
+        } else {
+           _mesa_glsl_error(&loc, state,
+                            "sampler arrays indexed with non-constant "
+                            "expressions is forbidden in GLSL 1.30 and "
+                            "later");
+           error_emitted = true;
+        }
+      }
+
       if (error_emitted)
         result->type = glsl_type::error_type;
 
@@ -1359,6 +1637,7 @@ ast_expression::hir(exec_list *instructions,
       result = new(ctx) ir_dereference_variable(var);
 
       if (var != NULL) {
+        var->used = true;
         type = result->type;
       } else {
         _mesa_glsl_error(& loc, state, "`%s' undeclared",
@@ -1461,7 +1740,7 @@ ast_compound_statement::hir(exec_list *instructions,
 
 
 static const glsl_type *
-process_array_type(const glsl_type *base, ast_node *array_size,
+process_array_type(YYLTYPE *loc, const glsl_type *base, ast_node *array_size,
                   struct _mesa_glsl_parse_state *state)
 {
    unsigned length = 0;
@@ -1497,6 +1776,12 @@ process_array_type(const glsl_type *base, ast_node *array_size,
            }
         }
       }
+   } else if (state->es_shader) {
+      /* Section 10.17 of the GLSL ES 1.00 specification states that unsized
+       * array declarations have been removed from the language.
+       */
+      _mesa_glsl_error(loc, state, "unsized array declarations are not "
+                      "allowed in GLSL ES 1.00.");
    }
 
    return glsl_type::get_array_instance(base, length);
@@ -1509,16 +1794,12 @@ ast_type_specifier::glsl_type(const char **name,
 {
    const struct glsl_type *type;
 
-   if ((this->type_specifier == ast_struct) && (this->type_name == NULL)) {
-      /* FINISHME: Handle annonymous structures. */
-      type = NULL;
-   } else {
-      type = state->symbols->get_type(this->type_name);
-      *name = this->type_name;
+   type = state->symbols->get_type(this->type_name);
+   *name = this->type_name;
 
-      if (this->is_array) {
-        type = process_array_type(type, this->array_size, state);
-      }
+   if (this->is_array) {
+      YYLTYPE loc = this->get_location();
+      type = process_array_type(&loc, type, this->array_size, state);
    }
 
    return type;
@@ -1531,18 +1812,26 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
                                 struct _mesa_glsl_parse_state *state,
                                 YYLTYPE *loc)
 {
-   if (qual->invariant)
-      var->invariant = 1;
+   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);
+      } else {
+        var->invariant = 1;
+      }
+   }
 
-   /* FINISHME: Mark 'in' variables at global scope as read-only. */
-   if (qual->constant || qual->attribute || qual->uniform
-       || (qual->varying && (state->target == fragment_shader)))
+   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;
 
-   if (qual->centroid)
+   if (qual->flags.q.centroid)
       var->centroid = 1;
 
-   if (qual->attribute && state->target != vertex_shader) {
+   if (qual->flags.q.attribute && state->target != vertex_shader) {
       var->type = glsl_type::error_type;
       _mesa_glsl_error(loc, state,
                       "`attribute' variables may not be declared in the "
@@ -1556,7 +1845,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
     *     float, vec2, vec3, vec4, mat2, mat3, and mat4, or arrays of
     *     these."
     */
-   if (qual->varying) {
+   if (qual->flags.q.varying) {
       const glsl_type *non_array_type;
 
       if (var->type && var->type->is_array())
@@ -1574,28 +1863,46 @@ 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.
     */
-   if (qual->in && qual->out)
+   if (qual->flags.q.in && qual->flags.q.out)
       var->mode = ir_var_inout;
-   else if (qual->attribute || qual->in
-           || (qual->varying && (state->target == fragment_shader)))
+   else if (qual->flags.q.attribute || qual->flags.q.in
+           || (qual->flags.q.varying && (state->target == fragment_shader)))
       var->mode = ir_var_in;
-   else if (qual->out || (qual->varying && (state->target == vertex_shader)))
+   else if (qual->flags.q.out
+           || (qual->flags.q.varying && (state->target == vertex_shader)))
       var->mode = ir_var_out;
-   else if (qual->uniform)
+   else if (qual->flags.q.uniform)
       var->mode = ir_var_uniform;
 
-   if (qual->flat)
+   if (state->all_invariant && (state->current_function == NULL)) {
+      switch (state->target) {
+      case vertex_shader:
+        if (var->mode == ir_var_out)
+           var->invariant = true;
+        break;
+      case geometry_shader:
+        if ((var->mode == ir_var_in) || (var->mode == ir_var_out))
+           var->invariant = true;
+        break;
+      case fragment_shader:
+        if (var->mode == ir_var_in)
+           var->invariant = true;
+        break;
+      }
+   }
+
+   if (qual->flags.q.flat)
       var->interpolation = ir_var_flat;
-   else if (qual->noperspective)
+   else if (qual->flags.q.noperspective)
       var->interpolation = ir_var_noperspective;
    else
       var->interpolation = ir_var_smooth;
 
-   var->pixel_center_integer = qual->pixel_center_integer;
-   var->origin_upper_left = qual->origin_upper_left;
-   if ((qual->origin_upper_left || qual->pixel_center_integer)
+   var->pixel_center_integer = qual->flags.q.pixel_center_integer;
+   var->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->origin_upper_left)
+      const char *const qual_string = (qual->flags.q.origin_upper_left)
         ? "origin_upper_left" : "pixel_center_integer";
 
       _mesa_glsl_error(loc, state,
@@ -1604,11 +1911,404 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
                       qual_string);
    }
 
-   if (var->type->is_array() && (state->language_version >= 120)) {
+   if (qual->flags.q.explicit_location) {
+      const bool global_scope = (state->current_function == NULL);
+      bool fail = false;
+      const char *string = "";
+
+      /* In the vertex shader only shader inputs can be given explicit
+       * locations.
+       *
+       * In the fragment shader only shader outputs can be given explicit
+       * locations.
+       */
+      switch (state->target) {
+      case vertex_shader:
+        if (!global_scope || (var->mode != ir_var_in)) {
+           fail = true;
+           string = "input";
+        }
+        break;
+
+      case geometry_shader:
+        _mesa_glsl_error(loc, state,
+                         "geometry shader variables cannot be given "
+                         "explicit locations\n");
+        break;
+
+      case fragment_shader:
+        if (!global_scope || (var->mode != ir_var_in)) {
+           fail = true;
+           string = "output";
+        }
+        break;
+      };
+
+      if (fail) {
+        _mesa_glsl_error(loc, state,
+                         "only %s shader %s variables can be given an "
+                         "explicit location\n",
+                         _mesa_glsl_shader_target_name(state->target),
+                         string);
+      } else {
+        var->explicit_location = true;
+
+        /* This bit of silliness is needed because invalid explicit locations
+         * are supposed to be flagged during linking.  Small negative values
+         * biased by VERT_ATTRIB_GENERIC0 or FRAG_RESULT_DATA0 could alias
+         * built-in values (e.g., -16+VERT_ATTRIB_GENERIC0 = VERT_ATTRIB_POS).
+         * The linker needs to be able to differentiate these cases.  This
+         * 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);
+        } else {
+           var->location = qual->location;
+        }
+      }
+   }
+
+   /* Does the declaration use the 'layout' keyword?
+    */
+   const bool uses_layout = qual->flags.q.pixel_center_integer
+      || qual->flags.q.origin_upper_left
+      || qual->flags.q.explicit_location;
+
+   /* Does the declaration use the deprecated 'attribute' or 'varying'
+    * keywords?
+    */
+   const bool uses_deprecated_qualifier = qual->flags.q.attribute
+      || qual->flags.q.varying;
+
+   /* 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
+    * allowed the layout qualifier to be used with 'varying' and 'attribute'.
+    * These extensions and all following extensions that add the 'layout'
+    * keyword have been modified to require the use of 'in' or 'out'.
+    *
+    * The following extension do not allow the deprecated keywords:
+    *
+    *    GL_AMD_conservative_depth
+    *    GL_ARB_gpu_shader5
+    *    GL_ARB_separate_shader_objects
+    *    GL_ARB_tesselation_shader
+    *    GL_ARB_transform_feedback3
+    *    GL_ARB_uniform_buffer_object
+    *
+    * It is unknown whether GL_EXT_shader_image_load_store or GL_NV_gpu_shader5
+    * allow layout with the deprecated keywords.
+    */
+   const bool relaxed_layout_qualifier_checking =
+      state->ARB_fragment_coord_conventions_enable;
+
+   if (uses_layout && uses_deprecated_qualifier) {
+      if (relaxed_layout_qualifier_checking) {
+        _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'");
+      }
+   }
+
+   /* Layout qualifiers for gl_FragDepth, which are enabled by extension
+    * AMD_conservative_depth.
+    */
+   int depth_layout_count = qual->flags.q.depth_any
+      + qual->flags.q.depth_greater
+      + qual->flags.q.depth_less
+      + qual->flags.q.depth_unchanged;
+   if (depth_layout_count > 0
+       && !state->AMD_conservative_depth_enable) {
+       _mesa_glsl_error(loc, state,
+                        "extension GL_AMD_conservative_depth must be enabled "
+                       "to use depth layout qualifiers");
+   } else if (depth_layout_count > 0
+              && strcmp(var->name, "gl_FragDepth") != 0) {
+       _mesa_glsl_error(loc, state,
+                        "depth layout qualifiers can be applied only to "
+                        "gl_FragDepth");
+   } else if (depth_layout_count > 1
+              && strcmp(var->name, "gl_FragDepth") == 0) {
+      _mesa_glsl_error(loc, state,
+                       "at most one depth layout qualifier can be applied to "
+                       "gl_FragDepth");
+   }
+   if (qual->flags.q.depth_any)
+      var->depth_layout = ir_depth_layout_any;
+   else if (qual->flags.q.depth_greater)
+      var->depth_layout = ir_depth_layout_greater;
+   else if (qual->flags.q.depth_less)
+      var->depth_layout = ir_depth_layout_less;
+   else if (qual->flags.q.depth_unchanged)
+       var->depth_layout = ir_depth_layout_unchanged;
+   else
+       var->depth_layout = ir_depth_layout_none;
+
+   if (var->type->is_array() && state->language_version != 110) {
       var->array_lvalue = true;
    }
 }
 
+/**
+ * Get the variable that is being redeclared by this declaration
+ *
+ * Semantic checks to verify the validity of the redeclaration are also
+ * performed.  If semantic checks fail, compilation error will be emitted via
+ * \c _mesa_glsl_error, but a non-\c NULL pointer will still be returned.
+ *
+ * \returns
+ * A pointer to an existing variable in the current scope if the declaration
+ * is a redeclaration, \c NULL otherwise.
+ */
+ir_variable *
+get_variable_being_redeclared(ir_variable *var, ast_declaration *decl,
+                             struct _mesa_glsl_parse_state *state)
+{
+   /* Check if this declaration is actually a re-declaration, either to
+    * resize an array or add qualifiers to an existing variable.
+    *
+    * This is allowed for variables in the current scope, or when at
+    * global scope (for built-ins in the implicit outer scope).
+    */
+   ir_variable *earlier = state->symbols->get_variable(decl->identifier);
+   if (earlier == NULL ||
+       (state->current_function != NULL &&
+       !state->symbols->name_declared_this_scope(decl->identifier))) {
+      return NULL;
+   }
+
+
+   YYLTYPE loc = decl->get_location();
+
+   /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec,
+    *
+    * "It is legal to declare an array without a size and then
+    *  later re-declare the same name as an array of the same
+    *  type and specify a size."
+    */
+   if ((earlier->type->array_size() == 0)
+       && var->type->is_array()
+       && (var->type->element_type() == earlier->type->element_type())) {
+      /* FINISHME: This doesn't match the qualifiers on the two
+       * FINISHME: declarations.  It's not 100% clear whether this is
+       * FINISHME: required or not.
+       */
+
+      /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec:
+       *
+       *     "The size [of gl_TexCoord] can be at most
+       *     gl_MaxTextureCoords."
+       */
+      const unsigned size = unsigned(var->type->array_size());
+      if ((strcmp("gl_TexCoord", var->name) == 0)
+         && (size > state->Const.MaxTextureCoords)) {
+        _mesa_glsl_error(& loc, state, "`gl_TexCoord' array size cannot "
+                         "be larger than gl_MaxTextureCoords (%u)\n",
+                         state->Const.MaxTextureCoords);
+      } else 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);
+      }
+
+      earlier->type = var->type;
+      delete var;
+      var = NULL;
+   } else if (state->ARB_fragment_coord_conventions_enable
+             && strcmp(var->name, "gl_FragCoord") == 0
+             && earlier->type == var->type
+             && earlier->mode == var->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;
+
+      /* According to section 4.3.7 of the GLSL 1.30 spec,
+       * the following built-in varaibles can be redeclared with an
+       * interpolation qualifier:
+       *    * gl_FrontColor
+       *    * gl_BackColor
+       *    * gl_FrontSecondaryColor
+       *    * gl_BackSecondaryColor
+       *    * gl_Color
+       *    * gl_SecondaryColor
+       */
+   } else if (state->language_version >= 130
+             && (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;
+
+      /* Layout qualifiers for gl_FragDepth. */
+   } else if (state->AMD_conservative_depth_enable
+             && strcmp(var->name, "gl_FragDepth") == 0
+             && earlier->type == var->type
+             && earlier->mode == var->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");
+      }
+
+      /* 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));
+      }
+
+      earlier->depth_layout = var->depth_layout;
+
+   } else {
+      _mesa_glsl_error(&loc, state, "`%s' redeclared", decl->identifier);
+   }
+
+   return earlier;
+}
+
+/**
+ * Generate the IR for an initializer in a variable declaration
+ */
+ir_rvalue *
+process_initializer(ir_variable *var, ast_declaration *decl,
+                   ast_fully_specified_type *type,
+                   exec_list *initializer_instructions,
+                   struct _mesa_glsl_parse_state *state)
+{
+   ir_rvalue *result = NULL;
+
+   YYLTYPE initializer_loc = decl->initializer->get_location();
+
+   /* From page 24 (page 30 of the PDF) of the GLSL 1.10 spec:
+    *
+    *    "All uniform variables are read-only and are initialized either
+    *    directly by an application via API commands, or indirectly by
+    *    OpenGL."
+    */
+   if ((state->language_version <= 110)
+       && (var->mode == ir_var_uniform)) {
+      _mesa_glsl_error(& initializer_loc, state,
+                      "cannot initialize uniforms in GLSL 1.10");
+   }
+
+   if (var->type->is_sampler()) {
+      _mesa_glsl_error(& initializer_loc, state,
+                      "cannot initialize samplers");
+   }
+
+   if ((var->mode == ir_var_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)
+                      ? "attribute" : "varying");
+   }
+
+   ir_dereference *const lhs = new(state) ir_dereference_variable(var);
+   ir_rvalue *rhs = decl->initializer->hir(initializer_instructions,
+                                          state);
+
+   /* Calculate the constant value if this is a const or uniform
+    * declaration.
+    */
+   if (type->qualifier.flags.q.constant
+       || type->qualifier.flags.q.uniform) {
+      ir_rvalue *new_rhs = validate_assignment(state, var->type, rhs);
+      if (new_rhs != NULL) {
+        rhs = new_rhs;
+
+        ir_constant *constant_value = rhs->constant_expression_value();
+        if (!constant_value) {
+           _mesa_glsl_error(& initializer_loc, state,
+                            "initializer of %s variable `%s' must be a "
+                            "constant expression",
+                            (type->qualifier.flags.q.constant)
+                            ? "const" : "uniform",
+                            decl->identifier);
+           if (var->type->is_numeric()) {
+              /* Reduce cascading errors. */
+              var->constant_value = ir_constant::zero(state, var->type);
+           }
+        } else {
+           rhs = constant_value;
+           var->constant_value = constant_value;
+        }
+      } else {
+        _mesa_glsl_error(&initializer_loc, state,
+                         "initializer of type %s cannot be assigned to "
+                         "variable of type %s",
+                         rhs->type->name, var->type->name);
+        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;
+      if (type->qualifier.flags.q.constant)
+        var->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,
+                               lhs, rhs,
+                               type->get_location());
+        initializer_type = result->type;
+      } else
+        initializer_type = rhs->type;
+
+      /* If the declared variable is an unsized array, it must inherrit
+       * its full type from the initializer.  A declaration such as
+       *
+       *     uniform float a[] = float[](1.0, 2.0, 3.0, 3.0);
+       *
+       * becomes
+       *
+       *     uniform float a[4] = float[](1.0, 2.0, 3.0, 3.0);
+       *
+       * The assignment generated in the if-statement (below) will also
+       * automatically handle this case for non-uniforms.
+       *
+       * If the declared variable is not an array, the types must
+       * already match exactly.  As a result, the type assignment
+       * here can be done unconditionally.  For non-uniforms the call
+       * to do_assignment can change the type of the initializer (via
+       * the implicit conversion rules).  For uniforms the initializer
+       * must be a constant expression, and the type of that expression
+       * was validated above.
+       */
+      var->type = initializer_type;
+
+      var->read_only = temp;
+   }
+
+   return result;
+}
 
 ir_rvalue *
 ast_declarator_list::hir(exec_list *instructions,
@@ -1661,6 +2361,11 @@ ast_declarator_list::hir(exec_list *instructions,
            _mesa_glsl_error(& loc, state,
                             "`%s' cannot be marked invariant, fragment shader "
                             "inputs only\n", 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;
         }
@@ -1714,7 +2419,8 @@ ast_declarator_list::hir(exec_list *instructions,
       }
 
       if (decl->is_array) {
-        var_type = process_array_type(decl_type, decl->array_size, state);
+        var_type = process_array_type(&loc, decl_type, decl->array_size,
+                                      state);
       } else {
         var_type = decl_type;
       }
@@ -1729,20 +2435,23 @@ ast_declarator_list::hir(exec_list *instructions,
        *
        *     Local variables can only use the qualifier const."
        *
-       * This is relaxed in GLSL 1.30.
+       * This is relaxed in GLSL 1.30.  It is also relaxed by any extension
+       * that adds the 'layout' keyword.
        */
-      if (state->language_version < 120) {
-        if (this->type->qualifier.out) {
+      if ((state->language_version < 130)
+         && !state->ARB_explicit_attrib_location_enable
+         && !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 GLSL 1.10.",
-                            decl->identifier);
+                            "only valid for function parameters in %s.",
+                            decl->identifier, state->version_string);
         }
-        if (this->type->qualifier.in) {
+        if (this->type->qualifier.flags.q.in) {
            _mesa_glsl_error(& loc, state,
                             "`in' qualifier in declaration of `%s' "
-                            "only valid for function parameters in GLSL 1.10.",
-                            decl->identifier);
+                            "only valid for function parameters in %s.",
+                            decl->identifier, state->version_string);
         }
         /* FINISHME: Test for other invalid qualifiers. */
       }
@@ -1750,7 +2459,7 @@ ast_declarator_list::hir(exec_list *instructions,
       apply_type_qualifier_to_variable(& this->type->qualifier, var, state,
                                       & loc);
 
-      if (this->type->qualifier.invariant) {
+      if (this->type->qualifier.flags.q.invariant) {
         if ((state->target == vertex_shader) && !(var->mode == ir_var_out ||
                                                   var->mode == ir_var_inout)) {
            /* FINISHME: Note that this doesn't work for invariant on
@@ -1777,16 +2486,16 @@ ast_declarator_list::hir(exec_list *instructions,
         /* There is no need to check for 'inout' here because the parser will
          * only allow that in function parameter lists.
          */
-        if (this->type->qualifier.attribute) {
+        if (this->type->qualifier.flags.q.attribute) {
            mode = "attribute";
-        } else if (this->type->qualifier.uniform) {
+        } else if (this->type->qualifier.flags.q.uniform) {
            mode = "uniform";
-        } else if (this->type->qualifier.varying) {
+        } else if (this->type->qualifier.flags.q.varying) {
            mode = "varying";
-        } else if (this->type->qualifier.in) {
+        } else if (this->type->qualifier.flags.q.in) {
            mode = "in";
            extra = " or in function parameter list";
-        } else if (this->type->qualifier.out) {
+        } else if (this->type->qualifier.flags.q.out) {
            mode = "out";
            extra = " or in function parameter list";
         }
@@ -1798,6 +2507,8 @@ ast_declarator_list::hir(exec_list *instructions,
                             mode, var->name, extra);
         }
       } else if (var->mode == ir_var_in) {
+         var->read_only = true;
+
         if (state->target == vertex_shader) {
            bool error_emitted = false;
 
@@ -1850,94 +2561,144 @@ ast_declarator_list::hir(exec_list *instructions,
         }
       }
 
-      /* Process the initializer and add its instructions to a temporary
-       * list.  This list will be added to the instruction stream (below) after
-       * the declaration is added.  This is done because in some cases (such as
-       * redeclarations) the declaration may not actually be added to the
-       * instruction stream.
+      /* Integer vertex outputs must be qualified with 'flat'.
+       *
+       * From section 4.3.6 of the GLSL 1.30 spec:
+       *    "If a vertex output is a signed or unsigned integer or integer
+       *    vector, then it must be qualified with the interpolation qualifier
+       *    flat."
        */
-      exec_list initializer_instructions;
-      if (decl->initializer != NULL) {
-        YYLTYPE initializer_loc = decl->initializer->get_location();
+      if (state->language_version >= 130
+          && state->target == vertex_shader
+          && state->current_function == NULL
+          && var->type->is_integer()
+          && var->mode == ir_var_out
+          && var->interpolation != ir_var_flat) {
+
+         _mesa_glsl_error(&loc, state, "If a vertex output is an integer, "
+                          "then it must be qualified with 'flat'");
+      }
 
-        /* From page 24 (page 30 of the PDF) of the GLSL 1.10 spec:
-         *
-         *    "All uniform variables are read-only and are initialized either
-         *    directly by an application via API commands, or indirectly by
-         *    OpenGL."
-         */
-        if ((state->language_version <= 110)
-            && (var->mode == ir_var_uniform)) {
-           _mesa_glsl_error(& initializer_loc, state,
-                            "cannot initialize uniforms in GLSL 1.10");
-        }
 
-        if (var->type->is_sampler()) {
-           _mesa_glsl_error(& initializer_loc, state,
-                            "cannot initialize samplers");
-        }
+      /* Interpolation qualifiers cannot be applied to 'centroid' and
+       * 'centroid varying'.
+       *
+       * From page 29 (page 35 of the PDF) of the GLSL 1.30 spec:
+       *    "interpolation qualifiers may only precede the qualifiers in,
+       *    centroid in, out, or centroid out in a declaration. They do not apply
+       *    to the deprecated storage qualifiers varying or centroid varying."
+       */
+      if (state->language_version >= 130
+          && this->type->qualifier.has_interpolation()
+          && this->type->qualifier.flags.q.varying) {
+
+         const char *i = this->type->qualifier.interpolation_string();
+         assert(i != NULL);
+         const char *s;
+         if (this->type->qualifier.flags.q.centroid)
+            s = "centroid varying";
+         else
+            s = "varying";
+
+         _mesa_glsl_error(&loc, state,
+                          "qualifier '%s' cannot be applied to the "
+                          "deprecated storage qualifier '%s'", i, s);
+      }
 
-        if ((var->mode == ir_var_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)
-                            ? "attribute" : "varying");
-        }
 
-        ir_dereference *const lhs = new(ctx) ir_dereference_variable(var);
-        ir_rvalue *rhs = decl->initializer->hir(&initializer_instructions,
-                                                state);
+      /* Interpolation qualifiers can only apply to vertex shader outputs and
+       * fragment shader inputs.
+       *
+       * From page 29 (page 35 of the PDF) of the GLSL 1.30 spec:
+       *    "Outputs from a vertex shader (out) and inputs to a fragment
+       *    shader (in) can be further qualified with one or more of these
+       *    interpolation qualifiers"
+       */
+      if (state->language_version >= 130
+          && this->type->qualifier.has_interpolation()) {
+
+         const char *i = this->type->qualifier.interpolation_string();
+         assert(i != NULL);
+
+         switch (state->target) {
+         case vertex_shader:
+            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:
+            if (this->type->qualifier.flags.q.out) {
+               _mesa_glsl_error(&loc, state,
+                                "qualifier '%s' cannot be applied to fragment "
+                                "shader outputs", i);
+            }
+            break;
+         default:
+            assert(0);
+         }
+      }
 
-        /* Calculate the constant value if this is a const or uniform
-         * declaration.
-         */
-        if (this->type->qualifier.constant || this->type->qualifier.uniform) {
-           ir_rvalue *new_rhs = validate_assignment(state, var->type, rhs);
-           if (new_rhs != NULL) {
-              rhs = new_rhs;
-
-              ir_constant *constant_value = rhs->constant_expression_value();
-              if (!constant_value) {
-                 _mesa_glsl_error(& initializer_loc, state,
-                                  "initializer of %s variable `%s' must be a "
-                                  "constant expression",
-                                  (this->type->qualifier.constant)
-                                  ? "const" : "uniform",
-                                  decl->identifier);
-                 if (var->type->is_numeric()) {
-                    /* Reduce cascading errors. */
-                    var->constant_value = ir_constant::zero(ctx, var->type);
-                 }
-              } else {
-                 rhs = constant_value;
-                 var->constant_value = constant_value;
-              }
-           } else {
-              _mesa_glsl_error(&initializer_loc, state,
-                               "initializer of type %s cannot be assigned to "
-                               "variable of type %s",
-                               rhs->type->name, var->type->name);
-              if (var->type->is_numeric()) {
-                 /* Reduce cascading errors. */
-                 var->constant_value = ir_constant::zero(ctx, var->type);
-              }
-           }
-        }
 
-        if (rhs && !rhs->type->is_error()) {
-           bool temp = var->read_only;
-           if (this->type->qualifier.constant)
-              var->read_only = false;
+      /* From section 4.3.4 of the GLSL 1.30 spec:
+       *    "It is an error to use centroid in in a vertex shader."
+       */
+      if (state->language_version >= 130
+          && this->type->qualifier.flags.q.centroid
+          && this->type->qualifier.flags.q.in
+          && state->target == vertex_shader) {
 
-           /* Never emit code to initialize a uniform.
-            */
-           if (!this->type->qualifier.uniform)
-              result = do_assignment(&initializer_instructions, state,
-                                     lhs, rhs,
-                                     this->get_location());
-           var->read_only = temp;
-        }
+         _mesa_glsl_error(&loc, state,
+                          "'centroid in' cannot be used in a vertex shader");
+      }
+
+
+      /* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30.
+       */
+      if (this->type->specifier->precision != ast_precision_none
+          && state->language_version != 100
+          && state->language_version < 130) {
+
+         _mesa_glsl_error(&loc, state,
+                          "precision qualifiers are supported only in GLSL ES "
+                          "1.00, and GLSL 1.30 and later");
+      }
+
+
+      /* Precision qualifiers only apply to floating point and integer types.
+       *
+       * From section 4.5.2 of the GLSL 1.30 spec:
+       *    "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.
+       */
+      if (this->type->specifier->precision != ast_precision_none
+          && !var->type->is_float()
+          && !var->type->is_integer()
+          && !(var->type->is_array()
+               && (var->type->fields.array->is_float()
+                   || var->type->fields.array->is_integer()))) {
+
+         _mesa_glsl_error(&loc, state,
+                          "precision qualifiers apply only to floating point "
+                          "and integer types");
+      }
+
+      /* Process the initializer and add its instructions to a temporary
+       * list.  This list will be added to the instruction stream (below) after
+       * the declaration is added.  This is done because in some cases (such as
+       * redeclarations) the declaration may not actually be added to the
+       * instruction stream.
+       */
+      exec_list initializer_instructions;
+      ir_variable *earlier = get_variable_being_redeclared(var, decl, state);
+
+      if (decl->initializer != NULL) {
+        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:
@@ -1946,117 +2707,56 @@ ast_declarator_list::hir(exec_list *instructions,
        *      its declaration, so they must be initialized when
        *      declared."
        */
-      if (this->type->qualifier.constant && decl->initializer == NULL) {
+      if (this->type->qualifier.flags.q.constant && decl->initializer == NULL) {
         _mesa_glsl_error(& loc, state,
-                         "const declaration of `%s' must be initialized");
+                         "const declaration of `%s' must be initialized",
+                         decl->identifier);
       }
 
-      /* Check if this declaration is actually a re-declaration, either to
-       * resize an array or add qualifiers to an existing variable.
-       *
-       * This is allowed for variables in the current scope, or when at
-       * global scope (for built-ins in the implicit outer scope).
+      /* If the declaration is not a redeclaration, there are a few additional
+       * semantic checks that must be applied.  In addition, variable that was
+       * created for the declaration should be added to the IR stream.
        */
-      ir_variable *earlier = state->symbols->get_variable(decl->identifier);
-      if (earlier != NULL && (state->current_function == NULL ||
-         state->symbols->name_declared_this_scope(decl->identifier))) {
-
-        /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec,
+      if (earlier == NULL) {
+        /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec,
          *
-         * "It is legal to declare an array without a size and then
-         *  later re-declare the same name as an array of the same
-         *  type and specify a size."
+         *   "Identifiers starting with "gl_" are reserved for use by
+         *   OpenGL, and may not be declared in a shader as either a
+         *   variable or a function."
          */
-        if ((earlier->type->array_size() == 0)
-            && var->type->is_array()
-            && (var->type->element_type() == earlier->type->element_type())) {
-           /* FINISHME: This doesn't match the qualifiers on the two
-            * FINISHME: declarations.  It's not 100% clear whether this is
-            * FINISHME: required or not.
-            */
-
-           /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec:
-            *
-            *     "The size [of gl_TexCoord] can be at most
-            *     gl_MaxTextureCoords."
-            */
-           const unsigned size = unsigned(var->type->array_size());
-           if ((strcmp("gl_TexCoord", var->name) == 0)
-               && (size > state->Const.MaxTextureCoords)) {
-              YYLTYPE loc = this->get_location();
-
-              _mesa_glsl_error(& loc, state, "`gl_TexCoord' array size cannot "
-                               "be larger than gl_MaxTextureCoords (%u)\n",
-                               state->Const.MaxTextureCoords);
-           } else if ((size > 0) && (size <= earlier->max_array_access)) {
-              YYLTYPE loc = this->get_location();
-
-              _mesa_glsl_error(& loc, state, "array size must be > %u due to "
-                               "previous access",
-                               earlier->max_array_access);
-           }
+        if (strncmp(decl->identifier, "gl_", 3) == 0)
+           _mesa_glsl_error(& loc, state,
+                            "identifier `%s' uses reserved `gl_' prefix",
+                            decl->identifier);
 
-           earlier->type = var->type;
-           delete var;
-           var = NULL;
-        } else if (state->extensions->ARB_fragment_coord_conventions
-                   && strcmp(var->name, "gl_FragCoord") == 0
-                   && earlier->type == var->type
-                   && earlier->mode == var->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;
-        } else {
+        /* 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, "`%s' redeclared", decl->identifier);
+           _mesa_glsl_error(&loc, state, "name `%s' already taken in the "
+                            "current scope", decl->identifier);
+           continue;
         }
 
-        continue;
-      }
-
-      /* By now, we know it's a new variable declaration (we didn't hit the
-       * above "continue").
-       *
-       * From page 15 (page 21 of the PDF) of the GLSL 1.10 spec,
-       *
-       *   "Identifiers starting with "gl_" are reserved for use by
-       *   OpenGL, and may not be declared in a shader as either a
-       *   variable or a function."
-       */
-      if (strncmp(decl->identifier, "gl_", 3) == 0)
-        _mesa_glsl_error(& loc, state,
-                         "identifier `%s' uses reserved `gl_' prefix",
-                         decl->identifier);
-
-      /* 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->name, 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);
       }
 
-      /* 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);
    }
 
@@ -2129,7 +2829,7 @@ ast_parameter_declarator::hir(exec_list *instructions,
     * call already handled the "vec4[..] foo" case.
     */
    if (this->is_array) {
-      type = process_array_type(type, this->array_size, state);
+      type = process_array_type(&loc, type, this->array_size, state);
    }
 
    if (type->array_size() == 0) {
@@ -2182,6 +2882,27 @@ ast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters,
 }
 
 
+void
+emit_function(_mesa_glsl_parse_state *state, exec_list *instructions,
+             ir_function *f)
+{
+   /* Emit the new function header */
+   if (state->current_function == NULL) {
+      instructions->push_tail(f);
+   } else {
+      /* IR invariants disallow function declarations or definitions nested
+       * within other function definitions.  Insert the new ir_function
+       * block in the instruction sequence before the ir_function block
+       * containing the current ir_function_signature.
+       */
+      ir_function *const curr =
+        const_cast<ir_function *>(state->current_function->function());
+
+      curr->insert_before(f);
+   }
+}
+
+
 ir_rvalue *
 ast_function::hir(exec_list *instructions,
                  struct _mesa_glsl_parse_state *state)
@@ -2258,7 +2979,7 @@ ast_function::hir(exec_list *instructions,
     * that the previously seen signature does not have an associated definition.
     */
    f = state->symbols->get_function(name);
-   if (f != NULL && !f->is_builtin) {
+   if (f != NULL && (state->es_shader || f->has_user_signature())) {
       sig = f->exact_matching_signature(&hir_parameters);
       if (sig != NULL) {
         const char *badvar = sig->qualifiers_match(&hir_parameters);
@@ -2284,7 +3005,7 @@ ast_function::hir(exec_list *instructions,
       }
    } else {
       f = new(ctx) ir_function(name);
-      if (!state->symbols->add_function(f->name, f)) {
+      if (!state->symbols->add_function(f)) {
         /* This function name shadows a non-function use of the same name. */
         YYLTYPE loc = this->get_location();
 
@@ -2293,24 +3014,7 @@ ast_function::hir(exec_list *instructions,
         return NULL;
       }
 
-      /* Emit the new function header */
-      if (state->current_function == NULL)
-        instructions->push_tail(f);
-      else {
-        /* IR invariants disallow function declarations or definitions nested
-         * within other function definitions.  Insert the new ir_function
-         * block in the instruction sequence before the ir_function block
-         * containing the current ir_function_signature.
-         *
-         * This can only happen in a GLSL 1.10 shader.  In all other GLSL
-         * versions this nesting is disallowed.  There is a check for this at
-         * the top of this function.
-         */
-        ir_function *const curr =
-           const_cast<ir_function *>(state->current_function->function());
-
-        curr->insert_before(f);
-      }
+      emit_function(state, instructions, f);
    }
 
    /* Verify the return type of main() */
@@ -2376,7 +3080,7 @@ ast_function_definition::hir(exec_list *instructions,
 
         _mesa_glsl_error(& loc, state, "parameter `%s' redeclared", var->name);
       } else {
-        state->symbols->add_variable(var->name, var);
+        state->symbols->add_variable(var);
       }
    }
 
@@ -2415,28 +3119,26 @@ ast_jump_statement::hir(exec_list *instructions,
       assert(state->current_function);
 
       if (opt_return_value) {
-        if (state->current_function->return_type->base_type ==
-            GLSL_TYPE_VOID) {
-           YYLTYPE loc = this->get_location();
+        ir_rvalue *const ret = opt_return_value->hir(instructions, state);
 
-           _mesa_glsl_error(& loc, state,
-                            "`return` with a value, in function `%s' "
-                            "returning void",
-                            state->current_function->function_name());
-        }
-
-        ir_expression *const ret = (ir_expression *)
-           opt_return_value->hir(instructions, state);
-        assert(ret != NULL);
+        /* 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. */
-        if (state->current_function->return_type != ret->type) {
+        if (state->current_function->return_type != ret_type) {
            YYLTYPE loc = this->get_location();
 
            _mesa_glsl_error(& loc, state,
                             "`return' with wrong type %s, in function `%s' "
                             "returning %s",
-                            ret->type->name,
+                            ret_type->name,
                             state->current_function->function_name(),
                             state->current_function->return_type->name);
         }
@@ -2653,6 +3355,58 @@ ir_rvalue *
 ast_type_specifier::hir(exec_list *instructions,
                          struct _mesa_glsl_parse_state *state)
 {
+   if (!this->is_precision_statement && this->structure == NULL)
+      return NULL;
+
+   YYLTYPE loc = this->get_location();
+
+   if (this->precision != ast_precision_none
+       && state->language_version != 100
+       && state->language_version < 130) {
+      _mesa_glsl_error(&loc, state,
+                       "precision qualifiers exist only in "
+                       "GLSL ES 1.00, and GLSL 1.30 and later");
+      return NULL;
+   }
+   if (this->precision != ast_precision_none
+       && this->structure != NULL) {
+      _mesa_glsl_error(&loc, state,
+                       "precision qualifiers do not apply to structures");
+      return NULL;
+   }
+
+   /* If this is a precision statement, check that the type to which it is
+    * applied is either float or int.
+    *
+    * From section 4.5.3 of the GLSL 1.30 spec:
+    *    "The precision statement
+    *       precision precision-qualifier type;
+    *    can be used to establish a default precision qualifier. The type
+    *    field can be either int or float [...].  Any other types or
+    *    qualifiers will result in an error.
+    */
+   if (this->is_precision_statement) {
+      assert(this->precision != ast_precision_none);
+      assert(this->structure == NULL); /* The check for structures was
+                                        * performed above. */
+      if (this->is_array) {
+         _mesa_glsl_error(&loc, state,
+                          "default precision statements do not apply to "
+                          "arrays");
+         return NULL;
+      }
+      if (this->type_specifier != ast_float
+          && this->type_specifier != ast_int) {
+         _mesa_glsl_error(&loc, state,
+                          "default precision statements apply only to types "
+                          "float and int");
+         return NULL;
+      }
+
+      /* FINISHME: Translate precision statements into IR. */
+      return NULL;
+   }
+
    if (this->structure != NULL)
       return this->structure->hir(instructions, state);
 
@@ -2678,13 +3432,12 @@ ast_struct_specifier::hir(exec_list *instructions,
       }
    }
 
-
    /* Allocate storage for the structure fields and process the field
     * declarations.  As the declarations are processed, try to also convert
     * the types to HIR.  This ensures that structure definitions embedded in
     * other structure definitions are processed.
     */
-   glsl_struct_field *const fields = talloc_array(state, glsl_struct_field,
+   glsl_struct_field *const fields = ralloc_array(state, glsl_struct_field,
                                                  decl_count);
 
    unsigned i = 0;
@@ -2694,16 +3447,26 @@ ast_struct_specifier::hir(exec_list *instructions,
 
       decl_list->type->specifier->hir(instructions, state);
 
+      /* Section 10.9 of the GLSL ES 1.00 specification states that
+       * embedded structure definitions have been removed from the language.
+       */
+      if (state->es_shader && decl_list->type->specifier->structure != NULL) {
+        YYLTYPE loc = this->get_location();
+        _mesa_glsl_error(&loc, state, "Embedded structure definitions are "
+                         "not allowed in GLSL ES 1.00.");
+      }
+
       const glsl_type *decl_type =
         decl_list->type->specifier->glsl_type(& type_name, state);
 
       foreach_list_typed (ast_declaration, decl, link,
                          &decl_list->declarations) {
-        const struct glsl_type *const field_type =
-           (decl->is_array)
-           ? process_array_type(decl_type, decl->array_size, state)
-           : decl_type;
-
+        const struct glsl_type *field_type = decl_type;
+        if (decl->is_array) {
+           YYLTYPE loc = decl->get_location();
+           field_type = process_array_type(&loc, decl_type, decl->array_size,
+                                           state);
+        }
         fields[i].type = (field_type != NULL)
            ? field_type : glsl_type::error_type;
         fields[i].name = decl->identifier;
@@ -2713,31 +3476,16 @@ ast_struct_specifier::hir(exec_list *instructions,
 
    assert(i == decl_count);
 
-   const char *name;
-   if (this->name == NULL) {
-      static unsigned anon_count = 1;
-      char buf[32];
-
-      snprintf(buf, sizeof(buf), "#anon_struct_%04x", anon_count);
-      anon_count++;
-
-      name = strdup(buf);
-   } else {
-      name = this->name;
-   }
-
    const glsl_type *t =
-      glsl_type::get_record_instance(fields, decl_count, name);
+      glsl_type::get_record_instance(fields, decl_count, this->name);
 
    YYLTYPE loc = this->get_location();
    if (!state->symbols->add_type(name, t)) {
       _mesa_glsl_error(& loc, state, "struct `%s' previously defined", name);
    } else {
-
-      const glsl_type **s = (const glsl_type **)
-        realloc(state->user_structures,
-                sizeof(state->user_structures[0]) *
-                (state->num_user_structures + 1));
+      const glsl_type **s = reralloc(state, state->user_structures,
+                                    const glsl_type *,
+                                    state->num_user_structures + 1);
       if (s != NULL) {
         s[state->num_user_structures] = t;
         state->user_structures = s;