From: Ian Romanick Date: Thu, 10 Jun 2010 00:26:20 +0000 (-0700) Subject: Detect and process constant record constructors X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ab92d0e53eab9030742e5e6d938a5739e549f16c;p=mesa.git Detect and process constant record constructors --- diff --git a/ast_function.cpp b/ast_function.cpp index 889a239c6e3..f0c1f0409a0 100644 --- a/ast_function.cpp +++ b/ast_function.cpp @@ -290,6 +290,50 @@ process_array_constructor(exec_list *instructions, } +/** + * Try to convert a record constructor to a constant expression + */ +static ir_constant * +constant_record_constructor(const glsl_type *constructor_type, + YYLTYPE *loc, exec_list *parameters, + struct _mesa_glsl_parse_state *state) +{ + bool all_parameters_are_constant = true; + + exec_node *node = parameters->head; + for (unsigned i = 0; i < constructor_type->length; i++) { + ir_instruction *ir = (ir_instruction *) node; + + if (node->is_tail_sentinal()) { + _mesa_glsl_error(loc, state, + "insufficient parameters to constructor for `%s'", + constructor_type->name); + return NULL; + } + + if (ir->type != constructor_type->fields.structure[i].type) { + _mesa_glsl_error(loc, state, + "parameter type mismatch in constructor for `%s' " + " (%s vs %s)", + constructor_type->name, + ir->type->name, + constructor_type->fields.structure[i].type->name); + return NULL; + } + + if (ir->as_constant() == NULL) + all_parameters_are_constant = false; + + node = node->next; + } + + if (!all_parameters_are_constant) + return NULL; + + return new ir_constant(constructor_type, parameters); +} + + ir_rvalue * ast_function_expression::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) @@ -528,6 +572,17 @@ ast_function_expression::hir(exec_list *instructions, process_parameters(instructions, &actual_parameters, &this->expressions, state); + const glsl_type *const type = + state->symbols->get_type(id->primary_expression.identifier); + + if ((type != NULL) && type->is_record()) { + ir_constant *constant = + constant_record_constructor(type, &loc, &actual_parameters, state); + + if (constant != NULL) + return constant; + } + return match_function_by_name(instructions, id->primary_expression.identifier, & loc, &actual_parameters, state);