From 0d605cb97c9cd2f9a170e3aa15bdf4021a75fc14 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 28 Apr 2010 12:04:23 -0700 Subject: [PATCH] Factor out parameter list matching from ast_function::hir for later reuse. Unfortunately, we still have two kinds of matching - one, with implicit conversions (for use in calls) and another without them (for finding a prototype to overwrite when processing a function body). This commit does not attempt to coalesce the two. --- ast_to_hir.cpp | 79 +++++++++++-------------------------------------- ir.h | 9 +++++- ir_function.cpp | 43 +++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 63 deletions(-) diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp index 0e7ab1ab3a3..52e372c7e49 100644 --- a/ast_to_hir.cpp +++ b/ast_to_hir.cpp @@ -1883,36 +1883,6 @@ ast_parameter_declarator::parameters_to_hir(struct simple_node *ast_parameters, } -static bool -parameter_lists_match(exec_list *list_a, exec_list *list_b) -{ - exec_list_iterator iter_a = list_a->iterator(); - exec_list_iterator iter_b = list_b->iterator(); - - while (iter_a.has_next() && iter_b.has_next()) { - ir_variable *a = (ir_variable *)iter_a.get(); - ir_variable *b = (ir_variable *)iter_b.get(); - - /* If the types of the parameters do not match, the parameters lists - * are different. - */ - if (a->type != b->type) - return false; - - iter_a.next(); - iter_b.next(); - } - - /* Unless both lists are exhausted, they differ in length and, by - * definition, do not match. - */ - if (iter_a.has_next() != iter_b.has_next()) - return false; - - return true; -} - - ir_rvalue * ast_function::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) @@ -1943,45 +1913,30 @@ ast_function::hir(exec_list *instructions, const char *const name = identifier; f = state->symbols->get_function(name); if (f != NULL) { - foreach_iter(exec_list_iterator, iter, *f) { - sig = (struct ir_function_signature *) iter.get(); - - /* Compare the parameter list of the function being defined to the - * existing function. If the parameter lists match, then the return - * type must also match and the existing function must not have a - * definition. - */ - if (parameter_lists_match(& hir_parameters, & sig->parameters)) { - const char *mismatch = sig->qualifiers_match(&hir_parameters); - if (mismatch != NULL) { - YYLTYPE loc = this->get_location(); + ir_function_signature *sig = f->exact_matching_signature(&hir_parameters); + if (sig != NULL) { + const char *badvar = sig->qualifiers_match(&hir_parameters); + if (badvar != NULL) { + YYLTYPE loc = this->get_location(); - _mesa_glsl_error(&loc, state, "function `%s' parameter `%s' " - "qualifiers don't match prototype", - name, mismatch); - } + _mesa_glsl_error(&loc, state, "function `%s' parameter `%s' " + "qualifiers don't match prototype", name, badvar); + } - if (sig->return_type != return_type) { - YYLTYPE loc = this->get_location(); + if (sig->return_type != return_type) { + YYLTYPE loc = this->get_location(); - _mesa_glsl_error(& loc, state, - "function `%s' return type doesn't match " - "prototype", - name); - } + _mesa_glsl_error(&loc, state, "function `%s' return type doesn't " + "match prototype", name); + } - if (is_definition && sig->is_defined) { - YYLTYPE loc = this->get_location(); + if (is_definition && sig->is_defined) { + YYLTYPE loc = this->get_location(); - _mesa_glsl_error(& loc, state, "function `%s' redefined", name); - sig = NULL; - break; - } + _mesa_glsl_error(& loc, state, "function `%s' redefined", name); + sig = NULL; } - - sig = NULL; } - } else if (state->symbols->name_declared_this_scope(name)) { /* This function name shadows a non-function use of the same name. */ diff --git a/ir.h b/ir.h index b9ab25b6453..118d97ffa3c 100644 --- a/ir.h +++ b/ir.h @@ -276,10 +276,17 @@ public: } /** - * Find a signature that matches a set of actual parameters. + * Find a signature that matches a set of actual parameters, taking implicit + * conversions into account. */ const ir_function_signature *matching_signature(exec_list *actual_param); + /** + * Find a signature that exactly matches a set of actual parameters without + * any implicit type conversions. + */ + ir_function_signature *exact_matching_signature(exec_list *actual_ps); + /** * Name of the function. */ diff --git a/ir_function.cpp b/ir_function.cpp index a8b73f1e1aa..5db93f67fb8 100644 --- a/ir_function.cpp +++ b/ir_function.cpp @@ -180,3 +180,46 @@ ir_function::matching_signature(exec_list *actual_parameters) return match; } + + +static bool +parameter_lists_match_exact(exec_list *list_a, exec_list *list_b) +{ + exec_list_iterator iter_a = list_a->iterator(); + exec_list_iterator iter_b = list_b->iterator(); + + while (iter_a.has_next() && iter_b.has_next()) { + ir_variable *a = (ir_variable *)iter_a.get(); + ir_variable *b = (ir_variable *)iter_b.get(); + + /* If the types of the parameters do not match, the parameters lists + * are different. + */ + if (a->type != b->type) + return false; + + iter_a.next(); + iter_b.next(); + } + + /* Unless both lists are exhausted, they differ in length and, by + * definition, do not match. + */ + if (iter_a.has_next() != iter_b.has_next()) + return false; + + return true; +} + +ir_function_signature * +ir_function::exact_matching_signature(exec_list *actual_parameters) +{ + foreach_iter(exec_list_iterator, iter, signatures) { + ir_function_signature *const sig = + (ir_function_signature *) iter.get(); + + if (parameter_lists_match_exact(&sig->parameters, actual_parameters)) + return sig; + } + return NULL; +} -- 2.30.2