From: Mike Stump Date: Thu, 5 May 1994 22:19:26 +0000 (+0000) Subject: 35th Cygnus<->FSF merge X-Git-Tag: misc/cutover-egcs-0~6726 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=700f8a87923fe4fb60045c6edbb1430636342fa1;p=thirdparty%2Fgcc.git 35th Cygnus<->FSF merge From-SVN: r7217 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 27a7b119aa60..d5443014a11a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,17 +1,210 @@ -Tue May 3 19:11:24 1994 Jason Merrill (jason@deneb.cygnus.com) +Thu May 5 09:35:35 1994 Brendan Kehoe (brendan@lisa.cygnus.com) + + * typeck.c (build_modify_expr): Warn about assignment to `this'. + +Wed May 4 15:55:49 1994 Jason Merrill (jason@deneb.cygnus.com) + + * init.c (build_delete): Use the global operator delete when + requested. + + * decl.c (lookup_name_real): If we find the type we're looking in a + base class while defining a class, set IDENTIFIER_CLASS_VALUE for + the type. + + * class.c (finish_struct): Remove a couple of dependencies on + language linkage. + + * decl.c (pushtag): Classes do nest in extern "C" blocks. + (pushdecl): Only set DECL_NESTED_TYPENAME on the canonical one for + the type. + (pushtag): Remove another dependency on the language linkage. + + * lex.c (cons_up_default_function): Don't set DECL_CLASS_CONTEXT to + a const-qualified type. + + * decl.c (push_overloaded_decl): Throw away built-in decls here. + (duplicate_decls): Instead of here. + +Wed May 4 15:27:40 1994 Per Bothner (bothner@kalessin.cygnus.com) + + * typeck.c (get_member_function_from_ptrfunc): Do The Right + Thing (I hope) if we're using thunks. + +Wed May 4 13:52:38 1994 Jason Merrill (jason@deneb.cygnus.com) + + * parse.y (specialization): aggr template_type_name ';'. + (named_class_head_sans_basetype): Use it. + (explicit_instantiation): Ditto. + (tmpl.2): Revert. + + * cvt.c (build_type_conversion_1): Use convert_for_initialization, + rather than convert, to do conversions after the UDC. + + * cp-tree.h (SHARED_MEMBER_P): This member is shared between all + instances of the class. + + * search.c (lookup_field): If the entity found by two routes is the + same, it's not ambiguous. + +Wed May 4 12:10:00 1994 Per Bothner (bothner@kalessin.cygnus.com) + + * decl.c (lookup_name_real): Check for a NULL TREE_VALUE, + to prevent the compiler from crashing ... + +Wed May 4 11:19:45 1994 Jason Merrill (jason@deneb.cygnus.com) + + * call.c (build_method_call): If we don't have an object, check + basetype_path to figure out where to look up the function. + + * typeck.c (convert_for_initialization): Pass TYPE_BINFO (type) to + build_method_call in case exp is NULL_TREE. + +Tue May 3 16:02:53 1994 Per Bothner (bothner@kalessin.cygnus.com) + + Give a vtable entries a unique named type, for the sake of gdb. + * class.c (build_vtable_entry): The addres of a thunk now has + type vtable_entry_type, not ptr_type_node. + * method.c (make_thunk): Fix type of THUNK_DECL. + * class.c (add_virtual_function, override_one_vtable): Use + vfunc_ptr_type_node, instead of ptr_type_node. + * cp-tree.h (vfunc_ptr_type_node): New macro. + * decl.c (init_decl_processing): Make vtable_entry_type + be a unique type of pointer to a unique function type. + +Tue May 3 09:20:44 1994 Jason Merrill (jason@deneb.cygnus.com) + + * parse.y (do_explicit): Sets doing_explicit to 1. + (explicit_instantiation): Use do_explicit rather than TEMPLATE + directly, add "do_explicit error" rule. + (datadef): Set doing_explicit to 0 after an explicit instantiation. + (tmpl.2): Don't instantiate if we see a ';' unless we're doing an + explicit instantiation. + (named_class_head_sans_basetype): Remove aggr template_type_name + ';' again. + +Mon May 2 23:17:21 1994 Jason Merrill (jason@deneb.cygnus.com) + + * search.c (lookup_nested_tag): Lose. + + * decl2.c (grokfield): Set DECL_CONTEXT on TYPE_DECLs. + (lookup_name_nonclass): Lose. + + * decl.c (poplevel_class): Add force parameter. + (lookup_name_real): Fix handling of explicit scoping which specifies + a class currently being defined. Add 'nonclass' argument. + (lookup_name, lookup_name_nonclass): Shells for lookup_name_real. + + * class.c (finish_struct): Don't unset IDENTIFIER_CLASS_VALUEs here. + (popclass): Force clearing of IDENTIFIER_CLASS_VALUEs if we're being + called from finish_struct. + +Mon May 2 19:06:21 1994 Per Bothner (bothner@kalessin.cygnus.com) + + * decl.c (init_decl_processing), cp-tree.h: Removed memptr_type. + (It seeems redundant, given build_ptrmemfunc_type.) + * typeck.c (get_member_function_from_ptrfunc), gc.c (build_headof, + build_classof): Use vtable_entry_type instead of memptr_type. + * method.c (emit_thunk): Call poplevel with functionbody==0 + to prevent DECL_INITIAL being set to a BLOCK. + +Mon May 2 15:02:11 1994 Jason Merrill (jason@deneb.cygnus.com) + + * parse.y (named_class_head_sans_basetype): Add "aggr + template_type_name ';'" rule for forward declaration of + specializations. + +Mon May 2 15:02:11 1994 Jason Merrill (jason@deneb.cygnus.com) + + * class.c (instantiate_type): Deal with pmf's. * Make-lang.in (cc1plus): Don't depend on OBJS or BC_OBJS, since stamp-objlist does. + * Makefile.in (../cc1plus): Depend on OBJDEPS. (OBJDEPS): Dependency version of OBJS. +Mon May 2 12:51:31 1994 Kung Hsu (kung@mexican.cygnus.com) + + * search.c (dfs_debug_mark): unmark TYPE_DECL_SUPPRESS_DEBUG, not + DECL_IGNORED_P. + +Fri Apr 29 12:29:56 1994 Jason Merrill (jason@deneb.cygnus.com) + + * class.c (finish_struct): Clear out memory of local tags. And + typedefs. + + * decl2.c (grokclassfn): Don't set DECL_CONTEXT to a cv-qualified + type. + * search.c (get_matching_virtual): Be more helpful in error message. + + * *: Use DECL_ARTIFICIAL (renamed from DECL_SYNTHESIZED). + + * lex.c (default_assign_ref_body): Expect TYPE_NESTED_NAME to work. + (default_copy_constructor_body): Ditto. + + * class.c (finish_struct): Don't gratuitously create multiple decls + for nested classes. + +Thu Apr 28 23:39:38 1994 Jason Merrill (jason@deneb.cygnus.com) + + Avoid clobbering the arg types of other functions when reverting + static member functions. + * decl.c (revert_static_member_fn): Rearrange arguments, don't + require values for 'fn' and 'argtypes', add warning to comment + above. + (decls_match): Rearrange arguments in call to rsmf. + (grok_op_properties): Don't pass values for fn and argtypes. + * pt.c (instantiate_template): Don't pass values for fn and argtypes. + Thu Apr 28 16:29:11 1994 Doug Evans (dje@canuck.cygnus.com) * Make-lang.in (cc1plus): Depend on stamp-objlist. * Makefile.in (BC_OBJS): Delete. - (OBJS): Cat ../stamp-objlist to get everything, except ../c-common.o. + (OBJS): Cat ../stamp-objlist to get language independent files. + Include ../c-common.o. (../cc1plus): Delete reference to BC_OBJS. +Thu Apr 28 02:12:08 1994 Jason Merrill (jason@deneb.cygnus.com) + + * search.c (compute_access): No really, deal with static members + properly. Would I lie to you? + + Implement lexical hiding of function declarations. + * pt.c (tsubst): Use lookup_name to look for function decls to guide + instantiation. + * method.c (build_opfncall): Use lookup_name_nonclass to look for + non-member functions. + * init.c (do_friend): Use lookup_name_nonclass to look for + functions. + * error.c (ident_fndecl): Use lookup_name to look for functions. + * decl2.c (lookup_name_nonclass): New function, skips over + CLASS_VALUE. + * decl.c (struct binding_level): Lose overloads_shadowed field. + (poplevel): Don't deal with overloads_shadowed. + (push_overloaded_decl): Do lexical hiding for functions. + * class.c (instantiate_type): Don't check non-members if we have + members with the same name. + * call.c (build_method_call): Use lookup_name_nonclass instead of + IDENTIFIER_GLOBAL_VALUE to check for non-member functions. + (build_overload_call_real): Ditto. + + * decl.c (duplicate_decls): Check for ambiguous overloads here. + (push_overloaded_decl): Instead of here. + + * decl.c (pushdecl): Back out Chip's last change. + + * decl.c (grok_op_properties): operators cannot be static members. + + * cp-tree.h (DECL_SYNTHESIZED): DECL_SOURCE_LINE == 0 + (SET_DECL_SYNTHESIZED): DECL_SOURCE_LINE = 0 + * lex.c (cons_up_default_function): Use SET_DECL_SYNTHESIZED. + + * method.c (do_inline_function_hair): Don't put friends of local + classes into global scope, either. + + * typeck2.c (build_functional_cast): Don't look for a function call + interpretation. + Thu Apr 28 15:19:46 1994 Mike Stump (mrs@cygnus.com) * cp-tree.h: disable use of backend EH. @@ -170,6 +363,17 @@ Sun Apr 24 16:52:51 1994 Doug Evans (dje@canuck.cygnus.com) (*.o): Use complete pathname to headers in parent dir. (doc, info, dvi): Delete. +Sun Apr 24 16:52:51 1994 Doug Evans (dje@canuck.cygnus.com) + + * Make-lang.in (c++.install-common): Check for g++-cross. + * Makefile.in: Remove Cygnus cruft. + (config.status): Delete. + (RTL_H): Define. + (TREE_H): Use complete pathname, some native makes have minimal + VPATH support. + (*.o): Use complete pathname to headers in parent dir. + (doc, info, dvi): Delete. + Sun Apr 24 00:47:49 1994 Jason Merrill (jason@deneb.cygnus.com) * decl.c (pushdecl): Avoid redundant warning on redeclaring function @@ -290,6 +494,11 @@ Fri Apr 22 03:27:26 1994 Doug Evans (dje@cygnus.com) * Language directory reorganization. See parent makefile. +Fri Apr 22 03:27:26 1994 Doug Evans (dje@cygnus.com) + + * Language directory reorganization. + See parent makefile. + Thu Apr 21 18:27:57 1994 Per Bothner (bothner@kalessin.cygnus.com) * cp-tree.h (THUNK_DELTA): It is normally negative, so diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 62ca226904e9..bc3b7314b911 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -2859,6 +2859,8 @@ build_method_call (instance, name, parms, basetype_path, flags) if (basetype != NULL_TREE) ; /* call to a constructor... */ + else if (basetype_path) + basetype = BINFO_TYPE (basetype_path); else if (IDENTIFIER_HAS_TYPE_VALUE (name)) { basetype = IDENTIFIER_TYPE_VALUE (name); @@ -3429,7 +3431,7 @@ build_method_call (instance, name, parms, basetype_path, flags) } if (pass == 0) { - tree igv = IDENTIFIER_GLOBAL_VALUE (name); + tree igv = lookup_name_nonclass (name); /* No exact match could be found. Now try to find match using default conversions. */ @@ -3516,7 +3518,7 @@ build_method_call (instance, name, parms, basetype_path, flags) goto found_and_maybe_warn; } - if ((flags & ~LOOKUP_GLOBAL) & (LOOKUP_COMPLAIN|LOOKUP_SPECULATIVELY)) + if (flags & (LOOKUP_COMPLAIN|LOOKUP_SPECULATIVELY)) { if ((flags & (LOOKUP_SPECULATIVELY|LOOKUP_COMPLAIN)) == LOOKUP_SPECULATIVELY) @@ -3925,23 +3927,25 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx) if (! flag_ansi_overloading) { + tree fn; + /* This is a speed improvement that ends up not working properly in the situation of fns with and without default parameters. I turned this off in the new method so it'll go through the argument matching code to properly diagnose a match/failure. (bpk) */ overload_name = build_decl_overload (fnname, parmtypes, 0); + fn = lookup_name_nonclass (overload_name); /* Now check to see whether or not we can win. Note that if we are called from `build_method_call', then we cannot have a mis-match, because we would have already found such a winning case. */ - if (IDENTIFIER_GLOBAL_VALUE (overload_name)) - if (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (overload_name)) != TREE_LIST) - return build_function_call (DECL_MAIN_VARIANT (IDENTIFIER_GLOBAL_VALUE (overload_name)), parms); + if (fn && TREE_CODE (fn) == FUNCTION_DECL) + return build_function_call (DECL_MAIN_VARIANT (fn), parms); } - functions = IDENTIFIER_GLOBAL_VALUE (fnname); + functions = lookup_name_nonclass (fnname); if (functions == NULL_TREE) { diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 0807ce7cab85..fe169ad3e37c 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -361,7 +361,7 @@ build_vtable_entry (delta, pfn) extern tree make_thunk (); if (idelta) { - pfn = build1 (ADDR_EXPR, ptr_type_node, + pfn = build1 (ADDR_EXPR, vtable_entry_type, make_thunk (pfn, idelta)); TREE_READONLY (pfn) = 1; TREE_CONSTANT (pfn) = 1; @@ -782,7 +782,7 @@ add_virtual_function (pending_virtuals, has_virtual, fndecl, t) { /* FUNCTION_TYPEs and OFFSET_TYPEs no longer freely convert to void *. Make such a conversion here. */ - tree vfn = build1 (ADDR_EXPR, ptr_type_node, fndecl); + tree vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, fndecl); TREE_CONSTANT (vfn) = 1; #ifndef DUMB_USER @@ -2389,7 +2389,7 @@ override_one_vtable (binfo, old, t) if (! CLASSTYPE_ABSTRACT_VIRTUALS (t)) CLASSTYPE_ABSTRACT_VIRTUALS (t) = error_mark_node; - vfn = build1 (ADDR_EXPR, ptr_type_node, fndecl); + vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, fndecl); TREE_CONSTANT (vfn) = 1; /* We can use integer_zero_node, as we will will core dump @@ -2668,7 +2668,7 @@ finish_struct (t, list_of_fieldlists, warn_anon) } if (write_virtuals == 3 && CLASSTYPE_INTERFACE_KNOWN (t) - && current_lang_name == lang_name_cplusplus && ! IS_SIGNATURE (t)) + && ! IS_SIGNATURE (t)) { CLASSTYPE_INTERFACE_ONLY (t) = interface_only; CLASSTYPE_VTABLE_NEEDS_WRITING (t) = ! interface_only; @@ -3653,7 +3653,14 @@ finish_struct (t, list_of_fieldlists, warn_anon) last_x = tree_last (TYPE_FIELDS (t)); while (x) { +#if 0 /* What's wrong with using the decl the type already has? */ tree tag = build_lang_decl (TYPE_DECL, TREE_PURPOSE (x), TREE_VALUE (x)); + DECL_CONTEXT (tag) = t; +#else + tree tag = TYPE_NAME (TREE_VALUE (x)); +#endif + DECL_CLASS_CONTEXT (tag) = t; + #ifdef DWARF_DEBUGGING_INFO if (write_symbols == DWARF_DEBUG) { @@ -3662,8 +3669,8 @@ finish_struct (t, list_of_fieldlists, warn_anon) DECL_IGNORED_P (tag) = 1; } #endif /* DWARF_DEBUGGING_INFO */ - DECL_CONTEXT (tag) = t; - DECL_CLASS_CONTEXT (tag) = t; + + TREE_NONLOCAL_FLAG (TREE_VALUE (x)) = 0; x = TREE_CHAIN (x); last_x = chainon (last_x, tag); } @@ -3691,16 +3698,12 @@ finish_struct (t, list_of_fieldlists, warn_anon) else if (TYPE_NEEDS_CONSTRUCTING (t)) build_class_init_list (t); - if (current_lang_name == lang_name_cplusplus) - { - if (! CLASSTYPE_DECLARED_EXCEPTION (t) - && ! IS_SIGNATURE (t)) - embrace_waiting_friends (t); + if (! CLASSTYPE_DECLARED_EXCEPTION (t) && ! IS_SIGNATURE (t)) + embrace_waiting_friends (t); - /* Write out inline function definitions. */ - do_inline_function_hair (t, CLASSTYPE_INLINE_FRIENDS (t)); - CLASSTYPE_INLINE_FRIENDS (t) = 0; - } + /* Write out inline function definitions. */ + do_inline_function_hair (t, CLASSTYPE_INLINE_FRIENDS (t)); + CLASSTYPE_INLINE_FRIENDS (t) = 0; if (CLASSTYPE_VSIZE (t) != 0) { @@ -4097,9 +4100,9 @@ pushclass (type, modify) } /* Get out of the current class scope. If we were in a class scope - previously, that is the one popped to. The flag MODIFY tells - whether the current scope declarations needs to be modified - as a result of popping to the previous scope. */ + previously, that is the one popped to. The flag MODIFY tells whether + the current scope declarations needs to be modified as a result of + popping to the previous scope. 0 is used for class definitions. */ void popclass (modify) int modify; @@ -4116,7 +4119,7 @@ popclass (modify) /* This code can be seen as a cache miss. When we've cached a class' scope's bindings and we can't use them, we need to reset them. This is it! */ - for (t = previous_class_values; t; t = TREE_CHAIN(t)) + for (t = previous_class_values; t; t = TREE_CHAIN (t)) IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE; while (tags) { @@ -4141,7 +4144,9 @@ popclass (modify) undo_template_name_overload (current_class_name, 0); } - poplevel_class (); + /* Force clearing of IDENTIFIER_CLASS_VALUEs after a class definition, + since not all class decls make it there currently. */ + poplevel_class (! modify); /* Since poplevel_class does the popping of class decls nowadays, this really only frees the obstack used for these decls. @@ -4540,10 +4545,11 @@ instantiate_type (lhstype, rhs, complain) return save_elem; } name = DECL_NAME (TREE_VALUE (rhs)); +#if 0 if (TREE_CODE (lhstype) == FUNCTION_TYPE && globals < 0) { /* Try to instantiate from non-member functions. */ - rhs = IDENTIFIER_GLOBAL_VALUE (name); + rhs = lookup_name_nonclass (name); if (rhs && TREE_CODE (rhs) == TREE_LIST) { /* This code seems to be missing a `return'. */ @@ -4551,6 +4557,7 @@ instantiate_type (lhstype, rhs, complain) instantiate_type (lhstype, rhs, complain); } } +#endif } if (complain) error ("no static member functions named `%s'", @@ -4655,7 +4662,9 @@ instantiate_type (lhstype, rhs, complain) return rhs; case ADDR_EXPR: - if (TREE_CODE (lhstype) != POINTER_TYPE) + if (TYPE_PTRMEMFUNC_P (lhstype)) + lhstype = TYPE_PTRMEMFUNC_FN_TYPE (lhstype); + else if (TREE_CODE (lhstype) != POINTER_TYPE) { if (complain) error ("type for resolving address of overloaded function must be pointer type"); @@ -4663,7 +4672,8 @@ instantiate_type (lhstype, rhs, complain) } TREE_TYPE (rhs) = lhstype; lhstype = TREE_TYPE (lhstype); - TREE_OPERAND (rhs, 0) = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain); + TREE_OPERAND (rhs, 0) = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), + complain); if (TREE_OPERAND (rhs, 0) == error_mark_node) return error_mark_node; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 078b69e938f0..1a82e0bc96db 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -936,9 +936,8 @@ struct lang_decl_flags unsigned constructor_for_vbase_attr : 1; unsigned mutable_flag : 1; unsigned is_default_implementation : 1; - unsigned synthesized : 1; unsigned saved_inline : 1; - unsigned dummy : 9; + unsigned dummy : 10; tree access; tree context; @@ -1000,6 +999,12 @@ struct lang_decl member function. */ #define DECL_STATIC_FUNCTION_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.static_function) +/* Nonzero for a class member means that it is shared between all objects + of that class. */ +#define SHARED_MEMBER_P(NODE) \ + (TREE_CODE (NODE) == VAR_DECL || TREE_CODE (NODE) == TYPE_DECL \ + || TREE_CODE (NODE) == CONST_DECL) + /* Nonzero for FUNCTION_DECL means that this decl is a member function (static or non-static). */ #define DECL_FUNCTION_MEMBER_P(NODE) \ @@ -1106,8 +1111,9 @@ struct lang_decl #define DECL_PUBLIC(NODE) (DECL_LANG_FLAG_7 (NODE)) #endif -/* This method was synthesized by cons_up_default_function. */ -#define DECL_SYNTHESIZED(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.synthesized) +/* This _DECL represents a compiler-generated entity. */ +#define DECL_ARTIFICIAL(NODE) (DECL_SOURCE_LINE (NODE) == 0) +#define SET_DECL_ARTIFICIAL(NODE) (DECL_SOURCE_LINE (NODE) = 0) /* Record whether a typedef for type `int' was actually `signed int'. */ #define C_TYPEDEF_EXPLICITLY_SIGNED(exp) DECL_LANG_FLAG_1 ((exp)) @@ -1327,7 +1333,6 @@ extern tree void_list_node; extern tree void_zero_node; extern tree default_function_type; extern tree vtable_entry_type; -extern tree memptr_type; extern tree sigtable_entry_type; extern tree __t_desc_type_node, __i_desc_type_node, __m_desc_type_node; extern tree Type_info_type_node; @@ -1347,6 +1352,11 @@ extern tree class_type_node, record_type_node, union_type_node, enum_type_node; extern tree exception_type_node, unknown_type_node; extern tree opaque_type_node, signature_type_node; +/* Node for "pointer to (virtual) function". + This may be distinct from ptr_type_node so gdb can distinuish them. */ +#define vfunc_ptr_type_node \ + (flag_vtable_thunks ? vtable_entry_type : ptr_type_node) + /* Array type `(void *)[]' */ extern tree vtbl_type_node; extern tree delta_type_node; @@ -1812,7 +1822,7 @@ extern void insert_block PROTO((tree)); extern void add_block_current_level PROTO((tree)); extern void set_block PROTO((tree)); extern void pushlevel_class PROTO((void)); -extern tree poplevel_class PROTO((void)); +extern tree poplevel_class PROTO((int)); /* skip print_other_binding_stack and print_binding_level */ extern void print_binding_stack PROTO((void)); extern void push_to_top_level PROTO((void)); @@ -1906,6 +1916,7 @@ extern tree reparse_absdcl_as_expr PROTO((tree, tree)); extern tree reparse_absdcl_as_casts PROTO((tree, tree)); extern tree reparse_decl_as_expr PROTO((tree, tree)); extern tree finish_decl_parsing PROTO((tree)); +extern tree lookup_name_nonclass PROTO((tree)); /* in edsel.c */ diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index bcf21c12f9f6..b1604129ca5b 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -1539,7 +1539,11 @@ build_type_conversion_1 (xtype, basetype, expr, typename, for_sure) && (TREE_READONLY (TREE_TYPE (TREE_TYPE (rval))) > TREE_READONLY (TREE_TYPE (xtype)))) warning ("user-defined conversion casting away `const'"); - return convert (xtype, rval); + rval = convert_for_initialization (NULL_TREE, xtype, rval, flags, + "conversion", NULL_TREE, 0); + if (rval == error_mark_node) + return NULL_TREE; + return rval; } /* Convert an aggregate EXPR to type XTYPE. If a conversion diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 5af301bc68de..1533f95620c0 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -224,7 +224,7 @@ tree sizet_ftype_string; tree int_ftype_cptr_cptr_sizet; /* C++ extensions */ -tree memptr_type, vtable_entry_type; +tree vtable_entry_type; tree delta_type_node; tree __t_desc_type_node, __i_desc_type_node, __m_desc_type_node; tree __t_desc_array_type, __i_desc_array_type, __m_desc_array_type; @@ -531,9 +531,6 @@ struct binding_level /* Same, for IDENTIFIER_TYPE_VALUE. */ tree type_shadowed; - /* Same, for IDENTIFIER_GLOBAL_VALUE for overloaded functions. */ - tree overloads_shadowed; - /* For each level (except not the global one), a chain of BLOCK nodes for all the levels that were entered and exited one level down. */ @@ -1025,9 +1022,6 @@ poplevel (keep, reverse, functionbody) for (link = current_binding_level->type_shadowed; link; link = TREE_CHAIN (link)) IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link); - for (link = current_binding_level->overloads_shadowed; - link; link = TREE_CHAIN (link)) - IDENTIFIER_GLOBAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link); /* If the level being exited is the top level of a function, check over all the labels. */ @@ -1232,9 +1226,11 @@ pushlevel_class () while (current_binding_level->parm_flag == 2); } -/* ...and a poplevel for class declarations. */ +/* ...and a poplevel for class declarations. FORCE is used to force + clearing out of CLASS_VALUEs after a class definition. */ tree -poplevel_class () +poplevel_class (force) + int force; { register struct binding_level *level = class_binding_level; tree block = NULL_TREE; @@ -1250,7 +1246,7 @@ poplevel_class () shouldn't even be used when current_class_type isn't set, and second, if we don't touch it here, we're able to use the caching effect if the next time we're entering a class scope, it is the same class. */ - if (current_class_depth != 1) + if (current_class_depth != 1 || force) for (shadowed = level->class_shadowed; shadowed; shadowed = TREE_CHAIN (shadowed)) @@ -1779,10 +1775,7 @@ pushtag (name, type, globalize) if (b->parm_flag != 2 || TYPE_SIZE (current_class_type) != NULL_TREE) { - if (current_lang_name == lang_name_cplusplus) - d = lookup_nested_type (type, cdecl); - else - d = NULL_TREE; + d = lookup_nested_type (type, cdecl); if (d == NULL_TREE) { @@ -1854,7 +1847,7 @@ pushtag (name, type, globalize) } TYPE_NAME (type) = d; - if (context == NULL_TREE || current_lang_name != lang_name_cplusplus) + if (context == NULL_TREE) /* Non-nested class. */ DECL_NESTED_TYPENAME (d) = name; else if (context && TREE_CODE (context) == FUNCTION_DECL) @@ -1980,10 +1973,10 @@ decls_match (newdecl, olddecl) is METHOD_TYPE. Change that to FUNCTION_TYPE, and proceed. */ if (TREE_CODE (f1) == METHOD_TYPE && DECL_STATIC_FUNCTION_P (olddecl)) - revert_static_member_fn (&f1, &newdecl, &p1); + revert_static_member_fn (&newdecl, &f1, &p1); else if (TREE_CODE (f2) == METHOD_TYPE && DECL_STATIC_FUNCTION_P (newdecl)) - revert_static_member_fn (&f2, &olddecl, &p2); + revert_static_member_fn (&olddecl, &f2, &p2); /* Here we must take care of the case where new default parameters are specified. Also, warn if an old @@ -2154,29 +2147,29 @@ duplicate_decls (newdecl, olddecl) else if (TREE_CODE (olddecl) == FUNCTION_DECL && (DECL_BUILT_IN (olddecl) || DECL_BUILT_IN_NONANSI (olddecl)) && DECL_ASSEMBLER_NAME (newdecl) == DECL_ASSEMBLER_NAME (olddecl)) + /* Redeclaring a builtin as another function is handled in + push_overloaded_decl. */ { /* If you declare a built-in or predefined function name as static, the old definition is overridden, but optionally warn this was a bad choice of name. */ if (! TREE_PUBLIC (newdecl)) - { - if (warn_shadow) - cp_warning ("shadowing %s function `%#D'", - DECL_BUILT_IN (olddecl) ? "built-in" : "library", - newdecl); - /* Discard the old built-in function. */ - } - else if (! types_match) + if (warn_shadow) + cp_warning ("shadowing %s function `%#D'", + DECL_BUILT_IN (olddecl) ? "built-in" : "library", + newdecl); + /* Likewise, if the built-in is not ansi, then programs can override + it even globally without an error. */ + else if (! DECL_BUILT_IN (olddecl)) + cp_warning ("library function `%#D' redeclared as non-function `%#D'", + olddecl, newdecl); + else { cp_warning ("declaration of `%#D'", newdecl); cp_warning ("conflicts with built-in declaration `%#D'", olddecl); } - if (TREE_CODE (newdecl) != FUNCTION_DECL) - return 0; - - if (! types_match) - TREE_TYPE (olddecl) = TREE_TYPE (newdecl); + return 0; } else if (TREE_CODE (olddecl) != TREE_CODE (newdecl)) { @@ -2211,8 +2204,15 @@ duplicate_decls (newdecl, olddecl) newdecl); cp_error_at ("previous declaration `%#D' here", olddecl); } - - return 0; + + if (compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), + TYPE_ARG_TYPES (TREE_TYPE (olddecl)), 2)) + { + cp_error ("new declaration `%#D'", newdecl); + cp_error_at ("ambiguates old declaration `%#D'", olddecl); + } + else + return 0; } /* Already complained about this, so don't do so again. */ @@ -2333,7 +2333,7 @@ duplicate_decls (newdecl, olddecl) /* Optionally warn about more than one declaration for the same name, but don't warn about a function declaration followed by a definition. */ if (warn_redundant_decls - && DECL_SOURCE_LINE (olddecl) != 0 + && ! DECL_ARTIFICIAL (olddecl) && !(new_defines_function && DECL_INITIAL (olddecl) == NULL_TREE) /* Don't warn about extern decl followed by (tentative) definition. */ && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl))) @@ -2490,6 +2490,14 @@ duplicate_decls (newdecl, olddecl) if (TREE_CODE (newdecl) == FUNCTION_DECL) { + if (! types_match) + { + DECL_LANGUAGE (olddecl) = DECL_LANGUAGE (newdecl); + DECL_ASSEMBLER_NAME (olddecl) = DECL_ASSEMBLER_NAME (newdecl); + DECL_ARGUMENTS (olddecl) = DECL_ARGUMENTS (newdecl); + DECL_RESULT (olddecl) = DECL_RESULT (newdecl); + DECL_RTL (olddecl) = DECL_RTL (newdecl); + } if (new_defines_function) /* If defining a function declared with other language linkage, use the previously declared language linkage. */ @@ -2630,10 +2638,9 @@ pushdecl (x) nglobals = len; #endif - /* Don't change DECL_CONTEXT of virtual methods. */ if (x != current_function_decl - && (TREE_CODE (x) != FUNCTION_DECL - || !DECL_VIRTUAL_P (x)) + /* Don't change DECL_CONTEXT of virtual methods. */ + && (TREE_CODE (x) != FUNCTION_DECL || !DECL_VIRTUAL_P (x)) && ! DECL_CONTEXT (x)) DECL_CONTEXT (x) = current_function_decl; /* A local declaration for a function doesn't constitute nesting. */ @@ -2660,10 +2667,7 @@ pushdecl (x) char *file; int line; - if (DECL_EXTERNAL (x)) - t = lookup_name (name, 0); - else - t = lookup_name_current_level (name); + t = lookup_name_current_level (name); if (t == error_mark_node) { /* error_mark_node is 0 for a while during initialization! */ @@ -2956,7 +2960,7 @@ pushdecl (x) /* Maybe warn if shadowing something else. */ else if (warn_shadow && !DECL_EXTERNAL (x) /* No shadow warnings for internally generated vars. */ - && DECL_SOURCE_LINE (x) != 0 + && ! DECL_ARTIFICIAL (x) /* No shadow warnings for vars made for inlining. */ && ! DECL_FROM_INLINE (x)) { @@ -2997,7 +3001,7 @@ pushdecl (x) { if (current_class_name) { - if (!DECL_NESTED_TYPENAME (x)) + if (!DECL_NESTED_TYPENAME (TYPE_NAME (TREE_TYPE (x)))) set_nested_typename (x, current_class_name, DECL_NAME (x), TREE_TYPE (x)); } @@ -3173,10 +3177,10 @@ overloaded_globals_p (list) return 0; } -/* DECL is a FUNCTION_DECL which may have other definitions already in place. - We get around this by making IDENTIFIER_GLOBAL_VALUE (DECL_NAME (DECL)) - point to a list of all the things that want to be referenced by that name. - It is then up to the users of that name to decide what to do with that +/* DECL is a FUNCTION_DECL which may have other definitions already in + place. We get around this by making the value of the identifier point + to a list of all the things that want to be referenced by that name. It + is then up to the users of that name to decide what to do with that list. DECL may also be a TEMPLATE_DECL, with a FUNCTION_DECL in its DECL_RESULT @@ -3191,80 +3195,89 @@ push_overloaded_decl (decl, forgettable) int forgettable; { tree orig_name = DECL_NAME (decl); - tree glob = IDENTIFIER_GLOBAL_VALUE (orig_name); + tree old; + int doing_global = (global_bindings_p () || ! forgettable + || flag_traditional || pseudo_global_level_p ()); + + if (doing_global) + { + old = IDENTIFIER_GLOBAL_VALUE (orig_name); + if (old && TREE_CODE (old) == FUNCTION_DECL + && (DECL_BUILT_IN (old) || DECL_BUILT_IN_NONANSI (old))) + { + if (! decls_match (decl, old) + && (DECL_LANGUAGE (decl) == lang_c + || compparms (TYPE_ARG_TYPES (TREE_TYPE (decl)), + TYPE_ARG_TYPES (TREE_TYPE (old)), 2))) + { + cp_warning ("declaration of `%#D'", decl); + cp_warning ("conflicts with built-in declaration `%#D'", old); + } + old = NULL_TREE; + } + } + else + { + old = IDENTIFIER_LOCAL_VALUE (orig_name); + + if (! purpose_member (orig_name, current_binding_level->shadowed)) + { + current_binding_level->shadowed + = tree_cons (orig_name, old, current_binding_level->shadowed); + old = NULL_TREE; + } + } - if (glob) + if (old) { +#if 0 /* We cache the value of builtin functions as ADDR_EXPRs in the name space. Convert it to some kind of _DECL after remembering what to forget. */ - if (TREE_CODE (glob) == ADDR_EXPR) - glob = TREE_OPERAND (glob, 0); - - else if (TREE_CODE (decl) == TEMPLATE_DECL) - { - tree tmp; - - for (tmp = get_first_fn (glob); tmp; tmp = DECL_CHAIN (tmp)) - if (decl == tmp || duplicate_decls (decl, tmp)) - return decl; - } - else if (TREE_CODE (glob) == VAR_DECL) + if (TREE_CODE (old) == ADDR_EXPR) + old = TREE_OPERAND (old, 0); + else +#endif + if (TREE_CODE (old) == VAR_DECL) { - cp_error_at ("previous non-function declaration `%#D'", glob); + cp_error_at ("previous non-function declaration `%#D'", old); cp_error ("conflicts with function declaration `%#D'", decl); return error_mark_node; } - else if (TREE_CODE (glob) == TYPE_DECL) + else if (TREE_CODE (old) == TYPE_DECL) { - tree t = TREE_TYPE (glob); + tree t = TREE_TYPE (old); if (IS_AGGR_TYPE (t) && warn_shadow) cp_warning ("`%#D' hides constructor for `%#T'", decl, t); } - else if (is_overloaded_fn (glob)) + else if (is_overloaded_fn (old)) { tree tmp; - for (tmp = get_first_fn (glob); tmp; tmp = DECL_CHAIN (tmp)) - { - if (decl == tmp || duplicate_decls (decl, tmp)) - return tmp; - /* Avoid doing things about built-ins, since duplicate_decls - will have given warnings/errors for them. */ - if (!DECL_BUILT_IN (tmp) && !DECL_BUILT_IN_NONANSI (tmp) - && compparms (TYPE_ARG_TYPES (TREE_TYPE (decl)), - TYPE_ARG_TYPES (TREE_TYPE (tmp)), 2)) - { - cp_error ("new declaration `%#D'", decl); - cp_error_at ("ambiguates old declaration `%#D'", tmp); - } - } + for (tmp = get_first_fn (old); tmp; tmp = DECL_CHAIN (tmp)) + if (decl == tmp || duplicate_decls (decl, tmp)) + return tmp; } } - if (forgettable - && ! flag_traditional - && (glob == NULL_TREE || TREE_PERMANENT (glob) == 1) - && !global_bindings_p () - && !pseudo_global_level_p ()) - current_binding_level->overloads_shadowed - = tree_cons (orig_name, glob, - current_binding_level->overloads_shadowed); - - if (glob || TREE_CODE (decl) == TEMPLATE_DECL) + if (old || TREE_CODE (decl) == TEMPLATE_DECL) { - if (glob && is_overloaded_fn (glob)) - DECL_CHAIN (decl) = get_first_fn (glob); + if (old && is_overloaded_fn (old)) + DECL_CHAIN (decl) = get_first_fn (old); else DECL_CHAIN (decl) = NULL_TREE; - glob = tree_cons (orig_name, decl, NULL_TREE); - TREE_TYPE (glob) = unknown_type_node; + old = tree_cons (orig_name, decl, NULL_TREE); + TREE_TYPE (old) = unknown_type_node; } else /* orig_name is not ambiguous. */ - glob = decl; - - IDENTIFIER_GLOBAL_VALUE (orig_name) = glob; + old = decl; + + if (doing_global) + IDENTIFIER_GLOBAL_VALUE (orig_name) = old; + else + IDENTIFIER_LOCAL_VALUE (orig_name) = old; + return decl; } @@ -3530,7 +3543,7 @@ define_label (filename, line, name) of internal entities. They can't be accessed, and they should be cleaned up by the time we get to the label. */ - && DECL_SOURCE_LINE (new_decls) != 0 + && ! DECL_ARTIFICIAL (new_decls) && ((DECL_INITIAL (new_decls) != NULL_TREE && DECL_INITIAL (new_decls) != error_mark_node) || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls)))) @@ -3849,9 +3862,9 @@ lookup_nested_type (type, context) Otherwise we prefer non-TYPE_DECLs. */ tree -lookup_name (name, prefer_type) +lookup_name_real (name, prefer_type, nonclass) tree name; - int prefer_type; + int prefer_type, nonclass; { register tree val; int yylex = 0; @@ -3879,10 +3892,29 @@ lookup_name (name, prefer_type) else if (! IS_AGGR_TYPE (got_scope)) /* Someone else will give an error about this if needed. */ val = NULL_TREE; + else if (TYPE_BEING_DEFINED (got_scope)) + { + val = IDENTIFIER_CLASS_VALUE (name); + if (val && DECL_CONTEXT (val) != got_scope) + { + struct binding_level *b = class_binding_level; + for (val = NULL_TREE; b; b = b->level_chain) + { + tree t = purpose_member (name, b->class_shadowed); + if (t && TREE_VALUE (t) + && DECL_CONTEXT (TREE_VALUE (t)) == got_scope) + { + val = TREE_VALUE (t); + break; + } + } + } + if (val == NULL_TREE + && CLASSTYPE_LOCAL_TYPEDECLS (got_scope)) + val = lookup_field (got_scope, name, 0, 1); + } else if (got_scope == current_class_type) val = IDENTIFIER_CLASS_VALUE (name); - else if (TYPE_BEING_DEFINED (got_scope)) - val = lookup_nested_tag (got_scope, name); else val = lookup_field (got_scope, name, 0, 0); @@ -3895,21 +3927,19 @@ lookup_name (name, prefer_type) val = IDENTIFIER_LOCAL_VALUE (name); /* In C++ class fields are between local and global scope, just before the global scope. */ - else if (current_class_type) + else if (current_class_type && ! nonclass) { val = IDENTIFIER_CLASS_VALUE (name); if (val == NULL_TREE - && TYPE_SIZE (current_class_type) == NULL_TREE + && TYPE_BEING_DEFINED (current_class_type) && CLASSTYPE_LOCAL_TYPEDECLS (current_class_type)) + /* Try to find values from base classes if we are presently + defining a type. We are presently only interested in + TYPE_DECLs. */ { - /* Try to find values from base classes - if we are presently defining a type. - We are presently only interested in TYPE_DECLs. */ val = lookup_field (current_class_type, name, 0, 1); - if (val == error_mark_node) - return val; - if (val && TREE_CODE (val) != TYPE_DECL) - val = NULL_TREE; + if (val) + pushdecl_class_level (val); } /* yylex() calls this with -2, since we should never start digging for @@ -3948,6 +3978,21 @@ lookup_name (name, prefer_type) return val; } +tree +lookup_name_nonclass (name) + tree name; +{ + return lookup_name_real (name, 0, 1); +} + +tree +lookup_name (name, prefer_type) + tree name; + int prefer_type; +{ + return lookup_name_real (name, prefer_type, 0); +} + /* Similar to `lookup_name' but look only at current binding level. */ tree @@ -4654,34 +4699,40 @@ init_decl_processing () pushdecl (lookup_name (get_identifier ("__gc_main"), 0)); } - /* Simplify life by making a "memptr_type". Give its - fields names so that the debugger can use them. */ - - memptr_type = make_lang_type (RECORD_TYPE); - fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier, - delta_type_node); - fields[1] = build_lang_field_decl (FIELD_DECL, index_identifier, - delta_type_node); - fields[2] = build_lang_field_decl (FIELD_DECL, pfn_identifier, - ptr_type_node); - finish_builtin_type (memptr_type, VTBL_PTR_TYPE, fields, 2, - double_type_node); - - /* Make this part of an invisible union. */ - fields[3] = copy_node (fields[2]); - TREE_TYPE (fields[3]) = delta_type_node; - DECL_NAME (fields[3]) = delta2_identifier; - DECL_MODE (fields[3]) = TYPE_MODE (delta_type_node); - DECL_SIZE (fields[3]) = TYPE_SIZE (delta_type_node); - TREE_UNSIGNED (fields[3]) = 0; - TREE_CHAIN (fields[2]) = fields[3]; - memptr_type = build_type_variant (memptr_type, 1, 0); - record_builtin_type (RID_MAX, VTBL_PTR_TYPE, memptr_type); - if (flag_vtable_thunks) - vtable_entry_type = ptr_type_node; + { + /* Make sure we get a unique function type, so we can give + its pointer type a name. (This wins for gdb.) */ + tree vfunc_type = make_node (FUNCTION_TYPE); + TREE_TYPE (vfunc_type) = integer_type_node; + TYPE_ARG_TYPES (vfunc_type) = NULL_TREE; + layout_type (vfunc_type); + + vtable_entry_type = build_pointer_type (vfunc_type); + } else - vtable_entry_type = memptr_type; + { + vtable_entry_type = make_lang_type (RECORD_TYPE); + fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier, + delta_type_node); + fields[1] = build_lang_field_decl (FIELD_DECL, index_identifier, + delta_type_node); + fields[2] = build_lang_field_decl (FIELD_DECL, pfn_identifier, + ptr_type_node); + finish_builtin_type (vtable_entry_type, VTBL_PTR_TYPE, fields, 2, + double_type_node); + + /* Make this part of an invisible union. */ + fields[3] = copy_node (fields[2]); + TREE_TYPE (fields[3]) = delta_type_node; + DECL_NAME (fields[3]) = delta2_identifier; + DECL_MODE (fields[3]) = TYPE_MODE (delta_type_node); + DECL_SIZE (fields[3]) = TYPE_SIZE (delta_type_node); + TREE_UNSIGNED (fields[3]) = 0; + TREE_CHAIN (fields[2]) = fields[3]; + vtable_entry_type = build_type_variant (vtable_entry_type, 1, 0); + } + record_builtin_type (RID_MAX, VTBL_PTR_TYPE, vtable_entry_type); vtbl_type_node = build_array_type (vtable_entry_type, NULL_TREE); @@ -6625,7 +6676,8 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals, grok_ctor_properties (ctype, decl); if (check == 0 && ! current_function_decl) { - /* FIXME: this should only need to look at IDENTIFIER_GLOBAL_VALUE. */ + /* FIXME: this should only need to look at + IDENTIFIER_GLOBAL_VALUE. */ tmp = lookup_name (DECL_ASSEMBLER_NAME (decl), 0); if (tmp == NULL_TREE) IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl)) = decl; @@ -9515,8 +9567,7 @@ grok_op_properties (decl, virtualp, friendp) /* When the compiler encounters the definition of A::operator new, it doesn't look at the class declaration to find out if it's static. */ if (methodp) - revert_static_member_fn (&TREE_TYPE (decl), &decl, - &TYPE_ARG_TYPES (TREE_TYPE (decl))); + revert_static_member_fn (&decl, NULL, NULL); /* Take care of function decl if we had syntax errors. */ if (argtypes == NULL_TREE) @@ -9531,8 +9582,7 @@ grok_op_properties (decl, virtualp, friendp) || name == ansi_opname[(int) VEC_DELETE_EXPR]) { if (methodp) - revert_static_member_fn (&TREE_TYPE (decl), &decl, - &TYPE_ARG_TYPES (TREE_TYPE (decl))); + revert_static_member_fn (&decl, NULL, NULL); if (argtypes == NULL_TREE) TREE_TYPE (decl) = @@ -9554,7 +9604,7 @@ grok_op_properties (decl, virtualp, friendp) /* An operator function must either be a non-static member function or have at least one parameter of a class, a reference to a class, an enumeration, or a reference to an enumeration. 13.4.0.6 */ - if (! methodp) + if (! methodp || DECL_STATIC_FUNCTION_P (decl)) { if (OPERATOR_TYPENAME_P (name) || name == ansi_opname[(int) CALL_EXPR] @@ -9566,6 +9616,9 @@ grok_op_properties (decl, virtualp, friendp) { tree p = argtypes; + if (DECL_STATIC_FUNCTION_P (decl)) + cp_error ("`%D' must be either a non-static member function or a non-member function", decl); + if (p) for (; TREE_VALUE (p) != void_type_node ; p = TREE_CHAIN (p)) { @@ -12119,20 +12172,30 @@ deactivate_exception_cleanups () } /* Change a static member function definition into a FUNCTION_TYPE, instead - of the METHOD_TYPE that we create when it's originally parsed. */ + of the METHOD_TYPE that we create when it's originally parsed. + + WARNING: DO NOT pass &TREE_TYPE (decl) to FN or &TYPE_ARG_TYPES + (TREE_TYPE (decl)) to ARGTYPES, as doing so will corrupt the types of + other decls. Either pass the addresses of local variables or NULL. */ + void -revert_static_member_fn (fn, decl, argtypes) - tree *fn, *decl, *argtypes; +revert_static_member_fn (decl, fn, argtypes) + tree *decl, *fn, *argtypes; { - tree tmp, function = *fn; + tree tmp; + tree function = fn ? *fn : TREE_TYPE (*decl); + tree args = argtypes ? *argtypes : TYPE_ARG_TYPES (function); - *argtypes = TREE_CHAIN (*argtypes); - tmp = build_function_type (TREE_TYPE (function), *argtypes); + args = TREE_CHAIN (args); + tmp = build_function_type (TREE_TYPE (function), args); tmp = build_type_variant (tmp, TYPE_READONLY (function), TYPE_VOLATILE (function)); tmp = build_exception_variant (TYPE_METHOD_BASETYPE (function), tmp, TYPE_RAISES_EXCEPTIONS (function)); TREE_TYPE (*decl) = tmp; - *fn = tmp; DECL_STATIC_FUNCTION_P (*decl) = 1; + if (fn) + *fn = tmp; + if (argtypes) + *argtypes = args; } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index b910b6731ad5..34b7499fcecb 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -781,6 +781,7 @@ grokclassfn (ctype, cname, function, flags, quals) tree fn_name = DECL_NAME (function); tree arg_types; tree parm; + tree qualtype; if (fn_name == NULL_TREE) { @@ -790,7 +791,9 @@ grokclassfn (ctype, cname, function, flags, quals) } if (quals) - ctype = grok_method_quals (ctype, function, quals); + qualtype = grok_method_quals (ctype, function, quals); + else + qualtype = ctype; arg_types = TYPE_ARG_TYPES (TREE_TYPE (function)); if (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE) @@ -812,7 +815,7 @@ grokclassfn (ctype, cname, function, flags, quals) of virtual baseclasses or not. */ parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node); /* Mark the artificial `__in_chrg' parameter as "artificial". */ - DECL_SOURCE_LINE (parm) = 0; + SET_DECL_ARTIFICIAL (parm); DECL_ARG_TYPE (parm) = integer_type_node; DECL_REGISTER (parm) = 1; TREE_CHAIN (parm) = last_function_parms; @@ -822,7 +825,7 @@ grokclassfn (ctype, cname, function, flags, quals) parm = build_decl (PARM_DECL, this_identifier, type); /* Mark the artificial `this' parameter as "artificial". */ - DECL_SOURCE_LINE (parm) = 0; + SET_DECL_ARTIFICIAL (parm); DECL_ARG_TYPE (parm) = type; /* We can make this a register, so long as we don't accidentally complain if someone tries to take its address. */ @@ -865,7 +868,7 @@ grokclassfn (ctype, cname, function, flags, quals) DECL_ASSEMBLER_NAME (function) = get_identifier (buf); parm = build_decl (PARM_DECL, in_charge_identifier, const_integer_type); /* Mark the artificial `__in_chrg' parameter as "artificial". */ - DECL_SOURCE_LINE (parm) = 0; + SET_DECL_ARTIFICIAL (parm); TREE_USED (parm) = 1; #if 0 /* We don't need to mark the __in_chrg parameter itself as `const' @@ -878,7 +881,7 @@ grokclassfn (ctype, cname, function, flags, quals) /* This is the same chain as DECL_ARGUMENTS (...). */ TREE_CHAIN (last_function_parms) = parm; - TREE_TYPE (function) = build_cplus_method_type (ctype, void_type_node, + TREE_TYPE (function) = build_cplus_method_type (qualtype, void_type_node, arg_types); TYPE_HAS_DESTRUCTOR (ctype) = 1; } @@ -891,7 +894,7 @@ grokclassfn (ctype, cname, function, flags, quals) arg_types = hash_tree_chain (integer_type_node, TREE_CHAIN (arg_types)); TREE_TYPE (function) - = build_cplus_method_type (ctype, + = build_cplus_method_type (qualtype, TREE_TYPE (TREE_TYPE (function)), arg_types); arg_types = TYPE_ARG_TYPES (TREE_TYPE (function)); @@ -901,7 +904,8 @@ grokclassfn (ctype, cname, function, flags, quals) if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE) /* Only true for static member functions. */ - these_arg_types = hash_tree_chain (TYPE_POINTER_TO (ctype), arg_types); + these_arg_types = hash_tree_chain (TYPE_POINTER_TO (qualtype), + arg_types); DECL_ASSEMBLER_NAME (function) = build_decl_overload (fn_name, these_arg_types, @@ -1211,6 +1215,8 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree) if (TREE_CODE (value) == TYPE_DECL) { DECL_NONLOCAL (value) = 1; + DECL_CONTEXT (value) = current_class_type; + DECL_CLASS_CONTEXT (value) = current_class_type; CLASSTYPE_LOCAL_TYPEDECLS (current_class_type) = 1; pushdecl_class_level (value); return value; @@ -2739,7 +2745,7 @@ finish_file () vars = build_decl (TYPE_DECL, get_identifier (" @%$#@!"), integer_type_node); #endif DECL_IGNORED_P (vars) = 1; - DECL_SOURCE_LINE (vars) = 0; + SET_DECL_ARTIFICIAL (vars); pushdecl (vars); #endif diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 1fbf21aa14e5..66f12669b084 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -500,7 +500,7 @@ tree ident_fndecl (t) tree t; { - tree n = IDENTIFIER_GLOBAL_VALUE (t); + tree n = lookup_name (t, 0); if (TREE_CODE (n) == FUNCTION_DECL) return n; diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 07de74c3d119..8a81db9ef5cf 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2791,7 +2791,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals) { /* @@ Should be able to ingest later definitions of this function before use. */ - tree decl = IDENTIFIER_GLOBAL_VALUE (declarator); + tree decl = lookup_name_nonclass (declarator); if (decl == NULL_TREE) { warning ("implicitly declaring `%s' as struct", @@ -3676,6 +3676,26 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) { tree dtor = DECL_MAIN_VARIANT (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0)); tree basetypes = TYPE_BINFO (type); + tree passed_auto_delete; + tree do_delete = NULL_TREE; + + if (use_global_delete) + { + tree cond = fold (build (BIT_AND_EXPR, integer_type_node, + auto_delete, integer_one_node)); + tree call = build_builtin_call + (void_type_node, BID, build_tree_list (NULL_TREE, addr)); + + cond = fold (build (COND_EXPR, void_type_node, cond, + call, void_zero_node)); + if (cond != void_zero_node) + do_delete = cond; + + passed_auto_delete = fold (build (BIT_AND_EXPR, integer_type_node, + auto_delete, integer_two_node)); + } + else + passed_auto_delete = auto_delete; if (flags & LOOKUP_PROTECT) { @@ -3723,8 +3743,10 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) if (function == error_mark_node) return error_mark_node; TREE_TYPE (function) = build_pointer_type (TREE_TYPE (dtor)); - TREE_CHAIN (parms) = build_tree_list (NULL_TREE, auto_delete); + TREE_CHAIN (parms) = build_tree_list (NULL_TREE, passed_auto_delete); expr = build_function_call (function, parms); + if (do_delete) + expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete); if (ptr && (flags & LOOKUP_DESTRUCTOR) == 0) { /* Handle the case where a virtual destructor is @@ -3761,8 +3783,10 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) but that's now obsolete. */ my_friendly_assert (DECL_INITIAL (dtor) != void_type_node, 221); - TREE_CHAIN (parms) = build_tree_list (NULL_TREE, auto_delete); + TREE_CHAIN (parms) = build_tree_list (NULL_TREE, passed_auto_delete); expr = build_function_call (dtor, parms); + if (do_delete) + expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete); if (ifexp != integer_one_node) expr = build (COND_EXPR, void_type_node, diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index ec26d83ca234..51cb77238e24 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -1836,14 +1836,10 @@ cons_up_default_function (type, name, fields, kind) } #endif /* DEBUG_DEFAULT_FUNCTIONS */ - DECL_CLASS_CONTEXT (fn) = type; + DECL_CLASS_CONTEXT (fn) = TYPE_MAIN_VARIANT (type); /* Show that this function was generated by the compiler. */ -#if 0 - DECL_SOURCE_LINE (fn) = 0; -#else - DECL_SYNTHESIZED (fn) = 1; -#endif + SET_DECL_ARTIFICIAL (fn); return fn; } @@ -1956,7 +1952,6 @@ default_assign_ref_body (bufp, lenp, type, fields) btype = BINFO_TYPE (binfo); name = TYPE_NESTED_NAME (btype); - if (!name) name = DECL_NAME(TYPE_NAME(btype)); s = IDENTIFIER_POINTER (name); tneed = (2 * strlen (s)) + 33; @@ -2122,7 +2117,6 @@ default_copy_constructor_body (bufp, lenp, type, fields) btype = BINFO_TYPE (binfo); name = TYPE_NESTED_NAME (btype); - if (!name) name = DECL_NAME(TYPE_NAME(btype)); s = IDENTIFIER_POINTER (name); tneed = (2 * strlen (s)) + 30; diff --git a/gcc/cp/method.c b/gcc/cp/method.c index c61bf487deba..d4ce558abb98 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -135,7 +135,8 @@ do_inline_function_hair (type, friend_list) } /* Allow this decl to be seen in global scope */ - IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (fndecl)) = fndecl; + if (! current_function_decl) + IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (fndecl)) = fndecl; } friend_list = TREE_CHAIN (friend_list); @@ -1242,7 +1243,7 @@ build_opfncall (code, flags, xarg1, xarg2, arg3) else fnname = ansi_opname[(int) code]; - global_fn = IDENTIFIER_GLOBAL_VALUE (fnname); + global_fn = lookup_name_nonclass (fnname); /* This is the last point where we will accept failure. This may be too eager if we wish an overloaded operator not to match, @@ -1682,7 +1683,7 @@ make_thunk (function, delta) thunk = build_decl (THUNK_DECL, get_identifier (buffer), TREE_TYPE (func_decl)); DECL_RESULT (thunk) - = build_decl (RESULT_DECL, NULL_TREE, void_type_node); + = build_decl (RESULT_DECL, NULL_TREE, TREE_TYPE (vtable_entry_type)); make_function_rtl (thunk); DECL_INITIAL (thunk) = function; THUNK_DELTA (thunk) = delta; @@ -1824,7 +1825,7 @@ emit_thunk (thunk_fndecl) emit_insn (gen_rtx (USE, VOIDmode, need_use[--need_use_count])); expand_end_bindings (NULL, 1, 0); - poplevel (0, 0, 1); + poplevel (0, 0, 0); TREE_ASM_WRITTEN (thunk_fndecl) = 1; diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index ed57b7f1c92b..32c5e524fd99 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -80,6 +80,8 @@ void yyerror (); error message if the user supplies an empty conditional expression. */ static char *cond_stmt_keyword; +static int doing_explicit; + /* Nonzero if we have an `extern "C"' acting as an extern specifier. */ int have_extern_spec; int used_extern_spec; @@ -262,7 +264,7 @@ empty_parms () %type qualified_type_name complete_type_name notype_identifier %type complex_type_name nested_name_specifier_1 %type nomods_initdecls nomods_initdcl0 -%type new_initializer new_placement +%type new_initializer new_placement specialization /* in order to recognize aggr tags as defining and thus shadowing. */ %token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN @@ -542,6 +544,7 @@ datadef: | declmods ';' { pedwarn ("empty declaration"); } | explicit_instantiation ';' + { doing_explicit = 0; } | typed_declspecs ';' { tree t = $$; @@ -778,11 +781,16 @@ identifier_defn: | PTYPENAME_DEFN ; +do_explicit: TEMPLATE %prec EMPTY + { doing_explicit = 1; } + ; + explicit_instantiation: - TEMPLATE aggr template_type - { do_type_instantiation ($3); } - | TEMPLATE typed_declspecs declarator + do_explicit specialization template_instantiation + { do_type_instantiation ($3 ? $3 : $2); } + | do_explicit typed_declspecs declarator { do_function_instantiation ($2, $3); } + | do_explicit error ; template_type: @@ -797,8 +805,8 @@ template_type_name: { $$ = lookup_template_class ($$, $3, NULL_TREE); } ; -tmpl.2: %prec EMPTY - /* Always do expansion if it hasn't been done already. */ +tmpl.2: + /* empty */ %prec EMPTY { $$ = instantiate_class_template ($0, 1); } ; @@ -2212,6 +2220,15 @@ aggr: AGGR { error ("no body nor ';' separates two class, struct or union declarations"); } ; +specialization: + aggr template_type_name ';' + { + yyungetc (';', 1); current_aggr = $$; $$ = $2; + if (doing_explicit) + instantiate_class_template ($$, 1); + } + ; + named_class_head_sans_basetype: aggr identifier { current_aggr = $$; $$ = $2; } @@ -2227,6 +2244,7 @@ named_class_head_sans_basetype: overload_template_name ($$, 0); } | aggr template_type_name ':' { yyungetc (':', 1); goto aggr2; } + | specialization ; named_class_head_sans_basetype_defn: @@ -4137,7 +4155,7 @@ operator_name: { $$ = ansi_opname[VEC_NEW_EXPR]; } | operator DELETE '[' ']' { $$ = ansi_opname[VEC_DELETE_EXPR]; } - /* Should we be pushing into class scope to parse this? */ + /* Names here should be looked up in class scope ALSO. */ | operator typed_typespecs conversion_declarator { $$ = grokoptypename ($2, $3); } | operator error diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3bea33d11813..377d4a7a7e3c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1314,7 +1314,7 @@ tsubst (t, args, nargs, in_decl) tree decls; int got_it = 0; - decls = IDENTIFIER_GLOBAL_VALUE (r); + decls = lookup_name (r, 0); if (decls == NULL_TREE) /* no match */; else if (TREE_CODE (decls) == TREE_LIST) @@ -1624,8 +1624,7 @@ instantiate_template (tmpl, targ_ptr) && DECL_STATIC_FUNCTION_P (fndecl)) { tree olddecl = DECL_RESULT (tmpl); - revert_static_member_fn (&TREE_TYPE (olddecl), &DECL_RESULT (tmpl), - &TYPE_ARG_TYPES (TREE_TYPE (olddecl))); + revert_static_member_fn (&DECL_RESULT (tmpl), NULL, NULL); /* Chop off the this pointer that grokclassfn so kindly added for us (it didn't know yet if the fn was static or not). */ DECL_ARGUMENTS (olddecl) = TREE_CHAIN (DECL_ARGUMENTS (olddecl)); diff --git a/gcc/cp/search.c b/gcc/cp/search.c index b601075821c8..946763c4aaa9 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -813,7 +813,7 @@ compute_access (basetype_path, field) PUBLIC_RETURN; /* Member found immediately within object. */ - if (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE || static_mem) + if (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE) { /* Are we (or an enclosing scope) friends with the class that has FIELD? */ @@ -847,7 +847,8 @@ compute_access (basetype_path, field) types = basetype_path; via_protected = 0; access = access_default; - protected_ok = 0; + protected_ok = static_mem && current_class_type + && ACCESSIBLY_DERIVED_FROM_P (BINFO_TYPE (types), current_class_type); while (1) { @@ -1024,7 +1025,6 @@ lookup_field (xbasetype, name, protect, want_type) we know that binfo of a virtual base class will always == itself when found along any line. (mrs) */ - /* Things for memoization. */ char *errstr = 0; /* Set this to nonzero if we don't know how to compute @@ -1209,7 +1209,11 @@ lookup_field (xbasetype, name, protect, want_type) if (nval || lookup_fnfields_here (type, name)>=0) { - if (rval_binfo && hides (rval_binfo_h, binfo_h)) + if (nval && nval == rval && SHARED_MEMBER_P (nval)) + { + /* This is ok, the member found is the same [class.ambig] */ + } + else if (rval_binfo && hides (rval_binfo_h, binfo_h)) { /* This is ok, the member found is in rval_binfo, not here (binfo). */ @@ -1476,7 +1480,6 @@ lookup_fnfields (basetype_path, name, complain) /* For now, don't try this. */ int protect = complain; - /* Things for memoization. */ char *errstr = 0; /* Set this to nonzero if we don't know how to compute @@ -1578,11 +1581,6 @@ lookup_fnfields (basetype_path, name, complain) TREE_TYPE (entry) = NULL_TREE; } - if (errstr && protect) - { - error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type)); - return error_mark_node; - } return rvals; } rval = NULL_TREE; @@ -1697,7 +1695,7 @@ lookup_fnfields (basetype_path, name, complain) else { /* This is ambiguous. */ - errstr = "request for member `%s' is ambiguous"; + errstr = "request for method `%D' is ambiguous"; rvals = error_mark_node; break; } @@ -1733,7 +1731,7 @@ lookup_fnfields (basetype_path, name, complain) if (errstr && protect) { - error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type)); + cp_error (errstr, name); rvals = error_mark_node; } @@ -1946,7 +1944,8 @@ get_matching_virtual (binfo, fndecl, dtorp) if (IDENTIFIER_ERROR_LOCUS (name) == NULL_TREE && ! comptypes (TREE_TYPE (TREE_TYPE (tmp)), drettype, 1)) { - cp_error ("conflicting return type specified for virtual function `%D'", fndecl); + cp_error ("conflicting return type specified for virtual function `%#D'", fndecl); + cp_error ("overriding definition as `%#D'", tmp); SET_IDENTIFIER_ERROR_LOCUS (name, basetype); } break; @@ -2368,7 +2367,7 @@ dfs_debug_mark (binfo) /* We cannot rely on some alien method to solve our problems, so we must write out the debug info ourselves. */ if (write_symbols != DWARF_DEBUG) - DECL_IGNORED_P (TYPE_NAME (t)) = 0; + TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 0; if (! TREE_ASM_WRITTEN (TYPE_NAME (t))) rest_of_type_compilation (t, global_bindings_p ()); } @@ -3175,27 +3174,3 @@ reinit_search_statistics () n_outer_fields_searched = 0; n_contexts_saved = 0; } - -tree -lookup_nested_tag (type, name) - tree type, name; -{ - tree tags = CLASSTYPE_TAGS (type); - - for (; tags; tags = TREE_CHAIN (tags)) - { - /* The TREE_PURPOSE of an enum tag (which becomes a member of the - enclosing class) is set to the name for the enum type. So, if - name is `bar', and we strike `baz' for `enum bar { baz }', then - this test will be true. */ - if (TREE_PURPOSE (tags) == name) - break; - } - if (tags) - return TYPE_NAME (TREE_VALUE (tags)); - - if (TYPE_CONTEXT (type)) - return lookup_nested_tag (TYPE_CONTEXT (type), name); - - return NULL_TREE; -} diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 9ea4408e12da..55f5f86f3c37 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2114,28 +2114,35 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function) return instance; vtbl = convert_pointer_to (ptr_type_node, instance); - vtbl = build (PLUS_EXPR, - build_pointer_type (build_pointer_type (memptr_type)), - vtbl, convert (sizetype, delta2)); + vtbl + = build (PLUS_EXPR, + build_pointer_type (build_pointer_type (vtable_entry_type)), + vtbl, convert (sizetype, delta2)); vtbl = build_indirect_ref (vtbl, NULL_PTR); aref = build_array_ref (vtbl, size_binop (MINUS_EXPR, index, integer_one_node)); - aref = save_expr (aref); + if (! flag_vtable_thunks) + { + aref = save_expr (aref); - /* Save the intermediate result in a SAVE_EXPR so we don't have to - compute each component of the virtual function pointer twice. */ - if (/* !building_cleanup && */ TREE_CODE (aref) == INDIRECT_REF) - TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0)); + /* Save the intermediate result in a SAVE_EXPR so we don't have to + compute each component of the virtual function pointer twice. */ + if (/* !building_cleanup && */ TREE_CODE (aref) == INDIRECT_REF) + TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0)); - delta = build (PLUS_EXPR, integer_type_node, - build_conditional_expr (e1, build_component_ref (aref, delta_identifier, 0, 0), integer_zero_node), - delta); + delta = build (PLUS_EXPR, integer_type_node, + build_conditional_expr (e1, build_component_ref (aref, delta_identifier, 0, 0), integer_zero_node), + delta); + } *instance_ptrptr = build (PLUS_EXPR, TREE_TYPE (*instance_ptrptr), *instance_ptrptr, convert (integer_type_node, delta)); - e2 = build_component_ref (aref, pfn_identifier, 0, 0); + if (flag_vtable_thunks) + e2 = aref; + else + e2 = build_component_ref (aref, pfn_identifier, 0, 0); e3 = PFN_FROM_PTRMEMFUNC (function); TREE_TYPE (e2) = TREE_TYPE (e3); @@ -5502,10 +5509,16 @@ build_modify_expr (lhs, modifycode, rhs) /* check to see if there is an assignment to `this' */ if (lhs == current_class_decl) { - if (flag_this_is_variable > 0 - && DECL_NAME (current_function_decl) != NULL_TREE - && current_class_name != DECL_NAME (current_function_decl)) - warning ("assignment to `this' not in constructor or destructor"); + if (DECL_NAME (current_function_decl) != NULL_TREE) + { + /* ARM 18.3.3 and draft standard section C.11 say that assigning + something to this is an anachronism. */ + if (pedantic) + warning ("anachronistic assignment to `this' pointer"); + else if (flag_this_is_variable > 0 + && current_class_name != DECL_NAME (current_function_decl)) + warning ("assignment to `this' not in constructor or destructor"); + } current_function_just_assigned_this = 1; } @@ -5670,7 +5683,7 @@ build_modify_expr (lhs, modifycode, rhs) { /* Allow array assignment in compiler-generated code. */ if ((pedantic || flag_ansi) - && ! DECL_SYNTHESIZED (current_function_decl)) + && ! DECL_ARTIFICIAL (current_function_decl)) pedwarn ("ANSI C++ forbids assignment between arrays"); /* Have to wrap this in RTL_EXPR for two cases: @@ -6600,7 +6613,7 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum) { tree init = build_method_call (exp, constructor_name_full (type), build_tree_list (NULL_TREE, rhs), - NULL_TREE, LOOKUP_NORMAL); + TYPE_BINFO (type), LOOKUP_NORMAL); if (init == error_mark_node) return error_mark_node; diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index fd426a4cd9e3..53106b2e44d8 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1362,10 +1362,9 @@ build_m_component_ref (datum, component) /* Return a tree node for the expression TYPENAME '(' PARMS ')'. - Because we cannot tell whether this construct is really - a function call or a call to a constructor or a request for - a type conversion, we try all three, and report any ambiguities - we find. */ + Because we cannot tell whether this construct is really a call to a + constructor or a request for a type conversion, we try both, and + report any ambiguities we find. */ tree build_functional_cast (exp, parms) tree exp; @@ -1375,8 +1374,6 @@ build_functional_cast (exp, parms) or a C cast in C++'s `functional' notation. */ tree type, name = NULL_TREE; tree expr_as_ctor = NULL_TREE; - tree expr_as_method = NULL_TREE; - tree expr_as_fncall = NULL_TREE; tree expr_as_conversion = NULL_TREE; if (exp == error_mark_node || parms == error_mark_node) @@ -1423,50 +1420,16 @@ build_functional_cast (exp, parms) name = DECL_NAME (name); } - /* Try evaluating as a call to a function. */ - if (IDENTIFIER_CLASS_VALUE (name) - && (TREE_CODE (IDENTIFIER_CLASS_VALUE (name)) == TREE_LIST - || TREE_CODE (IDENTIFIER_CLASS_VALUE (name)) == FUNCTION_DECL)) - { - expr_as_method = build_method_call (current_class_decl, name, parms, - NULL_TREE, LOOKUP_SPECULATIVELY); - if (expr_as_method == error_mark_node) - expr_as_method = NULL_TREE; - } - - if (IDENTIFIER_GLOBAL_VALUE (name) - && (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TREE_LIST - || TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == FUNCTION_DECL)) - { - expr_as_fncall = build_overload_call (name, parms, 0, - (struct candidate *)0); - if (expr_as_fncall == NULL_TREE) - expr_as_fncall = error_mark_node; - } - if (! IS_AGGR_TYPE (type)) { /* this must build a C cast */ if (parms == NULL_TREE) - { - if (expr_as_method || expr_as_fncall) - goto return_function; - - return build1 (NOP_EXPR, type, integer_zero_node); - } - if (expr_as_method - || (expr_as_fncall && expr_as_fncall != error_mark_node)) - { - cp_error ("ambiguity between cast to `%#T' and function call", type); - return error_mark_node; - } + return build1 (NOP_EXPR, type, integer_zero_node); return build_c_cast (type, build_compound_expr (parms)); } if (TYPE_SIZE (type) == NULL_TREE) { - if (expr_as_method || expr_as_fncall) - goto return_function; cp_error ("type `%T' is not yet defined", type); return error_mark_node; } @@ -1475,7 +1438,7 @@ build_functional_cast (exp, parms) expr_as_conversion = build_type_conversion (CONVERT_EXPR, type, TREE_VALUE (parms), 0); - if (! TYPE_NEEDS_CONSTRUCTING (type) && parms != NULL_TREE) + if (! TYPE_HAS_CONSTRUCTOR (type) && parms != NULL_TREE) { char *msg = 0; @@ -1488,71 +1451,13 @@ build_functional_cast (exp, parms) } else msg = "type `%T' does not have a constructor"; - if ((expr_as_method || expr_as_fncall) && expr_as_conversion) - msg = "ambiguity between conversion to `%T' and function call"; - else if (expr_as_method || expr_as_fncall) - goto return_function; - else if (expr_as_conversion) + if (expr_as_conversion) return expr_as_conversion; cp_error (msg, type); return error_mark_node; } -#if 0 - /* Constructors are not inherited... --jason */ - if (! TYPE_HAS_CONSTRUCTOR (type)) - { - if (expr_as_method || expr_as_fncall) - goto return_function; - if (expr_as_conversion) - return expr_as_conversion; - - /* Look through this type until we find the - base type which has a constructor. */ - do - { - tree binfos = TYPE_BINFO_BASETYPES (type); - int i, index = 0; - - while (binfos && TREE_VEC_LENGTH (binfos) == 1 - && ! TYPE_HAS_CONSTRUCTOR (type)) - { - type = BINFO_TYPE (TREE_VEC_ELT (binfos, 0)); - binfos = TYPE_BINFO_BASETYPES (type); - } - if (TYPE_HAS_CONSTRUCTOR (type)) - break; - /* Hack for MI. */ - i = binfos ? TREE_VEC_LENGTH (binfos) : 0; - if (i == 0) break; - while (--i > 0) - { - if (TYPE_HAS_CONSTRUCTOR (BINFO_TYPE (TREE_VEC_ELT (binfos, i)))) - { - if (index == 0) - index = i; - else - { - error ("multiple base classes with constructor, ambiguous"); - type = 0; - break; - } - } - } - if (type == 0) - break; - } while (! TYPE_HAS_CONSTRUCTOR (type)); - if (type == 0) - return error_mark_node; - } - name = TYPE_NAME (type); - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); - - my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 321); -#endif - { int flags = LOOKUP_SPECULATIVELY|LOOKUP_COMPLAIN; @@ -1565,20 +1470,7 @@ build_functional_cast (exp, parms) if (expr_as_ctor && expr_as_ctor != error_mark_node) { -#if 0 - /* mrs Mar 12, 1992 I claim that if it is a constructor, it is - impossible to be an expr_as_method, without being a - constructor call. */ - if (expr_as_method - || (expr_as_fncall && expr_as_fncall != error_mark_node)) -#else - if (expr_as_fncall && expr_as_fncall != error_mark_node) -#endif - { - cp_warning ("function hides constructor for class `%T'", type); - return expr_as_fncall; - } - else if (expr_as_conversion && expr_as_conversion != error_mark_node) + if (expr_as_conversion && expr_as_conversion != error_mark_node) { /* ANSI C++ June 5 1992 WP 12.3.2.6.1 */ cp_error ("ambiguity between conversion to `%T' and constructor", @@ -1632,23 +1524,8 @@ build_functional_cast (exp, parms) } if (expr_as_conversion) - { - if (expr_as_method || expr_as_fncall) - { - cp_error ("ambiguity between conversion to `%T' and function call", - type); - return error_mark_node; - } - return expr_as_conversion; - } - return_function: - if (expr_as_method) - return build_method_call (current_class_decl, name, parms, - NULL_TREE, LOOKUP_NORMAL); - if (expr_as_fncall) - return expr_as_fncall == error_mark_node - ? build_overload_call (name, parms, LOOKUP_COMPLAIN, (struct candidate *)0) - : expr_as_fncall; + return expr_as_conversion; + cp_error ("no suitable conversion to `%T' exists", type); return error_mark_node; }