aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl2.c
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2017-06-30 14:50:48 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2017-06-30 14:50:48 +0000
commitfe32bb1b5bd2973305a206a29ed4c7c8749d98c5 (patch)
treefc79ce537be5fa1789fba27c6c91096f4669ec07 /gcc/cp/decl2.c
parent367e91e1c5c293da8d0999cb2bc5d8cd2c95e6b4 (diff)
downloadgcc-fe32bb1b5bd2973305a206a29ed4c7c8749d98c5.zip
gcc-fe32bb1b5bd2973305a206a29ed4c7c8749d98c5.tar.gz
gcc-fe32bb1b5bd2973305a206a29ed4c7c8749d98c5.tar.bz2
cp-tree.h (lookup_fnfields_1, [...]): Don't declare.
* cp-tree.h (lookup_fnfields_1, class_method_index_for_fn): Don't declare. (lookup_all_conversions): Declare. * class.c (get_basefndecls): Use lookup_fnfields_slot. * decl.c (register_dtor_fn): Use lookup_fnfields_slot. * decl2.c (check_class_fn): Use lookup_fnfields_slot. Rework diagnostics. * pt.c (retrieve_specialization): Use lookup_fnfields_slot. (check_explicit_specialization): Use lookup_fnfields_slot_nolazy, lookup_all_conversions. * search.c (lookup_fnfields_1): Make static. (lookup_all_conversions): New. (class_method_index_for_fn): Delete. * semantics.c (classtype_has_nothrow_assign_or_copy_p): Use lookup_fnfields_slot. * g++.dg/concepts/memfun-err.C: Adjust diagnostics. * g++.dg/cpp0x/decltype9.C: Likewise. * g++.dg/cpp0x/forw_enum9.C: Likewise. * g++.dg/lookup/decl1.C: Likewise. * g++.dg/lookup/extern-c-redecl.C: Likewise. * g++.dg/other/pr28432.C: Likewise. * g++.dg/parse/crash12.C: Likewise. * g++.dg/parse/enum3.C: Likewise. * g++.dg/parse/operator6.C: Likewise. * g++.dg/template/crash69.C: Likewise. * g++.dg/template/error27.C: Likewise. * g++.dg/template/error28.C: Likewise. * g++.dg/template/memfriend6.C: Likewise. * g++.old-deja/g++.mike/err1.C: Likewise. * g++.old-deja/g++.mike/p811.C: Likewise. * g++.old-deja/g++.other/crash25.C: Likewise. * g++.old-deja/g++.other/dtor4.C: Likewise. * g++.old-deja/g++.pt/t37.C: Likewise. From-SVN: r249843
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