diff options
author | Jason Merrill <jason@casey.cygnus.com> | 2000-02-27 06:54:04 +0000 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2000-02-27 01:54:04 -0500 |
commit | aa52c1ffad50ffe721a19a816f474c56958b1d3a (patch) | |
tree | c1ebb4b0526c7af728ba50f410f9d903a12a083e /gcc/cp/class.c | |
parent | 0172e2bc87664db2dead8bd8e4157a3343bce72e (diff) | |
download | gcc-aa52c1ffad50ffe721a19a816f474c56958b1d3a.zip gcc-aa52c1ffad50ffe721a19a816f474c56958b1d3a.tar.gz gcc-aa52c1ffad50ffe721a19a816f474c56958b1d3a.tar.bz2 |
Implement class scope using-declarations for functions.
* class.c (handle_using_decl): Call add_method for used functions.
Use IDENTIFIER_CLASS_VALUE to check for conflicts.
(add_method): Used functions are hidden by local functions.
(check_bases_and_members): Handle using-decls before finalizing
CLASSTYPE_METHOD_VEC.
* call.c (add_function_candidate): Add ctype parm; if non-zero,
override the type of 'this' accordingly.
(add_template_candidate, add_template_candidate_real): Add ctype parm.
(convert_class_to_reference, build_user_type_conversion_1,
build_new_function_call, build_object_call, build_new_op,
build_new_method_call): Pass ctype parm.
* search.c (lookup_member): Put rval_binfo, not basetype_path, in
the baselink.
* call.c (convert_class_to_reference, build_user_type_conversion_1,
build_new_function_call, build_object_call, build_new_op,
build_new_method_call, build_op_delete_call): Don't get basetype_path
from a baselink.
* typeck.c (build_component_ref): Likewise.
* init.c (build_offset_ref): Likewise.
(resolve_offset_ref): Don't call enforce_access.
Call build_scoped_ref.
* typeck2.c (build_scoped_ref): Simplify. Do nothing if it
would cause an error or if -pedantic.
* class.c (alter_access): Lose binfo parm.
From-SVN: r32212
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r-- | gcc/cp/class.c | 132 |
1 files changed, 64 insertions, 68 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c index ce3c2e8..d186027 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -91,7 +91,7 @@ static void add_virtual_function PARAMS ((tree *, tree *, int *, tree, tree)); static tree delete_duplicate_fields_1 PARAMS ((tree, tree)); static void delete_duplicate_fields PARAMS ((tree)); static void finish_struct_bits PARAMS ((tree)); -static int alter_access PARAMS ((tree, tree, tree, tree)); +static int alter_access PARAMS ((tree, tree, tree)); static void handle_using_decl PARAMS ((tree, tree)); static int overrides PARAMS ((tree, tree)); static int strictly_overrides PARAMS ((tree, tree)); @@ -1441,8 +1441,7 @@ void add_method (type, fields, method) tree type, *fields, method; { - /* Setting the DECL_CONTEXT here is probably redundant. */ - DECL_CONTEXT (method) = type; + int using = (DECL_CONTEXT (method) != type); if (fields && *fields) *fields = build_overload (method, *fields); @@ -1558,20 +1557,27 @@ add_method (type, fields, method) same name and the same parameter types cannot be overloaded if any of them is a static member function declaration. */ - if (DECL_STATIC_FUNCTION_P (fn) - != DECL_STATIC_FUNCTION_P (method)) + if ((DECL_STATIC_FUNCTION_P (fn) + != DECL_STATIC_FUNCTION_P (method)) + || using) { tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn)); tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (method)); if (! DECL_STATIC_FUNCTION_P (fn)) parms1 = TREE_CHAIN (parms1); - else + if (! DECL_STATIC_FUNCTION_P (method)) parms2 = TREE_CHAIN (parms2); if (compparms (parms1, parms2)) - cp_error ("`%#D' and `%#D' cannot be overloaded", - fn, method); + { + if (using) + /* Defer to the local function. */ + return; + else + cp_error ("`%#D' and `%#D' cannot be overloaded", + fn, method); + } } /* Since this is an ordinary function in a @@ -1715,14 +1721,12 @@ delete_duplicate_fields (fields) TREE_CHAIN (x) = delete_duplicate_fields_1 (x, TREE_CHAIN (x)); } -/* Change the access of FDECL to ACCESS in T. The access to FDECL is - along the path given by BINFO. Return 1 if change was legit, - otherwise return 0. */ +/* Change the access of FDECL to ACCESS in T. Return 1 if change was + legit, otherwise return 0. */ static int -alter_access (t, binfo, fdecl, access) +alter_access (t, fdecl, access) tree t; - tree binfo; tree fdecl; tree access; { @@ -1746,7 +1750,7 @@ alter_access (t, binfo, fdecl, access) } else { - enforce_access (binfo, fdecl); + enforce_access (t, fdecl); DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl)); return 1; } @@ -1768,11 +1772,7 @@ handle_using_decl (using_decl, t) : access_public_node; tree fdecl, binfo; tree flist = NULL_TREE; - tree fields = TYPE_FIELDS (t); - tree method_vec = CLASSTYPE_METHOD_VEC (t); - tree tmp; - int i; - int n_methods; + tree old_value; binfo = binfo_or_else (ctype, t); if (! binfo) @@ -1793,57 +1793,58 @@ handle_using_decl (using_decl, t) return; } - /* Functions are represented as TREE_LIST, with the purpose - being the type and the value the functions. Other members - come as themselves. */ - if (TREE_CODE (fdecl) == TREE_LIST) + if (BASELINK_P (fdecl)) /* Ignore base type this came from. */ fdecl = TREE_VALUE (fdecl); - if (TREE_CODE (fdecl) == OVERLOAD) + old_value = IDENTIFIER_CLASS_VALUE (name); + if (old_value) { - /* We later iterate over all functions. */ - flist = fdecl; - fdecl = OVL_FUNCTION (flist); + if (is_overloaded_fn (old_value)) + old_value = OVL_CURRENT (old_value); + + if (DECL_P (old_value) && DECL_CONTEXT (old_value) == t) + /* OK */; + else + old_value = NULL_TREE; } - - name = DECL_NAME (fdecl); - n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0; - for (i = 2; i < n_methods && TREE_VEC_ELT (method_vec, i); i++) - if (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i))) - == name) - { - cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t); - cp_error_at (" because of local method `%#D' with same name", - OVL_CURRENT (TREE_VEC_ELT (method_vec, i))); - return; - } - if (! DECL_LANG_SPECIFIC (fdecl)) - /* We don't currently handle DECL_ACCESS for TYPE_DECLs; just return. */ - return; - - for (tmp = fields; tmp; tmp = TREE_CHAIN (tmp)) - if (DECL_NAME (tmp) == name) - { - cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t); - cp_error_at (" because of local field `%#D' with same name", tmp); - return; - } - - /* Make type T see field decl FDECL with access ACCESS.*/ - if (flist) + if (is_overloaded_fn (fdecl)) + flist = fdecl; + else if (! DECL_LANG_SPECIFIC (fdecl)) + my_friendly_abort (20000221); + + if (! old_value) + ; + else if (is_overloaded_fn (old_value)) { - while (flist) + if (flist) + /* It's OK to use functions from a base when there are functions with + the same name already present in the current class. */; + else { - if (alter_access (t, binfo, OVL_FUNCTION (flist), - access) == 0) - return; - flist = OVL_CHAIN (flist); + cp_error ("`%D' invalid in `%#T'", using_decl, t); + cp_error_at (" because of local method `%#D' with same name", + OVL_CURRENT (old_value)); + return; } } else - alter_access (t, binfo, fdecl, access); + { + cp_error ("`%D' invalid in `%#T'", using_decl, t); + cp_error_at (" because of local field `%#D' with same name", old_value); + return; + } + + /* Make type T see field decl FDECL with access ACCESS.*/ + if (flist) + for (; flist; flist = OVL_NEXT (flist)) + { + add_method (t, 0, OVL_CURRENT (flist)); + alter_access (t, OVL_CURRENT (flist), access); + } + else + alter_access (t, fdecl, access); } /* Run through the base clases of T, updating @@ -4413,17 +4414,12 @@ check_bases_and_members (t, empty_p) cant_have_const_ctor, no_const_asn_ref); + /* Process the using-declarations. */ + for (; access_decls; access_decls = TREE_CHAIN (access_decls)) + handle_using_decl (TREE_VALUE (access_decls), t); + /* Build and sort the CLASSTYPE_METHOD_VEC. */ finish_struct_methods (t); - - /* Process the access-declarations. We wait until now to do this - because handle_using_decls requires that the CLASSTYPE_METHOD_VEC - be set up correctly. */ - while (access_decls) - { - handle_using_decl (TREE_VALUE (access_decls), t); - access_decls = TREE_CHAIN (access_decls); - } } /* If T needs a pointer to its virtual function table, set TYPE_VFIELD |