diff options
author | Nathan Sidwell <nathan@acm.org> | 2017-06-30 14:50:48 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2017-06-30 14:50:48 +0000 |
commit | fe32bb1b5bd2973305a206a29ed4c7c8749d98c5 (patch) | |
tree | fc79ce537be5fa1789fba27c6c91096f4669ec07 /gcc/cp/decl2.c | |
parent | 367e91e1c5c293da8d0999cb2bc5d8cd2c95e6b4 (diff) | |
download | gcc-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.c | 177 |
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 |