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

#include "glsl_symbol_table.h"
#include "ast.h"
#include "compiler/glsl_types.h"
#include "ir.h"
#include "linker_util.h"
#include "main/shader_types.h"
#include "main/consts_exts.h"
#include "main/shaderobj.h"
#include "builtin_functions.h"

static ir_rvalue *
convert_component(ir_rvalue *src, const glsl_type *desired_type);

static unsigned
process_parameters(exec_list *instructions, exec_list *actual_parameters,
                   exec_list *parameters,
                   struct _mesa_glsl_parse_state *state)
{
   void *mem_ctx = state;
   unsigned count = 0;

   foreach_list_typed(ast_node, ast, link, parameters) {
      /* We need to process the parameters first in order to know if we can
       * raise or not a unitialized warning. Calling set_is_lhs silence the
       * warning for now. Raising the warning or not will be checked at
       * verify_parameter_modes.
       */
      ast->set_is_lhs(true);
      ir_rvalue *result = ast->hir(instructions, state);

      /* Error happened processing function parameter */
      if (!result) {
         actual_parameters->push_tail(ir_rvalue::error_value(mem_ctx));
         count++;
         continue;
      }

      ir_constant *const constant =
         result->constant_expression_value(mem_ctx);

      if (constant != NULL)
         result = constant;

      actual_parameters->push_tail(result);
      count++;
   }

   return count;
}


/**
 * Generate a source prototype for a function signature
 *
 * \param return_type Return type of the function.  May be \c NULL.
 * \param name        Name of the function.
 * \param parameters  List of \c ir_instruction nodes representing the
 *                    parameter list for the function.  This may be either a
 *                    formal (\c ir_variable) or actual (\c ir_rvalue)
 *                    parameter list.  Only the type is used.
 *
 * \return
 * A ralloced string representing the prototype of the function.
 */
char *
prototype_string(const glsl_type *return_type, const char *name,
                 exec_list *parameters)
{
   char *str = NULL;

   if (return_type != NULL)
      str = ralloc_asprintf(NULL, "%s ", glsl_get_type_name(return_type));

   ralloc_asprintf_append(&str, "%s(", name);

   const char *comma = "";
   foreach_in_list(const ir_instruction, param, parameters) {
      ralloc_asprintf_append(&str, "%s%s", comma,
                             glsl_get_type_name(param->ir_type ==
                                                ir_type_variable ? ((ir_variable *)param)->type :
                                                ((ir_rvalue *)param)->type));
      comma = ", ";
   }

   ralloc_strcat(&str, ")");
   return str;
}

static bool
verify_image_parameter(YYLTYPE *loc, _mesa_glsl_parse_state *state,
                       const ir_variable *formal, const ir_variable *actual)
{
   /**
    * From the ARB_shader_image_load_store specification:
    *
    * "The values of image variables qualified with coherent,
    *  volatile, restrict, readonly, or writeonly may not be passed
    *  to functions whose formal parameters lack such
    *  qualifiers. [...] It is legal to have additional qualifiers
    *  on a formal parameter, but not to have fewer."
    */
   if (actual->data.memory_coherent && !formal->data.memory_coherent) {
      _mesa_glsl_error(loc, state,
                       "function call parameter `%s' drops "
                       "`coherent' qualifier", formal->name);
      return false;
   }

   if (actual->data.memory_volatile && !formal->data.memory_volatile) {
      _mesa_glsl_error(loc, state,
                       "function call parameter `%s' drops "
                       "`volatile' qualifier", formal->name);
      return false;
   }

   if (actual->data.memory_restrict && !formal->data.memory_restrict) {
      _mesa_glsl_error(loc, state,
                       "function call parameter `%s' drops "
                       "`restrict' qualifier", formal->name);
      return false;
   }

   if (actual->data.memory_read_only && !formal->data.memory_read_only) {
      _mesa_glsl_error(loc, state,
                       "function call parameter `%s' drops "
                       "`readonly' qualifier", formal->name);
      return false;
   }

   if (actual->data.memory_write_only && !formal->data.memory_write_only) {
      _mesa_glsl_error(loc, state,
                       "function call parameter `%s' drops "
                       "`writeonly' qualifier", formal->name);
      return false;
   }

   return true;
}

static bool
verify_first_atomic_parameter(YYLTYPE *loc, _mesa_glsl_parse_state *state,
                              ir_variable *var)
{
   if (!var ||
       (!var->is_in_shader_storage_block() &&
        var->data.mode != ir_var_shader_shared)) {
      _mesa_glsl_error(loc, state, "First argument to atomic function "
                       "must be a buffer or shared variable");
      return false;
   }
   return true;
}

static bool
is_atomic_function(const char *func_name)
{
   return !strcmp(func_name, "atomicAdd") ||
          !strcmp(func_name, "atomicMin") ||
          !strcmp(func_name, "atomicMax") ||
          !strcmp(func_name, "atomicAnd") ||
          !strcmp(func_name, "atomicOr") ||
          !strcmp(func_name, "atomicXor") ||
          !strcmp(func_name, "atomicExchange") ||
          !strcmp(func_name, "atomicCompSwap");
}

static bool
verify_atomic_image_parameter_qualifier(YYLTYPE *loc, _mesa_glsl_parse_state *state,
                                        ir_variable *var)
{
   if (!var ||
       (var->data.image_format != PIPE_FORMAT_R32_UINT &&
        var->data.image_format != PIPE_FORMAT_R32_SINT &&
        var->data.image_format != PIPE_FORMAT_R32_FLOAT)) {
      _mesa_glsl_error(loc, state, "Image atomic functions should use r32i/r32ui "
                       "format qualifier");
      return false;
   }
   return true;
}

static bool
is_atomic_image_function(const char *func_name)
{
   return !strcmp(func_name, "imageAtomicAdd") ||
          !strcmp(func_name, "imageAtomicMin") ||
          !strcmp(func_name, "imageAtomicMax") ||
          !strcmp(func_name, "imageAtomicAnd") ||
          !strcmp(func_name, "imageAtomicOr") ||
          !strcmp(func_name, "imageAtomicXor") ||
          !strcmp(func_name, "imageAtomicExchange") ||
          !strcmp(func_name, "imageAtomicCompSwap") ||
          !strcmp(func_name, "imageAtomicIncWrap") ||
          !strcmp(func_name, "imageAtomicDecWrap");
}


/**
 * Verify that 'out' and 'inout' actual parameters are lvalues.  Also, verify
 * that 'const_in' formal parameters (an extension in our IR) correspond to
 * ir_constant actual parameters.
 */
static bool
verify_parameter_modes(_mesa_glsl_parse_state *state,
                       ir_function_signature *sig,
                       exec_list &actual_ir_parameters,
                       exec_list &actual_ast_parameters)
{
   exec_node *actual_ir_node  = actual_ir_parameters.get_head_raw();
   exec_node *actual_ast_node = actual_ast_parameters.get_head_raw();

   foreach_in_list(const ir_variable, formal, &sig->parameters) {
      /* The lists must be the same length. */
      assert(!actual_ir_node->is_tail_sentinel());
      assert(!actual_ast_node->is_tail_sentinel());

      const ir_rvalue *const actual = (ir_rvalue *) actual_ir_node;
      const ast_expression *const actual_ast =
         exec_node_data(ast_expression, actual_ast_node, link);

      YYLTYPE loc = actual_ast->get_location();

      /* Verify that 'const_in' parameters are ir_constants. */
      if (formal->data.mode == ir_var_const_in &&
          actual->ir_type != ir_type_constant) {
         _mesa_glsl_error(&loc, state,
                          "parameter `in %s' must be a constant expression",
                          formal->name);
         return false;
      }

      /* Verify that shader_in parameters are shader inputs */
      if (formal->data.must_be_shader_input) {
         const ir_rvalue *val = actual;

         /* GLSL 4.40 allows swizzles, while earlier GLSL versions do not. */
         if (val->ir_type == ir_type_swizzle) {
            if (!state->is_version(440, 0)) {
               _mesa_glsl_error(&loc, state,
                                "parameter `%s` must not be swizzled",
                                formal->name);
               return false;
            }
            val = ((ir_swizzle *)val)->val;
         }

         for (;;) {
            if (val->ir_type == ir_type_dereference_array) {
               val = ((ir_dereference_array *)val)->array;
            } else if (val->ir_type == ir_type_dereference_record &&
                       !state->es_shader) {
               val = ((ir_dereference_record *)val)->record;
            } else
               break;
         }

         ir_variable *var = NULL;
         if (const ir_dereference_variable *deref_var = val->as_dereference_variable())
            var = deref_var->variable_referenced();

         if (!var || var->data.mode != ir_var_shader_in) {
            _mesa_glsl_error(&loc, state,
                             "parameter `%s` must be a shader input",
                             formal->name);
            return false;
         }

         var->data.must_be_shader_input = 1;
      }

      /* GLSL spec prohibits using bias with anything else than fragment stage,
       * this starts already at GLSL 1.30 but here is a quote from latest 4.60
       * spec, Section 8.9 "Texture Functions":
       *
       *    "... the bias parameter is optional for fragment shaders. The bias
       *     parameter is not accepted in any other shader stage."
       *
       * Mesa has drirc "allow_vertex_texture_bias" to allow bias in vertex
       * stage, additionally GL_NV_compute_shader_derivatives makes it possible
       * to use bias in compute shaders.
       */
      if (sig->is_builtin() &&
          strcmp(formal->name, "bias") == 0 &&
          state->stage != MESA_SHADER_FRAGMENT &&
          !state->NV_compute_shader_derivatives_enable &&
          (!(state->allow_vertex_texture_bias &&
             state->stage == MESA_SHADER_VERTEX))) {
         _mesa_glsl_error(&loc, state,
                          "bias parameter may only be used in fragment stage");
      }

      /* Verify that 'out' and 'inout' actual parameters are lvalues. */
      if (formal->data.mode == ir_var_function_out
          || formal->data.mode == ir_var_function_inout) {
         const char *mode = NULL;
         switch (formal->data.mode) {
         case ir_var_function_out:   mode = "out";   break;
         case ir_var_function_inout: mode = "inout"; break;
         default:                    assert(false);  break;
         }

         /* This AST-based check catches errors like f(i++).  The IR-based
          * is_lvalue() is insufficient because the actual parameter at the
          * IR-level is just a temporary value, which is an l-value.
          */
         if (actual_ast->non_lvalue_description != NULL) {
            _mesa_glsl_error(&loc, state,
                             "function parameter '%s %s' references a %s",
                             mode, formal->name,
                             actual_ast->non_lvalue_description);
            return false;
         }

         ir_variable *var = actual->variable_referenced();

         if (var && formal->data.mode == ir_var_function_inout) {
            if ((var->data.mode == ir_var_auto ||
                 var->data.mode == ir_var_shader_out) &&
                !var->data.assigned &&
                !is_gl_identifier(var->name)) {
               _mesa_glsl_warning(&loc, state, "`%s' used uninitialized",
                                  var->name);
            }
         }

         if (var)
            var->data.assigned = true;

         if (var && var->data.read_only) {
            _mesa_glsl_error(&loc, state,
                             "function parameter '%s %s' references the "
                             "read-only variable '%s'",
                             mode, formal->name,
                             actual->variable_referenced()->name);
            return false;
         } else if (!actual->is_lvalue(state)) {
            _mesa_glsl_error(&loc, state,
                             "function parameter '%s %s' is not an lvalue",
                             mode, formal->name);
            return false;
         }
      } else {
         assert(formal->data.mode == ir_var_function_in ||
                formal->data.mode == ir_var_const_in);
         ir_variable *var = actual->variable_referenced();
         if (var) {
            if ((var->data.mode == ir_var_auto ||
                 var->data.mode == ir_var_shader_out) &&
                !var->data.assigned &&
                !is_gl_identifier(var->name)) {
               _mesa_glsl_warning(&loc, state, "`%s' used uninitialized",
                                  var->name);
            }
         }
      }

      if (glsl_type_is_image(formal->type) &&
          actual->variable_referenced()) {
         if (!verify_image_parameter(&loc, state, formal,
                                     actual->variable_referenced()))
            return false;
      }

      actual_ir_node  = actual_ir_node->next;
      actual_ast_node = actual_ast_node->next;
   }

   /* The first parameter of atomic functions must be a buffer variable */
   const char *func_name = sig->function_name();
   bool is_atomic = is_atomic_function(func_name);
   if (is_atomic) {
      const ir_rvalue *const actual =
         (ir_rvalue *) actual_ir_parameters.get_head_raw();

      const ast_expression *const actual_ast =
         exec_node_data(ast_expression,
                        actual_ast_parameters.get_head_raw(), link);
      YYLTYPE loc = actual_ast->get_location();

      if (!verify_first_atomic_parameter(&loc, state,
                                         actual->variable_referenced())) {
         return false;
      }
   } else if (is_atomic_image_function(func_name)) {
      const ir_rvalue *const actual =
         (ir_rvalue *) actual_ir_parameters.get_head_raw();

      const ast_expression *const actual_ast =
         exec_node_data(ast_expression,
                        actual_ast_parameters.get_head_raw(), link);
      YYLTYPE loc = actual_ast->get_location();

      if (!verify_atomic_image_parameter_qualifier(&loc, state,
                                         actual->variable_referenced())) {
         return false;
      }
   }

   return true;
}

struct copy_index_deref_data {
   void *mem_ctx;
   exec_list *before_instructions;
};

static void
copy_index_derefs_to_temps(ir_instruction *ir, void *data)
{
   struct copy_index_deref_data *d = (struct copy_index_deref_data *)data;

   if (ir->ir_type == ir_type_dereference_array) {
      ir_dereference_array *a = (ir_dereference_array *) ir;
      ir = a->array->as_dereference();

      ir_rvalue *idx = a->array_index;
      ir_variable *var = idx->variable_referenced();

      /* If the index is read only it cannot change so there is no need
       * to copy it.
       */
      if (!var || var->data.read_only || var->data.memory_read_only)
         return;

      ir_variable *tmp = new(d->mem_ctx) ir_variable(idx->type, "idx_tmp",
                                                      ir_var_temporary);
      d->before_instructions->push_tail(tmp);

      ir_dereference_variable *const deref_tmp_1 =
         new(d->mem_ctx) ir_dereference_variable(tmp);
      ir_assignment *const assignment =
         new(d->mem_ctx) ir_assignment(deref_tmp_1,
                                       idx->clone(d->mem_ctx, NULL));
      d->before_instructions->push_tail(assignment);

      /* Replace the array index with a dereference of the new temporary */
      ir_dereference_variable *const deref_tmp_2 =
         new(d->mem_ctx) ir_dereference_variable(tmp);
      a->array_index = deref_tmp_2;
   }
}

static void
fix_parameter(void *mem_ctx, ir_rvalue *actual, const glsl_type *formal_type,
              exec_list *before_instructions, exec_list *after_instructions,
              bool parameter_is_inout)
{
   ir_expression *const expr = actual->as_expression();

   /* If the types match exactly and the parameter is not a vector-extract,
    * nothing needs to be done to fix the parameter.
    */
   if (formal_type == actual->type
       && (expr == NULL || expr->operation != ir_binop_vector_extract)
       && actual->as_dereference_variable())
      return;

   /* An array index could also be an out variable so we need to make a copy
    * of them before the function is called.
    */
   if (!actual->as_dereference_variable()) {
      struct copy_index_deref_data data;
      data.mem_ctx = mem_ctx;
      data.before_instructions = before_instructions;

      visit_tree(actual, copy_index_derefs_to_temps, &data);
   }

   /* To convert an out parameter, we need to create a temporary variable to
    * hold the value before conversion, and then perform the conversion after
    * the function call returns.
    *
    * This has the effect of transforming code like this:
    *
    *   void f(out int x);
    *   float value;
    *   f(value);
    *
    * Into IR that's equivalent to this:
    *
    *   void f(out int x);
    *   float value;
    *   int out_parameter_conversion;
    *   f(out_parameter_conversion);
    *   value = float(out_parameter_conversion);
    *
    * If the parameter is an ir_expression of ir_binop_vector_extract,
    * additional conversion is needed in the post-call re-write.
    */
   ir_variable *tmp =
      new(mem_ctx) ir_variable(formal_type, "inout_tmp", ir_var_temporary);

   before_instructions->push_tail(tmp);

   /* If the parameter is an inout parameter, copy the value of the actual
    * parameter to the new temporary.  Note that no type conversion is allowed
    * here because inout parameters must match types exactly.
    */
   if (parameter_is_inout) {
      /* Inout parameters should never require conversion, since that would
       * require an implicit conversion to exist both to and from the formal
       * parameter type, and there are no bidirectional implicit conversions.
       */
      assert (actual->type == formal_type);

      ir_dereference_variable *const deref_tmp_1 =
         new(mem_ctx) ir_dereference_variable(tmp);
      ir_assignment *const assignment =
         new(mem_ctx) ir_assignment(deref_tmp_1, actual->clone(mem_ctx, NULL));
      before_instructions->push_tail(assignment);
   }

   /* Replace the parameter in the call with a dereference of the new
    * temporary.
    */
   ir_dereference_variable *const deref_tmp_2 =
      new(mem_ctx) ir_dereference_variable(tmp);
   actual->replace_with(deref_tmp_2);


   /* Copy the temporary variable to the actual parameter with optional
    * type conversion applied.
    */
   ir_rvalue *rhs = new(mem_ctx) ir_dereference_variable(tmp);
   if (actual->type != formal_type)
      rhs = convert_component(rhs, actual->type);

   ir_rvalue *lhs = actual;
   if (expr != NULL && expr->operation == ir_binop_vector_extract) {
      lhs = new(mem_ctx) ir_dereference_array(expr->operands[0]->clone(mem_ctx,
                                                                       NULL),
                                              expr->operands[1]->clone(mem_ctx,
                                                                       NULL));
   }

   ir_assignment *const assignment_2 = new(mem_ctx) ir_assignment(lhs, rhs);
   after_instructions->push_tail(assignment_2);
}

/**
 * Generate a function call.
 *
 * For non-void functions, this returns a dereference of the temporary
 * variable which stores the return value for the call.  For void functions,
 * this returns NULL.
 */
static ir_rvalue *
generate_call(exec_list *instructions, ir_function_signature *sig,
              exec_list *actual_parameters,
              ir_variable *sub_var,
              ir_rvalue *array_idx,
              struct _mesa_glsl_parse_state *state)
{
   void *ctx = state;
   exec_list post_call_conversions;

   /* Perform implicit conversion of arguments.  For out parameters, we need
    * to place them in a temporary variable and do the conversion after the
    * call takes place.  Since we haven't emitted the call yet, we'll place
    * the post-call conversions in a temporary exec_list, and emit them later.
    */
   foreach_two_lists(formal_node, &sig->parameters,
                     actual_node, actual_parameters) {
      ir_rvalue *actual = (ir_rvalue *) actual_node;
      ir_variable *formal = (ir_variable *) formal_node;

      if (glsl_type_is_numeric(formal->type) || glsl_type_is_boolean(formal->type)) {
         switch (formal->data.mode) {
         case ir_var_const_in:
         case ir_var_function_in: {
            ir_rvalue *converted
               = convert_component(actual, formal->type);
            actual->replace_with(converted);
            break;
         }
         case ir_var_function_out:
         case ir_var_function_inout:
            fix_parameter(ctx, actual, formal->type,
                          instructions, &post_call_conversions,
                          formal->data.mode == ir_var_function_inout);
            break;
         default:
            assert (!"Illegal formal parameter mode");
            break;
         }
      }
   }

   /* Section 4.3.2 (Const) of the GLSL 1.10.59 spec says:
    *
    *     "Initializers for const declarations must be formed from literal
    *     values, other const variables (not including function call
    *     paramaters), or expressions of these.
    *
    *     Constructors may be used in such expressions, but function calls may
    *     not."
    *
    * Section 4.3.3 (Constant Expressions) of the GLSL 1.20.8 spec says:
    *
    *     "A constant expression is one of
    *
    *         ...
    *
    *         - a built-in function call whose arguments are all constant
    *           expressions, with the exception of the texture lookup
    *           functions, the noise functions, and ftransform. The built-in
    *           functions dFdx, dFdy, and fwidth must return 0 when evaluated
    *           inside an initializer with an argument that is a constant
    *           expression."
    *
    * Section 5.10 (Constant Expressions) of the GLSL ES 1.00.17 spec says:
    *
    *     "A constant expression is one of
    *
    *         ...
    *
    *         - a built-in function call whose arguments are all constant
    *           expressions, with the exception of the texture lookup
    *           functions."
    *
    * Section 4.3.3 (Constant Expressions) of the GLSL ES 3.00.4 spec says:
    *
    *     "A constant expression is one of
    *
    *         ...
    *
    *         - a built-in function call whose arguments are all constant
    *           expressions, with the exception of the texture lookup
    *           functions.  The built-in functions dFdx, dFdy, and fwidth must
    *           return 0 when evaluated inside an initializer with an argument
    *           that is a constant expression."
    *
    * If the function call is a constant expression, don't generate any
    * instructions; just generate an ir_constant.
    */
   if (state->is_version(120, 100) ||
       state->consts->AllowGLSLBuiltinConstantExpression) {
      ir_constant *value = sig->constant_expression_value(ctx,
                                                          actual_parameters,
                                                          NULL);
      if (value != NULL) {
         return value;
      }
   }

   ir_dereference_variable *deref = NULL;
   if (!glsl_type_is_void(sig->return_type)) {
      /* Create a new temporary to hold the return value. */
      char *const name = ir_variable::temporaries_allocate_names
         ? ralloc_asprintf(ctx, "%s_retval", sig->function_name())
         : NULL;

      ir_variable *var;

      var = new(ctx) ir_variable(sig->return_type, name, ir_var_temporary);
      var->data.precision = sig->return_precision;
      instructions->push_tail(var);

      ralloc_free(name);

      deref = new(ctx) ir_dereference_variable(var);
   }

   ir_call *call = new(ctx) ir_call(sig, deref,
                                    actual_parameters, sub_var, array_idx);
   instructions->push_tail(call);

   /* Also emit any necessary out-parameter conversions. */
   instructions->append_list(&post_call_conversions);

   return deref ? deref->clone(ctx, NULL) : NULL;
}

/**
 * Given a function name and parameter list, find the matching signature.
 */
static ir_function_signature *
match_function_by_name(const char *name,
                       exec_list *actual_parameters,
                       struct _mesa_glsl_parse_state *state)
{
   ir_function *f = state->symbols->get_function(name);
   ir_function_signature *local_sig = NULL;
   ir_function_signature *sig = NULL;

   /* Is the function hidden by a record type constructor? */
   if (state->symbols->get_type(name))
      return sig; /* no match */

   /* Is the function hidden by a variable (impossible in 1.10)? */
   if (!state->symbols->separate_function_namespace
       && state->symbols->get_variable(name))
      return sig; /* no match */

   if (f != NULL) {
      /* In desktop GL, the presence of a user-defined signature hides any
       * built-in signatures, so we must ignore them.  In contrast, in ES2
       * user-defined signatures add new overloads, so we must consider them.
       */
      bool allow_builtins = state->es_shader || !f->has_user_signature();

      /* Look for a match in the local shader.  If exact, we're done. */
      bool is_exact = false;
      sig = local_sig = f->matching_signature(state, actual_parameters,
                                              state->has_implicit_conversions(),
                                              state->has_implicit_int_to_uint_conversion(),
                                              allow_builtins, &is_exact);
      if (is_exact)
         return sig;

      if (!allow_builtins)
         return sig;
   }

   /* Local shader has no exact candidates; check the built-ins. */
   sig = _mesa_glsl_find_builtin_function(state, name, actual_parameters);

   /* if _mesa_glsl_find_builtin_function failed, fall back to the result
    * of choose_best_inexact_overload() instead. This should only affect
    * GLES.
    */
   return sig ? sig : local_sig;
}

static ir_function_signature *
match_subroutine_by_name(const char *name,
                         exec_list *actual_parameters,
                         struct _mesa_glsl_parse_state *state,
                         ir_variable **var_r)
{
   void *ctx = state;
   ir_function_signature *sig = NULL;
   ir_function *f, *found = NULL;
   const char *new_name;
   ir_variable *var;
   bool is_exact = false;

   new_name =
      ralloc_asprintf(ctx, "%s_%s",
                      _mesa_shader_stage_to_subroutine_prefix(state->stage),
                      name);
   var = state->symbols->get_variable(new_name);
   if (!var)
      return NULL;

   for (int i = 0; i < state->num_subroutine_types; i++) {
      f = state->subroutine_types[i];
      if (strcmp(f->name, glsl_get_type_name(glsl_without_array(var->type))))
         continue;
      found = f;
      break;
   }

   if (!found)
      return NULL;
   *var_r = var;
   sig = found->matching_signature(state, actual_parameters,
                                   state->has_implicit_conversions(),
                                   state->has_implicit_int_to_uint_conversion(),
                                   false, &is_exact);
   return sig;
}

static ir_rvalue *
generate_array_index(void *mem_ctx, exec_list *instructions,
                     struct _mesa_glsl_parse_state *state, YYLTYPE loc,
                     const ast_expression *array, ast_expression *idx,
                     const char **function_name, exec_list *actual_parameters)
{
   if (array->oper == ast_array_index) {
      /* This handles arrays of arrays */
      ir_rvalue *outer_array = generate_array_index(mem_ctx, instructions,
                                                    state, loc,
                                                    array->subexpressions[0],
                                                    array->subexpressions[1],
                                                    function_name,
                                                    actual_parameters);
      ir_rvalue *outer_array_idx = idx->hir(instructions, state);

      YYLTYPE index_loc = idx->get_location();
      return _mesa_ast_array_index_to_hir(mem_ctx, state, outer_array,
                                          outer_array_idx, loc,
                                          index_loc);
   } else {
      ir_variable *sub_var = NULL;
      *function_name = array->primary_expression.identifier;

      if (!match_subroutine_by_name(*function_name, actual_parameters,
                                    state, &sub_var)) {
         _mesa_glsl_error(&loc, state, "Unknown subroutine `%s'",
                          *function_name);
         *function_name = NULL; /* indicate error condition to caller */
         return NULL;
      }

      ir_rvalue *outer_array_idx = idx->hir(instructions, state);
      return new(mem_ctx) ir_dereference_array(sub_var, outer_array_idx);
   }
}

static bool
function_exists(_mesa_glsl_parse_state *state,
                struct glsl_symbol_table *symbols, const char *name)
{
   ir_function *f = symbols->get_function(name);
   if (f != NULL) {
      foreach_in_list(ir_function_signature, sig, &f->signatures) {
         if (sig->is_builtin() && !sig->is_builtin_available(state))
            continue;
         return true;
      }
   }
   return false;
}

static void
print_function_prototypes(_mesa_glsl_parse_state *state, YYLTYPE *loc,
                          ir_function *f)
{
   if (f == NULL)
      return;

   foreach_in_list(ir_function_signature, sig, &f->signatures) {
      if (sig->is_builtin() && !sig->is_builtin_available(state))
         continue;

      char *str = prototype_string(sig->return_type, f->name,
                                   &sig->parameters);
      _mesa_glsl_error(loc, state, "   %s", str);
      ralloc_free(str);
   }
}

/**
 * Raise a "no matching function" error, listing all possible overloads the
 * compiler considered so developers can figure out what went wrong.
 */
static void
no_matching_function_error(const char *name,
                           YYLTYPE *loc,
                           exec_list *actual_parameters,
                           _mesa_glsl_parse_state *state)
{
   struct glsl_symbol_table *symb = _mesa_glsl_get_builtin_function_symbols();

   if (!function_exists(state, state->symbols, name)
       && (!state->uses_builtin_functions
           || !function_exists(state, symb, name))) {
      _mesa_glsl_error(loc, state, "no function with name '%s'", name);
   } else {
      char *str = prototype_string(NULL, name, actual_parameters);
      _mesa_glsl_error(loc, state,
                       "no matching function for call to `%s';"
                       " candidates are:",
                       str);
      ralloc_free(str);

      print_function_prototypes(state, loc,
                                state->symbols->get_function(name));

      if (state->uses_builtin_functions) {
         print_function_prototypes(state, loc, symb->get_function(name));
      }
   }
}

/**
 * Perform automatic type conversion of constructor parameters
 *
 * This implements the rules in the "Conversion and Scalar Constructors"
 * section (GLSL 1.10 section 5.4.1), not the "Implicit Conversions" rules.
 */
static ir_rvalue *
convert_component(ir_rvalue *src, const glsl_type *desired_type)
{
   void *ctx = ralloc_parent(src);
   const unsigned a = desired_type->base_type;
   const unsigned b = src->type->base_type;
   ir_expression *result = NULL;

   if (glsl_type_is_error(src->type))
      return src;

   assert(a <= GLSL_TYPE_IMAGE);
   assert(b <= GLSL_TYPE_IMAGE);

   if (a == b)
      return src;

   switch (a) {
   case GLSL_TYPE_UINT:
      switch (b) {
      case GLSL_TYPE_INT:
         result = new(ctx) ir_expression(ir_unop_i2u, src);
         break;
      case GLSL_TYPE_FLOAT16:
         result = new(ctx) ir_expression(ir_unop_f162u, src);
         break;
      case GLSL_TYPE_FLOAT:
         result = new(ctx) ir_expression(ir_unop_f2u, src);
         break;
      case GLSL_TYPE_BOOL:
         result = new(ctx) ir_expression(ir_unop_i2u,
                                         new(ctx) ir_expression(ir_unop_b2i,
                                                                src));
         break;
      case GLSL_TYPE_DOUBLE:
         result = new(ctx) ir_expression(ir_unop_d2u, src);
         break;
      case GLSL_TYPE_UINT64:
         result = new(ctx) ir_expression(ir_unop_u642u, src);
         break;
      case GLSL_TYPE_INT64:
         result = new(ctx) ir_expression(ir_unop_i642u, src);
         break;
      case GLSL_TYPE_SAMPLER:
         result = new(ctx) ir_expression(ir_unop_unpack_sampler_2x32, src);
         break;
      case GLSL_TYPE_IMAGE:
         result = new(ctx) ir_expression(ir_unop_unpack_image_2x32, src);
         break;
      }
      break;
   case GLSL_TYPE_INT:
      switch (b) {
      case GLSL_TYPE_UINT:
         result = new(ctx) ir_expression(ir_unop_u2i, src);
         break;
      case GLSL_TYPE_FLOAT16:
         result = new(ctx) ir_expression(ir_unop_f162i, src);
         break;
      case GLSL_TYPE_FLOAT:
         result = new(ctx) ir_expression(ir_unop_f2i, src);
         break;
      case GLSL_TYPE_BOOL:
         result = new(ctx) ir_expression(ir_unop_b2i, src);
         break;
      case GLSL_TYPE_DOUBLE:
         result = new(ctx) ir_expression(ir_unop_d2i, src);
         break;
      case GLSL_TYPE_UINT64:
         result = new(ctx) ir_expression(ir_unop_u642i, src);
         break;
      case GLSL_TYPE_INT64:
         result = new(ctx) ir_expression(ir_unop_i642i, src);
         break;
      }
      break;
   case GLSL_TYPE_FLOAT16:
      switch (b) {
      case GLSL_TYPE_UINT:
         result = new(ctx) ir_expression(ir_unop_u2f16, desired_type, src, NULL);
         break;
      case GLSL_TYPE_INT:
         result = new(ctx) ir_expression(ir_unop_i2f16, desired_type, src, NULL);
         break;
      case GLSL_TYPE_BOOL:
         result = new(ctx) ir_expression(ir_unop_b2f16, desired_type, src, NULL);
         break;
      case GLSL_TYPE_FLOAT:
         result = new(ctx) ir_expression(ir_unop_f2f16, desired_type, src, NULL);
         break;
      case GLSL_TYPE_DOUBLE:
         result = new(ctx) ir_expression(ir_unop_d2f16, desired_type, src, NULL);
         break;
      case GLSL_TYPE_UINT64:
         result = new(ctx) ir_expression(ir_unop_u642f16, desired_type, src, NULL);
         break;
      case GLSL_TYPE_INT64:
         result = new(ctx) ir_expression(ir_unop_i642f16, desired_type, src, NULL);
         break;
      }
      break;
   case GLSL_TYPE_FLOAT:
      switch (b) {
      case GLSL_TYPE_UINT:
         result = new(ctx) ir_expression(ir_unop_u2f, desired_type, src, NULL);
         break;
      case GLSL_TYPE_INT:
         result = new(ctx) ir_expression(ir_unop_i2f, desired_type, src, NULL);
         break;
      case GLSL_TYPE_BOOL:
         result = new(ctx) ir_expression(ir_unop_b2f, desired_type, src, NULL);
         break;
      case GLSL_TYPE_FLOAT16:
         result = new(ctx) ir_expression(ir_unop_f162f, desired_type, src, NULL);
         break;
      case GLSL_TYPE_DOUBLE:
         result = new(ctx) ir_expression(ir_unop_d2f, desired_type, src, NULL);
         break;
      case GLSL_TYPE_UINT64:
         result = new(ctx) ir_expression(ir_unop_u642f, desired_type, src, NULL);
         break;
      case GLSL_TYPE_INT64:
         result = new(ctx) ir_expression(ir_unop_i642f, desired_type, src, NULL);
         break;
      }
      break;
   case GLSL_TYPE_BOOL:
      switch (b) {
      case GLSL_TYPE_UINT:
         result = new(ctx) ir_expression(ir_unop_i2b,
                                         new(ctx) ir_expression(ir_unop_u2i,
                                                                src));
         break;
      case GLSL_TYPE_INT:
         result = new(ctx) ir_expression(ir_unop_i2b, desired_type, src, NULL);
         break;
      case GLSL_TYPE_FLOAT16:
         result = new(ctx) ir_expression(ir_unop_f162b, desired_type, src, NULL);
         break;
      case GLSL_TYPE_FLOAT:
         result = new(ctx) ir_expression(ir_unop_f2b, desired_type, src, NULL);
         break;
      case GLSL_TYPE_DOUBLE:
         result = new(ctx) ir_expression(ir_unop_d2b, desired_type, src, NULL);
         break;
      case GLSL_TYPE_UINT64:
         result = new(ctx) ir_expression(ir_unop_i642b,
                                         new(ctx) ir_expression(ir_unop_u642i64,
                                                                src));
         break;
      case GLSL_TYPE_INT64:
         result = new(ctx) ir_expression(ir_unop_i642b, desired_type, src, NULL);
         break;
      }
      break;
   case GLSL_TYPE_DOUBLE:
      switch (b) {
      case GLSL_TYPE_INT:
         result = new(ctx) ir_expression(ir_unop_i2d, src);
         break;
      case GLSL_TYPE_UINT:
         result = new(ctx) ir_expression(ir_unop_u2d, src);
         break;
      case GLSL_TYPE_BOOL:
         result = new(ctx) ir_expression(ir_unop_f2d,
                                         new(ctx) ir_expression(ir_unop_b2f,
                                                                src));
         break;
      case GLSL_TYPE_FLOAT16:
         result = new(ctx) ir_expression(ir_unop_f162d, desired_type, src, NULL);
         break;
      case GLSL_TYPE_FLOAT:
         result = new(ctx) ir_expression(ir_unop_f2d, desired_type, src, NULL);
         break;
      case GLSL_TYPE_UINT64:
         result = new(ctx) ir_expression(ir_unop_u642d, desired_type, src, NULL);
         break;
      case GLSL_TYPE_INT64:
         result = new(ctx) ir_expression(ir_unop_i642d, desired_type, src, NULL);
         break;
      }
      break;
   case GLSL_TYPE_UINT64:
      switch (b) {
      case GLSL_TYPE_INT:
         result = new(ctx) ir_expression(ir_unop_i2u64, src);
         break;
      case GLSL_TYPE_UINT:
         result = new(ctx) ir_expression(ir_unop_u2u64, src);
         break;
      case GLSL_TYPE_BOOL:
         result = new(ctx) ir_expression(ir_unop_i642u64,
                                         new(ctx) ir_expression(ir_unop_b2i64,
                                                                src));
         break;
      case GLSL_TYPE_FLOAT16:
         result = new(ctx) ir_expression(ir_unop_f162u64, src);
         break;
      case GLSL_TYPE_FLOAT:
         result = new(ctx) ir_expression(ir_unop_f2u64, src);
         break;
      case GLSL_TYPE_DOUBLE:
         result = new(ctx) ir_expression(ir_unop_d2u64, src);
         break;
      case GLSL_TYPE_INT64:
         result = new(ctx) ir_expression(ir_unop_i642u64, src);
         break;
      }
      break;
   case GLSL_TYPE_INT64:
      switch (b) {
      case GLSL_TYPE_INT:
         result = new(ctx) ir_expression(ir_unop_i2i64, src);
         break;
      case GLSL_TYPE_UINT:
         result = new(ctx) ir_expression(ir_unop_u2i64, src);
         break;
      case GLSL_TYPE_BOOL:
         result = new(ctx) ir_expression(ir_unop_b2i64, src);
         break;
      case GLSL_TYPE_FLOAT16:
         result = new(ctx) ir_expression(ir_unop_f162i64, src);
         break;
      case GLSL_TYPE_FLOAT:
         result = new(ctx) ir_expression(ir_unop_f2i64, src);
         break;
      case GLSL_TYPE_DOUBLE:
         result = new(ctx) ir_expression(ir_unop_d2i64, src);
         break;
      case GLSL_TYPE_UINT64:
         result = new(ctx) ir_expression(ir_unop_u642i64, src);
         break;
      }
      break;
   case GLSL_TYPE_SAMPLER:
      switch (b) {
      case GLSL_TYPE_UINT:
         result = new(ctx)
            ir_expression(ir_unop_pack_sampler_2x32, desired_type, src);
         break;
      }
      break;
   case GLSL_TYPE_IMAGE:
      switch (b) {
      case GLSL_TYPE_UINT:
         result = new(ctx)
            ir_expression(ir_unop_pack_image_2x32, desired_type, src);
         break;
      }
      break;
   }

   assert(result != NULL);
   assert(result->type == desired_type);

   /* Try constant folding; it may fold in the conversion we just added. */
   ir_constant *const constant = result->constant_expression_value(ctx);
   return (constant != NULL) ? (ir_rvalue *) constant : (ir_rvalue *) result;
}


/**
 * Perform automatic type and constant conversion of constructor parameters
 *
 * This implements the rules in the "Implicit Conversions" rules, not the
 * "Conversion and Scalar Constructors".
 *
 * After attempting the implicit conversion, an attempt to convert into a
 * constant valued expression is also done.
 *
 * The \c from \c ir_rvalue is converted "in place".
 *
 * \param from   Operand that is being converted
 * \param to     Base type the operand will be converted to
 * \param state  GLSL compiler state
 *
 * \return
 * If the attempt to convert into a constant expression succeeds, \c true is
 * returned. Otherwise \c false is returned.
 */
static bool
implicitly_convert_component(ir_rvalue * &from, const glsl_base_type to,
                             struct _mesa_glsl_parse_state *state)
{
   void *mem_ctx = state;
   ir_rvalue *result = from;

   if (to != from->type->base_type) {
      const glsl_type *desired_type =
         glsl_simple_type(to,
                          from->type->vector_elements,
                          from->type->matrix_columns);

      if (_mesa_glsl_can_implicitly_convert(from->type, desired_type,
                                            state->has_implicit_conversions(),
                                            state->has_implicit_int_to_uint_conversion())) {
         /* Even though convert_component() implements the constructor
          * conversion rules (not the implicit conversion rules), its safe
          * to use it here because we already checked that the implicit
          * conversion is legal.
          */
         result = convert_component(from, desired_type);
      }
   }

   ir_rvalue *const constant = result->constant_expression_value(mem_ctx);

   if (constant != NULL)
      result = constant;

   if (from != result) {
      from->replace_with(result);
      from = result;
   }

   return constant != NULL;
}


/**
 * Dereference a specific component from a scalar, vector, or matrix
 */
static ir_rvalue *
dereference_component(ir_rvalue *src, unsigned component)
{
   void *ctx = ralloc_parent(src);
   assert(component < glsl_get_components(src->type));

   /* If the source is a constant, just create a new constant instead of a
    * dereference of the existing constant.
    */
   ir_constant *constant = src->as_constant();
   if (constant)
      return new(ctx) ir_constant(constant, component);

   if (glsl_type_is_scalar(src->type)) {
      return src;
   } else if (glsl_type_is_vector(src->type)) {
      return new(ctx) ir_swizzle(src, component, 0, 0, 0, 1);
   } else {
      assert(glsl_type_is_matrix(src->type));

      /* Dereference a row of the matrix, then call this function again to get
       * a specific element from that row.
       */
      const int c = component / glsl_get_column_type(src->type)->vector_elements;
      const int r = component % glsl_get_column_type(src->type)->vector_elements;
      ir_constant *const col_index = new(ctx) ir_constant(c);
      ir_dereference *const col = new(ctx) ir_dereference_array(src,
                                                                col_index);

      col->type = glsl_get_column_type(src->type);

      return dereference_component(col, r);
   }

   assert(!"Should not get here.");
   return NULL;
}


static ir_rvalue *
process_vec_mat_constructor(exec_list *instructions,
                            const glsl_type *constructor_type,
                            YYLTYPE *loc, exec_list *parameters,
                            struct _mesa_glsl_parse_state *state)
{
   void *ctx = state;

   /* The ARB_shading_language_420pack spec says:
    *
    * "If an initializer is a list of initializers enclosed in curly braces,
    *  the variable being declared must be a vector, a matrix, an array, or a
    *  structure.
    *
    *      int i = { 1 }; // illegal, i is not an aggregate"
    */
   if (constructor_type->vector_elements <= 1) {
      _mesa_glsl_error(loc, state, "aggregates can only initialize vectors, "
                       "matrices, arrays, and structs");
      return ir_rvalue::error_value(ctx);
   }

   exec_list actual_parameters;
   const unsigned parameter_count =
      process_parameters(instructions, &actual_parameters, parameters, state);

   if (parameter_count == 0
       || (glsl_type_is_vector(constructor_type) &&
           constructor_type->vector_elements != parameter_count)
       || (glsl_type_is_matrix(constructor_type) &&
           constructor_type->matrix_columns != parameter_count)) {
      _mesa_glsl_error(loc, state, "%s constructor must have %u parameters",
                       glsl_type_is_vector(constructor_type) ? "vector" : "matrix",
                       constructor_type->vector_elements);
      return ir_rvalue::error_value(ctx);
   }

   bool all_parameters_are_constant = true;

   /* Type cast each parameter and, if possible, fold constants. */
   foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) {
      /* Apply implicit conversions (not the scalar constructor rules, see the
       * spec quote above!) and attempt to convert the parameter to a constant
       * valued expression. After doing so, track whether or not all the
       * parameters to the constructor are trivially constant valued
       * expressions.
       */
      all_parameters_are_constant &=
         implicitly_convert_component(ir, constructor_type->base_type, state);

      if (glsl_type_is_matrix(constructor_type)) {
         if (ir->type != glsl_get_column_type(constructor_type)) {
            _mesa_glsl_error(loc, state, "type error in matrix constructor: "
                             "expected: %s, found %s",
                             glsl_get_type_name(glsl_get_column_type(constructor_type)),
                             glsl_get_type_name(ir->type));
            return ir_rvalue::error_value(ctx);
         }
      } else if (ir->type != glsl_get_scalar_type(constructor_type)) {
         _mesa_glsl_error(loc, state, "type error in vector constructor: "
                          "expected: %s, found %s",
                          glsl_get_type_name(glsl_get_scalar_type(constructor_type)),
                          glsl_get_type_name(ir->type));
         return ir_rvalue::error_value(ctx);
      }
   }

   if (all_parameters_are_constant)
      return new(ctx) ir_constant(constructor_type, &actual_parameters);

   ir_variable *var = new(ctx) ir_variable(constructor_type, "vec_mat_ctor",
                                           ir_var_temporary);
   instructions->push_tail(var);

   int i = 0;

   foreach_in_list(ir_rvalue, rhs, &actual_parameters) {
      ir_instruction *assignment = NULL;

      if (glsl_type_is_matrix(var->type)) {
         ir_rvalue *lhs =
            new(ctx) ir_dereference_array(var, new(ctx) ir_constant(i));
         assignment = new(ctx) ir_assignment(lhs, rhs);
      } else {
         /* use writemask rather than index for vector */
         assert(glsl_type_is_vector(var->type));
         assert(i < 4);
         ir_dereference *lhs = new(ctx) ir_dereference_variable(var);
         assignment = new(ctx) ir_assignment(lhs, rhs, 1u << i);
      }

      instructions->push_tail(assignment);

      i++;
   }

   return new(ctx) ir_dereference_variable(var);
}


static ir_rvalue *
process_array_constructor(exec_list *instructions,
                          const glsl_type *constructor_type,
                          YYLTYPE *loc, exec_list *parameters,
                          struct _mesa_glsl_parse_state *state)
{
   void *ctx = state;
   /* Array constructors come in two forms: sized and unsized.  Sized array
    * constructors look like 'vec4[2](a, b)', where 'a' and 'b' are vec4
    * variables.  In this case the number of parameters must exactly match the
    * specified size of the array.
    *
    * Unsized array constructors look like 'vec4[](a, b)', where 'a' and 'b'
    * are vec4 variables.  In this case the size of the array being constructed
    * is determined by the number of parameters.
    *
    * From page 52 (page 58 of the PDF) of the GLSL 1.50 spec:
    *
    *    "There must be exactly the same number of arguments as the size of
    *    the array being constructed. If no size is present in the
    *    constructor, then the array is explicitly sized to the number of
    *    arguments provided. The arguments are assigned in order, starting at
    *    element 0, to the elements of the constructed array. Each argument
    *    must be the same type as the element type of the array, or be a type
    *    that can be converted to the element type of the array according to
    *    Section 4.1.10 "Implicit Conversions.""
    */
   exec_list actual_parameters;
   const unsigned parameter_count =
      process_parameters(instructions, &actual_parameters, parameters, state);
   bool is_unsized_array = glsl_type_is_unsized_array(constructor_type);

   if ((parameter_count == 0) ||
       (!is_unsized_array && (constructor_type->length != parameter_count))) {
      const unsigned min_param = is_unsized_array
         ? 1 : constructor_type->length;

      _mesa_glsl_error(loc, state, "array constructor must have %s %u "
                       "parameter%s",
                       is_unsized_array ? "at least" : "exactly",
                       min_param, (min_param <= 1) ? "" : "s");
      return ir_rvalue::error_value(ctx);
   }

   if (is_unsized_array) {
      constructor_type =
         glsl_array_type(constructor_type->fields.array,
                         parameter_count, 0);
      assert(constructor_type != NULL);
      assert(constructor_type->length == parameter_count);
   }

   bool all_parameters_are_constant = true;
   const glsl_type *element_type = constructor_type->fields.array;

   /* Type cast each parameter and, if possible, fold constants. */
   foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) {
      /* Apply implicit conversions (not the scalar constructor rules, see the
       * spec quote above!) and attempt to convert the parameter to a constant
       * valued expression. After doing so, track whether or not all the
       * parameters to the constructor are trivially constant valued
       * expressions.
       */
      all_parameters_are_constant &=
         implicitly_convert_component(ir, element_type->base_type, state);

      if (glsl_type_is_unsized_array(constructor_type->fields.array)) {
         /* As the inner parameters of the constructor are created without
          * knowledge of each other we need to check to make sure unsized
          * parameters of unsized constructors all end up with the same size.
          *
          * e.g we make sure to fail for a constructor like this:
          * vec4[][] a = vec4[][](vec4[](vec4(0.0), vec4(1.0)),
          *                       vec4[](vec4(0.0), vec4(1.0), vec4(1.0)),
          *                       vec4[](vec4(0.0), vec4(1.0)));
          */
         if (glsl_type_is_unsized_array(element_type)) {
            /* This is the first parameter so just get the type */
            element_type = ir->type;
         } else if (element_type != ir->type) {
            _mesa_glsl_error(loc, state, "type error in array constructor: "
                             "expected: %s, found %s",
                             glsl_get_type_name(element_type),
                             glsl_get_type_name(ir->type));
            return ir_rvalue::error_value(ctx);
         }
      } else if (ir->type != constructor_type->fields.array) {
         _mesa_glsl_error(loc, state, "type error in array constructor: "
                          "expected: %s, found %s",
                          glsl_get_type_name(constructor_type->fields.array),
                          glsl_get_type_name(ir->type));
         return ir_rvalue::error_value(ctx);
      } else {
         element_type = ir->type;
      }
   }

   if (glsl_type_is_unsized_array(constructor_type->fields.array)) {
      constructor_type =
         glsl_array_type(element_type, parameter_count, 0);
      assert(constructor_type != NULL);
      assert(constructor_type->length == parameter_count);
   }

   if (all_parameters_are_constant)
      return new(ctx) ir_constant(constructor_type, &actual_parameters);

   ir_variable *var = new(ctx) ir_variable(constructor_type, "array_ctor",
                                           ir_var_temporary);
   instructions->push_tail(var);

   int i = 0;
   foreach_in_list(ir_rvalue, rhs, &actual_parameters) {
      ir_rvalue *lhs = new(ctx) ir_dereference_array(var,
                                                     new(ctx) ir_constant(i));

      ir_instruction *assignment = new(ctx) ir_assignment(lhs, rhs);
      instructions->push_tail(assignment);

      i++;
   }

   return new(ctx) ir_dereference_variable(var);
}


/**
 * Determine if a list consists of a single scalar r-value
 */
static bool
single_scalar_parameter(exec_list *parameters)
{
   const ir_rvalue *const p = (ir_rvalue *) parameters->get_head_raw();
   assert(((ir_rvalue *)p)->as_rvalue() != NULL);

   return (glsl_type_is_scalar(p->type) && p->next->is_tail_sentinel());
}


/**
 * Generate inline code for a vector constructor
 *
 * The generated constructor code will consist of a temporary variable
 * declaration of the same type as the constructor.  A sequence of assignments
 * from constructor parameters to the temporary will follow.
 *
 * \return
 * An \c ir_dereference_variable of the temprorary generated in the constructor
 * body.
 */
static ir_rvalue *
emit_inline_vector_constructor(const glsl_type *type,
                               exec_list *instructions,
                               exec_list *parameters,
                               void *ctx)
{
   assert(!parameters->is_empty());

   ir_variable *var = new(ctx) ir_variable(type, "vec_ctor", ir_var_temporary);
   instructions->push_tail(var);

   /* There are three kinds of vector constructors.
    *
    *  - Construct a vector from a single scalar by replicating that scalar to
    *    all components of the vector.
    *
    *  - Construct a vector from at least a matrix. This case should already
    *    have been taken care of in ast_function_expression::hir by breaking
    *    down the matrix into a series of column vectors.
    *
    *  - Construct a vector from an arbirary combination of vectors and
    *    scalars.  The components of the constructor parameters are assigned
    *    to the vector in order until the vector is full.
    */
   const unsigned lhs_components = glsl_get_components(type);
   if (single_scalar_parameter(parameters)) {
      ir_rvalue *first_param = (ir_rvalue *)parameters->get_head_raw();
      return new(ctx) ir_swizzle(first_param, 0, 0, 0, 0, lhs_components);
   } else {
      unsigned base_component = 0;
      unsigned base_lhs_component = 0;
      ir_constant_data data;
      unsigned constant_mask = 0, constant_components = 0;

      memset(&data, 0, sizeof(data));

      foreach_in_list(ir_rvalue, param, parameters) {
         unsigned rhs_components = glsl_get_components(param->type);

         /* Do not try to assign more components to the vector than it has! */
         if ((rhs_components + base_lhs_component) > lhs_components) {
            rhs_components = lhs_components - base_lhs_component;
         }

         const ir_constant *const c = param->as_constant();
         if (c != NULL) {
            for (unsigned i = 0; i < rhs_components; i++) {
               switch (c->type->base_type) {
               case GLSL_TYPE_UINT:
                  data.u[i + base_component] = c->get_uint_component(i);
                  break;
               case GLSL_TYPE_INT:
                  data.i[i + base_component] = c->get_int_component(i);
                  break;
               case GLSL_TYPE_FLOAT:
                  data.f[i + base_component] = c->get_float_component(i);
                  break;
               case GLSL_TYPE_DOUBLE:
                  data.d[i + base_component] = c->get_double_component(i);
                  break;
               case GLSL_TYPE_BOOL:
                  data.b[i + base_component] = c->get_bool_component(i);
                  break;
               case GLSL_TYPE_UINT64:
                  data.u64[i + base_component] = c->get_uint64_component(i);
                  break;
               case GLSL_TYPE_INT64:
                  data.i64[i + base_component] = c->get_int64_component(i);
                  break;
               default:
                  assert(!"Should not get here.");
                  break;
               }
            }

            /* Mask of fields to be written in the assignment. */
            constant_mask |= ((1U << rhs_components) - 1) << base_lhs_component;
            constant_components += rhs_components;

            base_component += rhs_components;
         }
         /* Advance the component index by the number of components
          * that were just assigned.
          */
         base_lhs_component += rhs_components;
      }

      if (constant_mask != 0) {
         ir_dereference *lhs = new(ctx) ir_dereference_variable(var);
         const glsl_type *rhs_type =
            glsl_simple_type(var->type->base_type, constant_components, 1);
         ir_rvalue *rhs = new(ctx) ir_constant(rhs_type, &data);

         ir_instruction *inst =
            new(ctx) ir_assignment(lhs, rhs, constant_mask);
         instructions->push_tail(inst);
      }

      base_component = 0;
      foreach_in_list(ir_rvalue, param, parameters) {
         unsigned rhs_components = glsl_get_components(param->type);

         /* Do not try to assign more components to the vector than it has! */
         if ((rhs_components + base_component) > lhs_components) {
            rhs_components = lhs_components - base_component;
         }

         /* If we do not have any components left to copy, break out of the
          * loop. This can happen when initializing a vec4 with a mat3 as the
          * mat3 would have been broken into a series of column vectors.
          */
         if (rhs_components == 0) {
            break;
         }

         const ir_constant *const c = param->as_constant();
         if (c == NULL) {
            /* Mask of fields to be written in the assignment. */
            const unsigned write_mask = ((1U << rhs_components) - 1)
               << base_component;

            ir_dereference *lhs = new(ctx) ir_dereference_variable(var);

            /* Generate a swizzle so that LHS and RHS sizes match. */
            ir_rvalue *rhs =
               new(ctx) ir_swizzle(param, 0, 1, 2, 3, rhs_components);

            ir_instruction *inst =
               new(ctx) ir_assignment(lhs, rhs, write_mask);
            instructions->push_tail(inst);
         }

         /* Advance the component index by the number of components that were
          * just assigned.
          */
         base_component += rhs_components;
      }
   }
   return new(ctx) ir_dereference_variable(var);
}


/**
 * Generate assignment of a portion of a vector to a portion of a matrix column
 *
 * \param src_base  First component of the source to be used in assignment
 * \param column    Column of destination to be assiged
 * \param row_base  First component of the destination column to be assigned
 * \param count     Number of components to be assigned
 *
 * \note
 * \c src_base + \c count must be less than or equal to the number of
 * components in the source vector.
 */
static ir_instruction *
assign_to_matrix_column(ir_variable *var, unsigned column, unsigned row_base,
                        ir_rvalue *src, unsigned src_base, unsigned count,
                        void *mem_ctx)
{
   ir_constant *col_idx = new(mem_ctx) ir_constant(column);
   ir_dereference *column_ref = new(mem_ctx) ir_dereference_array(var,
                                                                  col_idx);

   assert(glsl_get_components(column_ref->type) >= (row_base + count));
   assert(glsl_get_components(src->type) >= (src_base + count));

   /* Generate a swizzle that extracts the number of components from the source
    * that are to be assigned to the column of the matrix.
    */
   if (count < src->type->vector_elements) {
      src = new(mem_ctx) ir_swizzle(src,
                                    src_base + 0, src_base + 1,
                                    src_base + 2, src_base + 3,
                                    count);
   }

   /* Mask of fields to be written in the assignment. */
   const unsigned write_mask = ((1U << count) - 1) << row_base;

   return new(mem_ctx) ir_assignment(column_ref, src, write_mask);
}


/**
 * Generate inline code for a matrix constructor
 *
 * The generated constructor code will consist of a temporary variable
 * declaration of the same type as the constructor.  A sequence of assignments
 * from constructor parameters to the temporary will follow.
 *
 * \return
 * An \c ir_dereference_variable of the temprorary generated in the constructor
 * body.
 */
static ir_rvalue *
emit_inline_matrix_constructor(const glsl_type *type,
                               exec_list *instructions,
                               exec_list *parameters,
                               void *ctx)
{
   assert(!parameters->is_empty());

   ir_variable *var = new(ctx) ir_variable(type, "mat_ctor", ir_var_temporary);
   instructions->push_tail(var);

   /* There are three kinds of matrix constructors.
    *
    *  - Construct a matrix from a single scalar by replicating that scalar to
    *    along the diagonal of the matrix and setting all other components to
    *    zero.
    *
    *  - Construct a matrix from an arbirary combination of vectors and
    *    scalars.  The components of the constructor parameters are assigned
    *    to the matrix in column-major order until the matrix is full.
    *
    *  - Construct a matrix from a single matrix.  The source matrix is copied
    *    to the upper left portion of the constructed matrix, and the remaining
    *    elements take values from the identity matrix.
    */
   ir_rvalue *const first_param = (ir_rvalue *) parameters->get_head_raw();
   if (single_scalar_parameter(parameters)) {
      /* Assign the scalar to the X component of a vec4, and fill the remaining
       * components with zero.
       */
      glsl_base_type param_base_type = first_param->type->base_type;
      assert(glsl_type_is_float_16_32_64(first_param->type));
      ir_variable *rhs_var =
         new(ctx) ir_variable(glsl_simple_type(param_base_type, 4, 1),
                              "mat_ctor_vec",
                              ir_var_temporary);
      instructions->push_tail(rhs_var);

      ir_constant_data zero;
      for (unsigned i = 0; i < 4; i++)
         if (glsl_type_is_float(first_param->type))
            zero.f[i] = 0.0;
         else
            zero.d[i] = 0.0;

      ir_instruction *inst =
         new(ctx) ir_assignment(new(ctx) ir_dereference_variable(rhs_var),
                                new(ctx) ir_constant(rhs_var->type, &zero));
      instructions->push_tail(inst);

      ir_dereference *const rhs_ref =
         new(ctx) ir_dereference_variable(rhs_var);

      inst = new(ctx) ir_assignment(rhs_ref, first_param, 0x01);
      instructions->push_tail(inst);

      /* Assign the temporary vector to each column of the destination matrix
       * with a swizzle that puts the X component on the diagonal of the
       * matrix.  In some cases this may mean that the X component does not
       * get assigned into the column at all (i.e., when the matrix has more
       * columns than rows).
       */
      static const unsigned rhs_swiz[4][4] = {
         { 0, 1, 1, 1 },
         { 1, 0, 1, 1 },
         { 1, 1, 0, 1 },
         { 1, 1, 1, 0 }
      };

      const unsigned cols_to_init = MIN2(type->matrix_columns,
                                         type->vector_elements);
      for (unsigned i = 0; i < cols_to_init; i++) {
         ir_constant *const col_idx = new(ctx) ir_constant(i);
         ir_rvalue *const col_ref = new(ctx) ir_dereference_array(var,
                                                                  col_idx);

         ir_rvalue *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var);
         ir_rvalue *const rhs = new(ctx) ir_swizzle(rhs_ref, rhs_swiz[i],
                                                    type->vector_elements);

         inst = new(ctx) ir_assignment(col_ref, rhs);
         instructions->push_tail(inst);
      }

      for (unsigned i = cols_to_init; i < type->matrix_columns; i++) {
         ir_constant *const col_idx = new(ctx) ir_constant(i);
         ir_rvalue *const col_ref = new(ctx) ir_dereference_array(var,
                                                                  col_idx);

         ir_rvalue *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var);
         ir_rvalue *const rhs = new(ctx) ir_swizzle(rhs_ref, 1, 1, 1, 1,
                                                    type->vector_elements);

         inst = new(ctx) ir_assignment(col_ref, rhs);
         instructions->push_tail(inst);
      }
   } else if (glsl_type_is_matrix(first_param->type)) {
      /* From page 50 (56 of the PDF) of the GLSL 1.50 spec:
       *
       *     "If a matrix is constructed from a matrix, then each component
       *     (column i, row j) in the result that has a corresponding
       *     component (column i, row j) in the argument will be initialized
       *     from there. All other components will be initialized to the
       *     identity matrix. If a matrix argument is given to a matrix
       *     constructor, it is an error to have any other arguments."
       */
      assert(first_param->next->is_tail_sentinel());
      ir_rvalue *const src_matrix = first_param;

      /* If the source matrix is smaller, pre-initialize the relavent parts of
       * the destination matrix to the identity matrix.
       */
      if ((src_matrix->type->matrix_columns < var->type->matrix_columns) ||
          (src_matrix->type->vector_elements < var->type->vector_elements)) {

         /* If the source matrix has fewer rows, every column of the
          * destination must be initialized.  Otherwise only the columns in
          * the destination that do not exist in the source must be
          * initialized.
          */
         unsigned col =
            (src_matrix->type->vector_elements < var->type->vector_elements)
            ? 0 : src_matrix->type->matrix_columns;

         const glsl_type *const col_type = glsl_get_column_type(var->type);
         for (/* empty */; col < var->type->matrix_columns; col++) {
            ir_constant_data ident;

            if (!glsl_type_is_double(col_type)) {
               ident.f[0] = 0.0f;
               ident.f[1] = 0.0f;
               ident.f[2] = 0.0f;
               ident.f[3] = 0.0f;
               ident.f[col] = 1.0f;
            } else {
               ident.d[0] = 0.0;
               ident.d[1] = 0.0;
               ident.d[2] = 0.0;
               ident.d[3] = 0.0;
               ident.d[col] = 1.0;
            }

            ir_rvalue *const rhs = new(ctx) ir_constant(col_type, &ident);

            ir_rvalue *const lhs =
               new(ctx) ir_dereference_array(var, new(ctx) ir_constant(col));

            ir_instruction *inst = new(ctx) ir_assignment(lhs, rhs);
            instructions->push_tail(inst);
         }
      }

      /* Assign columns from the source matrix to the destination matrix.
       *
       * Since the parameter will be used in the RHS of multiple assignments,
       * generate a temporary and copy the paramter there.
       */
      ir_variable *const rhs_var =
         new(ctx) ir_variable(first_param->type, "mat_ctor_mat",
                              ir_var_temporary);
      instructions->push_tail(rhs_var);

      ir_dereference *const rhs_var_ref =
         new(ctx) ir_dereference_variable(rhs_var);
      ir_instruction *const inst =
         new(ctx) ir_assignment(rhs_var_ref, first_param);
      instructions->push_tail(inst);

      const unsigned last_row = MIN2(src_matrix->type->vector_elements,
                                     var->type->vector_elements);
      const unsigned last_col = MIN2(src_matrix->type->matrix_columns,
                                     var->type->matrix_columns);

      unsigned swiz[4] = { 0, 0, 0, 0 };
      for (unsigned i = 1; i < last_row; i++)
         swiz[i] = i;

      const unsigned write_mask = (1U << last_row) - 1;

      for (unsigned i = 0; i < last_col; i++) {
         ir_dereference *const lhs =
            new(ctx) ir_dereference_array(var, new(ctx) ir_constant(i));
         ir_rvalue *const rhs_col =
            new(ctx) ir_dereference_array(rhs_var, new(ctx) ir_constant(i));

         /* If one matrix has columns that are smaller than the columns of the
          * other matrix, wrap the column access of the larger with a swizzle
          * so that the LHS and RHS of the assignment have the same size (and
          * therefore have the same type).
          *
          * It would be perfectly valid to unconditionally generate the
          * swizzles, this this will typically result in a more compact IR
          * tree.
          */
         ir_rvalue *rhs;
         if (lhs->type->vector_elements != rhs_col->type->vector_elements) {
            rhs = new(ctx) ir_swizzle(rhs_col, swiz, last_row);
         } else {
            rhs = rhs_col;
         }

         ir_instruction *inst =
            new(ctx) ir_assignment(lhs, rhs, write_mask);
         instructions->push_tail(inst);
      }
   } else {
      const unsigned cols = type->matrix_columns;
      const unsigned rows = type->vector_elements;
      unsigned remaining_slots = rows * cols;
      unsigned col_idx = 0;
      unsigned row_idx = 0;

      foreach_in_list(ir_rvalue, rhs, parameters) {
         unsigned rhs_components = glsl_get_components(rhs->type);
         unsigned rhs_base = 0;

         if (remaining_slots == 0)
            break;

         /* Since the parameter might be used in the RHS of two assignments,
          * generate a temporary and copy the paramter there.
          */
         ir_variable *rhs_var =
            new(ctx) ir_variable(rhs->type, "mat_ctor_vec", ir_var_temporary);
         instructions->push_tail(rhs_var);

         ir_dereference *rhs_var_ref =
            new(ctx) ir_dereference_variable(rhs_var);
         ir_instruction *inst = new(ctx) ir_assignment(rhs_var_ref, rhs);
         instructions->push_tail(inst);

         do {
            /* Assign the current parameter to as many components of the matrix
             * as it will fill.
             *
             * NOTE: A single vector parameter can span two matrix columns.  A
             * single vec4, for example, can completely fill a mat2.
             */
            unsigned count = MIN2(rows - row_idx,
                                  rhs_components - rhs_base);

            rhs_var_ref = new(ctx) ir_dereference_variable(rhs_var);
            ir_instruction *inst = assign_to_matrix_column(var, col_idx,
                                                           row_idx,
                                                           rhs_var_ref,
                                                           rhs_base,
                                                           count, ctx);
            instructions->push_tail(inst);
            rhs_base += count;
            row_idx += count;
            remaining_slots -= count;

            /* Sometimes, there is still data left in the parameters and
             * components left to be set in the destination but in other
             * column.
             */
            if (row_idx >= rows) {
               row_idx = 0;
               col_idx++;
            }
         } while(remaining_slots > 0 && rhs_base < rhs_components);
      }
   }

   return new(ctx) ir_dereference_variable(var);
}


static ir_rvalue *
emit_inline_record_constructor(const glsl_type *type,
                               exec_list *instructions,
                               exec_list *parameters,
                               void *mem_ctx)
{
   ir_variable *const var =
      new(mem_ctx) ir_variable(type, "record_ctor", ir_var_temporary);
   ir_dereference_variable *const d =
      new(mem_ctx) ir_dereference_variable(var);

   instructions->push_tail(var);

   exec_node *node = parameters->get_head_raw();
   for (unsigned i = 0; i < type->length; i++) {
      assert(!node->is_tail_sentinel());

      ir_dereference *const lhs =
         new(mem_ctx) ir_dereference_record(d->clone(mem_ctx, NULL),
                                            type->fields.structure[i].name);

      ir_rvalue *const rhs = ((ir_instruction *) node)->as_rvalue();
      assert(rhs != NULL);

      ir_instruction *const assign = new(mem_ctx) ir_assignment(lhs, rhs);

      instructions->push_tail(assign);
      node = node->next;
   }

   return d;
}


static ir_rvalue *
process_record_constructor(exec_list *instructions,
                           const glsl_type *constructor_type,
                           YYLTYPE *loc, exec_list *parameters,
                           struct _mesa_glsl_parse_state *state)
{
   void *ctx = state;
   /* From page 32 (page 38 of the PDF) of the GLSL 1.20 spec:
    *
    *    "The arguments to the constructor will be used to set the structure's
    *     fields, in order, using one argument per field. Each argument must
    *     be the same type as the field it sets, or be a type that can be
    *     converted to the field's type according to Section 4.1.10 “Implicit
    *     Conversions.”"
    *
    * From page 35 (page 41 of the PDF) of the GLSL 4.20 spec:
    *
    *    "In all cases, the innermost initializer (i.e., not a list of
    *     initializers enclosed in curly braces) applied to an object must
    *     have the same type as the object being initialized or be a type that
    *     can be converted to the object's type according to section 4.1.10
    *     "Implicit Conversions". In the latter case, an implicit conversion
    *     will be done on the initializer before the assignment is done."
    */
   exec_list actual_parameters;

   const unsigned parameter_count =
         process_parameters(instructions, &actual_parameters, parameters,
                            state);

   if (parameter_count != constructor_type->length) {
      _mesa_glsl_error(loc, state,
                       "%s parameters in constructor for `%s'",
                       parameter_count > constructor_type->length
                       ? "too many": "insufficient",
                       glsl_get_type_name(constructor_type));
      return ir_rvalue::error_value(ctx);
   }

   bool all_parameters_are_constant = true;

   int i = 0;
   /* Type cast each parameter and, if possible, fold constants. */
   foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) {

      const glsl_struct_field *struct_field =
         &constructor_type->fields.structure[i];

      /* Apply implicit conversions (not the scalar constructor rules, see the
       * spec quote above!) and attempt to convert the parameter to a constant
       * valued expression. After doing so, track whether or not all the
       * parameters to the constructor are trivially constant valued
       * expressions.
       */
      all_parameters_are_constant &=
         implicitly_convert_component(ir, struct_field->type->base_type,
                                      state);

      if (ir->type != struct_field->type) {
         _mesa_glsl_error(loc, state,
                          "parameter type mismatch in constructor for `%s.%s' "
                          "(%s vs %s)",
                          glsl_get_type_name(constructor_type),
                          struct_field->name,
                          glsl_get_type_name(ir->type),
                          glsl_get_type_name(struct_field->type));
         return ir_rvalue::error_value(ctx);
      }

      i++;
   }

   if (all_parameters_are_constant) {
      return new(ctx) ir_constant(constructor_type, &actual_parameters);
   } else {
      return emit_inline_record_constructor(constructor_type, instructions,
                                            &actual_parameters, state);
   }
}

ir_rvalue *
ast_function_expression::handle_method(exec_list *instructions,
                                       struct _mesa_glsl_parse_state *state)
{
   const ast_expression *field = subexpressions[0];
   ir_rvalue *op;
   ir_rvalue *result;
   void *ctx = state;
   /* Handle "method calls" in GLSL 1.20 - namely, array.length() */
   YYLTYPE loc = get_location();
   state->check_version(120, 300, &loc, "methods not supported");

   const char *method;
   method = field->primary_expression.identifier;

   /* This would prevent to raise "uninitialized variable" warnings when
    * calling array.length.
    */
   field->subexpressions[0]->set_is_lhs(true);
   op = field->subexpressions[0]->hir(instructions, state);
   if (strcmp(method, "length") == 0) {
      if (!this->expressions.is_empty()) {
         _mesa_glsl_error(&loc, state, "length method takes no arguments");
         goto fail;
      }

      if (glsl_type_is_array(op->type)) {
         if (glsl_type_is_unsized_array(op->type)) {
            if (!state->has_shader_storage_buffer_objects()) {
               _mesa_glsl_error(&loc, state,
                                "length called on unsized array"
                                " only available with"
                                " ARB_shader_storage_buffer_object");
               goto fail;
            } else if (op->variable_referenced()->is_in_shader_storage_block()) {
               /* Calculate length of an unsized array in run-time */
               result = new(ctx)
                  ir_expression(ir_unop_ssbo_unsized_array_length, op);
            } else {
               /* When actual size is known at link-time, this will be
                * replaced with a constant expression.
                */
               result = new (ctx)
                  ir_expression(ir_unop_implicitly_sized_array_length, op);
            }
         } else {
            result = new(ctx) ir_constant(glsl_array_size(op->type));
         }
      } else if (glsl_type_is_vector(op->type)) {
         if (state->has_420pack()) {
            /* .length() returns int. */
            result = new(ctx) ir_constant((int) op->type->vector_elements);
         } else {
            _mesa_glsl_error(&loc, state, "length method on matrix only"
                             " available with ARB_shading_language_420pack");
            goto fail;
         }
      } else if (glsl_type_is_matrix(op->type)) {
         if (state->has_420pack()) {
            /* .length() returns int. */
            result = new(ctx) ir_constant((int) op->type->matrix_columns);
         } else {
            _mesa_glsl_error(&loc, state, "length method on matrix only"
                             " available with ARB_shading_language_420pack");
            goto fail;
         }
      } else {
         _mesa_glsl_error(&loc, state, "length called on scalar.");
         goto fail;
      }
   } else {
      _mesa_glsl_error(&loc, state, "unknown method: `%s'", method);
      goto fail;
   }
   return result;
 fail:
   return ir_rvalue::error_value(ctx);
}

static inline bool is_valid_constructor(const glsl_type *type,
                                        struct _mesa_glsl_parse_state *state)
{
   return glsl_type_is_numeric(type) || glsl_type_is_boolean(type) ||
          (state->has_bindless() && (glsl_type_is_sampler(type) || glsl_type_is_image(type)));
}

ir_rvalue *
ast_function_expression::hir(exec_list *instructions,
                             struct _mesa_glsl_parse_state *state)
{
   void *ctx = state;
   /* There are three sorts of function calls.
    *
    * 1. constructors - The first subexpression is an ast_type_specifier.
    * 2. methods - Only the .length() method of array types.
    * 3. functions - Calls to regular old functions.
    *
    */
   if (is_constructor()) {
      const ast_type_specifier *type =
         (ast_type_specifier *) subexpressions[0];
      YYLTYPE loc = type->get_location();
      const char *name;

      const glsl_type *const constructor_type = type->glsl_type(& name, state);

      /* constructor_type can be NULL if a variable with the same name as the
       * structure has come into scope.
       */
      if (constructor_type == NULL) {
         _mesa_glsl_error(& loc, state, "unknown type `%s' (structure name "
                          "may be shadowed by a variable with the same name)",
                          type->type_name);
         return ir_rvalue::error_value(ctx);
      }


      /* Constructors for opaque types are illegal.
       *
       * From section 4.1.7 of the ARB_bindless_texture spec:
       *
       * "Samplers are represented using 64-bit integer handles, and may be "
       *  converted to and from 64-bit integers using constructors."
       *
       * From section 4.1.X of the ARB_bindless_texture spec:
       *
       * "Images are represented using 64-bit integer handles, and may be
       *  converted to and from 64-bit integers using constructors."
       */
      if (glsl_contains_atomic(constructor_type) ||
          (!state->has_bindless() && glsl_contains_opaque(constructor_type))) {
         _mesa_glsl_error(& loc, state, "cannot construct %s type `%s'",
                          state->has_bindless() ? "atomic" : "opaque",
                          glsl_get_type_name(constructor_type));
         return ir_rvalue::error_value(ctx);
      }

      if (glsl_type_is_subroutine(constructor_type)) {
         _mesa_glsl_error(& loc, state,
                          "subroutine name cannot be a constructor `%s'",
                          glsl_get_type_name(constructor_type));
         return ir_rvalue::error_value(ctx);
      }

      if (glsl_type_is_array(constructor_type)) {
         if (!state->check_version(state->allow_glsl_120_subset_in_110 ? 110 : 120,
                                   300, &loc, "array constructors forbidden")) {
            return ir_rvalue::error_value(ctx);
         }

         return process_array_constructor(instructions, constructor_type,
                                          & loc, &this->expressions, state);
      }


      /* There are two kinds of constructor calls.  Constructors for arrays and
       * structures must have the exact number of arguments with matching types
       * in the correct order.  These constructors follow essentially the same
       * type matching rules as functions.
       *
       * Constructors for built-in language types, such as mat4 and vec2, are
       * free form.  The only requirements are that the parameters must provide
       * enough values of the correct scalar type and that no arguments are
       * given past the last used argument.
       *
       * When using the C-style initializer syntax from GLSL 4.20, constructors
       * must have the exact number of arguments with matching types in the
       * correct order.
       */
      if (glsl_type_is_struct(constructor_type)) {
         return process_record_constructor(instructions, constructor_type,
                                           &loc, &this->expressions,
                                           state);
      }

      if (!is_valid_constructor(constructor_type, state))
         return ir_rvalue::error_value(ctx);

      /* Total number of components of the type being constructed. */
      const unsigned type_components = glsl_get_components(constructor_type);

      /* Number of components from parameters that have actually been
       * consumed.  This is used to perform several kinds of error checking.
       */
      unsigned components_used = 0;

      unsigned matrix_parameters = 0;
      unsigned nonmatrix_parameters = 0;
      exec_list actual_parameters;

      foreach_list_typed(ast_node, ast, link, &this->expressions) {
         ir_rvalue *result = ast->hir(instructions, state);

         /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec:
          *
          *    "It is an error to provide extra arguments beyond this
          *    last used argument."
          */
         if (components_used >= type_components) {
            _mesa_glsl_error(& loc, state, "too many parameters to `%s' "
                             "constructor",
                             glsl_get_type_name(constructor_type));
            return ir_rvalue::error_value(ctx);
         }

         if (!is_valid_constructor(result->type, state)) {
            _mesa_glsl_error(& loc, state, "cannot construct `%s' from a "
                             "non-numeric data type",
                             glsl_get_type_name(constructor_type));
            return ir_rvalue::error_value(ctx);
         }

         /* Count the number of matrix and nonmatrix parameters.  This
          * is used below to enforce some of the constructor rules.
          */
         if (glsl_type_is_matrix(result->type))
            matrix_parameters++;
         else
            nonmatrix_parameters++;

         actual_parameters.push_tail(result);
         components_used += glsl_get_components(result->type);
      }

      /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec:
       *
       *    "It is an error to construct matrices from other matrices. This
       *    is reserved for future use."
       */
      if (matrix_parameters > 0
          && glsl_type_is_matrix(constructor_type)
          && !state->check_version(120, 100, &loc,
                                   "cannot construct `%s' from a matrix",
                                   glsl_get_type_name(constructor_type))) {
         return ir_rvalue::error_value(ctx);
      }

      /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec:
       *
       *    "If a matrix argument is given to a matrix constructor, it is
       *    an error to have any other arguments."
       */
      if ((matrix_parameters > 0)
          && ((matrix_parameters + nonmatrix_parameters) > 1)
          && glsl_type_is_matrix(constructor_type)) {
         _mesa_glsl_error(& loc, state, "for matrix `%s' constructor, "
                          "matrix must be only parameter",
                          glsl_get_type_name(constructor_type));
         return ir_rvalue::error_value(ctx);
      }

      /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec:
       *
       *    "In these cases, there must be enough components provided in the
       *    arguments to provide an initializer for every component in the
       *    constructed value."
       */
      if (components_used < type_components && components_used != 1
          && matrix_parameters == 0) {
         _mesa_glsl_error(& loc, state, "too few components to construct "
                          "`%s'",
                          glsl_get_type_name(constructor_type));
         return ir_rvalue::error_value(ctx);
      }

      /* Matrices can never be consumed as is by any constructor but matrix
       * constructors. If the constructor type is not matrix, always break the
       * matrix up into a series of column vectors.
       */
      if (!glsl_type_is_matrix(constructor_type)) {
         foreach_in_list_safe(ir_rvalue, matrix, &actual_parameters) {
            if (!glsl_type_is_matrix(matrix->type))
               continue;

            /* Create a temporary containing the matrix. */
            ir_variable *var = new(ctx) ir_variable(matrix->type, "matrix_tmp",
                                                    ir_var_temporary);
            instructions->push_tail(var);
            instructions->push_tail(
               new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
                                      matrix));
            var->constant_value = matrix->constant_expression_value(ctx);

            /* Replace the matrix with dereferences of its columns. */
            for (int i = 0; i < matrix->type->matrix_columns; i++) {
               matrix->insert_before(
                  new (ctx) ir_dereference_array(var,
                                                 new(ctx) ir_constant(i)));
            }
            matrix->remove();
         }
      }

      bool all_parameters_are_constant = true;

      /* Type cast each parameter and, if possible, fold constants.*/
      foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) {
         const glsl_type *desired_type;

         /* From section 5.4.1 of the ARB_bindless_texture spec:
          *
          * "In the following four constructors, the low 32 bits of the sampler
          *  type correspond to the .x component of the uvec2 and the high 32
          *  bits correspond to the .y component."
          *
          *  uvec2(any sampler type)     // Converts a sampler type to a
          *                              //   pair of 32-bit unsigned integers
          *  any sampler type(uvec2)     // Converts a pair of 32-bit unsigned integers to
          *                              //   a sampler type
          *  uvec2(any image type)       // Converts an image type to a
          *                              //   pair of 32-bit unsigned integers
          *  any image type(uvec2)       // Converts a pair of 32-bit unsigned integers to
          *                              //   an image type
          */
         if (glsl_type_is_sampler(ir->type) || glsl_type_is_image(ir->type)) {
            /* Convert a sampler/image type to a pair of 32-bit unsigned
             * integers as defined by ARB_bindless_texture.
             */
            if (constructor_type != &glsl_type_builtin_uvec2) {
               _mesa_glsl_error(&loc, state, "sampler and image types can only "
                                "be converted to a pair of 32-bit unsigned "
                                "integers");
            }
            desired_type = &glsl_type_builtin_uvec2;
         } else if (glsl_type_is_sampler(constructor_type) ||
                    glsl_type_is_image(constructor_type)) {
            /* Convert a pair of 32-bit unsigned integers to a sampler or image
             * type as defined by ARB_bindless_texture.
             */
            if (ir->type != &glsl_type_builtin_uvec2) {
               _mesa_glsl_error(&loc, state, "sampler and image types can only "
                                "be converted from a pair of 32-bit unsigned "
                                "integers");
            }
            desired_type = constructor_type;
         } else {
            desired_type =
               glsl_simple_type(constructor_type->base_type,
                                ir->type->vector_elements,
                                ir->type->matrix_columns);
         }

         ir_rvalue *result = convert_component(ir, desired_type);

         /* If the bindless packing constructors are used directly as function
          * params to bultin functions the compiler doesn't know what to do
          * with them. To avoid this make sure we always copy the results from
          * the pack to a temp first.
          */
         if (result->as_expression() &&
             result->as_expression()->operation == ir_unop_pack_sampler_2x32) {
            ir_variable *var =
               new(ctx) ir_variable(desired_type, "sampler_ctor",
                                    ir_var_temporary);
            instructions->push_tail(var);

            ir_dereference *lhs = new(ctx) ir_dereference_variable(var);
            ir_instruction *assignment = new(ctx) ir_assignment(lhs, result);
            instructions->push_tail(assignment);
            result = new(ctx) ir_dereference_variable(var);
         }

         /* Attempt to convert the parameter to a constant valued expression.
          * After doing so, track whether or not all the parameters to the
          * constructor are trivially constant valued expressions.
          */
         ir_rvalue *const constant = result->constant_expression_value(ctx);

         if (constant != NULL)
            result = constant;
         else
            all_parameters_are_constant = false;

         if (result != ir) {
            ir->replace_with(result);
         }
      }

      /* If all of the parameters are trivially constant, create a
       * constant representing the complete collection of parameters.
       */
      if (all_parameters_are_constant) {
         return new(ctx) ir_constant(constructor_type, &actual_parameters);
      } else if (glsl_type_is_scalar(constructor_type)) {
         return dereference_component((ir_rvalue *)
                                      actual_parameters.get_head_raw(),
                                      0);
      } else if (glsl_type_is_vector(constructor_type)) {
         return emit_inline_vector_constructor(constructor_type,
                                               instructions,
                                               &actual_parameters,
                                               ctx);
      } else {
         assert(glsl_type_is_matrix(constructor_type));
         return emit_inline_matrix_constructor(constructor_type,
                                               instructions,
                                               &actual_parameters,
                                               ctx);
      }
   } else if (subexpressions[0]->oper == ast_field_selection) {
      return handle_method(instructions, state);
   } else {
      const ast_expression *id = subexpressions[0];
      const char *func_name = NULL;
      YYLTYPE loc = get_location();
      exec_list actual_parameters;
      ir_variable *sub_var = NULL;
      ir_rvalue *array_idx = NULL;

      process_parameters(instructions, &actual_parameters, &this->expressions,
                         state);

      if (id->oper == ast_array_index) {
         array_idx = generate_array_index(ctx, instructions, state, loc,
                                          id->subexpressions[0],
                                          id->subexpressions[1], &func_name,
                                          &actual_parameters);
      } else if (id->oper == ast_identifier) {
         func_name = id->primary_expression.identifier;
      } else {
         _mesa_glsl_error(&loc, state, "function name is not an identifier");
      }

      /* an error was emitted earlier */
      if (!func_name)
         return ir_rvalue::error_value(ctx);

      ir_function_signature *sig =
         match_function_by_name(func_name, &actual_parameters, state);

      ir_rvalue *value = NULL;
      if (sig == NULL) {
         sig = match_subroutine_by_name(func_name, &actual_parameters,
                                        state, &sub_var);
      }

      if (sig == NULL) {
         no_matching_function_error(func_name, &loc,
                                    &actual_parameters, state);
         value = ir_rvalue::error_value(ctx);
      } else if (!verify_parameter_modes(state, sig,
                                         actual_parameters,
                                         this->expressions)) {
         /* an error has already been emitted */
         value = ir_rvalue::error_value(ctx);
      } else if (sig->is_builtin() && strcmp(func_name, "ftransform") == 0) {
         /* ftransform refers to global variables, and we don't have any code
          * for remapping the variable references in the built-in shader.
          */
         ir_variable *mvp =
            state->symbols->get_variable("gl_ModelViewProjectionMatrix");
         ir_variable *vtx = state->symbols->get_variable("gl_Vertex");
         value = new(ctx) ir_expression(ir_binop_mul, &glsl_type_builtin_vec4,
                                        new(ctx) ir_dereference_variable(mvp),
                                        new(ctx) ir_dereference_variable(vtx));
      } else {
         bool is_begin_interlock = false;
         bool is_end_interlock = false;
         if (sig->is_builtin() &&
             state->stage == MESA_SHADER_FRAGMENT &&
             state->ARB_fragment_shader_interlock_enable) {
            is_begin_interlock = strcmp(func_name, "beginInvocationInterlockARB") == 0;
            is_end_interlock = strcmp(func_name, "endInvocationInterlockARB") == 0;
         }

         if (sig->is_builtin() &&
             ((state->stage == MESA_SHADER_TESS_CTRL &&
               strcmp(func_name, "barrier") == 0) ||
              is_begin_interlock || is_end_interlock)) {
            if (state->current_function == NULL ||
                strcmp(state->current_function->function_name(), "main") != 0) {
               _mesa_glsl_error(&loc, state,
                                "%s() may only be used in main()", func_name);
            }

            if (state->found_return) {
               _mesa_glsl_error(&loc, state,
                                "%s() may not be used after return", func_name);
            }

            if (instructions != &state->current_function->body) {
               _mesa_glsl_error(&loc, state,
                                "%s() may not be used in control flow", func_name);
            }
         }

         /* There can be only one begin/end interlock pair in the function. */
         if (is_begin_interlock) {
            if (state->found_begin_interlock)
               _mesa_glsl_error(&loc, state,
                                "beginInvocationInterlockARB may not be used twice");
            state->found_begin_interlock = true;
         } else if (is_end_interlock) {
            if (!state->found_begin_interlock)
               _mesa_glsl_error(&loc, state,
                                "endInvocationInterlockARB may not be used "
                                "before beginInvocationInterlockARB");
            if (state->found_end_interlock)
               _mesa_glsl_error(&loc, state,
                                "endInvocationInterlockARB may not be used twice");
            state->found_end_interlock = true;
         }

         value = generate_call(instructions, sig, &actual_parameters, sub_var,
                               array_idx, state);
         if (!value) {
            ir_variable *const tmp = new(ctx) ir_variable(&glsl_type_builtin_void,
                                                          "void_var",
                                                          ir_var_temporary);
            instructions->push_tail(tmp);
            value = new(ctx) ir_dereference_variable(tmp);
         }
      }

      return value;
   }

   unreachable("not reached");
}

bool
ast_function_expression::has_sequence_subexpression() const
{
   foreach_list_typed(const ast_node, ast, link, &this->expressions) {
      if (ast->has_sequence_subexpression())
         return true;
   }

   return false;
}

ir_rvalue *
ast_aggregate_initializer::hir(exec_list *instructions,
                               struct _mesa_glsl_parse_state *state)
{
   void *ctx = state;
   YYLTYPE loc = this->get_location();

   if (!this->constructor_type) {
      _mesa_glsl_error(&loc, state, "type of C-style initializer unknown");
      return ir_rvalue::error_value(ctx);
   }
   const glsl_type *const constructor_type = this->constructor_type;

   if (!state->has_420pack()) {
      _mesa_glsl_error(&loc, state, "C-style initialization requires the "
                       "GL_ARB_shading_language_420pack extension");
      return ir_rvalue::error_value(ctx);
   }

   if (glsl_type_is_array(constructor_type)) {
      return process_array_constructor(instructions, constructor_type, &loc,
                                       &this->expressions, state);
   }

   if (glsl_type_is_struct(constructor_type)) {
      return process_record_constructor(instructions, constructor_type, &loc,
                                        &this->expressions, state);
   }

   return process_vec_mat_constructor(instructions, constructor_type, &loc,
                                      &this->expressions, state);
}
