aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl2.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/decl2.c')
-rw-r--r--gcc/cp/decl2.c177
1 files changed, 75 insertions, 102 deletions
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 08f122d..877745c 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -558,10 +558,6 @@ check_member_template (tree tmpl)
tree
check_classfn (tree ctype, tree function, tree template_parms)
{
- int ix;
- bool is_template;
- tree pushed_scope;
-
if (DECL_USE_TEMPLATE (function)
&& !(TREE_CODE (function) == TEMPLATE_DECL
&& DECL_TEMPLATE_SPECIALIZATION (function))
@@ -594,7 +590,7 @@ check_classfn (tree ctype, tree function, tree template_parms)
}
/* OK, is this a definition of a member template? */
- is_template = (template_parms != NULL_TREE);
+ bool is_template = (template_parms != NULL_TREE);
/* [temp.mem]
@@ -608,111 +604,88 @@ check_classfn (tree ctype, tree function, tree template_parms)
/* We must enter the scope here, because conversion operators are
named by target type, and type equivalence relies on typenames
resolving within the scope of CTYPE. */
- pushed_scope = push_scope (ctype);
- ix = class_method_index_for_fn (complete_type (ctype), function);
- if (ix >= 0)
- {
- vec<tree, va_gc> *methods = CLASSTYPE_METHOD_VEC (ctype);
-
- for (ovl_iterator iter ((*methods)[ix]); iter; ++iter)
- {
- tree fndecl = *iter;
- tree p1 = TYPE_ARG_TYPES (TREE_TYPE (function));
- tree 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);
-
- /* A member template definition only matches a member template
- declaration. */
- if (is_template != (TREE_CODE (fndecl) == TEMPLATE_DECL))
- continue;
-
- /* ref-qualifier or absence of same must match. */
- if (type_memfn_rqual (TREE_TYPE (function))
- != type_memfn_rqual (TREE_TYPE (fndecl)))
- continue;
-
- // Include constraints in the match.
- tree c1 = get_constraints (function);
- tree c2 = get_constraints (fndecl);
-
- /* While finding a match, same types and params are not enough
- if the function is versioned. Also check version ("target")
- attributes. */
- if (same_type_p (TREE_TYPE (TREE_TYPE (function)),
- TREE_TYPE (TREE_TYPE (fndecl)))
- && compparms (p1, p2)
- && !targetm.target_option.function_versions (function, fndecl)
- && (!is_template
- || comp_template_parms (template_parms,
- DECL_TEMPLATE_PARMS (fndecl)))
- && equivalent_constraints (c1, c2)
- && (DECL_TEMPLATE_SPECIALIZATION (function)
- == DECL_TEMPLATE_SPECIALIZATION (fndecl))
- && (!DECL_TEMPLATE_SPECIALIZATION (function)
- || (DECL_TI_TEMPLATE (function)
- == DECL_TI_TEMPLATE (fndecl))))
- {
- if (pushed_scope)
- pop_scope (pushed_scope);
- return fndecl;
- }
- }
-
- error_at (DECL_SOURCE_LOCATION (function),
- "prototype for %q#D does not match any in class %qT",
- function, ctype);
+ tree pushed_scope = push_scope (ctype);
+ tree matched = NULL_TREE;
+ tree fns = lookup_fnfields_slot (ctype, DECL_NAME (function));
+
+ for (ovl_iterator iter (fns); !matched && iter; ++iter)
+ {
+ tree fndecl = *iter;
+ tree p1 = TYPE_ARG_TYPES (TREE_TYPE (function));
+ tree 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);
+
+ /* A member template definition only matches a member template
+ declaration. */
+ if (is_template != (TREE_CODE (fndecl) == TEMPLATE_DECL))
+ continue;
- const char *format = NULL;
- tree first = OVL_FIRST ((*methods)[ix]);
- bool is_conv_op = DECL_CONV_FN_P (first);
- tree prev = NULL_TREE;
+ /* ref-qualifier or absence of same must match. */
+ if (type_memfn_rqual (TREE_TYPE (function))
+ != type_memfn_rqual (TREE_TYPE (fndecl)))
+ continue;
- if (is_conv_op)
- ix = CLASSTYPE_FIRST_CONVERSION_SLOT;
- do
- {
- ovl_iterator iter ((*methods)[ix++]);
- if (is_conv_op && !DECL_CONV_FN_P (*iter))
- break;
- for (; iter; ++iter)
- {
- if (prev)
- {
- if (!format)
- format = N_("candidates are: %+#D");
- error (format, prev);
- format = " %+#D";
- }
- prev = *iter;
- }
- }
- while (is_conv_op && size_t (ix) < methods->length ());
- if (prev)
+ // Include constraints in the match.
+ tree c1 = get_constraints (function);
+ tree c2 = get_constraints (fndecl);
+
+ /* While finding a match, same types and params are not enough
+ if the function is versioned. Also check version ("target")
+ attributes. */
+ if (same_type_p (TREE_TYPE (TREE_TYPE (function)),
+ TREE_TYPE (TREE_TYPE (fndecl)))
+ && compparms (p1, p2)
+ && !targetm.target_option.function_versions (function, fndecl)
+ && (!is_template
+ || comp_template_parms (template_parms,
+ DECL_TEMPLATE_PARMS (fndecl)))
+ && equivalent_constraints (c1, c2)
+ && (DECL_TEMPLATE_SPECIALIZATION (function)
+ == DECL_TEMPLATE_SPECIALIZATION (fndecl))
+ && (!DECL_TEMPLATE_SPECIALIZATION (function)
+ || (DECL_TI_TEMPLATE (function) == DECL_TI_TEMPLATE (fndecl))))
+ matched = fndecl;
+ }
+
+ if (!matched)
+ {
+ if (!COMPLETE_TYPE_P (ctype))
+ cxx_incomplete_type_error (function, ctype);
+ else
{
- if (!format)
- format = N_("candidate is: %+#D");
- error (format, prev);
+ if (DECL_CONV_FN_P (function))
+ fns = lookup_all_conversions (ctype);
+
+ error_at (DECL_SOURCE_LOCATION (function),
+ "no declaration matches %q#D", function);
+ if (fns)
+ print_candidates (fns);
+ else if (DECL_CONV_FN_P (function))
+ inform (DECL_SOURCE_LOCATION (function),
+ "no conversion operators declared");
+ else
+ inform (DECL_SOURCE_LOCATION (function),
+ "no functions named %qD", function);
+ inform (DECL_SOURCE_LOCATION (TYPE_NAME (ctype)),
+ "%#qT defined here", ctype);
}
+ matched = error_mark_node;
}
- else if (!COMPLETE_TYPE_P (ctype))
- cxx_incomplete_type_error (function, ctype);
- else
- error ("no %q#D member function declared in class %qT",
- function, ctype);
if (pushed_scope)
pop_scope (pushed_scope);
- return error_mark_node;
+
+ return matched;
}
/* DECL is a function with vague linkage. Remember it so that at the