diff options
-rw-r--r-- | gcc/cp/ChangeLog | 163 | ||||
-rw-r--r-- | gcc/cp/Make-lang.in | 17 | ||||
-rw-r--r-- | gcc/cp/Makefile.in | 2 | ||||
-rw-r--r-- | gcc/cp/call.c | 25 | ||||
-rw-r--r-- | gcc/cp/class.c | 6 | ||||
-rw-r--r-- | gcc/cp/cp-tree.def | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 20 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 135 | ||||
-rw-r--r-- | gcc/cp/decl.c | 31 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 6 | ||||
-rw-r--r-- | gcc/cp/except.c | 15 | ||||
-rw-r--r-- | gcc/cp/expr.c | 3 | ||||
-rw-r--r-- | gcc/cp/init.c | 86 | ||||
-rw-r--r-- | gcc/cp/lex.c | 58 | ||||
-rw-r--r-- | gcc/cp/parse.y | 73 | ||||
-rw-r--r-- | gcc/cp/pt.c | 33 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 5 | ||||
-rw-r--r-- | gcc/cp/search.c | 7 | ||||
-rw-r--r-- | gcc/cp/tree.c | 10 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 44 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 18 | ||||
-rw-r--r-- | gcc/cp/xref.c | 3 |
22 files changed, 506 insertions, 256 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a5cd33947f2..1a2aaee49ff 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,9 +1,164 @@ -Tue Nov 12 08:39:17 1996 Brendan Kehoe <brendan@lisa.cygnus.com> +Mon Nov 25 15:16:41 1996 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - * decl.c (cp_finish_decl): In MINIMAL_PARSE_MODE, only try to use - the DECL_VINDEX of DECL if it's set. + * Make-lang.in (c++.stage[1234]): Depend upon stage[1-4]-start, so + that make -j3 bootstrap works better. - * tree.c (mapcar): Handle RTL_EXPR. +Sun Nov 24 02:09:39 1996 Jason Merrill <jason@yorick.cygnus.com> + + * decl.c (pushtag): Do pushdecl for anon tags. + +Thu Nov 21 16:30:24 1996 Jason Merrill <jason@yorick.cygnus.com> + + * typeck.c (c_expand_return): Fix logic. + (unary_complex_lvalue): Avoid unused warning on address of INIT_EXPR. + + * decl.c (grokfndecl): Also note_debug_info_needed on ctype here. + +Wed Nov 20 18:47:31 1996 Bob Manson <manson@charmed.cygnus.com> + + * g++.c (main): Make sure arglist has a final NULL entry. Add + PEXECUTE_LAST to the flags passed to pexecute, as otherwise + stdin/stdout of the invoked program are redirected to + nowheresville. + +Tue Nov 19 16:12:44 1996 Jason Merrill <jason@yorick.cygnus.com> + + * decl.c (implicitly_declare): Set DECL_ARTIFICIAL. + +Tue Nov 19 15:48:19 1996 Mike Stump <mrs@cygnus.com> + + * init.c (resolve_offset_ref): Handle obj.vfn better. + * typeck.c (build_component_ref): Set TREE_TYPE on result from + build_vfn_ref. + +Tue Nov 19 13:14:33 1996 Mike Stump <mrs@cygnus.com> + + * typeck.c (convert_for_assignment): Also handle anachronistic + implicit conversions from (::*)() to cv void*. + * cvt.c (cp_convert_to_pointer): Likewise. + +Mon Nov 18 17:05:26 1996 Jason Merrill <jason@yorick.cygnus.com> + + * lex.c (handle_cp_pragma): Fix bogus warning. + +Mon Nov 18 16:10:43 1996 Mike Stump <mrs@cygnus.com> + + * cvt.c (cp_convert_to_pointer): Avoid thinking a POINTER_TYPE + (METHOD_TYPE) is a TYPE_PTRMEMFUNC_P. + +Thu Nov 14 23:18:17 1996 Jason Merrill <jason@yorick.cygnus.com> + + * class.c (finish_struct_1): Support DWARF2_DEBUG. + * search.c (dfs_debug_mark): Likewise. + * decl2.c (finish_vtable_vardecl): Likewise. + * decl.c (pushtag, finish_enum): Likewise. + * lex.c (check_newline): Use debug_* instead of calling *out + functions directly. + +Thu Nov 14 15:21:46 1996 Brendan Kehoe <brendan@lisa.cygnus.com> + + * Make-lang.in (cplib2.ready): Add else clause to avoid problems + on some picky hosts. + +Wed Nov 13 12:32:07 1996 Jason Merrill <jason@yorick.cygnus.com> + + * class.c (finish_struct_1): A class has a non-trivial copy + constructor if it has virtual functions. + + * cvt.c (cp_convert): Always call a constructor. + + * call.c (reference_binding): Still tack on a REF_BIND + for bad conversions. + (build_user_type_conversion_1): Propagate ICS_BAD_FLAG. + + * typeck.c (convert_arguments): Pass LOOKUP_ONLYCONVERTING. + (c_expand_return): Likewise. + * typeck2.c (digest_init): Likewise for { }. + * init.c (expand_aggr_init_1): Keep the CONSTRUCTOR handling. + * cvt.c (cp_convert): Handle failure better. + +Wed Nov 13 11:51:20 1996 Brendan Kehoe <brendan@lisa.cygnus.com> + + * g++.c (main): Also set PEXECUTE_SEARCH, to make the invocation + of GCC be path-relative. + +Wed Nov 13 11:27:16 1996 Michael Meissner <meissner@tiktok.cygnus.com> + + * Make-lang.in (g++-cross): G++-cross doesn't need version.o, but + it does need choose-temp.o and pexecute.o. + +Wed Nov 13 07:53:38 1996 Brendan Kehoe <brendan@lisa.cygnus.com> + + * g++.c (error) [!HAVE_VPRINTF]: Put error back for the only time + that we still use it. + (P_tmpdir, R_OK, W_OK, X_OK) [__MSDOS__]: Delete unnecessary macros. + +Wed Nov 13 02:00:26 1996 Jason Merrill <jason@yorick.cygnus.com> + + * init.c (expand_default_init): Avoid calling constructors to + initialize reference temps. + + * cvt.c (convert_to_reference): Fix. + +Tue Nov 12 19:10:07 1996 Jason Merrill <jason@yorick.cygnus.com> + + * cvt.c (cp_convert): Simplify for flag_ansi_overloading. + (convert_to_reference): Likewise. + * typeck.c (convert_for_initialization): Likewise. + * init.c (expand_default_init): Likewise. + (expand_aggr_init_1): Likewise. + * cp-tree.h (CONV_NONCONVERTING): Lose. + * typeck.c (build_c_cast): Lose allow_nonconverting parm. + * *.c: Adjust. + * call.c (build_user_type_conversion_1): Assume LOOKUP_ONLYCONVERTING. + +Tue Nov 12 16:29:04 1996 Brendan Kehoe <brendan@canuck.cygnus.com> + + * pt.c (tsubst_expr): Reverse args to expand_start_catch_block. + +Tue Nov 12 15:26:17 1996 Jason Merrill <jason@yorick.cygnus.com> + + * init.c (expand_aggr_init_1): Don't crash on non-constructor + TARGET_EXPR. + +Tue Nov 12 14:00:50 1996 Brendan Kehoe <brendan@lisa.cygnus.com> + + * g++.c: Include gansidecl.h. + (VPROTO, PVPROTO, VA_START): Delete. + (choose_temp_base_try, choose_temp_base, perror_exec, + run_dos) [__MSDOS__]: Delete fns. + (pfatal_with_name): Delete fn. + (temp_filename): Declare like in gcc.c. + (pexecute, pwait, choose_temp_base): Declare from gcc.c. + (error_count, signal_count): Define. + (error): Delete both definitions. + (PEXECUTE_{FIRST,LAST,SEARCH,VERBOSE}): Define from gcc.c. + (pfatal_pexecute): Add fn from gcc.c. + (main): Rename local VERBOSE var to VERBOSE_FLAG. Rewrite the + code to use the pexecute stuff also used by gcc.c. + (MIN_FATAL_STATUS): Define. + * Make-lang.in (g++): Add dependency on and linking with + choose-temp.o and pexecute.o. + + * cp-tree.h: Include gansidecl.h. + (STDIO_PROTO): Delete #undef/#define. + * cvt.c (NULL): Delete #undef/#define. + * expr.c (NULL): Likewise. + * init.c (NULL): Likewise. + * rtti.c (NULL): Likewise. + * xref.c (NULL): Likewise. + + * cp-tree.h (build_user_type_conversion): Add prototype. + * call.c (build_user_type_conversion): Delete prototype. Correct + decl of FLAGS arg to be an int. + * cvt.c (build_user_type_conversion): Likewise. + +Tue Nov 12 12:16:20 1996 Jason Merrill <jason@yorick.cygnus.com> + + * cp-tree.def: Add TRY_BLOCK and HANDLER. + * except.c (expand_start_catch_block): Support templates. + * parse.y (try_block, handler_seq): Likewise. + * pt.c (tsubst_expr): Support TRY_BLOCK and HANDLER. Mon Nov 11 13:57:31 1996 Jason Merrill <jason@yorick.cygnus.com> diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index b6b0105857c..45037eb0f71 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -72,13 +72,13 @@ C++ c++: cc1plus .PHONY: C++ c++ # Create the compiler driver for g++. -g++: $(srcdir)/cp/g++.c $(CONFIG_H) $(LIBDEPS) - $(CC) $(ALL_CFLAGS) $(INCLUDES) $(LDFLAGS) -o $@ $(srcdir)/cp/g++.c $(LIBS) +g++: $(srcdir)/cp/g++.c $(CONFIG_H) choose-temp.o pexecute.o $(LIBDEPS) + $(CC) $(ALL_CFLAGS) $(INCLUDES) $(LDFLAGS) -o $@ $(srcdir)/cp/g++.c choose-temp.o pexecute.o $(LIBS) # Create a version of the g++ driver which calls the cross-compiler. -g++-cross: $(srcdir)/cp/g++.c version.o $(LIBDEPS) +g++-cross: $(srcdir)/cp/g++.c choose-temp.o pexecute.o $(LIBDEPS) $(CC) $(ALL_CFLAGS) $(INCLUDES) $(LDFLAGS) -o $@ \ - -DGCC_NAME=\"$(GCC_CROSS_NAME)\" $(srcdir)/cp/g++.c version.o $(LIBS) + -DGCC_NAME=\"$(GCC_CROSS_NAME)\" $(srcdir)/cp/g++.c choose-temp.o pexecute.o $(LIBS) cxxmain.o: cplus-dem.c demangle.h rm -f cxxmain.c @@ -150,6 +150,7 @@ cplib2.ready: $(GCC_PASSES) $(LIBGCC2_DEPS) stmp-int-hdrs touch cplib2.ready; \ fi; \ rm -f cplib2.new; \ + else true ; \ fi @if [ -f cplib2.ready ]; then true; else \ touch cplib2.ready; \ @@ -225,13 +226,13 @@ c++.maintainer-clean: # Stage hooks: # The main makefile has already created stage?/cp. -c++.stage1: +c++.stage1: stage1-start -mv cp/*$(objext) stage1/cp -c++.stage2: +c++.stage2: stage2-start -mv cp/*$(objext) stage2/cp -c++.stage3: +c++.stage3: stage3-start -mv cp/*$(objext) stage3/cp -c++.stage4: +c++.stage4: stage4-start -mv cp/*$(objext) stage4/cp # Maintenance hooks: diff --git a/gcc/cp/Makefile.in b/gcc/cp/Makefile.in index 28b15cfce22..dc86dc38242 100644 --- a/gcc/cp/Makefile.in +++ b/gcc/cp/Makefile.in @@ -242,7 +242,7 @@ except.o : except.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) $(sr expr.o : expr.c $(CONFIG_H) $(CXX_TREE_H) $(RTL_H) $(srcdir)/../flags.h \ $(srcdir)/../expr.h ../insn-codes.h xref.o : xref.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../input.h -pt.o : pt.c $(CONFIG_H) $(CXX_TREE_H) decl.h $(PARSE_H) +pt.o : pt.c $(CONFIG_H) $(CXX_TREE_H) decl.h $(PARSE_H) lex.h error.o : error.c $(CONFIG_H) $(CXX_TREE_H) errfn.o : errfn.c $(CONFIG_H) $(CXX_TREE_H) sig.o : sig.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 576ed3a2e42..d1adc3ab4cc 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -3179,8 +3179,7 @@ reference_binding (rto, from, expr, flags) else conv = NULL_TREE; - if (! conv && TYPE_READONLY (to) && ! TYPE_VOLATILE (to) - && (flags & LOOKUP_NO_TEMP_BIND) == 0) + if (! conv) { conv = standard_conversion (TYPE_MAIN_VARIANT (to), strip_top_quals (from), expr); @@ -3192,15 +3191,10 @@ reference_binding (rto, from, expr, flags) if (TREE_CODE (TREE_OPERAND (conv, 0)) == BASE_CONV) TREE_OPERAND (conv, 0) = TREE_OPERAND (TREE_OPERAND (conv, 0), 0); } - } - - if (! conv) - { - conv = standard_conversion - (TYPE_MAIN_VARIANT (to), strip_top_quals (from), expr); - if (conv) + if (conv && ! (TYPE_READONLY (to) && ! TYPE_VOLATILE (to) + && (flags & LOOKUP_NO_TEMP_BIND) == 0)) ICS_BAD_FLAG (conv) = 1; - } + } return conv; } @@ -4149,7 +4143,7 @@ print_z_candidates (candidates) } else cp_error_at ("%s %+D%s", str, candidates->fn, - candidates->viable == -1 ? " <bad>" : ""); + candidates->viable == -1 ? " <near match>" : ""); str = " "; } } @@ -4189,7 +4183,7 @@ build_user_type_conversion_1 (totype, expr, flags) } for (; ctors; ctors = DECL_CHAIN (ctors)) { - if ((flags & LOOKUP_ONLYCONVERTING) && DECL_NONCONVERTING_P (ctors)) + if (DECL_NONCONVERTING_P (ctors)) continue; candidates = add_function_candidate (candidates, ctors, args, flags); @@ -4259,13 +4253,16 @@ build_user_type_conversion_1 (totype, expr, flags) ? totype : non_reference (TREE_TYPE (TREE_TYPE (cand->fn)))), NULL_TREE, cand->fn, cand->convs, cand->basetype_path); ICS_USER_FLAG (cand->second_conv) = 1; + if (cand->viable == -1) + ICS_BAD_FLAG (cand->second_conv) = 1; return cand; } tree build_user_type_conversion (totype, expr, flags) - tree totype, expr, flags; + tree totype, expr; + int flags; { struct z_candidate *cand = build_user_type_conversion_1 (totype, expr, flags); @@ -5237,7 +5234,7 @@ build_new_method_call (instance, name, args, basetype_path, flags) mem_args = tree_cons (NULL_TREE, instance_ptr, args); for (; t; t = DECL_CHAIN (t)) { - /* XXX copy-init should go through build_user_type_conversion. */ + /* We can end up here for copy-init of same or base class. */ if (name == ctor_identifier && (flags & LOOKUP_ONLYCONVERTING) && DECL_NONCONVERTING_P (t)) diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 356c9ca988d..67498ee6c9d 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -3593,10 +3593,10 @@ finish_struct_1 (t, warn_anon) TYPE_HAS_COMPLEX_INIT_REF (t) |= (TYPE_HAS_INIT_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t) - || any_default_members); + || has_virtual || any_default_members); TYPE_NEEDS_CONSTRUCTING (t) |= (TYPE_HAS_CONSTRUCTOR (t) || TYPE_USES_VIRTUAL_BASECLASSES (t) - || has_virtual || any_default_members || first_vfn_base_index >= 0); + || has_virtual || any_default_members); if (! IS_SIGNATURE (t)) CLASSTYPE_NON_AGGREGATE (t) = ! aggregate || has_virtual || TYPE_HAS_CONSTRUCTOR (t); @@ -4180,7 +4180,7 @@ finish_struct_1 (t, warn_anon) } #endif - if (write_symbols != DWARF_DEBUG) + if (write_symbols != DWARF_DEBUG && write_symbols != DWARF2_DEBUG) { /* If the type has methods, we want to think about cutting down the amount of symbol table stuff we output. The value stored in diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index ab271ea63fd..be97b02ca95 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -138,6 +138,8 @@ DEFTREECODE (GOTO_STMT, "goto_stmt", "e", 1) DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", "e", 2) DEFTREECODE (CASE_LABEL, "case_label", "e", 2) DEFTREECODE (RETURN_INIT, "return_init", "e", 2) +DEFTREECODE (TRY_BLOCK, "try_stmt", "e", 2) +DEFTREECODE (HANDLER, "catch_stmt", "e", 2) DEFTREECODE (IDENTITY_CONV, "identity_conv", "e", 1) DEFTREECODE (LVALUE_CONV, "lvalue_conv", "e", 1) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f9f76a33932..528f1b7f42b 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -22,17 +22,7 @@ Boston, MA 02111-1307, USA. */ #ifndef _CP_TREE_H #define _CP_TREE_H -/* Borrow everything that is C from c-tree.h, - but do so by copy, not by inclusion, since c-tree.h defines - lang_identifier. */ - -#ifndef STDIO_PROTO -#ifdef BUFSIZ -#define STDIO_PROTO(ARGS) PROTO(ARGS) -#else -#define STDIO_PROTO(ARGS) () -#endif -#endif +#include "gansidecl.h" /* Language-dependent contents of an identifier. */ @@ -1881,7 +1871,6 @@ extern tree current_class_type; /* _TYPE: the type of the current class */ CONV_CONST : Perform the explicit conversions for const_cast. CONV_REINTERPRET: Perform the explicit conversions for reinterpret_cast. CONV_PRIVATE : Perform upcasts to private bases. - CONV_NONCONVERTING : Allow non-converting constructors to be used. CONV_FORCE_TEMP : Require a new temporary when converting to the same aggregate type. */ @@ -1890,7 +1879,7 @@ extern tree current_class_type; /* _TYPE: the type of the current class */ #define CONV_CONST 4 #define CONV_REINTERPRET 8 #define CONV_PRIVATE 16 -#define CONV_NONCONVERTING 32 +/* #define CONV_NONCONVERTING 32 */ #define CONV_FORCE_TEMP 64 #define CONV_STATIC_CAST (CONV_IMPLICIT | CONV_STATIC | CONV_FORCE_TEMP) #define CONV_OLD_CONVERT (CONV_IMPLICIT | CONV_STATIC | CONV_CONST \ @@ -1938,7 +1927,7 @@ extern void overflow_warning PROTO((tree)); extern void unsigned_conversion_warning PROTO((tree, tree)); /* in call.c */ -extern struct candidate *ansi_c_bullshit; +extern struct candidate *ansi_c_filler; extern int rank_for_overload PROTO((struct candidate *, struct candidate *)); extern int can_convert PROTO((tree, tree)); @@ -1955,6 +1944,7 @@ extern tree build_method_call PROTO((tree, tree, tree, tree, int)); extern tree build_overload_call_real PROTO((tree, tree, int, struct candidate *, int)); extern tree build_overload_call PROTO((tree, tree, int)); extern tree build_new_method_call PROTO((tree, tree, tree, tree, int)); +extern tree build_user_type_conversion PROTO((tree, tree, int)); extern tree build_new_function_call PROTO((tree, tree, tree)); extern tree build_new_op PROTO((enum tree_code, int, tree, tree, tree)); @@ -2471,7 +2461,7 @@ extern tree build_compound_expr PROTO((tree)); extern tree build_static_cast PROTO((tree, tree)); extern tree build_reinterpret_cast PROTO((tree, tree)); extern tree build_const_cast PROTO((tree, tree)); -extern tree build_c_cast PROTO((tree, tree, int)); +extern tree build_c_cast PROTO((tree, tree)); extern tree build_x_modify_expr PROTO((tree, enum tree_code, tree)); extern tree build_modify_expr PROTO((tree, enum tree_code, tree)); extern int language_lvalue_valid PROTO((tree)); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 68b3d6c2de8..410a34b00c7 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -32,10 +32,7 @@ Boston, MA 02111-1307, USA. */ #include "class.h" #include "convert.h" -#undef NULL -#define NULL (char *)0 - -tree build_user_type_conversion (); +extern tree static_aggregates; /* Change of width--truncation and extension of integers or reals-- is represented with NOP_EXPR. Proper functioning of many things @@ -151,21 +148,18 @@ cp_convert_to_pointer (type, expr) if (TYPE_PTRMEMFUNC_P (type)) type = TYPE_PTRMEMFUNC_FN_TYPE (type); - if (TYPE_PTRMEMFUNC_P (intype)) - intype = TYPE_PTRMEMFUNC_FN_TYPE (intype); - /* Handle anachronistic conversions from (::*)() to void* or (*)(). */ + /* Handle anachronistic conversions from (::*)() to cv void* or (*)(). */ if (TREE_CODE (type) == POINTER_TYPE && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE - || TREE_TYPE (type) == void_type_node)) + || TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)) { /* Allow an implicit this pointer for pointer to member functions. */ - if (TREE_CODE (intype) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (intype)) == METHOD_TYPE) + if (TYPE_PTRMEMFUNC_P (intype)) { tree decl, basebinfo; - tree fntype = TREE_TYPE (intype); + tree fntype = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (intype)); tree t = TYPE_METHOD_BASETYPE (fntype); if (current_class_type == 0 @@ -198,6 +192,9 @@ cp_convert_to_pointer (type, expr) intype = TREE_TYPE (expr); } + if (TYPE_PTRMEMFUNC_P (intype)) + intype = TYPE_PTRMEMFUNC_FN_TYPE (intype); + form = TREE_CODE (intype); if (form == POINTER_TYPE || form == REFERENCE_TYPE) @@ -589,7 +586,7 @@ build_up_reference (type, arg, flags, checkconst) break; } - if ((flags&DIRECT_BIND) + if ((flags & DIRECT_BIND) && ! real_lvalue_p (targ)) { if (toplevel_bindings_p ()) @@ -605,7 +602,7 @@ build_up_reference (type, arg, flags, checkconst) DECL_INITIAL (arg) = targ; cp_finish_decl (arg, targ, NULL_TREE, 0, LOOKUP_ONLYCONVERTING); } - else if (TREE_ADDRESSABLE (targ) == 0 && !(flags&DIRECT_BIND)) + else if (TREE_ADDRESSABLE (targ) == 0 && !(flags & DIRECT_BIND)) { tree slot = build_decl (VAR_DECL, NULL_TREE, argtype); arg = build (TARGET_EXPR, argtype, slot, arg, NULL_TREE, NULL_TREE); @@ -737,7 +734,19 @@ convert_to_reference (reftype, expr, convtype, flags, decl) if (rval != error_mark_node) rval = build1 (NOP_EXPR, reftype, rval); } - else if (decl) + else if (flag_ansi_overloading) + { + rval = convert_for_initialization (NULL_TREE, type, expr, flags, + "converting", 0, 0); + if (rval == error_mark_node) + return error_mark_node; + rval = build_up_reference (reftype, rval, flags, 1); + + if (rval && ! TYPE_READONLY (TREE_TYPE (reftype))) + cp_pedwarn ("initializing non-const `%T' with `%T' will use a temporary", + reftype, intype); + } + else { tree rval_as_ctor = NULL_TREE; @@ -766,7 +775,6 @@ convert_to_reference (reftype, expr, convtype, flags, decl) if (toplevel_bindings_p ()) { - extern tree static_aggregates; tree t = get_temp_name (type, toplevel_bindings_p ()); init = build_method_call (t, ctor_identifier, build_tree_list (NULL_TREE, expr), @@ -1274,50 +1282,67 @@ cp_convert (type, expr, convtype, flags) There may be some ambiguity between using a constructor vs. using a type conversion operator when both apply. */ - if (IS_AGGR_TYPE (dtype) && ! DERIVED_FROM_P (type, dtype) - && TYPE_HAS_CONVERSION (dtype)) - conversion = build_type_conversion (CONVERT_EXPR, type, e, 1); - - if (conversion == error_mark_node) + if (flag_ansi_overloading) { - if (flags & LOOKUP_COMPLAIN) - error ("ambiguous pointer conversion"); - return conversion; + ctor = e; + + if ((flags & LOOKUP_ONLYCONVERTING) + && ! (IS_AGGR_TYPE (dtype) && DERIVED_FROM_P (type, dtype))) + ctor = build_user_type_conversion (type, ctor, flags); + if (ctor) + ctor = build_method_call (NULL_TREE, ctor_identifier, + build_tree_list (NULL_TREE, ctor), + TYPE_BINFO (type), flags); + if (ctor) + return build_cplus_new (type, ctor); } - - if (TYPE_HAS_CONSTRUCTOR (complete_type (type)) - && (! flag_ansi_overloading || ! conversion)) - ctor = build_method_call (NULL_TREE, ctor_identifier, - build_tree_list (NULL_TREE, e), - TYPE_BINFO (type), - (flags & LOOKUP_NORMAL) | LOOKUP_SPECULATIVELY - | (convtype & CONV_NONCONVERTING ? 0 : LOOKUP_ONLYCONVERTING) - | (flags & LOOKUP_NO_CONVERSION) - | (conversion ? LOOKUP_NO_CONVERSION : 0)); - - if (ctor == error_mark_node) + else { - if (flags & LOOKUP_COMPLAIN) - cp_error ("in conversion to type `%T'", type); - if (flags & LOOKUP_SPECULATIVELY) - return NULL_TREE; - return error_mark_node; - } + if (IS_AGGR_TYPE (dtype) && ! DERIVED_FROM_P (type, dtype) + && TYPE_HAS_CONVERSION (dtype)) + conversion = build_type_conversion (CONVERT_EXPR, type, e, 1); + + if (conversion == error_mark_node) + { + if (flags & LOOKUP_COMPLAIN) + error ("ambiguous pointer conversion"); + return conversion; + } + + if (TYPE_HAS_CONSTRUCTOR (complete_type (type))) + ctor = build_method_call (NULL_TREE, ctor_identifier, + build_tree_list (NULL_TREE, e), + TYPE_BINFO (type), + (flags & LOOKUP_NORMAL) + | LOOKUP_SPECULATIVELY + | (flags & LOOKUP_ONLYCONVERTING) + | (flags & LOOKUP_NO_CONVERSION) + | (conversion ? LOOKUP_NO_CONVERSION : 0)); + + if (ctor == error_mark_node) + { + if (flags & LOOKUP_COMPLAIN) + cp_error ("in conversion to type `%T'", type); + if (flags & LOOKUP_SPECULATIVELY) + return NULL_TREE; + return error_mark_node; + } - if (conversion && ctor) - { - if (flags & LOOKUP_COMPLAIN) - error ("both constructor and type conversion operator apply"); - if (flags & LOOKUP_SPECULATIVELY) - return NULL_TREE; - return error_mark_node; - } - else if (conversion) - return conversion; - else if (ctor) - { - ctor = build_cplus_new (type, ctor); - return ctor; + if (conversion && ctor) + { + if (flags & LOOKUP_COMPLAIN) + error ("both constructor and type conversion operator apply"); + if (flags & LOOKUP_SPECULATIVELY) + return NULL_TREE; + return error_mark_node; + } + else if (conversion) + return conversion; + else if (ctor) + { + ctor = build_cplus_new (type, ctor); + return ctor; + } } } diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index dbb2a903ed1..ebfc6b45a1b 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2077,15 +2077,10 @@ pushtag (name, type, globalize) if (! globalize && processing_template_decl && IS_AGGR_TYPE (type)) push_template_decl (d); - /* If it is anonymous, then we are called from pushdecl, - and we don't want to infinitely recurse. */ - if (! ANON_AGGRNAME_P (name)) - { - if (b->parm_flag == 2) - d = pushdecl_class_level (d); - else - d = pushdecl_with_scope (d, b); - } + if (b->parm_flag == 2) + d = pushdecl_class_level (d); + else + d = pushdecl_with_scope (d, b); } else { @@ -2102,7 +2097,7 @@ pushtag (name, type, globalize) } if (newdecl) { - if (write_symbols != DWARF_DEBUG) + if (write_symbols != DWARF_DEBUG && write_symbols != DWARF2_DEBUG) { if (ANON_AGGRNAME_P (name)) DECL_IGNORED_P (d) = 1; @@ -3589,6 +3584,7 @@ implicitly_declare (functionid) DECL_EXTERNAL (decl) = 1; TREE_PUBLIC (decl) = 1; + DECL_ARTIFICIAL (decl) = 1; /* ANSI standard says implicit declarations are in the innermost block. So we record the decl in the standard fashion. */ @@ -6211,8 +6207,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) { if (init && DECL_INITIAL (decl)) DECL_INITIAL (decl) = init; - if (minimal_parse_mode && ! DECL_ARTIFICIAL (decl) - && DECL_VINDEX (decl)) + if (minimal_parse_mode && ! DECL_ARTIFICIAL (decl)) { tree stmt = DECL_VINDEX (decl); DECL_VINDEX (decl) = NULL_TREE; @@ -7129,7 +7124,15 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals, return decl; if (check && funcdef_flag) - DECL_INITIAL (decl) = error_mark_node; + { + /* Do this before the decl is actually defined so that the DWARF debug + info for the class reflects the declaration, rather than the + definition, of this decl. */ + if (ctype) + note_debug_info_needed (ctype); + + DECL_INITIAL (decl) = error_mark_node; + } if (flags == NO_SPECIAL && ctype && constructor_name (cname) == declarator) { @@ -10716,7 +10719,7 @@ finish_enum (enumtype, values) } /* Finish debugging output for this type. */ - if (write_symbols != DWARF_DEBUG) + if (write_symbols != DWARF_DEBUG && write_symbols != DWARF2_DEBUG) rest_of_type_compilation (enumtype, global_bindings_p ()); return enumtype; diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 5055d20c663..a2d73c4bf25 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2423,8 +2423,7 @@ finish_vtable_vardecl (prev, vars) if (TREE_TYPE (DECL_INITIAL (vars)) == 0) store_init_value (vars, DECL_INITIAL (vars)); -#ifdef DWARF_DEBUGGING_INFO - if (write_symbols == DWARF_DEBUG) + if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG) { /* Mark the VAR_DECL node representing the vtable itself as a "gratuitous" one, thereby forcing dwarfout.c to ignore it. @@ -2449,7 +2448,6 @@ finish_vtable_vardecl (prev, vars) DECL_IGNORED_P (vars) = 1; } -#endif /* DWARF_DEBUGGING_INFO */ rest_of_decl_compilation (vars, NULL_PTR, 1, 1); return 1; @@ -3190,7 +3188,7 @@ reparse_absdcl_as_casts (decl, expr) { type = groktypename (TREE_VALUE (TREE_OPERAND (decl, 1))); decl = TREE_OPERAND (decl, 0); - expr = build_c_cast (type, expr, 0); + expr = build_c_cast (type, expr); } return expr; diff --git a/gcc/cp/except.c b/gcc/cp/except.c index fefcd021f6b..21522508fc5 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -425,6 +425,21 @@ expand_start_catch_block (declspecs, declarator) tree decl = NULL_TREE; tree init; + if (processing_template_decl) + { + if (declspecs) + { + decl = grokdeclarator (declarator, declspecs, CATCHPARM, + 1, NULL_TREE); + pushdecl (decl); + decl = build_min_nt (DECL_STMT, copy_to_permanent (declarator), + copy_to_permanent (declspecs), + NULL_TREE); + add_tree (decl); + } + return; + } + if (! doing_eh (1)) return; diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c index 3351ccba770..8aa142d12ff 100644 --- a/gcc/cp/expr.c +++ b/gcc/cp/expr.c @@ -27,9 +27,6 @@ Boston, MA 02111-1307, USA. */ #include "expr.h" #include "cp-tree.h" -#undef NULL -#define NULL 0 - /* Hook used by expand_expr to expand language-specific tree codes. */ rtx diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 84fd6a22365..154ab8068fc 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -29,9 +29,6 @@ Boston, MA 02111-1307, USA. */ #include "flags.h" #include "output.h" -#undef NULL -#define NULL 0 - /* In C++, structures with well-defined constructors are initialized by those constructors, unasked. CURRENT_BASE_INIT_LIST holds a list of stmts for a BASE_INIT term in the grammar. @@ -1269,6 +1266,27 @@ expand_default_init (binfo, true_exp, exp, init, alias_this, flags) tree rval; tree parms; + if (flag_ansi_overloading && init && TREE_CODE (init) != TREE_LIST + && (flags & LOOKUP_ONLYCONVERTING)) + { + /* Base subobjects should only get direct-initialization. */ + if (true_exp != exp) + abort (); + + /* We special-case TARGET_EXPRs here to avoid an error about + private copy constructors for temporaries bound to reference vars. + If the TARGET_EXPR represents a call to a function that has + permission to create such objects, a reference can bind directly + to the return value. An object variable must be initialized + via the copy constructor, even if the call is elided. */ + if (! (TREE_CODE (exp) == VAR_DECL && DECL_ARTIFICIAL (exp) + && TREE_CODE (init) == TARGET_EXPR && TREE_TYPE (init) == type)) + init = cp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags); + + expand_assignment (exp, init, 0, 0); + return; + } + if (init == NULL_TREE || (TREE_CODE (init) == TREE_LIST && ! TREE_TYPE (init))) { @@ -1276,7 +1294,8 @@ expand_default_init (binfo, true_exp, exp, init, alias_this, flags) if (parms) init = TREE_VALUE (parms); } - else if (TREE_CODE (init) == INDIRECT_REF && TREE_HAS_CONSTRUCTOR (init) + else if (! flag_ansi_overloading + && TREE_CODE (init) == INDIRECT_REF && TREE_HAS_CONSTRUCTOR (init) && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (init))) { rval = convert_for_initialization (exp, type, init, 0, 0, 0, 0); @@ -1296,6 +1315,14 @@ expand_default_init (binfo, true_exp, exp, init, alias_this, flags) flags |= LOOKUP_HAS_IN_CHARGE; } + if (flag_ansi_overloading) + { + rval = build_method_call (exp, ctor_identifier, + parms, binfo, flags); + expand_expr_stmt (rval); + return; + } + if (init && TREE_CHAIN (parms) == NULL_TREE && TYPE_HAS_TRIVIAL_INIT_REF (type) && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (init))) @@ -1376,7 +1403,24 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags) NULL_TREE, know that it was meant for us--just slide exp on in and expand the constructor. Constructors now come as TARGET_EXPRs. */ - if (init) + + if (init && TREE_CODE (exp) == VAR_DECL + && TREE_CODE (init) == CONSTRUCTOR + && TREE_HAS_CONSTRUCTOR (init)) + { + tree t = store_init_value (exp, init); + if (!t) + { + expand_decl_init (exp); + return; + } + t = build (INIT_EXPR, type, exp, init); + TREE_SIDE_EFFECTS (t) = 1; + expand_expr_stmt (t); + return; + } + + if (init && ! flag_ansi_overloading) { tree init_list = NULL_TREE; @@ -1457,7 +1501,7 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags) { tree tmp = TREE_OPERAND (TREE_OPERAND (init, 1), 1); - if (TREE_CODE (TREE_VALUE (tmp)) == NOP_EXPR + if (tmp && TREE_CODE (TREE_VALUE (tmp)) == NOP_EXPR && TREE_OPERAND (TREE_VALUE (tmp), 0) == integer_zero_node) { /* In order for this to work for RESULT_DECLs, if their @@ -1487,22 +1531,6 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags) } } - if (TREE_CODE (exp) == VAR_DECL - && TREE_CODE (init) == CONSTRUCTOR - && TREE_HAS_CONSTRUCTOR (init)) - { - tree t = store_init_value (exp, init); - if (!t) - { - expand_decl_init (exp); - return; - } - t = build (INIT_EXPR, type, exp, init); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr_stmt (t); - return; - } - /* Handle this case: when calling a constructor: xyzzy foo(bar); which really means: xyzzy foo = bar; Ugh! @@ -1534,13 +1562,7 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags) { tree rval = build_type_conversion (CONVERT_EXPR, type, init, 1); - if (flag_ansi_overloading && rval) - { - if (rval != error_mark_node) - expand_aggr_init_1 (binfo, true_exp, exp, rval, alias_this, flags); - return; - } - else if (rval) + if (rval) { /* See if there is a constructor for``type'' that takes a ``ttype''-typed object. */ @@ -2028,6 +2050,10 @@ resolve_offset_ref (exp) return member; } + if (TREE_CODE (TREE_TYPE (member)) == POINTER_TYPE + && TREE_CODE (TREE_TYPE (TREE_TYPE (member))) == METHOD_TYPE) + return member; + /* Syntax error can cause a member which should have been seen as static to be grok'd as non-static. */ if (TREE_CODE (member) == FIELD_DECL && current_class_ref == NULL_TREE) @@ -3078,7 +3104,7 @@ build_new (placement, decl, init, use_global_new) if (rval && TREE_TYPE (rval) != build_pointer_type (type)) { /* The type of new int [3][3] is not int *, but int [3] * */ - rval = build_c_cast (build_pointer_type (type), rval, 0); + rval = build_c_cast (build_pointer_type (type), rval); } if (pending_sizes) diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 4888981f47b..448cb1f2e03 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -1974,11 +1974,7 @@ check_newline () && getch () == 'e' && ((c = getch ()) == ' ' || c == '\t')) { -#ifdef DWARF_DEBUGGING_INFO - if ((debug_info_level == DINFO_LEVEL_VERBOSE) - && (write_symbols == DWARF_DEBUG)) - dwarfout_define (lineno, get_directive_line (finput)); -#endif /* DWARF_DEBUGGING_INFO */ + debug_define (lineno, get_directive_line (finput)); goto skipline; } } @@ -1990,11 +1986,7 @@ check_newline () && getch () == 'f' && ((c = getch ()) == ' ' || c == '\t')) { -#ifdef DWARF_DEBUGGING_INFO - if ((debug_info_level == DINFO_LEVEL_VERBOSE) - && (write_symbols == DWARF_DEBUG)) - dwarfout_undef (lineno, get_directive_line (finput)); -#endif /* DWARF_DEBUGGING_INFO */ + debug_undef (lineno, get_directive_line (finput)); goto skipline; } } @@ -2233,15 +2225,7 @@ linenum: p->name = input_filename; input_file_stack = p; input_file_stack_tick++; -#ifdef DBX_DEBUGGING_INFO - if (write_symbols == DBX_DEBUG) - dbxout_start_new_source_file (input_filename); -#endif -#ifdef DWARF_DEBUGGING_INFO - if (debug_info_level == DINFO_LEVEL_VERBOSE - && write_symbols == DWARF_DEBUG) - dwarfout_start_new_source_file (input_filename); -#endif /* DWARF_DEBUGGING_INFO */ + debug_start_source_file (input_filename); in_system_header = entering_system_header; if (c_header_level) ++c_header_level; @@ -2270,15 +2254,7 @@ linenum: input_file_stack = p->next; free (p); input_file_stack_tick++; -#ifdef DBX_DEBUGGING_INFO - if (write_symbols == DBX_DEBUG) - dbxout_resume_previous_source_file (); -#endif -#ifdef DWARF_DEBUGGING_INFO - if (debug_info_level == DINFO_LEVEL_VERBOSE - && write_symbols == DWARF_DEBUG) - dwarfout_resume_previous_source_file (input_file_stack->line); -#endif /* DWARF_DEBUGGING_INFO */ + debug_end_source_file (input_file_stack->line); } else error ("#-lines for entering and leaving files don't match"); @@ -4332,7 +4308,6 @@ handle_cp_pragma (pname) else if (! strcmp (pname, "interface")) { tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename)); - int warned_already = 0; char *main_filename = input_filename; main_filename = FILE_NAME_NONDIRECTORY (main_filename); @@ -4348,18 +4323,12 @@ handle_cp_pragma (pname) return -1; } main_filename = TREE_STRING_POINTER (yylval.ttype); - } - - while (token != END_OF_LINE) - { - if (!warned_already && extra_warnings) - { - warning ("garbage after `#pragma interface' ignored"); - warned_already = 1; - } token = real_yylex (); } + if (token != END_OF_LINE) + warning ("garbage after `#pragma interface' ignored"); + #ifndef NO_LINKAGE_HEURISTICS write_virtuals = 3; @@ -4394,7 +4363,6 @@ handle_cp_pragma (pname) else if (! strcmp (pname, "implementation")) { tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename)); - int warned_already = 0; char *main_filename = main_input_filename ? main_input_filename : input_filename; main_filename = FILE_NAME_NONDIRECTORY (main_filename); @@ -4408,18 +4376,12 @@ handle_cp_pragma (pname) return -1; } main_filename = TREE_STRING_POINTER (yylval.ttype); - } - - while (token != END_OF_LINE) - { - if (!warned_already && extra_warnings) - { - warning ("garbage after `#pragma implementation' ignored"); - warned_already = 1; - } token = real_yylex (); } + if (token != END_OF_LINE) + warning ("garbage after `#pragma implementation' ignored"); + #ifndef NO_LINKAGE_HEURISTICS if (write_virtuals == 3) { diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index cb80c8e566f..2a751420dc1 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -1224,7 +1224,7 @@ expr_no_commas: { $$ = build_m_component_ref ($$, build_x_unary_op ($2, $3)); } | object '(' type_id ')' expr_no_commas %prec UNARY { tree type = groktypename ($3.t); - $$ = build_m_component_ref ($$, build_c_cast (type, $5, 0)); } + $$ = build_m_component_ref ($$, build_c_cast (type, $5)); } | object primary_no_id %prec UNARY { $$ = build_m_component_ref ($$, $2); } */ @@ -1421,7 +1421,7 @@ primary: } #endif else my_friendly_abort (79); - $$ = build_c_cast (type, build_compound_expr ($3), 1); + $$ = build_c_cast (type, build_compound_expr ($3)); } } | functional_cast @@ -3678,18 +3678,75 @@ function_try_block: try_block: TRY - { expand_start_try_stmts (); } + { + if (processing_template_decl) + { + $<ttype>$ = build_min_nt (TRY_BLOCK, NULL_TREE, + NULL_TREE); + add_tree ($<ttype>$); + } + else + { + emit_line_note (input_filename, lineno); + expand_start_try_stmts (); + } + } compstmt - { expand_start_all_catch (); } + { + if (processing_template_decl) + { + TREE_OPERAND ($<ttype>2, 0) = TREE_CHAIN ($<ttype>2); + TREE_CHAIN ($<ttype>2) = NULL_TREE; + last_tree = $<ttype>2; + } + else + expand_start_all_catch (); + } handler_seq - { expand_end_all_catch (); } + { + if (processing_template_decl) + { + TREE_OPERAND ($<ttype>2, 1) = TREE_CHAIN ($<ttype>2); + TREE_CHAIN ($<ttype>2) = NULL_TREE; + last_tree = $<ttype>2; + } + else + expand_end_all_catch (); + } ; handler_seq: /* empty */ - | handler_seq CATCH .pushlevel handler_args compstmt - { expand_end_catch_block (); } - .poplevel + | handler_seq CATCH + { + if (processing_template_decl) + { + $<ttype>$ = build_min_nt (HANDLER, NULL_TREE, + NULL_TREE); + add_tree ($<ttype>$); + } + } + .pushlevel handler_args + { + if (processing_template_decl) + { + TREE_OPERAND ($<ttype>3, 0) = TREE_CHAIN ($<ttype>3); + TREE_CHAIN ($<ttype>3) = NULL_TREE; + last_tree = $<ttype>3; + } + } + compstmt + { + if (processing_template_decl) + { + TREE_OPERAND ($<ttype>3, 1) = TREE_CHAIN ($<ttype>3); + TREE_CHAIN ($<ttype>3) = NULL_TREE; + last_tree = $<ttype>3; + } + else + expand_end_catch_block (); + } + .poplevel ; type_specifier_seq: diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 46a8a149b17..9c4f42fad6c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2427,7 +2427,38 @@ tsubst_expr (t, args, nargs, in_decl) expand_computed_goto (tsubst_expr (TREE_OPERAND (t, 0), args, nargs, in_decl)); break; - + + case TRY_BLOCK: + lineno = TREE_COMPLEXITY (t); + emit_line_note (input_filename, lineno); + expand_start_try_stmts (); + tsubst_expr (TREE_OPERAND (t, 0), args, nargs, in_decl); + expand_start_all_catch (); + { + tree handler = TREE_OPERAND (t, 1); + for (; handler; handler = TREE_CHAIN (handler)) + tsubst_expr (handler, args, nargs, in_decl); + } + expand_end_all_catch (); + break; + + case HANDLER: + lineno = TREE_COMPLEXITY (t); + do_pushlevel (); + if (TREE_OPERAND (t, 0)) + { + tree d = TREE_OPERAND (t, 0); + expand_start_catch_block + (tsubst (TREE_OPERAND (d, 1), args, nargs, in_decl), + tsubst (TREE_OPERAND (d, 0), args, nargs, in_decl)); + } + else + expand_start_catch_block (NULL_TREE, NULL_TREE); + tsubst_expr (TREE_OPERAND (t, 1), args, nargs, in_decl); + expand_end_catch_block (); + do_poplevel (); + break; + default: return build_expr_from_tree (tsubst_copy (t, args, nargs, in_decl)); } diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 1ecccd84e80..ebf5c024591 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -27,9 +27,6 @@ Boston, MA 02111-1307, USA. */ #include "output.h" #include "assert.h" -#undef NULL -#define NULL 0 - #ifndef INT_TYPE_SIZE #define INT_TYPE_SIZE BITS_PER_WORD #endif @@ -1364,7 +1361,7 @@ build_m_desc (decl) tree_cons (NULL_TREE, vcontext, tree_cons (NULL_TREE, build_t_desc (TREE_TYPE (TREE_TYPE (decl)), ! IS_AGGR_TYPE (taggr)), - tree_cons (NULL_TREE, build_c_cast (build_pointer_type (default_function_type), build_unary_op (ADDR_EXPR, decl, 0), 0), + tree_cons (NULL_TREE, build_c_cast (build_pointer_type (default_function_type), build_unary_op (ADDR_EXPR, decl, 0)), tree_cons (NULL_TREE, parm_count, tree_cons (NULL_TREE, req_count, build_tree_list (NULL_TREE, build_unary_op (ADDR_EXPR, parm_types, 0))))))))); diff --git a/gcc/cp/search.c b/gcc/cp/search.c index f2b2a50a0ef..b503d7849c1 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -2543,8 +2543,11 @@ dfs_debug_mark (binfo) return; /* We can't do the TYPE_DECL_SUPPRESS_DEBUG thing with DWARF, which - does not support name references between translation units. */ - if (write_symbols == DWARF_DEBUG) + does not support name references between translation units. Well, we + could, but that would mean putting global labels in the debug output + before each exported type and each of its functions and static data + members. */ + if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG) { rest_of_type_compilation (t, global_bindings_p ()); return; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index c391d7af021..0d0dc05318e 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1592,16 +1592,6 @@ mapcar (t, func) TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func); return t; - break; - - case RTL_EXPR: - t = copy_node (t); - if (RTL_EXPR_SEQUENCE (t)) - RTL_EXPR_SEQUENCE (t) = copy_rtx (RTL_EXPR_SEQUENCE (t)); - if (RTL_EXPR_RTL (t)) - RTL_EXPR_RTL (t) = copy_rtx (RTL_EXPR_RTL (t)); - return t; - break; case CONVERT_EXPR: case ADDR_EXPR: diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 60c8f0031ec..146cf07bfc8 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1837,10 +1837,13 @@ build_component_ref (datum, component, basetype_path, protect) && ! resolves_to_fixed_type_p (datum, 0)) { tree addr = build_unary_op (ADDR_EXPR, datum, 0); + tree fntype = TREE_TYPE (fndecl); + addr = convert_pointer_to (DECL_CONTEXT (fndecl), addr); datum = build_indirect_ref (addr, NULL_PTR); my_friendly_assert (datum != error_mark_node, 310); fndecl = build_vfn_ref (&addr, datum, DECL_VINDEX (fndecl)); + TREE_TYPE (fndecl) = build_pointer_type (fntype); } mark_used (fndecl); return build (OFFSET_REF, TREE_TYPE (fndecl), datum, fndecl); @@ -2436,7 +2439,7 @@ build_x_function_call (function, params, decl) decl = convert_pointer_to (TREE_TYPE (ctypeptr), decl); } else - decl = build_c_cast (ctypeptr, decl, 0); + decl = build_c_cast (ctypeptr, decl); params = tree_cons (NULL_TREE, decl, params); } @@ -2716,6 +2719,9 @@ convert_arguments (return_loc, typelist, values, fndecl, flags) if (! flag_elide_constructors) return_loc = 0; + /* Argument passing is always copy-initialization. */ + flags |= LOOKUP_ONLYCONVERTING; + if (fndecl) { if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE) @@ -4490,7 +4496,9 @@ unary_complex_lvalue (code, arg) || TREE_CODE (arg) == INIT_EXPR) { tree real_result = build_unary_op (code, TREE_OPERAND (arg, 0), 0); - return build (COMPOUND_EXPR, TREE_TYPE (real_result), arg, real_result); + arg = build (COMPOUND_EXPR, TREE_TYPE (real_result), arg, real_result); + TREE_NO_UNUSED_WARNING (arg) = 1; + return arg; } if (TREE_CODE (TREE_TYPE (arg)) == FUNCTION_TYPE @@ -5188,7 +5196,7 @@ build_static_cast (type, expr) ok = 1; if (ok) - return build_c_cast (type, expr, 0); + return build_c_cast (type, expr); cp_error ("static_cast from `%T' to `%T'", intype, type); return error_mark_node; @@ -5354,10 +5362,9 @@ build_const_cast (type, expr) when doing the cast. */ tree -build_c_cast (type, expr, allow_nonconverting) +build_c_cast (type, expr) register tree type; tree expr; - int allow_nonconverting; { register tree value = expr; @@ -5485,11 +5492,9 @@ build_c_cast (type, expr, allow_nonconverting) warning ("cast to pointer from integer of different size"); #endif - flag = allow_nonconverting ? CONV_NONCONVERTING : 0; - if (TREE_CODE (type) == REFERENCE_TYPE) value = (convert_from_reference - (convert_to_reference (type, value, CONV_OLD_CONVERT|flag, + (convert_to_reference (type, value, CONV_C_CAST, LOOKUP_COMPLAIN, NULL_TREE))); else { @@ -6267,7 +6272,7 @@ build_ptrmemfunc (type, pfn, force) /* Handle null pointer to member function conversions. */ if (integer_zerop (pfn)) { - pfn = build_c_cast (type, integer_zero_node, 0); + pfn = build_c_cast (type, integer_zero_node); return build_ptrmemfunc1 (TYPE_GET_PTRMEMFUNC_TYPE (type), integer_zero_node, integer_zero_node, pfn, NULL_TREE); @@ -6761,10 +6766,10 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) } else if (TYPE_HAS_CONSTRUCTOR (type) || IS_AGGR_TYPE (TREE_TYPE (rhs))) return convert (type, rhs); - /* Handle anachronistic conversions from (::*)() to void* or (*)(). */ + /* Handle anachronistic conversions from (::*)() to cv void* or (*)(). */ else if (TREE_CODE (type) == POINTER_TYPE && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE - || TREE_TYPE (type) == void_type_node) + || TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node) && TREE_TYPE (rhs) && TYPE_PTRMEMFUNC_P (TREE_TYPE (rhs))) return convert (type, rhs); @@ -6886,6 +6891,9 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum) if (IS_AGGR_TYPE (type) && (TYPE_NEEDS_CONSTRUCTING (type) || TREE_HAS_CONSTRUCTOR (rhs))) { + if (flag_ansi_overloading) + return cp_convert (type, rhs, CONV_IMPLICIT|CONV_FORCE_TEMP, flags); + if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype)) { /* This is sufficient to perform initialization. No need, @@ -7130,9 +7138,9 @@ c_expand_return (retval) /* convert to reference now, so we can give error if we return an reference to a non-lvalue. */ - retval = convert_for_initialization (tmp_result, valtype, retval, - LOOKUP_NORMAL, "return", - NULL_TREE, 0); + retval = convert_for_initialization + (tmp_result, valtype, retval, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING, + "return", NULL_TREE, 0); /* Sort through common things to see what it is we are returning. */ @@ -7207,14 +7215,14 @@ c_expand_return (retval) { /* We already did this above for refs, don't do it again. */ if (TREE_CODE (valtype) != REFERENCE_TYPE) - retval = convert_for_initialization (NULL_TREE, valtype, retval, - LOOKUP_NORMAL, - "return", NULL_TREE, 0); + retval = convert_for_initialization + (NULL_TREE, valtype, retval, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING, + "return", NULL_TREE, 0); /* We can't initialize a register from a NEW_EXPR. */ if (! current_function_returns_struct && TREE_CODE (retval) == TARGET_EXPR - && TREE_CODE (TREE_OPERAND (retval, 0)) == NEW_EXPR) + && TREE_CODE (TREE_OPERAND (retval, 1)) == NEW_EXPR) retval = build (COMPOUND_EXPR, TREE_TYPE (retval), retval, TREE_OPERAND (retval, 0)); diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 1c0029744ce..8c7604f8d87 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -865,16 +865,12 @@ digest_init (type, init, tail) return process_init_constructor (type, init, (tree *)0); else if (TYPE_NON_AGGREGATE_CLASS (type)) { -#if 0 - /* This isn't true. */ - /* This can only be reached when caller is initializing - ARRAY_TYPE. In that case, we don't want to convert - INIT to TYPE. We will let `expand_vec_init' do it. */ - return init; -#else - return convert_for_initialization (0, type, init, LOOKUP_NORMAL, + int flags = LOOKUP_NORMAL; + /* Initialization from { } is copy-initialization. */ + if (tail) + flags |= LOOKUP_ONLYCONVERTING; + return convert_for_initialization (0, type, init, flags, "initialization", NULL_TREE, 0); -#endif } else if (tail != 0) { @@ -1442,7 +1438,7 @@ build_functional_cast (exp, parms) parms = build_compound_expr (parms); } - return build_c_cast (type, parms, 1); + return build_c_cast (type, parms); } /* Prepare to evaluate as a call to a constructor. If this expression @@ -1459,7 +1455,7 @@ build_functional_cast (exp, parms) } if (parms && TREE_CHAIN (parms) == NULL_TREE) - return build_c_cast (type, TREE_VALUE (parms), 1); + return build_c_cast (type, TREE_VALUE (parms)); exp = build_method_call (NULL_TREE, ctor_identifier, parms, TYPE_BINFO (type), LOOKUP_NORMAL); diff --git a/gcc/cp/xref.c b/gcc/cp/xref.c index a5ea79452db..a09ab7ff295 100644 --- a/gcc/cp/xref.c +++ b/gcc/cp/xref.c @@ -61,9 +61,6 @@ int flag_gnu_xref; #ifndef FALSE #define FALSE 0 #endif -#ifndef NULL -#define NULL 0 -#endif #define PALLOC(typ) ((typ *) calloc(1,sizeof(typ))) |