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 | |
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
-rw-r--r-- | gcc/cp/ChangeLog | 29 | ||||
-rw-r--r-- | gcc/cp/call.c | 137 | ||||
-rw-r--r-- | gcc/cp/class.c | 132 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 10 | ||||
-rw-r--r-- | gcc/cp/init.c | 35 | ||||
-rw-r--r-- | gcc/cp/search.c | 10 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 5 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 48 |
8 files changed, 205 insertions, 201 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index af946b3..f5c9bcf 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,32 @@ +2000-02-26 Jason Merrill <jason@casey.cygnus.com> + + 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. + 2000-02-26 Mark Mitchell <mark@codesourcery.com> * semantics.c (simplify_aggr_init_exprs_p): Don't walk into diff --git a/gcc/cp/call.c b/gcc/cp/call.c index f672c96..8ced478 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -61,10 +61,10 @@ static tree build_this PARAMS ((tree)); static struct z_candidate * splice_viable PARAMS ((struct z_candidate *)); static int any_viable PARAMS ((struct z_candidate *)); static struct z_candidate * add_template_candidate - PARAMS ((struct z_candidate *, tree, tree, tree, tree, int, + PARAMS ((struct z_candidate *, tree, tree, tree, tree, tree, int, unification_kind_t)); static struct z_candidate * add_template_candidate_real - PARAMS ((struct z_candidate *, tree, tree, tree, tree, int, + PARAMS ((struct z_candidate *, tree, tree, tree, tree, tree, int, tree, unification_kind_t)); static struct z_candidate * add_template_conv_candidate PARAMS ((struct z_candidate *, tree, tree, tree, tree)); @@ -81,7 +81,7 @@ static struct z_candidate * build_builtin_candidate static struct z_candidate * add_conv_candidate PARAMS ((struct z_candidate *, tree, tree, tree)); static struct z_candidate * add_function_candidate - PARAMS ((struct z_candidate *, tree, tree, int)); + PARAMS ((struct z_candidate *, tree, tree, tree, int)); static tree implicit_conversion PARAMS ((tree, tree, tree, int)); static tree standard_conversion PARAMS ((tree, tree, tree)); static tree reference_binding PARAMS ((tree, tree, tree, int)); @@ -91,7 +91,7 @@ static int is_subseq PARAMS ((tree, tree)); static int maybe_handle_ref_bind PARAMS ((tree*, tree*)); static void maybe_handle_implicit_object PARAMS ((tree*)); static struct z_candidate * add_candidate PARAMS ((struct z_candidate *, - tree, tree, int)); + tree, tree, int)); static tree source_type PARAMS ((tree)); static void add_warning PARAMS ((struct z_candidate *, struct z_candidate *)); static int reference_related_p PARAMS ((tree, tree)); @@ -879,7 +879,7 @@ convert_class_to_reference (t, s, expr) { tree fns = TREE_VALUE (conversions); - while (fns) + for (; fns; fns = OVL_NEXT (fns)) { tree f = OVL_CURRENT (fns); tree t2 = TREE_TYPE (TREE_TYPE (f)); @@ -891,7 +891,7 @@ convert_class_to_reference (t, s, expr) { candidates = add_template_candidate (candidates, - f, + f, s, NULL_TREE, arglist, build_reference_type (t), @@ -914,13 +914,11 @@ convert_class_to_reference (t, s, expr) else if (TREE_CODE (t2) == REFERENCE_TYPE && reference_compatible_p (t, TREE_TYPE (t2))) candidates - = add_function_candidate (candidates, f, arglist, + = add_function_candidate (candidates, f, s, arglist, LOOKUP_NORMAL); if (candidates != old_candidates) - candidates->basetype_path = TREE_PURPOSE (conversions); - - fns = OVL_NEXT (fns); + candidates->basetype_path = TYPE_BINFO (s); } } @@ -1235,12 +1233,15 @@ add_candidate (candidates, fn, convs, viable) /* Create an overload candidate for the function or method FN called with the argument list ARGLIST and add it to CANDIDATES. FLAGS is passed on - to implicit_conversion. */ + to implicit_conversion. + + CTYPE, if non-NULL, is the type we want to pretend this function + comes from for purposes of overload resolution. */ static struct z_candidate * -add_function_candidate (candidates, fn, arglist, flags) +add_function_candidate (candidates, fn, ctype, arglist, flags) struct z_candidate *candidates; - tree fn, arglist; + tree fn, ctype, arglist; int flags; { tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn)); @@ -1307,25 +1308,31 @@ add_function_candidate (candidates, fn, arglist, flags) tree arg = TREE_VALUE (argnode); tree argtype = lvalue_type (arg); tree t; + int is_this; if (parmnode == void_list_node) break; + is_this = (i == 0 && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn) + && ! DECL_CONSTRUCTOR_P (fn)); + if (parmnode) { tree parmtype = TREE_VALUE (parmnode); - /* [over.match.funcs] For conversion functions, the function is - considered to be a member of the class of the implicit object - argument for the purpose of defining the type of the implicit - object parameter. + /* The type of the implicit object parameter ('this') for + overload resolution is not always the same as for the + function itself; conversion functions are considered to + be members of the class being converted, and functions + introduced by a using-declaration are considered to be + members of the class that uses them. - Since build_over_call ignores the ICS for the `this' parameter, - we can just change the parm type. */ - if (DECL_CONV_FN_P (fn) && i == 0) + Since build_over_call ignores the ICS for the `this' + parameter, we can just change the parm type. */ + if (ctype && is_this) { parmtype - = build_qualified_type (TREE_TYPE (argtype), + = build_qualified_type (ctype, TYPE_QUALS (TREE_TYPE (parmtype))); parmtype = build_pointer_type (parmtype); } @@ -1338,8 +1345,7 @@ add_function_candidate (candidates, fn, arglist, flags) ICS_ELLIPSIS_FLAG (t) = 1; } - if (i == 0 && t && TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE - && ! DECL_CONSTRUCTOR_P (fn)) + if (t && is_this) ICS_THIS_FLAG (t) = 1; TREE_VEC_ELT (convs, i) = t; @@ -2090,16 +2096,16 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags) TMPL is the template. EXPLICIT_TARGS are any explicit template arguments. ARGLIST is the arguments provided at the call-site. The RETURN_TYPE is the desired type for conversion operators. If - OBJ is NULL_TREE, FLAGS are as for add_function_candidate. If an - OBJ is supplied, FLAGS are ignored, and OBJ is as for + OBJ is NULL_TREE, FLAGS and CTYPE are as for add_function_candidate. + If an OBJ is supplied, FLAGS and CTYPE are ignored, and OBJ is as for add_conv_candidate. */ static struct z_candidate* -add_template_candidate_real (candidates, tmpl, explicit_targs, +add_template_candidate_real (candidates, tmpl, ctype, explicit_targs, arglist, return_type, flags, obj, strict) struct z_candidate *candidates; - tree tmpl, explicit_targs, arglist, return_type; + tree tmpl, ctype, explicit_targs, arglist, return_type; int flags; tree obj; unification_kind_t strict; @@ -2124,7 +2130,8 @@ add_template_candidate_real (candidates, tmpl, explicit_targs, /* Aha, this is a conversion function. */ cand = add_conv_candidate (candidates, fn, obj, arglist); else - cand = add_function_candidate (candidates, fn, arglist, flags); + cand = add_function_candidate (candidates, fn, ctype, + arglist, flags); if (DECL_TI_TEMPLATE (fn) != tmpl) /* This situation can occur if a member template of a template class is specialized. Then, instantiate_template might return @@ -2152,16 +2159,16 @@ add_template_candidate_real (candidates, tmpl, explicit_targs, static struct z_candidate * -add_template_candidate (candidates, tmpl, explicit_targs, +add_template_candidate (candidates, tmpl, ctype, explicit_targs, arglist, return_type, flags, strict) struct z_candidate *candidates; - tree tmpl, explicit_targs, arglist, return_type; + tree tmpl, ctype, explicit_targs, arglist, return_type; int flags; unification_kind_t strict; { return - add_template_candidate_real (candidates, tmpl, explicit_targs, - arglist, return_type, flags, + add_template_candidate_real (candidates, tmpl, ctype, + explicit_targs, arglist, return_type, flags, NULL_TREE, strict); } @@ -2172,8 +2179,8 @@ add_template_conv_candidate (candidates, tmpl, obj, arglist, return_type) tree tmpl, obj, arglist, return_type; { return - add_template_candidate_real (candidates, tmpl, NULL_TREE, arglist, - return_type, 0, obj, DEDUCE_CONV); + add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE, + arglist, return_type, 0, obj, DEDUCE_CONV); } @@ -2290,12 +2297,12 @@ build_user_type_conversion_1 (totype, expr, flags) { templates = tree_cons (NULL_TREE, ctor, templates); candidates = - add_template_candidate (candidates, ctor, + add_template_candidate (candidates, ctor, totype, NULL_TREE, args, NULL_TREE, flags, DEDUCE_CALL); } else - candidates = add_function_candidate (candidates, ctor, + candidates = add_function_candidate (candidates, ctor, totype, args, flags); if (candidates) @@ -2336,16 +2343,23 @@ build_user_type_conversion_1 (totype, expr, flags) tree fn = OVL_CURRENT (fns); struct z_candidate *old_candidates = candidates; + /* [over.match.funcs] For conversion functions, the function is + considered to be a member of the class of the implicit object + argument for the purpose of defining the type of the implicit + object parameter. + + So we pass fromtype as CTYPE to add_*_candidate. */ + if (TREE_CODE (fn) == TEMPLATE_DECL) { templates = tree_cons (NULL_TREE, fn, templates); candidates = - add_template_candidate (candidates, fn, NULL_TREE, + add_template_candidate (candidates, fn, fromtype, NULL_TREE, args, totype, flags, DEDUCE_CONV); } else - candidates = add_function_candidate (candidates, fn, + candidates = add_function_candidate (candidates, fn, fromtype, args, flags); if (candidates != old_candidates) @@ -2356,7 +2370,7 @@ build_user_type_conversion_1 (totype, expr, flags) 0, convflags); candidates->second_conv = ics; - candidates->basetype_path = TREE_PURPOSE (convs); + candidates->basetype_path = TYPE_BINFO (fromtype); if (ics == NULL_TREE) candidates->viable = 0; @@ -2491,21 +2505,17 @@ build_new_function_call (fn, args) for (t1 = fn; t1; t1 = OVL_CHAIN (t1)) { tree t = OVL_FUNCTION (t1); - struct z_candidate *old_candidates = candidates; if (TREE_CODE (t) == TEMPLATE_DECL) { templates = tree_cons (NULL_TREE, t, templates); candidates = add_template_candidate - (candidates, t, explicit_targs, args, NULL_TREE, + (candidates, t, NULL_TREE, explicit_targs, args, NULL_TREE, LOOKUP_NORMAL, DEDUCE_CALL); } else if (! template_only) candidates = add_function_candidate - (candidates, t, args, LOOKUP_NORMAL); - - if (candidates != old_candidates) - candidates->basetype_path = CP_DECL_CONTEXT (t); + (candidates, t, NULL_TREE, args, LOOKUP_NORMAL); } if (! any_viable (candidates)) @@ -2572,7 +2582,7 @@ build_object_call (obj, args) if (fns) { - tree base = TREE_PURPOSE (fns); + tree base = BINFO_TYPE (TREE_PURPOSE (fns)); mem_args = tree_cons (NULL_TREE, build_this (obj), args); for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns)) @@ -2581,16 +2591,16 @@ build_object_call (obj, args) if (TREE_CODE (fn) == TEMPLATE_DECL) { candidates - = add_template_candidate (candidates, fn, NULL_TREE, + = add_template_candidate (candidates, fn, base, NULL_TREE, mem_args, NULL_TREE, LOOKUP_NORMAL, DEDUCE_CALL); } else candidates = add_function_candidate - (candidates, fn, mem_args, LOOKUP_NORMAL); + (candidates, fn, base, mem_args, LOOKUP_NORMAL); if (candidates) - candidates->basetype_path = base; + candidates->basetype_path = TYPE_BINFO (type); } } @@ -2617,9 +2627,6 @@ build_object_call (obj, args) } else candidates = add_conv_candidate (candidates, fn, obj, args); - - if (candidates) - candidates->basetype_path = TREE_PURPOSE (convs); } } @@ -3184,12 +3191,13 @@ build_new_op (code, flags, arg1, arg2, arg3) { templates = tree_cons (NULL_TREE, fn, templates); candidates - = add_template_candidate (candidates, fn, NULL_TREE, + = add_template_candidate (candidates, fn, NULL_TREE, NULL_TREE, arglist, TREE_TYPE (fnname), flags, DEDUCE_CALL); } else - candidates = add_function_candidate (candidates, fn, arglist, flags); + candidates = add_function_candidate (candidates, fn, NULL_TREE, + arglist, flags); } if (IS_AGGR_TYPE (TREE_TYPE (arg1))) @@ -3203,7 +3211,7 @@ build_new_op (code, flags, arg1, arg2, arg3) if (fns) { - tree basetype = TREE_PURPOSE (fns); + tree basetype = BINFO_TYPE (TREE_PURPOSE (fns)); mem_arglist = tree_cons (NULL_TREE, build_this (arg1), TREE_CHAIN (arglist)); for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns)) { @@ -3220,16 +3228,16 @@ build_new_op (code, flags, arg1, arg2, arg3) /* A member template. */ templates = tree_cons (NULL_TREE, fn, templates); candidates - = add_template_candidate (candidates, fn, NULL_TREE, + = add_template_candidate (candidates, fn, basetype, NULL_TREE, this_arglist, TREE_TYPE (fnname), flags, DEDUCE_CALL); } else candidates = add_function_candidate - (candidates, fn, this_arglist, flags); + (candidates, fn, basetype, this_arglist, flags); - if (candidates) - candidates->basetype_path = basetype; + if (candidates) + candidates->basetype_path = TYPE_BINFO (TREE_TYPE (arg1)); } } @@ -3547,7 +3555,7 @@ build_op_delete_call (code, addr, size, flags, placement) { if (TREE_CODE (fns) == TREE_LIST) /* Member functions. */ - enforce_access (TREE_PURPOSE (fns), fn); + enforce_access (type, fn); return build_function_call (fn, tree_cons (NULL_TREE, addr, args)); } @@ -3567,7 +3575,7 @@ build_op_delete_call (code, addr, size, flags, placement) { if (BASELINK_P (fns)) /* Member functions. */ - enforce_access (TREE_PURPOSE (fns), fn); + enforce_access (type, fn); return build_function_call (fn, tree_cons (NULL_TREE, addr, build_tree_list (NULL_TREE, size))); @@ -4254,6 +4262,7 @@ build_new_method_call (instance, name, args, basetype_path, flags) return error_mark_node; if (fns) { + tree base = BINFO_TYPE (TREE_PURPOSE (fns)); tree fn = TREE_VALUE (fns); if (name == ctor_identifier && TYPE_USES_VIRTUAL_BASECLASSES (basetype) && ! (flags & LOOKUP_HAS_IN_CHARGE)) @@ -4282,16 +4291,16 @@ build_new_method_call (instance, name, args, basetype_path, flags) /* A member template. */ templates = tree_cons (NULL_TREE, t, templates); candidates = - add_template_candidate (candidates, t, explicit_targs, + add_template_candidate (candidates, t, base, explicit_targs, this_arglist, TREE_TYPE (name), flags, DEDUCE_CALL); } else if (! template_only) - candidates = add_function_candidate (candidates, t, + candidates = add_function_candidate (candidates, t, base, this_arglist, flags); if (candidates) - candidates->basetype_path = TREE_PURPOSE (fns); + candidates->basetype_path = basetype_path; } } 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 diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index e2f459f..6902232 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -635,15 +635,7 @@ tree convert_pointer_to (binfo, expr) tree binfo, expr; { - tree type; - - if (TREE_CODE (binfo) == TREE_VEC) - type = BINFO_TYPE (binfo); - else if (IS_AGGR_TYPE (binfo)) - type = binfo; - else - type = binfo; - return convert_pointer_to_real (type, expr); + return convert_pointer_to_real (binfo, expr); } /* C++ conversions, preference to static cast conversions. */ diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 1c993b3..69a4e3a 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1611,8 +1611,7 @@ build_offset_ref (type, name) if (member == error_mark_node) return error_mark_node; - /* A lot of this logic is now handled in lookup_field and - lookup_fnfield. */ + /* A lot of this logic is now handled in lookup_member. */ if (member && BASELINK_P (member)) { /* Go from the TREE_BASELINK to the member function info. */ @@ -1648,7 +1647,6 @@ build_offset_ref (type, name) t = OVL_CURRENT (t); /* unique functions are handled easily. */ - basebinfo = TREE_PURPOSE (fnfields); if (!enforce_access (basebinfo, t)) return error_mark_node; mark_used (t); @@ -1776,29 +1774,24 @@ resolve_offset_ref (exp) if (TREE_CODE (member) == FIELD_DECL && (base == current_class_ref || is_dummy_object (base))) { - tree basetype_path; tree expr; + basetype = DECL_CONTEXT (member); + + /* Try to get to basetype from 'this'; if that doesn't work, + nothing will. */ + base = current_class_ref; + + /* First convert to the intermediate base specified, if appropriate. */ if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE) - basetype = TYPE_OFFSET_BASETYPE (type); - else - basetype = DECL_CONTEXT (member); + base = build_scoped_ref (base, TYPE_OFFSET_BASETYPE (type)); - base = current_class_ptr; + addr = build_unary_op (ADDR_EXPR, base, 0); + addr = convert_pointer_to (basetype, addr); + + if (addr == error_mark_node) + return error_mark_node; - if (get_base_distance (basetype, TREE_TYPE (TREE_TYPE (base)), 0, &basetype_path) < 0) - { - error_not_base_type (basetype, TREE_TYPE (TREE_TYPE (base))); - return error_mark_node; - } - /* Kludge: we need to use basetype_path now, because - convert_pointer_to will bash it. */ - enforce_access (basetype_path, member); - addr = convert_pointer_to (basetype, base); - - /* Even in the case of illegal access, we form the - COMPONENT_REF; that will allow better error recovery than - just feeding back error_mark_node. */ expr = build (COMPONENT_REF, TREE_TYPE (member), build_indirect_ref (addr, NULL_PTR), member); return convert_from_reference (expr); diff --git a/gcc/cp/search.c b/gcc/cp/search.c index e95262b..4b604eb 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1606,7 +1606,15 @@ lookup_member (xbasetype, name, protect, want_type) if (rval && is_overloaded_fn (rval)) { - rval = tree_cons (basetype_path, rval, NULL_TREE); + /* Note that the binfo we put in the baselink is the binfo where + we found the functions, which we need for overload + resolution, but which should not be passed to enforce_access; + rather, enforce_access wants a binfo which refers to the + scope in which we started looking for the function. This + will generally be the binfo passed into this function as + xbasetype. */ + + rval = tree_cons (rval_binfo, rval, NULL_TREE); SET_BASELINK_P (rval); } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 2cc4944..ae01800 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2151,7 +2151,7 @@ build_component_ref (datum, component, basetype_path, protect) if (DECL_STATIC_FUNCTION_P (TREE_VALUE (fndecls))) { tree fndecl = TREE_VALUE (fndecls); - enforce_access (TREE_PURPOSE (fndecls), fndecl); + enforce_access (basetype_path, fndecl); mark_used (fndecl); return fndecl; } @@ -2221,7 +2221,8 @@ build_component_ref (datum, component, basetype_path, protect) else addr = convert_pointer_to (base, addr); datum = build_indirect_ref (addr, NULL_PTR); - my_friendly_assert (datum != error_mark_node, 311); + if (datum == error_mark_node) + return error_mark_node; } basetype = base; diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index d380953..88ddc89 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1031,7 +1031,11 @@ process_init_constructor (type, init, elts) x.A::ii refers to the ii member of the L part of the A part of the C object named by X. In this case, - DATUM would be x, and BASETYPE would be A. */ + DATUM would be x, and BASETYPE would be A. + + Note that this is nonconformant; the standard specifies that first + we look up ii in A, then convert x to an L& and pull out the ii part. + But narrowing seems to be standard practice, so let's do it anyway. */ tree build_scoped_ref (datum, basetype) @@ -1044,43 +1048,15 @@ build_scoped_ref (datum, basetype) if (datum == error_mark_node) return error_mark_node; - if (TREE_CODE (type) == REFERENCE_TYPE) - type = TREE_TYPE (type); - - type = TYPE_MAIN_VARIANT (type); + /* Don't do this if it would cause an error or if we're being pedantic. */ + if (! ACCESSIBLY_UNIQUELY_DERIVED_P (basetype, type) + || pedantic) + return datum; - /* This is an easy conversion. */ - if (is_aggr_type (basetype, 1)) - { - tree binfo = TYPE_BINFO (basetype); - if (binfo != TYPE_BINFO (type)) - { - binfo = get_binfo (binfo, type, 1); - if (binfo == error_mark_node) - return error_mark_node; - if (binfo == 0) - return error_not_base_type (basetype, type); - } + ref = build_unary_op (ADDR_EXPR, datum, 0); + ref = convert_pointer_to (basetype, ref); - switch (TREE_CODE (datum)) - { - case NOP_EXPR: - case CONVERT_EXPR: - case FLOAT_EXPR: - case FIX_TRUNC_EXPR: - case FIX_FLOOR_EXPR: - case FIX_ROUND_EXPR: - case FIX_CEIL_EXPR: - ref = convert_pointer_to (binfo, - build_unary_op (ADDR_EXPR, TREE_OPERAND (datum, 0), 0)); - break; - default: - ref = convert_pointer_to (binfo, - build_unary_op (ADDR_EXPR, datum, 0)); - } - return build_indirect_ref (ref, "(compiler error in build_scoped_ref)"); - } - return error_mark_node; + return build_indirect_ref (ref, "(compiler error in build_scoped_ref)"); } /* Build a reference to an object specified by the C++ `->' operator. |