check_classfn (ctype, function)
tree ctype, function;
{
- tree fn_name = DECL_NAME (function);
- tree fndecl, fndecls;
- tree method_vec = CLASSTYPE_METHOD_VEC (complete_type (ctype));
- tree *methods = 0;
- tree *end = 0;
+ int ix;
if (DECL_USE_TEMPLATE (function)
&& !(TREE_CODE (function) == TEMPLATE_DECL
reason we should, either. We let our callers know we didn't
find the method, but we don't complain. */
return NULL_TREE;
-
- if (method_vec != 0)
+
+ ix = lookup_fnfields_1 (complete_type (ctype),
+ DECL_CONSTRUCTOR_P (function) ? ctor_identifier :
+ DECL_DESTRUCTOR_P (function) ? dtor_identifier :
+ DECL_NAME (function));
+
+ if (ix >= 0)
{
- methods = &TREE_VEC_ELT (method_vec, 0);
- end = TREE_VEC_END (method_vec);
-
- /* First suss out ctors and dtors. */
- if (*methods && fn_name == DECL_NAME (OVL_CURRENT (*methods))
- && DECL_CONSTRUCTOR_P (function))
- goto got_it;
- if (*++methods && fn_name == DECL_NAME (OVL_CURRENT (*methods))
- && DECL_DESTRUCTOR_P (function))
- goto got_it;
-
- while (++methods != end && *methods)
+ tree methods = CLASSTYPE_METHOD_VEC (ctype);
+ tree fndecls, fndecl;
+ bool is_conv_op;
+ const char *format = NULL;
+
+ for (fndecls = TREE_VEC_ELT (methods, ix);
+ fndecls; fndecls = OVL_NEXT (fndecls))
+ {
+ tree p1, p2;
+
+ fndecl = OVL_CURRENT (fndecls);
+ p1 = TYPE_ARG_TYPES (TREE_TYPE (function));
+ p2 = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
+
+ /* We cannot simply call decls_match because this doesn't
+ work for static member functions that are pretending to
+ be methods, and because the name may have been changed by
+ asm("new_name"). */
+
+ /* Get rid of the this parameter on functions that become
+ static. */
+ if (DECL_STATIC_FUNCTION_P (fndecl)
+ && TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
+ p1 = TREE_CHAIN (p1);
+
+ if (same_type_p (TREE_TYPE (TREE_TYPE (function)),
+ TREE_TYPE (TREE_TYPE (fndecl)))
+ && compparms (p1, p2)
+ && (DECL_TEMPLATE_SPECIALIZATION (function)
+ == DECL_TEMPLATE_SPECIALIZATION (fndecl))
+ && (!DECL_TEMPLATE_SPECIALIZATION (function)
+ || (DECL_TI_TEMPLATE (function)
+ == DECL_TI_TEMPLATE (fndecl))))
+ return fndecl;
+ }
+ error ("prototype for `%#D' does not match any in class `%T'",
+ function, ctype);
+ is_conv_op = DECL_CONV_FN_P (fndecl);
+
+ if (is_conv_op)
+ ix = CLASSTYPE_FIRST_CONVERSION_SLOT;
+ fndecls = TREE_VEC_ELT (methods, ix);
+ while (fndecls)
{
- fndecl = *methods;
- if (fn_name == DECL_NAME (OVL_CURRENT (*methods)))
+ fndecl = OVL_CURRENT (fndecls);
+ fndecls = OVL_NEXT (fndecls);
+
+ if (!fndecls && is_conv_op)
{
- got_it:
- for (fndecls = *methods; fndecls != NULL_TREE;
- fndecls = OVL_NEXT (fndecls))
+ if (TREE_VEC_LENGTH (methods) > ix)
{
- fndecl = OVL_CURRENT (fndecls);
-
- /* We cannot simply call decls_match because this
- doesn't work for static member functions that are
- pretending to be methods, and because the name
- may have been changed by asm("new_name"). */
- if (DECL_NAME (function) == DECL_NAME (fndecl))
+ ix++;
+ fndecls = TREE_VEC_ELT (methods, ix);
+ if (!DECL_CONV_FN_P (OVL_CURRENT (fndecls)))
{
- tree p1 = TYPE_ARG_TYPES (TREE_TYPE (function));
- tree p2 = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
-
- /* Get rid of the this parameter on functions that become
- static. */
- if (DECL_STATIC_FUNCTION_P (fndecl)
- && TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
- p1 = TREE_CHAIN (p1);
-
- if (same_type_p (TREE_TYPE (TREE_TYPE (function)),
- TREE_TYPE (TREE_TYPE (fndecl)))
- && compparms (p1, p2)
- && (DECL_TEMPLATE_SPECIALIZATION (function)
- == DECL_TEMPLATE_SPECIALIZATION (fndecl))
- && (!DECL_TEMPLATE_SPECIALIZATION (function)
- || (DECL_TI_TEMPLATE (function)
- == DECL_TI_TEMPLATE (fndecl))))
- return fndecl;
+ fndecls = NULL_TREE;
+ is_conv_op = false;
}
}
- break; /* loser */
+ else
+ is_conv_op = false;
}
+ if (format)
+ format = " %#D";
+ else if (fndecls)
+ format = "candidates are: %#D";
+ else
+ format = "candidate is: %#D";
+ cp_error_at (format, fndecl);
}
}
-
- if (methods != end && *methods)
- {
- tree fndecl = *methods;
- error ("prototype for `%#D' does not match any in class `%T'",
- function, ctype);
- cp_error_at ("candidate%s: %+#D", OVL_NEXT (fndecl) ? "s are" : " is",
- OVL_CURRENT (fndecl));
- while (fndecl = OVL_NEXT (fndecl), fndecl)
- cp_error_at (" %#D", OVL_CURRENT(fndecl));
- }
+ else if (!COMPLETE_TYPE_P (ctype))
+ cxx_incomplete_type_error (function, ctype);
else
- {
- methods = 0;
- if (!COMPLETE_TYPE_P (ctype))
- cxx_incomplete_type_error (function, ctype);
- else
- error ("no `%#D' member function declared in class `%T'",
- function, ctype);
- }
+ error ("no `%#D' member function declared in class `%T'",
+ function, ctype);
/* If we did not find the method in the class, add it to avoid
spurious errors (unless the CTYPE is not yet defined, in which