X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fglsl%2Fir_function.cpp;h=fe4209c77cce58b53f467f64c3c3339765ce2940;hb=93c8692ce92d396f0a4db5bc91d8e7322fa7dd50;hp=dd63e3078f880ea13ed6cd6cfd12d719d786408e;hpb=6efe1a849586e46028c1eb763175904166ec7076;p=mesa.git diff --git a/src/glsl/ir_function.cpp b/src/glsl/ir_function.cpp index dd63e3078f8..fe4209c77cc 100644 --- a/src/glsl/ir_function.cpp +++ b/src/glsl/ir_function.cpp @@ -24,17 +24,20 @@ #include "glsl_types.h" #include "ir.h" +typedef enum { + PARAMETER_LIST_NO_MATCH, + PARAMETER_LIST_EXACT_MATCH, + PARAMETER_LIST_INEXACT_MATCH /*< Match requires implicit conversion. */ +} parameter_list_match_t; + /** * \brief Check if two parameter lists match. * * \param list_a Parameters of the function definition. * \param list_b Actual parameters passed to the function. - * \return If an exact match, return 0. - * If an inexact match requiring implicit conversion, return 1. - * If not a match, return -1. * \see matching_signature() */ -static int +static parameter_list_match_t parameter_lists_match(const exec_list *list_a, const exec_list *list_b) { const exec_node *node_a = list_a->head; @@ -52,11 +55,11 @@ parameter_lists_match(const exec_list *list_a, const exec_list *list_b) * do not match. */ if (node_b->is_tail_sentinel()) - return -1; + return PARAMETER_LIST_NO_MATCH; const ir_variable *const param = (ir_variable *) node_a; - const ir_instruction *const actual = (ir_instruction *) node_b; + const ir_rvalue *const actual = (ir_rvalue *) node_b; if (param->type == actual->type) continue; @@ -72,29 +75,29 @@ parameter_lists_match(const exec_list *list_a, const exec_list *list_b) * as uniform. */ assert(0); - return -1; + return PARAMETER_LIST_NO_MATCH; case ir_var_const_in: - case ir_var_in: + case ir_var_function_in: if (!actual->type->can_implicitly_convert_to(param->type)) - return -1; + return PARAMETER_LIST_NO_MATCH; break; - case ir_var_out: + case ir_var_function_out: if (!param->type->can_implicitly_convert_to(actual->type)) - return -1; + return PARAMETER_LIST_NO_MATCH; break; - case ir_var_inout: + case ir_var_function_inout: /* Since there are no bi-directional automatic conversions (e.g., * there is int -> float but no float -> int), inout parameters must * be exact matches. */ - return -1; + return PARAMETER_LIST_NO_MATCH; default: assert(false); - return -1; + return PARAMETER_LIST_NO_MATCH; } } @@ -103,17 +106,25 @@ parameter_lists_match(const exec_list *list_a, const exec_list *list_b) * match. */ if (!node_b->is_tail_sentinel()) - return -1; + return PARAMETER_LIST_NO_MATCH; if (inexact_match) - return 1; + return PARAMETER_LIST_INEXACT_MATCH; else - return 0; + return PARAMETER_LIST_EXACT_MATCH; } ir_function_signature * ir_function::matching_signature(const exec_list *actual_parameters) +{ + bool is_exact; + return matching_signature(actual_parameters, &is_exact); +} + +ir_function_signature * +ir_function::matching_signature(const exec_list *actual_parameters, + bool *is_exact) { ir_function_signature *match = NULL; bool multiple_inexact_matches = false; @@ -132,18 +143,21 @@ ir_function::matching_signature(const exec_list *actual_parameters) ir_function_signature *const sig = (ir_function_signature *) iter.get(); - const int score = parameter_lists_match(& sig->parameters, - actual_parameters); - - /* If we found an exact match, simply return it */ - if (score == 0) + switch (parameter_lists_match(& sig->parameters, actual_parameters)) { + case PARAMETER_LIST_EXACT_MATCH: + *is_exact = true; return sig; - - if (score > 0) { + case PARAMETER_LIST_INEXACT_MATCH: if (match == NULL) match = sig; else multiple_inexact_matches = true; + continue; + case PARAMETER_LIST_NO_MATCH: + continue; + default: + assert(false); + return NULL; } } @@ -154,6 +168,8 @@ ir_function::matching_signature(const exec_list *actual_parameters) * FINISHME: a "no matching signature" error; it should report that the * FINISHME: call is ambiguous. But reporting errors from here is hard. */ + *is_exact = false; + if (multiple_inexact_matches) return NULL;