diff options
author | Ian Romanick <ian.d.romanick@intel.com> | 2010-06-09 17:26:20 -0700 |
---|---|---|
committer | Ian Romanick <ian.d.romanick@intel.com> | 2010-06-11 13:51:42 -0700 |
commit | ab92d0e53eab9030742e5e6d938a5739e549f16c (patch) | |
tree | e85c3d9f2ed15a68835832bd46241d8107fb69ff /ast_function.cpp | |
parent | c077131c0f4692b46afb06ab236288a24f2cfa14 (diff) |
Detect and process constant record constructors
Diffstat (limited to 'ast_function.cpp')
-rw-r--r-- | ast_function.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/ast_function.cpp b/ast_function.cpp index 889a239c6e..f0c1f0409a 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); |