/*
 * Copyright © 2010 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

/**
 * \file ast_to_hir.c
 * Convert abstract syntax to to high-level intermediate reprensentation (HIR).
 *
 * During the conversion to HIR, the majority of the symantic checking is
 * preformed on the program.  This includes:
 *
 *    * Symbol table management
 *    * Type checking
 *    * Function binding
 *
 * The majority of this work could be done during parsing, and the parser could
 * probably generate HIR directly.  However, this results in frequent changes
 * to the parser code.  Since we do not assume that every system this complier
 * is built on will have Flex and Bison installed, we have to store the code
 * generated by these tools in our version control system.  In other parts of
 * the system we've seen problems where a parser was changed but the generated
 * code was not committed, merge conflicts where created because two developers
 * had slightly different versions of Bison installed, etc.
 *
 * I have also noticed that running Bison generated parsers in GDB is very
 * irritating.  When you get a segfault on '$$ = $1->foo', you can't very
 * well 'print $1' in GDB.
 *
 * As a result, my preference is to put as little C code as possible in the
 * parser (and lexer) sources.
 */

#include "main/core.h" /* for struct gl_extensions */
#include "glsl_symbol_table.h"
#include "glsl_parser_extras.h"
#include "ast.h"
#include "glsl_types.h"
#include "ir.h"

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);

   state->symbols->language_version = state->language_version;

   state->current_function = NULL;

   /* 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,
    *  available for user-defined functions and global variables, is nested
    *  inside the scope containing the built-in functions."
    *
    * Since built-in functions like ftransform() access built-in variables,
    * it follows that those must be in the outer scope as well.
    *
    * We push scope here to create this nesting effect...but don't pop.
    * This way, a shader's globals are still in the symbol table for use
    * by the linker.
    */
   state->symbols->push_scope();

   foreach_list_typed (ast_node, ast, link, & state->translation_unit)
      ast->hir(instructions, state);
}


/**
 * If a conversion is available, convert one operand to a different type
 *
 * The \c from \c ir_rvalue is converted "in place".
 *
 * \param to     Type that the operand it to be converted to
 * \param from   Operand that is being converted
 * \param state  GLSL compiler state
 *
 * \return
 * If a conversion is possible (or unnecessary), \c true is returned.
 * Otherwise \c false is returned.
 */
bool
apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from,
			  struct _mesa_glsl_parse_state *state)
{
   void *ctx = state;
   if (to->base_type == from->type->base_type)
      return true;

   /* This conversion was added in GLSL 1.20.  If the compilation mode is
    * GLSL 1.10, the conversion is skipped.
    */
   if (state->language_version < 120)
      return false;

   /* From page 27 (page 33 of the PDF) of the GLSL 1.50 spec:
    *
    *    "There are no implicit array or structure conversions. For
    *    example, an array of int cannot be implicitly converted to an
    *    array of float. There are no implicit conversions between
    *    signed and unsigned integers."
    */
   /* FINISHME: The above comment is partially a lie.  There is int/uint
    * FINISHME: conversion for immediate constants.
    */
   if (!to->is_float() || !from->type->is_numeric())
      return false;

   /* Convert to a floating point type with the same number of components
    * as the original type - i.e. int to float, not int to vec4.
    */
   to = glsl_type::get_instance(GLSL_TYPE_FLOAT, from->type->vector_elements,
			        from->type->matrix_columns);

   switch (from->type->base_type) {
   case GLSL_TYPE_INT:
      from = new(ctx) ir_expression(ir_unop_i2f, to, from, NULL);
      break;
   case GLSL_TYPE_UINT:
      from = new(ctx) ir_expression(ir_unop_u2f, to, from, NULL);
      break;
   case GLSL_TYPE_BOOL:
      from = new(ctx) ir_expression(ir_unop_b2f, to, from, NULL);
      break;
   default:
      assert(0);
   }

   return true;
}


static const struct glsl_type *
arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
		       bool multiply,
		       struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
{
   const glsl_type *type_a = value_a->type;
   const glsl_type *type_b = value_b->type;

   /* From GLSL 1.50 spec, page 56:
    *
    *    "The arithmetic binary operators add (+), subtract (-),
    *    multiply (*), and divide (/) operate on integer and
    *    floating-point scalars, vectors, and matrices."
    */
   if (!type_a->is_numeric() || !type_b->is_numeric()) {
      _mesa_glsl_error(loc, state,
		       "Operands to arithmetic operators must be numeric");
      return glsl_type::error_type;
   }


   /*    "If one operand is floating-point based and the other is
    *    not, then the conversions from Section 4.1.10 "Implicit
    *    Conversions" are applied to the non-floating-point-based operand."
    */
   if (!apply_implicit_conversion(type_a, value_b, state)
       && !apply_implicit_conversion(type_b, value_a, state)) {
      _mesa_glsl_error(loc, state,
		       "Could not implicitly convert operands to "
		       "arithmetic operator");
      return glsl_type::error_type;
   }
   type_a = value_a->type;
   type_b = value_b->type;

   /*    "If the operands are integer types, they must both be signed or
    *    both be unsigned."
    *
    * From this rule and the preceeding conversion it can be inferred that
    * both types must be GLSL_TYPE_FLOAT, or GLSL_TYPE_UINT, or GLSL_TYPE_INT.
    * The is_numeric check above already filtered out the case where either
    * type is not one of these, so now the base types need only be tested for
    * equality.
    */
   if (type_a->base_type != type_b->base_type) {
      _mesa_glsl_error(loc, state,
		       "base type mismatch for arithmetic operator");
      return glsl_type::error_type;
   }

   /*    "All arithmetic binary operators result in the same fundamental type
    *    (signed integer, unsigned integer, or floating-point) as the
    *    operands they operate on, after operand type conversion. After
    *    conversion, the following cases are valid
    *
    *    * The two operands are scalars. In this case the operation is
    *      applied, resulting in a scalar."
    */
   if (type_a->is_scalar() && type_b->is_scalar())
      return type_a;

   /*   "* One operand is a scalar, and the other is a vector or matrix.
    *      In this case, the scalar operation is applied independently to each
    *      component of the vector or matrix, resulting in the same size
    *      vector or matrix."
    */
   if (type_a->is_scalar()) {
      if (!type_b->is_scalar())
	 return type_b;
   } else if (type_b->is_scalar()) {
      return type_a;
   }

   /* All of the combinations of <scalar, scalar>, <vector, scalar>,
    * <scalar, vector>, <scalar, matrix>, and <matrix, scalar> have been
    * handled.
    */
   assert(!type_a->is_scalar());
   assert(!type_b->is_scalar());

   /*   "* The two operands are vectors of the same size. In this case, the
    *      operation is done component-wise resulting in the same size
    *      vector."
    */
   if (type_a->is_vector() && type_b->is_vector()) {
      if (type_a == type_b) {
	 return type_a;
      } else {
	 _mesa_glsl_error(loc, state,
			  "vector size mismatch for arithmetic operator");
	 return glsl_type::error_type;
      }
   }

   /* All of the combinations of <scalar, scalar>, <vector, scalar>,
    * <scalar, vector>, <scalar, matrix>, <matrix, scalar>, and
    * <vector, vector> have been handled.  At least one of the operands must
    * be matrix.  Further, since there are no integer matrix types, the base
    * type of both operands must be float.
    */
   assert(type_a->is_matrix() || type_b->is_matrix());
   assert(type_a->base_type == GLSL_TYPE_FLOAT);
   assert(type_b->base_type == GLSL_TYPE_FLOAT);

   /*   "* The operator is add (+), subtract (-), or divide (/), and the
    *      operands are matrices with the same number of rows and the same
    *      number of columns. In this case, the operation is done component-
    *      wise resulting in the same size matrix."
    *    * The operator is multiply (*), where both operands are matrices or
    *      one operand is a vector and the other a matrix. A right vector
    *      operand is treated as a column vector and a left vector operand as a
    *      row vector. In all these cases, it is required that the number of
    *      columns of the left operand is equal to the number of rows of the
    *      right operand. Then, the multiply (*) operation does a linear
    *      algebraic multiply, yielding an object that has the same number of
    *      rows as the left operand and the same number of columns as the right
    *      operand. Section 5.10 "Vector and Matrix Operations" explains in
    *      more detail how vectors and matrices are operated on."
    */
   if (! multiply) {
      if (type_a == type_b)
	 return type_a;
   } else {
      if (type_a->is_matrix() && type_b->is_matrix()) {
	 /* Matrix multiply.  The columns of A must match the rows of B.  Given
	  * the other previously tested constraints, this means the vector type
	  * of a row from A must be the same as the vector type of a column from
	  * B.
	  */
	 if (type_a->row_type() == type_b->column_type()) {
	    /* The resulting matrix has the number of columns of matrix B and
	     * the number of rows of matrix A.  We get the row count of A by
	     * looking at the size of a vector that makes up a column.  The
	     * transpose (size of a row) is done for B.
	     */
	    const glsl_type *const type =
	       glsl_type::get_instance(type_a->base_type,
				       type_a->column_type()->vector_elements,
				       type_b->row_type()->vector_elements);
	    assert(type != glsl_type::error_type);

	    return type;
	 }
      } else if (type_a->is_matrix()) {
	 /* A is a matrix and B is a column vector.  Columns of A must match
	  * rows of B.  Given the other previously tested constraints, this
	  * means the vector type of a row from A must be the same as the
	  * vector the type of B.
	  */
	 if (type_a->row_type() == type_b) {
	    /* The resulting vector has a number of elements equal to
	     * the number of rows of matrix A. */
	    const glsl_type *const type =
	       glsl_type::get_instance(type_a->base_type,
				       type_a->column_type()->vector_elements,
				       1);
	    assert(type != glsl_type::error_type);

	    return type;
	 }
      } else {
	 assert(type_b->is_matrix());

	 /* A is a row vector and B is a matrix.  Columns of A must match rows
	  * of B.  Given the other previously tested constraints, this means
	  * the type of A must be the same as the vector type of a column from
	  * B.
	  */
	 if (type_a == type_b->column_type()) {
	    /* The resulting vector has a number of elements equal to
	     * the number of columns of matrix B. */
	    const glsl_type *const type =
	       glsl_type::get_instance(type_a->base_type,
				       type_b->row_type()->vector_elements,
				       1);
	    assert(type != glsl_type::error_type);

	    return type;
	 }
      }

      _mesa_glsl_error(loc, state, "size mismatch for matrix multiplication");
      return glsl_type::error_type;
   }


   /*    "All other cases are illegal."
    */
   _mesa_glsl_error(loc, state, "type mismatch");
   return glsl_type::error_type;
}


static const struct glsl_type *
unary_arithmetic_result_type(const struct glsl_type *type,
			     struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
{
   /* From GLSL 1.50 spec, page 57:
    *
    *    "The arithmetic unary operators negate (-), post- and pre-increment
    *     and decrement (-- and ++) operate on integer or floating-point
    *     values (including vectors and matrices). All unary operators work
    *     component-wise on their operands. These result with the same type
    *     they operated on."
    */
   if (!type->is_numeric()) {
      _mesa_glsl_error(loc, state,
		       "Operands to arithmetic operators must be numeric");
      return glsl_type::error_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)
{
   /* 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
    *    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");
      return glsl_type::error_type;
   }

   /*    "The operands cannot be vectors of differing size. If one operand is
    *    a scalar and the other vector, then the scalar is applied component-
    *    wise to the vector, resulting in the same type as the vector. If both
    *    are vectors of the same size, the result is computed component-wise."
    */
   if (type_a->is_vector()) {
      if (!type_b->is_vector()
	  || (type_a->vector_elements == type_b->vector_elements))
	 return type_a;
   } else
      return type_b;

   /*    "The operator modulus (%) is not defined for any other data types
    *    (non-integer types)."
    */
   _mesa_glsl_error(loc, state, "type mismatch");
   return glsl_type::error_type;
}


static const struct glsl_type *
relational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
		       struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
{
   const glsl_type *type_a = value_a->type;
   const glsl_type *type_b = value_b->type;

   /* From GLSL 1.50 spec, page 56:
    *    "The relational operators greater than (>), less than (<), greater
    *    than or equal (>=), and less than or equal (<=) operate only on
    *    scalar integer and scalar floating-point expressions."
    */
   if (!type_a->is_numeric()
       || !type_b->is_numeric()
       || !type_a->is_scalar()
       || !type_b->is_scalar()) {
      _mesa_glsl_error(loc, state,
		       "Operands to relational operators must be scalar and "
		       "numeric");
      return glsl_type::error_type;
   }

   /*    "Either the operands' types must match, or the conversions from
    *    Section 4.1.10 "Implicit Conversions" will be applied to the integer
    *    operand, after which the types must match."
    */
   if (!apply_implicit_conversion(type_a, value_b, state)
       && !apply_implicit_conversion(type_b, value_a, state)) {
      _mesa_glsl_error(loc, state,
		       "Could not implicitly convert operands to "
		       "relational operator");
      return glsl_type::error_type;
   }
   type_a = value_a->type;
   type_b = value_b->type;

   if (type_a->base_type != type_b->base_type) {
      _mesa_glsl_error(loc, state, "base type mismatch");
      return glsl_type::error_type;
   }

   /*    "The result is scalar Boolean."
    */
   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
 *
 * Validates that \c rhs can be assigned to some location.  If the types are
 * not an exact match but an automatic conversion is possible, \c rhs will be
 * converted.
 *
 * \return
 * \c NULL if \c rhs cannot be assigned to a location with type \c lhs_type.
 * Otherwise the actual RHS to be assigned will be returned.  This may be
 * \c rhs, or it may be \c rhs after some type conversion.
 *
 * \note
 * In addition to being used for assignments, this function is used to
 * type-check return values.
 */
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())
      return rhs;

   /* If the types are identical, the assignment can trivially proceed.
    */
   if (rhs_type == lhs_type)
      return rhs;

   /* If the array element types are the same and the size of the LHS is zero,
    * the assignment is okay.
    *
    * Note: Whole-array assignments are not permitted in GLSL 1.10, but this
    * is handled by ir_dereference::is_lvalue.
    */
   if (lhs_type->is_array() && rhs->type->is_array()
       && (lhs_type->element_type() == rhs->type->element_type())
       && (lhs_type->array_size() == 0)) {
      return rhs;
   }

   /* 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)
	 return rhs;
   }

   return NULL;
}

ir_rvalue *
do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
	      ir_rvalue *lhs, ir_rvalue *rhs,
	      YYLTYPE lhs_loc)
{
   void *ctx = state;
   bool error_emitted = (lhs->type->is_error() || rhs->type->is_error());

   if (!error_emitted) {
      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);
   if (new_rhs == NULL) {
      _mesa_glsl_error(& lhs_loc, state, "type mismatch");
   } else {
      rhs = new_rhs;

      /* If the LHS array was not declared with a size, it takes it size from
       * the RHS.  If the LHS is an l-value and a whole array, it must be a
       * dereference of a variable.  Any other case would require that the LHS
       * is either not an l-value or not a whole array.
       */
      if (lhs->type->array_size() == 0) {
	 ir_dereference *const d = lhs->as_dereference();

	 assert(d != NULL);

	 ir_variable *const var = d->variable_referenced();

	 assert(var != NULL);

	 if (var->max_array_access >= unsigned(rhs->type->array_size())) {
	    /* FINISHME: This should actually log the location of the RHS. */
	    _mesa_glsl_error(& lhs_loc, state, "array size must be > %u due to "
			     "previous access",
			     var->max_array_access);
	 }

	 var->type = glsl_type::get_array_instance(lhs->type->element_type(),
						   rhs->type->array_size());
	 d->type = var->type;
      }
   }

   /* Most callers of do_assignment (assign, add_assign, pre_inc/dec,
    * but not post_inc) need the converted assigned value as an rvalue
    * to handle things like:
    *
    * i = j += 1;
    *
    * So we always just store the computed value being assigned to a
    * temporary and return a deref of that temporary.  If the rvalue
    * ends up not being used, the temp will get copy-propagated out.
    */
   ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp",
					   ir_var_temporary);
   ir_dereference_variable *deref_var = new(ctx) ir_dereference_variable(var);
   instructions->push_tail(var);
   instructions->push_tail(new(ctx) ir_assignment(deref_var,
						  rhs,
						  NULL));
   deref_var = new(ctx) ir_dereference_variable(var);

   if (!error_emitted)
      instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var, NULL));

   return new(ctx) ir_dereference_variable(var);
}

static ir_rvalue *
get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue)
{
   void *ctx = hieralloc_parent(lvalue);
   ir_variable *var;

   var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp",
			      ir_var_temporary);
   instructions->push_tail(var);
   var->mode = ir_var_auto;

   instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
						  lvalue, NULL));

   /* Once we've created this temporary, mark it read only so it's no
    * longer considered an lvalue.
    */
   var->read_only = true;

   return new(ctx) ir_dereference_variable(var);
}


ir_rvalue *
ast_node::hir(exec_list *instructions,
	      struct _mesa_glsl_parse_state *state)
{
   (void) instructions;
   (void) state;

   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,
		    struct _mesa_glsl_parse_state *state)
{
   void *ctx = state;
   static const int operations[AST_NUM_OPERATORS] = {
      -1,               /* ast_assign doesn't convert to ir_expression. */
      -1,               /* ast_plus doesn't convert to ir_expression. */
      ir_unop_neg,
      ir_binop_add,
      ir_binop_sub,
      ir_binop_mul,
      ir_binop_div,
      ir_binop_mod,
      ir_binop_lshift,
      ir_binop_rshift,
      ir_binop_less,
      ir_binop_greater,
      ir_binop_lequal,
      ir_binop_gequal,
      ir_binop_all_equal,
      ir_binop_any_nequal,
      ir_binop_bit_and,
      ir_binop_bit_xor,
      ir_binop_bit_or,
      ir_unop_bit_not,
      ir_binop_logic_and,
      ir_binop_logic_xor,
      ir_binop_logic_or,
      ir_unop_logic_not,

      /* Note: The following block of expression types actually convert
       * to multiple IR instructions.
       */
      ir_binop_mul,     /* ast_mul_assign */
      ir_binop_div,     /* ast_div_assign */
      ir_binop_mod,     /* ast_mod_assign */
      ir_binop_add,     /* ast_add_assign */
      ir_binop_sub,     /* ast_sub_assign */
      ir_binop_lshift,  /* ast_ls_assign */
      ir_binop_rshift,  /* ast_rs_assign */
      ir_binop_bit_and, /* ast_and_assign */
      ir_binop_bit_xor, /* ast_xor_assign */
      ir_binop_bit_or,  /* ast_or_assign */

      -1,               /* ast_conditional doesn't convert to ir_expression. */
      ir_binop_add,     /* ast_pre_inc. */
      ir_binop_sub,     /* ast_pre_dec. */
      ir_binop_add,     /* ast_post_inc. */
      ir_binop_sub,     /* ast_post_dec. */
      -1,               /* ast_field_selection doesn't conv to ir_expression. */
      -1,               /* ast_array_index doesn't convert to ir_expression. */
      -1,               /* ast_function_call doesn't conv to ir_expression. */
      -1,               /* ast_identifier doesn't convert to ir_expression. */
      -1,               /* ast_int_constant doesn't convert to ir_expression. */
      -1,               /* ast_uint_constant doesn't conv to ir_expression. */
      -1,               /* ast_float_constant doesn't conv to ir_expression. */
      -1,               /* ast_bool_constant doesn't conv to ir_expression. */
      -1,               /* ast_sequence doesn't convert to ir_expression. */
   };
   ir_rvalue *result = NULL;
   ir_rvalue *op[3];
   const struct glsl_type *type = glsl_type::error_type;
   bool error_emitted = false;
   YYLTYPE loc;

   loc = this->get_location();

   switch (this->oper) {
   case ast_assign: {
      op[0] = this->subexpressions[0]->hir(instructions, state);
      op[1] = this->subexpressions[1]->hir(instructions, state);

      result = do_assignment(instructions, state, op[0], op[1],
			     this->subexpressions[0]->get_location());
      error_emitted = result->type->is_error();
      type = result->type;
      break;
   }

   case ast_plus:
      op[0] = this->subexpressions[0]->hir(instructions, state);

      type = unary_arithmetic_result_type(op[0]->type, state, & loc);

      error_emitted = type->is_error();

      result = op[0];
      break;

   case ast_neg:
      op[0] = this->subexpressions[0]->hir(instructions, state);

      type = unary_arithmetic_result_type(op[0]->type, state, & loc);

      error_emitted = type->is_error();

      result = new(ctx) ir_expression(operations[this->oper], type,
				      op[0], NULL);
      break;

   case ast_add:
   case ast_sub:
   case ast_mul:
   case ast_div:
      op[0] = this->subexpressions[0]->hir(instructions, state);
      op[1] = this->subexpressions[1]->hir(instructions, state);

      type = arithmetic_result_type(op[0], op[1],
				    (this->oper == ast_mul),
				    state, & loc);
      error_emitted = type->is_error();

      result = new(ctx) ir_expression(operations[this->oper], type,
				      op[0], op[1]);
      break;

   case ast_mod:
      op[0] = this->subexpressions[0]->hir(instructions, state);
      op[1] = this->subexpressions[1]->hir(instructions, state);

      type = modulus_result_type(op[0]->type, op[1]->type, state, & loc);

      assert(operations[this->oper] == ir_binop_mod);

      result = new(ctx) ir_expression(operations[this->oper], type,
				      op[0], op[1]);
      error_emitted = type->is_error();
      break;

   case ast_lshift:
   case ast_rshift:
       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:
   case ast_lequal:
   case ast_gequal:
      op[0] = this->subexpressions[0]->hir(instructions, state);
      op[1] = this->subexpressions[1]->hir(instructions, state);

      type = relational_result_type(op[0], op[1], state, & loc);

      /* The relational operators must either generate an error or result
       * in a scalar boolean.  See page 57 of the GLSL 1.50 spec.
       */
      assert(type->is_error()
	     || ((type->base_type == GLSL_TYPE_BOOL)
		 && type->is_scalar()));

      result = new(ctx) ir_expression(operations[this->oper], type,
				      op[0], op[1]);
      error_emitted = type->is_error();
      break;

   case ast_nequal:
   case ast_equal:
      op[0] = this->subexpressions[0]->hir(instructions, state);
      op[1] = this->subexpressions[1]->hir(instructions, state);

      /* From page 58 (page 64 of the PDF) of the GLSL 1.50 spec:
       *
       *    "The equality operators equal (==), and not equal (!=)
       *    operate on all types. They result in a scalar Boolean. If
       *    the operand types do not match, then there must be a
       *    conversion from Section 4.1.10 "Implicit Conversions"
       *    applied to one operand that can make them match, in which
       *    case this conversion is done."
       */
      if ((!apply_implicit_conversion(op[0]->type, op[1], state)
	   && !apply_implicit_conversion(op[1]->type, op[0], state))
	  || (op[0]->type != op[1]->type)) {
	 _mesa_glsl_error(& loc, state, "operands of `%s' must have the same "
			  "type", (this->oper == ast_equal) ? "==" : "!=");
	 error_emitted = true;
      } else if ((state->language_version <= 110)
		 && (op[0]->type->is_array() || op[1]->type->is_array())) {
	 _mesa_glsl_error(& loc, state, "array comparisons forbidden in "
			  "GLSL 1.10");
	 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));
      break;

   case ast_bit_and:
   case ast_bit_xor:
   case ast_bit_or:
      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);
      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_bit_not:
      op[0] = this->subexpressions[0]->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, "operand of `~' must be an integer");
	 error_emitted = true;
      }

      type = op[0]->type;
      result = new(ctx) ir_expression(ir_unop_bit_not, type, op[0], NULL);
      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;
      }

      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;
	    }
	    result = op[1];
	 } else {
	    result = op0_const;
	 }
	 type = glsl_type::bool_type;
      } else {
	 ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
						       "and_tmp",
						       ir_var_temporary);
	 instructions->push_tail(tmp);

	 ir_if *const stmt = new(ctx) ir_if(op[0]);
	 instructions->push_tail(stmt);

	 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;
	 }

	 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);
	 stmt->then_instructions.push_tail(then_assign);

	 ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
	 ir_assignment *const else_assign =
	    new(ctx) ir_assignment(else_deref, new(ctx) ir_constant(false), NULL);
	 stmt->else_instructions.push_tail(else_assign);

	 result = new(ctx) ir_dereference_variable(tmp);
	 type = tmp->type;
      }
      break;
   }

   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;
      }

      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;
      } else {
	 ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
						       "or_tmp",
						       ir_var_temporary);
	 instructions->push_tail(tmp);

	 ir_if *const stmt = new(ctx) ir_if(op[0]);
	 instructions->push_tail(stmt);

	 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);

	 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);
	 stmt->else_instructions.push_tail(else_assign);

	 result = new(ctx) ir_dereference_variable(tmp);
	 type = tmp->type;
      }
      break;
   }

   case ast_logic_xor:
      op[0] = this->subexpressions[0]->hir(instructions, state);
      op[1] = this->subexpressions[1]->hir(instructions, state);


      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;
      }

      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:
   case ast_div_assign:
   case ast_add_assign:
   case ast_sub_assign: {
      op[0] = this->subexpressions[0]->hir(instructions, state);
      op[1] = this->subexpressions[1]->hir(instructions, state);

      type = arithmetic_result_type(op[0], op[1],
				    (this->oper == ast_mul_assign),
				    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());
      type = result->type;
      error_emitted = (op[0]->type->is_error());

      /* GLSL 1.10 does not allow array assignment.  However, we don't have to
       * explicitly test for this because none of the binary expression
       * operators allow array operands either.
       */

      break;
   }

   case ast_mod_assign: {
      op[0] = this->subexpressions[0]->hir(instructions, state);
      op[1] = this->subexpressions[1]->hir(instructions, state);

      type = modulus_result_type(op[0]->type, op[1]->type, state, & loc);

      assert(operations[this->oper] == ir_binop_mod);

      ir_rvalue *temp_rhs;
      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());
      type = result->type;
      error_emitted = type->is_error();
      break;
   }

   case ast_ls_assign:
   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: {
      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);

      /* 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;
      }

      /* The :? operator is implemented by generating an anonymous temporary
       * followed by an if-statement.  The last instruction in each branch of
       * the if-statement assigns a value to the anonymous temporary.  This
       * temporary is the r-value of the expression.
       */
      exec_list then_instructions;
      exec_list else_instructions;

      op[1] = this->subexpressions[1]->hir(&then_instructions, state);
      op[2] = this->subexpressions[2]->hir(&else_instructions, state);

      /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec:
       *
       *     "The second and third expressions can be any type, as
       *     long their types match, or there is a conversion in
       *     Section 4.1.10 "Implicit Conversions" that can be applied
       *     to one of the expressions to make their types match. This
       *     resulting matching type is the type of the entire
       *     expression."
       */
      if ((!apply_implicit_conversion(op[1]->type, op[2], state)
	   && !apply_implicit_conversion(op[2]->type, op[1], state))
	  || (op[1]->type != op[2]->type)) {
	 YYLTYPE loc = this->subexpressions[1]->get_location();

	 _mesa_glsl_error(& loc, state, "Second and third operands of ?: "
			  "operator must have matching types.");
	 error_emitted = true;
	 type = glsl_type::error_type;
      } else {
	 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();

      if (then_instructions.is_empty()
	  && else_instructions.is_empty()
	  && (cond_val != NULL) && (then_val != NULL) && (else_val != NULL)) {
	 result = (cond_val->value.b[0]) ? then_val : else_val;
      } else {
	 ir_variable *const tmp =
	    new(ctx) ir_variable(type, "conditional_tmp", ir_var_temporary);
	 instructions->push_tail(tmp);

	 ir_if *const stmt = new(ctx) ir_if(op[0]);
	 instructions->push_tail(stmt);

	 then_instructions.move_nodes_to(& stmt->then_instructions);
	 ir_dereference *const then_deref =
	    new(ctx) ir_dereference_variable(tmp);
	 ir_assignment *const then_assign =
	    new(ctx) ir_assignment(then_deref, op[1], NULL);
	 stmt->then_instructions.push_tail(then_assign);

	 else_instructions.move_nodes_to(& stmt->else_instructions);
	 ir_dereference *const else_deref =
	    new(ctx) ir_dereference_variable(tmp);
	 ir_assignment *const else_assign =
	    new(ctx) ir_assignment(else_deref, op[2], NULL);
	 stmt->else_instructions.push_tail(else_assign);

	 result = new(ctx) ir_dereference_variable(tmp);
      }
      break;
   }

   case ast_pre_inc:
   case ast_pre_dec: {
      op[0] = this->subexpressions[0]->hir(instructions, state);
      if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
	 op[1] = new(ctx) ir_constant(1.0f);
      else
	 op[1] = new(ctx) ir_constant(1);

      type = arithmetic_result_type(op[0], op[1], false, state, & loc);

      ir_rvalue *temp_rhs;
      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());
      type = result->type;
      error_emitted = op[0]->type->is_error();
      break;
   }

   case ast_post_inc:
   case ast_post_dec: {
      op[0] = this->subexpressions[0]->hir(instructions, state);
      if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
	 op[1] = new(ctx) ir_constant(1.0f);
      else
	 op[1] = new(ctx) ir_constant(1);

      error_emitted = op[0]->type->is_error() || op[1]->type->is_error();

      type = arithmetic_result_type(op[0], op[1], false, state, & loc);

      ir_rvalue *temp_rhs;
      temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
					op[0], op[1]);

      /* Get a temporary of a copy of the lvalue before it's modified.
       * This may get thrown away later.
       */
      result = get_lvalue_copy(instructions, op[0]->clone(ctx, NULL));

      (void)do_assignment(instructions, state,
			  op[0]->clone(ctx, NULL), temp_rhs,
			  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: {
      YYLTYPE index_loc = subexpressions[1]->get_location();

      op[0] = subexpressions[0]->hir(instructions, state);
      op[1] = subexpressions[1]->hir(instructions, state);

      error_emitted = op[0]->type->is_error() || op[1]->type->is_error();

      ir_rvalue *const array = op[0];

      result = new(ctx) ir_dereference_array(op[0], op[1]);

      /* Do not use op[0] after this point.  Use array.
       */
      op[0] = NULL;


      if (error_emitted)
	 break;

      if (!array->type->is_array()
	  && !array->type->is_matrix()
	  && !array->type->is_vector()) {
	 _mesa_glsl_error(& index_loc, state,
			  "cannot dereference non-array / non-matrix / "
			  "non-vector");
	 error_emitted = true;
      }

      if (!op[1]->type->is_integer()) {
	 _mesa_glsl_error(& index_loc, state,
			  "array index must be integer type");
	 error_emitted = true;
      } else if (!op[1]->type->is_scalar()) {
	 _mesa_glsl_error(& index_loc, state,
			  "array index must be scalar");
	 error_emitted = true;
      }

      /* If the array index is a constant expression and the array has a
       * declared size, ensure that the access is in-bounds.  If the array
       * index is not a constant expression, ensure that the array has a
       * declared size.
       */
      ir_constant *const const_index = op[1]->constant_expression_value();
      if (const_index != NULL) {
	 const int idx = const_index->value.i[0];
	 const char *type_name;
	 unsigned bound = 0;

	 if (array->type->is_matrix()) {
	    type_name = "matrix";
	 } else if (array->type->is_vector()) {
	    type_name = "vector";
	 } else {
	    type_name = "array";
	 }

	 /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec:
	  *
	  *    "It is illegal to declare an array with a size, and then
	  *    later (in the same shader) index the same array with an
	  *    integral constant expression greater than or equal to the
	  *    declared size. It is also illegal to index an array with a
	  *    negative constant expression."
	  */
	 if (array->type->is_matrix()) {
	    if (array->type->row_type()->vector_elements <= idx) {
	       bound = array->type->row_type()->vector_elements;
	    }
	 } else if (array->type->is_vector()) {
	    if (array->type->vector_elements <= idx) {
	       bound = array->type->vector_elements;
	    }
	 } else {
	    if ((array->type->array_size() > 0)
		&& (array->type->array_size() <= idx)) {
	       bound = array->type->array_size();
	    }
	 }

	 if (bound > 0) {
	    _mesa_glsl_error(& loc, state, "%s index must be < %u",
			     type_name, bound);
	    error_emitted = true;
	 } else if (idx < 0) {
	    _mesa_glsl_error(& loc, state, "%s index must be >= 0",
			     type_name);
	    error_emitted = true;
	 }

	 if (array->type->is_array()) {
	    /* If the array is a variable dereference, it dereferences the
	     * whole array, by definition.  Use this to get the variable.
	     *
	     * FINISHME: Should some methods for getting / setting / testing
	     * 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))
	       v->max_array_access = idx;
	 }
      } else if (array->type->array_size() == 0) {
	 _mesa_glsl_error(&loc, state, "unsized array index must be constant");
      } else {
	 if (array->type->is_array()) {
	    /* whole_variable_referenced can return NULL if the array is a
	     * member of a structure.  In this case it is safe to not update
	     * the max_array_access field because it is never used for fields
	     * of structures.
	     */
	    ir_variable *v = array->whole_variable_referenced();
	    if (v != NULL)
	       v->max_array_access = array->type->array_size();
          // TODO: should this be array->type->array_size() - 1
	 }
      }

      /* 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;

      type = result->type;
      break;
   }

   case ast_function_call:
      /* Should *NEVER* get here.  ast_function_call should always be handled
       * by ast_function_expression::hir.
       */
      assert(0);
      break;

   case ast_identifier: {
      /* ast_identifier can appear several places in a full abstract syntax
       * tree.  This particular use must be at location specified in the grammar
       * as 'variable_identifier'.
       */
      ir_variable *var = 
	 state->symbols->get_variable(this->primary_expression.identifier);

      result = new(ctx) ir_dereference_variable(var);

      if (var != NULL) {
	 type = result->type;
      } else {
	 _mesa_glsl_error(& loc, state, "`%s' undeclared",
			  this->primary_expression.identifier);

	 error_emitted = true;
      }
      break;
   }

   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;

   case ast_sequence: {
      /* It should not be possible to generate a sequence in the AST without
       * any expressions in it.
       */
      assert(!this->expressions.is_empty());

      /* The r-value of a sequence is the last expression in the sequence.  If
       * the other expressions in the sequence do not have side-effects (and
       * 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);

      type = result->type;

      /* Any errors should have already been emitted in the loop above.
       */
      error_emitted = true;
      break;
   }
   }

   if (type->is_error() && !error_emitted)
      _mesa_glsl_error(& loc, state, "type mismatch");

   return result;
}


ir_rvalue *
ast_expression_statement::hir(exec_list *instructions,
			      struct _mesa_glsl_parse_state *state)
{
   /* It is possible to have expression statements that don't have an
    * expression.  This is the solitary semicolon:
    *
    * for (i = 0; i < 5; i++)
    *     ;
    *
    * In this case the expression will be NULL.  Test for NULL and don't do
    * anything in that case.
    */
   if (expression != NULL)
      expression->hir(instructions, state);

   /* Statements do not have r-values.
    */
   return NULL;
}


ir_rvalue *
ast_compound_statement::hir(exec_list *instructions,
			    struct _mesa_glsl_parse_state *state)
{
   if (new_scope)
      state->symbols->push_scope();

   foreach_list_typed (ast_node, ast, link, &this->statements)
      ast->hir(instructions, state);

   if (new_scope)
      state->symbols->pop_scope();

   /* Compound statements do not have r-values.
    */
   return NULL;
}


static const glsl_type *
process_array_type(YYLTYPE *loc, const glsl_type *base, ast_node *array_size,
		   struct _mesa_glsl_parse_state *state)
{
   unsigned length = 0;

   /* FINISHME: Reject delcarations of multidimensional arrays. */

   if (array_size != NULL) {
      exec_list dummy_instructions;
      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");
	 } else if (!ir->type->is_scalar()) {
	    _mesa_glsl_error(& loc, state, "array size must be scalar type");
	 } else {
	    ir_constant *const size = ir->constant_expression_value();

	    if (size == NULL) {
	       _mesa_glsl_error(& loc, state, "array size must be a "
				"constant valued expression");
	    } else if (size->value.i[0] <= 0) {
	       _mesa_glsl_error(& loc, state, "array size must be > 0");
	    } else {
	       assert(size->type == ir->type);
	       length = size->value.u[0];
	    }
	 }
      }
   } 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);
}


const glsl_type *
ast_type_specifier::glsl_type(const char **name,
			      struct _mesa_glsl_parse_state *state) const
{
   const struct glsl_type *type;

   type = state->symbols->get_type(this->type_name);
   *name = this->type_name;

   if (this->is_array) {
      YYLTYPE loc = this->get_location();
      type = process_array_type(&loc, type, this->array_size, state);
   }

   return type;
}


static void
apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
				 ir_variable *var,
				 struct _mesa_glsl_parse_state *state,
				 YYLTYPE *loc)
{
   if (qual->flags.q.invariant)
      var->invariant = 1;

   /* FINISHME: Mark 'in' variables at global scope as read-only. */
   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->flags.q.centroid)
      var->centroid = 1;

   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 "
		       "%s shader",
		       _mesa_glsl_shader_target_name(state->target));
   }

   /* From page 25 (page 31 of the PDF) of the GLSL 1.10 spec:
    *
    *     "The varying qualifier can be used only with the data types
    *     float, vec2, vec3, vec4, mat2, mat3, and mat4, or arrays of
    *     these."
    */
   if (qual->flags.q.varying) {
      const glsl_type *non_array_type;

      if (var->type && var->type->is_array())
	 non_array_type = var->type->fields.array;
      else
	 non_array_type = var->type;

      if (non_array_type && non_array_type->base_type != GLSL_TYPE_FLOAT) {
	 var->type = glsl_type::error_type;
	 _mesa_glsl_error(loc, state,
			  "varying variables must be of base type float");
      }
   }

   /* If there is no qualifier that changes the mode of the variable, leave
    * the setting alone.
    */
   if (qual->flags.q.in && qual->flags.q.out)
      var->mode = ir_var_inout;
   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->flags.q.out
	    || (qual->flags.q.varying && (state->target == vertex_shader)))
      var->mode = ir_var_out;
   else if (qual->flags.q.uniform)
      var->mode = ir_var_uniform;

   if (qual->flags.q.flat)
      var->interpolation = ir_var_flat;
   else if (qual->flags.q.noperspective)
      var->interpolation = ir_var_noperspective;
   else
      var->interpolation = ir_var_smooth;

   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->flags.q.origin_upper_left)
	 ? "origin_upper_left" : "pixel_center_integer";

      _mesa_glsl_error(loc, state,
		       "layout qualifier `%s' can only be applied to "
		       "fragment shader input `gl_FragCoord'",
		       qual_string);
   }

   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;
	 }
      }
   }

   if (var->type->is_array() && state->language_version != 110) {
      var->array_lvalue = true;
   }
}


ir_rvalue *
ast_declarator_list::hir(exec_list *instructions,
			 struct _mesa_glsl_parse_state *state)
{
   void *ctx = state;
   const struct glsl_type *decl_type;
   const char *type_name = NULL;
   ir_rvalue *result = NULL;
   YYLTYPE loc = this->get_location();

   /* From page 46 (page 52 of the PDF) of the GLSL 1.50 spec:
    *
    *     "To ensure that a particular output variable is invariant, it is
    *     necessary to use the invariant qualifier. It can either be used to
    *     qualify a previously declared variable as being invariant
    *
    *         invariant gl_Position; // make existing gl_Position be invariant"
    *
    * In these cases the parser will set the 'invariant' flag in the declarator
    * list, and the type will be NULL.
    */
   if (this->invariant) {
      assert(this->type == NULL);

      if (state->current_function != NULL) {
	 _mesa_glsl_error(& loc, state,
			  "All uses of `invariant' keyword must be at global "
			  "scope\n");
      }

      foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
	 assert(!decl->is_array);
	 assert(decl->array_size == NULL);
	 assert(decl->initializer == NULL);

	 ir_variable *const earlier =
	    state->symbols->get_variable(decl->identifier);
	 if (earlier == NULL) {
	    _mesa_glsl_error(& loc, state,
			     "Undeclared variable `%s' cannot be marked "
			     "invariant\n", decl->identifier);
	 } else if ((state->target == vertex_shader)
	       && (earlier->mode != ir_var_out)) {
	    _mesa_glsl_error(& loc, state,
			     "`%s' cannot be marked invariant, vertex shader "
			     "outputs only\n", decl->identifier);
	 } else if ((state->target == fragment_shader)
	       && (earlier->mode != ir_var_in)) {
	    _mesa_glsl_error(& loc, state,
			     "`%s' cannot be marked invariant, fragment shader "
			     "inputs only\n", decl->identifier);
	 } else {
	    earlier->invariant = true;
	 }
      }

      /* Invariant redeclarations do not have r-values.
       */
      return NULL;
   }

   assert(this->type != NULL);
   assert(!this->invariant);

   /* The type specifier may contain a structure definition.  Process that
    * before any of the variable declarations.
    */
   (void) this->type->specifier->hir(instructions, state);

   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) {
      } else {
	    _mesa_glsl_error(& loc, state, "incomplete declaration");
      }
   }

   foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
      const struct glsl_type *var_type;
      ir_variable *var;

      /* FINISHME: Emit a warning if a variable declaration shadows a
       * FINISHME: declaration at a higher scope.
       */

      if ((decl_type == NULL) || decl_type->is_void()) {
	 if (type_name != NULL) {
	    _mesa_glsl_error(& loc, state,
			     "invalid type `%s' in declaration of `%s'",
			     type_name, decl->identifier);
	 } else {
	    _mesa_glsl_error(& loc, state,
			     "invalid type in declaration of `%s'",
			     decl->identifier);
	 }
	 continue;
      }

      if (decl->is_array) {
	 var_type = process_array_type(&loc, decl_type, decl->array_size,
				       state);
      } else {
	 var_type = decl_type;
      }

      var = new(ctx) ir_variable(var_type, decl->identifier, ir_var_auto);

      /* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification;
       *
       *     "Global variables can only use the qualifiers const,
       *     attribute, uni form, or varying. Only one may be
       *     specified.
       *
       *     Local variables can only use the qualifier const."
       *
       * This is relaxed in GLSL 1.30.
       */
      if (state->language_version < 120) {
	 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);
	 }
	 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);
	 }
	 /* FINISHME: Test for other invalid qualifiers. */
      }

      apply_type_qualifier_to_variable(& this->type->qualifier, var, state,
				       & loc);

      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
	     * a function signature outval
	     */
	    _mesa_glsl_error(& loc, state,
			     "`%s' cannot be marked invariant, vertex shader "
			     "outputs only\n", var->name);
	 } else if ((state->target == fragment_shader) &&
		    !(var->mode == ir_var_in || var->mode == ir_var_inout)) {
	    /* FINISHME: Note that this doesn't work for invariant on
	     * a function signature inval
	     */
	    _mesa_glsl_error(& loc, state,
			     "`%s' cannot be marked invariant, fragment shader "
			     "inputs only\n", var->name);
	 }
      }

      if (state->current_function != NULL) {
	 const char *mode = NULL;
	 const char *extra = "";

	 /* There is no need to check for 'inout' here because the parser will
	  * only allow that in function parameter lists.
	  */
	 if (this->type->qualifier.flags.q.attribute) {
	    mode = "attribute";
	 } else if (this->type->qualifier.flags.q.uniform) {
	    mode = "uniform";
	 } else if (this->type->qualifier.flags.q.varying) {
	    mode = "varying";
	 } else if (this->type->qualifier.flags.q.in) {
	    mode = "in";
	    extra = " or in function parameter list";
	 } else if (this->type->qualifier.flags.q.out) {
	    mode = "out";
	    extra = " or in function parameter list";
	 }

	 if (mode) {
	    _mesa_glsl_error(& loc, state,
			     "%s variable `%s' must be declared at "
			     "global scope%s",
			     mode, var->name, extra);
	 }
      } else if (var->mode == ir_var_in) {
	 if (state->target == vertex_shader) {
	    bool error_emitted = false;

	    /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
	     *
	     *    "Vertex shader inputs can only be float, floating-point
	     *    vectors, matrices, signed and unsigned integers and integer
	     *    vectors. Vertex shader inputs can also form arrays of these
	     *    types, but not structures."
	     *
	     * From page 31 (page 27 of the PDF) of the GLSL 1.30 spec:
	     *
	     *    "Vertex shader inputs can only be float, floating-point
	     *    vectors, matrices, signed and unsigned integers and integer
	     *    vectors. They cannot be arrays or structures."
	     *
	     * From page 23 (page 29 of the PDF) of the GLSL 1.20 spec:
	     *
	     *    "The attribute qualifier can be used only with float,
	     *    floating-point vectors, and matrices. Attribute variables
	     *    cannot be declared as arrays or structures."
	     */
	    const glsl_type *check_type = var->type->is_array()
	       ? var->type->fields.array : var->type;

	    switch (check_type->base_type) {
	    case GLSL_TYPE_FLOAT:
	       break;
	    case GLSL_TYPE_UINT:
	    case GLSL_TYPE_INT:
	       if (state->language_version > 120)
		  break;
	       /* FALLTHROUGH */
	    default:
	       _mesa_glsl_error(& loc, state,
				"vertex shader input / attribute cannot have "
				"type %s`%s'",
				var->type->is_array() ? "array of " : "",
				check_type->name);
	       error_emitted = true;
	    }

	    if (!error_emitted && (state->language_version <= 130)
		&& var->type->is_array()) {
	       _mesa_glsl_error(& loc, state,
				"vertex shader input / attribute cannot have "
				"array type");
	       error_emitted = true;
	    }
	 }
      }

      /* 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;
      if (decl->initializer != 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(ctx) 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 (this->type->qualifier.flags.q.constant
	     || this->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",
				   (this->type->qualifier.flags.q.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.flags.q.constant)
	       var->read_only = false;

	    /* Never emit code to initialize a uniform.
	     */
	    const glsl_type *initializer_type;
	    if (!this->type->qualifier.flags.q.uniform) {
	       result = do_assignment(&initializer_instructions, state,
				      lhs, rhs,
				      this->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;
	 }
      }

      /* From page 23 (page 29 of the PDF) of the GLSL 1.10 spec:
       *
       *     "It is an error to write to a const variable outside of
       *      its declaration, so they must be initialized when
       *      declared."
       */
      if (this->type->qualifier.flags.q.constant && decl->initializer == NULL) {
	 _mesa_glsl_error(& loc, state,
			  "const declaration of `%s' must be initialized");
      }

      /* 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))) {

	 /* 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)) {
	       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);
	    }

	    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;
	 } else {
	    YYLTYPE loc = this->get_location();
	    _mesa_glsl_error(&loc, state, "`%s' redeclared", decl->identifier);
	 }

	 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)) {
	 YYLTYPE loc = this->get_location();
	 _mesa_glsl_error(&loc, state, "name `%s' already taken in the "
			  "current scope", decl->identifier);
	 continue;
      }

      /* Push the variable declaration to the top.  It means that all
       * the variable declarations will appear in a funny
       * last-to-first order, but otherwise we run into trouble if a
       * function is prototyped, a global var is decled, then the
       * function is defined with usage of the global var.  See
       * glslparsertest's CorrectModule.frag.
       */
      instructions->push_head(var);
      instructions->append_list(&initializer_instructions);
   }


   /* Generally, variable declarations do not have r-values.  However,
    * one is used for the declaration in
    *
    * while (bool b = some_condition()) {
    *   ...
    * }
    *
    * so we return the rvalue from the last seen declaration here.
    */
   return result;
}


ir_rvalue *
ast_parameter_declarator::hir(exec_list *instructions,
			      struct _mesa_glsl_parse_state *state)
{
   void *ctx = state;
   const struct glsl_type *type;
   const char *name = NULL;
   YYLTYPE loc = this->get_location();

   type = this->type->specifier->glsl_type(& name, state);

   if (type == NULL) {
      if (name != NULL) {
	 _mesa_glsl_error(& loc, state,
			  "invalid type `%s' in declaration of `%s'",
			  name, this->identifier);
      } else {
	 _mesa_glsl_error(& loc, state,
			  "invalid type in declaration of `%s'",
			  this->identifier);
      }

      type = glsl_type::error_type;
   }

   /* From page 62 (page 68 of the PDF) of the GLSL 1.50 spec:
    *
    *    "Functions that accept no input arguments need not use void in the
    *    argument list because prototypes (or definitions) are required and
    *    therefore there is no ambiguity when an empty argument list "( )" is
    *    declared. The idiom "(void)" as a parameter list is provided for
    *    convenience."
    *
    * Placing this check here prevents a void parameter being set up
    * for a function, which avoids tripping up checks for main taking
    * parameters and lookups of an unnamed symbol.
    */
   if (type->is_void()) {
      if (this->identifier != NULL)
	 _mesa_glsl_error(& loc, state,
			  "named parameter cannot have type `void'");

      is_void = true;
      return NULL;
   }

   if (formal_parameter && (this->identifier == NULL)) {
      _mesa_glsl_error(& loc, state, "formal parameter lacks a name");
      return NULL;
   }

   /* This only handles "vec4 foo[..]".  The earlier specifier->glsl_type(...)
    * call already handled the "vec4[..] foo" case.
    */
   if (this->is_array) {
      type = process_array_type(&loc, type, this->array_size, state);
   }

   if (type->array_size() == 0) {
      _mesa_glsl_error(&loc, state, "arrays passed as parameters must have "
		       "a declared size.");
      type = glsl_type::error_type;
   }

   is_void = false;
   ir_variable *var = new(ctx) ir_variable(type, this->identifier, ir_var_in);

   /* Apply any specified qualifiers to the parameter declaration.  Note that
    * for function parameters the default mode is 'in'.
    */
   apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc);

   instructions->push_tail(var);

   /* Parameter declarations do not have r-values.
    */
   return NULL;
}


void
ast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters,
					    bool formal,
					    exec_list *ir_parameters,
					    _mesa_glsl_parse_state *state)
{
   ast_parameter_declarator *void_param = NULL;
   unsigned count = 0;

   foreach_list_typed (ast_parameter_declarator, param, link, ast_parameters) {
      param->formal_parameter = formal;
      param->hir(ir_parameters, state);

      if (param->is_void)
	 void_param = param;

      count++;
   }

   if ((void_param != NULL) && (count > 1)) {
      YYLTYPE loc = void_param->get_location();

      _mesa_glsl_error(& loc, state,
		       "`void' parameter must be only parameter");
   }
}


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)
{
   void *ctx = state;
   ir_function *f = NULL;
   ir_function_signature *sig = NULL;
   exec_list hir_parameters;

   const char *const name = identifier;

   /* From page 21 (page 27 of the PDF) of the GLSL 1.20 spec,
    *
    *   "Function declarations (prototypes) cannot occur inside of functions;
    *   they must be at global scope, or for the built-in functions, outside
    *   the global scope."
    *
    * From page 27 (page 33 of the PDF) of the GLSL ES 1.00.16 spec,
    *
    *   "User defined functions may only be defined within the global scope."
    *
    * Note that this language does not appear in GLSL 1.10.
    */
   if ((state->current_function != NULL) && (state->language_version != 110)) {
      YYLTYPE loc = this->get_location();
      _mesa_glsl_error(&loc, state,
		       "declaration of function `%s' not allowed within "
		       "function body", name);
   }

   /* 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(name, "gl_", 3) == 0) {
      YYLTYPE loc = this->get_location();
      _mesa_glsl_error(&loc, state,
		       "identifier `%s' uses reserved `gl_' prefix", name);
   }

   /* Convert the list of function parameters to HIR now so that they can be
    * used below to compare this function's signature with previously seen
    * signatures for functions with the same name.
    */
   ast_parameter_declarator::parameters_to_hir(& this->parameters,
					       is_definition,
					       & hir_parameters, state);

   const char *return_type_name;
   const glsl_type *return_type =
      this->return_type->specifier->glsl_type(& return_type_name, state);

   if (!return_type) {
      YYLTYPE loc = this->get_location();
      _mesa_glsl_error(&loc, state,
		       "function `%s' has undeclared return type `%s'",
		       name, return_type_name);
      return_type = glsl_type::error_type;
   }

   /* From page 56 (page 62 of the PDF) of the GLSL 1.30 spec:
    * "No qualifier is allowed on the return type of a function."
    */
   if (this->return_type->has_qualifiers()) {
      YYLTYPE loc = this->get_location();
      _mesa_glsl_error(& loc, state,
		       "function `%s' return type has qualifiers", 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.
    */
   f = state->symbols->get_function(name);
   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);
	 if (badvar != NULL) {
	    YYLTYPE loc = this->get_location();

	    _mesa_glsl_error(&loc, state, "function `%s' parameter `%s' "
			     "qualifiers don't match prototype", name, badvar);
	 }

	 if (sig->return_type != return_type) {
	    YYLTYPE loc = this->get_location();

	    _mesa_glsl_error(&loc, state, "function `%s' return type doesn't "
			     "match prototype", name);
	 }

	 if (is_definition && sig->is_defined) {
	    YYLTYPE loc = this->get_location();

	    _mesa_glsl_error(& loc, state, "function `%s' redefined", name);
	 }
      }
   } else {
      f = new(ctx) ir_function(name);
      if (!state->symbols->add_function(f)) {
	 /* This function name shadows a non-function use of the same name. */
	 YYLTYPE loc = this->get_location();

	 _mesa_glsl_error(&loc, state, "function name `%s' conflicts with "
			  "non-function", name);
	 return NULL;
      }

      emit_function(state, instructions, f);
   }

   /* Verify the return type of main() */
   if (strcmp(name, "main") == 0) {
      if (! return_type->is_void()) {
	 YYLTYPE loc = this->get_location();

	 _mesa_glsl_error(& loc, state, "main() must return void");
      }

      if (!hir_parameters.is_empty()) {
	 YYLTYPE loc = this->get_location();

	 _mesa_glsl_error(& loc, state, "main() must not take any parameters");
      }
   }

   /* Finish storing the information about this new function in its signature.
    */
   if (sig == NULL) {
      sig = new(ctx) ir_function_signature(return_type);
      f->add_signature(sig);
   }

   sig->replace_parameters(&hir_parameters);
   signature = sig;

   /* Function declarations (prototypes) do not have r-values.
    */
   return NULL;
}


ir_rvalue *
ast_function_definition::hir(exec_list *instructions,
			     struct _mesa_glsl_parse_state *state)
{
   prototype->is_definition = true;
   prototype->hir(instructions, state);

   ir_function_signature *signature = prototype->signature;
   if (signature == NULL)
      return NULL;

   assert(state->current_function == NULL);
   state->current_function = signature;
   state->found_return = false;

   /* Duplicate parameters declared in the prototype as concrete variables.
    * Add these to the symbol table.
    */
   state->symbols->push_scope();
   foreach_iter(exec_list_iterator, iter, signature->parameters) {
      ir_variable *const var = ((ir_instruction *) iter.get())->as_variable();

      assert(var != NULL);

      /* The only way a parameter would "exist" is if two parameters have
       * the same name.
       */
      if (state->symbols->name_declared_this_scope(var->name)) {
	 YYLTYPE loc = this->get_location();

	 _mesa_glsl_error(& loc, state, "parameter `%s' redeclared", var->name);
      } else {
	 state->symbols->add_variable(var);
      }
   }

   /* Convert the body of the function to HIR. */
   this->body->hir(&signature->body, state);
   signature->is_defined = true;

   state->symbols->pop_scope();

   assert(state->current_function == signature);
   state->current_function = NULL;

   if (!signature->return_type->is_void() && !state->found_return) {
      YYLTYPE loc = this->get_location();
      _mesa_glsl_error(& loc, state, "function `%s' has non-void return type "
		       "%s, but no return statement",
		       signature->function_name(),
		       signature->return_type->name);
   }

   /* Function definitions do not have r-values.
    */
   return NULL;
}


ir_rvalue *
ast_jump_statement::hir(exec_list *instructions,
			struct _mesa_glsl_parse_state *state)
{
   void *ctx = state;

   switch (mode) {
   case ast_return: {
      ir_return *inst;
      assert(state->current_function);

      if (opt_return_value) {
	 if (state->current_function->return_type->base_type ==
	     GLSL_TYPE_VOID) {
	    YYLTYPE loc = this->get_location();

	    _mesa_glsl_error(& loc, state,
			     "`return` with a value, in function `%s' "
			     "returning void",
			     state->current_function->function_name());
	 }

	 ir_rvalue *const ret = opt_return_value->hir(instructions, state);
	 assert(ret != NULL);

	 /* Implicit conversions are not allowed for return values. */
	 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,
			     state->current_function->function_name(),
			     state->current_function->return_type->name);
	 }

	 inst = new(ctx) ir_return(ret);
      } else {
	 if (state->current_function->return_type->base_type !=
	     GLSL_TYPE_VOID) {
	    YYLTYPE loc = this->get_location();

	    _mesa_glsl_error(& loc, state,
			     "`return' with no value, in function %s returning "
			     "non-void",
			     state->current_function->function_name());
	 }
	 inst = new(ctx) ir_return;
      }

      state->found_return = true;
      instructions->push_tail(inst);
      break;
   }

   case ast_discard:
      if (state->target != fragment_shader) {
	 YYLTYPE loc = this->get_location();

	 _mesa_glsl_error(& loc, state,
			  "`discard' may only appear in a fragment shader");
      }
      instructions->push_tail(new(ctx) ir_discard);
      break;

   case ast_break:
   case ast_continue:
      /* FINISHME: Handle switch-statements.  They cannot contain 'continue',
       * FINISHME: and they use a different IR instruction for 'break'.
       */
      /* FINISHME: Correctly handle the nesting.  If a switch-statement is
       * FINISHME: inside a loop, a 'continue' is valid and will bind to the
       * FINISHME: loop.
       */
      if (state->loop_or_switch_nesting == NULL) {
	 YYLTYPE loc = this->get_location();

	 _mesa_glsl_error(& loc, state,
			  "`%s' may only appear in a loop",
			  (mode == ast_break) ? "break" : "continue");
      } else {
	 ir_loop *const loop = state->loop_or_switch_nesting->as_loop();

	 /* Inline the for loop expression again, since we don't know
	  * where near the end of the loop body the normal copy of it
	  * is going to be placed.
	  */
	 if (mode == ast_continue &&
	     state->loop_or_switch_nesting_ast->rest_expression) {
	    state->loop_or_switch_nesting_ast->rest_expression->hir(instructions,
								    state);
	 }

	 if (loop != NULL) {
	    ir_loop_jump *const jump =
	       new(ctx) ir_loop_jump((mode == ast_break)
				     ? ir_loop_jump::jump_break
				     : ir_loop_jump::jump_continue);
	    instructions->push_tail(jump);
	 }
      }

      break;
   }

   /* Jump instructions do not have r-values.
    */
   return NULL;
}


ir_rvalue *
ast_selection_statement::hir(exec_list *instructions,
			     struct _mesa_glsl_parse_state *state)
{
   void *ctx = state;

   ir_rvalue *const condition = this->condition->hir(instructions, state);

   /* From page 66 (page 72 of the PDF) of the GLSL 1.50 spec:
    *
    *    "Any expression whose type evaluates to a Boolean can be used as the
    *    conditional expression bool-expression. Vector types are not accepted
    *    as the expression to if."
    *
    * The checks are separated so that higher quality diagnostics can be
    * generated for cases where both rules are violated.
    */
   if (!condition->type->is_boolean() || !condition->type->is_scalar()) {
      YYLTYPE loc = this->condition->get_location();

      _mesa_glsl_error(& loc, state, "if-statement condition must be scalar "
		       "boolean");
   }

   ir_if *const stmt = new(ctx) ir_if(condition);

   if (then_statement != NULL) {
      state->symbols->push_scope();
      then_statement->hir(& stmt->then_instructions, state);
      state->symbols->pop_scope();
   }

   if (else_statement != NULL) {
      state->symbols->push_scope();
      else_statement->hir(& stmt->else_instructions, state);
      state->symbols->pop_scope();
   }

   instructions->push_tail(stmt);

   /* if-statements do not have r-values.
    */
   return NULL;
}


void
ast_iteration_statement::condition_to_hir(ir_loop *stmt,
					  struct _mesa_glsl_parse_state *state)
{
   void *ctx = state;

   if (condition != NULL) {
      ir_rvalue *const cond =
	 condition->hir(& stmt->body_instructions, state);

      if ((cond == NULL)
	  || !cond->type->is_boolean() || !cond->type->is_scalar()) {
	 YYLTYPE loc = condition->get_location();

	 _mesa_glsl_error(& loc, state,
			  "loop condition must be scalar boolean");
      } else {
	 /* As the first code in the loop body, generate a block that looks
	  * like 'if (!condition) break;' as the loop termination condition.
	  */
	 ir_rvalue *const not_cond =
	    new(ctx) ir_expression(ir_unop_logic_not, glsl_type::bool_type, cond,
				   NULL);

	 ir_if *const if_stmt = new(ctx) ir_if(not_cond);

	 ir_jump *const break_stmt =
	    new(ctx) ir_loop_jump(ir_loop_jump::jump_break);

	 if_stmt->then_instructions.push_tail(break_stmt);
	 stmt->body_instructions.push_tail(if_stmt);
      }
   }
}


ir_rvalue *
ast_iteration_statement::hir(exec_list *instructions,
			     struct _mesa_glsl_parse_state *state)
{
   void *ctx = state;

   /* For-loops and while-loops start a new scope, but do-while loops do not.
    */
   if (mode != ast_do_while)
      state->symbols->push_scope();

   if (init_statement != NULL)
      init_statement->hir(instructions, state);

   ir_loop *const stmt = new(ctx) ir_loop();
   instructions->push_tail(stmt);

   /* Track the current loop and / or switch-statement nesting.
    */
   ir_instruction *const nesting = state->loop_or_switch_nesting;
   ast_iteration_statement *nesting_ast = state->loop_or_switch_nesting_ast;

   state->loop_or_switch_nesting = stmt;
   state->loop_or_switch_nesting_ast = this;

   if (mode != ast_do_while)
      condition_to_hir(stmt, state);

   if (body != NULL)
      body->hir(& stmt->body_instructions, state);

   if (rest_expression != NULL)
      rest_expression->hir(& stmt->body_instructions, state);

   if (mode == ast_do_while)
      condition_to_hir(stmt, state);

   if (mode != ast_do_while)
      state->symbols->pop_scope();

   /* Restore previous nesting before returning.
    */
   state->loop_or_switch_nesting = nesting;
   state->loop_or_switch_nesting_ast = nesting_ast;

   /* Loops do not have r-values.
    */
   return NULL;
}


ir_rvalue *
ast_type_specifier::hir(exec_list *instructions,
			  struct _mesa_glsl_parse_state *state)
{
   if (this->structure != NULL)
      return this->structure->hir(instructions, state);

   return NULL;
}


ir_rvalue *
ast_struct_specifier::hir(exec_list *instructions,
			  struct _mesa_glsl_parse_state *state)
{
   unsigned decl_count = 0;

   /* Make an initial pass over the list of structure fields to determine how
    * many there are.  Each element in this list is an ast_declarator_list.
    * This means that we actually need to count the number of elements in the
    * 'declarations' list in each of the elements.
    */
   foreach_list_typed (ast_declarator_list, decl_list, link,
		       &this->declarations) {
      foreach_list_const (decl_ptr, & decl_list->declarations) {
	 decl_count++;
      }
   }

   /* 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 = hieralloc_array(state, glsl_struct_field,
						  decl_count);

   unsigned i = 0;
   foreach_list_typed (ast_declarator_list, decl_list, link,
		       &this->declarations) {
      const char *type_name;

      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 *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;
	 i++;
      }
   }

   assert(i == decl_count);

   const glsl_type *t =
      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));
      if (s != NULL) {
	 s[state->num_user_structures] = t;
	 state->user_structures = s;
	 state->num_user_structures++;
      }
   }

   /* Structure type definitions do not have r-values.
    */
   return NULL;
}
