mesa: set up gl_vert_result and gl_frag_attrib values for gl_ClipDistance.
[mesa.git] / src / glsl / ast_to_hir.cpp
index cdb16fd492bfffeba4f978a388c82f0d100bf5ce..ce29d5a87aa0ed1842e75dd1b346bd415e0cfbce 100644 (file)
@@ -66,6 +66,8 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
 
    state->current_function = NULL;
 
+   state->toplevel_ir = instructions;
+
    /* Section 4.2 of the GLSL 1.20 specification states:
     * "The built-in functions are scoped in a scope outside the global scope
     *  users declare global variables in.  That is, a shader's global scope,
@@ -83,6 +85,10 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
 
    foreach_list_typed (ast_node, ast, link, & state->translation_unit)
       ast->hir(instructions, state);
+
+   detect_recursion_unlinked(state, instructions);
+
+   state->toplevel_ir = NULL;
 }
 
 
@@ -447,9 +453,17 @@ modulus_result_type(const struct glsl_type *type_a,
     *    integer vectors. The operand types must both be signed or both be
     *    unsigned."
     */
-   if (!type_a->is_integer() || !type_b->is_integer()
-       || (type_a->base_type != type_b->base_type)) {
-      _mesa_glsl_error(loc, state, "type mismatch");
+   if (!type_a->is_integer()) {
+      _mesa_glsl_error(loc, state, "LHS of operator %% must be an integer.");
+      return glsl_type::error_type;
+   }
+   if (!type_b->is_integer()) {
+      _mesa_glsl_error(loc, state, "RHS of operator %% must be an integer.");
+      return glsl_type::error_type;
+   }
+   if (type_a->base_type != type_b->base_type) {
+      _mesa_glsl_error(loc, state,
+                      "operands of %% must have the same base type");
       return glsl_type::error_type;
    }
 
@@ -639,6 +653,16 @@ validate_assignment(struct _mesa_glsl_parse_state *state,
    return NULL;
 }
 
+static void
+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;
+   }
+}
+
 ir_rvalue *
 do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
              ir_rvalue *lhs, ir_rvalue *rhs, bool is_initializer,
@@ -655,16 +679,20 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
                           lhs->variable_referenced()->name);
          error_emitted = true;
 
+      } else if (state->language_version <= 110 && lhs->type->is_array()) {
+        /* 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."
+         */
+        _mesa_glsl_error(&lhs_loc, state, "whole array assignment is not "
+                         "allowed in GLSL 1.10 or GLSL ES 1.00.");
+        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 =
@@ -699,6 +727,8 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
                                                   rhs->type->array_size());
         d->type = var->type;
       }
+      mark_whole_array_access(rhs);
+      mark_whole_array_access(lhs);
    }
 
    /* Most callers of do_assignment (assign, add_assign, pre_inc/dec,
@@ -759,16 +789,6 @@ 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)
 {
@@ -848,6 +868,74 @@ do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
    return cmp;
 }
 
+/* For logical operations, we want to ensure that the operands are
+ * scalar booleans.  If it isn't, emit an error and return a constant
+ * boolean to avoid triggering cascading error messages.
+ */
+ir_rvalue *
+get_scalar_boolean_operand(exec_list *instructions,
+                          struct _mesa_glsl_parse_state *state,
+                          ast_expression *parent_expr,
+                          int operand,
+                          const char *operand_name,
+                          bool *error_emitted)
+{
+   ast_expression *expr = parent_expr->subexpressions[operand];
+   void *ctx = state;
+   ir_rvalue *val = expr->hir(instructions, state);
+
+   if (val->type->is_boolean() && val->type->is_scalar())
+      return val;
+
+   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));
+      *error_emitted = true;
+   }
+
+   return new(ctx) ir_constant(true);
+}
+
+/**
+ * If name refers to a builtin array whose maximum allowed size is less than
+ * size, report an error and return true.  Otherwise return false.
+ */
+static bool
+check_builtin_array_max_size(const char *name, unsigned size,
+                             YYLTYPE loc, struct _mesa_glsl_parse_state *state)
+{
+   if ((strcmp("gl_TexCoord", name) == 0)
+       && (size > state->Const.MaxTextureCoords)) {
+      /* 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."
+       */
+      _mesa_glsl_error(&loc, state, "`gl_TexCoord' array size cannot "
+                       "be larger than gl_MaxTextureCoords (%u)\n",
+                       state->Const.MaxTextureCoords);
+      return true;
+   } else if (strcmp("gl_ClipDistance", name) == 0
+              && size > state->Const.MaxClipPlanes) {
+      /* From section 7.1 (Vertex Shader Special Variables) of the
+       * GLSL 1.30 spec:
+       *
+       *   "The gl_ClipDistance array is predeclared as unsized and
+       *   must be sized by the shader either redeclaring it with a
+       *   size or indexing it only with integral constant
+       *   expressions. ... The size can be at most
+       *   gl_MaxClipDistances."
+       */
+      _mesa_glsl_error(&loc, state, "`gl_ClipDistance' array size cannot "
+                       "be larger than gl_MaxClipDistances (%u)\n",
+                       state->Const.MaxClipPlanes);
+      return true;
+   }
+   return false;
+}
+
 ir_rvalue *
 ast_expression::hir(exec_list *instructions,
                    struct _mesa_glsl_parse_state *state)
@@ -910,7 +998,7 @@ ast_expression::hir(exec_list *instructions,
    };
    ir_rvalue *result = NULL;
    ir_rvalue *op[3];
-   const struct glsl_type *type = glsl_type::error_type;
+   const struct glsl_type *type; /* a temporary variable for switch cases */
    bool error_emitted = false;
    YYLTYPE loc;
 
@@ -924,7 +1012,6 @@ ast_expression::hir(exec_list *instructions,
       result = do_assignment(instructions, state, op[0], op[1], false,
                             this->subexpressions[0]->get_location());
       error_emitted = result->type->is_error();
-      type = result->type;
       break;
    }
 
@@ -1043,10 +1130,12 @@ ast_expression::hir(exec_list *instructions,
         error_emitted = true;
       }
 
-      result = do_comparison(ctx, operations[this->oper], op[0], op[1]);
-      type = glsl_type::bool_type;
-
-      assert(error_emitted || (result->type == glsl_type::bool_type));
+      if (error_emitted) {
+        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);
+      }
       break;
 
    case ast_bit_and:
@@ -1079,29 +1168,16 @@ ast_expression::hir(exec_list *instructions,
       break;
 
    case ast_logic_and: {
-      op[0] = this->subexpressions[0]->hir(instructions, state);
-
-      if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
-        YYLTYPE loc = this->subexpressions[0]->get_location();
-
-        _mesa_glsl_error(& loc, state, "LHS of `%s' must be scalar boolean",
-                         operator_string(this->oper));
-        error_emitted = true;
-      }
+      exec_list rhs_instructions;
+      op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
+                                        "LHS", &error_emitted);
+      op[1] = get_scalar_boolean_operand(&rhs_instructions, state, this, 1,
+                                        "RHS", &error_emitted);
 
       ir_constant *op0_const = op[0]->constant_expression_value();
       if (op0_const) {
         if (op0_const->value.b[0]) {
-           op[1] = this->subexpressions[1]->hir(instructions, state);
-
-           if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
-              YYLTYPE loc = this->subexpressions[1]->get_location();
-
-              _mesa_glsl_error(& loc, state,
-                               "RHS of `%s' must be scalar boolean",
-                               operator_string(this->oper));
-              error_emitted = true;
-           }
+           instructions->append_list(&rhs_instructions);
            result = op[1];
         } else {
            result = op0_const;
@@ -1116,17 +1192,7 @@ ast_expression::hir(exec_list *instructions,
         ir_if *const stmt = new(ctx) ir_if(op[0]);
         instructions->push_tail(stmt);
 
-        op[1] = this->subexpressions[1]->hir(&stmt->then_instructions, state);
-
-        if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
-           YYLTYPE loc = this->subexpressions[1]->get_location();
-
-           _mesa_glsl_error(& loc, state,
-                            "RHS of `%s' must be scalar boolean",
-                            operator_string(this->oper));
-           error_emitted = true;
-        }
-
+        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], NULL);
@@ -1144,31 +1210,17 @@ ast_expression::hir(exec_list *instructions,
    }
 
    case ast_logic_or: {
-      op[0] = this->subexpressions[0]->hir(instructions, state);
-
-      if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
-        YYLTYPE loc = this->subexpressions[0]->get_location();
-
-        _mesa_glsl_error(& loc, state, "LHS of `%s' must be scalar boolean",
-                         operator_string(this->oper));
-        error_emitted = true;
-      }
+      exec_list rhs_instructions;
+      op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
+                                        "LHS", &error_emitted);
+      op[1] = get_scalar_boolean_operand(&rhs_instructions, state, this, 1,
+                                        "RHS", &error_emitted);
 
       ir_constant *op0_const = op[0]->constant_expression_value();
       if (op0_const) {
         if (op0_const->value.b[0]) {
            result = op0_const;
         } else {
-           op[1] = this->subexpressions[1]->hir(instructions, state);
-
-           if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
-              YYLTYPE loc = this->subexpressions[1]->get_location();
-
-              _mesa_glsl_error(& loc, state,
-                               "RHS of `%s' must be scalar boolean",
-                               operator_string(this->oper));
-              error_emitted = true;
-           }
            result = op[1];
         }
         type = glsl_type::bool_type;
@@ -1181,21 +1233,12 @@ ast_expression::hir(exec_list *instructions,
         ir_if *const stmt = new(ctx) ir_if(op[0]);
         instructions->push_tail(stmt);
 
-        op[1] = this->subexpressions[1]->hir(&stmt->else_instructions, state);
-
-        if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
-           YYLTYPE loc = this->subexpressions[1]->get_location();
-
-           _mesa_glsl_error(& loc, state, "RHS of `%s' must be scalar boolean",
-                            operator_string(this->oper));
-           error_emitted = true;
-        }
-
         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), NULL);
         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], NULL);
@@ -1208,29 +1251,27 @@ ast_expression::hir(exec_list *instructions,
    }
 
    case ast_logic_xor:
-      op[0] = this->subexpressions[0]->hir(instructions, state);
-      op[1] = this->subexpressions[1]->hir(instructions, state);
-
+      /* From page 33 (page 39 of the PDF) of the GLSL 1.10 spec:
+       *
+       *    "The logical binary operators and (&&), or ( | | ), and
+       *     exclusive or (^^). They operate only on two Boolean
+       *     expressions and result in a Boolean expression."
+       */
+      op[0] = get_scalar_boolean_operand(instructions, state, this, 0, "LHS",
+                                        &error_emitted);
+      op[1] = get_scalar_boolean_operand(instructions, state, this, 1, "RHS",
+                                        &error_emitted);
 
       result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
                                      op[0], op[1]);
-      type = glsl_type::bool_type;
       break;
 
    case ast_logic_not:
-      op[0] = this->subexpressions[0]->hir(instructions, state);
-
-      if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
-        YYLTYPE loc = this->subexpressions[0]->get_location();
-
-        _mesa_glsl_error(& loc, state,
-                         "operand of `!' must be scalar boolean");
-        error_emitted = true;
-      }
+      op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
+                                        "operand", &error_emitted);
 
       result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
                                      op[0], NULL);
-      type = glsl_type::bool_type;
       break;
 
    case ast_mul_assign:
@@ -1250,7 +1291,6 @@ ast_expression::hir(exec_list *instructions,
       result = do_assignment(instructions, state,
                             op[0]->clone(ctx, NULL), temp_rhs, false,
                             this->subexpressions[0]->get_location());
-      type = result->type;
       error_emitted = (op[0]->type->is_error());
 
       /* GLSL 1.10 does not allow array assignment.  However, we don't have to
@@ -1276,7 +1316,6 @@ ast_expression::hir(exec_list *instructions,
       result = do_assignment(instructions, state,
                             op[0]->clone(ctx, NULL), temp_rhs, false,
                             this->subexpressions[0]->get_location());
-      type = result->type;
       error_emitted = type->is_error();
       break;
    }
@@ -1313,20 +1352,14 @@ ast_expression::hir(exec_list *instructions,
    }
 
    case ast_conditional: {
-      op[0] = this->subexpressions[0]->hir(instructions, state);
-
       /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec:
        *
        *    "The ternary selection operator (?:). It operates on three
        *    expressions (exp1 ? exp2 : exp3). This operator evaluates the
        *    first expression, which must result in a scalar Boolean."
        */
-      if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
-        YYLTYPE loc = this->subexpressions[0]->get_location();
-
-        _mesa_glsl_error(& loc, state, "?: condition must be scalar boolean");
-        error_emitted = true;
-      }
+      op[0] = get_scalar_boolean_operand(instructions, state, this, 0,
+                                        "condition", &error_emitted);
 
       /* The :? operator is implemented by generating an anonymous temporary
        * followed by an if-statement.  The last instruction in each branch of
@@ -1424,7 +1457,6 @@ ast_expression::hir(exec_list *instructions,
       result = do_assignment(instructions, state,
                             op[0]->clone(ctx, NULL), temp_rhs, false,
                             this->subexpressions[0]->get_location());
-      type = result->type;
       error_emitted = op[0]->type->is_error();
       break;
    }
@@ -1454,14 +1486,12 @@ ast_expression::hir(exec_list *instructions,
                          op[0]->clone(ctx, NULL), temp_rhs, false,
                          this->subexpressions[0]->get_location());
 
-      type = result->type;
       error_emitted = op[0]->type->is_error();
       break;
    }
 
    case ast_field_selection:
       result = _mesa_ast_field_selection_to_hir(this, instructions, state);
-      type = result->type;
       break;
 
    case ast_array_index: {
@@ -1563,8 +1593,15 @@ ast_expression::hir(exec_list *instructions,
             * FINISHME: array access limits be added to ir_dereference?
             */
            ir_variable *const v = array->whole_variable_referenced();
-           if ((v != NULL) && (unsigned(idx) > v->max_array_access))
+           if ((v != NULL) && (unsigned(idx) > v->max_array_access)) {
               v->max_array_access = idx;
+
+               /* Check whether this access will, as a side effect, implicitly
+                * cause the size of a built-in array to be too large.
+                */
+               if (check_builtin_array_max_size(v->name, idx+1, loc, state))
+                  error_emitted = true;
+            }
         }
       } else if (array->type->array_size() == 0) {
         _mesa_glsl_error(&loc, state, "unsized array index must be constant");
@@ -1577,7 +1614,7 @@ ast_expression::hir(exec_list *instructions,
             */
            ir_variable *v = array->whole_variable_referenced();
            if (v != NULL)
-              v->max_array_access = array->type->array_size();
+              v->max_array_access = array->type->array_size() - 1;
         }
       }
 
@@ -1618,7 +1655,6 @@ ast_expression::hir(exec_list *instructions,
       if (error_emitted)
         result->type = glsl_type::error_type;
 
-      type = result->type;
       break;
    }
 
@@ -1641,7 +1677,6 @@ ast_expression::hir(exec_list *instructions,
 
       if (var != NULL) {
         var->used = true;
-        type = result->type;
       } else {
         _mesa_glsl_error(& loc, state, "`%s' undeclared",
                          this->primary_expression.identifier);
@@ -1652,22 +1687,18 @@ ast_expression::hir(exec_list *instructions,
    }
 
    case ast_int_constant:
-      type = glsl_type::int_type;
       result = new(ctx) ir_constant(this->primary_expression.int_constant);
       break;
 
    case ast_uint_constant:
-      type = glsl_type::uint_type;
       result = new(ctx) ir_constant(this->primary_expression.uint_constant);
       break;
 
    case ast_float_constant:
-      type = glsl_type::float_type;
       result = new(ctx) ir_constant(this->primary_expression.float_constant);
       break;
 
    case ast_bool_constant:
-      type = glsl_type::bool_type;
       result = new(ctx) ir_constant(bool(this->primary_expression.bool_constant));
       break;
 
@@ -1682,10 +1713,42 @@ ast_expression::hir(exec_list *instructions,
        * therefore add instructions to the instruction list), they get dropped
        * on the floor.
        */
-      foreach_list_typed (ast_node, ast, link, &this->expressions)
-        result = ast->hir(instructions, state);
+      exec_node *previous_tail_pred = NULL;
+      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();
 
-      type = result->type;
+        result = ast->hir(instructions, state);
+      }
 
       /* Any errors should have already been emitted in the loop above.
        */
@@ -1693,8 +1756,10 @@ ast_expression::hir(exec_list *instructions,
       break;
    }
    }
+   type = NULL; /* use result->type, not type. */
+   assert(result != NULL);
 
-   if (type->is_error() && !error_emitted)
+   if (result->type->is_error() && !error_emitted)
       _mesa_glsl_error(& loc, state, "type mismatch");
 
    return result;
@@ -1755,11 +1820,6 @@ process_array_type(YYLTYPE *loc, const glsl_type *base, ast_node *array_size,
       ir_rvalue *const ir = array_size->hir(& dummy_instructions, state);
       YYLTYPE loc = array_size->get_location();
 
-      /* FINISHME: Verify that the grammar forbids side-effects in array
-       * FINISHME: sizes.   i.e., 'vec4 [x = 12] data'
-       */
-      assert(dummy_instructions.is_empty());
-
       if (ir != NULL) {
         if (!ir->type->is_integer()) {
            _mesa_glsl_error(& loc, state, "array size must be integer type");
@@ -1776,6 +1836,14 @@ process_array_type(YYLTYPE *loc, const glsl_type *base, ast_node *array_size,
            } 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());
            }
         }
       }
@@ -1940,7 +2008,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
         break;
 
       case fragment_shader:
-        if (!global_scope || (var->mode != ir_var_in)) {
+        if (!global_scope || (var->mode != ir_var_out)) {
            fail = true;
            string = "output";
         }
@@ -2052,10 +2120,6 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
        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;
-   }
 }
 
 /**
@@ -2103,18 +2167,9 @@ get_variable_being_redeclared(ir_variable *var, ast_declaration *decl,
        * 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)) {
+      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);
@@ -2389,12 +2444,12 @@ ast_declarator_list::hir(exec_list *instructions,
 
    decl_type = this->type->specifier->glsl_type(& type_name, state);
    if (this->declarations.is_empty()) {
-      /* The only valid case where the declaration list can be empty is when
-       * the declaration is setting the default precision of a built-in type
-       * (e.g., 'precision highp vec4;').
-       */
-
       if (decl_type != NULL) {
+        /* Warn if this empty declaration is not for declaring a structure.
+         */
+        if (this->type->specifier->structure == NULL) {
+           _mesa_glsl_warning(&loc, state, "empty declaration");
+        }
       } else {
            _mesa_glsl_error(& loc, state, "incomplete declaration");
       }
@@ -2676,17 +2731,35 @@ ast_declarator_list::hir(exec_list *instructions,
        *    preceded by one of these precision qualifiers [...] Literal
        *    constants do not have precision qualifiers. Neither do Boolean
        *    variables.
+       *
+       * In GLSL ES, sampler types are also allowed.
+       *
+       * From page 87 of the GLSL ES spec:
+       *    "RESOLUTION: Allow sampler types to take a precision qualifier."
        */
       if (this->type->specifier->precision != ast_precision_none
           && !var->type->is_float()
           && !var->type->is_integer()
+          && !(var->type->is_sampler() && state->es_shader)
           && !(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");
+                          "precision qualifiers apply only to floating point"
+                          "%s types", state->es_shader ? ", integer, and sampler"
+                                                      : "and integer");
+      }
+
+      /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
+       *
+       *    "[Sampler types] can only be declared as function
+       *    parameters or uniform variables (see Section 4.3.5
+       *    "Uniform")".
+       */
+      if (var_type->contains_sampler() &&
+          !this->type->qualifier.flags.q.uniform) {
+         _mesa_glsl_error(&loc, state, "samplers must be declared uniform");
       }
 
       /* Process the initializer and add its instructions to a temporary
@@ -2849,6 +2922,38 @@ ast_parameter_declarator::hir(exec_list *instructions,
     */
    apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc);
 
+   /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
+    *
+    *    "Samplers 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_inout || var->mode == ir_var_out)
+       && type->contains_sampler()) {
+      _mesa_glsl_error(&loc, state, "out and inout parameters cannot contain samplers");
+      type = glsl_type::error_type;
+   }
+
+   /* From page 39 (page 45 of the PDF) of the GLSL 1.10 spec:
+    *
+    *    "When calling a function, expressions that do not evaluate to
+    *     l-values cannot be passed to parameters declared as out or inout."
+    *
+    * 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."
+    *
+    * 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_inout || var->mode == ir_var_out)
+       && type->is_array() && state->language_version == 110) {
+      _mesa_glsl_error(&loc, state, "Arrays cannot be out or inout parameters in GLSL 1.10");
+      type = glsl_type::error_type;
+   }
+
    instructions->push_tail(var);
 
    /* Parameter declarations do not have r-values.
@@ -2886,23 +2991,16 @@ 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_function(_mesa_glsl_parse_state *state, 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 invariants disallow function declarations or definitions
+    * nested within other function definitions.  But there is no
+    * requirement about the relative order of function declarations
+    * and definitions with respect to one another.  So simply insert
+    * the new ir_function block at the end of the toplevel instruction
+    * list.
+    */
+   state->toplevel_ir->push_tail(f);
 }
 
 
@@ -2917,6 +3015,12 @@ ast_function::hir(exec_list *instructions,
 
    const char *const name = identifier;
 
+   /* New functions are always added to the top-level IR instruction stream,
+    * so this instruction list pointer is ignored.  See also emit_function
+    * (called below).
+    */
+   (void) instructions;
+
    /* From page 21 (page 27 of the PDF) of the GLSL 1.20 spec,
     *
     *   "Function declarations (prototypes) cannot occur inside of functions;
@@ -2977,6 +3081,18 @@ ast_function::hir(exec_list *instructions,
                       "function `%s' return type has qualifiers", name);
    }
 
+   /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
+    *
+    *    "[Sampler types] can only be declared as function parameters
+    *    or uniform variables (see Section 4.3.5 "Uniform")".
+    */
+   if (return_type->contains_sampler()) {
+      YYLTYPE loc = this->get_location();
+      _mesa_glsl_error(&loc, state,
+                       "function `%s' return type can't contain a sampler",
+                       name);
+   }
+
    /* 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.
@@ -3017,7 +3133,7 @@ ast_function::hir(exec_list *instructions,
         return NULL;
       }
 
-      emit_function(state, instructions, f);
+      emit_function(state, f);
    }
 
    /* Verify the return type of main() */