Factor out parameter list matching from ast_function::hir for later reuse.
authorKenneth Graunke <kenneth@whitecape.org>
Wed, 28 Apr 2010 19:04:23 +0000 (12:04 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Wed, 28 Apr 2010 22:34:52 +0000 (15:34 -0700)
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
ir.h
ir_function.cpp

index 0e7ab1ab3a302ad0ae1a43346be326ba0f73fad6..52e372c7e493eab128922eac12b93b352a1d8e33 100644 (file)
@@ -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 b9ab25b645323d99e0db4fdd0447b05e41d8bd06..118d97ffa3cbfb50be6291e1789b1efa37f44ca3 100644 (file)
--- 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.
     */
index a8b73f1e1aa57562c107ce104e27db7838a19179..5db93f67fb8cdb5a8f3b2bcf074e69b3c6a06619 100644 (file)
@@ -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;
+}