OSDN Git Service

90th Cygnus<->FSF quick merge
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 Apr 1997 03:58:33 +0000 (03:58 +0000)
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 Apr 1997 03:58:33 +0000 (03:58 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@13831 138bc75d-0d04-0410-961f-82ee72b054a4

19 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/decl2.c
gcc/cp/friend.c [new file with mode: 0644]
gcc/cp/init.c
gcc/cp/lex.c
gcc/cp/method.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/search.c
gcc/cp/sig.c
gcc/cp/tree.c
gcc/cp/typeck.c

index 78ca954..d945770 100644 (file)
@@ -1,3 +1,194 @@
+Wed Mar 19 14:14:45 1997  Mike Stump  <mrs@cygnus.com>
+
+       * parse.y (left_curly): Avoid trying to use any fields of
+       error_mark_node, as there aren't any.
+
+Thu Mar 13 16:33:22 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * lex.c (do_identifier): Avoid breaking on overloaded methods
+       as default arguments.
+
+Wed Mar 12 13:55:10 1997  Hans-Peter Nilsson  <Hans-Peter.Nilsson@axis.se>
+
+        * call.c (add_template_candidate): Initialize the variable "dummy".
+
+Mon Mar 10 15:13:14 1997  Brendan Kehoe  <brendan@canuck.cygnus.com>
+
+       * decl.c (start_decl): Make sure TYPE isn't an error_mark_node
+       before we try to use TYPE_SIZE and TREE_CONSTANT on it.
+
+Fri Mar  7 13:19:36 1997  Brendan Kehoe  <brendan@lisa.cygnus.com>
+
+       * cp-tree.h (comp_ptr_ttypes, more_specialized): Add decl.
+       (debug_binfo): Delete decl, not needed.
+
+       * tree.c (fnaddr_from_vtable_entry, function_arg_chain,
+       promotes_to_aggr_type): Delete fns.
+       * cp-tree.h (FNADDR_FROM_VTABLE_ENTRY,
+       SET_FNADDR_FROM_VTABLE_ENTRY, FUNCTION_ARG_CHAIN,
+       PROMOTES_TO_AGGR_TYPE): Delete alternates to #if 1.
+
+       * decl.c (pending_invalid_xref{,_file,_line}): Delete unused vars.
+
+       * friend.c (is_friend_type): Delete fn.
+       * cp-tree.h (is_friend_type): Delete decl.
+
+       * decl.c (original_result_rtx, double_ftype_double,
+       double_ftype_double_double, int_ftype_int, long_ftype_long,
+       float_ftype_float, ldouble_ftype_ldouble, last_dtor_insn): Make static.
+       * typeck.c (original_result_rtx, warn_synth): Delete extern decls.
+
+       * decl.c (push_overloaded_decl{,_top_level}): Make static, adding
+       fwd decls.
+       * cp-tree.h (push_overloaded_decl{,_top_level}): Delete decls.
+
+       * decl.c (pushdecl_nonclass_level): #if 0, unused.
+       * cp-tree.h (pushdecl_nonclass_level): #if 0 decl.
+
+       * lex.c (reinit_lang_specific): #if 0, unused.
+       * cp-tree.h (reinit_lang_specific): #if 0 decl.
+
+       * decl.c (revert_static_member_fn): Make static, adding fwd decl.
+       * cp-tree.h (revert_static_member_fn): Delete decl.
+
+       * class.c (root_lang_context_p): Delete fn.
+       * cp-tree.h (root_lang_context_p): Delete decl.
+
+       * decl.c (set_current_level_tags_transparency): #if 0, unused.
+       * cp-tree.h (set_current_level_tags_transparency): #if 0 decl.
+
+       * lex.c (set_vardecl_interface_info): Make static.
+       * cp-tree.h (set_vardecl_interface_info): Delete decl.
+
+       * call.c (find_scoped_type): Make static.
+       * cp-tree.h (find_scoped_type): Delete decl.
+
+       * search.c (convert_pointer_to_vbase): Make static.
+       * cp-tree.h (convert_pointer_to_vbase): Delete decl.
+
+       * decl.c (const_ptr_type_node): Likewise.
+       * cp-tree.h (const_ptr_type_node): Delete decl.
+
+       * typeck.c (common_base_type): Make static.
+       * cp-tree.h (common_base_types): Delete erroneous decl.
+
+       * pt.c (classtype_mangled_name): Make static.
+       * cp-tree.h (classtype_mangled_name): Delete decl.
+
+       * lex.c (check_newline): Make static.
+       * cp-tree.h (check_newline): Delete decl.
+
+       * typeck.c (build_x_array_ref): Delete fn, same idea as
+       grok_array_decl.
+       * cp-tree.h (build_x_array_ref): Delete decl.
+
+       * lex.c (copy_decl_lang_specific): Delete fn, same idea as
+       copy_lang_decl.
+       * cp-tree.h (copy_decl_lang_specific): #if 0 decl.
+
+       * class.c (build_vtable_entry): Make static.
+       * cp-tree.h (build_vtable_entry): Delete decl.
+
+       * class.c (build_vbase_pointer): Make static.
+       * cp-tree.h (build_vbase_pointer): Delete decl.
+
+       * sig.c (build_sptr_ref): Add forward decl and make static.
+       * cp-tree.h (build_sptr_ref): Delete decl.
+
+       * call.c (build_new_method_call): Add forward decl and make static.
+       * cp-tree.h (build_new_method_call): Delete decl.
+
+       * call.c (build_object_call): Make static.
+       * class.c (check_for_override, complete_type_p, mark_overriders):
+       Likewise.
+       * decl.c (cp_function_chain): Likewise.
+       * lex.c (set_typedecl_interface_info, reinit_parse_for_block):
+       Likewise.
+       * pt.c (comp_template_args, get_class_bindings, push_tinst_level):
+       Likewise.
+       * tree.c (build_cplus_array_type_1): Likewise.
+       * typeck.c (comp_ptr_ttypes_{const,real,reinterpret}): Likewise.
+       (comp_target_parms): Likewise.
+
+       * init.c (build_builtin_call): Make static.
+       * cp-tree.h (build_builtin_call): Delete decl.
+
+       * typeck.c (binary_op_error): Delete decl.
+       * cp-tree.h (binary_op_error): Likewise.
+
+Thu Mar  6 16:13:52 1997  Brendan Kehoe  <brendan@lisa.cygnus.com>
+
+       * call.c (build_method_call): Compare against error_mark_node
+       directly, rather than the ERROR_MARK tree code.
+       * cvt.c (cp_convert): Likewise.
+       * decl.c (print_binding_level): Likewise.
+       (duplicate_decls): Likewise.
+       (grokdeclarator): Likewise.
+       (grokdeclarator): Likewise.
+       * init.c (expand_aggr_init_1): Likewise.
+       (decl_constant_value): Likewise.
+       * method.c (build_opfncall): Likewise.
+       (hack_identifier): Likewise.
+       * typeck.c (build_modify_expr): Likewise.
+
+       * typeck.c (build_c_cast): Don't decl TYPE as register tree.
+
+Sun Mar  2 02:54:36 1997  Bruno Haible  <bruno@linuix.mathematik.uni-karlsruhe.de>
+
+       * pt.c (unify): Strip NOP_EXPR wrappers before unifying integer values.
+
+       * pt.c (coerce_template_parms): Add new error message.
+
+       * method.c (build_overload_value): Implement name mangling for
+       floating-point template arguments.
+
+       * method.c (build_overload_int, icat, dicat): Fix mangling of template
+       arguments whose absolute value doesn't fit in a signed word.
+
+Mon Mar  3 12:14:54 1997  Brendan Kehoe  <brendan@lisa.cygnus.com>
+
+       * friend.c: New file; put all of the friend stuff in here.
+       * init.c: Instead of here.
+       * Makefile.in (CXX_OBJS): Add friend.o.
+       (friend.o): Add dependencies.
+       * Make-lang.in (CXX_SRCS): Add $(srcdir)/cp/friend.c.
+
+Sun Mar  2 11:04:43 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * call.c (build_scoped_method_call): Complain if the scope isn't a
+       base.
+
+Wed Feb 26 11:31:06 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * parse.y (left_curly): Don't crash on erroneous type.
+
+       * init.c (build_delete): Fix type of ref.
+
+Tue Feb 25 12:41:48 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * search.c (get_vbase_1): Renamed from get_vbase.
+       (get_vbase): Wrapper, now non-static.
+       (convert_pointer_to_vbase): Now static.
+
+       * call.c (build_scoped_method_call): Accept a binfo for BASETYPE.
+       * init.c (build_delete): Pass one.
+       (build_partial_cleanup_for): Use build_scoped_method_call.
+       * decl.c (finish_function): Pass a binfo.
+
+Mon Feb 24 15:00:12 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * call.c (build_over_call): Only synthesize non-trivial copy ctors.
+
+       * typeck.c (build_c_cast): Lose other reference to flag.
+
+       * call.c (build_field_call): Don't look for [cd]tor_identifier.
+       * decl2.c (delete_sanity): Remove meaningless use of
+       LOOKUP_HAS_IN_CHARGE.
+       * decl.c (finish_function): Use build_scoped_method_call instead
+       of build_delete for running vbase dtors.
+       * init.c (build_delete): Call overload resolution code instead of
+       duplicating it badly.
+
 Thu Feb 20 15:12:15 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
        * call.c (build_over_call): Call mark_used before trying to elide
index 00551a3..2dcfe43 100644 (file)
@@ -118,8 +118,9 @@ CXX_SRCS = $(srcdir)/cp/call.c $(srcdir)/cp/decl2.c \
  $(srcdir)/cp/ptree.c $(srcdir)/cp/tree.c $(srcdir)/cp/cvt.c \
  $(srcdir)/cp/errfn.c $(srcdir)/cp/rtti.c $(srcdir)/cp/method.c \
  $(srcdir)/cp/search.c $(srcdir)/cp/typeck.c $(srcdir)/cp/decl.c \
- $(srcdir)/cp/error.c $(srcdir)/cp/init.c $(srcdir)/cp/parse.y \
- $(srcdir)/cp/sig.c $(srcdir)/cp/typeck2.c $(srcdir)/cp/repo.c
+ $(srcdir)/cp/error.c $(srcdir)/cp/friend.c $(srcdir)/cp/init.c \
+ $(srcdir)/cp/parse.y $(srcdir)/cp/sig.c $(srcdir)/cp/typeck2.c \
+ $(srcdir)/cp/repo.c
 
 cc1plus: $(P) $(CXX_SRCS) $(LIBDEPS) stamp-objlist c-common.o c-pragma.o
        cd cp; $(MAKE) $(FLAGS_TO_PASS) $(CXX_FLAGS_TO_PASS) ../cc1plus
index dc86dc3..03ba91a 100644 (file)
@@ -160,7 +160,7 @@ INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config
 
 CXX_OBJS = call.o decl.o errfn.o expr.o pt.o sig.o typeck2.o \
  class.o decl2.o error.o lex.o parse.o ptree.o rtti.o spew.o typeck.o cvt.o \
- except.o init.o method.o search.o tree.o xref.o repo.o
+ except.o friend.o init.o method.o search.o tree.o xref.o repo.o
 
 # Language-independent object files.
 OBJS = `cat ../stamp-objlist` ../c-common.o ../c-pragma.o
@@ -231,6 +231,7 @@ typeck2.o : typeck2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h
 typeck.o : typeck.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H)
 class.o : class.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h
 call.o : call.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h class.h
+friend.o : friend.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H)
 init.o : init.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H)
 method.o : method.c $(CONFIG_H) $(CXX_TREE_H) class.h
 cvt.o : cvt.c $(CONFIG_H) $(CXX_TREE_H) class.h
index 75e7b56..df4ced9 100644 (file)
@@ -44,6 +44,7 @@ extern tree ctor_label, dtor_label;
    between an expected and the given type.  */
 
 static struct harshness_code convert_harshness PROTO((register tree, register tree, tree));
+static tree build_new_method_call              PROTO((tree, tree, tree, tree, int));
 
 #define EVIL_RETURN(ARG)       ((ARG).code = EVIL_CODE, (ARG))
 #define STD_RETURN(ARG)                ((ARG).code = STD_CODE, (ARG))
@@ -1175,6 +1176,9 @@ build_field_call (basetype_path, instance_ptr, name, parms)
 {
   tree field, instance;
 
+  if (name == ctor_identifier || name == dtor_identifier)
+    return NULL_TREE;
+
   if (instance_ptr == current_class_ptr)
     {
       /* Check to see if we really have a reference to an instance variable
@@ -1266,7 +1270,7 @@ build_field_call (basetype_path, instance_ptr, name, parms)
   return NULL_TREE;
 }
 
-tree
+static tree
 find_scoped_type (type, inner_name, inner_types)
      tree type, inner_name, inner_types;
 {
@@ -1424,6 +1428,14 @@ build_scoped_method_call (exp, basetype, name, parms)
   if (TREE_CODE (type) == REFERENCE_TYPE)
     type = TREE_TYPE (type);
 
+  if (TREE_CODE (basetype) == TREE_VEC)
+    {
+      binfo = basetype;
+      basetype = BINFO_TYPE (binfo);
+    }
+  else
+    binfo = NULL_TREE;
+
   /* Destructors can be "called" for simple types; see 5.2.4 and 12.4 Note
      that explicit ~int is caught in the parser; this deals with typedefs
      and template parms.  */
@@ -1449,13 +1461,21 @@ build_scoped_method_call (exp, basetype, name, parms)
       return error_mark_node;
     }
 
-  if ((binfo = binfo_or_else (basetype, type)))
+  if (! binfo)
     {
+      binfo = get_binfo (basetype, type, 1);
       if (binfo == error_mark_node)
        return error_mark_node;
+      if (! binfo)
+       error_not_base_type (basetype, type);
+    }
+
+  if (binfo)
+    {
       if (TREE_CODE (exp) == INDIRECT_REF)
-       decl = build_indirect_ref (convert_pointer_to (binfo,
-                                                      build_unary_op (ADDR_EXPR, exp, 0)), NULL_PTR);
+       decl = build_indirect_ref
+         (convert_pointer_to_real
+          (binfo, build_unary_op (ADDR_EXPR, exp, 0)), NULL_PTR);
       else
        decl = build_scoped_ref (exp, basetype);
 
@@ -1820,7 +1840,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
       if (! IS_AGGR_TYPE (basetype))
        {
        non_aggr_error:
-         if ((flags & LOOKUP_COMPLAIN) && TREE_CODE (basetype) != ERROR_MARK)
+         if ((flags & LOOKUP_COMPLAIN) && basetype != error_mark_node)
            cp_error ("request for member `%D' in `%E', which is of non-aggregate type `%T'",
                      name, instance, basetype);
 
@@ -2568,7 +2588,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
                   && TREE_OPERAND (TREE_OPERAND (instance_ptr, 0), 0) == instance)
            ;
          /* The call to `convert_pointer_to' may return error_mark_node.  */
-         else if (TREE_CODE (instance_ptr) == ERROR_MARK)
+         else if (instance_ptr == error_mark_node)
            return instance_ptr;
          else if (instance == NULL_TREE
                   || TREE_CODE (instance) != INDIRECT_REF
@@ -4074,7 +4094,7 @@ add_template_candidate (candidates, tmpl, arglist, flags)
   int ntparms = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (tmpl));
   tree *targs = (tree *) alloca (sizeof (tree) * ntparms);
   struct z_candidate *cand;
-  int i, dummy
+  int i, dummy = 0;
   tree fn;
 
   i = type_unification (DECL_TEMPLATE_PARMS (tmpl), targs,
@@ -4356,7 +4376,7 @@ build_new_function_call (fn, args, obj)
   return build_function_call (fn, args);
 }
 
-tree
+static tree
 build_object_call (obj, args)
      tree obj, args;
 {
@@ -5092,10 +5112,6 @@ build_over_call (fn, convs, args, flags)
 
   converted_args = nreverse (converted_args);
 
-  /* [class.copy]: the copy constructor is implicitly defined even if the
-     implementation  elided  its  use.  */
-  mark_used (fn);
-
   /* Avoid actually calling copy constructors and copy assignment operators,
      if possible.  */
   if (DECL_CONSTRUCTOR_P (fn)
@@ -5119,6 +5135,11 @@ build_over_call (fn, convs, args, flags)
       else
        arg = build_indirect_ref (arg, 0);
 
+      /* [class.copy]: the copy constructor is implicitly defined even if
+        the implementation elided its use.  */
+      if (TYPE_HAS_COMPLEX_INIT_REF (DECL_CONTEXT (fn)))
+       mark_used (fn);
+
       /* If we're creating a temp and we already have one, don't create a
          new one.  If we're not creating a temp but we get one, use
          INIT_EXPR to collapse the temp into our target.  Otherwise, if the
@@ -5159,6 +5180,8 @@ build_over_call (fn, convs, args, flags)
       return val;
     }
 
+  mark_used (fn);
+
   if (DECL_CONTEXT (fn) && IS_SIGNATURE (DECL_CONTEXT (fn)))
     return build_signature_method_call (fn, converted_args);
   else if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0)
@@ -5186,7 +5209,7 @@ build_over_call (fn, convs, args, flags)
   return convert_from_reference (require_complete_type (fn));
 }
 
-tree
+static tree
 build_new_method_call (instance, name, args, basetype_path, flags)
      tree instance, name, args, basetype_path;
      int flags;
index dc179d0..5ada32b 100644 (file)
@@ -121,7 +121,7 @@ int n_inner_fields_searched = 0;
 
 /* Virtual baseclass things.  */
 
-tree
+static tree
 build_vbase_pointer (exp, type)
      tree exp, type;
 {
@@ -135,7 +135,7 @@ build_vbase_pointer (exp, type)
 /* Is the type of the EXPR, the complete type of the object?
    If we are going to be wrong, we must be conservative, and return 0.  */
 
-int
+static int
 complete_type_p (expr)
      tree expr;
 {
@@ -372,11 +372,10 @@ static tree pending_hard_virtuals;
    Note that the index (DELTA2) in the virtual function table
    is always 0.  */
 
-tree
+static tree
 build_vtable_entry (delta, pfn)
      tree delta, pfn;
 {
-
   if (flag_vtable_thunks)
     {
       HOST_WIDE_INT idelta = TREE_INT_CST_LOW (delta);
@@ -2755,7 +2754,7 @@ get_basefndecls (fndecl, t)
    Since we start out with all functions already marked with a hider,
    no need to mark functions that are just hidden.  */
 
-void
+static void
 mark_overriders (fndecl, base_fndecls)
      tree fndecl, base_fndecls;
 {
@@ -2772,7 +2771,7 @@ mark_overriders (fndecl, base_fndecls)
    a method declared virtual in the base class, then
    mark this field as being virtual as well.  */
 
-void
+static void
 check_for_override (decl, ctype)
      tree decl, ctype;
 {
@@ -4821,12 +4820,6 @@ pop_lang_context ()
   else if (current_lang_name == lang_name_c)
     strict_prototype = strict_prototypes_lang_c;
 }
-
-int
-root_lang_context_p ()
-{
-  return current_lang_stack == current_lang_base;
-}
 \f
 /* Type instantiation routines.  */
 
index 9bd73ab..31cc776 100644 (file)
@@ -325,14 +325,12 @@ enum languages { lang_c, lang_cplusplus };
 /* In a *_TYPE, nonzero means a built-in type.  */
 #define TYPE_BUILT_IN(NODE) TYPE_LANG_FLAG_6(NODE)
 
-/* Macros which might want to be replaced by function calls.  */
-
 #define DELTA_FROM_VTABLE_ENTRY(ENTRY) \
   (!flag_vtable_thunks ? \
      TREE_VALUE (CONSTRUCTOR_ELTS (ENTRY)) \
    : TREE_CODE (TREE_OPERAND ((ENTRY), 0)) != THUNK_DECL ? integer_zero_node \
    : build_int_2 (THUNK_DELTA (TREE_OPERAND ((ENTRY), 0)), 0))
-#if 1
+
 /* Virtual function addresses can be gotten from a virtual function
    table entry using this macro.  */
 #define FNADDR_FROM_VTABLE_ENTRY(ENTRY) \
@@ -348,14 +346,6 @@ enum languages { lang_c, lang_cplusplus };
        && IS_AGGR_TYPE (TREE_TYPE (NODE)))     \
    || IS_AGGR_TYPE (NODE))
 
-#else
-#define FNADDR_FROM_VTABLE_ENTRY(ENTRY) (fnaddr_from_vtable_entry (ENTRY))
-#define SET_FNADDR_FROM_VTABLE_ENTRY(ENTRY,VALUE) \
-  (set_fnaddr_from_vtable_entry (ENTRY, VALUE))
-/* #define TYPE_NAME_STRING(NODE) (type_name_string (NODE)) */
-#define FUNCTION_ARG_CHAIN(NODE) (function_arg_chain (NODE))
-#define PROMOTES_TO_AGGR_TYPE(NODE,CODE) (promotes_to_aggr_type (NODE, CODE))
-#endif
 /* Nonzero iff TYPE is uniquely derived from PARENT.  Under MI, PARENT can
    be an ambiguous base class of TYPE, and this macro will be false.  */
 #define UNIQUELY_DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 0, (tree *)0) >= 0)
@@ -1499,7 +1489,7 @@ extern tree vt_off_identifier;
 /* A node that is a list (length 1) of error_mark_nodes.  */
 extern tree error_mark_list;
 
-extern tree ptr_type_node, const_ptr_type_node;
+extern tree ptr_type_node;
 extern tree class_type_node, record_type_node, union_type_node, enum_type_node;
 extern tree unknown_type_node;
 extern tree opaque_type_node, signature_type_node;
@@ -1927,7 +1917,6 @@ extern int get_arglist_len_in_bytes               PROTO((tree));
 extern int rank_for_overload                   PROTO((struct candidate *, struct candidate *));
 extern void compute_conversion_costs           PROTO((tree, tree, struct candidate *, int));
 extern tree build_vfield_ref                   PROTO((tree, tree));
-extern tree find_scoped_type                   PROTO((tree, tree, tree));
 extern tree resolve_scope_to_name              PROTO((tree, tree));
 extern tree build_scoped_method_call           PROTO((tree, tree, tree, tree));
 extern tree build_addr_func                    PROTO((tree));
@@ -1939,16 +1928,12 @@ extern int null_ptr_cst_p                       PROTO((tree));
 extern tree type_decays_to                     PROTO((tree));
 extern tree build_user_type_conversion         PROTO((tree, tree, int));
 extern tree build_new_function_call            PROTO((tree, tree, tree));
-extern tree build_object_call                  PROTO((tree, tree));
 extern tree build_new_op                       PROTO((enum tree_code, int, tree, tree, tree));
-extern tree build_new_method_call              PROTO((tree, tree, tree, tree, int));
 extern int can_convert                         PROTO((tree, tree));
 extern int can_convert_arg                     PROTO((tree, tree, tree));
 
 /* in class.c */
-extern tree build_vbase_pointer                        PROTO((tree, tree));
 extern tree build_vbase_path                   PROTO((enum tree_code, tree, tree, tree, int));
-extern tree build_vtable_entry                 PROTO((tree, tree));
 extern tree build_vtbl_ref                     PROTO((tree, tree));
 extern tree build_vfn_ref                      PROTO((tree *, tree, tree));
 extern void add_method                         PROTO((tree, tree *, tree));
@@ -1965,7 +1950,6 @@ extern void push_nested_class                     PROTO((tree, int));
 extern void pop_nested_class                   PROTO((int));
 extern void push_lang_context                  PROTO((tree));
 extern void pop_lang_context                   PROTO((void));
-extern int root_lang_context_p                 PROTO((void));
 extern tree instantiate_type                   PROTO((tree, tree, int));
 extern void print_class_statistics             PROTO((void));
 extern void maybe_push_cache_obstack           PROTO((void));
@@ -2023,12 +2007,12 @@ extern int decls_match                          PROTO((tree, tree));
 extern int duplicate_decls                     PROTO((tree, tree));
 extern tree pushdecl                           PROTO((tree));
 extern tree pushdecl_top_level                 PROTO((tree));
-extern void push_overloaded_decl_top_level     PROTO((tree, int));
 extern tree pushdecl_class_level               PROTO((tree));
+#if 0
 extern void pushdecl_nonclass_level            PROTO((tree));
+#endif
 extern void push_class_level_binding           PROTO((tree, tree));
 extern int overloaded_globals_p                        PROTO((tree));
-extern tree push_overloaded_decl               PROTO((tree, int));
 extern tree implicitly_declare                 PROTO((tree));
 extern tree lookup_label                       PROTO((tree));
 extern tree shadow_label                       PROTO((tree));
@@ -2038,7 +2022,9 @@ extern void pop_switch                            PROTO((void));
 extern void define_case_label                  PROTO((tree));
 extern tree getdecls                           PROTO((void));
 extern tree gettags                            PROTO((void));
+#if 0
 extern void set_current_level_tags_transparency        PROTO((int));
+#endif
 extern tree lookup_namespace_name              PROTO((tree, tree));
 extern tree make_typename_type                 PROTO((tree, tree));
 extern tree lookup_name_nonclass               PROTO((tree));
@@ -2082,7 +2068,6 @@ extern tree maybe_build_cleanup_and_delete        PROTO((tree));
 extern tree maybe_build_cleanup                        PROTO((tree));
 extern void cplus_expand_expr_stmt             PROTO((tree));
 extern void finish_stmt                                PROTO((void));
-extern void revert_static_member_fn            PROTO((tree *, tree *, tree *));
 extern int id_in_current_class                 PROTO((tree));
 extern void push_cp_function_context           PROTO((tree));
 extern void pop_cp_function_context            PROTO((tree));
@@ -2184,6 +2169,11 @@ extern void fixup_result_decl                    PROTO((tree, struct rtx_def *));
 extern int extract_init                                PROTO((tree, tree));
 extern void do_case                            PROTO((tree, tree));
 
+/* friend.c */
+extern int is_friend                           PROTO((tree, tree));
+extern void make_friend_class                  PROTO((tree, tree));
+extern tree do_friend                          PROTO((tree, tree, tree, tree, enum overload_flags, tree, int));
+
 /* in init.c */
 extern void init_init_processing               PROTO((void));
 extern void expand_direct_vtbls_init           PROTO((tree, tree, int, int, tree));
@@ -2200,11 +2190,6 @@ extern tree build_member_call                    PROTO((tree, tree, tree));
 extern tree build_offset_ref                   PROTO((tree, tree));
 extern tree resolve_offset_ref                 PROTO((tree));
 extern tree decl_constant_value                        PROTO((tree));
-extern int is_friend_type                      PROTO((tree, tree));
-extern int is_friend                           PROTO((tree, tree));
-extern void make_friend_class                  PROTO((tree, tree));
-extern tree do_friend                          PROTO((tree, tree, tree, tree, enum overload_flags, tree, int));
-extern tree build_builtin_call                 PROTO((tree, tree, tree));
 extern tree build_new                          PROTO((tree, tree, tree, int));
 extern tree expand_vec_init                    PROTO((tree, tree, tree, tree, int));
 extern tree build_x_delete                     PROTO((tree, tree, int, tree));
@@ -2223,13 +2208,14 @@ extern char *operator_name_string               PROTO((tree));
 extern void lang_init                          PROTO((void));
 extern void lang_finish                                PROTO((void));
 extern void init_filename_times                        PROTO((void));
+#if 0
 extern void reinit_lang_specific               PROTO((void));
+#endif
 extern void init_lex                           PROTO((void));
 extern void reinit_parse_for_function          PROTO((void));
 extern int *init_parse                         PROTO((void));
 extern void print_parse_statistics             PROTO((void));
 extern void extract_interface_info             PROTO((void));
-extern int set_vardecl_interface_info          PROTO((tree, tree));
 extern void do_pending_inlines                 PROTO((void));
 extern void process_next_inline                        PROTO((tree));
 /* skip save_pending_input */
@@ -2237,13 +2223,12 @@ extern void process_next_inline                 PROTO((tree));
 extern void yyungetc                           PROTO((int, int));
 extern void reinit_parse_for_method            PROTO((int, tree));
 #if 0
-extern void reinit_parse_for_block             PROTO((int, struct obstack *, int));
+extern void reinit_parse_for_block             PROTO((int, struct obstack *));
 #endif
 extern tree cons_up_default_function           PROTO((tree, tree, int));
 extern void check_for_missing_semicolon                PROTO((tree));
 extern void note_got_semicolon                 PROTO((tree));
 extern void note_list_got_semicolon            PROTO((tree));
-extern int check_newline                       PROTO((void));
 extern void do_pending_lang_change             PROTO((void));
 extern int identifier_type                     PROTO((tree));
 extern void see_typename                       PROTO((void));
@@ -2256,7 +2241,6 @@ extern tree build_lang_decl                       PROTO((enum tree_code, tree, tree));
 extern tree build_lang_field_decl              PROTO((enum tree_code, tree, tree));
 extern void copy_lang_decl                     PROTO((tree));
 extern tree make_lang_type                     PROTO((enum tree_code));
-extern void copy_decl_lang_specific            PROTO((tree));
 extern void dump_time_statistics               PROTO((void));
 /* extern void compiler_error                  PROTO((char *, HOST_WIDE_INT, HOST_WIDE_INT)); */
 extern void yyerror                            PROTO((char *));
@@ -2295,11 +2279,11 @@ extern void overload_template_name              PROTO((tree));
 extern int type_unification                    PROTO((tree, tree *, tree, tree, int *, int, int));
 struct tinst_level *tinst_for_decl             PROTO((void));
 extern void mark_decl_instantiated             PROTO((tree, int));
+extern int more_specialized                    PROTO((tree, tree));
 extern void mark_class_instantiated            PROTO((tree, int));
 extern void do_function_instantiation          PROTO((tree, tree, tree));
 extern void do_type_instantiation              PROTO((tree, tree));
 extern tree instantiate_decl                   PROTO((tree));
-extern tree classtype_mangled_name             PROTO((tree));
 extern tree lookup_nested_type_by_name         PROTO((tree, tree));
 extern tree do_poplevel                                PROTO((void));
 extern tree *get_bindings                      PROTO((tree, tree));
@@ -2326,7 +2310,7 @@ extern void synthesize_tinfo_fn                   PROTO((tree));
 /* in search.c */
 extern void push_memoized_context              PROTO((tree, int));
 extern void pop_memoized_context               PROTO((int));
-extern tree convert_pointer_to_vbase           PROTO((tree, tree));
+extern tree get_vbase                          PROTO((tree, tree));
 extern tree get_binfo                          PROTO((tree, tree, int));
 extern int get_base_distance                   PROTO((tree, tree, int, tree *));
 extern tree compute_access                     PROTO((tree, tree));
@@ -2365,7 +2349,6 @@ extern tree build_signature_reference_type        PROTO((tree, int, int));
 extern tree build_signature_pointer_constructor        PROTO((tree, tree));
 extern tree build_signature_method_call                PROTO((tree, tree));
 extern tree build_optr_ref                     PROTO((tree));
-extern tree build_sptr_ref                     PROTO((tree));
 extern void append_signature_fields            PROTO((tree));
 
 /* in spew.c */
@@ -2401,7 +2384,6 @@ extern tree get_decl_list                 PROTO((tree));
 extern tree make_binfo                         PROTO((tree, tree, tree, tree, tree));
 extern tree binfo_value                                PROTO((tree, tree));
 extern tree reverse_path                       PROTO((tree));
-extern void debug_binfo                                PROTO((tree));
 extern int decl_list_length                    PROTO((tree));
 extern int count_functions                     PROTO((tree));
 extern int is_overloaded_fn                    PROTO((tree));
@@ -2438,7 +2420,6 @@ extern tree common_type                           PROTO((tree, tree));
 extern int compexcepttypes                     PROTO((tree, tree));
 extern int comptypes                           PROTO((tree, tree, int));
 extern int comp_target_types                   PROTO((tree, tree, int));
-extern tree common_base_types                  PROTO((tree, tree));
 extern int compparms                           PROTO((tree, tree, int));
 extern int comp_target_types                   PROTO((tree, tree, int));
 extern int self_promoting_args_p               PROTO((tree));
@@ -2458,7 +2439,6 @@ extern tree build_component_ref                   PROTO((tree, tree, tree, int));
 extern tree build_x_component_ref              PROTO((tree, tree, tree, int));
 extern tree build_x_indirect_ref               PROTO((tree, char *));
 extern tree build_indirect_ref                 PROTO((tree, char *));
-extern tree build_x_array_ref                  PROTO((tree, tree));
 extern tree build_array_ref                    PROTO((tree, tree));
 extern tree build_x_function_call              PROTO((tree, tree, tree));
 extern tree get_member_function_from_ptrfunc   PROTO((tree *, tree));
@@ -2490,6 +2470,7 @@ extern tree convert_for_initialization            PROTO((tree, tree, tree, int, char *, tr
 extern void c_expand_asm_operands              PROTO((tree, tree, tree, tree, int, char *, int));
 extern void c_expand_return                    PROTO((tree));
 extern tree c_expand_start_case                        PROTO((tree));
+extern int comp_ptr_ttypes                     PROTO((tree, tree));
 extern int ptr_reasonably_similar              PROTO((tree, tree));
 extern tree build_ptrmemfunc                   PROTO((tree, tree, int));
 
index 1c40640..cf96115 100644 (file)
@@ -1153,8 +1153,8 @@ cp_convert (type, expr, convtype, flags)
   register tree e = expr;
   register enum tree_code code = TREE_CODE (type);
 
-  if (TREE_CODE (e) == ERROR_MARK
-      || TREE_CODE (TREE_TYPE (e)) == ERROR_MARK)
+  if (e == error_mark_node
+      || TREE_TYPE (e) == error_mark_node)
     return error_mark_node;
 
   if (IS_AGGR_TYPE (type) && (convtype & CONV_FORCE_TEMP))
index 77dce5b..1fd2026 100644 (file)
@@ -126,6 +126,9 @@ static struct stack_level *decl_stack;
 static tree grokparms                          PROTO((tree, int));
 static tree lookup_nested_type                 PROTO((tree, tree));
 static char *redeclaration_error_message       PROTO((tree, tree));
+static void revert_static_member_fn            PROTO((tree *, tree *, tree *));
+static tree push_overloaded_decl               PROTO((tree, int));
+static void push_overloaded_decl_top_level     PROTO((tree, int));
 
 tree define_function           
        PROTO((char *, tree, enum built_in_function, void (*)(), char *));
@@ -185,7 +188,8 @@ tree void_zero_node;
 
 /* Nodes for types `void *' and `const void *'.  */
 
-tree ptr_type_node, const_ptr_type_node;
+tree ptr_type_node;
+static tree const_ptr_type_node;
 
 /* Nodes for types `char *' and `const char *'.  */
 
@@ -215,10 +219,10 @@ tree default_function_type;
 
 /* function types `double (double)' and `double (double, double)', etc.  */
 
-tree double_ftype_double, double_ftype_double_double;
-tree int_ftype_int, long_ftype_long;
-tree float_ftype_float;
-tree ldouble_ftype_ldouble;
+static tree double_ftype_double, double_ftype_double_double;
+static tree int_ftype_int, long_ftype_long;
+static tree float_ftype_float;
+static tree ldouble_ftype_ldouble;
 
 /* Function type `int (const void *, const void *, size_t)' */
 static tree int_ftype_cptr_cptr_sizet;
@@ -264,7 +268,7 @@ tree dtor_label;
 /* In a destructor, the last insn emitted after the start of the
    function and the parms.  */
 
-rtx last_dtor_insn;
+static rtx last_dtor_insn;
 
 /* In a constructor, the point at which we are ready to return
    the pointer to the initialized object.  */
@@ -283,7 +287,7 @@ extern rtx cleanup_label, return_label;
    but due to being an addressable named return value, would up
    on the stack, this variable holds the named return value's
    original location.  */
-rtx original_result_rtx;
+static rtx original_result_rtx;
 
 /* Sequence of insns which represents base initialization.  */
 tree base_init_expr;
@@ -350,14 +354,6 @@ tree null_node;
 
 tree integer_one_node, integer_two_node, integer_three_node;
 
-/* Nonzero if we have seen an invalid cross reference
-   to a struct, union, or enum, but not yet printed the message.  */
-
-tree pending_invalid_xref;
-/* File and line to appear in the eventual error message.  */
-char *pending_invalid_xref_file;
-int pending_invalid_xref_line;
-
 /* While defining an enum type, this is 1 plus the last enumerator
    constant value.  */
 
@@ -1507,7 +1503,7 @@ print_binding_level (lvl)
              i = len;
            }
          print_node_brief (stderr, "", t, 0);
-         if (TREE_CODE (t) == ERROR_MARK)
+         if (t == error_mark_node)
            break;
        }
       if (i)
@@ -2375,10 +2371,8 @@ duplicate_decls (newdecl, olddecl)
      error (earlier) for some bogus type specification, and in that case,
      it is rather pointless to harass the user with yet more error message
      about the same declaration, so well just pretent the types match here.  */
-  if ((TREE_TYPE (newdecl)
-       && TREE_CODE (TREE_TYPE (newdecl)) == ERROR_MARK)
-      || (TREE_TYPE (olddecl)
-         && TREE_CODE (TREE_TYPE (olddecl)) == ERROR_MARK))
+  if (TREE_TYPE (newdecl) == error_mark_node
+      || TREE_TYPE (olddecl) == error_mark_node)
     types_match = 1;
 
   if (TREE_CODE (olddecl) == FUNCTION_DECL
@@ -2897,7 +2891,7 @@ duplicate_decls (newdecl, olddecl)
            }
          else
            {
-             /* Storage leak.  */
+             /* Storage leak.  */;
            }
        }
     }
@@ -3350,7 +3344,7 @@ pushdecl_top_level (x)
 /* Like push_overloaded_decl, only it places X in GLOBAL_BINDING_LEVEL,
    if appropriate.  */
 
-void
+static void
 push_overloaded_decl_top_level (x, forget)
      tree x;
      int forget;
@@ -3403,6 +3397,7 @@ pushdecl_class_level (x)
   return x;
 }
 
+#if 0
 /* This function is used to push the mangled decls for nested types into
    the appropriate scope.  Previously pushdecl_top_level was used, but that
    is incorrect for members of local classes.  */
@@ -3423,6 +3418,7 @@ pushdecl_nonclass_level (x)
 
   pushdecl_with_scope (x, b);
 }
+#endif
 
 /* Make the declaration(s) of X appear in CLASS scope
    under the name NAME.  */
@@ -3477,7 +3473,7 @@ overloaded_globals_p (list)
    about what language DECL should belong to (C or C++).  Otherwise,
    it's always DECL (and never something that's not a _DECL).  */
 
-tree
+static tree
 push_overloaded_decl (decl, forgettable)
      tree decl;
      int forgettable;
@@ -4118,12 +4114,14 @@ lookup_tag (form, name, binding_level, thislevel_only)
   return NULL_TREE;
 }
 
+#if 0
 void
 set_current_level_tags_transparency (tags_transparent)
      int tags_transparent;
 {
   current_binding_level->tag_transparent = tags_transparent;
 }
+#endif
 
 /* Given a type, find the tag that was defined for it and return the tag name.
    Otherwise return 0.  However, the value can never be 0
@@ -5744,20 +5742,24 @@ start_decl (declarator, declspecs, initialized)
       default:
        if (! processing_template_decl)
          {
-           if (TYPE_SIZE (type) != NULL_TREE
-               && ! TREE_CONSTANT (TYPE_SIZE (type)))
+           if (type != error_mark_node)
              {
-               cp_error
-                 ("variable-sized object `%D' may not be initialized", decl);
-               initialized = 0;
-             }
+               if (TYPE_SIZE (type) != NULL_TREE
+                   && ! TREE_CONSTANT (TYPE_SIZE (type)))
+                 {
+                   cp_error
+                     ("variable-sized object `%D' may not be initialized",
+                      decl);
+                   initialized = 0;
+                 }
 
-           if (TREE_CODE (type) == ARRAY_TYPE
-               && TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE)
-             {
-               cp_error
-                 ("elements of array `%#D' have incomplete type", decl);
-               initialized = 0;
+               if (TREE_CODE (type) == ARRAY_TYPE
+                   && TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE)
+                 {
+                   cp_error
+                     ("elements of array `%#D' have incomplete type", decl);
+                   initialized = 0;
+                 }
              }
          }
       }
@@ -7799,7 +7801,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
              typedef_decl = t;
            }
        }
-      else if (TREE_CODE (id) != ERROR_MARK)
+      else if (id != error_mark_node)
        /* Can't change CLASS nodes into RECORD nodes here!  */
        type = id;
 
@@ -8207,7 +8209,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
         array or function or pointer, and DECLARATOR has had its
         outermost layer removed.  */
 
-      if (TREE_CODE (type) == ERROR_MARK)
+      if (type == error_mark_node)
        {
          if (TREE_CODE (declarator) == SCOPE_REF)
            declarator = TREE_OPERAND (declarator, 1);
@@ -11661,14 +11663,13 @@ finish_function (lineno, call_poplevel, nested)
                    {
                      if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (vbases)))
                        {
-                         tree ptr = convert_pointer_to_vbase (BINFO_TYPE (vbases), current_class_ptr);
+                         tree vb = get_vbase
+                           (BINFO_TYPE (vbases),
+                            TYPE_BINFO (current_class_type));
                          expand_expr_stmt
-                           (build_delete
-                            (build_pointer_type (BINFO_TYPE (vbases)),
-                             ptr, integer_zero_node,
-                             (LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR
-                              |LOOKUP_HAS_IN_CHARGE|LOOKUP_NORMAL),
-                             0));
+                           (build_scoped_method_call
+                            (current_class_ref, vb, dtor_identifier,
+                             build_tree_list (NULL_TREE, integer_zero_node)));
                        }
                      vbases = TREE_CHAIN (vbases);
                    }
@@ -12460,7 +12461,7 @@ finish_stmt ()
    (TREE_TYPE (decl)) to ARGTYPES, as doing so will corrupt the types of
    other decls.  Either pass the addresses of local variables or NULL.  */
 
-void
+static void
 revert_static_member_fn (decl, fn, argtypes)
      tree *decl, *fn, *argtypes;
 {
@@ -12520,9 +12521,7 @@ struct cp_function
   struct binding_level *binding_level;
 };
 
-
-
-struct cp_function *cp_function_chain;
+static struct cp_function *cp_function_chain;
 
 extern int temp_name_counter;
 
index fe4228d..60a27a4 100644 (file)
@@ -1245,8 +1245,7 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
        }
 
       return build_delete (type, t, integer_three_node,
-                          LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE,
-                          use_global_delete);
+                          LOOKUP_NORMAL, use_global_delete);
     }
 }
 
diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c
new file mode 100644 (file)
index 0000000..6d7d9d5
--- /dev/null
@@ -0,0 +1,414 @@
+/* Help friends in C++.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include "config.h"
+#include "tree.h"
+#include "rtl.h"
+#include "cp-tree.h"
+#include "flags.h"
+#include "output.h"
+
+/* Friend data structures:
+
+   Lists of friend functions come from TYPE_DECL nodes.  Since all
+   aggregate types are automatically typedef'd, these nodes are guaranteed
+   to exist.
+
+   The TREE_PURPOSE of a friend list is the name of the friend,
+   and its TREE_VALUE is another list.
+
+   For each element of that list, either the TREE_VALUE or the TREE_PURPOSE
+   will be filled in, but not both.  The TREE_VALUE of that list is an
+   individual function which is a friend.  The TREE_PURPOSE of that list
+   indicates a type in which all functions by that name are friends.
+
+   Lists of friend classes come from _TYPE nodes.  Love that consistency
+   thang.  */
+
+int
+is_friend (type, supplicant)
+     tree type, supplicant;
+{
+  int declp;
+  register tree list;
+
+  if (supplicant == NULL_TREE || type == NULL_TREE)
+    return 0;
+
+  declp = (TREE_CODE_CLASS (TREE_CODE (supplicant)) == 'd');
+
+  if (declp)
+    /* It's a function decl.  */
+    {
+      tree list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type));
+      tree name = DECL_NAME (supplicant);
+      tree ctype;
+
+      if (DECL_FUNCTION_MEMBER_P (supplicant))
+       ctype = DECL_CLASS_CONTEXT (supplicant);
+      else
+       ctype = NULL_TREE;
+
+      for (; list ; list = TREE_CHAIN (list))
+       {
+         if (name == TREE_PURPOSE (list))
+           {
+             tree friends = TREE_VALUE (list);
+             for (; friends ; friends = TREE_CHAIN (friends))
+               {
+                 if (ctype == TREE_PURPOSE (friends))
+                   return 1;
+                 if (comptypes (TREE_TYPE (supplicant),
+                                TREE_TYPE (TREE_VALUE (friends)), 1))
+                   return 1;
+               }
+             break;
+           }
+       }
+    }
+  else
+    /* It's a type.  */
+    {
+      if (type == supplicant)
+       return 1;
+      
+      list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_MAIN_DECL (type)));
+      for (; list ; list = TREE_CHAIN (list))
+       if (supplicant == TREE_VALUE (list))
+         return 1;
+    }      
+
+  {
+    tree context;
+
+    if (! declp)
+      {
+       /* Are we a nested or local class?  If so, we aren't friends
+           with the CONTEXT.  */
+       if (IS_AGGR_TYPE (supplicant))
+         context = NULL_TREE;
+       else
+         context = DECL_CONTEXT (TYPE_MAIN_DECL (supplicant));
+      }
+    else if (DECL_FUNCTION_MEMBER_P (supplicant))
+      context = DECL_CLASS_CONTEXT (supplicant);
+    else
+      context = NULL_TREE;
+
+    if (context)
+      return is_friend (type, context);
+  }
+
+  return 0;
+}
+
+/* Add a new friend to the friends of the aggregate type TYPE.
+   DECL is the FUNCTION_DECL of the friend being added.  */
+
+static void
+add_friend (type, decl)
+     tree type, decl;
+{
+  tree typedecl = TYPE_MAIN_DECL (type);
+  tree list = DECL_FRIENDLIST (typedecl);
+  tree name = DECL_NAME (decl);
+
+  while (list)
+    {
+      if (name == TREE_PURPOSE (list))
+       {
+         tree friends = TREE_VALUE (list);
+         for (; friends ; friends = TREE_CHAIN (friends))
+           {
+             if (decl == TREE_VALUE (friends))
+               {
+                 cp_warning ("`%D' is already a friend of class `%T'",
+                             decl, type);
+                 cp_warning_at ("previous friend declaration of `%D'",
+                                TREE_VALUE (friends));
+                 return;
+               }
+           }
+         TREE_VALUE (list) = tree_cons (error_mark_node, decl,
+                                        TREE_VALUE (list));
+         return;
+       }
+      list = TREE_CHAIN (list);
+    }
+  DECL_FRIENDLIST (typedecl)
+    = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl),
+                DECL_FRIENDLIST (typedecl));
+  if (DECL_NAME (decl) == ansi_opname[(int) MODIFY_EXPR])
+    {
+      tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
+      TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1;
+      if (parmtypes && TREE_CHAIN (parmtypes))
+       {
+         tree parmtype = TREE_VALUE (TREE_CHAIN (parmtypes));
+         if (TREE_CODE (parmtype) == REFERENCE_TYPE
+             && TREE_TYPE (parmtypes) == TREE_TYPE (typedecl))
+           TYPE_HAS_ASSIGN_REF (TREE_TYPE (typedecl)) = 1;
+       }
+    }
+}
+
+/* Declare that every member function NAME in FRIEND_TYPE
+   (which may be NULL_TREE) is a friend of type TYPE.  */
+
+static void
+add_friends (type, name, friend_type)
+     tree type, name, friend_type;
+{
+  tree typedecl = TYPE_MAIN_DECL (type);
+  tree list = DECL_FRIENDLIST (typedecl);
+
+  while (list)
+    {
+      if (name == TREE_PURPOSE (list))
+       {
+         tree friends = TREE_VALUE (list);
+         while (friends && TREE_PURPOSE (friends) != friend_type)
+           friends = TREE_CHAIN (friends);
+         if (friends)
+           if (friend_type)
+             warning ("method `%s::%s' is already a friend of class",
+                      TYPE_NAME_STRING (friend_type),
+                      IDENTIFIER_POINTER (name));
+           else
+             warning ("function `%s' is already a friend of class `%s'",
+                      IDENTIFIER_POINTER (name),
+                      IDENTIFIER_POINTER (DECL_NAME (typedecl)));
+         else
+           TREE_VALUE (list) = tree_cons (friend_type, NULL_TREE,
+                                          TREE_VALUE (list));
+         return;
+       }
+      list = TREE_CHAIN (list);
+    }
+  DECL_FRIENDLIST (typedecl) =
+    tree_cons (name,
+              build_tree_list (friend_type, NULL_TREE),
+              DECL_FRIENDLIST (typedecl));
+  if (! strncmp (IDENTIFIER_POINTER (name),
+                IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]),
+                strlen (IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]))))
+    {
+      TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1;
+      sorry ("declaring \"friend operator =\" will not find \"operator = (X&)\" if it exists");
+    }
+}
+
+/* Make FRIEND_TYPE a friend class to TYPE.  If FRIEND_TYPE has already
+   been defined, we make all of its member functions friends of
+   TYPE.  If not, we make it a pending friend, which can later be added
+   when its definition is seen.  If a type is defined, then its TYPE_DECL's
+   DECL_UNDEFINED_FRIENDS contains a (possibly empty) list of friend
+   classes that are not defined.  If a type has not yet been defined,
+   then the DECL_WAITING_FRIENDS contains a list of types
+   waiting to make it their friend.  Note that these two can both
+   be in use at the same time!  */
+
+void
+make_friend_class (type, friend_type)
+     tree type, friend_type;
+{
+  tree classes;
+
+  if (IS_SIGNATURE (type))
+    {
+      error ("`friend' declaration in signature definition");
+      return;
+    }
+  if (IS_SIGNATURE (friend_type))
+    {
+      error ("signature type `%s' declared `friend'",
+            IDENTIFIER_POINTER (TYPE_IDENTIFIER (friend_type)));
+      return;
+    }
+  if (type == friend_type)
+    {
+      pedwarn ("class `%s' is implicitly friends with itself",
+              TYPE_NAME_STRING (type));
+      return;
+    }
+
+  GNU_xref_hier (TYPE_NAME_STRING (type),
+                TYPE_NAME_STRING (friend_type), 0, 0, 1);
+
+  classes = CLASSTYPE_FRIEND_CLASSES (type);
+  while (classes && TREE_VALUE (classes) != friend_type)
+    classes = TREE_CHAIN (classes);
+  if (classes)
+    warning ("class `%s' is already friends with class `%s'",
+            TYPE_NAME_STRING (TREE_VALUE (classes)), TYPE_NAME_STRING (type));
+  else
+    {
+      CLASSTYPE_FRIEND_CLASSES (type)
+       = tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
+    }
+}
+
+/* Main friend processor.  This is large, and for modularity purposes,
+   has been removed from grokdeclarator.  It returns `void_type_node'
+   to indicate that something happened, though a FIELD_DECL is
+   not returned.
+
+   CTYPE is the class this friend belongs to.
+
+   DECLARATOR is the name of the friend.
+
+   DECL is the FUNCTION_DECL that the friend is.
+
+   In case we are parsing a friend which is part of an inline
+   definition, we will need to store PARM_DECL chain that comes
+   with it into the DECL_ARGUMENTS slot of the FUNCTION_DECL.
+
+   FLAGS is just used for `grokclassfn'.
+
+   QUALS say what special qualifies should apply to the object
+   pointed to by `this'.  */
+
+tree
+do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag)
+     tree ctype, declarator, decl, parmdecls;
+     enum overload_flags flags;
+     tree quals;
+     int funcdef_flag;
+{
+  /* Every decl that gets here is a friend of something.  */
+  DECL_FRIEND_P (decl) = 1;
+
+  if (ctype)
+    {
+      tree cname = TYPE_NAME (ctype);
+      if (TREE_CODE (cname) == TYPE_DECL)
+       cname = DECL_NAME (cname);
+
+      /* A method friend.  */
+      if (TREE_CODE (decl) == FUNCTION_DECL)
+       {
+         if (flags == NO_SPECIAL && ctype && declarator == cname)
+           DECL_CONSTRUCTOR_P (decl) = 1;
+
+         /* This will set up DECL_ARGUMENTS for us.  */
+         grokclassfn (ctype, cname, decl, flags, quals);
+         if (TYPE_SIZE (ctype) != 0)
+           decl = check_classfn (ctype, decl);
+
+         if (TREE_TYPE (decl) != error_mark_node)
+           {
+             if (TYPE_SIZE (ctype))
+               add_friend (current_class_type, decl);
+             else
+               {
+                 cp_error ("member `%D' declared as friend before type `%T' defined",
+                           decl, ctype);
+               }
+           }
+       }
+      else
+       {
+         /* Possibly a bunch of method friends.  */
+
+         /* Get the class they belong to.  */
+         tree ctype = IDENTIFIER_TYPE_VALUE (cname);
+         tree fields = lookup_fnfields (TYPE_BINFO (ctype), declarator, 0);
+
+         if (fields)
+           add_friends (current_class_type, declarator, ctype);
+         else
+           error ("method `%s' is not a member of class `%s'",
+                  IDENTIFIER_POINTER (declarator),
+                  IDENTIFIER_POINTER (cname));
+         decl = void_type_node;
+       }
+    }
+  else if (TREE_CODE (decl) == FUNCTION_DECL
+          && ((IDENTIFIER_LENGTH (declarator) == 4
+               && IDENTIFIER_POINTER (declarator)[0] == 'm'
+               && ! strcmp (IDENTIFIER_POINTER (declarator), "main"))
+              || (IDENTIFIER_LENGTH (declarator) > 10
+                  && IDENTIFIER_POINTER (declarator)[0] == '_'
+                  && IDENTIFIER_POINTER (declarator)[1] == '_'
+                  && strncmp (IDENTIFIER_POINTER (declarator)+2,
+                              "builtin_", 8) == 0)))
+    {
+      /* raw "main", and builtin functions never gets overloaded,
+        but they can become friends.  */
+      add_friend (current_class_type, decl);
+      DECL_FRIEND_P (decl) = 1;
+      decl = void_type_node;
+    }
+  /* A global friend.
+     @@ or possibly a friend from a base class ?!?  */
+  else if (TREE_CODE (decl) == FUNCTION_DECL)
+    {
+      /* Friends must all go through the overload machinery,
+        even though they may not technically be overloaded.
+
+        Note that because classes all wind up being top-level
+        in their scope, their friend wind up in top-level scope as well.  */
+      DECL_ASSEMBLER_NAME (decl)
+       = build_decl_overload (declarator, TYPE_ARG_TYPES (TREE_TYPE (decl)),
+                              TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE);
+      DECL_ARGUMENTS (decl) = parmdecls;
+      if (funcdef_flag)
+       DECL_CLASS_CONTEXT (decl) = current_class_type;
+
+      /* We can call pushdecl here, because the TREE_CHAIN of this
+        FUNCTION_DECL is not needed for other purposes.  */
+      decl = pushdecl (decl);
+
+      make_decl_rtl (decl, NULL_PTR, 1);
+      add_friend (current_class_type, decl);
+
+      DECL_FRIEND_P (decl) = 1;
+    }
+  else
+    {
+      /* @@ Should be able to ingest later definitions of this function
+        before use.  */
+      tree decl = lookup_name_nonclass (declarator);
+      if (decl == NULL_TREE)
+       {
+         warning ("implicitly declaring `%s' as struct",
+                  IDENTIFIER_POINTER (declarator));
+         decl = xref_tag (record_type_node, declarator, NULL_TREE, 1);
+         decl = TYPE_MAIN_DECL (decl);
+       }
+
+      /* Allow abbreviated declarations of overloaded functions,
+        but not if those functions are really class names.  */
+      if (TREE_CODE (decl) == TREE_LIST && TREE_TYPE (TREE_PURPOSE (decl)))
+       {
+         warning ("`friend %s' archaic, use `friend class %s' instead",
+                  IDENTIFIER_POINTER (declarator),
+                  IDENTIFIER_POINTER (declarator));
+         decl = TREE_TYPE (TREE_PURPOSE (decl));
+       }
+
+      if (TREE_CODE (decl) == TREE_LIST)
+       add_friends (current_class_type, TREE_PURPOSE (decl), NULL_TREE);
+      else
+       make_friend_class (current_class_type, TREE_TYPE (decl));
+      decl = void_type_node;
+    }
+  return decl;
+}
index 7da2d24..4e1785d 100644 (file)
@@ -19,7 +19,6 @@ along with GNU CC; see the file COPYING.  If not, write to
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
-
 /* High-level class interface.  */
 
 #include "config.h"
@@ -52,8 +51,6 @@ static void expand_aggr_init_1 PROTO((tree, tree, tree, tree, int, int));
 static void expand_virtual_init PROTO((tree, tree));
 tree expand_vec_init ();
 
-static void add_friend (), add_friends ();
-
 /* Cache _builtin_new and _builtin_delete exprs.  */
 static tree BIN, BID, BIVN, BIVD;
 
@@ -491,13 +488,9 @@ static tree
 build_partial_cleanup_for (binfo)
      tree binfo;
 {
-  tree expr = convert_pointer_to_real (binfo,
-                                      build_unary_op (ADDR_EXPR, current_class_ref, 0));
-
-  return build_delete (TREE_TYPE (expr),
-                      expr,
-                      integer_zero_node,
-                      LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
+  return build_scoped_method_call
+    (current_class_ref, binfo, dtor_identifier,
+     build_tree_list (NULL_TREE, integer_zero_node));
 }
 
 /* Perform whatever initializations have yet to be done on the base
@@ -1452,7 +1445,7 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags)
 
       if (TREE_CODE (init) != TREE_LIST)
        {
-         if (TREE_CODE (init_type) == ERROR_MARK)
+         if (init_type == error_mark_node)
            return;
 
          /* This happens when we use C++'s functional cast notation.
@@ -2186,7 +2179,7 @@ decl_constant_value (decl)
       && ! pedantic
 #endif /* 0 */
       && DECL_INITIAL (decl) != 0
-      && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK
+      && DECL_INITIAL (decl) != error_mark_node
       /* This is invalid if initial value is not constant.
         If it has either a function call, a memory reference,
         or a variable, then re-evaluating it could give different results.  */
@@ -2204,408 +2197,12 @@ decl_constant_value (decl)
   return decl;
 }
 \f
-/* Friend handling routines.  */
-/* Friend data structures:
-
-   Lists of friend functions come from TYPE_DECL nodes.  Since all
-   aggregate types are automatically typedef'd, these nodes are guaranteed
-   to exist.
-
-   The TREE_PURPOSE of a friend list is the name of the friend,
-   and its TREE_VALUE is another list.
-
-   For each element of that list, either the TREE_VALUE or the TREE_PURPOSE
-   will be filled in, but not both.  The TREE_VALUE of that list is an
-   individual function which is a friend.  The TREE_PURPOSE of that list
-   indicates a type in which all functions by that name are friends.
-
-   Lists of friend classes come from _TYPE nodes.  Love that consistency
-   thang.  */
-
-int
-is_friend_type (type1, type2)
-     tree type1, type2;
-{
-  return is_friend (type1, type2);
-}
-
-int
-is_friend (type, supplicant)
-     tree type, supplicant;
-{
-  int declp;
-  register tree list;
-
-  if (supplicant == NULL_TREE || type == NULL_TREE)
-    return 0;
-
-  declp = (TREE_CODE_CLASS (TREE_CODE (supplicant)) == 'd');
-
-  if (declp)
-    /* It's a function decl.  */
-    {
-      tree list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type));
-      tree name = DECL_NAME (supplicant);
-      tree ctype;
-
-      if (DECL_FUNCTION_MEMBER_P (supplicant))
-       ctype = DECL_CLASS_CONTEXT (supplicant);
-      else
-       ctype = NULL_TREE;
-
-      for (; list ; list = TREE_CHAIN (list))
-       {
-         if (name == TREE_PURPOSE (list))
-           {
-             tree friends = TREE_VALUE (list);
-             for (; friends ; friends = TREE_CHAIN (friends))
-               {
-                 if (ctype == TREE_PURPOSE (friends))
-                   return 1;
-                 if (comptypes (TREE_TYPE (supplicant),
-                                TREE_TYPE (TREE_VALUE (friends)), 1))
-                   return 1;
-               }
-             break;
-           }
-       }
-    }
-  else
-    /* It's a type.  */
-    {
-      if (type == supplicant)
-       return 1;
-      
-      list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_MAIN_DECL (type)));
-      for (; list ; list = TREE_CHAIN (list))
-       if (supplicant == TREE_VALUE (list))
-         return 1;
-    }      
-
-  {
-    tree context;
-
-    if (! declp)
-      {
-       /* Are we a nested or local class?  If so, we aren't friends
-           with the CONTEXT.  */
-       if (IS_AGGR_TYPE (supplicant))
-         context = NULL_TREE;
-       else
-         context = DECL_CONTEXT (TYPE_MAIN_DECL (supplicant));
-      }
-    else if (DECL_FUNCTION_MEMBER_P (supplicant))
-      context = DECL_CLASS_CONTEXT (supplicant);
-    else
-      context = NULL_TREE;
-
-    if (context)
-      return is_friend (type, context);
-  }
-
-  return 0;
-}
-
-/* Add a new friend to the friends of the aggregate type TYPE.
-   DECL is the FUNCTION_DECL of the friend being added.  */
-
-static void
-add_friend (type, decl)
-     tree type, decl;
-{
-  tree typedecl = TYPE_MAIN_DECL (type);
-  tree list = DECL_FRIENDLIST (typedecl);
-  tree name = DECL_NAME (decl);
-
-  while (list)
-    {
-      if (name == TREE_PURPOSE (list))
-       {
-         tree friends = TREE_VALUE (list);
-         for (; friends ; friends = TREE_CHAIN (friends))
-           {
-             if (decl == TREE_VALUE (friends))
-               {
-                 cp_warning ("`%D' is already a friend of class `%T'",
-                             decl, type);
-                 cp_warning_at ("previous friend declaration of `%D'",
-                                TREE_VALUE (friends));
-                 return;
-               }
-           }
-         TREE_VALUE (list) = tree_cons (error_mark_node, decl,
-                                        TREE_VALUE (list));
-         return;
-       }
-      list = TREE_CHAIN (list);
-    }
-  DECL_FRIENDLIST (typedecl)
-    = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl),
-                DECL_FRIENDLIST (typedecl));
-  if (DECL_NAME (decl) == ansi_opname[(int) MODIFY_EXPR])
-    {
-      tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
-      TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1;
-      if (parmtypes && TREE_CHAIN (parmtypes))
-       {
-         tree parmtype = TREE_VALUE (TREE_CHAIN (parmtypes));
-         if (TREE_CODE (parmtype) == REFERENCE_TYPE
-             && TREE_TYPE (parmtypes) == TREE_TYPE (typedecl))
-           TYPE_HAS_ASSIGN_REF (TREE_TYPE (typedecl)) = 1;
-       }
-    }
-}
-
-/* Declare that every member function NAME in FRIEND_TYPE
-   (which may be NULL_TREE) is a friend of type TYPE.  */
-
-static void
-add_friends (type, name, friend_type)
-     tree type, name, friend_type;
-{
-  tree typedecl = TYPE_MAIN_DECL (type);
-  tree list = DECL_FRIENDLIST (typedecl);
-
-  while (list)
-    {
-      if (name == TREE_PURPOSE (list))
-       {
-         tree friends = TREE_VALUE (list);
-         while (friends && TREE_PURPOSE (friends) != friend_type)
-           friends = TREE_CHAIN (friends);
-         if (friends)
-           if (friend_type)
-             warning ("method `%s::%s' is already a friend of class",
-                      TYPE_NAME_STRING (friend_type),
-                      IDENTIFIER_POINTER (name));
-           else
-             warning ("function `%s' is already a friend of class `%s'",
-                      IDENTIFIER_POINTER (name),
-                      IDENTIFIER_POINTER (DECL_NAME (typedecl)));
-         else
-           TREE_VALUE (list) = tree_cons (friend_type, NULL_TREE,
-                                          TREE_VALUE (list));
-         return;
-       }
-      list = TREE_CHAIN (list);
-    }
-  DECL_FRIENDLIST (typedecl) =
-    tree_cons (name,
-              build_tree_list (friend_type, NULL_TREE),
-              DECL_FRIENDLIST (typedecl));
-  if (! strncmp (IDENTIFIER_POINTER (name),
-                IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]),
-                strlen (IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]))))
-    {
-      TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1;
-      sorry ("declaring \"friend operator =\" will not find \"operator = (X&)\" if it exists");
-    }
-}
-
-/* Make FRIEND_TYPE a friend class to TYPE.  If FRIEND_TYPE has already
-   been defined, we make all of its member functions friends of
-   TYPE.  If not, we make it a pending friend, which can later be added
-   when its definition is seen.  If a type is defined, then its TYPE_DECL's
-   DECL_UNDEFINED_FRIENDS contains a (possibly empty) list of friend
-   classes that are not defined.  If a type has not yet been defined,
-   then the DECL_WAITING_FRIENDS contains a list of types
-   waiting to make it their friend.  Note that these two can both
-   be in use at the same time!  */
-
-void
-make_friend_class (type, friend_type)
-     tree type, friend_type;
-{
-  tree classes;
-
-  if (IS_SIGNATURE (type))
-    {
-      error ("`friend' declaration in signature definition");
-      return;
-    }
-  if (IS_SIGNATURE (friend_type))
-    {
-      error ("signature type `%s' declared `friend'",
-            IDENTIFIER_POINTER (TYPE_IDENTIFIER (friend_type)));
-      return;
-    }
-  if (type == friend_type)
-    {
-      pedwarn ("class `%s' is implicitly friends with itself",
-              TYPE_NAME_STRING (type));
-      return;
-    }
-
-  GNU_xref_hier (TYPE_NAME_STRING (type),
-                TYPE_NAME_STRING (friend_type), 0, 0, 1);
-
-  classes = CLASSTYPE_FRIEND_CLASSES (type);
-  while (classes && TREE_VALUE (classes) != friend_type)
-    classes = TREE_CHAIN (classes);
-  if (classes)
-    warning ("class `%s' is already friends with class `%s'",
-            TYPE_NAME_STRING (TREE_VALUE (classes)), TYPE_NAME_STRING (type));
-  else
-    {
-      CLASSTYPE_FRIEND_CLASSES (type)
-       = tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
-    }
-}
-
-/* Main friend processor.  This is large, and for modularity purposes,
-   has been removed from grokdeclarator.  It returns `void_type_node'
-   to indicate that something happened, though a FIELD_DECL is
-   not returned.
-
-   CTYPE is the class this friend belongs to.
-
-   DECLARATOR is the name of the friend.
-
-   DECL is the FUNCTION_DECL that the friend is.
-
-   In case we are parsing a friend which is part of an inline
-   definition, we will need to store PARM_DECL chain that comes
-   with it into the DECL_ARGUMENTS slot of the FUNCTION_DECL.
-
-   FLAGS is just used for `grokclassfn'.
-
-   QUALS say what special qualifies should apply to the object
-   pointed to by `this'.  */
-
-tree
-do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag)
-     tree ctype, declarator, decl, parmdecls;
-     enum overload_flags flags;
-     tree quals;
-     int funcdef_flag;
-{
-  /* Every decl that gets here is a friend of something.  */
-  DECL_FRIEND_P (decl) = 1;
-
-  if (ctype)
-    {
-      tree cname = TYPE_NAME (ctype);
-      if (TREE_CODE (cname) == TYPE_DECL)
-       cname = DECL_NAME (cname);
-
-      /* A method friend.  */
-      if (TREE_CODE (decl) == FUNCTION_DECL)
-       {
-         if (flags == NO_SPECIAL && ctype && declarator == cname)
-           DECL_CONSTRUCTOR_P (decl) = 1;
-
-         /* This will set up DECL_ARGUMENTS for us.  */
-         grokclassfn (ctype, cname, decl, flags, quals);
-         if (TYPE_SIZE (ctype) != 0)
-           decl = check_classfn (ctype, decl);
-
-         if (TREE_TYPE (decl) != error_mark_node)
-           {
-             if (TYPE_SIZE (ctype))
-               add_friend (current_class_type, decl);
-             else
-               {
-                 cp_error ("member `%D' declared as friend before type `%T' defined",
-                           decl, ctype);
-               }
-           }
-       }
-      else
-       {
-         /* Possibly a bunch of method friends.  */
-
-         /* Get the class they belong to.  */
-         tree ctype = IDENTIFIER_TYPE_VALUE (cname);
-         tree fields = lookup_fnfields (TYPE_BINFO (ctype), declarator, 0);
-
-         if (fields)
-           add_friends (current_class_type, declarator, ctype);
-         else
-           error ("method `%s' is not a member of class `%s'",
-                  IDENTIFIER_POINTER (declarator),
-                  IDENTIFIER_POINTER (cname));
-         decl = void_type_node;
-       }
-    }
-  else if (TREE_CODE (decl) == FUNCTION_DECL
-          && ((IDENTIFIER_LENGTH (declarator) == 4
-               && IDENTIFIER_POINTER (declarator)[0] == 'm'
-               && ! strcmp (IDENTIFIER_POINTER (declarator), "main"))
-              || (IDENTIFIER_LENGTH (declarator) > 10
-                  && IDENTIFIER_POINTER (declarator)[0] == '_'
-                  && IDENTIFIER_POINTER (declarator)[1] == '_'
-                  && strncmp (IDENTIFIER_POINTER (declarator)+2,
-                              "builtin_", 8) == 0)))
-    {
-      /* raw "main", and builtin functions never gets overloaded,
-        but they can become friends.  */
-      add_friend (current_class_type, decl);
-      DECL_FRIEND_P (decl) = 1;
-      decl = void_type_node;
-    }
-  /* A global friend.
-     @@ or possibly a friend from a base class ?!?  */
-  else if (TREE_CODE (decl) == FUNCTION_DECL)
-    {
-      /* Friends must all go through the overload machinery,
-        even though they may not technically be overloaded.
-
-        Note that because classes all wind up being top-level
-        in their scope, their friend wind up in top-level scope as well.  */
-      DECL_ASSEMBLER_NAME (decl)
-       = build_decl_overload (declarator, TYPE_ARG_TYPES (TREE_TYPE (decl)),
-                              TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE);
-      DECL_ARGUMENTS (decl) = parmdecls;
-      if (funcdef_flag)
-       DECL_CLASS_CONTEXT (decl) = current_class_type;
-
-      /* We can call pushdecl here, because the TREE_CHAIN of this
-        FUNCTION_DECL is not needed for other purposes.  */
-      decl = pushdecl (decl);
-
-      make_decl_rtl (decl, NULL_PTR, 1);
-      add_friend (current_class_type, decl);
-
-      DECL_FRIEND_P (decl) = 1;
-    }
-  else
-    {
-      /* @@ Should be able to ingest later definitions of this function
-        before use.  */
-      tree decl = lookup_name_nonclass (declarator);
-      if (decl == NULL_TREE)
-       {
-         warning ("implicitly declaring `%s' as struct",
-                  IDENTIFIER_POINTER (declarator));
-         decl = xref_tag (record_type_node, declarator, NULL_TREE, 1);
-         decl = TYPE_MAIN_DECL (decl);
-       }
-
-      /* Allow abbreviated declarations of overloaded functions,
-        but not if those functions are really class names.  */
-      if (TREE_CODE (decl) == TREE_LIST && TREE_TYPE (TREE_PURPOSE (decl)))
-       {
-         warning ("`friend %s' archaic, use `friend class %s' instead",
-                  IDENTIFIER_POINTER (declarator),
-                  IDENTIFIER_POINTER (declarator));
-         decl = TREE_TYPE (TREE_PURPOSE (decl));
-       }
-
-      if (TREE_CODE (decl) == TREE_LIST)
-       add_friends (current_class_type, TREE_PURPOSE (decl), NULL_TREE);
-      else
-       make_friend_class (current_class_type, TREE_TYPE (decl));
-      decl = void_type_node;
-    }
-  return decl;
-}
-\f
 /* Common subroutines of build_new and build_vec_delete.  */
 
 /* Common interface for calling "builtin" functions that are not
    really builtin.  */
 
-tree
+static tree
 build_builtin_call (type, node, arglist)
      tree type;
      tree node;
@@ -3661,11 +3258,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
       else
        addr = convert_force (build_pointer_type (type), addr, 0);
 
-      if (TREE_CODE (addr) == NOP_EXPR
-         && TREE_OPERAND (addr, 0) == current_class_ptr)
-       ref = current_class_ref;
-      else
-       ref = build_indirect_ref (addr, NULL_PTR);
+      ref = build_indirect_ref (addr, NULL_PTR);
       ptr = 0;
     }
 
@@ -3699,6 +3292,8 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
       tree dtor = DECL_MAIN_VARIANT (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 1));
       tree passed_auto_delete;
       tree do_delete = NULL_TREE;
+      tree ifexp;
+      int nonnull;
 
       if (use_global_delete)
        {
@@ -3718,108 +3313,29 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
       else
        passed_auto_delete = auto_delete;
 
-      if (flags & LOOKUP_PROTECT)
-       {
-         tree access;
-         tree basetypes = NULL_TREE;
-         if (current_class_type != NULL_TREE)
-           basetypes = get_binfo (type, current_class_type, 0);
-         if (basetypes == NULL_TREE)
-           basetypes = TYPE_BINFO (type);
-         access = compute_access (basetypes, dtor);
-
-         if (access == access_private_node)
-           {
-             if (flags & LOOKUP_COMPLAIN)
-               cp_error ("destructor for type `%T' is private in this scope", type);
-             return error_mark_node;
-           }
-         else if (access == access_protected_node)
-           {
-             if (flags & LOOKUP_COMPLAIN)
-               cp_error ("destructor for type `%T' is protected in this scope", type);
-             return error_mark_node;
-           }
-       }
-
-      /* Once we are in a destructor, try not going through
-        the virtual function table to find the next destructor.  */
-      if (DECL_VINDEX (dtor)
-         && ! (flags & LOOKUP_NONVIRTUAL)
-         && TREE_CODE (auto_delete) != PARM_DECL
-         && (ptr == 1 || ! resolves_to_fixed_type_p (ref, 0)))
-       {
-         tree binfo, basetype;
-         /* The code below is probably all broken.  See call.c for the
-            complete right way to do this. this offsets may not be right
-            in the below.  (mrs) */
-         /* This destructor must be called via virtual function table.  */
-         dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (DECL_CONTEXT (dtor)), 1);
-         basetype = DECL_CLASS_CONTEXT (dtor);
-         binfo = get_binfo (basetype,
-                            TREE_TYPE (TREE_TYPE (TREE_VALUE (parms))),
-                            0);
-         expr = convert_pointer_to_real (binfo, TREE_VALUE (parms));
-         if (expr != TREE_VALUE (parms))
-           {
-             expr = fold (expr);
-             ref = build_indirect_ref (expr, NULL_PTR);
-             TREE_VALUE (parms) = expr;
-           }
-         function = build_vfn_ref (&TREE_VALUE (parms), ref, DECL_VINDEX (dtor));
-         if (function == error_mark_node)
-           return error_mark_node;
-         TREE_TYPE (function) = build_pointer_type (TREE_TYPE (dtor));
-         TREE_CHAIN (parms) = build_tree_list (NULL_TREE, passed_auto_delete);
-         expr = build_function_call (function, parms);
-         if (do_delete)
-           expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete);
-         if (ptr && (flags & LOOKUP_DESTRUCTOR) == 0)
-           {
-             /* Handle the case where a virtual destructor is
-                being called on an item that is 0.
+      expr = build_method_call
+       (ref, dtor_identifier, build_tree_list (NULL_TREE, passed_auto_delete),
+        NULL_TREE, flags);
 
-                @@ Does this really need to be done?  */
-             tree ifexp = build_binary_op(NE_EXPR, addr, integer_zero_node,1);
+      if (do_delete)
+       expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete);
 
-             expr = build (COND_EXPR, void_type_node,
-                           ifexp, expr, void_zero_node);
-           }
-       }
+      if (flags & LOOKUP_DESTRUCTOR)
+       /* Explicit destructor call; don't check for null pointer.  */
+       ifexp = integer_one_node;
       else
-       {
-         tree ifexp;
-
-         if ((flags & LOOKUP_DESTRUCTOR)
-             || TREE_CODE (ref) == VAR_DECL
-             || TREE_CODE (ref) == PARM_DECL
-             || TREE_CODE (ref) == COMPONENT_REF
-             || TREE_CODE (ref) == ARRAY_REF)
-           /* These can't be 0.  */
-           ifexp = integer_one_node;
-         else
-           /* Handle the case where a non-virtual destructor is
-              being called on an item that is 0.  */
-           ifexp = build_binary_op (NE_EXPR, addr, integer_zero_node, 1);
+       /* Handle deleting a null pointer.  */
+       ifexp = fold (build_binary_op (NE_EXPR, addr, integer_zero_node, 1));
 
-         /* Used to mean that this destructor was known to be empty,
-            but that's now obsolete.  */
-         my_friendly_assert (DECL_INITIAL (dtor) != void_type_node, 221);
+      if (ifexp != integer_one_node)
+       expr = build (COND_EXPR, void_type_node,
+                     ifexp, expr, void_zero_node);
 
-         TREE_CHAIN (parms) = build_tree_list (NULL_TREE, passed_auto_delete);
-         expr = build_function_call (dtor, parms);
-         if (do_delete)
-           expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete);
-
-         if (ifexp != integer_one_node)
-           expr = build (COND_EXPR, void_type_node,
-                         ifexp, expr, void_zero_node);
-       }
       return expr;
     }
   else
     {
-      /* This can get visibilities wrong.  */
+      /* We only get here from finish_function for a destructor.  */
       tree binfos = BINFO_BASETYPES (TYPE_BINFO (type));
       int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
       tree base_binfo = n_baseclasses > 0 ? TREE_VEC_ELT (binfos, 0) : NULL_TREE;
@@ -3827,39 +3343,12 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
       tree parent_auto_delete = auto_delete;
       tree cond;
 
-      /* If this type does not have a destructor, but does have
-        operator delete, call the parent parent destructor (if any),
-        but let this node do the deleting.  Otherwise, it is ok
-        to let the parent destructor do the deleting.  */
-      if (TYPE_GETS_REG_DELETE (type) && !use_global_delete)
-       {
-         parent_auto_delete = integer_zero_node;
-         if (auto_delete == integer_zero_node)
-           cond = NULL_TREE;
-         else
-           {
-             tree virtual_size;
-
-               /* This is probably wrong. It should be the size of the
-                  virtual object being deleted.  */
-             virtual_size = c_sizeof_nowarn (type);
-
-             expr = build_opfncall (DELETE_EXPR, LOOKUP_NORMAL, addr,
-                                    virtual_size, NULL_TREE);
-             if (expr == error_mark_node)
-               return error_mark_node;
-             if (auto_delete != integer_one_node)
-               cond = build (COND_EXPR, void_type_node,
-                             build (BIT_AND_EXPR, integer_type_node,
-                                    auto_delete, integer_one_node),
-                             expr, void_zero_node);
-             else
-               cond = expr;
-           }
-       }
+      /* If we have member delete or vbases, we call delete in
+        finish_function.  */
+      if (auto_delete == integer_zero_node)
+       cond = NULL_TREE;
       else if (base_binfo == NULL_TREE
-              || (TREE_VIA_VIRTUAL (base_binfo) == 0
-                  && ! TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo))))
+              || ! TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo)))
        {
          cond = build (COND_EXPR, void_type_node,
                        build (BIT_AND_EXPR, integer_type_node, auto_delete, integer_one_node),
@@ -3884,8 +3373,9 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
          else
            this_auto_delete = integer_zero_node;
 
-         expr = build_delete (build_pointer_type (BINFO_TYPE (base_binfo)), addr,
-                              this_auto_delete, flags, 0);
+         expr = build_scoped_method_call
+           (ref, base_binfo, dtor_identifier,
+            build_tree_list (NULL_TREE, this_auto_delete));
          exprstmt = tree_cons (NULL_TREE, expr, exprstmt);
        }
 
@@ -3897,13 +3387,9 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
              || TREE_VIA_VIRTUAL (base_binfo))
            continue;
 
-         /* May be zero offset if other baseclasses are virtual.  */
-         expr = fold (build (PLUS_EXPR, build_pointer_type (BINFO_TYPE (base_binfo)),
-                             addr, BINFO_OFFSET (base_binfo)));
-
-         expr = build_delete (build_pointer_type (BINFO_TYPE (base_binfo)), expr,
-                              integer_zero_node,
-                              flags, 0);
+         expr = build_scoped_method_call
+           (ref, base_binfo, dtor_identifier,
+            build_tree_list (NULL_TREE, integer_zero_node));
 
          exprstmt = tree_cons (NULL_TREE, expr, exprstmt);
        }
index 451f598..befb5a1 100644 (file)
@@ -271,7 +271,7 @@ char *token_buffer;         /* Pointer to token buffer.
 
 #include "hash.h"
 \f
-int check_newline ();
+static int check_newline ();
 
 /* Nonzero tells yylex to ignore \ in string constants.  */
 static int ignore_escape_flag = 0;
@@ -392,12 +392,14 @@ init_filename_times ()
    Stuck this hack in to get the files open correctly; this is called
    in place of init_lex if we are an unexec'd binary.    */
 
+#if 0
 void
 reinit_lang_specific ()
 {
   init_filename_times ();
   reinit_search_statistics ();
 }
+#endif
 
 int *init_parse ();
 
@@ -1091,7 +1093,7 @@ interface_strcmp (s)
   return 1;
 }
 
-void
+static void
 set_typedecl_interface_info (prev, vars)
      tree prev, vars;
 {
@@ -1103,7 +1105,7 @@ set_typedecl_interface_info (prev, vars)
     = interface_strcmp (FILE_NAME_NONDIRECTORY (DECL_SOURCE_FILE (vars)));
 }
 
-int
+static int
 set_vardecl_interface_info (prev, vars)
      tree prev, vars;
 {
@@ -1403,7 +1405,7 @@ store_pending_inline (decl, t)
   pending_inlines = t;
 }
 
-void reinit_parse_for_block ();
+static void reinit_parse_for_block PROTO((int, struct obstack *));
 
 void
 reinit_parse_for_method (yychar, decl)
@@ -1455,7 +1457,7 @@ reinit_parse_for_method (yychar, decl)
 /* Consume a block -- actually, a method beginning
    with `:' or `{' -- and save it away on the specified obstack.  */
 
-void
+static void
 reinit_parse_for_block (pyychar, obstackp)
      int pyychar;
      struct obstack *obstackp;
@@ -1900,7 +1902,7 @@ static int handle_sysv_pragma ();
 #endif
 static int handle_cp_pragma ();
 
-int
+static int
 check_newline ()
 {
   register int c;
@@ -2517,7 +2519,12 @@ do_identifier (token, parsing)
      [class.scope0] */
   if (id && current_class_type && parsing
       && TYPE_BEING_DEFINED (current_class_type)
-      && ! IDENTIFIER_CLASS_VALUE (token))
+      && ! IDENTIFIER_CLASS_VALUE (token)
+      /* Avoid breaking if we get called for a default argument that
+        refers to an overloaded method.  Eventually this will not be
+        necessary, since default arguments shouldn't be parsed until
+        after the class is complete.  (jason 3/12/97) */
+      && TREE_CODE (id) != TREE_LIST)
     pushdecl_class_level (id);
     
   if (!id || id == error_mark_node)
@@ -4158,33 +4165,6 @@ make_lang_type (code)
 }
 
 void
-copy_decl_lang_specific (decl)
-     tree decl;
-{
-  extern struct obstack *current_obstack, *saveable_obstack;
-  register int *old = (int *)DECL_LANG_SPECIFIC (decl);
-  struct obstack *obstack = current_obstack;
-  register int i = sizeof (struct lang_decl) / sizeof (int);
-  register int *pi;
-
-  if (! TREE_PERMANENT (decl))
-    obstack = saveable_obstack;
-  else
-    my_friendly_assert (obstack == &permanent_obstack, 237);
-
-  pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
-  while (i-- > 0)
-    pi[i] = old[i];
-
-  DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) pi;
-
-#ifdef GATHER_STATISTICS
-  tree_node_counts[(int)lang_decl] += 1;
-  tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl);
-#endif
-}
-
-void
 dump_time_statistics ()
 {
   register tree prev = 0, decl, next;
index 4600c5c..a9dd9d5 100644 (file)
@@ -261,28 +261,67 @@ __inline
 #endif
 void
 icat (i)
-     int i;
+     HOST_WIDE_INT i;
 {
+  unsigned HOST_WIDE_INT ui;
+
   /* Handle this case first, to go really quickly.  For many common values,
-     the result of i/10 below is 1.  */
+     the result of ui/10 below is 1.  */
   if (i == 1)
     {
       OB_PUTC ('1');
       return;
     }
 
-  if (i < 0)
+  if (i >= 0)
+    ui = i;
+  else
     {
       OB_PUTC ('m');
-      i = -i;
+      ui = -i;
+    }
+
+  if (ui >= 10)
+    icat (ui / 10);
+
+  OB_PUTC ('0' + (ui % 10));
+}
+
+static void
+dicat (lo, hi)
+     HOST_WIDE_INT lo, hi;
+{
+  unsigned HOST_WIDE_INT ulo, uhi, qlo, qhi;
+
+  if (hi >= 0)
+    {
+      uhi = hi;
+      ulo = lo;
     }
-  if (i < 10)
-    OB_PUTC ('0' + i);
   else
     {
-      icat (i / 10);
-      OB_PUTC ('0' + (i % 10));
+      uhi = (lo == 0 ? -hi : -hi-1);
+      ulo = -lo;
+    }
+  if (uhi == 0
+      && ulo < ((unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT - 1)))
+    {
+      icat (ulo);
+      return;
     }
+  /* Divide 2^HOST_WIDE_INT*uhi+ulo by 10. */
+  qhi = uhi / 10;
+  uhi = uhi % 10;
+  qlo = uhi * (((unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT - 1)) / 5);
+  qlo += ulo / 10;
+  ulo = ulo % 10;
+  ulo += uhi * (((unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT - 1)) % 5)
+        * 2;
+  qlo += ulo / 10;
+  ulo = ulo % 10;
+  /* Quotient is 2^HOST_WIDE_INT*qhi+qlo, remainder is ulo. */
+  dicat (qlo, qhi);
+  OB_PUTC ('0' + ulo);
 }
 
 static
@@ -380,17 +419,12 @@ build_overload_int (value)
   my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243);
   if (TYPE_PRECISION (TREE_TYPE (value)) == 2 * HOST_BITS_PER_WIDE_INT)
     {
-      if (tree_int_cst_lt (value, integer_zero_node))
-       {
-         OB_PUTC ('m');
-         value = build_int_2 (~ TREE_INT_CST_LOW (value),
-                              - TREE_INT_CST_HIGH (value));
-       }
       if (TREE_INT_CST_HIGH (value)
          != (TREE_INT_CST_LOW (value) >> (HOST_BITS_PER_WIDE_INT - 1)))
        {
          /* need to print a DImode value in decimal */
-         sorry ("conversion of long long as PT parameter");
+         dicat (TREE_INT_CST_LOW (value), TREE_INT_CST_HIGH (value));
+         return;
        }
       /* else fall through to print in smaller mode */
     }
@@ -440,54 +474,73 @@ build_overload_value (type, value)
        numeric_output_need_bar = 1;
        return;
       }
-#ifndef REAL_IS_NOT_DOUBLE
     case REAL_TYPE:
       {
        REAL_VALUE_TYPE val;
        char *bufp = digit_buffer;
        extern char *index ();
 
+       pedwarn ("ANSI C++ forbids floating-point template arguments");
+
        my_friendly_assert (TREE_CODE (value) == REAL_CST, 244);
        val = TREE_REAL_CST (value);
-       if (val < 0)
+       if (REAL_VALUE_ISNAN (val))
          {
-           val = -val;
-           *bufp++ = 'm';
+           sprintf (bufp, "NaN");
          }
-       sprintf (bufp, "%e", val);
-       bufp = (char *) index (bufp, 'e');
-       if (!bufp)
-         strcat (digit_buffer, "e0");
        else
          {
-           char *p;
-           bufp++;
-           if (*bufp == '-')
+           if (REAL_VALUE_NEGATIVE (val))
              {
+               val = REAL_VALUE_NEGATE (val);
                *bufp++ = 'm';
              }
-           p = bufp;
-           if (*p == '+')
-             p++;
-           while (*p == '0')
-             p++;
-           if (*p == 0)
+           if (REAL_VALUE_ISINF (val))
              {
-               *bufp++ = '0';
-               *bufp = 0;
+               sprintf (bufp, "Infinity");
              }
-           else if (p != bufp)
+           else
              {
-               while (*p)
-                 *bufp++ = *p++;
-               *bufp = 0;
+               ereal_to_decimal (val, bufp);
+               bufp = (char *) index (bufp, 'e');
+               if (!bufp)
+                 strcat (digit_buffer, "e0");
+               else
+                 {
+                   char *p;
+                   bufp++;
+                   if (*bufp == '-')
+                     {
+                       *bufp++ = 'm';
+                     }
+                   p = bufp;
+                   if (*p == '+')
+                     p++;
+                   while (*p == '0')
+                     p++;
+                   if (*p == 0)
+                     {
+                       *bufp++ = '0';
+                       *bufp = 0;
+                     }
+                   else if (p != bufp)
+                     {
+                       while (*p)
+                         *bufp++ = *p++;
+                       *bufp = 0;
+                     }
+                 }
+#ifdef NO_DOT_IN_LABEL
+               bufp = (char *) index (bufp, '.');
+               if (bufp)
+                 *bufp = '_';
+#endif
              }
          }
        OB_PUTCP (digit_buffer);
        numeric_output_need_bar = 1;
        return;
       }
-#endif
     case POINTER_TYPE:
       if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE
          && TREE_CODE (value) != ADDR_EXPR)
@@ -1151,8 +1204,8 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
 
   if (code == COND_EXPR)
     {
-      if (TREE_CODE (xarg2) == ERROR_MARK
-         || TREE_CODE (arg3) == ERROR_MARK)
+      if (xarg2 == error_mark_node
+         || arg3 == error_mark_node)
        return error_mark_node;
     }
   if (code == COMPONENT_REF)
@@ -1468,7 +1521,7 @@ hack_identifier (value, name)
 {
   tree type;
 
-  if (TREE_CODE (value) == ERROR_MARK)
+  if (value == error_mark_node)
     {
       if (current_class_name)
        {
index ff0a139..720c041 100644 (file)
@@ -2478,10 +2478,11 @@ left_curly:
                  push_obstacks_nochange ();
                  end_temporary_allocation ();
 
-                 if (! IS_AGGR_TYPE (t))
+                 if (t == error_mark_node
+                     || ! IS_AGGR_TYPE (t))
                    {
                      t = $<ttype>0 = make_lang_type (RECORD_TYPE);
-                     TYPE_NAME (t) = get_identifier ("erroneous type");
+                     pushtag (make_anon_name (), t, 0);
                    }
                  if (TYPE_SIZE (t))
                    duplicate_tag_error (t);
index 89002d4..d0a6c76 100644 (file)
@@ -65,11 +65,12 @@ static int unify ();
 
 void pop_template_decls ();
 
-tree classtype_mangled_name ();
+static tree classtype_mangled_name ();
 static char * mangle_class_name_for_template ();
 static tree tsubst_expr_values ();
+static int comp_template_args PROTO((tree, tree));
 tree most_specialized_class PROTO((tree, tree));
-tree get_class_bindings PROTO((tree, tree, tree));
+static tree get_class_bindings PROTO((tree, tree, tree));
 tree make_temp_vec PROTO((int));
 
 /* We've got a template header coming up; push to a new level for storing
@@ -448,6 +449,11 @@ coerce_template_parms (parms, arglist, in_decl)
          /* 14.2: Other template-arguments must be constant-expressions,
             addresses of objects or functions with external linkage, or of
             static class members.  */
+         else if (IS_AGGR_TYPE (TREE_TYPE (val)))
+           {
+             cp_error ("object `%E' cannot be used as template argument", arg);
+             val = error_mark_node;
+           }
          else if (!TREE_CONSTANT (val))
            {
              cp_error ("non-const `%E' cannot be used as template argument",
@@ -504,7 +510,7 @@ coerce_template_parms (parms, arglist, in_decl)
   return vec;
 }
 
-int
+static int
 comp_template_args (oldargs, newargs)
      tree oldargs, newargs;
 {
@@ -616,7 +622,7 @@ mangle_class_name_for_template (name, parms, arglist)
   return NULL;
 }
 
-tree
+static tree
 classtype_mangled_name (t)
      tree t;
 {
@@ -968,7 +974,7 @@ extern int max_tinst_depth;
 int depth_reached = 0;
 #endif
 
-int
+static int
 push_tinst_level (d)
      tree d;
 {
@@ -2808,7 +2814,11 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts, strict)
       return 0;
 
       /* Types INTEGER_CST and MINUS_EXPR can come from array bounds.  */
+      /* Type INTEGER_CST can come from ordinary constant template args.  */
     case INTEGER_CST:
+      while (TREE_CODE (arg) == NOP_EXPR)
+       arg = TREE_OPERAND (arg, 0);
+
       if (TREE_CODE (arg) != INTEGER_CST)
        return 1;
       return !tree_int_cst_equal (parm, arg);
@@ -2993,7 +3003,7 @@ get_bindings (fn, decl)
   return 0;
 }
 
-tree
+static tree
 get_class_bindings (tparms, parms, args)
      tree tparms, parms, args;
 {
index ec7a52b..f5f372c 100644 (file)
@@ -412,10 +412,10 @@ pop_memoized_context (use_old)
 /* Get a virtual binfo that is found inside BINFO's hierarchy that is
    the same type as the type given in PARENT.  To be optimal, we want
    the first one that is found by going through the least number of
-   virtual bases.  DEPTH should be NULL_PTR.  */
+   virtual bases.  */
 
 static tree
-get_vbase (parent, binfo, depth)
+get_vbase_1 (parent, binfo, depth)
      tree parent, binfo;
      unsigned int *depth;
 {
@@ -423,12 +423,6 @@ get_vbase (parent, binfo, depth)
   int i, n_baselinks;
   tree rval = NULL_TREE;
 
-  if (depth == 0)
-    {
-      unsigned int d = (unsigned int)-1;
-      return get_vbase (parent, binfo, &d);
-    }
-
   if (BINFO_TYPE (binfo) == parent && TREE_VIA_VIRTUAL (binfo))
     {
       *depth = 0;
@@ -449,7 +443,7 @@ get_vbase (parent, binfo, depth)
       if (*depth == 0)
        break;
 
-      nrval = get_vbase (parent, base_binfo, depth);
+      nrval = get_vbase_1 (parent, base_binfo, depth);
       if (nrval)
        rval = nrval;
     }
@@ -457,16 +451,25 @@ get_vbase (parent, binfo, depth)
   return rval;
 }
 
+tree
+get_vbase (parent, binfo)
+     tree parent;
+     tree binfo;
+{
+  unsigned int d = (unsigned int)-1;
+  return get_vbase_1 (parent, binfo, &d);
+}
+
 /* Convert EXPR to a virtual base class of type TYPE.  We know that
    EXPR is a non-null POINTER_TYPE to RECORD_TYPE.  We also know that
    the type of what expr points to has a virtual base of type TYPE.  */
 
-tree
+static tree
 convert_pointer_to_vbase (type, expr)
      tree type;
      tree expr;
 {
-  tree vb = get_vbase (type, TYPE_BINFO (TREE_TYPE (TREE_TYPE (expr))), NULL_PTR);
+  tree vb = get_vbase (type, TYPE_BINFO (TREE_TYPE (TREE_TYPE (expr))));
   return convert_pointer_to_real (vb, expr);
 }
 
@@ -3158,7 +3161,6 @@ note_debug_info_needed (type)
 /* Subroutines of push_class_decls ().  */
 
 /* Add in a decl to the envelope.  */
-
 static void
 envelope_add_decl (type, decl, values)
      tree type, decl, *values;
index 7e53de6..2a5efcd 100644 (file)
@@ -37,6 +37,8 @@ extern void sorry ();
 extern void compiler_error ();
 extern void make_decl_rtl                      PROTO((tree, char *, int));
 
+static tree build_sptr_ref                     PROTO((tree));
+
 /* Used to help generate globally unique names for signature tables.  */
 
 static int global_sigtable_name_counter;
@@ -1047,7 +1049,7 @@ build_optr_ref (instance)
 /* Create a COMPONENT_REF expression for referencing the SPTR field
    of a signature pointer or reference.  */
 
-tree
+static tree
 build_sptr_ref (instance)
      tree instance;
 {
index df732f5..aefce65 100644 (file)
@@ -404,7 +404,7 @@ build_cplus_method_type (basetype, rettype, argtypes)
   return t;
 }
 
-tree
+static tree
 build_cplus_array_type_1 (elt_type, index_type)
      tree elt_type;
      tree index_type;
@@ -1319,41 +1319,6 @@ get_first_fn (from)
   return TREE_VALUE (from);
 }
 
-tree
-fnaddr_from_vtable_entry (entry)
-     tree entry;
-{
-  if (flag_vtable_thunks)
-    {
-      tree func = entry;
-      if (TREE_CODE (func) == ADDR_EXPR)
-       func = TREE_OPERAND (func, 0);
-      if (TREE_CODE (func) == THUNK_DECL)
-       return DECL_INITIAL (func);
-      else
-       return entry;
-    }
-  else
-    return TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (entry))));
-}
-
-tree
-function_arg_chain (t)
-     tree t;
-{
-  return TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (t)));
-}
-
-int
-promotes_to_aggr_type (t, code)
-     tree t;
-     enum tree_code code;
-{
-  if (TREE_CODE (t) == code)
-    t = TREE_TYPE (t);
-  return IS_AGGR_TYPE (t);
-}
-
 int
 is_aggr_type_2 (t1, t2)
      tree t1, t2;
index 10fbdef..a734c01 100644 (file)
@@ -44,18 +44,17 @@ int mark_addressable PROTO((tree));
 static tree convert_for_assignment PROTO((tree, tree, char*, tree, int));
 /* static */ tree convert_for_initialization PROTO((tree, tree, tree, int, char*, tree, int));
 extern tree shorten_compare ();
-extern void binary_op_error ();
 static tree pointer_int_sum PROTO((enum tree_code, register tree, register tree));
 static tree pointer_diff PROTO((register tree, register tree));
+static int comp_target_parms PROTO((tree, tree, int));
+static int comp_ptr_ttypes_const PROTO((tree, tree));
+static int comp_ptr_ttypes_reinterpret PROTO((tree, tree));
 #if 0
 static tree convert_sequence ();
 #endif
 /* static */ tree unary_complex_lvalue PROTO((enum tree_code, tree));
 static tree get_delta_difference PROTO((tree, tree, int));
 
-extern rtx original_result_rtx;
-extern int warn_synth;
-
 /* Return the target type of TYPE, which meas return T for:
    T*, T&, T[], T (...), and otherwise, just T.  */
 
@@ -942,7 +941,7 @@ comp_target_types (ttl, ttr, nptrs)
    If there is not a unique most-derived base type, this function
    returns ERROR_MARK_NODE.  */
 
-tree
+static tree
 common_base_type (tt1, tt2)
      tree tt1, tt2;
 {
@@ -1049,7 +1048,7 @@ compparms (parms1, parms2, strict)
 /* This really wants return whether or not parameter type lists
    would make their owning functions assignment compatible or not.  */
 
-int
+static int
 comp_target_parms (parms1, parms2, strict)
      tree parms1, parms2;
      int strict;
@@ -2071,16 +2070,6 @@ build_indirect_ref (ptr, errorstring)
    will inherit the type of the array, which will be some pointer type.  */
 
 tree
-build_x_array_ref (array, idx)
-     tree array, idx;
-{
-  tree rval = build_opfncall (ARRAY_REF, LOOKUP_NORMAL, array, idx, NULL_TREE);
-  if (rval)
-    return rval;
-  return build_array_ref (array, idx);
-}
-
-tree
 build_array_ref (array, idx)
      tree array, idx;
 {
@@ -5365,8 +5354,7 @@ build_const_cast (type, expr)
 
 tree
 build_c_cast (type, expr)
-     register tree type;
-     tree expr;
+     tree type, expr;
 {
   register tree value = expr;
 
@@ -5436,7 +5424,6 @@ build_c_cast (type, expr)
   else
     {
       tree otype;
-      int flag;
 
       /* Convert functions and arrays to pointers and
         convert references to their expanded types,
@@ -5506,7 +5493,7 @@ build_c_cast (type, expr)
            value = decl_constant_value (value);
 
          ovalue = value;
-         value = convert_force (type, value, flag);
+         value = convert_force (type, value, CONV_C_CAST);
 
          /* Ignore any integer overflow caused by the cast.  */
          if (TREE_CODE (value) == INTEGER_CST)
@@ -5580,7 +5567,7 @@ build_modify_expr (lhs, modifycode, rhs)
   tree olhs = lhs;
 
   /* Avoid duplicate error messages from operands that had errors.  */
-  if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK)
+  if (lhs == error_mark_node || rhs == error_mark_node)
     return error_mark_node;
 
   /* Types that aren't fully specified cannot be used in assignments.  */
@@ -5616,14 +5603,14 @@ build_modify_expr (lhs, modifycode, rhs)
     case COMPOUND_EXPR:
       newrhs = build_modify_expr (TREE_OPERAND (lhs, 1),
                                  modifycode, rhs);
-      if (TREE_CODE (newrhs) == ERROR_MARK)
+      if (newrhs == error_mark_node)
        return error_mark_node;
       return build (COMPOUND_EXPR, lhstype,
                    TREE_OPERAND (lhs, 0), newrhs);
 
     case MODIFY_EXPR:
       newrhs = build_modify_expr (TREE_OPERAND (lhs, 0), modifycode, rhs);
-      if (TREE_CODE (newrhs) == ERROR_MARK)
+      if (newrhs == error_mark_node)
        return error_mark_node;
       return build (COMPOUND_EXPR, lhstype, lhs, newrhs);
 
@@ -5640,7 +5627,7 @@ build_modify_expr (lhs, modifycode, rhs)
                                                       modifycode, rhs),
                                    build_modify_expr (convert (TREE_TYPE (lhs), TREE_OPERAND (lhs, 2)),
                                                       modifycode, rhs));
-       if (TREE_CODE (cond) == ERROR_MARK)
+       if (cond == error_mark_node)
          return cond;
        /* Make sure the code to compute the rhs comes out
           before the split.  */
@@ -5796,7 +5783,7 @@ build_modify_expr (lhs, modifycode, rhs)
        result = build_modify_expr (inner_lhs, NOP_EXPR,
                                    convert (TREE_TYPE (inner_lhs),
                                             convert (lhstype, newrhs)));
-       if (TREE_CODE (result) == ERROR_MARK)
+       if (result == error_mark_node)
          return result;
        return convert (TREE_TYPE (lhs), result);
       }
@@ -5983,7 +5970,7 @@ build_modify_expr (lhs, modifycode, rhs)
                        TREE_OPERAND (newrhs, 0));
     }
 
-  if (TREE_CODE (newrhs) == ERROR_MARK)
+  if (newrhs == error_mark_node)
     return error_mark_node;
 
   if (TREE_CODE (newrhs) == COND_EXPR)
@@ -7321,7 +7308,7 @@ c_expand_start_case (exp)
 /* CONSTP remembers whether or not all the intervening pointers in the `to'
    type have been const.  */
 
-int
+static int
 comp_ptr_ttypes_real (to, from, constp)
      tree to, from;
      int constp;
@@ -7392,7 +7379,7 @@ ptr_reasonably_similar (to, from)
 
 /* Like comp_ptr_ttypes, for const_cast.  */
 
-int
+static int
 comp_ptr_ttypes_const (to, from)
      tree to, from;
 {
@@ -7413,7 +7400,7 @@ comp_ptr_ttypes_const (to, from)
 
 /* Like comp_ptr_ttypes, for reinterpret_cast.  */
 
-int
+static int
 comp_ptr_ttypes_reinterpret (to, from)
      tree to, from;
 {