]> gcc.gnu.org Git - gcc.git/commitdiff
49th Cygnus<->FSF merge
authorMike Stump <mrs@gcc.gnu.org>
Tue, 29 Nov 1994 00:59:16 +0000 (00:59 +0000)
committerMike Stump <mrs@gcc.gnu.org>
Tue, 29 Nov 1994 00:59:16 +0000 (00:59 +0000)
From-SVN: r8570

24 files changed:
gcc/cp/ChangeLog
gcc/cp/Make-lang.in
gcc/cp/Makefile.in
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/decl.h
gcc/cp/decl2.c
gcc/cp/except.c
gcc/cp/gxx.gperf
gcc/cp/gxxint.texi
gcc/cp/hash.h
gcc/cp/init.c
gcc/cp/lex.c
gcc/cp/lex.h
gcc/cp/method.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/search.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/cp/typeck2.c

index c93b656ba6c5f01b5eaefd8df87318ccd8a74376..a5372a58547e742b461b219dbbdbb99fd3bc9e3c 100644 (file)
@@ -1,3 +1,8 @@
+Mon Nov 28 16:44:41 1994  Mike Stump  <mrs@cygnus.com>
+
+       * Makefile.in: Make is easier to decide where parse.[ch] will be
+       built.
+
 Thu Nov 17 20:11:24 1994  Doug Evans  <dje@cygnus.com>
 
        * cp/Make-lang.in (CXX_INSTALL_NAME) Use program_transform_name.
@@ -12,33 +17,236 @@ Thu Nov  3 18:48:19 1994  Paul Eggert  <eggert@twinsun.com>
        * Makefile.in (spew.o, lex.o, pt.o):
        Depend on $(srcdir)/parse.h, not parse.h.
 
-Sat Oct 29 07:18:52 1994  Richard Kenner  (kenner@vlsi1.ultra.nyu.edu)
+Mon Nov 28 13:53:03 1994  Mike Stump  <mrs@cygnus.com>
+
+       * parse.y (THROW): Fix precedence of throw expressions.
+
+Mon Nov 28 13:15:16 1994  Mike Stump  <mrs@cygnus.com>
+
+       * typeck.c (build_unary_op): Allow promotions from bool to int on
+       unary ~.
+
+Sun Nov 27 00:16:21 1994  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+       * method.c (build_overload_name): Use DECL_ASSEMBLER_NAME for
+       classes when appropriate.
+       (build_overload_nested_name): When dealing with a function context,
+       use ASM_FORMAT_PRIVATE_NAME to tweak the name of the function to
+       avoid conflicts between local classes of the same name.
+
+Wed Nov 23 17:59:42 1994  Mike Stump  <mrs@cygnus.com>
+
+       * gxx.gperf, parse.y, lex.h, hash.h, lex.c (init_lex), delc.c
+       (duplicate_decls, grokdeclarator), cp-tree.h: Add support for
+       `explicit'.
+       * cvt.c (convert_to_reference, cp_convert, build_type_conversion_1,
+       build_type_conversion): Use LOOKUP_ONLYCONVERTING in
+       build_method_calls so that non-converting constructors are not used.
+       * call.c (build_method_call): If we shouldn't use a non-converting
+       constructor, then don't.
+
+Wed Nov 23 14:46:56 1994  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+       * call.c (build_method_call): Don't try to synthesize methods yet.
+
+Tue Nov 22 12:45:21 1994  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+       * pt.c (push_template_decls): Create CONST_DECLs for template
+       constant parameters, not VAR_DECLs.
+
+Sat Nov 19 15:28:31 1994  Jim Wilson  (wilson@chestnut.cygnus.com)
+
+       * typeck.c (build_binary_op_nodefault): Can shorten shift only if
+       shift count is less than size in bits of arg0.
+
+Thu Nov 17 15:30:50 1994  Mike Stump  <mrs@cygnus.com>
+
+       * gxx.gperf, hash.h, lex.c (init_lex, real_yylex), parse.y: Add new
+       ANSI keywords and, and_eq, bitand, bitor, explicit, namespace, not,
+       not_eq, or, or_eq, typename, using, xor, xor_eq to g++.  Still need
+       to add support for explicit, namespace, typename, and using, support
+       for the rest is already in.
+
+Thu Nov 17 10:56:50 1994  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+       * typeck2.c (build_m_component_ref): Check the basetype of the
+       member pointer against the main variant of the object type.
+
+Mon Nov 14 14:21:52 1994  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+       * cvt.c (convert_to_reference): Make sure that the original expr
+       gets its type back when converting a reference.
+
+       * method.c (build_overload_name): Clear numeric_outputed_need_bar here.
+       (build_decl_overload): Instead of here.
+
+Tue Nov  8 17:11:24 1994  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+       * cvt.c (cp_convert): Don't build a TARGET_EXPR if we're not in a
+       function.
+
+       * typeck.c (convert_for_initialization): Handle initialization from
+       a TARGET_EXPR.
+
+Sun Nov  6 01:34:24 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
+
+       * pt.c (lookup_nested_type_by_name): Fix list-walking logic.
+       (tsubst): When replacing a TEMPLATE_TYPE_PARM, propagate
+       TYPE_READONLY and TYPE_VOLATILE from the argument.
+       (unify): When unifying with a TEMPLATE_TYPE_PARM, remove cv-quals
+       present in parm from arg.
+       (type_unification): Strip REFERENCE_TYPE from the argument type.
+       (unify): Don't strip REFERENCE_TYPE from the argument type.
+
+Sat Nov  5 22:42:15 1994  Greg McGary  (gkm@magilla.cichlid.com)
+
+       * pt.c (do_type_instantiation): Check to see if there's a
+       IDENTIFIER_TEMPLATE on a class before calling
+       instantiate_member_templates().
+
+Fri Nov  4 19:04:18 1994  Mike Stump  <mrs@cygnus.com>
+
+       * gc.c (get_bad_cast_node): New routine to support compile time
+       throws of bad_cast.
+       * gc.c (build_dynamic_cast): Support throwing of bad_cast at compile
+       time.
+
+Fri Nov  4 11:12:00 1994  Mike Stump  <mrs@cygnus.com>
+
+       * except.c: Add hppa support.
+
+Fri Nov  4 10:50:50 1994  Mike Stump  <mrs@cygnus.com>
+
+       * except.c: Add rs6000 support.
+
+Thu Nov  3 14:24:23 1994  Mike Stump  <mrs@cygnus.com>
 
-       * g++.c (main): Cast arg to bzero to avoid warning.
+       * except.c (do_unwind): Add i[34]86 support.
+
+Thu Nov  3 00:10:46 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
+
+       * pt.c (do_pending_expansions): Unset TREE_PUBLIC on implicit
+       instantiations.
+
+Wed Nov  2 15:08:24 1994  Kung Hsu  (kung@mexican.cygnus.com)
+
+       * decl.c (finish_function): emit types used in method parameters
+       into symbol table.
+
+Wed Nov  2 15:05:47 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
+
+       * pt.c (process_template_parm): Allow pointer to member function
+       template parameter types.
+       (uses_template_parms): Handle pointer to member function
+       CONSTRUCTORs.
+
+       * g++.c (main): Cast first argument of bzero to (char *).
+       Pass -lstdc++ instead of -lg++ unless we are invoked as 'g++'.
+
+Mon Oct 31 14:50:48 1994  Kung Hsu  (kung@mexican.cygnus.com)
+
+       * gc.c (build_dynamic_cast): rewrite to make it work.
+       * class.c (finish_vtbls): build more vtables if flag_rtti is on.
+       * class.c (modify_all_direct_vtables): ditto.
+       * init.c (expand_direct_vtbls_init): expand more vtables if
+       flag_rtti is on.
+       * decl.c (init_type_desc): add default return.
+
+Tue Oct 25 17:13:09 1994  Kung Hsu  (kung@mexican.cygnus.com)
+
+       * tree.c (debug_binfo): get rid of the initial size entry of
+       vtable.
+       * cp-tree.h: change flag_dossier to flag rtti, define type
+       descriptor type nodes.
+       * decl.c (init_type_desc): new function to initialize type
+       descriptor type nodes.
+       * decl.c (record_builtin_type): change flag_dossier to flag_rtti.
+       * lex.c (init_lex): ditto.
+       * decl.c : change variable flag_dossier to flag_rtti.
+       * decl.c (duplicate_decls): get rid initial size entry of vtable.
+       * decl.c (hack_incomplete_structures): take out assert 164.
+       * search.c (get_abstract_virtuals_1): ditto.
+       * search.c (dfs_init_vbase_pointers): change CLASSTYPE_DOSSIER to
+       CLASSTYPE_RTTI.
+       * parse.y: ditto.
+       * class.c (prepare_fresh_vtable): for virtual bases, get right
+       offset.
+       * class.c (add_virtual_function): change flag_dossier to
+       flag_rtti.
+       * class.c (modify_one_vtable): modify the right rtti entry.
+       * class.c (override_one_vtable): get rid of size entry.
+       * class.c (finish_struct): change flag_dossier to flag_rtti, and
+       build extra vtables, build type descriptors for polymorphic
+       classes.
+       * gc.c (build_headof): make headof() works correctly with new
+       rtti.
+       * gc.c (build_typeid): make this function work with new rtti.
+       * gc.c (get_typeid): make this function work with new rtti.
+       * gc.c (build_bltn_desc): new function for new rtti.
+       * gc.c (build_user_desc): ditto.
+       * gc.c (build_class_desc): ditto.
+       * gc.c (build_ptr_desc): ditto.
+       * gc.c (build_attr_desc): ditto.
+       * gc.c (build_func_desc): ditto.
+       * gc.c (build_ptmf_desc): ditto.
+       * gc.c (build_ptmd_desc): ditto.
+       * gc.c (build_t_desc): ditto.
+       * gc.c : comment out old build_t_desc, build_i_desc, build_m_desc.
+
+Tue Oct 25 13:37:41 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
+
+       * call.c (convert_harshness): Check for TREE_UNSIGNED differences
+       after checking for integral conversions.
 
 Sun Oct 23 13:19:55 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
 
-        * decl2.c: Declare flag_access_control.
-        (struct lang_f_options): Add access-control.
-        * expr.c (cplus_expand_expr, NEW_EXPR): Unset flag_access_control
-        for the call to expand_aggr_init to copy the object out of the
-        pcc_struct_return slot.
-        * search.c (compute_access): if (!flag_access_control) return
-        access_public.
+       * decl2.c: Declare flag_access_control.
+       (struct lang_f_options): Add access-control.
+       * expr.c (cplus_expand_expr, NEW_EXPR): Unset flag_access_control
+       for the call to expand_aggr_init to copy the object out of the
+       pcc_struct_return slot.
+       * search.c (compute_access): if (!flag_access_control) return
+       access_public.
 
 Fri Oct 21 00:32:54 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
 
-        * decl.c (init_decl_processing): Use __pure_virtual for abort_fndecl
-        instead of abort, since the OSF/1 dynamic linker doesn't like to see
-        relocation entries for abort.
+       * lex.c (cons_up_default_function): Don't try to defer method
+       synthesis now.
+
+       * decl.c (init_decl_processing): Use __pure_virtual for abort_fndecl
+       instead of abort, since the OSF/1 dynamic linker doesn't like to see
+       relocation entries for abort.
+
+       * tree.c (array_type_nelts_total): Use sizetype, not
+       integer_type_node.
+       (array_type_nelts_top): Ditto.
 
-        * tree.c (array_type_nelts_total): Use sizetype, not
-        integer_type_node.
-        (array_type_nelts_top): Ditto.
+Thu Oct 20 15:48:27 1994  Mike Stump  <mrs@cygnus.com>
+
+       * decl.c (grokdeclarator): Added handling for catch parameters
+       (CATCHPARM).
+       * except.c (expand_start_catch_block): Use the new CATCHPARM context
+       instead of NORMAL.
+       * except.c (expand_throw): Don't let convert_to_reference complain
+       about what we are doing.
+
+Thu Oct 20 12:55:24 1994  Jim Wilson  (wilson@cygnus.com)
+
+       * method.c (emit_thunk): Call instantiate_virtual_regs.
+
+Wed Oct 19 14:15:33 1994  Mike Stump  <mrs@cygnus.com>
+
+       * except.c (expand_exception_blocks): Make sure throw code doesn't
+       get put in function that won't be output.
 
 Mon Oct 17 18:03:15 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
 
-        * decl.c (init_decl_processing): Make alloca a builtin.
+       * decl.c (init_decl_processing): Make alloca a builtin.
+
+Thu Oct 27 21:10:25 1994  Craig Burley  (craig@burley)
+
+       * g++.c (main): Only decrement "added" and set "library" to
+       NULL when "library" != NULL (just like 940829 fix).
 
 Mon Oct 17 15:56:11 1994  Mike Stump  <mrs@cygnus.com>
 
@@ -51,47 +259,74 @@ Fri Oct 14 18:54:48 1994  Mike Stump  <mrs@cygnus.com>
        * class.c (modify_one_vtable): Since the DECL_CONTEXT of fndecl can
        be set just below, use current_fndecl instead.
 
+Fri Oct 14 15:12:22 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
+
+       * init.c (expand_aggr_vbase_init_1): Don't call expand_aggr_init_1
+       with LOOKUP_SPECULATIVELY.
+       (expand_default_init): Abort if build_method_call returns NULL_TREE.
+
+       * typeck.c (build_modify_expr): Don't just build a MODIFY_EXPR if
+       the rhs is a TARGET_EXPR.
+
+       * parse.y (left_curly): Anonymous types are not affected by #pragma
+       interface/implementation.
+
+       * method.c (synthesize_method): Don't call setup_vtbl_ptr for the
+       default constructor if it isn't needed.
+
+       * lex.c (cons_up_default_function): Do synthesize methods for
+       anonymous types if necessary.
+
 Thu Oct 13 17:44:55 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
 
-        * method.c (build_decl_overload): Set numeric_outputed_need_bar to 0.
+       * method.c (build_decl_overload): Set numeric_outputed_need_bar to 0.
 
 Wed Oct 12 13:27:57 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
 
-        * lex.c (real_yylex): Use HOST_BITS_PER_WIDE_INT to determine the
-        bitmask for lexing character constants.
+       * typeck.c (build_modify_expr): Understand how to copy an aggregate.
+
+       * init.c (expand_default_init): Ditto.  Also remove some of the
+       crufty code that assumes methods will not be synthesized properly.
+
+       * lex.c (cons_up_default_function): If the containing type has no
+       name, these functions should never need to be called, so just
+       declare them.
 
-        * call.c (build_method_call): Disable code that tries to do tricky
-        stuff with a default parameter that is a constructor call, but
-        actually does other tricky stuff that breaks things.
+       * lex.c (real_yylex): Use HOST_BITS_PER_WIDE_INT to determine the
+       bitmask for lexing character constants.
+
+       * call.c (build_method_call): Disable code that tries to do tricky
+       stuff with a default parameter that is a constructor call, but
+       actually does other tricky stuff that breaks things.
 
 Wed Oct 12 16:14:01 1994  Benoit Belley  <belley@cae.ca>
 
-        * decl.c (finish_enum): Disable code which forces enums to be signed,
-        since this conflicts with their use as bitfields. type_promotes_to
-        handles promotion of enums of underlying unsigned types to signed
-        integer types.
+       * decl.c (finish_enum): Disable code which forces enums to be signed,
+       since this conflicts with their use as bitfields. type_promotes_to
+       handles promotion of enums of underlying unsigned types to signed
+       integer types.
 
 Wed Oct 12 13:24:03 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
 
-        * cvt.c (type_promotes_to): Also promote enums to long if
-        appropriate.
+       * cvt.c (type_promotes_to): Also promote enums to long if
+       appropriate.
 
-        * typeck.c (default_conversion): Don't expect type_promotes_to to
-        return a main variant.
+       * typeck.c (default_conversion): Don't expect type_promotes_to to
+       return a main variant.
 
 Wed Oct 12 12:19:45 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
 
-        * call.c (build_scoped_method_call): Don't lose side effects in the
-        object expression when calling a non-existent destructor.
+       * call.c (build_scoped_method_call): Don't lose side effects in the
+       object expression when calling a non-existent destructor.
 
 Fri Sep  2 19:05:21 1994  Rohan Lenard  (rjl@iassf.easams.com.au)
 
-        * call.c (build_scoped_method_call): Remove erroneous error message
-        when destructor call is written as a scoped call.
+       * call.c (build_scoped_method_call): Remove erroneous error message
+       when destructor call is written as a scoped call.
 
 Tue Oct 11 23:48:31 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
-  
-        * various: Cast pointer arguments to bzero and bcopy to char *.
+
+       * various: Cast pointer arguments to bzero and bcopy to char *.
 
 Tue Oct 11 19:34:32 1994  Mike Stump  <mrs@cygnus.com>
 
@@ -101,61 +336,172 @@ Tue Oct 11 19:34:32 1994  Mike Stump  <mrs@cygnus.com>
        offset to put into the vtable for the this parameter, make sure we
        don't offset from a parent of the DECL_CONTEXT of the function.
 
+Tue Oct 11 16:10:52 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
+
+       * pt.c (do_function_instantiation): Set DECL_EXTERNAL and
+       TREE_STATIC when setting DECL_INTERFACE_KNOWN.
+       (do_type_instantiation): Ditto.
+
+       * lex.c (cons_up_default_function): Set DECL_INTERFACE_KNOWN,
+       DECL_EXTERNAL and TREE_STATIC as appropriate.
+
+       * decl2.c (finish_file): Also synthesize methods that don't have
+       DECL_EXTERNAL set.  Set interface_unknown before doing so.
+
+       * decl.c (start_function): If DECL_INTERFACE_KNOWN is set on the
+       function decl, don't muck with TREE_PUBLIC and DECL_EXTERNAL.
+
 Mon Oct 10 00:56:53 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
 
-        * lex.c (cons_up_default_function): Mark methods in a template class
-        as template instances.  Store the values of interface_unknown and
-        interface_only for do_pending_inlines.
-        (do_pending_inlines): Use them.
+       * lex.c (cons_up_default_function): Mark methods in a template class
+       as template instances.  Store the values of interface_unknown and
+       interface_only for do_pending_inlines.
+       (do_pending_inlines): Use them.
+
+       * decl2.c (finish_file): If we haven't seen a definition of a
+       function declared static, make the decl non-PUBLIC so compile_file
+       can give an error.
 
 Sun Oct  9 02:42:29 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
 
-        * method.c (do_build_copy_constructor): Handle anonymous unions.
-        (do_build_assign_ref): Ditto.
-        (largest_union_member): Move from lex.c.
+       * method.c (do_build_copy_constructor): Handle anonymous unions.
+       (do_build_assign_ref): Ditto.
+       (largest_union_member): Move from lex.c.
+
+Sat Oct  8 14:59:43 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
+
+       Re-implement g++'s vague linkage independent of TREE_PUBLIC.
+       * pt.c (instantiate_member_templates): Lose redundant
+       -fexternal-templates handling.
+       (tsubst): Set TREE_PUBLIC and DECL_EXTERNAL on new decls.  Don't set
+       TREE_STATIC or DECL_INTERFACE_KNOWN.
+       (do_pending_expansions): Predicate on DECL_INTERFACE_KNOWN instead
+       of DECL_EXTERNAL for explicit instantiations.
+       (do_function_instantiation): Do the new thing.
+       (do_type_instantiation): Ditto.
+       (instantiate_template): Deal with member templates defined in a .cc
+       file with -fexternal-templates.
+       * except.c (expand_exception_blocks): Use DECL_LINKAGE_KNOWN to
+       decide whether to stick builtin_throw here.
+       * decl2.c (import_export_inline): Predicate on DECL_INTERFACE_KNOWN
+       rather than TREE_PUBLIC.  Generally fix rules.
+       (finish_file): Use DECL_INITIAL to determine whether or not a method
+       has been synthesized, rather than TREE_ASM_WRITTEN.
+       * decl.c (warn_extern_redeclared_static): Use DECL_PUBLIC instead of
+       TREE_PUBLIC.
+       (pushdecl): Ditto.
+       (duplicate_decls): Ditto.  Deal with DECL_DECLARED_STATIC and
+       DECL_INTERFACE_KNOWN. 
+       (redeclaration_error_message): Fix checking for conflicting linkage.
+       (define_function): Set DECL_INTERFACE_KNOWN.
+       (grokfndecl): Function decls are PUBLIC until we are sure about
+       their linkage.  Set DECL_DECLARED_STATIC as needed.
+       (start_function): Deal with linkage.  Move pushdecl after linkage
+       magic.
+       (finish_function): Don't set TREE_ASM_WRITTEN on discarded inlines.
+       * cp-tree.h (lang_decl_flags): Add interface_known and
+       declared_static.
+       (DECL_INTERFACE_KNOWN): New macro.
+       (DECL_DECLARED_STATIC): New macro.
+       (DECL_PUBLIC): New macro.
+
+       Clean up bogus use of TREE_PUBLIC.
+       * class.c (alter_access): Fix mistaken use of TREE_PUBLIC (it
+       doesn't correspond to TREE_PROTECTED and TREE_PRIVATE).
+       * init.c (do_friend): Don't arbitrarily set TREE_PUBLIC.
 
 Wed Oct  5 13:44:41 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
 
-        * call.c (build_overload_call_real): Don't immediately do
-        array->pointer conversion.
+       * call.c (build_overload_call_real): Don't immediately do
+       array->pointer conversion.
 
-        * pt.c (type_unification): If not passing to a reference, strip
-        cv-quals.  Also handle array->pointer conversion.
+       * pt.c (type_unification): If not passing to a reference, strip
+       cv-quals.  Also handle array->pointer conversion.
 
 Tue Oct  4 17:45:37 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
 
-        * decl.c (grokdeclarator): Don't warn about applying const to a
-        const typedef or template type parameter.
+       * decl.c (grokdeclarator): Don't warn about applying const to a
+       const typedef or template type parameter.
+
+       * decl2.c (finish_file): Also synthesize methods after walking the
+       vtables.  Ugly ugly ugly.
 
 Mon Oct  3 15:02:41 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
 
-        * decl.c (shadow_tag): Remove obsolete code for pushing tags and
-        dealing with exceptions.
+       * various: Remove lingering remnants of old exception handling code.
+
+       * decl2.c (finish_file): Synthesize methods before walking the
+       vtables, so that the vtables get emitted as needed.
+
+       * decl.c (shadow_tag): Remove obsolete code for pushing tags and
+       dealing with exceptions.
+
+Mon Oct  3 13:05:27 1994  Ian Lance Taylor  <ian@sanguine.cygnus.com>
+
+       * Make-lang.in (g++-cross): Depend upon version.o and $(LIBDEPS).
+
+Mon Oct  3 02:59:28 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
+
+       * decl2.c (finish_file): Fix inline handling.
 
 Sun Oct  2 00:21:56 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
 
-        * parse.y (expr_or_declarator): Add '(' expr_or_declarator ')' rule.
-        (direct_notype_declarator): Ditto.
-        (complex_direct_notype_declarator): Remove it here.
+       * decl.c (grokdeclarator): Handle redundant scope even better.
+       ({push,pop}_cp_function_context): Take toplev parameter.
 
-Sat Oct  1 21:42:18 1994  Jason Merrill  (jason@deneb.cygnus.com)
+       * method.c (synthesize_method): Pass toplev parameter to
+       {push,pop}_cp_function_context depending on decl_function_context
+       (fndecl).
 
-        * init.c (resolve_offset_ref): Fix types used in resolving .*
-        expressions.
+       * typeck.c (build_x_unary_op): Unary & on OFFSET_REFs is always the
+       built-in version.
 
-Thu Sep 29 16:15:36 1994  Michael I Bushnell  <mib@churchy.gnu.ai.mit.edu>
+       * method.c (synthesize_method): Don't be confused by __in_chrg
+       parameter.
 
-       * g++.c: Rework last change so it's done like collect.c (and 
-       gcc.c).
+       * class.c (popclass): Set C_C_D like start_function does.
 
-Wed Sep 28 19:19:01 1994  Brendan Kehoe  (brendan@mole.gnu.ai.mit.edu)
+       * decl.c (grokdeclarator): Handle redundant scope better.
 
-       * except.c (register_exception_table): Use Pmode, not PTRmode.
+       * parse.y (expr_or_declarator): Add '(' expr_or_declarator ')' rule.
+       (direct_notype_declarator): Ditto.
+       (complex_direct_notype_declarator): Remove it here.
 
-Wed Sep 14 10:17:27 1994  Michael I Bushnell  <mib@churchy.gnu.ai.mit.edu>
+Sat Oct  1 21:42:18 1994  Jason Merrill  (jason@deneb.cygnus.com)
 
-       * g++.c: Include <sys/errno.h> in case `errno' is a macro
-       as permitted by ANSI C.
+       * init.c (resolve_offset_ref): Fix types used in resolving .*
+       expressions.
+
+Sat Oct  1 15:18:49 1994  Jason Merrill  (jason@phydeaux.cygnus.com)
+
+       Beginnings of work to synthesize methods only when needed.
+       * call.c (build_method_call): Synthesize methods as necessary
+       (currently never necessary).
+       * class.c (popclass): Don't try to set C_C_D here, as it'll end up
+       on the wrong obstack.
+       * decl.c (push_cp_function_context): Mostly copied from
+       push_c_function_context.
+       (pop_cp_function_context): Similarly.
+       (finish_function): Reverse order of poplevel and pop_nested_class so
+       that current_class_decl is restored properly.  
+       (start_function): Ditto.
+       (finish_function): Add parameter 'nested'.  Don't call
+       permanent_allocation if (nested).
+       * various: Pass extra parameter to finish_function.     
+       * decl2.c (finish_file): Reorganize end-of-file inline handling,
+       synthesizing methods as necessary.
+       * lex.c (cons_up_default_function): Call mark_inline_for_output.
+       Only synthesize methods immediately if #pragma implementation
+       (currently disabled).
+       (do_pending_inlines): Call synthesize_method.
+       * method.c (synthesize_method): New function; all method synthesis
+       goes through here.  Calls do_build_assign_ref and
+       do_build_copy_constructor.
+       (build_default_constructor): Remove.
+       (build_dtor): Ditto.
+       (build_assign_ref): Rename to do_build_assign_ref and remove stuff
+       done by synthesize_method.
+       (build_copy_constructor): Similarly.
 
 Thu Sep 29 16:58:52 1994  Mike Stump  <mrs@cygnus.com>
 
@@ -282,12 +628,12 @@ Sun Sep 18 10:12:12 1994  Jason Merrill  (jason@deneb.cygnus.com)
        * *.c: Use cp_build_type_variant instead of c_build_type_variant.
 
        * pt.c (do_type_instantiation): Don't try to instantiate nested
-        enums.
+       enums.
 
 Tue Sep 13 10:56:58 1994  Jason Merrill  (jason@deneb.cygnus.com)
 
        * cvt.c (build_up_reference): Handle preincrement and predecrement
-        properly.
+       properly.
 
 Tue Sep 13 09:51:59 1994  Brendan Kehoe  (brendan@lisa.cygnus.com)
 
@@ -466,7 +812,7 @@ Sun Aug 21 23:07:35 1994  Gerald Baumgartner  (gb@cs.purdue.edu)
        * class.c (finish_struct): Move setting of CLASSTYPE_INTERFACE and
        CLASSTYPE_VTABLE_NEEDS_WRITING for signatures up to left_curly time.
        * decl.c (xref_tag): Move setting of CLASSTYPE_INTERFACE and
-        CLASSTYPE_VTABLE_NEEDS_WRITING for signatures down to left_curly time.
+       CLASSTYPE_VTABLE_NEEDS_WRITING for signatures down to left_curly time.
        * parse.y (left_curly): New final resting place for setting
        CLASSTYPE_INTERFACE and CLASSTYPE_VTABLE_NEEDS_WRITING for signatures.
 
@@ -486,12 +832,22 @@ Thu Aug 18 16:24:43 1994  Mike Stump  (mrs@cygnus.com)
 
        * error.c (dump_decl): Handle NULL args.
 
+Thu Sep 29 16:15:36 1994  Michael I Bushnell  <mib@churchy.gnu.ai.mit.edu>
+
+       * g++.c: Rework last change so it's done like collect.c (and 
+       gcc.c).
+
+Wed Sep 14 10:17:27 1994  Michael I Bushnell  <mib@churchy.gnu.ai.mit.edu>
+
+       * g++.c: Include <sys/errno.h> in case `errno' is a macro
+       as permitted by ANSI C.
+
 Thu Aug 18 12:48:09 1994  Mike Stump  (mrs@cygnus.com)
 
        * class.c (finish_struct): Move setting of CLASSTYPE_INTERFACE and
        CLASSTYPE_VTABLE_NEEDS_WRITING up to left_curly time.
        * decl.c (xref_tag): Move setting of CLASSTYPE_INTERFACE and
-        CLASSTYPE_VTABLE_NEEDS_WRITING down to left_curly time.
+       CLASSTYPE_VTABLE_NEEDS_WRITING down to left_curly time.
        * parse.y (left_curly): New final resting place for setting
        CLASSTYPE_INTERFACE and CLASSTYPE_VTABLE_NEEDS_WRITING.
 
@@ -851,7 +1207,7 @@ Fri Jul  8 12:59:38 1994  Jason Merrill  (jason@deneb.cygnus.com)
        * method.c (hack_identifier): Fix for new overloading.
 
        * typeck.c (build_binary_op_nodefault): Don't mess with division by
-        zero.
+       zero.
 
 Fri Jul  8 13:20:28 1994  Gerald Baumgartner  (gb@cs.purdue.edu)
 
index a9c3555f98ea3860d99bf3a470574bae52d97981..7a7da70ed4ebaed149179f933efd7d2ac076c5fa 100644 (file)
@@ -61,7 +61,7 @@ g++: $(srcdir)/cp/g++.c $(CONFIG_H) $(LIBDEPS)
        $(CC) $(ALL_CFLAGS) $(INCLUDES) $(LDFLAGS) -o g++ $(srcdir)/cp/g++.c $(LIBS)
 
 # Create a version of the g++ driver which calls the cross-compiler.
-g++-cross: $(srcdir)/cp/g++.c
+g++-cross: $(srcdir)/cp/g++.c version.o $(LIBDEPS)
        $(CC) $(ALL_CFLAGS) $(INCLUDES) $(LDFLAGS) -o g++-cross \
           -DGCC_NAME=\"$(GCC_CROSS_NAME)\" $(srcdir)/cp/g++.c version.o $(LIBS)
 
index 84cabe3652873ac3da13512252780a825dad5124..ed7c63f6128d16def7b096f47e27345d082109d9 100644 (file)
@@ -187,15 +187,26 @@ RTL_H = $(srcdir)/../rtl.h $(srcdir)/../rtl.def \
 TREE_H = $(srcdir)/../tree.h $(srcdir)/../real.h $(srcdir)/../tree.def \
        $(srcdir)/../machmode.h $(srcdir)/../machmode.def
 CXX_TREE_H = $(TREE_H) cp-tree.h tree.def
+PARSE_H = $(srcdir)/parse.h
+PARSE_C = $(srcdir)/parse.c
 
-parse.o : $(srcdir)/parse.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h
+parse.o : $(PARSE_C) $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h
        $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \
-  `echo $(srcdir)/parse.c | sed 's,^\./,,'`
-
-$(srcdir)/parse.c $(srcdir)/parse.h : $(srcdir)/parse.y
+  `echo $(PARSE_C) | sed 's,^\./,,'`
+
+#$(PARSE_C) $(PARSE_H) : $(srcdir)/parse.y
+#      @echo expect 1 shift/reduce confict and 34 reduce/reduce conflicts.
+#      cd $(srcdir); $(BISON) $(BISONFLAGS) -d -o parse.c parse.y
+#      cd $(srcdir); grep '^#define[   ]*YYEMPTY' parse.c >>parse.h
+$(PARSE_C) $(PARSE_H) : stamp-parse ; @true
+stamp-parse: $(srcdir)/parse.y
        @echo expect 1 shift/reduce confict and 34 reduce/reduce conflicts.
-       cd $(srcdir); $(BISON) $(BISONFLAGS) -d -o parse.c parse.y
-       cd $(srcdir); grep '^#define[   ]*YYEMPTY' parse.c >>parse.h
+       $(BISON) $(BISONFLAGS) -d $(srcdir)/parse.y
+       grep '^#define[         ]*YYEMPTY' y.tab.c >>y.tab.h
+       $(srcdir)/../move-if-change y.tab.c $(PARSE_C)
+       $(srcdir)/../move-if-change y.tab.h $(PARSE_H)
+       cp $(PARSE_C) y.tab.c
+       touch stamp-parse
 
 # hash.h really depends on $(srcdir)/gxx.gperf.
 # But this would screw things for people that don't have gperf,
@@ -206,9 +217,9 @@ $(srcdir)/hash.h:
                $(srcdir)/gxx.gperf >$(srcdir)/hash.h
 
 spew.o : spew.c $(CONFIG_H) $(CXX_TREE_H) \
-  $(srcdir)/parse.h $(srcdir)/../flags.h lex.h
+  $(PARSE_H) $(srcdir)/../flags.h lex.h
 lex.o : lex.c $(CONFIG_H) $(CXX_TREE_H) \
-  $(srcdir)/parse.h input.c $(srcdir)/../flags.h hash.h lex.h
+  $(PARSE_H) input.c $(srcdir)/../flags.h hash.h lex.h
 decl.o : decl.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
   lex.h decl.h $(srcdir)/../stack.h
 decl2.o : decl2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
@@ -229,7 +240,7 @@ expr.o : expr.c $(CONFIG_H) $(CXX_TREE_H) $(RTL_H) $(srcdir)/../flags.h \
   $(srcdir)/../expr.h ../insn-codes.h
 edsel.o : edsel.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../stack.h $(srcdir)/../flags.h
 xref.o : xref.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../input.h
-pt.o : pt.c $(CONFIG_H) $(CXX_TREE_H) decl.h $(srcdir)/parse.h
+pt.o : pt.c $(CONFIG_H) $(CXX_TREE_H) decl.h $(PARSE_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
index 41580a6199fbeb0a884bf13ae80eec302efd93a1..436fc313ebc677911a0a367cfb0ceccf7ee7f923 100644 (file)
@@ -525,13 +525,6 @@ convert_harshness (type, parmtype, parm)
       else
        penalty = 2;
 
-      if (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (intype))
-       {
-         ttl = unsigned_type (ttl);
-         intype = unsigned_type (intype);
-         penalty += 2;
-       }
-
       ttr = intype;
 
       /* If the initializer is not an lvalue, then it does not
@@ -551,6 +544,13 @@ convert_harshness (type, parmtype, parm)
          return h;
        }
 
+      if (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (intype))
+       {
+         ttl = unsigned_type (ttl);
+         ttr = intype = unsigned_type (intype);
+         penalty += 2;
+       }
+
       if (ttl == ttr)
        {
          if (penalty > 2)
@@ -2197,6 +2197,12 @@ build_method_call (instance, name, parms, basetype_path, flags)
                      cp->function = function;
                      cp->basetypes = basetype_path;
 
+                     /* Don't allow non-converting constructors to convert. */
+                     if (flags & LOOKUP_ONLYCONVERTING
+                         && DECL_LANG_SPECIFIC (function)
+                         && DECL_NONCONVERTING_P (function))
+                       continue;
+
                      /* No "two-level" conversions.  */
                      if (flags & LOOKUP_NO_CONVERSION
                          && (cp->h.code & USER_CODE))
@@ -2434,6 +2440,13 @@ build_method_call (instance, name, parms, basetype_path, flags)
   /* Declare external function if necessary. */
   assemble_external (function);
 
+#if 0
+  if (DECL_ARTIFICIAL (function) && ! flag_no_inline
+      && DECL_SAVED_INSNS (function) == 0
+      && ! TREE_ASM_WRITTEN (function))
+    synthesize_method (function);
+#endif
+
   fntype = TREE_TYPE (function);
   if (TREE_CODE (fntype) == POINTER_TYPE)
     fntype = TREE_TYPE (fntype);
index a3bcb26d3d2f0f138fd11cc3715ddaa78cc9ad71..5b89370eface1219b58f41e59bbdb13e199249f1 100644 (file)
@@ -659,7 +659,7 @@ prepare_fresh_vtable (binfo, for_type)
      for_type, and we really want different names.  (mrs) */
   tree name = build_type_pathname (VTABLE_NAME_FORMAT, basetype, for_type);
   tree new_decl = build_decl (VAR_DECL, name, TREE_TYPE (orig_decl));
-  tree path;
+  tree path, offset;
   int result;
 
   /* Remember which class this vtable is really for.  */
@@ -676,11 +676,18 @@ prepare_fresh_vtable (binfo, for_type)
 
   /* Make fresh virtual list, so we can smash it later.  */
   BINFO_VIRTUALS (binfo) = copy_list (BINFO_VIRTUALS (binfo));
+
+  if (TREE_VIA_VIRTUAL (binfo))
+    offset = BINFO_OFFSET (binfo_member (BINFO_TYPE (binfo), 
+                           CLASSTYPE_VBASECLASSES (for_type)));
+  else
+    offset = BINFO_OFFSET (binfo);
+
   /* Install the value for `headof' if that's what we're doing.  */
-  if (flag_dossier)
-    TREE_VALUE (TREE_CHAIN (BINFO_VIRTUALS (binfo)))
-      = build_vtable_entry (size_binop (MINUS_EXPR, integer_zero_node, BINFO_OFFSET (binfo)),
-                           FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (TREE_CHAIN (BINFO_VIRTUALS (binfo)))));
+  if (flag_rtti)
+    TREE_VALUE (BINFO_VIRTUALS (binfo))
+      = build_vtable_entry (size_binop (MINUS_EXPR, integer_zero_node, offset),
+           FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (BINFO_VIRTUALS (binfo))));
 
 #ifdef GATHER_STATISTICS
   n_vtables += 1;
@@ -803,11 +810,13 @@ add_virtual_function (pending_virtuals, has_virtual, fndecl, t)
     {
       tree entry;
 
-      if (flag_dossier && *has_virtual == 0)
+      if (flag_rtti && *has_virtual == 0)
        {
-         /* CLASSTYPE_DOSSIER is only used as a Boolean (NULL or not). */
-         CLASSTYPE_DOSSIER (t) = integer_one_node;
+         /* CLASSTYPE_RTTI is only used as a Boolean (NULL or not). */
+         CLASSTYPE_RTTI (t) = integer_one_node;
+#if 0
          *has_virtual = 1;
+#endif
         }
 
       /* Build a new INT_CST for this DECL_VINDEX.  */
@@ -1083,19 +1092,21 @@ alter_access (t, fdecl, access)
        error ("conflicting access specifications for field `%s', ignored",
               IDENTIFIER_POINTER (DECL_NAME (fdecl)));
     }
-  else if (TREE_PRIVATE (fdecl) && access != access_private)
-    cp_error_at ("cannot make private `%D' non-private", fdecl);
+  else if (TREE_PRIVATE (fdecl))
+    {
+      if (access != access_private)
+       cp_error_at ("cannot make private `%D' non-private", fdecl);
+      goto alter;
+    }
   else if (TREE_PROTECTED (fdecl))
     {
-      if (access == access_public)
-       cp_error_at ("cannot make protected `%D' public", fdecl);
+      if (access != access_protected)
+       cp_error_at ("cannot make protected `%D' non-protected", fdecl);
       goto alter;
     }
   /* ARM 11.3: an access declaration may not be used to restrict access
      to a member that is accessible in the base class.  */
-  else if (TREE_PUBLIC (fdecl)
-          && (access == access_private
-              || access == access_protected))
+  else if (access != access_public)
     cp_error_at ("cannot reduce access of public member `%D'", fdecl);
   else if (elem == NULL_TREE)
     {
@@ -2120,7 +2131,7 @@ finish_vtbls (binfo, do_self, t)
        {
          base_binfo = binfo_member (BINFO_TYPE (base_binfo), CLASSTYPE_VBASECLASSES (t));
        }
-      finish_vtbls (base_binfo, is_not_base_vtable, t);
+      finish_vtbls (base_binfo, (is_not_base_vtable || flag_rtti), t);
     }
 }
 
@@ -2239,12 +2250,34 @@ modify_one_vtable (binfo, t, fndecl, pfn)
      tree binfo, t, fndecl, pfn;
 {
   tree virtuals = BINFO_VIRTUALS (binfo);
+  tree old_rtti;
   unsigned HOST_WIDE_INT n;
   
-  n = 0;
-  /* Skip initial vtable length field and RTTI fake object. */
-  for (; virtuals && n < 1 + flag_dossier; n++)
-      virtuals = TREE_CHAIN (virtuals);
+  /* update rtti entry */
+  if (flag_rtti)
+    {
+      if (binfo == TYPE_BINFO (t))
+       {
+         if (! BINFO_NEW_VTABLE_MARKED (binfo))
+           build_vtable (TYPE_BINFO (DECL_CONTEXT (CLASSTYPE_VFIELD (t))), t);
+       }
+      else
+       {
+         if (! BINFO_NEW_VTABLE_MARKED (binfo))
+           prepare_fresh_vtable (binfo, t);
+       }
+      old_rtti = get_vtable_entry_n (BINFO_VIRTUALS (binfo), 0);
+      if (old_rtti)
+       TREE_VALUE (old_rtti) = build_vtable_entry (
+       DELTA_FROM_VTABLE_ENTRY (TREE_VALUE (old_rtti)), 
+        build_t_desc (t, 0));
+    }
+  if (fndecl == NULL_TREE) return;
+
+  /* Skip RTTI fake object. */
+  n = 1;
+  if (virtuals)
+    virtuals = TREE_CHAIN (virtuals);
   while (virtuals)
     {
       tree current_fndecl = TREE_VALUE (virtuals);
@@ -2330,7 +2363,7 @@ modify_all_direct_vtables (binfo, do_self, t, fndecl, pfn)
       int is_not_base_vtable =
        i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
       if (! TREE_VIA_VIRTUAL (base_binfo))
-       modify_all_direct_vtables (base_binfo, is_not_base_vtable, t, fndecl, pfn);
+       modify_all_direct_vtables (base_binfo, (is_not_base_vtable || flag_rtti), t, fndecl, pfn);
     }
 }
 
@@ -2345,10 +2378,10 @@ fixup_vtable_deltas (binfo, t)
   tree virtuals = BINFO_VIRTUALS (binfo);
   unsigned HOST_WIDE_INT n;
   
-  n = 0;
-  /* Skip initial vtable length field and RTTI fake object. */
-  for (; virtuals && n < 1 + flag_dossier; n++)
-      virtuals = TREE_CHAIN (virtuals);
+  /* Skip RTTI fake object. */
+  n = 1;
+  if (virtuals)
+    virtuals = TREE_CHAIN (virtuals);
   while (virtuals)
     {
       tree fndecl = TREE_VALUE (virtuals);
@@ -2489,21 +2522,9 @@ override_one_vtable (binfo, old, t)
   if (BINFO_NEW_VTABLE_MARKED (binfo))
     choose = NEITHER;
 
-  /* Skip size entry. */
-  virtuals = TREE_CHAIN (virtuals);
   /* Skip RTTI fake object. */
-  if (flag_dossier)
-    {
-      virtuals = TREE_CHAIN (virtuals);
-    }
-
-  /* Skip size entry. */
+  virtuals = TREE_CHAIN (virtuals);
   old_virtuals = TREE_CHAIN (old_virtuals);
-  /* Skip RTTI fake object. */
-  if (flag_dossier)
-    {
-      old_virtuals = TREE_CHAIN (old_virtuals);
-    }
 
   while (virtuals)
     {
@@ -2789,8 +2810,10 @@ finish_struct (t, list_of_fieldlists, warn_anon)
     }
 #endif
 
-  if (flag_dossier)
+#if 0
+  if (flag_rtti)
     build_t_desc (t, 0);
+#endif
 
   TYPE_BINFO (t) = NULL_TREE;
 
@@ -3303,7 +3326,6 @@ finish_struct (t, list_of_fieldlists, warn_anon)
          tail = &TREE_CHAIN (dtor);
 
          if (DECL_VINDEX (dtor) == NULL_TREE
-             && ! CLASSTYPE_DECLARED_EXCEPTION (t)
              && (needs_virtual_dtor
                  || pending_virtuals != NULL_TREE
                  || pending_hard_virtuals != NULL_TREE))
@@ -3319,6 +3341,9 @@ finish_struct (t, list_of_fieldlists, warn_anon)
   *tail_user_methods = NULL_TREE;
 
   TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_HAS_DESTRUCTOR (t);
+  if (flag_rtti && (max_has_virtual > 0 || needs_virtual_dtor) && 
+       has_virtual == 0)
+    has_virtual = 1;
 
   if (! fn_fields)
     nonprivate_method = 1;
@@ -3374,7 +3399,6 @@ finish_struct (t, list_of_fieldlists, warn_anon)
       method_vec = finish_struct_methods (t, fn_fields, nonprivate_method);
 
       if (TYPE_HAS_CONSTRUCTOR (t)
-         && ! CLASSTYPE_DECLARED_EXCEPTION (t)
          && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE
          && DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE)
        {
@@ -3485,7 +3509,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
       DECL_FCONTEXT (vfield) = t;
       DECL_FIELD_SIZE (vfield) = 0;
       DECL_ALIGN (vfield) = TYPE_ALIGN (ptr_type_node);
-      if (CLASSTYPE_DOSSIER (t))
+      if (CLASSTYPE_RTTI (t))
        {
          /* vfield is always first entry in structure.  */
          TREE_CHAIN (vfield) = fields;
@@ -3680,14 +3704,16 @@ finish_struct (t, list_of_fieldlists, warn_anon)
       vbases = CLASSTYPE_VBASECLASSES (t);
       CLASSTYPE_N_VBASECLASSES (t) = list_length (vbases);
 
+      /* The rtti code should do this.  (mrs) */
+#if 0 
       while (vbases)
        {
-         /* The rtti code should do this.  (mrs) */
-         /* Update dossier info with offsets for virtual baseclasses.  */
-         if (flag_dossier && ! BINFO_NEW_VTABLE_MARKED (vbases))
+         /* Update rtti info with offsets for virtual baseclasses.  */
+         if (flag_rtti && ! BINFO_NEW_VTABLE_MARKED (vbases))
            prepare_fresh_vtable (vbases, t);
          vbases = TREE_CHAIN (vbases);
        }
+#endif
 
       {
        /* Now fixup overrides of all functions in vtables from all
@@ -3750,6 +3776,15 @@ finish_struct (t, list_of_fieldlists, warn_anon)
 #ifdef NOTQUITE
   cp_warning ("Doing hard virtuals for %T...", t);
 #endif
+
+  if (has_virtual > max_has_virtual)
+    max_has_virtual = has_virtual;
+  if (max_has_virtual > 0)
+    TYPE_VIRTUAL_P (t) = 1;
+
+  if (flag_rtti && TYPE_VIRTUAL_P (t) && !pending_hard_virtuals)
+    modify_all_vtables (t, NULL_TREE, NULL_TREE);
+
   while (pending_hard_virtuals)
     {
       modify_all_vtables (t,
@@ -3761,19 +3796,27 @@ finish_struct (t, list_of_fieldlists, warn_anon)
 
   /* Under our model of GC, every C++ class gets its own virtual
      function table, at least virtually.  */
-  if (pending_virtuals || CLASSTYPE_DOSSIER (t))
+  if (pending_virtuals || (flag_rtti && TYPE_VIRTUAL_P (t)))
     {
       pending_virtuals = nreverse (pending_virtuals);
       /* We must enter these virtuals into the table.  */
       if (first_vfn_base_index < 0)
        {
-         if (flag_dossier)
+         if (flag_rtti)
            pending_virtuals = tree_cons (NULL_TREE,
-                                         build_vtable_entry (integer_zero_node,
-                                                             build_t_desc (t, 0)),
-                                         pending_virtuals);
+               build_vtable_entry (integer_zero_node, build_t_desc (t, 0)),
+               pending_virtuals);
+         else 
+            pending_virtuals = tree_cons (NULL_TREE,
+                build_vtable_entry (integer_zero_node, integer_zero_node),
+                pending_virtuals);
+
+#if 0
+         /* The size is no longer used. */
+         /* now we put the size of the vtable as first entry */
          pending_virtuals = tree_cons (NULL_TREE, the_null_vtable_entry,
                                        pending_virtuals);
+#endif
          build_vtable (NULL_TREE, t);
        }
       else
@@ -3784,9 +3827,9 @@ finish_struct (t, list_of_fieldlists, warn_anon)
          if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t)))
            build_vtable (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), first_vfn_base_index), t);
 
-         /* Update the dossier pointer for this class.  */
-         if (flag_dossier)
-           TREE_VALUE (TREE_CHAIN (TYPE_BINFO_VIRTUALS (t)))
+         /* Update the rtti pointer for this class.  */
+         if (flag_rtti)
+           TREE_VALUE (TYPE_BINFO_VIRTUALS (t))
              = build_vtable_entry (integer_zero_node, build_t_desc (t, 0));
        }
 
@@ -3815,11 +3858,8 @@ finish_struct (t, list_of_fieldlists, warn_anon)
        CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1;
     }
 
-  if (has_virtual > max_has_virtual)
-    max_has_virtual = has_virtual;
   if (max_has_virtual || first_vfn_base_index >= 0)
     {
-      TYPE_VIRTUAL_P (t) = 1;
       CLASSTYPE_VSIZE (t) = has_virtual;
       if (first_vfn_base_index >= 0)
        {
@@ -3970,7 +4010,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
   else if (TYPE_NEEDS_CONSTRUCTING (t))
     build_class_init_list (t);
 
-  if (! CLASSTYPE_DECLARED_EXCEPTION (t) && ! IS_SIGNATURE (t))
+  if (! IS_SIGNATURE (t))
     embrace_waiting_friends (t);
 
   /* Write out inline function definitions.  */
@@ -4022,13 +4062,23 @@ finish_struct (t, list_of_fieldlists, warn_anon)
   finish_vtbls (TYPE_BINFO (t), 1, t);
   TYPE_BEING_DEFINED (t) = 0;
 
-  if (flag_dossier && CLASSTYPE_VTABLE_NEEDS_WRITING (t))
+  if (flag_rtti && TYPE_VIRTUAL_P (t) && CLASSTYPE_VTABLE_NEEDS_WRITING (t))
     {
       tree variants;
-      tree tdecl;
+      tree tdecl, td;
 
       /* Now instantiate its type descriptors.  */
-      tdecl = TREE_OPERAND (build_t_desc (t, 1), 0);
+      td = build_t_desc (t, 1);
+      if (td == NULL_TREE)
+       {
+         cp_error ("failed to build type descriptor node of '%T', maybe typeinfo.h not included", t);
+         tdecl = NULL_TREE;
+       }
+      else
+        tdecl = TREE_OPERAND (td, 0);
+
+#if 0
+      /* I see no need for building the following TD */
       variants = TYPE_POINTER_TO (t);
       build_type_variant (variants, 1, 0);
       while (variants)
@@ -4036,6 +4086,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
          build_t_desc (variants, 1);
          variants = TYPE_NEXT_VARIANT (variants);
        }
+#endif
       variants = build_reference_type (t);
       build_type_variant (variants, 1, 0);
       while (variants)
@@ -4043,11 +4094,14 @@ finish_struct (t, list_of_fieldlists, warn_anon)
          build_t_desc (variants, 1);
          variants = TYPE_NEXT_VARIANT (variants);
        }
-      DECL_CONTEXT (tdecl) = t;
+      if (tdecl != NULL_TREE)
+        DECL_CONTEXT (tdecl) = t;
     }
+#if 0
   /* Still need to instantiate this C struct's type descriptor.  */
-  else if (flag_dossier && ! CLASSTYPE_DOSSIER (t))
+  else if (flag_rtti && ! CLASSTYPE_RTTI (t))
     build_t_desc (t, 1);
+#endif
 
 #if 0
   if (TYPE_NAME (t) && TYPE_IDENTIFIER (t))
@@ -4450,9 +4504,20 @@ popclass (modify)
          if (TREE_CODE (TREE_TYPE (current_class_decl)) == POINTER_TYPE)
            {
              tree temp;
-             /* Can't call build_indirect_ref here, because it has special
-                logic to return C_C_D given this argument.  */
-             C_C_D = build1 (INDIRECT_REF, current_class_type, current_class_decl);
+             if (CLASSTYPE_INST_VAR (current_class_type) == NULL_TREE)
+               {
+                 /* Can't call build_indirect_ref here, because it has special
+                    logic to return C_C_D given this argument.  */
+                 C_C_D = build1 (INDIRECT_REF, current_class_type, current_class_decl);
+                 CLASSTYPE_INST_VAR (current_class_type) = C_C_D;
+               }
+             else
+               {
+                 C_C_D = CLASSTYPE_INST_VAR (current_class_type);
+                 /* `current_class_decl' is different for every
+                    function we compile.  */
+                 TREE_OPERAND (C_C_D, 0) = current_class_decl;
+               }
              temp = TREE_TYPE (TREE_TYPE (current_class_decl));
              TREE_READONLY (C_C_D) = TYPE_READONLY (temp);
              TREE_SIDE_EFFECTS (C_C_D) = TYPE_VOLATILE (temp);
index 13c21dcb070a7124b09c7ad7cd11d8a20152c840..98e2dd9641b717d4fc154cddecac7ab1b2aa7efd 100644 (file)
@@ -408,7 +408,7 @@ struct lang_type
       unsigned interface_only : 1;
       unsigned interface_unknown : 1;
       unsigned needs_virtual_reinit : 1;
-      unsigned declared_exception : 1;
+      unsigned vec_delete_takes_size : 1;
       unsigned declared_class : 1;
       unsigned being_defined : 1;
       unsigned redefined : 1;
@@ -442,13 +442,12 @@ struct lang_type
       unsigned has_const_init_ref : 1;
       unsigned has_complex_init_ref : 1;
       unsigned has_complex_assign_ref : 1;
-      unsigned vec_delete_takes_size : 1;
       unsigned has_abstract_assign_ref : 1;
 
       /* The MIPS compiler gets it wrong if this struct also
         does not fill out to a multiple of 4 bytes.  Add a
         member `dummy' with new bits if you go over the edge.  */
-      unsigned dummy : 19;
+      unsigned dummy : 20;
 
       unsigned n_vancestors : 16;
     } type_flags;
@@ -495,7 +494,7 @@ struct lang_type
   char *mi_matrix;
   union tree_node *conversions[last_conversion_type];
 
-  union tree_node *dossier;
+  union tree_node *rtti;
 
   union tree_node *methods;
 
@@ -629,8 +628,8 @@ struct lang_type
    signature reference type.  */
 #define SIGNATURE_REFERENCE_TO(NODE) (TYPE_LANG_SPECIFIC(NODE)->signature_reference_to)
 
-/* The is the VAR_DECL that contains NODE's dossier.  */
-#define CLASSTYPE_DOSSIER(NODE) (TYPE_LANG_SPECIFIC(NODE)->dossier)
+/* The is the VAR_DECL that contains NODE's rtti.  */
+#define CLASSTYPE_RTTI(NODE) (TYPE_LANG_SPECIFIC(NODE)->rtti)
 
 /* List of all explicit methods (chained using DECL_NEXT_METHOD),
    in order they were parsed. */
@@ -816,8 +815,6 @@ struct lang_type
 
 /* Say whether this node was declared as a "class" or a "struct".  */
 #define CLASSTYPE_DECLARED_CLASS(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.declared_class)
-/* Say whether this node was declared as a "class" or a "struct".  */
-#define CLASSTYPE_DECLARED_EXCEPTION(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.declared_exception)
 /* whether this can be globalized.  */
 #define CLASSTYPE_NO_GLOBALIZE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.no_globalize)
 
@@ -947,7 +944,10 @@ struct lang_decl_flags
   unsigned saved_inline : 1;
   unsigned use_template : 2;
 
-  unsigned dummy : 8;
+  unsigned interface_known : 1;
+  unsigned declared_static : 1;
+  unsigned nonconverting : 1;
+  unsigned dummy : 5;
 
   tree access;
   tree context;
@@ -1032,6 +1032,10 @@ struct lang_decl
    is mutable.  */
 #define DECL_MUTABLE_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.mutable_flag)
 
+/* Nonzero for _DECL means that this constructor is a non-converting
+   constructor.  */
+#define DECL_NONCONVERTING_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.nonconverting)
+
 /* Nonzero for FUNCTION_DECL means that this member function
    exists as part of an abstract class's interface.  */
 #define DECL_ABSTRACT_VIRTUAL_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.abstract_virtual)
@@ -1322,6 +1326,18 @@ struct lang_decl
 #define SET_CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \
   (CLASSTYPE_USE_TEMPLATE(NODE) = 3)
 
+/* We know what we're doing with this decl now.  */
+#define DECL_INTERFACE_KNOWN(NODE) \
+  (DECL_LANG_SPECIFIC (NODE)->decl_flags.interface_known)
+
+/* This decl was declared to have internal linkage.  */
+#define DECL_DECLARED_STATIC(NODE) \
+  (DECL_LANG_SPECIFIC (NODE)->decl_flags.declared_static)
+
+#define DECL_PUBLIC(NODE) \
+  (TREE_CODE (NODE) == FUNCTION_DECL ? ! DECL_DECLARED_STATIC (NODE) \
+   : TREE_PUBLIC (NODE))
+
 #define THUNK_DELTA(DECL) ((DECL)->decl.frame_size.i)
 
 /* ...and for unexpanded-parameterized-type nodes.  */
@@ -1330,7 +1346,7 @@ struct lang_decl
 
 /* An enumeration of the kind of tags that C++ accepts.  */
 enum tag_types { record_type, class_type, union_type, enum_type,
-                  exception_type, signature_type };
+                  signature_type };
 
 /* Zero means prototype weakly, as in ANSI C (no args means nothing).
    Each language context defines how this variable should be set.  */
@@ -1387,8 +1403,14 @@ extern tree void_zero_node;
 extern tree default_function_type;
 extern tree vtable_entry_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;
+extern tree __t_desc_type_node;
+extern tree __tp_desc_type_node;
+extern tree __access_mode_type_node;
+extern tree __bltn_desc_type_node, __user_desc_type_node;
+extern tree __class_desc_type_node, __attr_desc_type_node;
+extern tree __ptr_desc_type_node, __func_desc_type_node;
+extern tree __ptmf_desc_type_node, __ptmd_desc_type_node;
+extern tree type_info_type_node;
 extern tree class_star_type_node;
 extern tree this_identifier;
 extern tree pfn_identifier;
@@ -1402,7 +1424,7 @@ extern tree error_mark_list;
 
 extern tree ptr_type_node, const_ptr_type_node;
 extern tree class_type_node, record_type_node, union_type_node, enum_type_node;
-extern tree exception_type_node, unknown_type_node;
+extern tree unknown_type_node;
 extern tree opaque_type_node, signature_type_node;
 
 /* Node for "pointer to (virtual) function".
@@ -1419,11 +1441,6 @@ extern tree long_long_integer_type_node, long_long_unsigned_type_node;
 extern tree integer_two_node, integer_three_node;
 extern tree bool_type_node, true_node, false_node;
 
-/* in except.c */
-extern tree current_exception_type;
-extern tree current_exception_decl;
-extern tree current_exception_object;
-
 /* in pt.c  */
 /* PARM_VEC is a vector of template parameters, either IDENTIFIER_NODEs or
    PARM_DECLs.  BINDINGS, if non-null, is a vector of bindings for those
@@ -1715,9 +1732,9 @@ extern int flag_int_enum_equivalence;
 
 extern int flag_gc;
 
-/* Nonzero means generate 'dossiers' that give run-time type information.  */
+/* Nonzero means generate 'rtti' that give run-time type information.  */
 
-extern int flag_dossier;
+extern int flag_rtti;
 
 /* Nonzero means do emit exported implementations of functions even if
    they can be inlined.  */
@@ -1782,7 +1799,8 @@ extern tree current_class_type;   /* _TYPE: the type of the current class */
 #define LOOKUP_GLOBAL (16)
 #define LOOKUP_HAS_IN_CHARGE (32)
 #define LOOKUP_SPECULATIVELY (64)
-/* 128 & 256 are free */
+#define LOOKUP_ONLYCONVERTING (128)
+/* 256 is free */
 #define LOOKUP_NO_CONVERSION (512)
 #define LOOKUP_DESTRUCTOR (512)
 
@@ -1953,7 +1971,7 @@ extern tree grok_enum_decls                       PROTO((tree, tree));
 extern int start_function                      PROTO((tree, tree, tree, int));
 extern void store_parm_decls                   PROTO((void));
 extern void store_return_init                  PROTO((tree, tree));
-extern void finish_function                    PROTO((int, int));
+extern void finish_function                    PROTO((int, int, int));
 extern tree start_method                       PROTO((tree, tree, tree));
 extern tree finish_method                      PROTO((tree));
 extern void hack_incomplete_structures         PROTO((tree));
index 7777350d925a09359c324c31ea4839eafd9b5aa5..783d1f24ea0810bedecf35fe1ae47052fc38148c 100644 (file)
@@ -663,10 +663,12 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
 
       if (form == REFERENCE_TYPE)
        {
-         rval = copy_node (expr);
-         TREE_TYPE (rval) = build_pointer_type (TREE_TYPE (TREE_TYPE (expr)));
-         rval = cp_convert (build_pointer_type (TREE_TYPE (reftype)), rval,
+         tree type = TREE_TYPE (expr);
+         tree tmp = copy_node (expr);
+         TREE_TYPE (tmp) = build_pointer_type (TREE_TYPE (TREE_TYPE (expr)));
+         rval = cp_convert (build_pointer_type (TREE_TYPE (reftype)), tmp,
                             convtype, flags);
+         TREE_TYPE (tmp) = type;
          TREE_TYPE (rval) = reftype;
          return rval;
        }
@@ -725,7 +727,8 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
          && (rval = build_method_call
              (NULL_TREE, constructor_name_full (type),
               build_tree_list (NULL_TREE, expr), TYPE_BINFO (type),
-              LOOKUP_NO_CONVERSION|LOOKUP_SPECULATIVELY)))
+              LOOKUP_NO_CONVERSION|LOOKUP_SPECULATIVELY
+              | LOOKUP_ONLYCONVERTING)))
        {
          tree init;
 
@@ -736,7 +739,8 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
              init = build_method_call (t, constructor_name_full (type),
                                        build_tree_list (NULL_TREE, expr),
                                        TYPE_BINFO (type),
-                                       LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
+                                       LOOKUP_NORMAL|LOOKUP_NO_CONVERSION
+                                       | LOOKUP_ONLYCONVERTING);
 
              if (init == error_mark_node)
                return error_mark_node;
@@ -750,7 +754,8 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
              init = build_method_call (NULL_TREE, constructor_name_full (type),
                                        build_tree_list (NULL_TREE, expr),
                                        TYPE_BINFO (type),
-                                       LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
+                                       LOOKUP_NORMAL|LOOKUP_NO_CONVERSION
+                                       |LOOKUP_ONLYCONVERTING);
 
              if (init == error_mark_node)
                return error_mark_node;
@@ -1283,12 +1288,9 @@ cp_convert (type, expr, convtype, flags)
   if (IS_AGGR_TYPE_CODE (code))
     {
       tree dtype = TREE_TYPE (e);
+      tree ctor = NULL_TREE;
+      tree conversion = NULL_TREE;
 
-      if (TREE_CODE (dtype) == REFERENCE_TYPE)
-       {
-         e = convert_from_reference (e);
-         dtype = TREE_TYPE (e);
-       }
       dtype = TYPE_MAIN_VARIANT (dtype);
 
       /* Conversion of object pointers or signature pointers/references
@@ -1321,87 +1323,78 @@ cp_convert (type, expr, convtype, flags)
         There may be some ambiguity between using a constructor
         vs. using a type conversion operator when both apply.  */
 
-      else if (IS_AGGR_TYPE (dtype))
-       {
-         tree binfo;
-
-         tree conversion;
-
-         if (! DERIVED_FROM_P (type, dtype) && TYPE_HAS_CONVERSION (dtype))
-           conversion = build_type_conversion (CONVERT_EXPR, type, e, 1);
-         else
-           conversion = NULL_TREE;
-
-         if (TYPE_HAS_CONSTRUCTOR (type))
-           {
-             tree rval = build_method_call (NULL_TREE, constructor_name_full (type),
-                                            build_tree_list (NULL_TREE, e),
-                                            TYPE_BINFO (type),
-                                            conversion ? LOOKUP_NO_CONVERSION : 0);
+      if (IS_AGGR_TYPE (dtype) && ! DERIVED_FROM_P (type, dtype)
+         && TYPE_HAS_CONVERSION (dtype))
+       conversion = build_type_conversion (CONVERT_EXPR, type, e, 1);
 
-             if (rval != error_mark_node)
-               {
-                 if (conversion)
-                   {
-                     error ("both constructor and type conversion operator apply");
-                     return error_mark_node;
-                   }
-                 /* call to constructor successful.  */
-                 rval = build_cplus_new (type, rval, 1);
-                 return rval;
-               }
-           }
-         /* Type conversion successful/applies.  */
-         if (conversion)
-           {
-             if (conversion == error_mark_node)
-               error ("ambiguous pointer conversion");
-             return conversion;
-           }
-
-         /* now try normal C++ assignment semantics.  */
-         binfo = TYPE_BINFO (dtype);
-         if (BINFO_TYPE (binfo) == type
-             || (binfo = get_binfo (type, dtype, 1)))
-           {
-             if (binfo == error_mark_node)
-               return error_mark_node;
-           }
-         if (binfo != NULL_TREE)
-           {
-             if (lvalue_p (e))
-               {
-                 e = build_unary_op (ADDR_EXPR, e, 0);
+      if (conversion == error_mark_node)
+       {
+         error ("ambiguous pointer conversion");
+         return conversion;
+       }
 
-                 if (! BINFO_OFFSET_ZEROP (binfo))
-                   e = build (PLUS_EXPR, TYPE_POINTER_TO (type),
-                              e, BINFO_OFFSET (binfo));
-                 return build1 (INDIRECT_REF, type, e);
-               }
+      if (TYPE_HAS_CONSTRUCTOR (type))
+       ctor = build_method_call (NULL_TREE, constructor_name_full (type),
+                                 build_tree_list (NULL_TREE, e),
+                                 TYPE_BINFO (type),
+                                 LOOKUP_NORMAL | LOOKUP_SPECULATIVELY
+                                 | LOOKUP_ONLYCONVERTING
+                                 | (conversion ? LOOKUP_NO_CONVERSION : 0));
 
-             sorry ("addressable aggregates");
-             return error_mark_node;
-           }
-         error ("conversion between incompatible aggregate types requested");
+      if (ctor == error_mark_node)
+       {
+         cp_error ("in conversion to type `%T'", type);
          return error_mark_node;
        }
-      /* conversion from non-aggregate to aggregate type requires
-         constructor.  */
-      else if (TYPE_HAS_CONSTRUCTOR (type))
+      
+      if (conversion && ctor)
        {
-         tree rval;
-         tree init = build_method_call (NULL_TREE, constructor_name_full (type),
-                                        build_tree_list (NULL_TREE, e),
-                                        TYPE_BINFO (type), LOOKUP_NORMAL);
-         if (init == error_mark_node)
+         error ("both constructor and type conversion operator apply");
+         return error_mark_node;
+       }
+      else if (conversion)
+       return conversion;
+      else if (ctor)
+       {
+         if (current_function_decl)
+           /* We can't pass 1 to the with_cleanup_p arg here, because that
+              screws up passing classes by value.  */
+           ctor = build_cplus_new (type, ctor, 0);
+         else
            {
-             cp_error ("in conversion to type `%T'", type);
-             return error_mark_node;
+             register tree parm = TREE_OPERAND (ctor, 1);
+
+             /* Initializers for static variables and parameters
+                have to handle doing the initialization and
+                cleanup themselves.  */
+             my_friendly_assert (TREE_CODE (ctor) == CALL_EXPR, 322);
+#if 0
+             /* The following assertion fails in cases where we
+                are initializing a static member variable of a
+                particular instance of a template class with a
+                call to a constructor of the given instance, as
+                in:
+                
+                TMPL<int> object = TMPL<int>();
+                
+                Curiously, the assertion does not fail if we do
+                the same thing for a static member of a
+                non-template class, as in:
+                
+                T object = T();
+                
+                I can't see why we should care here whether or not
+                the initializer expression involves a call to
+                `new', so for the time being, it seems best to
+                just avoid doing this assertion.  */
+             my_friendly_assert (TREE_CALLS_NEW (TREE_VALUE (parm)),
+                                 323);
+#endif
+             TREE_VALUE (parm) = NULL_TREE;
+             ctor = build_indirect_ref (ctor, NULL_PTR);
+             TREE_HAS_CONSTRUCTOR (ctor) = 1;
            }
-         /* We can't pass 1 to the with_cleanup_p arg here, because that
-             screws up passing classes by value.  */
-         rval = build_cplus_new (type, init, 0);
-         return rval;
+         return ctor;
        }
     }
 
@@ -1483,9 +1476,9 @@ build_type_conversion_1 (xtype, basetype, expr, typename, for_sure)
   int flags;
 
   if (for_sure == 0)
-    flags = LOOKUP_PROTECT;
+    flags = LOOKUP_PROTECT|LOOKUP_ONLYCONVERTING;
   else
-    flags = LOOKUP_NORMAL;
+    flags = LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING;
 
   rval = build_method_call (expr, typename, NULL_TREE, NULL_TREE, flags);
   if (rval == error_mark_node)
@@ -1615,9 +1608,9 @@ build_type_conversion (code, xtype, expr, for_sure)
              int flags;
 
              if (for_sure == 0)
-               flags = LOOKUP_PROTECT;
+               flags = LOOKUP_PROTECT|LOOKUP_ONLYCONVERTING;
              else
-               flags = LOOKUP_NORMAL;
+               flags = LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING;
              rval = build_method_call (expr,
                                        constructor_name_full (typename),
                                        NULL_TREE, NULL_TREE, flags);
index 048ce5eb0e254c24db195933e549fcf0d10e2f5b..60fe14fd46ed4d93ccd5ff277d4c151756edb88a 100644 (file)
@@ -234,11 +234,27 @@ tree int_ftype_cptr_cptr_sizet;
 /* C++ extensions */
 tree vtable_entry_type;
 tree delta_type_node;
-tree __t_desc_type_node, __i_desc_type_node, __m_desc_type_node;
+#if 0
+/* Old rtti stuff. */
+tree __baselist_desc_type_node;
+tree __i_desc_type_node, __m_desc_type_node;
 tree __t_desc_array_type, __i_desc_array_type, __m_desc_array_type;
+#endif
+tree __t_desc_type_node, __tp_desc_type_node;
+tree __access_mode_type_node;
+tree __bltn_desc_type_node, __user_desc_type_node, __class_desc_type_node;
+tree __ptr_desc_type_node, __attr_desc_type_node, __func_desc_type_node;
+tree __ptmf_desc_type_node, __ptmd_desc_type_node;
+#if 0
+/* Not needed yet?  May be needed one day?  */
+tree __bltn_desc_array_type, __user_desc_array_type, __class_desc_array_type;
+tree __ptr_desc_array_type, __attr_dec_array_type, __func_desc_array_type;
+tree __ptmf_desc_array_type, __ptmd_desc_array_type;
+#endif
+
 tree class_star_type_node;
 tree class_type_node, record_type_node, union_type_node, enum_type_node;
-tree exception_type_node, unknown_type_node;
+tree unknown_type_node;
 tree opaque_type_node, signature_type_node;
 tree sigtable_entry_type;
 tree maybe_gc_cleanup;
@@ -1729,10 +1745,7 @@ pushtag (name, type, globalize)
         TYPE_NAME (type) = name;
       
       /* Do C++ gratuitous typedefing.  */
-      if (IDENTIFIER_TYPE_VALUE (name) != type
-         && (TREE_CODE (type) != RECORD_TYPE
-             || b->parm_flag != 2
-             || !CLASSTYPE_DECLARED_EXCEPTION (type)))
+      if (IDENTIFIER_TYPE_VALUE (name) != type)
         {
           register tree d;
          int newdecl = 0;
@@ -2055,7 +2068,7 @@ warn_extern_redeclared_static (newdecl, olddecl)
     return;
 
   name = DECL_ASSEMBLER_NAME (newdecl);
-  if (TREE_PUBLIC (name) && ! TREE_PUBLIC (newdecl))
+  if (TREE_PUBLIC (name) && ! DECL_PUBLIC (newdecl))
     {
       /* It's okay to redeclare an ANSI built-in function as static,
         or to declare a non-ANSI built-in function as anything.  */
@@ -2119,7 +2132,7 @@ duplicate_decls (newdecl, olddecl)
       /* 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.  Ditto for overloads.  */
-      if (! TREE_PUBLIC (newdecl)
+      if (! DECL_PUBLIC (newdecl)
          || (TREE_CODE (newdecl) == FUNCTION_DECL
              && DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl)))
        {
@@ -2453,33 +2466,29 @@ duplicate_decls (newdecl, olddecl)
     {
       TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
       DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
+      TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
 
-      if (TREE_CODE (newdecl) != FUNCTION_DECL)
-       TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
+      if (TREE_CODE (newdecl) == FUNCTION_DECL)
+       {
+         DECL_DECLARED_STATIC (newdecl) = DECL_DECLARED_STATIC (olddecl);
+         DECL_INTERFACE_KNOWN (newdecl) = DECL_INTERFACE_KNOWN (olddecl);
+       }
     }
   else
     {
       TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
-      /* A `const' which was not declared `extern' and is
-        in static storage is invisible.  */
+      /* A `const' which was not declared `extern' gets internal linkage.  */
       if (TREE_CODE (newdecl) == VAR_DECL
-         && TREE_READONLY (newdecl) && TREE_STATIC (newdecl)
-         && ! DECL_THIS_EXTERN (newdecl))
+         && TREE_READONLY (newdecl) && ! DECL_THIS_EXTERN (newdecl))
        TREE_PUBLIC (newdecl) = 0;
-      else if (TREE_CODE (newdecl) != FUNCTION_DECL)
-       TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
-    }
+      else
+       {
+         TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
 
-  /* For functions, static overrides non-static.  */
-  if (TREE_CODE (newdecl) == FUNCTION_DECL)
-    {
-      TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
-      /* This is since we don't automatically
-        copy the attributes of NEWDECL into OLDDECL.  */
-      TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
-      /* If this clears `static', clear it in the identifier too.  */
-      if (! TREE_PUBLIC (olddecl))
-       TREE_PUBLIC (DECL_ASSEMBLER_NAME (olddecl)) = 0;
+         /* If this clears PUBLIC, clear it in the identifier too.  */
+         if (TREE_CODE (newdecl) == FUNCTION_DECL && ! TREE_PUBLIC (olddecl))
+           TREE_PUBLIC (DECL_ASSEMBLER_NAME (olddecl)) = 0;
+       }
     }
 
   /* If either decl says `inline', this fn is inline,
@@ -2551,6 +2560,7 @@ duplicate_decls (newdecl, olddecl)
     {
       DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl);
       DECL_ACCESS (newdecl) = DECL_ACCESS (olddecl);
+      DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
     }
 
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
@@ -2843,7 +2853,7 @@ pushdecl (x)
 
          /* If the first global decl has external linkage,
             warn if we later see static one.  */
-         if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && TREE_PUBLIC (x))
+         if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && DECL_PUBLIC (x))
            TREE_PUBLIC (name) = 1;
 
          /* Don't install a TYPE_DECL if we already have another
@@ -3376,10 +3386,10 @@ redeclaration_error_message (newdecl, olddecl)
       if (DECL_LANG_SPECIFIC (olddecl) && DECL_ABSTRACT_VIRTUAL_P (olddecl))
        return 0;
 
-      /* Declarations of functions can insist on internal linkage
-        but they can't be inconsistent with internal linkage,
-        so there can be no error on that account.
-        However defining the same name twice is no good.  */
+      /* We'll complain about linkage mismatches in
+         warn_extern_redeclared_static.  */
+
+      /* defining the same name twice is no good.  */
       if (DECL_INITIAL (olddecl) != NULL_TREE
          && DECL_INITIAL (newdecl) != NULL_TREE
          /* However, defining once as extern inline and a second
@@ -3415,13 +3425,12 @@ redeclaration_error_message (newdecl, olddecl)
   else if (current_binding_level == global_binding_level)
     {
       /* Objects declared at top level:  */
+      /* Insist that the linkage match.  */
+      if (! TREE_PUBLIC (newdecl) && TREE_PUBLIC (olddecl))
+       return "conflicting declarations of `%#D'";
       /* If at least one is a reference, it's ok.  */
       if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl))
        return 0;
-      /* Now we have two tentative defs, or one tentative and one real def.  */
-      /* Insist that the linkage match.  */
-      if (TREE_PUBLIC (olddecl) != TREE_PUBLIC (newdecl))
-       return "conflicting declarations of `%#D'";
       /* Reject two definitions.  */
       return "redefinition of `%#D'";
     }
@@ -4134,7 +4143,7 @@ record_builtin_type (rid_index, name, type)
        }
     }
 
-  if (flag_dossier)
+  if (flag_rtti)
     {
       if (builtin_type_tdescs_len+5 >= builtin_type_tdescs_max)
        {
@@ -4254,7 +4263,7 @@ init_decl_processing ()
 #endif
 
   gcc_obstack_init (&decl_obstack);
-  if (flag_dossier)
+  if (flag_rtti)
     {
       builtin_type_tdescs_max = 100;
       builtin_type_tdescs_arr = (tree *)xmalloc (100 * sizeof (tree));
@@ -4839,7 +4848,8 @@ init_decl_processing ()
       record_builtin_type (RID_MAX, SIGTABLE_PTR_TYPE, sigtable_entry_type);
     }
 
-  if (flag_dossier)
+#if 0
+  if (flag_rtti)
     {
       /* Must build __t_desc type.  Currently, type descriptors look like this:
 
@@ -4950,9 +4960,7 @@ init_decl_processing ()
                           integer_type_node);
     }
 
-  /* Now, C++.  */
-  current_lang_name = lang_name_cplusplus;
-  if (flag_dossier)
+  if (flag_rtti)
     {
       int i = builtin_type_tdescs_len;
       while (i > 0)
@@ -4962,6 +4970,10 @@ init_decl_processing ()
          TREE_PUBLIC (TREE_OPERAND (tdesc, 0)) = 1;
        }
     }
+#endif /*flag_rtti*/
+
+  /* Now, C++.  */
+  current_lang_name = lang_name_cplusplus;
 
   auto_function (ansi_opname[(int) NEW_EXPR],
                 build_function_type (ptr_type_node,
@@ -5016,6 +5028,74 @@ init_decl_processing ()
   init_function_format_info ();
 }
 
+/* initialize type descriptor type node of various rtti type. */
+
+int
+init_type_desc()
+{
+  tree tdecl;
+
+  tdecl = lookup_name (get_identifier ("type_info"), 0);
+  if (tdecl == NULL_TREE)
+    return 0;
+  __t_desc_type_node = TREE_TYPE(tdecl);
+  __tp_desc_type_node = build_pointer_type (__t_desc_type_node);
+
+#if 0
+  tdecl = lookup_name (get_identifier ("__baselist_type_info"), 0);
+  if (tdecl == NULL_TREE)
+    return 0;
+  __baselist_desc_type_node = TREE_TYPE (tdecl);
+#endif
+
+  tdecl = lookup_name (get_identifier ("__builtin_type_info"), 0);
+  if (tdecl == NULL_TREE)
+    return 0;
+  __bltn_desc_type_node = TREE_TYPE (tdecl);
+
+  tdecl = lookup_name (get_identifier ("__user_type_info"), 0);
+  if (tdecl == NULL_TREE)
+    return 0;
+  __user_desc_type_node = TREE_TYPE (tdecl);
+
+  tdecl = lookup_name (get_identifier ("__class_type_info"), 0);
+  if (tdecl == NULL_TREE)
+    return 0;
+  __class_desc_type_node = TREE_TYPE (tdecl);
+
+  tdecl = lookup_field (__class_desc_type_node, 
+       get_identifier ("access_mode"), 0, 0);
+  if (tdecl == NULL_TREE)
+    return 0;
+  __access_mode_type_node = TREE_TYPE (tdecl);
+
+  tdecl = lookup_name (get_identifier ("__attr_type_info"), 0);
+  if (tdecl == NULL_TREE)
+    return 0;
+  __attr_desc_type_node = TREE_TYPE (tdecl);
+
+  tdecl = lookup_name (get_identifier ("__pointer_type_info"), 0);
+  if (tdecl == NULL_TREE)
+    return 0;
+  __ptr_desc_type_node = TREE_TYPE (tdecl);
+
+  tdecl = lookup_name (get_identifier ("__func_type_info"), 0);
+  if (tdecl == NULL_TREE)
+    return 0;
+  __func_desc_type_node = TREE_TYPE (tdecl);
+
+  tdecl = lookup_name (get_identifier ("__ptmf_type_info"), 0);
+  if (tdecl == NULL_TREE)
+    return 0;
+  __ptmf_desc_type_node = TREE_TYPE (tdecl);
+
+  tdecl = lookup_name (get_identifier ("__ptmd_type_info"), 0);
+  if (tdecl == NULL_TREE)
+    return 0;
+  __ptmd_desc_type_node = TREE_TYPE (tdecl);
+
+  return 1;
+}
 /* Make a definition for a builtin function named NAME and whose data type
    is TYPE.  TYPE should be a function type with argument types.
    FUNCTION_CODE tells later passes how to compile calls to this function.
@@ -5035,6 +5115,7 @@ define_function (name, type, function_code, pfn, library_name)
   tree decl = build_lang_decl (FUNCTION_DECL, get_identifier (name), type);
   DECL_EXTERNAL (decl) = 1;
   TREE_PUBLIC (decl) = 1;
+  DECL_INTERFACE_KNOWN (decl) = 1;
 
   /* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME,
      we cannot change DECL_ASSEMBLER_NAME until we have installed this
@@ -5213,11 +5294,6 @@ start_decl (declarator, declspecs, initialized, raises)
       pop_obstacks ();
     }
 
-  /* Interesting work for this is done in `finish_exception_decl'.  */
-  if (TREE_CODE (type) == RECORD_TYPE
-      && CLASSTYPE_DECLARED_EXCEPTION (type))
-    return decl;
-
   /* Corresponding pop_obstacks is done in `finish_decl'.  */
   push_obstacks_nochange ();
 
@@ -5258,9 +5334,6 @@ start_decl (declarator, declspecs, initialized, raises)
           DECL_ARGUMENTS (decl) = args;
         }
       d = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), TREE_TYPE (decl));
-      if (interface_unknown && flag_external_templates
-         && ! DECL_IN_SYSTEM_HEADER (decl))
-       warn_if_unknown_interface ();
       TREE_PUBLIC (d) = TREE_PUBLIC (decl);
       TREE_STATIC (d) = TREE_STATIC (decl);
       DECL_EXTERNAL (d) = (DECL_EXTERNAL (decl)
@@ -5751,12 +5824,6 @@ finish_decl (decl, init, asmspec_tree, need_pop)
                                DECL_CONTEXT (decl) == NULL_TREE, 0);
       goto finish_end;
     }
-  if (type != error_mark_node && IS_AGGR_TYPE (type)
-      && CLASSTYPE_DECLARED_EXCEPTION (type))
-    {
-      CLASSTYPE_GOT_SEMICOLON (type) = 1;
-      goto finish_end;
-    }
   if (TREE_CODE (decl) != FUNCTION_DECL)
     {
       ttype = target_type (type);
@@ -6158,7 +6225,7 @@ finish_decl (decl, init, asmspec_tree, need_pop)
          else if (toplev && ! TREE_PUBLIC (decl))
            {
              /* If this is a static const, change its apparent linkage
-                if it belongs to a #pragma interface.  */
+                if it belongs to a #pragma interface.  */
              if (!interface_unknown)
                {
                  TREE_PUBLIC (decl) = 1;
@@ -6623,8 +6690,14 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals,
       DECL_CLASS_CONTEXT (decl) = ctype;
     }
 
+  /* All function decls start out public; we'll fix their linkage later (at
+     definition or EOF) if appropriate.  */
+  TREE_PUBLIC (decl) = 1;
+
   if (publicp)
-    TREE_PUBLIC (decl) = 1;
+    ;
+  else
+    DECL_DECLARED_STATIC (decl) = 1;
 
   DECL_EXTERNAL (decl) = 1;
   if (quals != NULL_TREE && TREE_CODE (type) == FUNCTION_TYPE)
@@ -6876,7 +6949,7 @@ build_ptrmemfunc_type (type)
   t = make_lang_type (RECORD_TYPE);
 
   /* Let the front-end know this is a pointer to member function. */
-  TYPE_PTRMEMFUNC_FLAG(t) = 1;
+  TYPE_PTRMEMFUNC_FLAG (t) = 1;
   /* and not really an aggregate.  */
   IS_AGGR_TYPE (t) = 0;
 
@@ -6920,6 +6993,7 @@ build_ptrmemfunc_type (type)
       try to parse.
      PARM for a parameter declaration (either within a function prototype
       or before a function body).  Make a PARM_DECL, or return void_type_node.
+     CATCHPARM for a parameter declaration before a catch clause.
      TYPENAME if for a typename (in a cast or sizeof).
       Don't make a DECL node; just return the ..._TYPE node.
      FIELD for a struct or union field; make a FIELD_DECL.
@@ -6972,7 +7046,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
   int longlong = 0;
   int constp;
   int volatilep;
-  int virtualp, friendp, inlinep, staticp;
+  int virtualp, explicitp, friendp, inlinep, staticp;
   int explicit_int = 0;
   int explicit_char = 0;
   int opaque_typedef = 0;
@@ -7553,6 +7627,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
     warning ("duplicate `volatile'");
 #endif
   virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits);
+  RIDBIT_RESET (RID_VIRTUAL, specbits);
+  explicitp = RIDBIT_SETP (RID_EXPLICIT, specbits) != 0;
+  RIDBIT_RESET (RID_EXPLICIT, specbits);
 
   if (RIDBIT_SETP (RID_STATIC, specbits))
     staticp = 1 + (decl_context == FIELD);
@@ -7564,37 +7641,36 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
       staticp = 0;
     }
   friendp = RIDBIT_SETP (RID_FRIEND, specbits);
-  RIDBIT_RESET (RID_VIRTUAL, specbits);
   RIDBIT_RESET (RID_FRIEND, specbits);
 
   if (RIDBIT_SETP (RID_MUTABLE, specbits))
     {
       if (decl_context == PARM)
        {
-         error ("non-member `%s' cannot be declared mutable", name);
+         error ("non-member `%s' cannot be declared `mutable'", name);
          RIDBIT_RESET (RID_MUTABLE, specbits);
        }
       else if (friendp || decl_context == TYPENAME)
        {
-         error ("non-object member `%s' cannot be declared mutable", name);
+         error ("non-object member `%s' cannot be declared `mutable'", name);
          RIDBIT_RESET (RID_MUTABLE, specbits);
        }
       else if (staticp)
        {
-         error ("static `%s' cannot be declared mutable", name);
+         error ("static `%s' cannot be declared `mutable'", name);
          RIDBIT_RESET (RID_MUTABLE, specbits);
        }
 #if 0
       if (RIDBIT_SETP (RID_TYPEDEF, specbits))
        {
-         error ("non-object member `%s' cannot be declared mutable", name);
+         error ("non-object member `%s' cannot be declared `mutable'", name);
          RIDBIT_RESET (RID_MUTABLE, specbits);
        }
       /* Because local typedefs are parsed twice, we don't want this
         message here. */
       else if (decl_context != FIELD)
        {
-         error ("non-member `%s' cannot be declared mutable", name);
+         error ("non-member `%s' cannot be declared `mutable'", name);
          RIDBIT_RESET (RID_MUTABLE, specbits);
        }
 #endif
@@ -7682,7 +7758,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
     error ("multiple storage classes in declaration of `%s'", name);
   else if (decl_context != NORMAL && nclasses > 0)
     {
-      if (decl_context == PARM
+      if ((decl_context == PARM || decl_context == CATCHPARM)
          && (RIDBIT_SETP (RID_REGISTER, specbits)
              || RIDBIT_SETP (RID_AUTO, specbits)))
        ;
@@ -7782,7 +7858,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
                     op ? operator_name_string (tmp) : name);
            }
          else
-           error ((decl_context == PARM
+           error (((decl_context == PARM || decl_context == CATCHPARM)
                    ? "storage class specified for parameter `%s'"
                    : "storage class specified for typename"), name);
          RIDBIT_RESET (RID_REGISTER, specbits);
@@ -8107,6 +8183,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
                  }
                else            /* it's a constructor. */
                  {
+                   if (explicitp == 1)
+                     explicitp = 2;
                    /* ANSI C++ June 5 1992 WP 12.1.2.  A constructor may
                       not be declared const or volatile.  A constructor may
                       not be virtual.  A constructor may not be static.  */
@@ -8389,10 +8467,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
                /* This is the `standard' use of the scoping operator:
                   basetype :: member .  */
 
-               if (TREE_CODE (type) == FUNCTION_TYPE)
+               if (ctype == current_class_type)
+                 cp_pedwarn ("extra qualification `%T::' on member `%s' ignored",
+                             ctype, name);
+               else if (TREE_CODE (type) == FUNCTION_TYPE)
                  {
                    if (current_class_type == NULL_TREE
-                       || TYPE_MAIN_VARIANT (ctype) == current_class_type
                        || friendp)
                      type = build_cplus_method_type (build_type_variant (ctype, constp, volatilep),
                                                      TREE_TYPE (type), TYPE_ARG_TYPES (type));
@@ -8403,19 +8483,14 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
                        return void_type_node;
                      }
                  }
-               else if (TYPE_MAIN_VARIANT (ctype) == current_class_type)
-                 {
-                   if (extra_warnings)
-                     cp_warning ("redundant qualification `%T' on member `%s' ignored",
-                                 ctype, name);
-                   type = build_offset_type (ctype, type);
-                 }
                else if (TYPE_SIZE (ctype) != NULL_TREE
                         || (RIDBIT_SETP (RID_TYPEDEF, specbits)))
                  {
                    tree t;
                    /* have to move this code elsewhere in this function.
-                      this code is used for i.e., typedef int A::M; M *pm; */
+                      this code is used for i.e., typedef int A::M; M *pm;
+
+                      It is?  How? jason 10/2/94 */
 
                    if (explicit_int == -1 && decl_context == FIELD
                        && funcdef_flag == 0)
@@ -8441,7 +8516,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
                                /* Don't include destructor with constructors.  */
                                t = DECL_CHAIN (TREE_VALUE (t));
                                if (t == NULL_TREE)
-                                 error ("class `%s' does not have any constructors", IDENTIFIER_POINTER (sname));
+                                 cp_error ("`%T' does not have any constructors",
+                                           ctype);
                                t = build_tree_list (NULL_TREE, t);
                              }
                            t = build_lang_field_decl (FIELD_DECL, build_nt (SCOPE_REF, ctype, t), type);
@@ -8456,15 +8532,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
 
                    if (current_class_type)
                      {
-                       if (TYPE_MAIN_VARIANT (ctype) != current_class_type)
-                         {
-                           cp_error ("cannot declare member `%T::%s' within `%T'",
-                                  ctype, name, current_class_type);
-                           return void_type_node;
-                         }
-                       else if (extra_warnings)
-                         cp_warning ("extra qualification `%T' on member `%s' ignored",
-                                  ctype, name);
+                       cp_error ("cannot declare member `%T::%s' within `%T'",
+                                 ctype, name, current_class_type);
+                       return void_type_node;
                      }
                    type = build_offset_type (ctype, type);
                  }
@@ -8526,6 +8596,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
        }
     }
 
+  if (explicitp == 1)
+    {
+      error ("only constructors can be declared `explicit'");
+      explicitp = 0;
+    }
+
   /* Now TYPE has the actual type.  */
 
   /* If this is declaring a typedef name, return a TYPE_DECL.  */
@@ -8658,6 +8734,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
       return type;
     }
   else if (declarator == NULL_TREE && decl_context != PARM
+          && decl_context != CATCHPARM
           && TREE_CODE (type) != UNION_TYPE
           && ! bitfield)
     {
@@ -8803,6 +8880,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
            if (decl == NULL_TREE)
              return NULL_TREE;
 
+           if (explicitp == 2)
+             DECL_NONCONVERTING_P (decl) = 1;
+
            DECL_INLINE (decl) = inlinep;
          }
        else if (TREE_CODE (type) == METHOD_TYPE)
@@ -8817,20 +8897,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
 
            DECL_INLINE (decl) = inlinep;
          }
-       else if (TREE_CODE (type) == RECORD_TYPE
-                && CLASSTYPE_DECLARED_EXCEPTION (type))
-         {
-           /* Handle a class-local exception declaration.  */
-           decl = build_lang_field_decl (VAR_DECL, declarator, type);
-           if (ctype == NULL_TREE)
-             ctype = current_class_type;
-           return void_type_node;
-         }
        else if (TYPE_SIZE (type) == NULL_TREE && !staticp
                 && (TREE_CODE (type) != ARRAY_TYPE || initialized == 0))
          {
-           error ("field `%s' has incomplete type",
-                  IDENTIFIER_POINTER (declarator));
+           cp_error ("field `%D' has incomplete type", declarator);
 
            /* If we're instantiating a template, tell them which
               instantiation made the field's type be incomplete.  */
@@ -8839,9 +8909,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
                && IDENTIFIER_TEMPLATE (DECL_NAME (TYPE_NAME (current_class_type)))
                && declspecs && TREE_VALUE (declspecs)
                && TREE_TYPE (TREE_VALUE (declspecs)) == type)
-             error ("  in instantiation of template `%s'",
-                    TYPE_NAME_STRING (current_class_type));
-               
+             cp_error ("  in instantiation of template `%T'",
+                       current_class_type);
+
            type = error_mark_node;
            decl = NULL_TREE;
          }
@@ -9062,6 +9132,31 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
       {
        /* It's a variable.  */
 
+       if (decl_context == CATCHPARM)
+         {
+           if (ctype)
+             {
+               ctype = NULL_TREE;
+               error ("cannot use `::' in parameter declaration");
+             }
+
+           /* A parameter declared as an array of T is really a pointer to T.
+              One declared as a function is really a pointer to a function.
+              One declared as a member is really a pointer to member.  */
+
+           if (TREE_CODE (type) == ARRAY_TYPE)
+             {
+               /* Transfer const-ness of array into that of type pointed to. */
+               type = build_pointer_type
+                 (cp_build_type_variant (TREE_TYPE (type), constp, volatilep));
+               volatilep = constp = 0;
+             }
+           else if (TREE_CODE (type) == FUNCTION_TYPE)
+             type = build_pointer_type (type);
+           else if (TREE_CODE (type) == OFFSET_TYPE)
+             type = build_pointer_type (type);
+         }
+
        /* An uninitialized decl with `extern' is a reference.  */
        decl = grokvardecl (type, declarator, specbits, initialized);
        bad_specifiers (decl, "variable", virtualp, quals != NULL_TREE,
@@ -9850,7 +9945,6 @@ xref_tag (code_type_node, name, binfo, globalize)
     {
     case record_type:
     case class_type:
-    case exception_type:
     case signature_type:
       code = RECORD_TYPE;
       len = list_length (binfo);
@@ -9949,17 +10043,6 @@ xref_tag (code_type_node, name, binfo, globalize)
          if (flag_cadillac)
            cadillac_start_enum (ref);
        }
-      else if (tag_code == exception_type)
-       {
-         ref = make_lang_type (code);
-         /* Enable us to recognize when an exception type is created in
-            class context.  To do nested classes correctly, this should
-            probably be cleared out when we leave this class's scope.  */
-         CLASSTYPE_DECLARED_EXCEPTION (ref) = 1;
-         pushtag (name, ref, globalize);
-         if (flag_cadillac)
-           cadillac_start_struct (ref);
-       }
       else
        {
          struct binding_level *old_b = class_binding_level;
@@ -9990,17 +10073,6 @@ xref_tag (code_type_node, name, binfo, globalize)
     }
   else
     {
-      if (IS_AGGR_TYPE_CODE (code))
-       {
-         if (IS_AGGR_TYPE (ref)
-             && ((tag_code == exception_type)
-                 != (CLASSTYPE_DECLARED_EXCEPTION (ref) == 1)))
-           {
-             cp_error ("type `%T' is both exception and aggregate type", ref);
-             CLASSTYPE_DECLARED_EXCEPTION (ref) = (tag_code == exception_type);
-           }
-       }
-
       /* If it no longer looks like a nested type, make sure it's
         in global scope.  */
       if (b == global_binding_level && !class_binding_level
@@ -10666,29 +10738,20 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
      (This does not mean `static' in the C sense!)  */
   TREE_STATIC (decl1) = 1;
 
-  /* Record the decl so that the function name is defined.
-     If we already have a decl for this name, and it is a FUNCTION_DECL,
-     use the old decl.  */
-
-  if (pre_parsed_p == 0)
-    {
-      current_function_decl = decl1 = pushdecl (decl1);
-      DECL_MAIN_VARIANT (decl1) = decl1;
-      fntype = TREE_TYPE (decl1);
-    }
-  else
-    current_function_decl = decl1;
-
+  if (DECL_INTERFACE_KNOWN (decl1))
+    /* We know.  */;
   /* If this function belongs to an interface, it is public.
      If it belongs to someone else's interface, it is also external.
      It doesn't matter whether it's inline or not.  */
-  if (interface_unknown == 0
-      && ! TREE_PUBLIC (decl1))
+  else if (interface_unknown == 0)
     {
-      TREE_PUBLIC (decl1) = 1;
-      DECL_EXTERNAL (decl1)
-       = (interface_only
-          || (DECL_INLINE (decl1) && ! flag_implement_inlines));
+      if (DECL_DECLARED_STATIC (decl1) || DECL_TEMPLATE_INSTANTIATION (decl1))
+       DECL_EXTERNAL (decl1)
+         = (interface_only
+            || (DECL_INLINE (decl1) && ! flag_implement_inlines));
+      else
+       DECL_EXTERNAL (decl1) = current_extern_inline;
+      DECL_INTERFACE_KNOWN (decl1) = 1;
     }
   else
     {
@@ -10698,12 +10761,32 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
         defining how to inline.  So set DECL_EXTERNAL in that case.  */
       DECL_EXTERNAL (decl1) = current_extern_inline;
 
-      DECL_DEFER_OUTPUT (decl1)
-       = DECL_INLINE (decl1) && ! TREE_PUBLIC (decl1)
-         && (DECL_FUNCTION_MEMBER_P (decl1)
-             || DECL_TEMPLATE_INSTANTIATION (decl1));
+      if (DECL_INLINE (decl1) && (DECL_FUNCTION_MEMBER_P (decl1)
+                                 || DECL_TEMPLATE_INSTANTIATION (decl1)))
+       /* We know nothing yet */;
+      else
+       {
+         DECL_INTERFACE_KNOWN (decl1) = 1;
+         if (DECL_DECLARED_STATIC (decl1))
+           TREE_PUBLIC (decl1) = 0;
+       }
+
+      DECL_DEFER_OUTPUT (decl1) = ! DECL_INTERFACE_KNOWN (decl1);
     }
 
+  /* Record the decl so that the function name is defined.
+     If we already have a decl for this name, and it is a FUNCTION_DECL,
+     use the old decl.  */
+
+  if (pre_parsed_p == 0)
+    {
+      current_function_decl = decl1 = pushdecl (decl1);
+      DECL_MAIN_VARIANT (decl1) = decl1;
+      fntype = TREE_TYPE (decl1);
+    }
+  else
+    current_function_decl = decl1;
+
   if (ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1))
     {
       if (TREE_CODE (fntype) == METHOD_TYPE)
@@ -10716,18 +10799,6 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
     }
   restype = TREE_TYPE (fntype);
 
-  pushlevel (0);
-  current_binding_level->parm_flag = 1;
-
-  /* Save the parm names or decls from this function's declarator
-     where store_parm_decls will find them.  */
-  current_function_parms = last_function_parms;
-  current_function_parm_tags = last_function_parm_tags;
-
-  GNU_xref_function (decl1, current_function_parms);
-
-  make_function_rtl (decl1);
-
   if (ctype)
     {
       push_nested_class (ctype, 1);
@@ -10777,6 +10848,18 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
        push_memoized_context (0, 1);
     }
 
+  pushlevel (0);
+  current_binding_level->parm_flag = 1;
+
+  /* Save the parm names or decls from this function's declarator
+     where store_parm_decls will find them.  */
+  current_function_parms = last_function_parms;
+  current_function_parm_tags = last_function_parm_tags;
+
+  GNU_xref_function (decl1, current_function_parms);
+
+  make_function_rtl (decl1);
+
   /* Allocate further tree nodes temporarily during compilation
      of this function only.  Tiemann moved up here from bottom of fn.  */
   temporary_allocation ();
@@ -10972,9 +11055,11 @@ store_parm_decls ()
       if (flag_gc)
        expand_expr (build_function_call (lookup_name (get_identifier ("__gc_main"), 0), NULL_TREE),
                     0, VOIDmode, 0);
-
-      if (flag_dossier)
+#if 0
+      /* done at a differnet time */
+      if (flag_rtti)
        output_builtin_tdesc_entries ();
+#endif
     }
 }
 
@@ -11043,9 +11128,10 @@ store_return_init (return_id, init)
    constructors.  */
 
 void
-finish_function (lineno, call_poplevel)
+finish_function (lineno, call_poplevel, nested)
      int lineno;
      int call_poplevel;
+     int nested;
 {
   register tree fndecl = current_function_decl;
   tree fntype, ctype = NULL_TREE;
@@ -11072,7 +11158,7 @@ finish_function (lineno, call_poplevel)
       store_parm_decls ();
     }
 
-  if (write_symbols != NO_DEBUG && TREE_CODE (fntype) != METHOD_TYPE)
+  if (write_symbols != NO_DEBUG /*&& TREE_CODE (fntype) != METHOD_TYPE*/)
     {
       tree ttype = target_type (fntype);
       tree parmdecl;
@@ -11442,19 +11528,6 @@ finish_function (lineno, call_poplevel)
       expand_label (no_return_label);
     }
 
-  /* reset scope for C++: if we were in the scope of a class,
-     then when we finish this function, we are not longer so.
-     This cannot be done until we know for sure that no more
-     class members will ever be referenced in this function
-     (i.e., calls to destructors).  */
-  if (current_class_name)
-    {
-      ctype = current_class_type;
-      pop_nested_class (1);
-    }
-  else
-    pop_memoized_context (1);
-
   /* Generate rtl for function exit.  */
   expand_function_end (input_filename, lineno, 1);
 
@@ -11468,6 +11541,19 @@ finish_function (lineno, call_poplevel)
     my_friendly_abort (122);
   poplevel (1, 0, 1);
 
+  /* reset scope for C++: if we were in the scope of a class,
+     then when we finish this function, we are not longer so.
+     This cannot be done until we know for sure that no more
+     class members will ever be referenced in this function
+     (i.e., calls to destructors).  */
+  if (current_class_name)
+    {
+      ctype = current_class_type;
+      pop_nested_class (1);
+    }
+  else
+    pop_memoized_context (1);
+
   /* Must mark the RESULT_DECL as being in this function.  */
   DECL_CONTEXT (DECL_RESULT (fndecl)) = DECL_INITIAL (fndecl);
 
@@ -11554,7 +11640,8 @@ finish_function (lineno, call_poplevel)
   /* Free all the tree nodes making up this function.  */
   /* Switch back to allocating nodes permanently
      until we start another function.  */
-  permanent_allocation (1);
+  if (! nested)
+    permanent_allocation (1);
 
   if (flag_cadillac)
     cadillac_finish_function (fndecl);
@@ -11802,7 +11889,9 @@ hack_incomplete_structures (type)
                            decl);
              }
          }
+       /*
        my_friendly_assert (current_binding_level->n_incomplete > 0, 164);
+       */
        --current_binding_level->n_incomplete;
       }
 }
@@ -11980,3 +12069,100 @@ id_in_current_class (id)
 {
   return !!purpose_member (id, class_binding_level->class_shadowed);
 }
+
+struct cp_function
+{
+  int returns_value;
+  int returns_null;
+  int warn_about_return_type;
+  int extern_inline;
+  int assigns_this;
+  int just_assigned_this;
+  int parms_stored;
+  tree named_labels;
+  tree shadowed_labels;
+  tree ctor_label;
+  tree dtor_label;
+  rtx result_rtx;
+  struct cp_function *next;
+  struct binding_level *binding_level;
+};
+
+struct cp_function *cp_function_chain;
+
+/* Save and reinitialize the variables
+   used during compilation of a C++ function.  */
+
+void
+push_cp_function_context (toplev)
+     int toplev;
+{
+  struct cp_function *p
+    = (struct cp_function *) xmalloc (sizeof (struct cp_function));
+
+  push_function_context_to (toplev);
+
+  p->next = cp_function_chain;
+  cp_function_chain = p;
+
+  p->named_labels = named_labels;
+  p->shadowed_labels = shadowed_labels;
+  p->returns_value = current_function_returns_value;
+  p->returns_null = current_function_returns_null;
+  p->warn_about_return_type = warn_about_return_type;
+  p->extern_inline = current_extern_inline;
+  p->binding_level = current_binding_level;
+  p->ctor_label = ctor_label;
+  p->dtor_label = dtor_label;
+  p->assigns_this = current_function_assigns_this;
+  p->just_assigned_this = current_function_just_assigned_this;
+  p->parms_stored = current_function_parms_stored;
+  p->result_rtx = original_result_rtx;
+}
+
+/* Restore the variables used during compilation of a C++ function.  */
+
+void
+pop_cp_function_context (toplev)
+     int toplev;
+{
+  struct cp_function *p = cp_function_chain;
+  tree link;
+
+  /* Bring back all the labels that were shadowed.  */
+  for (link = shadowed_labels; link; link = TREE_CHAIN (link))
+    if (DECL_NAME (TREE_VALUE (link)) != 0)
+      SET_IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)),
+                                 TREE_VALUE (link));
+
+#if 0
+  if (DECL_SAVED_INSNS (current_function_decl) == 0)
+    {
+      /* Stop pointing to the local nodes about to be freed.  */
+      /* But DECL_INITIAL must remain nonzero so we know this
+        was an actual function definition.  */
+      DECL_INITIAL (current_function_decl) = error_mark_node;
+      DECL_ARGUMENTS (current_function_decl) = 0;
+    }
+#endif
+
+  pop_function_context_from (toplev);
+
+  cp_function_chain = p->next;
+
+  named_labels = p->named_labels;
+  shadowed_labels = p->shadowed_labels;
+  current_function_returns_value = p->returns_value;
+  current_function_returns_null = p->returns_null;
+  warn_about_return_type = p->warn_about_return_type;
+  current_extern_inline = p->extern_inline;
+  current_binding_level = p->binding_level;
+  ctor_label = p->ctor_label;
+  dtor_label = p->dtor_label;
+  current_function_assigns_this = p->assigns_this;
+  current_function_just_assigned_this = p->just_assigned_this;
+  current_function_parms_stored = p->parms_stored;
+  original_result_rtx = p->result_rtx;
+
+  free (p);
+}
index b088179ec7b64f982bde2d445810d7d2d5c29700..d0dfe8aac8700d6070afe000cbae4e990a14b88c 100644 (file)
@@ -22,6 +22,7 @@ enum decl_context
 { NORMAL,                      /* Ordinary declaration */
   FUNCDEF,                     /* Function definition */
   PARM,                                /* Declaration of parm before function body */
+  CATCHPARM,                   /* Declaration of catch parm */
   FIELD,                       /* Declaration inside struct or union */
   BITFIELD,                    /* Likewise but with specified width */
   TYPENAME,                    /* Typename (inside cast or sizeof)  */
index a50b7bce12931736f6f28719770bf1028be44d57..49318707ddd1aa37cfa7ad4ab9ec66dc87a6328c 100644 (file)
@@ -301,9 +301,9 @@ int flag_cadillac;
    that can be collected when they become garbage.  */
 int flag_gc;
 
-/* Controls whether compiler generates 'dossiers' that give
+/* Controls whether compiler generates 'type descriptor' that give
    run-time type information.  */
-int flag_dossier;
+int flag_rtti = 0;
 
 /* Nonzero if we wish to output cross-referencing information
    for the GNU class browser.  */
@@ -365,7 +365,7 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
   {"dollars-in-identifiers", &dollars_in_ident, 1},
   {"enum-int-equiv", &flag_int_enum_equivalence, 1},
   {"gc", &flag_gc, 1},
-  {"dossier", &flag_dossier, 1},
+  {"rtti", &flag_rtti, 1},
   {"xref", &flag_gnu_xref, 1},
   {"nonnull-objects", &flag_assume_nonnull_objects, 1},
   {"implement-inlines", &flag_implement_inlines, 1},
@@ -442,14 +442,14 @@ lang_decode_option (p)
        {
          flag_gc = 1;
          /* This must come along for the ride.  */
-         flag_dossier = 1;
+         flag_rtti = 1;
          found = 1;
        }
       else if (! strcmp (p, "no-gc"))
        {
          flag_gc = 0;
          /* This must come along for the ride.  */
-         flag_dossier = 0;
+         flag_rtti = 0;
          found = 1;
        }
       else if (! strcmp (p, "alt-external-templates"))
@@ -707,15 +707,10 @@ grok_x_components (specs, components)
            tcode = class_type_node;
          else if (IS_SIGNATURE(t))
            tcode = signature_type_node;
-         else if (CLASSTYPE_DECLARED_EXCEPTION(t))
-           tcode = exception_type_node;
          
          t = xref_defn_tag(tcode, TYPE_IDENTIFIER(t), NULL_TREE);
          if (TYPE_CONTEXT(t))
            CLASSTYPE_NO_GLOBALIZE(t) = 1;
-         if (TYPE_LANG_SPECIFIC (t)
-             && CLASSTYPE_DECLARED_EXCEPTION (t))
-           shadow_tag (specs);
          return NULL_TREE;
          break;
 
@@ -2170,7 +2165,9 @@ finish_table (name, type, init, publicp)
   if (TREE_VALUE (init) == integer_zero_node
       && TREE_CHAIN (init) == NULL_TREE)
     {
+#if 0
       if (empty_table == NULL_TREE)
+#endif
        {
          empty_table = get_temp_name (atype, 1);
          init = build (CONSTRUCTOR, atype, NULL_TREE, init);
@@ -2347,9 +2344,6 @@ mark_vtable_entries (decl)
 {
   tree entries = TREE_CHAIN (CONSTRUCTOR_ELTS (DECL_INITIAL (decl)));
 
-  if (flag_dossier)
-    entries = TREE_CHAIN (entries);
-
   for (; entries; entries = TREE_CHAIN (entries))
     {
       tree fnaddr = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries));
@@ -2439,14 +2433,18 @@ finish_vtable_vardecl (prev, vars)
 
       /* Stuff this virtual function table's size into
         `pfn' slot of `the_null_vtable_entry'.  */
+#if 0
+      /* we do not put size as first entry any more */
       tree nelts = array_type_nelts (TREE_TYPE (vars));
       if (flag_vtable_thunks)
        TREE_VALUE (CONSTRUCTOR_ELTS (DECL_INITIAL (vars))) = nelts;
       else
        SET_FNADDR_FROM_VTABLE_ENTRY (the_null_vtable_entry, nelts);
-      /* Kick out the dossier before writing out the vtable.  */
-      if (flag_dossier)
-       rest_of_decl_compilation (TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (TREE_CHAIN (CONSTRUCTOR_ELTS (DECL_INITIAL (vars))))), 0), 0, 1, 1);
+#endif
+
+      /* Kick out the type descriptor before writing out the vtable.  */
+      if (flag_rtti)
+       rest_of_decl_compilation (TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (CONSTRUCTOR_ELTS (DECL_INITIAL (vars)))), 0), 0, 1, 1);
 
       /* Write it out.  */
       mark_vtable_entries (vars);
@@ -2565,30 +2563,32 @@ void
 import_export_inline (decl)
      tree decl;
 {
-  if (TREE_PUBLIC (decl))
+  if (DECL_INTERFACE_KNOWN (decl))
     return;
 
-  /* If an explicit instantiation doesn't have TREE_PUBLIC set, it was with
-     'extern'.  */
-  if (DECL_EXPLICIT_INSTANTIATION (decl)
-      || (DECL_IMPLICIT_INSTANTIATION (decl) && ! flag_implicit_templates))
+  if (DECL_TEMPLATE_INSTANTIATION (decl))
     {
-      TREE_PUBLIC (decl) = 1;
-      DECL_EXTERNAL (decl) = 1;
+      if (DECL_IMPLICIT_INSTANTIATION (decl) && flag_implicit_templates)
+       TREE_PUBLIC (decl) = 0;
+      else
+       DECL_EXTERNAL (decl) = 1;
     }
   else if (DECL_FUNCTION_MEMBER_P (decl))
     {
       tree ctype = DECL_CLASS_CONTEXT (decl);
       if (CLASSTYPE_INTERFACE_KNOWN (ctype))
        {
-         TREE_PUBLIC (decl) = 1;
          DECL_EXTERNAL (decl)
            = (CLASSTYPE_INTERFACE_ONLY (ctype)
               || (DECL_INLINE (decl) && ! flag_implement_inlines));
        }
+      else
+       TREE_PUBLIC (decl) = 0;
     }
+  else
+    TREE_PUBLIC (decl) = 0;
 }
-  
+
 extern int parse_time, varconst_time;
 
 #define TIMEVAR(VAR, BODY)    \
@@ -2693,7 +2693,7 @@ finish_file ()
   poplevel (1, 0, 0);
   pop_momentary ();
 
-  finish_function (lineno, 0);
+  finish_function (lineno, 0, 0);
 
   assemble_destructor (IDENTIFIER_POINTER (fnname));
 
@@ -2818,7 +2818,7 @@ finish_file ()
       poplevel (1, 0, 0);
       pop_momentary ();
 
-      finish_function (lineno, 0);
+      finish_function (lineno, 0, 0);
       assemble_constructor (IDENTIFIER_POINTER (fnname));
     }
 
@@ -2871,74 +2871,86 @@ finish_file ()
   pushdecl (vars);
 #endif
 
+  interface_unknown = 1;
+  interface_only = 0;
+
+  for (vars = saved_inlines; vars; vars = TREE_CHAIN (vars))
+    {
+      tree decl = TREE_VALUE (vars);
+
+      if (DECL_ARTIFICIAL (decl)
+         && ! DECL_INITIAL (decl)
+         && (TREE_USED (decl) || ! DECL_EXTERNAL (decl)))
+       synthesize_method (decl);
+    }
+
   walk_vtables ((void (*)())0, finish_vtable_vardecl);
   if (flag_handle_signatures)
     walk_sigtables ((void (*)())0, finish_sigtable_vardecl);
 
+  for (vars = saved_inlines; vars; vars = TREE_CHAIN (vars))
+    {
+      tree decl = TREE_VALUE (vars);
+
+      if (DECL_ARTIFICIAL (decl)
+         && ! DECL_INITIAL (decl)
+         && TREE_USED (decl))
+       synthesize_method (decl);
+    }
+
   for (vars = getdecls (); vars; vars = TREE_CHAIN (vars))
     {
       if (TREE_CODE (vars) == THUNK_DECL)
        emit_thunk (vars);
+      else if (TREE_CODE (vars) == FUNCTION_DECL
+              && ! DECL_INTERFACE_KNOWN (vars)
+              && DECL_DECLARED_STATIC (vars))
+       TREE_PUBLIC (vars) = 0;
     }
 
+  /* Now write out inline functions which had their addresses taken and
+     which were not declared virtual and which were not declared `extern
+     inline'.  */
   {
-    int reconsider = 0;                /* More may be referenced; check again */
-    tree delayed = NULL_TREE;  /* These might be referenced later */
+    int reconsider = 1;                /* More may be referenced; check again */
+    saved_inlines = tree_cons (NULL_TREE, NULL_TREE, saved_inlines);
 
-    /* Now write out inline functions which had their addresses taken and
-       which were not declared virtual and which were not declared `extern
-       inline'.  */
-    while (saved_inlines)
+    while (reconsider)
       {
-       tree decl = TREE_VALUE (saved_inlines);
-       saved_inlines = TREE_CHAIN (saved_inlines);
-       /* Redefinition of a member function can cause DECL_SAVED_INSNS to be
-          0; don't crash.  */
-       if (TREE_ASM_WRITTEN (decl) || DECL_SAVED_INSNS (decl) == 0)
-         continue;
-       import_export_inline (decl);
-       if (TREE_PUBLIC (decl)
-           || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
-           || flag_keep_inline_functions)
+       tree last = saved_inlines;
+       tree place = TREE_CHAIN (saved_inlines);
+       reconsider = 0;
+
+       for (; place; place = TREE_CHAIN (place))
          {
-           if (DECL_EXTERNAL (decl))
-             assemble_external (decl);
-           else
+           tree decl = TREE_VALUE (place);
+
+           if (TREE_ASM_WRITTEN (decl) || DECL_SAVED_INSNS (decl) == 0)
              {
-               reconsider = 1;
-               temporary_allocation ();
-               output_inline_function (decl);
-               permanent_allocation (1);
+               TREE_CHAIN (last) = TREE_CHAIN (place);
+               continue;
              }
-         }
-       else if (TREE_USED (decl)
-                || TREE_USED (DECL_ASSEMBLER_NAME (decl)))
-         delayed = tree_cons (NULL_TREE, decl, delayed);
-      }
-
-    if (reconsider && delayed)
-      {
-       while (reconsider)
-         {
-           tree place;
-           reconsider = 0;
-           for (place = delayed; place; place = TREE_CHAIN (place))
+           import_export_inline (decl);
+           if (TREE_PUBLIC (decl)
+               || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
+               || flag_keep_inline_functions)
              {
-               tree decl = TREE_VALUE (place);
-               if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
-                   && ! TREE_ASM_WRITTEN (decl))
+               TREE_CHAIN (last) = TREE_CHAIN (place);
+
+               if (DECL_EXTERNAL (decl))
+                 assemble_external (decl);
+               else
                  {
-                   if (DECL_EXTERNAL (decl))
-                     assemble_external (decl);
-                   else
-                     {
-                       reconsider = 1;
-                       temporary_allocation ();
-                       output_inline_function (decl);
-                       permanent_allocation (1);
-                     }
+                   reconsider = 1;
+                   temporary_allocation ();
+                   output_inline_function (decl);
+                   permanent_allocation (1);
                  }
+
+               continue;
              }
+
+           last = place;
          }
       }
   }
index 982147125d9c976201bf1586ba7e1db91712c21f..4d6ac7372f8aa14cee28e15597c30837ffdade14 100644 (file)
@@ -43,6 +43,9 @@ tree builtin_return_address_fndecl;
 #define TRY_NEW_EH
 #endif
 #endif
+#if defined(__i386) || defined(__rs6000) || defined(__hppa)
+#define TRY_NEW_EH
+#endif
 #endif
 
 #ifndef TRY_NEW_EH
@@ -188,60 +191,6 @@ easy_expand_asm (str)
   expand_asm (build_string (strlen (str)+1, str));
 }
 
-/* unwind the stack. */
-static void
-do_unwind (throw_label)
-     rtx throw_label;
-{
-#ifdef sparc
-  extern FILE *asm_out_file;
-  tree fcall;
-  tree params;
-  rtx return_val_rtx;
-
-  /* call to  __builtin_return_address () */
-  params=tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
-  fcall = build_function_call (BuiltinReturnAddress, params);
-  return_val_rtx = expand_expr (fcall, NULL_RTX, SImode, 0);
-  /* In the return, the new pc is pc+8, as the value comming in is
-     really the address of the call insn, not the next insn.  */
-  emit_move_insn (return_val_rtx, plus_constant(gen_rtx (LABEL_REF,
-                                                        Pmode,
-                                                        throw_label), -8));
-  /* We use three values, PC, type, and value */
-  easy_expand_asm ("st %l0,[%fp]");
-  easy_expand_asm ("st %l1,[%fp+4]");
-  easy_expand_asm ("st %l2,[%fp+8]");
-  easy_expand_asm ("ret");
-  easy_expand_asm ("restore");
-  emit_barrier ();
-#endif
-#if m88k
-  rtx temp_frame = frame_pointer_rtx;
-
-  temp_frame = memory_address (Pmode, temp_frame);
-  temp_frame = copy_to_reg (gen_rtx (MEM, Pmode, temp_frame));
-
-  /* hopefully this will successfully pop the frame! */
-  emit_move_insn (frame_pointer_rtx, temp_frame);
-  emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
-  emit_move_insn (arg_pointer_rtx, frame_pointer_rtx);
-  emit_insn (gen_add2_insn (stack_pointer_rtx, gen_rtx (CONST_INT, VOIDmode,
-                                                    (HOST_WIDE_INT)m88k_debugger_offset (stack_pointer_rtx, 0))));
-
-#if 0
-  emit_insn (gen_add2_insn (arg_pointer_rtx, gen_rtx (CONST_INT, VOIDmode,
-                                                  -(HOST_WIDE_INT)m88k_debugger_offset (arg_pointer_rtx, 0))));
-
-  emit_move_insn (stack_pointer_rtx, arg_pointer_rtx);
-
-  emit_insn (gen_add2_insn (stack_pointer_rtx, gen_rtx (CONST_INT, VOIDmode,
-                                                    (HOST_WIDE_INT)m88k_debugger_offset (arg_pointer_rtx, 0))));
-#endif
-#endif
-}
-
-
 
 #if 0
 /* This is the startup, and finish stuff per exception table. */
@@ -834,10 +783,26 @@ init_exception_processing ()
 
   pop_lang_context ();
   throw_label = gen_label_rtx ();
+#ifdef sparc
   saved_pc = gen_rtx (REG, Pmode, 16);
   saved_throw_type = gen_rtx (REG, Pmode, 17);
   saved_throw_value = gen_rtx (REG, Pmode, 18);
-
+#endif
+#ifdef __i386
+  saved_pc = gen_rtx (REG, Pmode, 3);
+  saved_throw_type = gen_rtx (REG, Pmode, 4);
+  saved_throw_value = gen_rtx (REG, Pmode, 5);
+#endif
+#ifdef __rs6000
+  saved_pc = gen_rtx (REG, Pmode, 12);
+  saved_throw_type = gen_rtx (REG, Pmode, 13);
+  saved_throw_value = gen_rtx (REG, Pmode, 14);
+#endif
+#ifdef __hppa
+  saved_pc = gen_rtx (REG, Pmode, 5);
+  saved_throw_type = gen_rtx (REG, Pmode, 6);
+  saved_throw_value = gen_rtx (REG, Pmode, 7);
+#endif
   new_eh_queue (&ehqueue);
   new_eh_queue (&eh_table_output_queue);
   new_eh_stack (&ehstack);
@@ -1112,7 +1077,7 @@ expand_start_catch_block (declspecs, declarator)
   if (declspecs)
     {
       tree init_type;
-      decl = grokdeclarator (declarator, declspecs, NORMAL, 1, NULL_TREE);
+      decl = grokdeclarator (declarator, declspecs, CATCHPARM, 1, NULL_TREE);
 
       /* Figure out the type that the initializer is. */
       init_type = TREE_TYPE (decl);
@@ -1247,6 +1212,82 @@ do_function_call (func, params, return_type)
   return NULL_RTX;
 }
 
+/* unwind the stack. */
+static void
+do_unwind (throw_label)
+     rtx throw_label;
+{
+#ifdef sparc
+  extern FILE *asm_out_file;
+  tree fcall;
+  tree params;
+  rtx return_val_rtx;
+
+  /* call to  __builtin_return_address () */
+  params=tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
+  fcall = build_function_call (BuiltinReturnAddress, params);
+  return_val_rtx = expand_expr (fcall, NULL_RTX, SImode, 0);
+  /* In the return, the new pc is pc+8, as the value comming in is
+     really the address of the call insn, not the next insn.  */
+  emit_move_insn (return_val_rtx, plus_constant(gen_rtx (LABEL_REF,
+                                                        Pmode,
+                                                        throw_label), -8));
+  /* We use three values, PC, type, and value */
+  easy_expand_asm ("st %l0,[%fp]");
+  easy_expand_asm ("st %l1,[%fp+4]");
+  easy_expand_asm ("st %l2,[%fp+8]");
+  easy_expand_asm ("ret");
+  easy_expand_asm ("restore");
+  emit_barrier ();
+#endif
+#if defined(__i386) || defined(__rs6000) || defined(__hppa)
+  extern FILE *asm_out_file;
+  tree fcall;
+  tree params;
+  rtx return_val_rtx;
+
+  /* call to  __builtin_return_address () */
+  params=tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
+  fcall = build_function_call (BuiltinReturnAddress, params);
+  return_val_rtx = expand_expr (fcall, NULL_RTX, SImode, 0);
+#if 0
+  /* I would like to do this here, but doesn't seem to work. */
+  emit_move_insn (return_val_rtx, gen_rtx (LABEL_REF,
+                                          Pmode,
+                                          throw_label));
+  /* So, for now, just pass throw label to stack unwinder. */
+#endif
+  /* We use three values, PC, type, and value */
+  params = tree_cons (NULL_TREE, make_tree (ptr_type_node,
+                                           gen_rtx (LABEL_REF, Pmode, throw_label)), NULL_TREE);
+  
+  do_function_call (Unwind, params, NULL_TREE);
+  emit_barrier ();
+#endif
+#if m88k
+  rtx temp_frame = frame_pointer_rtx;
+
+  temp_frame = memory_address (Pmode, temp_frame);
+  temp_frame = copy_to_reg (gen_rtx (MEM, Pmode, temp_frame));
+
+  /* hopefully this will successfully pop the frame! */
+  emit_move_insn (frame_pointer_rtx, temp_frame);
+  emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
+  emit_move_insn (arg_pointer_rtx, frame_pointer_rtx);
+  emit_insn (gen_add2_insn (stack_pointer_rtx, gen_rtx (CONST_INT, VOIDmode,
+                                                    (HOST_WIDE_INT)m88k_debugger_offset (stack_pointer_rtx, 0))));
+
+#if 0
+  emit_insn (gen_add2_insn (arg_pointer_rtx, gen_rtx (CONST_INT, VOIDmode,
+                                                  -(HOST_WIDE_INT)m88k_debugger_offset (arg_pointer_rtx, 0))));
+
+  emit_move_insn (stack_pointer_rtx, arg_pointer_rtx);
+
+  emit_insn (gen_add2_insn (stack_pointer_rtx, gen_rtx (CONST_INT, VOIDmode,
+                                                    (HOST_WIDE_INT)m88k_debugger_offset (arg_pointer_rtx, 0))));
+#endif
+#endif
+}
 
 /* is called from expand_excpetion_blocks () to generate the code in a function
    to "throw" if anything in the function needs to preform a throw.
@@ -1306,6 +1347,12 @@ expand_builtin_throw ()
 
   emit_jump_insn (gen_beq (gotta_call_terminate));
 
+#ifndef sparc
+  /* On the SPARC, __builtin_return_address is already -8, no need to
+     subtract any more from it. */
+  emit_insn (gen_add2_insn (return_val_rtx, GEN_INT (-1)));
+#endif
+
   /* yes it did */
   emit_move_insn (saved_pc, return_val_rtx);
   do_unwind (throw_label);
@@ -1344,7 +1391,8 @@ expand_exception_blocks ()
   {
     static int have_done = 0;
     if (! have_done && TREE_PUBLIC (current_function_decl)
-       && ! DECL_INLINE (current_function_decl))
+       && DECL_INTERFACE_KNOWN (current_function_decl)
+       && ! DECL_EXTERNAL (current_function_decl))
       {
        have_done = 1;
        expand_builtin_throw ();
@@ -1394,7 +1442,7 @@ expand_throw (exp)
        rtx throw_value_rtx;
 
        emit_move_insn (saved_throw_type, throw_type_rtx);
-       exp = convert_to_reference (build_reference_type (build_type_variant (TREE_TYPE (exp), 1, 0)), exp, CONV_STATIC, LOOKUP_COMPLAIN, NULL_TREE);
+       exp = convert_to_reference (build_reference_type (build_type_variant (TREE_TYPE (exp), 1, 0)), exp, CONV_STATIC, LOOKUP_COMPLAIN, error_mark_node);
        if (exp == error_mark_node)
          error ("  in thrown expression");
        throw_value_rtx = expand_expr (build_unary_op (ADDR_EXPR, exp, 0), NULL_RTX, VOIDmode, 0);
@@ -1437,7 +1485,8 @@ build_exception_table ()
         /* Beginning marker for table. */
         ASM_OUTPUT_ALIGN (asm_out_file, 2);
         ASM_OUTPUT_LABEL (asm_out_file, "__EXCEPTION_TABLE__");
-        fprintf (asm_out_file, "        .word   0, 0, 0\n");
+        output_exception_table_entry (asm_out_file,
+                                      const0_rtx, const0_rtx, const0_rtx);
        }
      count++;
      output_exception_table_entry (asm_out_file,
@@ -1449,7 +1498,8 @@ build_exception_table ()
     {
       /* Ending marker for table. */
       ASM_OUTPUT_LABEL (asm_out_file, "__EXCEPTION_END__");
-      fprintf (asm_out_file, "        .word   -1, -1, -1\n");
+      output_exception_table_entry (asm_out_file,
+                                   constm1_rtx, constm1_rtx, constm1_rtx);
     }
 
 #endif /* TRY_NEW_EH */
@@ -1472,7 +1522,10 @@ tree
 build_throw (e)
      tree e;
 {
-  e = build1 (THROW_EXPR, void_type_node, e);
-  TREE_SIDE_EFFECTS (e) = 1;
+  if (e != error_mark_node)
+    {
+      e = build1 (THROW_EXPR, void_type_node, e);
+      TREE_SIDE_EFFECTS (e) = 1;
+    }
   return e;
 }
index aa59484a3059f13329a89eaff11e28e7e06b1028..2ed6f80d3044ebdbd98c50da12c9dea62019df20 100644 (file)
@@ -27,7 +27,11 @@ __volatile, TYPE_QUAL, RID_VOLATILE
 __volatile__, TYPE_QUAL, RID_VOLATILE
 __wchar_t, TYPESPEC, RID_WCHAR  /* Unique to ANSI C++ */,
 asm, ASM_KEYWORD, NORID,
+and, ANDAND, NORID,
+and_eq, ASSIGN, NORID,
 auto, SCSPEC, RID_AUTO,
+bitand, '&', NORID,
+bitor, '|', NORID,
 bool, TYPESPEC, RID_BOOL,
 break, BREAK, NORID,
 case, CASE, NORID,
@@ -35,6 +39,7 @@ catch, CATCH, NORID,
 char, TYPESPEC, RID_CHAR,
 class, AGGR, RID_CLASS,
 classof, CLASSOF, NORID,
+compl, '~', NORID,
 const, TYPE_QUAL, RID_CONST,
 const_cast, CONST_CAST, NORID,
 continue, CONTINUE, NORID,
@@ -45,6 +50,7 @@ double, TYPESPEC, RID_DOUBLE,
 dynamic_cast, DYNAMIC_CAST, NORID,
 else, ELSE, NORID,
 enum, ENUM, NORID,
+explicit, SCSPEC, RID_EXPLICIT,
 extern, SCSPEC, RID_EXTERN,
 false, CXX_FALSE, NORID,
 float, TYPESPEC, RID_FLOAT,
@@ -57,8 +63,13 @@ inline, SCSPEC, RID_INLINE,
 int, TYPESPEC, RID_INT,
 long, TYPESPEC, RID_LONG,
 mutable, SCSPEC, RID_MUTABLE,
+namespace, NAMESPACE, NORID,
 new, NEW, NORID,
+not, '!', NORID,
+not_eq, EQCOMPARE, NORID,
 operator, OPERATOR, NORID,
+or, OROR, NORID,
+or_eq, ASSIGN, NORID,
 overload, OVERLOAD, NORID,
 private, VISSPEC, RID_PRIVATE,
 protected, VISSPEC, RID_PROTECTED,
@@ -75,17 +86,21 @@ static, SCSPEC, RID_STATIC,
 static_cast, STATIC_CAST, NORID,
 struct, AGGR, RID_RECORD,
 switch, SWITCH, NORID,
+template, TEMPLATE, RID_TEMPLATE,
 this, THIS, NORID,
 throw, THROW, NORID,
-template, TEMPLATE, RID_TEMPLATE,
 true, CXX_TRUE, NORID,
 try, TRY, NORID,
 typedef, SCSPEC, RID_TYPEDEF,
-typeof, TYPEOF, NORID,
+typename, TYPENAME_KEYWORD, NORID,
 typeid, TYPEID, NORID,
+typeof, TYPEOF, NORID,
 union, AGGR, RID_UNION,
 unsigned, TYPESPEC, RID_UNSIGNED,
+using, USING, NORID,
 virtual, SCSPEC, RID_VIRTUAL,
 void, TYPESPEC, RID_VOID,
 volatile, TYPE_QUAL, RID_VOLATILE,
 while, WHILE, NORID,
+xor, '^', NORID,
+xor_eq, ASSIGN, NORID,
index 2441da1ba1dda4da4920024988113fdcf4955f2c..fc9157cc9e2a852d04a469630e08d0ccbc971ca8 100644 (file)
@@ -1185,7 +1185,7 @@ On an rs6000, xlC stores exception objects on that stack, under the try
 block.  When is unwinds down into a handler, the frame pointer is
 adjusted back to the normal value for the frame in which the handler
 resides, and the stack pointer is left unchanged from the time at which
-the object was throwed.  This is so that there is always someplace for
+the object was thrown.  This is so that there is always someplace for
 the exception object, and nothing can overwrite it, once we start
 throwing.  The only bad part, is that the stack remains large.
 
index 8453c4bec35548c7271560d33b369922d4064fae..6f6a97ad85dc4396c68db686f721790cde1ad1bc 100644 (file)
@@ -1,14 +1,14 @@
 /* C code produced by gperf version 2.5 (GNU C++ version) */
-/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,7,$ /deneb/blob/jason/g++/small/devo/gcc/cp/gxx.gperf  */
+/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,7,$ ../../../devo/gcc/cp/gxx.gperf  */
 /* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf  */
 struct resword { char *name; short token; enum rid rid;};
 
-#define TOTAL_KEYWORDS 86
+#define TOTAL_KEYWORDS 101
 #define MIN_WORD_LENGTH 2
 #define MAX_WORD_LENGTH 16
 #define MIN_HASH_VALUE 4
-#define MAX_HASH_VALUE 171
-/* maximum key range = 168, duplicates = 0 */
+#define MAX_HASH_VALUE 210
+/* maximum key range = 207, duplicates = 0 */
 
 #ifdef __GNUC__
 inline
@@ -20,19 +20,19 @@ hash (str, len)
 {
   static unsigned char asso_values[] =
     {
-     172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
-     172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
-     172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
-     172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
-     172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
-     172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
-     172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
-     172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
-     172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
-     172, 172, 172, 172, 172,   0, 172,  36,   1,  61,
-       0,   0,  30,  44,  44,  35, 172,   7,  12,  53,
-      40,  17,   6, 172,  28,   2,   4,  35,  31,  51,
-       5,   7, 172, 172, 172, 172, 172, 172,
+     211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
+     211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
+     211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
+     211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
+     211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
+     211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
+     211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
+     211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
+     211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
+     211, 211, 211, 211, 211,   0, 211,  35,   1,  69,
+      61,   0,  19,  65,  20, 100, 211,   5,  11,  52,
+       3,  25,   6,   2,  31,  26,   4,  41,  24,  64,
+      10,  24, 211, 211, 211, 211, 211, 211,
     };
   register int hval = len;
 
@@ -65,120 +65,144 @@ is_reserved_word (str, len)
     {
       {"",}, {"",}, {"",}, {"",}, 
       {"else",  ELSE, NORID,},
-      {"",}, 
-      {"delete",  DELETE, NORID,},
-      {"double",  TYPESPEC, RID_DOUBLE,},
+      {"",}, {"",}, {"",}, 
       {"true",  CXX_TRUE, NORID,},
-      {"__asm__",  GCC_ASM_KEYWORD, NORID},
-      {"typeid",  TYPEID, NORID,},
-      {"",}, 
-      {"this",  THIS, NORID,},
+      {"extern",  SCSPEC, RID_EXTERN,},
+      {"not",  '!', NORID,},
+      {"not_eq",  EQCOMPARE, NORID,},
+      {"",}, {"",}, 
+      {"__inline",  SCSPEC, RID_INLINE},
       {"",}, 
-      {"try",  TRY, NORID,},
-      {"",}, {"",}, {"",}, {"",}, 
-      {"do",  DO, NORID,},
+      {"__inline__",  SCSPEC, RID_INLINE},
       {"",}, 
-      {"static_cast",  STATIC_CAST, NORID,},
+      {"xor_eq",  ASSIGN, NORID,},
+      {"",}, {"",}, {"",}, 
       {"template",  TEMPLATE, RID_TEMPLATE,},
-      {"protected",  VISSPEC, RID_PROTECTED,},
+      {"",}, {"",}, 
+      {"__alignof__",  ALIGNOF, NORID},
+      {"__extension__",  EXTENSION, NORID},
+      {"bool",  TYPESPEC, RID_BOOL,},
       {"",}, 
-      {"__classof__",  CLASSOF, NORID},
+      {"typeof",  TYPEOF, NORID,},
+      {"",}, 
+      {"try",  TRY, NORID,},
+      {"or_eq",  ASSIGN, NORID,},
+      {"__asm__",  GCC_ASM_KEYWORD, NORID},
       {"",}, 
       {"__headof__",  HEADOF, NORID},
       {"",}, 
-      {"bool",  TYPESPEC, RID_BOOL,},
+      {"private",  VISSPEC, RID_PRIVATE,},
       {"__const__",  TYPE_QUAL, RID_CONST},
       {"__volatile",  TYPE_QUAL, RID_VOLATILE},
       {"__const",  TYPE_QUAL, RID_CONST},
       {"__volatile__",  TYPE_QUAL, RID_VOLATILE},
-      {"__typeof__",  TYPEOF, NORID},
-      {"void",  TYPESPEC, RID_VOID,},
-      {"friend",  SCSPEC, RID_FRIEND,},
+      {"__alignof",  ALIGNOF, NORID},
+      {"and_eq",  ASSIGN, NORID,},
+      {"xor",  '^', NORID,},
+      {"static_cast",  STATIC_CAST, NORID,},
+      {"break",  BREAK, NORID,},
+      {"namespace",  NAMESPACE, NORID,},
+      {"__classof__",  CLASSOF, NORID},
+      {"typedef",  SCSPEC, RID_TYPEDEF,},
       {"false",  CXX_FALSE, NORID,},
       {"sizeof",  SIZEOF, NORID,},
-      {"short",  TYPESPEC, RID_SHORT,},
-      {"typeof",  TYPEOF, NORID,},
-      {"",}, 
-      {"int",  TYPESPEC, RID_INT,},
-      {"__signed",  TYPESPEC, RID_SIGNED},
-      {"private",  VISSPEC, RID_PRIVATE,},
-      {"__signed__",  TYPESPEC, RID_SIGNED},
-      {"extern",  SCSPEC, RID_EXTERN,},
-      {"struct",  AGGR, RID_RECORD,},
-      {"signed",  TYPESPEC, RID_SIGNED,},
-      {"break",  BREAK, NORID,},
-      {"__attribute",  ATTRIBUTE, NORID},
-      {"default",  DEFAULT, NORID,},
-      {"__attribute__",  ATTRIBUTE, NORID},
-      {"__classof",  CLASSOF, NORID},
-      {"sigof",  SIGOF, NORID          /* Extension */,},
       {"__headof",  HEADOF, NORID},
-      {"switch",  SWITCH, NORID,},
-      {"__label__",  LABEL, NORID},
-      {"__extension__",  EXTENSION, NORID},
-      {"",}, 
-      {"__asm",  GCC_ASM_KEYWORD, NORID},
       {"for",  FOR, NORID,},
-      {"__typeof",  TYPEOF, NORID},
-      {"__alignof__",  ALIGNOF, NORID},
       {"",}, 
-      {"case",  CASE, NORID,},
+      {"__label__",  LABEL, NORID},
+      {"switch",  SWITCH, NORID,},
       {"virtual",  SCSPEC, RID_VIRTUAL,},
-      {"if",  IF, NORID,},
-      {"while",  WHILE, NORID,},
+      {"or",  OROR, NORID,},
+      {"__typeof__",  TYPEOF, NORID},
+      {"this",  THIS, NORID,},
       {"",}, 
-      {"class",  AGGR, RID_CLASS,},
-      {"typedef",  SCSPEC, RID_TYPEDEF,},
-      {"const",  TYPE_QUAL, RID_CONST,},
-      {"static",  SCSPEC, RID_STATIC,},
-      {"auto",  SCSPEC, RID_AUTO,},
+      {"bitor",  '|', NORID,},
       {"float",  TYPESPEC, RID_FLOAT,},
-      {"inline",  SCSPEC, RID_INLINE,},
-      {"throw",  THROW, NORID,},
-      {"unsigned",  TYPESPEC, RID_UNSIGNED,},
+      {"typename",  TYPENAME_KEYWORD, NORID,},
+      {"__classof",  CLASSOF, NORID},
+      {"short",  TYPESPEC, RID_SHORT,},
+      {"delete",  DELETE, NORID,},
+      {"double",  TYPESPEC, RID_DOUBLE,},
       {"",}, 
-      {"headof",  HEADOF, NORID,},
+      {"new",  NEW, NORID,},
+      {"typeid",  TYPEID, NORID,},
       {"",}, 
-      {"goto",  GOTO, NORID,},
-      {"",}, {"",}, 
-      {"public",  VISSPEC, RID_PUBLIC,},
-      {"signature",  AGGR, RID_SIGNATURE       /* Extension */,},
+      {"case",  CASE, NORID,},
+      {"union",  AGGR, RID_UNION,},
+      {"sigof",  SIGOF, NORID          /* Extension */,},
+      {"__typeof",  TYPEOF, NORID},
+      {"struct",  AGGR, RID_RECORD,},
       {"volatile",  TYPE_QUAL, RID_VOLATILE,},
-      {"__inline",  SCSPEC, RID_INLINE},
-      {"overload",  OVERLOAD, NORID,},
-      {"__inline__",  SCSPEC, RID_INLINE},
-      {"__alignof",  ALIGNOF, NORID},
-      {"asm",  ASM_KEYWORD, NORID,},
+      {"signature",  AGGR, RID_SIGNATURE       /* Extension */,},
+      {"while",  WHILE, NORID,},
+      {"return",  RETURN, NORID,},
       {"",}, 
-      {"new",  NEW, NORID,},
+      {"__asm",  GCC_ASM_KEYWORD, NORID},
+      {"protected",  VISSPEC, RID_PROTECTED,},
+      {"reinterpret_cast",  REINTERPRET_CAST, NORID,},
+      {"friend",  SCSPEC, RID_FRIEND,},
+      {"",}, 
+      {"do",  DO, NORID,},
+      {"auto",  SCSPEC, RID_AUTO,},
+      {"asm",  ASM_KEYWORD, NORID,},
+      {"compl",  '~', NORID,},
+      {"public",  VISSPEC, RID_PUBLIC,},
       {"",}, 
       {"mutable",  SCSPEC, RID_MUTABLE,},
-      {"union",  AGGR, RID_UNION,},
-      {"operator",  OPERATOR, NORID,},
-      {"register",  SCSPEC, RID_REGISTER,},
-      {"",}, {"",}, 
-      {"__wchar_t",  TYPESPEC, RID_WCHAR  /* Unique to ANSI C++ */,},
       {"",}, 
-      {"long",  TYPESPEC, RID_LONG,},
+      {"signed",  TYPESPEC, RID_SIGNED,},
+      {"",}, 
+      {"throw",  THROW, NORID,},
+      {"and",  ANDAND, NORID,},
       {"",}, {"",}, {"",}, 
-      {"continue",  CONTINUE, NORID,},
-      {"return",  RETURN, NORID,},
+      {"bitand",  '&', NORID,},
+      {"const",  TYPE_QUAL, RID_CONST,},
+      {"static",  SCSPEC, RID_STATIC,},
+      {"headof",  HEADOF, NORID,},
+      {"int",  TYPESPEC, RID_INT,},
       {"enum",  ENUM, NORID,},
+      {"",}, 
+      {"__signed__",  TYPESPEC, RID_SIGNED},
+      {"default",  DEFAULT, NORID,},
+      {"",}, 
+      {"__wchar_t",  TYPESPEC, RID_WCHAR  /* Unique to ANSI C++ */,},
+      {"using",  USING, NORID,},
+      {"__attribute",  ATTRIBUTE, NORID},
+      {"",}, 
+      {"__attribute__",  ATTRIBUTE, NORID},
+      {"",}, 
+      {"goto",  GOTO, NORID,},
+      {"operator",  OPERATOR, NORID,},
+      {"if",  IF, NORID,},
+      {"continue",  CONTINUE, NORID,},
+      {"explicit",  SCSPEC, RID_EXPLICIT,},
       {"",}, {"",}, 
-      {"dynamic_cast",  DYNAMIC_CAST, NORID,},
-      {"",}, {"",}, 
-      {"reinterpret_cast",  REINTERPRET_CAST, NORID,},
-      {"",}, {"",}, {"",}, {"",}, 
-      {"char",  TYPESPEC, RID_CHAR,},
+      {"class",  AGGR, RID_CLASS,},
       {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
+      {"char",  TYPESPEC, RID_CHAR,},
+      {"",}, {"",}, {"",}, {"",}, 
       {"classof",  CLASSOF, NORID,},
+      {"",}, {"",}, {"",}, {"",}, 
+      {"long",  TYPESPEC, RID_LONG,},
+      {"",}, {"",}, {"",}, {"",}, 
+      {"void",  TYPESPEC, RID_VOID,},
+      {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
+      {"overload",  OVERLOAD, NORID,},
+      {"",}, {"",}, 
+      {"catch",  CATCH, NORID,},
+      {"",}, {"",}, {"",}, {"",}, {"",}, 
+      {"__signed",  TYPESPEC, RID_SIGNED},
+      {"register",  SCSPEC, RID_REGISTER,},
       {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
       {"const_cast",  CONST_CAST, NORID,},
+      {"",}, {"",}, 
+      {"dynamic_cast",  DYNAMIC_CAST, NORID,},
       {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
       {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
-      {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
-      {"",}, {"",}, {"",}, {"",}, {"",}, 
-      {"catch",  CATCH, NORID,},
+      {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
+      {"inline",  SCSPEC, RID_INLINE,},
+      {"",}, {"",}, {"",}, 
+      {"unsigned",  TYPESPEC, RID_UNSIGNED,},
     };
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
index e0905c6cdf9f4339eaeb46fdf69d18c391fa551a..777ebe5ea986112fced17ebc911b010981b61aeb 100644 (file)
@@ -125,6 +125,7 @@ expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr)
   tree real_binfos = BINFO_BASETYPES (real_binfo);
   tree binfos = BINFO_BASETYPES (binfo);
   int i, n_baselinks = real_binfos ? TREE_VEC_LENGTH (real_binfos) : 0;
+  int has_expanded = 0;
 
   for (i = 0; i < n_baselinks; i++)
     {
@@ -133,8 +134,12 @@ expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr)
       int is_not_base_vtable =
        i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (real_binfo));
       if (! TREE_VIA_VIRTUAL (real_base_binfo))
-       expand_direct_vtbls_init (real_base_binfo, base_binfo,
-                                 is_not_base_vtable, can_elide, addr);
+       {
+         expand_direct_vtbls_init (real_base_binfo, base_binfo,
+                 (is_not_base_vtable || flag_rtti), can_elide, addr);
+         if (is_not_base_vtable && flag_rtti)
+           has_expanded = 1;
+       }
     }
 #if 0
   /* Before turning this on, make sure it is correct.  */
@@ -142,7 +147,7 @@ expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr)
     return;
 #endif
   /* Should we use something besides CLASSTYPE_VFIELDS? */
-  if (init_self && CLASSTYPE_VFIELDS (BINFO_TYPE (real_binfo)))
+  if (init_self && !has_expanded && CLASSTYPE_VFIELDS (BINFO_TYPE (real_binfo)))
     {
       tree base_ptr = convert_pointer_to_real (binfo, addr);
       expand_virtual_init (real_binfo, base_ptr);
@@ -421,13 +426,14 @@ emit_base_init (t, immediately)
              switch (n_baseclasses)
                {
                case 0:
-                 error ("type `%s' does not have a base class to initialize",
-                        IDENTIFIER_POINTER (current_class_name));
+                 cp_error ("`%T' does not have a base class to initialize",
+                           current_class_type);
                  return;
                case 1:
                  break;
                default:
-                 error ("unnamed initializer ambiguous for type `%s' which uses multiple inheritance", IDENTIFIER_POINTER (current_class_name));
+                 cp_error ("unnamed initializer ambiguous for `%T' which uses multiple inheritance",
+                           current_class_type);
                  return;
                }
              binfo = TREE_VEC_ELT (binfos, 0);
@@ -449,9 +455,9 @@ emit_base_init (t, immediately)
                      break;
                  if (i < 0)
                    {
-                     error ("type `%s' is not an immediate base class of type `%s'",
-                            IDENTIFIER_POINTER (basename),
-                            IDENTIFIER_POINTER (current_class_name));
+                     cp_error ("`%T' is not an immediate base class of `%T'",
+                               IDENTIFIER_TYPE_VALUE (basename),
+                               current_class_type);
                      continue;
                    }
                }
@@ -641,9 +647,8 @@ emit_base_init (t, immediately)
 
              if (TREE_STATIC (member))
                {
-                 error_with_aggr_type (DECL_FIELD_CONTEXT (member),
-                                       "field `%s::%s' is static; only point of initialization is its declaration",
-                                       IDENTIFIER_POINTER (TREE_PURPOSE (init_list)));
+                 cp_error ("field `%#D' is static; only point of initialization is its declaration",
+                           member);
                  continue;
                }
 
@@ -745,8 +750,7 @@ expand_aggr_vbase_init_1 (binfo, exp, addr, init_list)
   if (init)
     init = TREE_PURPOSE (init);
   /* Call constructors, but don't set up vtables.  */
-  expand_aggr_init_1 (binfo, exp, ref, init, 0,
-                     LOOKUP_COMPLAIN|LOOKUP_SPECULATIVELY);
+  expand_aggr_init_1 (binfo, exp, ref, init, 0, LOOKUP_COMPLAIN);
   expand_cleanups_to (NULL_TREE);
   CLEAR_BINFO_VBASE_INIT_MARKED (binfo);
 }
@@ -1196,12 +1200,12 @@ expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags)
      out, then look hard.  */
   tree rval;
   tree parms;
-  int xxref_init_possible;
 
   if (init == NULL_TREE || TREE_CODE (init) == TREE_LIST)
     {
       parms = init;
-      if (parms) init = TREE_VALUE (parms);
+      if (parms)
+       init = TREE_VALUE (parms);
     }
   else if (TREE_CODE (init) == INDIRECT_REF && TREE_HAS_CONSTRUCTOR (init))
     {
@@ -1213,16 +1217,6 @@ expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags)
   else
     parms = build_tree_list (NULL_TREE, init);
 
-  if (TYPE_HAS_INIT_REF (type)
-      || init == NULL_TREE
-      || TREE_CHAIN (parms) != NULL_TREE)
-    xxref_init_possible = 0;
-  else
-    {
-      xxref_init_possible = LOOKUP_SPECULATIVELY;
-      flags &= ~LOOKUP_COMPLAIN;
-    }
-
   if (TYPE_USES_VIRTUAL_BASECLASSES (type))
     {
       if (true_exp == exp)
@@ -1232,114 +1226,43 @@ expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags)
       flags |= LOOKUP_HAS_IN_CHARGE;
     }
 
-  rval = build_method_call (exp, constructor_name_full (type),
-                           parms, binfo, flags|xxref_init_possible);
-  if (rval == NULL_TREE && xxref_init_possible)
-    {
-      /* It is an error to implement a default copy constructor if
-        (see ARM 12.8 for details) ... one case being if another
-        copy constructor already exists. */
-      tree init_type = TREE_TYPE (init);
-      if (TREE_CODE (init_type) == REFERENCE_TYPE)
-       init_type = TREE_TYPE (init_type);
-      if (TYPE_MAIN_VARIANT (init_type) == TYPE_MAIN_VARIANT (type)
-         || (IS_AGGR_TYPE (init_type)
-             && UNIQUELY_DERIVED_FROM_P (type, init_type)))
-       {
-         if (type == BINFO_TYPE (binfo)
-             && TYPE_USES_VIRTUAL_BASECLASSES (type))
-           {
-             tree addr = build_unary_op (ADDR_EXPR, exp, 0);
-             expand_aggr_vbase_init (binfo, exp, addr, NULL_TREE);
-
-             expand_indirect_vtbls_init (binfo, exp, addr, 1);
-           }
-         expand_expr_stmt (build_modify_expr (exp, INIT_EXPR, init));
-         return;
-       }
-      else
-       rval = build_method_call (exp, constructor_name_full (type), parms,
-                                 binfo, flags);
-    }
-
-  /* Private, protected, or otherwise unavailable.  */
-  if (rval == error_mark_node && (flags&LOOKUP_COMPLAIN))
-    cp_error ("in base initialization for class `%T'", binfo);
-  /* A valid initialization using constructor.  */
-  else if (rval != error_mark_node && rval != NULL_TREE)
+  if (init && TREE_CHAIN (parms) == NULL_TREE
+      && TYPE_HAS_CONSTRUCTOR (type)
+      && ! TYPE_NEEDS_CONSTRUCTING (type)
+      && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (init)))
     {
-      /* p. 222: if the base class assigns to `this', then that
-        value is used in the derived class.  */
-      if ((flag_this_is_variable & 1) && alias_this)
-       {
-         TREE_TYPE (rval) = TREE_TYPE (current_class_decl);
-         expand_assignment (current_class_decl, rval, 0, 0);
-       }
-      else
-       expand_expr_stmt (rval);
+      rval = build (INIT_EXPR, type, exp, init);
+      TREE_SIDE_EFFECTS (rval) = 1;
+      expand_expr_stmt (rval);
     }
-  else if (parms && TREE_CHAIN (parms) == NULL_TREE)
+  else
     {
-      /* If we are initializing one aggregate value
-        from another, and though there are constructors,
-        and none accept the initializer, just do a bitwise
-        copy.
-
-        The above sounds wrong, ``If a class has any copy
-        constructor defined, the default copy constructor will
-        not be generated.'' 12.8 Copying Class Objects  (mrs)
-
-        @@ This should reject initializer which a constructor
-        @@ rejected on access gounds, but there is
-        @@ no way right now to recognize that case with
-        @@ just `error_mark_node'.  */
-      tree itype;
-      init = TREE_VALUE (parms);
-      itype = TREE_TYPE (init);
-      if (TREE_CODE (itype) == REFERENCE_TYPE)
-       {
-         init = convert_from_reference (init);
-         itype = TREE_TYPE (init);
-       }
-      itype = TYPE_MAIN_VARIANT (itype);
+      rval = build_method_call (exp, constructor_name_full (type),
+                               parms, binfo, flags);
 
-      /* This is currently how the default X(X&) constructor
-        is implemented.  */
-      if (comptypes (TYPE_MAIN_VARIANT (type), itype, 0))
-       {
-#if 0
-         warning ("bitwise copy in initialization of type `%s'",
-                  TYPE_NAME_STRING (type));
-#endif
-         rval = build (INIT_EXPR, type, exp, init);
-         expand_expr_stmt (rval);
-       }
-      else
+      /* Private, protected, or otherwise unavailable.  */
+      if (rval == error_mark_node)
        {
-         cp_error ("in base initialization for class `%T',", binfo);
-         cp_error ("invalid initializer to constructor for type `%T'", type);
-         return;
+         if (flags & LOOKUP_COMPLAIN)
+           cp_error ("in base initialization for %sclass `%T'",
+                     TREE_VIA_VIRTUAL (binfo) ? "virtual base " : "",
+                     binfo);
        }
-    }
-  else
-    {
-      if (init == NULL_TREE)
-       my_friendly_assert (parms == NULL_TREE, 210);
-      if (parms == NULL_TREE && TREE_VIA_VIRTUAL (binfo))
-       cp_error ("virtual baseclass `%T' does not have default initializer", binfo);
+      else if (rval == NULL_TREE)
+       my_friendly_abort (361);
       else
        {
-         cp_error ("in base initialization for class `%T',", binfo);
-         /* This will make an error message for us.  */
-         build_method_call (exp, constructor_name_full (type), parms, binfo,
-                            (TYPE_USES_VIRTUAL_BASECLASSES (type)
-                             ? LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE
-                             : LOOKUP_NORMAL));
+         /* p. 222: if the base class assigns to `this', then that
+            value is used in the derived class.  */
+         if ((flag_this_is_variable & 1) && alias_this)
+           {
+             TREE_TYPE (rval) = TREE_TYPE (current_class_decl);
+             expand_assignment (current_class_decl, rval, 0, 0);
+           }
+         else
+           expand_expr_stmt (rval);
        }
-      return;
     }
-  /* Constructor has been called, but vtables may be for TYPE
-     rather than for FOR_TYPE.  */
 }
 
 /* This function is responsible for initializing EXP with INIT
@@ -2707,7 +2630,6 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
     {
       /* raw "main", and builtin functions never gets overloaded,
         but they can become friends.  */
-      TREE_PUBLIC (decl) = 1;
       add_friend (current_class_type, decl);
       DECL_FRIEND_P (decl) = 1;
       decl = void_type_node;
index 44c78f0dba7b0258edfdb96228057ebba8ebce0e..9d85c47d5afaaa0f0b048e79deafd7e405991ae1 100644 (file)
@@ -660,6 +660,9 @@ init_lex ()
   ridpointers[(int) RID_VIRTUAL] = get_identifier ("virtual");
   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VIRTUAL],
                          build_tree_list (NULL_TREE, ridpointers[(int) RID_VIRTUAL]));
+  ridpointers[(int) RID_EXPLICIT] = get_identifier ("explicit");
+  SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXPLICIT],
+                         build_tree_list (NULL_TREE, ridpointers[(int) RID_EXPLICIT]));
   ridpointers[(int) RID_FRIEND] = get_identifier ("friend");
   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FRIEND],
                          build_tree_list (NULL_TREE, ridpointers[(int) RID_FRIEND]));
@@ -681,11 +684,6 @@ init_lex ()
   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_MUTABLE],
                          build_tree_list (NULL_TREE, ridpointers[(int) RID_MUTABLE]));
 
-  /* Exception handling extensions.  */
-  exception_type_node = build_int_2 (exception_type, 0);
-  TREE_TYPE (exception_type_node) = exception_type_node;
-  ridpointers[(int) RID_EXCEPTION] = exception_type_node;
-
   /* Signature handling extensions.  */
   signature_type_node = build_int_2 (signature_type, 0);
   TREE_TYPE (signature_type_node) = signature_type_node;
@@ -790,7 +788,7 @@ init_lex ()
     }
 #endif
 
-  if (! (flag_gc || flag_dossier))
+  if (! (flag_gc || flag_rtti))
     {
       UNSET_RESERVED_WORD ("classof");
       UNSET_RESERVED_WORD ("headof");
@@ -806,6 +804,17 @@ init_lex ()
     UNSET_RESERVED_WORD ("asm");
   if (flag_no_asm || flag_traditional)
     UNSET_RESERVED_WORD ("typeof");
+  if (!flag_ansi)
+    {
+      /* These are new ANSI keywords that may break code.  */
+      UNSET_RESERVED_WORD ("and");
+      UNSET_RESERVED_WORD ("bitand");
+      UNSET_RESERVED_WORD ("bitor");
+      UNSET_RESERVED_WORD ("compl");
+      UNSET_RESERVED_WORD ("not");
+      UNSET_RESERVED_WORD ("or");
+      UNSET_RESERVED_WORD ("xor");
+    }
 
   token_count = init_parse ();
   interface_unknown = 1;
@@ -1125,19 +1134,7 @@ do_pending_inlines ()
            DECL_PENDING_INLINE_INFO (f) = 0;
            interface_unknown = t->interface == 1;
            interface_only = t->interface == 0;
-           switch (- t->lineno)
-             {
-             case 0: case 1:
-               build_dtor (f); break;
-             case 2:
-               build_default_constructor (f); break;
-             case 3: case 4:
-               build_copy_constructor (f); break;
-             case 5: case 6:
-               build_assign_ref (f); break;
-             default:
-               ;
-             }
+           synthesize_method (f);
            if (tail)
              tail->next = t->next;
            else
@@ -1712,6 +1709,7 @@ cons_up_default_function (type, name, kind)
   tree fn, args;
   tree argtype;
   int retref = 0;
+  int complex = 0;
 
   name = constructor_name (name);
   switch (kind)
@@ -1722,10 +1720,13 @@ cons_up_default_function (type, name, kind)
       /* Fall through...  */
     case 0:
       name = build_parse_node (BIT_NOT_EXPR, name);
-      /* Fall through...  */
+      args = void_list_node;
+      break;
+
     case 2:
       /* Default constructor.  */
       args = void_list_node;
+      complex = TYPE_NEEDS_CONSTRUCTING (type);
       break;
 
     case 3:
@@ -1739,6 +1740,7 @@ cons_up_default_function (type, name, kind)
                        build_tree_list (hash_tree_chain (argtype, NULL_TREE),
                                         get_identifier ("_ctor_arg")),
                        void_list_node);
+      complex = TYPE_HAS_COMPLEX_INIT_REF (type);
       break;
 
     case 5:
@@ -1755,6 +1757,7 @@ cons_up_default_function (type, name, kind)
                        build_tree_list (hash_tree_chain (argtype, NULL_TREE),
                                         get_identifier ("_ctor_arg")),
                        void_list_node);
+      complex = TYPE_HAS_COMPLEX_ASSIGN_REF (type);
       break;
 
     default:
@@ -1777,20 +1780,34 @@ cons_up_default_function (type, name, kind)
   if (fn == void_type_node)
     return fn;
 
-  if (CLASSTYPE_TEMPLATE_INSTANTIATION (type))
+  if (processing_template_defn)
     SET_DECL_IMPLICIT_INSTANTIATION (fn);
 
-  /* This kludge should go away when synthesized methods are handled
-     properly, i.e. only when needed.  */
-  {
-    struct pending_inline *t;
-    t = (struct pending_inline *)
-      obstack_alloc (&synth_obstack, sizeof (struct pending_inline));
-    t->lineno = -kind;
-    t->can_free = 0;
-    t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2));
-    store_pending_inline (fn, t);
-  }
+  if (CLASSTYPE_INTERFACE_KNOWN (type))
+    {
+      DECL_INTERFACE_KNOWN (fn) = 1;
+      DECL_EXTERNAL (fn) = (CLASSTYPE_INTERFACE_ONLY (type)
+                           || ! flag_implement_inlines);
+      TREE_STATIC (fn) = ! DECL_EXTERNAL (fn);
+    }
+
+  /* When on-the-fly synthesis works properly, remove the second and third
+     conditions here.  */
+  if (flag_keep_inline_functions
+      || ! flag_no_inline
+      || complex
+      || ! DECL_EXTERNAL (fn))
+    {
+      struct pending_inline *t;
+      t = (struct pending_inline *)
+       obstack_alloc (&synth_obstack, sizeof (struct pending_inline));
+      t->lineno = -kind;
+      t->can_free = 0;
+      t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2));
+      store_pending_inline (fn, t);
+    }
+  else
+    mark_inline_for_output (fn);
 
 #ifdef DEBUG_DEFAULT_FUNCTIONS
   { char *fn_type = NULL;
@@ -3474,6 +3491,52 @@ real_yylex ()
                  else
                    yylval.ttype = old_ttype;
                }
+             else if (ptr->token == EQCOMPARE)
+               {
+                 yylval.code = NE_EXPR;
+                 token_buffer[0] = '!';
+                 token_buffer[1] = '=';
+                 token_buffer[2] = 0;
+               }
+             else if (ptr->token == ASSIGN)
+               {
+                 if (strcmp ("and_eq", token_buffer) == 0)
+                   {
+                     yylval.code = BIT_AND_EXPR;
+                     token_buffer[0] = '&';
+                   }
+                 else if (strcmp ("or_eq", token_buffer) == 0)
+                   {
+                     yylval.code = BIT_IOR_EXPR;
+                     token_buffer[0] = '|';
+                   }
+                 else if (strcmp ("xor_eq", token_buffer) == 0)
+                   {
+                     yylval.code = BIT_XOR_EXPR;
+                     token_buffer[0] = '^';
+                   }
+                 token_buffer[1] = '=';
+                 token_buffer[2] = 0;
+               }
+             else if (ptr->token == '&')
+               {
+                 yylval.code = BIT_AND_EXPR;
+                 token_buffer[0] = '&';
+                 token_buffer[1] = 0;
+               }
+             else if (ptr->token == '|')
+               {
+                 yylval.code = BIT_IOR_EXPR;
+                 token_buffer[0] = '|';
+                 token_buffer[1] = 0;
+               }
+             else if (ptr->token == '^')
+               {
+                 yylval.code = BIT_XOR_EXPR;
+                 token_buffer[0] = '^';
+                 token_buffer[1] = 0;
+               }
+
              value = (int) ptr->token;
            }
        }
index 291b9cde6e31b74e9be4f36aa5a890bdd0874bda..105ca3a875d4b8c5b679854caf3072bb673b8624 100644 (file)
@@ -58,6 +58,7 @@ enum rid
   RID_VOLATILE,
   RID_FRIEND,
   RID_VIRTUAL,
+  RID_EXPLICIT,
   RID_SIGNED,
   RID_AUTO,
   RID_MUTABLE,
index b22aa7c30810dbba78446f5a96139a24644d09aa..90dd4df3ba01f2074c9dbf69a1d38248a6026c7a 100644 (file)
@@ -59,6 +59,7 @@ static char *scratch_firstobj;
                 IDENTIFIER_LENGTH (ID)))
 # define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S)))
 # define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0'))
+# define OB_LAST() (obstack_next_free (&scratch_obstack)[-1])
 
 #ifdef NO_AUTO_OVERLOAD
 int is_overloaded ();
@@ -317,19 +318,39 @@ static int numeric_outputed_need_bar;
 static void build_overload_identifier ();
 
 static void
-build_overload_nested_name (context)
-     tree context;
+build_overload_nested_name (decl)
+     tree decl;
 {
-  /* We use DECL_NAME here, because pushtag now sets the DECL_ASSEMBLER_NAME.  */
-  tree name = DECL_NAME (context);
-  if (DECL_CONTEXT (context))
+  if (DECL_CONTEXT (decl))
     {
-      context = DECL_CONTEXT (context);
+      tree context = DECL_CONTEXT (decl);
       if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
-       context = TYPE_NAME (context);
+       context = TYPE_MAIN_DECL (context);
       build_overload_nested_name (context);
     }
-  build_overload_identifier (name);
+
+  if (TREE_CODE (decl) == FUNCTION_DECL)
+    {
+      tree name = DECL_ASSEMBLER_NAME (decl);
+      char *label;
+      extern int var_labelno;
+
+      ASM_FORMAT_PRIVATE_NAME (label, IDENTIFIER_POINTER (name), var_labelno);
+      var_labelno++;
+
+      if (numeric_outputed_need_bar)
+       {
+         OB_PUTC ('_');
+         numeric_outputed_need_bar = 0;
+       }
+      icat (strlen (label));
+      OB_PUTCP (label);
+    }
+  else                         /* TYPE_DECL */
+    {
+      tree name = DECL_NAME (decl);
+      build_overload_identifier (name);
+    }
 }
 
 static void
@@ -514,6 +535,7 @@ build_overload_name (parmtypes, begin, end)
   tree parmtype;
 
   if (begin) OB_INIT ();
+  numeric_outputed_need_bar = 0;
 
   if ((just_one = (TREE_CODE (parmtypes) != TREE_LIST)))
     {
@@ -761,6 +783,13 @@ build_overload_name (parmtypes, begin, end)
            if (TREE_CODE (name) == TYPE_DECL)
              {
                tree context = name;
+
+               /* If DECL_ASSEMBLER_NAME has been set properly, use it. */
+               if (DECL_ASSEMBLER_NAME (context) != DECL_NAME (context))
+                 {
+                   OB_PUTID (DECL_ASSEMBLER_NAME (context));
+                   break;
+                 }
                while (DECL_CONTEXT (context))
                  {
                    i += 1;
@@ -779,8 +808,8 @@ build_overload_name (parmtypes, begin, end)
                icat (i);
                if (i > 9)
                  OB_PUTC ('_');
-                numeric_outputed_need_bar = 0;
-               build_overload_nested_name (TYPE_NAME (parmtype));
+               numeric_outputed_need_bar = 0;
+               build_overload_nested_name (TYPE_MAIN_DECL (parmtype));
              }
            else
              build_overload_identifier (name);
@@ -920,7 +949,6 @@ build_decl_overload (dname, parms, for_method)
     {
       ALLOCATE_TYPEVEC (parms);
       nofold = 0;
-      numeric_outputed_need_bar = 0;
       if (for_method)
        {
          build_overload_name (TREE_VALUE (parms), 0, 0);
@@ -1906,6 +1934,10 @@ emit_thunk (thunk_fndecl)
 
   unshare_all_rtl (insns);
 
+  /* Instantiate all virtual registers.  */
+
+  instantiate_virtual_regs (current_function_decl, get_insns ());
+
   /* We are no longer anticipating cse in this function, at least.  */
 
   cse_not_expected = 1;
@@ -1971,16 +2003,6 @@ emit_thunk (thunk_fndecl)
 \f
 /* Code for synthesizing methods which have default semantics defined.  */
 
-void
-build_default_constructor (fndecl)
-     tree fndecl;
-{
-  start_function (NULL_TREE, fndecl, NULL_TREE, 1);
-  store_parm_decls ();
-  setup_vtbl_ptr ();
-  finish_function (lineno, 0);
-}
-
 /* For the anonymous union in TYPE, return the member that is at least as
    large as the rest of the members, so we can copy it.  */
 static tree
@@ -2000,14 +2022,12 @@ largest_union_member (type)
 
 /* Generate code for default X(X&) constructor.  */
 void
-build_copy_constructor (fndecl)
+do_build_copy_constructor (fndecl)
      tree fndecl;
 {
   tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
   tree t;
 
-  start_function (NULL_TREE, fndecl, NULL_TREE, 1);
-  store_parm_decls ();
   clear_last_expr ();
   push_momentary ();
 
@@ -2085,17 +2105,15 @@ build_copy_constructor (fndecl)
     }
 
   pop_momentary ();
-  finish_function (lineno, 0);
 }
 
 void
-build_assign_ref (fndecl)
+do_build_assign_ref (fndecl)
      tree fndecl;
 {
   tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
 
-  start_function (NULL_TREE, fndecl, NULL_TREE, 1);
-  store_parm_decls ();
+  clear_last_expr ();
   push_momentary ();
 
   parm = convert_from_reference (parm);
@@ -2158,14 +2176,45 @@ build_assign_ref (fndecl)
     }
   c_expand_return (C_C_D);
   pop_momentary ();
-  finish_function (lineno, 0);
 }
 
+void push_cp_function_context ();
+void pop_cp_function_context ();
+
 void
-build_dtor (fndecl)
+synthesize_method (fndecl)
      tree fndecl;
 {
+  int nested = (current_function_decl != NULL_TREE);
+  int toplev = (decl_function_context (fndecl) == NULL_TREE);
+  char *f = input_filename;
+
+  if (nested)
+    push_cp_function_context (toplev);
+
+  input_filename = DECL_SOURCE_FILE (fndecl);
+  extract_interface_info ();
   start_function (NULL_TREE, fndecl, NULL_TREE, 1);
   store_parm_decls ();
-  finish_function (lineno, 0);
+
+  if (DECL_NAME (fndecl) == ansi_opname[MODIFY_EXPR])
+    do_build_assign_ref (fndecl);
+  else if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
+    ;
+  else
+    {
+      tree arg_chain = FUNCTION_ARG_CHAIN (fndecl);
+      if (DECL_CONSTRUCTOR_FOR_VBASE_P (fndecl))
+       arg_chain = TREE_CHAIN (arg_chain);
+      if (arg_chain != void_list_node)
+       do_build_copy_constructor (fndecl);
+      else if (TYPE_NEEDS_CONSTRUCTING (current_class_type))
+       setup_vtbl_ptr ();
+    }
+
+  finish_function (lineno, 0, nested);
+  input_filename = f;
+  extract_interface_info ();
+  if (nested)
+    pop_cp_function_context (toplev);
 }
index 0e6836d596d45dd27ba12b9215804a5b945870d4..c04d608fd1dd884532c197c078b5b000f310e76b 100644 (file)
@@ -150,6 +150,7 @@ empty_parms ()
 %token <ttype> AGGR
 %token <itype> VISSPEC
 %token DELETE NEW OVERLOAD THIS OPERATOR CXX_TRUE CXX_FALSE
+%token NAMESPACE TYPENAME_KEYWORD USING
 %token LEFT_RIGHT TEMPLATE
 %token TYPEID DYNAMIC_CAST STATIC_CAST REINTERPRET_CAST CONST_CAST
 %token <itype> SCOPE
@@ -170,6 +171,7 @@ empty_parms ()
 
 %left '{' ',' ';'
 
+%nonassoc THROW
 %right <code> ASSIGN '='
 %right <code> '?' ':'
 %left <code> OROR
@@ -190,7 +192,7 @@ empty_parms ()
 %left <code> POINTSAT '.' '(' '['
 
 %right SCOPE                   /* C++ extension */
-%nonassoc NEW DELETE TRY CATCH THROW
+%nonassoc NEW DELETE TRY CATCH
 
 %type <code> unop
 
@@ -430,9 +432,7 @@ template_def:
                {
                  yychar = ':';
                template1:
-                 if (current_aggr == exception_type_node)
-                   error ("template type must define an aggregate or union");
-                 else if (current_aggr == signature_type_node)
+                 if (current_aggr == signature_type_node)
                    sorry ("template type defining a signature");
                  /* Maybe pedantic warning for union?
                     How about an enum? :-)  */
@@ -564,7 +564,7 @@ datadef:
 fndef:
          fn.def1 base_init compstmt_or_error
                {
-                 finish_function (lineno, 1);
+                 finish_function (lineno, 1, 0);
                  /* finish_function performs these three statements:
 
                     expand_end_bindings (getdecls (), 1, 0);
@@ -577,7 +577,7 @@ fndef:
                }
        | fn.def1 return_init base_init compstmt_or_error
                {
-                 finish_function (lineno, 1);
+                 finish_function (lineno, 1, 0);
                  /* finish_function performs these three statements:
 
                     expand_end_bindings (getdecls (), 1, 0);
@@ -589,13 +589,13 @@ fndef:
                  if ($<ttype>$) process_next_inline ($<ttype>$);
                }
        | fn.def1 nodecls compstmt_or_error
-               { finish_function (lineno, 0);
+               { finish_function (lineno, 0, 0);
                  if ($<ttype>$) process_next_inline ($<ttype>$); }
        | fn.def1 return_init ';' nodecls compstmt_or_error
-               { finish_function (lineno, 0);
+               { finish_function (lineno, 0, 0);
                  if ($<ttype>$) process_next_inline ($<ttype>$); }
        | fn.def1 return_init nodecls compstmt_or_error
-               { finish_function (lineno, 0);
+               { finish_function (lineno, 0, 0);
                  if ($<ttype>$) process_next_inline ($<ttype>$); }
        | typed_declspecs declarator error
                {}
@@ -1148,7 +1148,7 @@ sub_cast_expr:
                    {
                      tree type = IDENTIFIER_TYPE_VALUE ($3);
                      if (! IS_SIGNATURE(type))
-                       $$ = CLASSTYPE_DOSSIER (type);
+                       $$ = CLASSTYPE_RTTI (type);
                      else
                        {
                          sorry ("signature name as argument of `classof'");
@@ -2109,9 +2109,6 @@ structsp:
 
                  if (TREE_CODE ($$) == ENUMERAL_TYPE)
                    /* $$ = $1 from default rule.  */;
-                 else if (CLASSTYPE_DECLARED_EXCEPTION ($$))
-                   {
-                   }
                  else
                    {
                      $$ = finish_struct ($$, $3, semi);
@@ -2435,8 +2432,12 @@ left_curly: '{'
                      int needs_writing;
                      tree name = TYPE_IDENTIFIER (t);
 
-                     CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
-                     SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
+                     if (! ANON_AGGRNAME_P (name))
+                       {
+                         CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
+                         SET_CLASSTYPE_INTERFACE_UNKNOWN_X
+                           (t, interface_unknown);
+                       }
 
                      /* Record how to set the access of this class's
                         virtual functions.  If write_virtuals == 2 or 3, then
@@ -3422,7 +3423,7 @@ handler_args:
                { expand_start_catch_block ($2, $3); }
        | '(' typed_typespecs after_type_declarator ')'
                { expand_start_catch_block ($2, $3); }
-       */
+       This allows reference parameters... */
        | '(' parm ')'
                { expand_start_catch_block (TREE_PURPOSE ($2),
                                            TREE_VALUE ($2)); }
index e3c3f0da08010d1988d3b46fc4bea05525d4648c..655535abd47796e2bb2421a5c01f44d6bc166468 100644 (file)
@@ -97,8 +97,7 @@ process_template_parm (list, next)
                             PARM, 0, NULL_TREE);
       /* A template parameter is not modifiable.  */
       TREE_READONLY (parm) = 1;
-      if (TREE_CODE (TREE_TYPE (parm)) == RECORD_TYPE
-         || TREE_CODE (TREE_TYPE (parm)) == UNION_TYPE)
+      if (IS_AGGR_TYPE (TREE_TYPE (parm)))
        {
          sorry ("aggregate template parameter types");
          TREE_TYPE (parm) = void_type_node;
@@ -466,7 +465,7 @@ coerce_template_parms (parms, arglist, in_decl)
              tree a = TREE_OPERAND (val, 0);
              if ((TREE_CODE (a) == VAR_DECL
                   || TREE_CODE (a) == FUNCTION_DECL)
-                 && !TREE_PUBLIC (a))
+                 && ! DECL_PUBLIC (a))
                {
                  cp_error ("address of non-extern `%E' cannot be used as template argument", a);
                  val = error_mark_node;
@@ -683,7 +682,8 @@ push_template_decls (parmlist, arglist, class_level)
          val = digest_init (TREE_TYPE (parm), arg, (tree *) 0);
          if (val != error_mark_node)
            {
-             decl = build_decl (VAR_DECL, DECL_NAME (parm), TREE_TYPE (parm));
+             decl = build_decl (CONST_DECL, DECL_NAME (parm),
+                                TREE_TYPE (parm));
              DECL_INITIAL (decl) = val;
              TREE_READONLY (decl) = 1;
            }
@@ -834,6 +834,11 @@ uses_template_parms (t)
     case UNINSTANTIATED_P_TYPE:
       return 1;
 
+    case CONSTRUCTOR:
+      if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
+       return uses_template_parms (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
+      /* else fall through */
+
     default:
       switch (TREE_CODE_CLASS (TREE_CODE (t)))
        {
@@ -898,19 +903,6 @@ instantiate_member_templates (classname)
                                     &TREE_VEC_ELT (parmvec, 0));
          type = IDENTIFIER_TYPE_VALUE (id);
          my_friendly_assert (type != 0, 277);
-         if (flag_external_templates)
-           {
-             if (CLASSTYPE_INTERFACE_UNKNOWN (type))
-               {
-                 DECL_EXTERNAL (t2) = 0;
-                 TREE_PUBLIC (t2) = 0;
-               }
-             else
-               {
-                 DECL_EXTERNAL (t2) = CLASSTYPE_INTERFACE_ONLY (type);
-                 TREE_PUBLIC (t2) = 1;
-               }
-           }
          break;
        case 1:
          /* Failure.  */
@@ -1116,15 +1108,11 @@ lookup_nested_type_by_name (ctype, name)
 {
   tree t;
 
-  t = TREE_VALUE(CLASSTYPE_TAGS(ctype)); 
-  while (t)
-  {
-    if (strcmp(IDENTIFIER_POINTER(name), IDENTIFIER_POINTER(TYPE_IDENTIFIER(t)))
- == 0)
-      return t;
-    else 
-      t = TREE_CHAIN(t);
-  }
+  for (t = CLASSTYPE_TAGS (ctype); t; t = TREE_CHAIN (t))
+    {
+      if (name == TREE_PURPOSE (t))
+       return TREE_VALUE (t);
+    }
   return NULL_TREE;
 }
 
@@ -1198,9 +1186,12 @@ tsubst (t, args, nargs, in_decl)
         tsubst (TYPE_MAX_VALUE (t), args, nargs, in_decl));
 
     case TEMPLATE_TYPE_PARM:
-      return cp_build_type_variant (args[TEMPLATE_TYPE_IDX (t)],
-                                  TYPE_READONLY (t),
-                                  TYPE_VOLATILE (t));
+      {
+       tree arg = args[TEMPLATE_TYPE_IDX (t)];
+       return cp_build_type_variant
+         (arg, TYPE_READONLY (arg) || TYPE_READONLY (t),
+          TYPE_VOLATILE (arg) || TYPE_VOLATILE (t));
+      }
 
     case TEMPLATE_CONST_PARM:
       return args[TEMPLATE_CONST_IDX (t)];
@@ -1404,9 +1395,10 @@ tsubst (t, args, nargs, in_decl)
                }
            }
          }
-       TREE_PUBLIC (r) = TREE_PUBLIC (t);
-       DECL_EXTERNAL (r) = DECL_EXTERNAL (t);
-       TREE_STATIC (r) = TREE_STATIC (t);
+       TREE_PUBLIC (r) = 1;
+       DECL_EXTERNAL (r) = 1;
+       TREE_STATIC (r) = 0;
+       DECL_INTERFACE_KNOWN (r) = 0;
        DECL_INLINE (r) = DECL_INLINE (t);
        {
 #if 0                          /* Maybe later.  -jason  */
@@ -1719,10 +1711,21 @@ instantiate_template (tmpl, targ_ptr)
        input_filename = p->filename = t->filename;
 
        extract_interface_info ();
-       
-       if (interface_unknown && flag_external_templates && ! DECL_IN_SYSTEM_HEADER (tmpl))
-         warn_if_unknown_interface ();
-       if (interface_unknown || !flag_external_templates)
+
+       if (interface_unknown && flag_external_templates)
+         {
+           if (DECL_CLASS_CONTEXT (fndecl)
+               && CLASSTYPE_INTERFACE_KNOWN (DECL_CLASS_CONTEXT (fndecl)))
+             {
+               interface_unknown = 0;
+               interface_only
+                 = CLASSTYPE_INTERFACE_ONLY (DECL_CLASS_CONTEXT (fndecl));
+             }
+           else if (! DECL_IN_SYSTEM_HEADER (tmpl))
+             warn_if_unknown_interface ();
+         }
+
+       if (interface_unknown || ! flag_external_templates)
          p->interface = 1;             /* unknown */
        else
          p->interface = interface_only ? 0 : 2;
@@ -2008,6 +2011,9 @@ type_unification (tparms, targs, parms, args, nsubsts, subr)
          arg = TREE_TYPE (arg);
        }
 #endif
+      if (TREE_CODE (arg) == REFERENCE_TYPE)
+       arg = TREE_TYPE (arg);
+
       if (TREE_CODE (parm) != REFERENCE_TYPE)
        {
          if (TREE_CODE (arg) == FUNCTION_TYPE
@@ -2068,9 +2074,6 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
   if (arg == parm)
     return 0;
 
-  if (TREE_CODE (arg) == REFERENCE_TYPE)
-    arg = TREE_TYPE (arg);
-
   switch (TREE_CODE (parm))
     {
     case TEMPLATE_TYPE_PARM:
@@ -2082,6 +2085,7 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
          return 1;
        }
       idx = TEMPLATE_TYPE_IDX (parm);
+#if 0
       /* Template type parameters cannot contain cv-quals; i.e.
          template <class T> void f (T& a, T& b) will not generate
         void f (const int& a, const int& b).  */
@@ -2089,6 +2093,13 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
          || TYPE_VOLATILE (arg) > TYPE_VOLATILE (parm))
        return 1;
       arg = TYPE_MAIN_VARIANT (arg);
+#else
+      {
+       int constp = TYPE_READONLY (arg) > TYPE_READONLY (parm);
+       int volatilep = TYPE_VOLATILE (arg) > TYPE_VOLATILE (parm);
+       arg = cp_build_type_variant (arg, constp, volatilep);
+      }
+#endif
       /* Simple cases: Value already set, does match or doesn't.  */
       if (targs[idx] == arg)
        return 0;
@@ -2205,22 +2216,19 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
     case UNINSTANTIATED_P_TYPE:
       {
        tree a;
-       /* Unification of something that is not a template fails. (mrs) */
-       if (TYPE_NAME (arg) == 0)
+       /* Unification of something that is not a class fails.  */
+       if (! IS_AGGR_TYPE (arg))
          return 1;
        a = IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (arg));
-       /* Unification of something that is not a template fails. (mrs) */
-       if (a == 0)
-         return 1;
-       if (UPT_TEMPLATE (parm) != TREE_PURPOSE (a))
-         /* different templates */
-         return 1;
-       return unify (tparms, targs, ntparms, UPT_PARMS (parm), TREE_VALUE (a),
-                     nsubsts);
+       if (a && UPT_TEMPLATE (parm) == TREE_PURPOSE (a))
+         return unify (tparms, targs, ntparms, UPT_PARMS (parm),
+                       TREE_VALUE (a), nsubsts);
+       /* FIXME: Should check base conversions here.  */
+       return 1;
       }
 
     case RECORD_TYPE:
-      if (TYPE_PTRMEMFUNC_P (parm))
+      if (TYPE_PTRMEMFUNC_FLAG (parm))
        return unify (tparms, targs, ntparms, TYPE_PTRMEMFUNC_FN_TYPE (parm),
                      arg, nsubsts);
 
@@ -2295,6 +2303,9 @@ do_pending_expansions ()
       else if (! flag_implicit_templates)
        DECIDE (0);
 
+      /* OK, it was an implicit instantiation.  */
+      TREE_PUBLIC (t) = 0;
+
       /* If it's a method, let the class type decide it.
         @@ What if the method template is in a separate file?
         Maybe both file contexts should be taken into account?
@@ -2425,17 +2436,14 @@ do_function_instantiation (declspecs, declarator, storage)
   if (flag_external_templates)
     return;
 
-  if (DECL_EXPLICIT_INSTANTIATION (result) && TREE_PUBLIC (result))
-    return;
-
   SET_DECL_EXPLICIT_INSTANTIATION (result);
+  TREE_PUBLIC (result) = 1;
 
   if (storage == NULL_TREE)
     {
-      TREE_PUBLIC (result) = 1;
-      DECL_EXTERNAL (result) = (DECL_INLINE (result)
-                               && ! flag_implement_inlines);
-      TREE_STATIC (result) = ! DECL_EXTERNAL (result);
+      DECL_INTERFACE_KNOWN (result) = 1;
+      DECL_EXTERNAL (result) = 0;
+      TREE_STATIC (result) = 1;
     }
   else if (storage == ridpointers[(int) RID_EXTERN])
     ;
@@ -2475,7 +2483,7 @@ do_type_instantiation (name, storage)
     }
 
   /* We've already instantiated this.  */
-  if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && CLASSTYPE_INTERFACE_KNOWN (t))
+  if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && ! CLASSTYPE_INTERFACE_ONLY (t))
     {
       if (! extern_p)
        cp_pedwarn ("multiple explicit instantiation of `%#T'", t);
@@ -2485,22 +2493,29 @@ do_type_instantiation (name, storage)
   if (! CLASSTYPE_TEMPLATE_SPECIALIZATION (t))
     {
       SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t);
+      SET_CLASSTYPE_INTERFACE_KNOWN (t);
+      CLASSTYPE_INTERFACE_ONLY (t) = extern_p;
+      CLASSTYPE_VTABLE_NEEDS_WRITING (t) = ! extern_p;
+      TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = extern_p;
       if (! extern_p)
        {
-         SET_CLASSTYPE_INTERFACE_KNOWN (t);
-         CLASSTYPE_INTERFACE_ONLY (t) = 0;
-         CLASSTYPE_VTABLE_NEEDS_WRITING (t) = 1;
          CLASSTYPE_DEBUG_REQUESTED (t) = 1;
-         TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 0;
          rest_of_type_compilation (t, 1);
        }
     }
-
-  instantiate_member_templates (TYPE_IDENTIFIER (t));
-
-  /* this should really be done by instantiate_member_templates */
+  
   {
-    tree tmp = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0);
+    tree tmp;
+    /* Classes nested in template classes currently don't have an
+       IDENTIFIER_TEMPLATE--their out-of-line members are handled
+       by the enclosing template class.  Note that there are name
+       conflict bugs with this approach. */
+    tmp = TYPE_IDENTIFIER (t);
+    if (IDENTIFIER_TEMPLATE (tmp))
+      instantiate_member_templates (tmp);
+
+    /* this should really be done by instantiate_member_templates */
+    tmp = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0);
     for (; tmp; tmp = TREE_CHAIN (tmp))
       {
        if (DECL_TEMPLATE_SPECIALIZATION (tmp)
@@ -2509,12 +2524,12 @@ do_type_instantiation (name, storage)
          continue;
 
        SET_DECL_EXPLICIT_INSTANTIATION (tmp);
+       TREE_PUBLIC (tmp) = 1;
        if (! extern_p)
          {
-           TREE_PUBLIC (tmp) = 1;
-           DECL_EXTERNAL (tmp) = (DECL_INLINE (tmp)
-                                  && ! flag_implement_inlines);
-           TREE_STATIC (tmp) = ! DECL_EXTERNAL (tmp);
+           DECL_INTERFACE_KNOWN (tmp) = 1;
+           DECL_EXTERNAL (tmp) = 0;
+           TREE_STATIC (tmp) = 1;
          }
       }
 
index 7f6af72689811babd739dd50beb17f12528d1504..9fb8e63d9bdca709f8c8aa93b00f339ad8de2a48 100644 (file)
@@ -377,8 +377,8 @@ pop_memoized_context (use_old)
     type_stack = (struct type_level *)type_stack->base.prev;
 }
 \f
-#if 0                          /* unused */
 /* This is the newer recursive depth first search routine. */
+#if 0                          /* unused */
 /* Return non-zero if PARENT is directly derived from TYPE.  By directly
    we mean it's only one step up the inheritance lattice.  We check this
    by walking horizontally across the types that TYPE directly inherits
@@ -1995,12 +1995,9 @@ get_abstract_virtuals_1 (binfo, do_self, abstract_virtuals)
   /* Should we use something besides CLASSTYPE_VFIELDS? */
   if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
     {
+      /* Get around first entry reserved for RTTI.  */
       tree tmp = TREE_CHAIN (BINFO_VIRTUALS (binfo));
 
-      /* Get around dossier entry if there is one.  */
-      if (flag_dossier)
-       tmp = TREE_CHAIN (tmp);
-
       while (tmp)
        {
          tree base_pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (tmp));
@@ -2417,10 +2414,10 @@ dfs_init_vbase_pointers (binfo)
 
   CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
 
-  /* If there is a dossier, it is the first field, though perhaps from
+  /* If there is a rtti, it is the first field, though perhaps from
      the base class.  Otherwise, the first fields are virtual base class
      pointer fields.  */
-  if (CLASSTYPE_DOSSIER (type) && VFIELD_NAME_P (DECL_NAME (fields)))
+  if (CLASSTYPE_RTTI (type) && VFIELD_NAME_P (DECL_NAME (fields)))
     /* Get past vtable for the object.  */
     fields = TREE_CHAIN (fields);
 
index 5db4a66e3080139d5f87596f4c9733f9b8a7cadc..13b88f675ec78f26445ec0706f82b3dbf2d190ab 100644 (file)
@@ -1250,9 +1250,8 @@ debug_binfo (elem)
   virtuals = BINFO_VIRTUALS (elem);
   if (virtuals != 0)
     {
+      /* skip the rtti type descriptor entry */
       virtuals = TREE_CHAIN (virtuals);
-      if (flag_dossier)
-       virtuals = TREE_CHAIN (virtuals);
     }
   i = 1;
   while (virtuals)
index cdf406686f6393125047fccfb333dc0abe2e60bd..f7289e1af9330a3a46050b3d2a8681bc738ff069 100644 (file)
@@ -3404,6 +3404,10 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
            unsigned_arg = TREE_UNSIGNED (TREE_TYPE (op0));
 
          if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
+             /* We can shorten only if the shift count is less than the
+                number of bits in the smaller type size.  */
+             && TREE_INT_CST_HIGH (op1) == 0
+             && TYPE_PRECISION (TREE_TYPE (arg0)) > TREE_INT_CST_LOW (op1)
              /* If arg is sign-extended and then unsigned-shifted,
                 we can simulate this with a signed shift in arg's type
                 only if the extended result is at least twice as wide
@@ -3756,8 +3760,12 @@ build_x_unary_op (code, xarg)
 {
   /* & rec, on incomplete RECORD_TYPEs is the simple opr &, not an
      error message. */
-  if (code != ADDR_EXPR || TREE_CODE (TREE_TYPE (xarg)) != RECORD_TYPE
-      || TYPE_SIZE (TREE_TYPE (xarg)))
+  if (code == ADDR_EXPR
+      && ((IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (xarg)))
+          && TYPE_SIZE (TREE_TYPE (xarg)) == NULL_TREE)
+         || (TREE_CODE (xarg) == OFFSET_REF)))
+    /* don't look for a function */;
+  else
     {
       tree rval = build_opfncall (code, LOOKUP_SPECULATIVELY, xarg,
                                  NULL_TREE, NULL_TREE);
@@ -3813,6 +3821,9 @@ build_unary_op (code, xarg, noconvert)
   if (typecode == ENUMERAL_TYPE)
     typecode = INTEGER_TYPE;
 
+  if (typecode == BOOLEAN_TYPE && ! noconvert)
+    typecode = INTEGER_TYPE;
+
   isaggrtype = IS_AGGR_TYPE_CODE (typecode);
 
   switch (code)
@@ -5435,7 +5446,14 @@ build_modify_expr (lhs, modifycode, rhs)
 
   if (modifycode == INIT_EXPR)
     {
-      if (TYPE_LANG_SPECIFIC (lhstype) && TYPE_HAS_CONSTRUCTOR (lhstype))
+      if (! IS_AGGR_TYPE (lhstype))
+       /* Do the default thing */;
+      else if (! TYPE_HAS_CONSTRUCTOR (lhstype))
+       cp_error ("`%T' has no constructors", lhstype);
+      else if (! TYPE_NEEDS_CONSTRUCTING (lhstype)
+              && TYPE_MAIN_VARIANT (lhstype) == TYPE_MAIN_VARIANT (TREE_TYPE (newrhs)))
+       /* Do the default thing */;
+      else
        {
          result = build_method_call (lhs, constructor_name_full (lhstype),
                                      build_tree_list (NULL_TREE, rhs),
@@ -5449,7 +5467,17 @@ build_modify_expr (lhs, modifycode, rhs)
     {
 #if 1
       /* `operator=' is not an inheritable operator.  */
-      if (TYPE_LANG_SPECIFIC (lhstype) && TYPE_HAS_ASSIGNMENT (lhstype))
+      if (! IS_AGGR_TYPE (lhstype))
+       /* Do the default thing */;
+      else if (! TYPE_HAS_ASSIGNMENT (lhstype))
+       cp_error ("`%T' does not define operator=", lhstype);
+      else if (! TYPE_HAS_REAL_ASSIGNMENT (lhstype)
+              && ! TYPE_HAS_COMPLEX_ASSIGN_REF (lhstype)
+              /* FIXME find some way to deal with TARGET_EXPRs here.  */
+              && TREE_CODE (newrhs) != TARGET_EXPR
+              && TYPE_MAIN_VARIANT (lhstype) == TYPE_MAIN_VARIANT (TREE_TYPE (newrhs)))
+       /* Do the default thing */;
+      else
        {
          result = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL,
                                   lhs, rhs, make_node (NOP_EXPR));
@@ -5655,6 +5683,8 @@ build_modify_expr (lhs, modifycode, rhs)
   if (TREE_SIDE_EFFECTS (newrhs))
     newrhs = stabilize_reference (newrhs);
 
+#if 0
+  /* This is now done by generating X(X&) and operator=(X&). */
   /* C++: The semantics of C++ differ from those of C when an
      assignment of an aggregate is desired.  Assignment in C++ is
      now defined as memberwise assignment of non-static members
@@ -5673,14 +5703,6 @@ build_modify_expr (lhs, modifycode, rhs)
          || (TREE_CODE (TREE_TYPE (newrhs)) == RECORD_TYPE
              && UNIQUELY_DERIVED_FROM_P (lhstype, TREE_TYPE (newrhs)))))
     {
-      /* This was decided in finish_struct.  */
-      if (modifycode == INIT_EXPR)
-       cp_error ("can't generate default copy constructor for `%T'", lhstype);
-      else
-       cp_error ("can't generate default assignment operator for `%T'",
-                 lhstype);
-#if 0
-      /* This is now done by generating X(X&) and operator=(X&). */
       tree vbases = CLASSTYPE_VBASECLASSES (lhstype);
       tree lhs_addr = build_unary_op (ADDR_EXPR, lhs, 0);
       tree rhs_addr;
@@ -5756,8 +5778,8 @@ build_modify_expr (lhs, modifycode, rhs)
                                               TYPE_BINFO (lhstype)),
                          result);
       return build_compound_expr (result);
-#endif
     }
+#endif
 
   /* Convert new value to destination type.  */
 
@@ -5811,6 +5833,7 @@ build_modify_expr (lhs, modifycode, rhs)
     }
   else
     {
+#if 0
       if (IS_AGGR_TYPE (lhstype))
        {
          if (result = build_opfncall (MODIFY_EXPR,
@@ -5818,6 +5841,7 @@ build_modify_expr (lhs, modifycode, rhs)
                                       make_node (NOP_EXPR)))
            return result;
        }
+#endif
       /* Avoid warnings on enum bit fields. */
       if (TREE_CODE (olhstype) == ENUMERAL_TYPE
          && TREE_CODE (lhstype) == INTEGER_TYPE)
@@ -6603,8 +6627,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
      `convert_for_initialization'.  They should otherwise be
      bashed before coming here.  */
   else if (codel == REFERENCE_TYPE)
-    /* Force an abort.  */
-    my_friendly_assert (codel != REFERENCE_TYPE, 317);
+    my_friendly_abort (317);
   else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (rhs)))
     {
       tree nrhs = build1 (NOP_EXPR, type, rhs);
@@ -6742,6 +6765,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
            }
          /* Handle the case of default parameter initialization and
             initialization of static variables.  */
+         else if (TREE_CODE (rhs) == TARGET_EXPR)
+           return rhs;
          else if (TREE_CODE (rhs) == INDIRECT_REF && TREE_HAS_CONSTRUCTOR (rhs))
            {
              my_friendly_assert (TREE_CODE (TREE_OPERAND (rhs, 0)) == CALL_EXPR, 318);
index dd6364e0e5bac8c9f032b22f76d632c17bfa002a..417eda0c835bcba711f1462ab09d8e2fa8ea081e 100644 (file)
@@ -329,7 +329,7 @@ ack (s, v, v2)
    silly.  So instead, we just do the equivalent of a call to fatal in the
    same situation (call exit).  */
 
-/* First used: 0 (reserved), Last used: 360.  Free: 261.  */
+/* First used: 0 (reserved), Last used: 361.  Free: */
 
 static int abortcount = 0;
 
@@ -1342,6 +1342,7 @@ build_m_component_ref (datum, component)
 
   if (TREE_CODE (objtype) == REFERENCE_TYPE)
     objtype = TREE_TYPE (objtype);
+  objtype = TYPE_MAIN_VARIANT (objtype);
 
   if (! IS_AGGR_TYPE (objtype))
     {
This page took 0.215401 seconds and 5 git commands to generate.