34th Cygnus<->FSF merge
authorMike Stump <mrs@gcc.gnu.org>
Thu, 28 Apr 1994 22:48:45 +0000 (22:48 +0000)
committerMike Stump <mrs@gcc.gnu.org>
Thu, 28 Apr 1994 22:48:45 +0000 (22:48 +0000)
From-SVN: r7171

15 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/error.c
gcc/cp/except.c
gcc/cp/init.c
gcc/cp/method.c
gcc/cp/parse.y
gcc/cp/search.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/cp/typeck2.c

index 2f79a78..6600bb0 100644 (file)
@@ -1,3 +1,263 @@
+Thu Apr 28 15:19:46 1994  Mike Stump  (mrs@cygnus.com)
+
+       * cp-tree.h: disable use of backend EH.
+
+Wed Apr 27 19:10:04 1994  Kung Hsu  (kung@mexican.cygnus.com)
+
+       * decl.c (xref_tag): not to use strstr(), it's not available on
+       all platforms.
+
+Wed Apr 27 18:10:12 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * class.c (finish_struct): Resolve yet another class/pmf confusion.
+
+       * call.c (build_overload_call_real): Don't take the single-function
+       shortcut if we're dealing with an overloaded operator.
+
+Wed Apr 27 17:35:37 1994  Mike Stump  (mrs@cygnus.com)
+
+       * search.c (get_base_distance): Search the virtual base class
+       binfos, incase someone wants to convert to a real virtual base
+       class.
+       * search.c (expand_indirect_vtbls_init): Use convert_pointer_to_real
+       instead of convert_pointer_to, as it now will work.
+
+Wed Apr 27 15:36:49 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * cvt.c (convert_to_reference): Don't complain about casting away
+       const and volatile.
+
+       * typeck.c (build_unary_op): References are too lvalues.
+
+Wed Apr 27 13:58:05 1994  Mike Stump  (mrs@cygnus.com)
+
+       * class.c (override_one_vtable): We have to prepare_fresh_vtable
+       before we modify it, not after, also, we cannot reuse an old vtable,
+       once we commit to a new vtable.  Implement ambiguous overrides in
+       virtual bases as abstract.  Hack until we make the class
+       ill-formed.
+
+Wed Apr 27 01:17:08 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * parse.y (unary_expr): Expand new_placement[opt] and
+       new_initializer[opt] inline.
+
+       * search.c (lookup_fnfields): Don't throw away the inheritance
+       information here, either.
+       (compute_access): Handle static members properly.
+
+       * init.c (build_member_call): Always set basetype_path, and pass it
+       to lookup_fnfields.
+
+       * search.c (lookup_field): Deal properly with the case where
+       xbasetype is a chain of binfos; don't throw away the inheritance
+       information.
+       (compute_access): protected_ok always starts out at 0.
+
+       * init.c (resolve_offset_ref): Don't cast `this' to the base type
+       until we've got our basetype_path.
+
+       * cp-tree.h (IS_OVERLOAD_TYPE): aggregate or enum.
+
+       * cvt.c (build_up_reference): Use build_pointer_type rather than
+       TYPE_POINTER_TO.
+
+       * call.c (convert_harshness_ansi): Call type_promotes_to for reals
+       as well.
+
+       * cvt.c (type_promotes_to): Retain const and volatile, add
+       float->double promotion.
+
+       * decl.c (grokdeclarator): Don't bash references to arrays into
+       references to pointers in function parms.  Use type_promotes_to.
+
+Tue Apr 26 23:44:36 1994  Mike Stump  (mrs@cygnus.com)
+
+       Finish off Apr 19th work.
+
+       * class.c (finish_struct_bits): Rename has_abstract_virtuals to
+       might_have_abstract_virtuals.
+       * class.c (strictly_overrides, override_one_vtable,
+       merge_overrides): New routines to handle virtual base overrides.
+       * class.c (finish_struct): Call merge_overrides to handle overrides
+       in virtual bases.
+
+Tue Apr 26 12:45:53 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * typeck.c (build_function_call): Call build_function_call_real with
+       LOOKUP_NORMAL.
+
+       * *: Don't deal with TYPE_EXPRs.
+
+       * tree.c (lvalue_p): If the type of the expression is a reference,
+       it's an lvalue.
+
+       * cvt.c (convert_to_reference): Complain about passing const
+       lvalues to non-const references.
+       (convert_from_reference): Don't arbitrarily throw away const and
+       volatile on the target type.
+
+       * parse.y: Simplify and fix rules for `new'.
+
+       * decl.c (grok_op_properties): operator void is illegal.
+
+Mon Apr 25 02:36:28 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * parse.y (components): Anonymous bitfields can still have declspecs.
+
+       * decl.c (pushdecl): Postpone handling of function templates like we
+       do C functions.
+
+       * search.c (expand_indirect_vtbls_init): Fix infinite loop when
+       convert_pointer_to fails.
+
+       * call.c (compute_conversion_costs_ansi): A user-defined conversion
+       by itself is better than that UDC followed by standard conversions.
+       Don't treat integers and reals specially.
+
+       * cp-tree.h: Declare flag_ansi.
+
+       * typeck.c (c_expand_return): pedwarn on return in void function
+       even if the expression is of type void.
+       (build_c_cast): Don't do as much checking for casts to void.
+       (build_modify_expr): pedwarn about array assignment if this code
+       wasn't generated by the compiler.
+
+       * tree.c (lvalue_p): A comma expression is an lvalue if its second
+       operand is.
+
+       * typeck.c (default_conversion): Move code for promoting enums and
+       ints from here.
+       * cvt.c (type_promotes_to): To here.
+       * call.c (convert_harshness_ansi): Use type_promotes_to.  Also fix
+       promotion semantics for reals.
+
+Sun Apr 24 00:47:49 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * decl.c (pushdecl): Avoid redundant warning on redeclaring function
+       with different return type.
+       (decls_match): Compare return types strictly.
+
+Fri Apr 22 12:55:42 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * cvt.c (build_type_conversion): Do try to convert through other
+       pointers.  This will fail if the class defines multiple pointer
+       conversions.
+
+       * error.c (dump_type_prefix): Print out pointers to arrays properly.
+       (dump_type_suffix): Ditto.  (was 'int *[]', now 'int (*)[]')
+
+       * typeck.c (build_unary_op): Disallow ++/-- on pointers to
+       incomplete type.
+
+       * decl.c (duplicate_decls): Check mismatched TREE_CODES after
+       checking for shadowing a builtin.  If we're redeclaring a builtin
+       function, bash the old decl to avoid an ambiguous overload.
+
+       * cvt.c (convert_to_reference): Don't force arrays to decay here.
+
+       * tree.c (lvalue_p): A MODIFY_EXPR is an lvalue.
+
+       * decl.c (duplicate_decls): Don't assume that the decls will have
+       types.
+
+       Mon Apr 18 11:35:32 1994  Chip Salzenberg  (chip@fin.uucp)
+
+       [ cp/* changes propagated from c-* changes in 940318 snapshot ]
+       * c-decl.c (pushdecl): Warn if type mismatch with another external decl
+       in a global scope.
+
+       Fri Apr 22 06:38:56 1994  Chip Salzenberg  (chip@fin.uucp)
+
+       * cp/typeck2.c (signature_error): Use cp_error for "%T".
+
+       Mon Apr 18 11:59:59 1994  Chip Salzenberg  (chip@fin.uucp)
+
+       [ cp/* changes propagated from c-* changes in 940415 snapshot ]
+       * cp/decl.c (duplicate_decls, pushdecl, builtin_function):
+       Use DECL_FUNCTION_CODE instead of DECL_SET_FUNCTION_CODE.
+
+       Mon Apr 18 11:55:18 1994  Chip Salzenberg  (chip@fin.uucp)
+
+       [ cp/* changes propagated from c-* changes in 940409 snapshot ]
+       * cp/decl.c (duplicate_decls): Put new type in same obstack as
+       old ones, or permanent if old ones in different obstacks.
+
+       Mon Apr 18 11:48:49 1994  Chip Salzenberg  (chip@fin.uucp)
+
+       [ cp/* changes propagated from c-* changes in 940401 snapshot ]
+       * cp/parse.y (attrib): Handle string args as expressions,
+       merging the two rules.  `mode' attribute now takes a string arg.
+       Delete the rule for an identifier as arg.
+
+       Mon Apr 18 11:24:00 1994  Chip Salzenberg  (chip@fin.uucp)
+
+       [ cp/* changes propagated from c-* changes in 940312 snapshot ]
+       * cp/typeck.c (pointer_int_sum): Multiplication should be done signed.
+       (pointer_diff): Likewise the division.
+
+       Sun Mar  6 19:43:39 1994  Chip Salzenberg  (chip@fin.uucp)
+
+       [ cp/* changes propagated from c-* changes in 940304 snapshot ]
+       * cp/decl.c (finish_decl): Issue warning for large objects,
+       if requested.
+
+       Sat Feb 19 22:20:32 1994  Chip Salzenberg  (chip@fin.uucp)
+
+       [ cp/* changes propagated from c-* changes in 940218 snapshot ]
+       * cp/parse.y (attrib): Handle attribute ((section ("string"))).
+       * cp/decl.c (duplicate_decls): Merge section name into new decl.
+
+       Tue Feb  8 09:49:17 1994  Chip Salzenberg  (chip@fin.uucp)
+
+       [ cp/* changes propagated from c-* changes in 940206 snapshot ]
+       * cp/typeck.c (signed_or_unsigned_type): Check for any
+        INTEGRAL_TYPE_P not just INTEGER_TYPE.
+
+       Mon Dec  6 13:35:31 1993  Norbert Kiesel  (norbert@i3.INformatik.rwth-aachen.DE)
+
+       * cp/decl.c (finish_enum): Start from 0 when determining precision
+       for short enums.
+
+       Fri Dec  3 17:07:58 1993  Ralph Campbell  (ralphc@pyramid.COM)
+
+       * cp/parse.y (unary_expr): Look at $1 for tree_code rather than
+       casting $$.
+
+       Wed Nov 17 19:22:09 1993  Chip Salzenberg  (chip@fin.uucp)
+
+       * cp/typeck.c (build_binary_op_nodefault): Propagate code
+       from C front-end to optimize unsigned short division.
+       (build_conditional_expr): Fix bug in "1 ? 42 : (void *) 8".
+
+       Wed Nov 17 19:17:18 1993  Chip Salzenberg  (chip@fin.uucp)
+
+       * cp/call.c (convert_harshness_ansi): Given an (e.g.) char
+       constant, prefer 'const char &' to 'int'.
+
+       Wed Feb  3 13:11:48 1993  Chip Salzenberg  (chip@fin.uucp)
+
+       * cp/class.c (finish_struct_methods):  Handle multiple
+       constructors in fn_fields list.
+
+Fri Apr 22 12:48:10 1994  Kung Hsu  (kung@mexican.cygnus.com)
+
+       * class.c (finish_struct): use TYPE_DECL_SUPPRESS_DEBUG to flag
+       types not to be dumped in stabs, like types in #pragma interface.
+       * decl.c (init_decl_processing): use TYPE_DECL_SUPPRESS_DEBUG to
+       mark unknown type.
+
+Thu Apr 21 18:27:57 1994  Per Bothner  (bothner@kalessin.cygnus.com)
+
+       * cp-tree.h (THUNK_DELTA):  It is normally negative, so
+       use signed .i variant of frame_size rather than unsigned .u.
+       * cp-tree.h (VTABLE_NAME_FORMAT):  If flag_vtable_thunks,
+       use "VT" rather than "vt" due to binary incompatibility.
+       * class.c (get_vtable_name):  Use strlen of VTABLE_NAME_FORMAT,
+       rather than sizeof, since it is now an expression.
+       * class.c (modify_one_vtable):  Modify to skip initial element
+       containing a count of the vtable.
+
 Thu Apr 21 00:09:02 1994  Jason Merrill  (jason@deneb.cygnus.com)
 
        * lex.c (check_newline): Force interface_unknown on main input file.
index dabed98..62ca226 100644 (file)
@@ -358,45 +358,20 @@ convert_harshness_ansi (type, parmtype, parm)
 
       if (coder == INTEGER_TYPE || coder == ENUMERAL_TYPE)
        {
-         if ((TREE_UNSIGNED (type) ^ TREE_UNSIGNED (parmtype))
-             || codel != coder
-             || TYPE_MODE (type) != TYPE_MODE (parmtype))
+         if (TYPE_MAIN_VARIANT (type)
+             == TYPE_MAIN_VARIANT (type_promotes_to (parmtype)))
            {
-             /* Make sure a value-preserving condition [from a smaller type to
-                a larger type] is preferred to a possibly value-destroying
-                standard conversion [from a larger type to a smaller type].  */
-             if (TYPE_PRECISION (type) >= TYPE_PRECISION (parmtype))
-               {
-                 h.code = PROMO_CODE;
-                 /* A char, short, wchar_t, etc., should promote to an int if
-                    it can handle it, otherwise to an unsigned.  So we'll make
-                    an unsigned.  */
-                 if (type != integer_type_node)
-                   h.int_penalty = 1;
-               }
-             else
-               h.code = STD_CODE;
-           }
-
-         /* If the three above conditions didn't trigger, we have found two
-            very similar types.  On systems where they're the same size, we
-            can end up here with TYPE as `long' and PARMTYPE as `int'.  Make
-            sure we realize that, even though they're the same mode, we will
-            have to do some sort of integral promotion on the type, since
-            they're not the same.  */
-         if (! comptypes (type, parmtype, 1) && h.code == 0)
-           {
-             /* This call to common_type will return the best type for the
-                combination.  If it matches TYPE, that means we'll be converting
-                from a so-called smaller type (in PARMTYPE) to the larger in TYPE,
-                thus an integral promotion.  Otherwise, it must be going from a
-                larger type in PARMTYPE to a smaller expected type in TYPE, so we
-                make it a standard conversion instead.  */
-             if (common_type (type, parmtype) == type)
-               h.code = PROMO_CODE;
-             else
-               h.code = STD_CODE;
+             h.code = PROMO_CODE;
+#if 0 /* What purpose does this serve?  -jason */
+             /* A char, short, wchar_t, etc., should promote to an int if
+                it can handle it, otherwise to an unsigned.  So we'll make
+                an unsigned.  */
+             if (type != integer_type_node)
+               h.int_penalty = 1;
+#endif
            }
+         else
+           h.code = STD_CODE;
            
          return h;
        }
@@ -412,9 +387,12 @@ convert_harshness_ansi (type, parmtype, parm)
     {
       if (coder == REAL_TYPE)
        {
-         /* Shun converting among float, double, and long double if a
-            choice exists.  */
-         h.code = PROMO_CODE;
+         if (TYPE_MAIN_VARIANT (type)
+             == TYPE_MAIN_VARIANT (type_promotes_to (parmtype)))
+           h.code = PROMO_CODE;
+         else
+           h.code = STD_CODE;
+           
          return h;
        }
       else if (coder == INTEGER_TYPE || coder == ENUMERAL_TYPE)
@@ -549,7 +527,7 @@ convert_harshness_ansi (type, parmtype, parm)
     tree ttl, ttr;
     register tree intype = TYPE_MAIN_VARIANT (parmtype);
     register enum tree_code form = TREE_CODE (intype);
-    int penalty;
+    int penalty = 0;
 
     if (codel == REFERENCE_TYPE || coder == REFERENCE_TYPE)
       {
@@ -695,7 +673,9 @@ convert_harshness_ansi (type, parmtype, parm)
        if (parm && codel != REFERENCE_TYPE)
          {
            h = convert_harshness_ansi (ttl, ttr, NULL_TREE);
-           if (penalty)
+           if (penalty == 2)
+             h.code |= QUAL_CODE;
+           else if (penalty == 4)
              h.code |= STD_CODE;
            h.distance = 0;
            return h;
@@ -1457,6 +1437,7 @@ compute_conversion_costs_ansi (function, tta_in, cp, arglen)
            {
              tree actual_type = TREE_TYPE (TREE_VALUE (tta));
              tree formal_type = TREE_VALUE (ttf);
+             int extra_conversions = 0;
 
              dont_convert_types = 1;
 
@@ -1484,40 +1465,41 @@ compute_conversion_costs_ansi (function, tta_in, cp, arglen)
                  if (TYPE_LANG_SPECIFIC (actual_type)
                      && TYPE_HAS_CONVERSION (actual_type))
                    {
-                     if (TREE_CODE (formal_type) == INTEGER_TYPE
-                         && TYPE_HAS_INT_CONVERSION (actual_type))
-                       win++;
-                     else if (TREE_CODE (formal_type) == REAL_TYPE
-                              && TYPE_HAS_REAL_CONVERSION (actual_type))
-                       win++;
-                     else
+                     tree conv;
+                     /* Don't issue warnings since we're only groping
+                        around for the right answer, we haven't yet
+                        committed to going with this solution.  */
+                     int old_inhibit_warnings = inhibit_warnings;
+
+                     inhibit_warnings = 1;
+                     conv = build_type_conversion
+                       (CALL_EXPR, TREE_VALUE (ttf), TREE_VALUE (tta), 0);
+                     inhibit_warnings = old_inhibit_warnings;
+
+                     if (conv)
                        {
-                         tree conv;
-                         /* Don't issue warnings since we're only groping
-                            around for the right answer, we haven't yet
-                            committed to going with this solution.  */
-                         int old_inhibit_warnings = inhibit_warnings;
-
-                         inhibit_warnings = 1;
-                         conv = build_type_conversion (CALL_EXPR, TREE_VALUE (ttf), TREE_VALUE (tta), 0);
-                         inhibit_warnings = old_inhibit_warnings;
-
+                         if (conv == error_mark_node)
+                           win += 2;
+                         else
+                           {
+                             win++;
+                             if (TREE_CODE (conv) != CALL_EXPR)
+                               extra_conversions = 1;
+                           }
+                       }
+                     else if (TREE_CODE (TREE_VALUE (ttf)) == REFERENCE_TYPE)
+                       {
+                         conv = build_type_conversion (CALL_EXPR, formal_type,
+                                                       TREE_VALUE (tta), 0);
                          if (conv)
                            {
                              if (conv == error_mark_node)
                                win += 2;
                              else
-                               win++;
-                           }
-                         else if (TREE_CODE (TREE_VALUE (ttf)) == REFERENCE_TYPE)
-                           {
-                             conv = build_type_conversion (CALL_EXPR, formal_type, TREE_VALUE (tta), 0);
-                             if (conv)
                                {
-                                 if (conv == error_mark_node)
-                                   win += 2;
-                                 else
-                                   win++;
+                                 win++;
+                                 if (TREE_CODE (conv) != CALL_EXPR)
+                                   extra_conversions = 1;
                                }
                            }
                        }
@@ -1528,7 +1510,8 @@ compute_conversion_costs_ansi (function, tta_in, cp, arglen)
              if (win == 1)
                {
                  user_strikes += 1;
-                 cp->v.ansi_harshness[strike_index].code = USER_CODE;
+                 cp->v.ansi_harshness[strike_index].code
+                   = USER_CODE | (extra_conversions ? STD_CODE : 0);
                  win = 0;
                }
              else
@@ -3976,7 +3959,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
       return error_mark_node;
     }
 
-  if (TREE_CODE (functions) == FUNCTION_DECL)
+  if (TREE_CODE (functions) == FUNCTION_DECL && ! IDENTIFIER_OPNAME_P (fnname))
     {
       functions = DECL_MAIN_VARIANT (functions);
       if (final_cp)
index b595f53..0807ce7 100644 (file)
@@ -503,7 +503,7 @@ get_vtable_name (type)
      tree type;
 {
   tree type_id = build_typename_overload (type);
-  char *buf = (char *)alloca (sizeof (VTABLE_NAME_FORMAT)
+  char *buf = (char *)alloca (strlen (VTABLE_NAME_FORMAT)
                              + IDENTIFIER_LENGTH (type_id) + 2);
   char *ptr = IDENTIFIER_POINTER (type_id);
   int i;
@@ -1608,17 +1608,23 @@ finish_struct_bits (t, max_has_virtual)
   if (n_baseclasses && max_has_virtual)
     {
       /* Done by `finish_struct' for classes without baseclasses.  */
-      int has_abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (t) != 0;
+      int might_have_abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (t) != 0;
       tree binfos = TYPE_BINFO_BASETYPES (t);
       for (i = n_baseclasses-1; i >= 0; i--)
        {
-         has_abstract_virtuals
+         might_have_abstract_virtuals
            |= (CLASSTYPE_ABSTRACT_VIRTUALS (BINFO_TYPE (TREE_VEC_ELT (binfos, i))) != 0);
-         if (has_abstract_virtuals)
+         if (might_have_abstract_virtuals)
            break;
        }
-      if (has_abstract_virtuals)
-       CLASSTYPE_ABSTRACT_VIRTUALS (t) = get_abstract_virtuals (t);
+      if (might_have_abstract_virtuals)
+       {
+         /* We use error_mark_node from override_one_vtable to signal
+            an artificial abstract. */
+         if (CLASSTYPE_ABSTRACT_VIRTUALS (t) == error_mark_node)
+           CLASSTYPE_ABSTRACT_VIRTUALS (t) = NULL_TREE;
+         CLASSTYPE_ABSTRACT_VIRTUALS (t) = get_abstract_virtuals (t);
+       }
     }
 
   if (n_baseclasses)
@@ -1809,10 +1815,12 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
            }
        }
 
-      /* Constructors are handled easily in search routines.
-        Besides, we know we won't find any, so do not bother looking.  */
-      if (fn_name == name && TREE_VEC_ELT (method_vec, 0) == 0)
-       TREE_VEC_ELT (method_vec, 0) = fn_fields;
+      /* Constructors are handled easily in search routines.  */
+      if (fn_name == name)
+       {
+         DECL_CHAIN (fn_fields) = TREE_VEC_ELT (method_vec, 0);
+         TREE_VEC_ELT (method_vec, 0) = fn_fields;
+       }
       else
        {
          testp = &TREE_VEC_ELT (method_vec, 0);
@@ -2122,17 +2130,13 @@ static void
 modify_one_vtable (binfo, t, fndecl, pfn)
      tree binfo, t, fndecl, pfn;
 {
-  tree virtuals;
+  tree virtuals = BINFO_VIRTUALS (binfo);
   unsigned HOST_WIDE_INT n;
   
-  virtuals = BINFO_VIRTUALS (binfo);
   n = 0;
-  /* Skip RTTI fake object. */
-  if (flag_dossier)
-    {
-      ++n;
+  /* Skip initial vtable length field and RTTI fake object. */
+  for (; virtuals && n < 1 + flag_dossier; n++)
       virtuals = TREE_CHAIN (virtuals);
-    }
   while (virtuals)
     {
       tree current_fndecl = TREE_VALUE (virtuals);
@@ -2264,6 +2268,176 @@ modify_all_vtables (t, fndecl, vfn)
     modify_all_indirect_vtables (TYPE_BINFO (t), 1, 0, t, fndecl, vfn);
 }
 
+/* Here, we already know that they match in every respect.
+   All we have to check is where they had their declarations.  */
+static int 
+strictly_overrides (fndecl1, fndecl2)
+     tree fndecl1, fndecl2;
+{
+  int distance = get_base_distance (DECL_CLASS_CONTEXT (fndecl2),
+                                   DECL_CLASS_CONTEXT (fndecl1),
+                                   0, (tree *)0);
+  if (distance == -2 || distance > 0)
+    return 1;
+  return 0;
+}
+
+/* Merge overrides for one vtable.
+   If we want to merge in same function, we are fine.
+   else
+     if one has a DECL_CLASS_CONTEXT that is a parent of the
+       other, than choose the more derived one
+     else
+       potentially ill-formed (see 10.3 [class.virtual])
+       we have to check later to see if there was an
+       override in this class.  If there was ok, if not
+       then it is ill-formed.  (mrs)
+
+   We take special care to reuse a vtable, if we can.  */
+static void
+override_one_vtable (binfo, old, t)
+     tree binfo, old, t;
+{
+  tree virtuals = BINFO_VIRTUALS (binfo);
+  tree old_virtuals = BINFO_VIRTUALS (old);
+  enum { REUSE_NEW, REUSE_OLD, UNDECIDED, NEITHER } choose = UNDECIDED;
+
+  /* If we have already committed to modifying it, then don't try and
+     reuse another vtable. */
+  if (BINFO_NEW_VTABLE_MARKED (binfo))
+    choose = NEITHER;
+
+  /* Skip size entry. */
+  virtuals = TREE_CHAIN (virtuals);
+  /* Skip RTTI fake object. */
+  if (flag_dossier)
+    {
+      virtuals = TREE_CHAIN (virtuals);
+    }
+
+  /* Skip size entry. */
+  old_virtuals = TREE_CHAIN (old_virtuals);
+  /* Skip RTTI fake object. */
+  if (flag_dossier)
+    {
+      old_virtuals = TREE_CHAIN (old_virtuals);
+    }
+
+  while (virtuals)
+    {
+      tree fndecl = TREE_VALUE (virtuals);
+      tree old_fndecl = TREE_VALUE (old_virtuals);
+      fndecl = FNADDR_FROM_VTABLE_ENTRY (fndecl);
+      old_fndecl = FNADDR_FROM_VTABLE_ENTRY (old_fndecl);
+      fndecl = TREE_OPERAND (fndecl, 0);
+      old_fndecl = TREE_OPERAND (old_fndecl, 0);
+      /* First check to see if they are the same. */
+      if (DECL_ASSEMBLER_NAME (fndecl) == DECL_ASSEMBLER_NAME (old_fndecl))
+       {
+         /* No need to do anything. */
+       }
+      else if (strictly_overrides (fndecl, old_fndecl))
+       {
+         if (choose == UNDECIDED)
+           choose = REUSE_NEW;
+         else if (choose == REUSE_OLD)
+           {
+             choose = NEITHER;
+             if (! BINFO_NEW_VTABLE_MARKED (binfo))
+               {
+                 prepare_fresh_vtable (binfo, t);
+                 override_one_vtable (binfo, old, t);
+                 return;
+               }
+           }
+       }
+      else if (strictly_overrides (old_fndecl, fndecl))
+       {
+         if (choose == UNDECIDED)
+           choose = REUSE_OLD;
+         else if (choose == REUSE_NEW)
+           {
+             choose = NEITHER;
+             if (! BINFO_NEW_VTABLE_MARKED (binfo))
+               {
+                 prepare_fresh_vtable (binfo, t);
+                 override_one_vtable (binfo, old, t);
+                 return;
+               }
+           }
+         TREE_VALUE (virtuals) = TREE_VALUE (old_virtuals);
+       }
+      else
+       {
+         choose = NEITHER;
+         if (! BINFO_NEW_VTABLE_MARKED (binfo))
+           {
+             prepare_fresh_vtable (binfo, t);
+             override_one_vtable (binfo, old, t);
+             return;
+           }
+         {
+           /* This MUST be overriden, or the class is ill-formed.  */
+           /* For now, we just make it abstract.  */
+           tree fndecl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0);
+           tree vfn;
+
+           fndecl = copy_node (fndecl);
+           copy_lang_decl (fndecl);
+           DECL_ABSTRACT_VIRTUAL_P (fndecl) = 1;
+           /* Make sure we search for it later. */
+           if (! CLASSTYPE_ABSTRACT_VIRTUALS (t))
+             CLASSTYPE_ABSTRACT_VIRTUALS (t) = error_mark_node;
+
+           vfn = build1 (ADDR_EXPR, ptr_type_node, fndecl);
+           TREE_CONSTANT (vfn) = 1;
+           
+           /* We can use integer_zero_node, as we will will core dump
+              if this is used anyway. */
+           TREE_VALUE (virtuals) = build_vtable_entry (integer_zero_node, vfn);
+         }
+       }
+      virtuals = TREE_CHAIN (virtuals);
+      old_virtuals = TREE_CHAIN (old_virtuals);
+    }
+
+  /* Let's reuse the old vtable. */
+  if (choose == REUSE_OLD)
+    {
+      BINFO_VTABLE (binfo) = BINFO_VTABLE (old);
+      BINFO_VIRTUALS (binfo) = BINFO_VIRTUALS (old);
+    }
+}
+
+/* Merge in overrides for virtual bases.
+   BINFO is the hierarchy we want to modify, and OLD has the potential
+   overrides.  */
+static void
+merge_overrides (binfo, old, do_self, t)
+     tree binfo, old, t;
+     int do_self;
+{
+  tree binfos = BINFO_BASETYPES (binfo);
+  tree old_binfos = BINFO_BASETYPES (old);
+  int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
+
+  /* Should we use something besides CLASSTYPE_VFIELDS? */
+  if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
+    {
+      override_one_vtable (binfo, old, t);
+    }
+
+  for (i = 0; i < n_baselinks; i++)
+    {
+      tree base_binfo = TREE_VEC_ELT (binfos, i);
+      tree old_base_binfo = TREE_VEC_ELT (old_binfos, i);
+      int is_not_base_vtable =
+       i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
+      if (! TREE_VIA_VIRTUAL (base_binfo))
+       merge_overrides (base_binfo, old_base_binfo, is_not_base_vtable, t);
+    }
+}
+
 /* Create a RECORD_TYPE or UNION_TYPE node for a C struct or union declaration
    (or C++ class declaration).
 
@@ -2802,7 +2976,8 @@ finish_struct (t, list_of_fieldlists, warn_anon)
              if (TREE_CODE (type) == ARRAY_TYPE)
                type = TREE_TYPE (type);
 
-             if (TYPE_LANG_SPECIFIC (type) && ! ANON_UNION_P (x))
+             if (TYPE_LANG_SPECIFIC (type) && ! ANON_UNION_P (x)
+                 && ! TYPE_PTRMEMFUNC_P (type))
                {
                  /* Never let anything with uninheritable virtuals
                     make it through without complaint.  */
@@ -3268,12 +3443,35 @@ finish_struct (t, list_of_fieldlists, warn_anon)
 
       while (vbases)
        {
+         /* The rtti code should do this.  (mrs) */
          /* Update dossier info with offsets for virtual baseclasses.  */
          if (flag_dossier && ! BINFO_NEW_VTABLE_MARKED (vbases))
            prepare_fresh_vtable (vbases, t);
-
          vbases = TREE_CHAIN (vbases);
        }
+
+      {
+       /* Now fixup overrides of all functions in vtables from all
+          direct or indirect virtual base classes.  */
+       tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
+       int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
+
+       for (i = 0; i < n_baseclasses; i++)
+         {
+           tree base_binfo = TREE_VEC_ELT (binfos, i);
+           tree basetype = BINFO_TYPE (base_binfo);
+           tree vbases;
+
+           vbases = CLASSTYPE_VBASECLASSES (basetype);
+           while (vbases)
+             {
+               merge_overrides (binfo_member (BINFO_TYPE (vbases),
+                                              CLASSTYPE_VBASECLASSES (t)),
+                                vbases, 1, t);
+               vbases = TREE_CHAIN (vbases);
+             }
+         }
+       }
     }
 
 #ifdef NOTQUITE
@@ -3618,16 +3816,16 @@ finish_struct (t, list_of_fieldlists, warn_anon)
          /* Don't output full info about any type
             which does not have its implementation defined here.  */
          if (TYPE_VIRTUAL_P (t) && write_virtuals == 2)
-           DECL_IGNORED_P (TYPE_NAME (t))
+           TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t))
              = (value_member (TYPE_IDENTIFIER (t), pending_vtables) == 0);
          else if (CLASSTYPE_INTERFACE_ONLY (t))
-           DECL_IGNORED_P (TYPE_NAME (t)) = 1;
+           TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 1;
          else if (CLASSTYPE_INTERFACE_UNKNOWN (t))
            /* Only a first approximation!  */
-           DECL_IGNORED_P (TYPE_NAME (t)) = 1;
+           TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 1;
        }
       else if (CLASSTYPE_INTERFACE_ONLY (t))
-       DECL_IGNORED_P (TYPE_NAME (t)) = 1;
+       TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 1;
     }
 
   /* Finish debugging output for this type.  */
index bfed8b2..078b69e 100644 (file)
@@ -275,7 +275,12 @@ extern int flag_elide_constructors;
 
 extern int flag_handle_exceptions;
 
-/* Nonzero means recognize and handle ansi-style exception handling constructs.  */
+/* Nonzero means handle things in ANSI, instead of GNU fashion.  */
+
+extern int flag_ansi;
+
+/* Nonzero means recognize and handle ansi-style exception handling
+   constructs.  */
 
 extern int flag_ansi_exceptions;
 
@@ -325,6 +330,8 @@ enum languages { lang_c, lang_cplusplus };
 #define IS_AGGR_TYPE_2(TYPE1,TYPE2) \
   (TREE_CODE (TYPE1) == TREE_CODE (TYPE2)      \
    && IS_AGGR_TYPE (TYPE1)&IS_AGGR_TYPE (TYPE2))
+#define IS_OVERLOAD_TYPE_CODE(t) (IS_AGGR_TYPE_CODE (t) || t == ENUMERAL_TYPE)
+#define IS_OVERLOAD_TYPE(t) (IS_OVERLOAD_TYPE_CODE (TREE_CODE (t)))
 
 /* In a *_TYPE, nonzero means a built-in type.  */
 #define TYPE_BUILT_IN(NODE) TYPE_LANG_FLAG_6(NODE)
@@ -1075,7 +1082,7 @@ struct lang_decl
 /* Nonzero in IDENTIFIER_NODE means that this name is overloaded, and
    should be looked up in a non-standard way.  */
 #define TREE_OVERLOADED(NODE) (TREE_LANG_FLAG_0 (NODE))
-#define DECL_OVERLOADED(NODE) (NOTHING)
+#define DECL_OVERLOADED(NODE) (DECL_LANG_FLAG_4 (NODE))
 #endif
 
 /* Nonzero if this (non-TYPE)_DECL has its virtual attribute set.
@@ -1091,7 +1098,7 @@ struct lang_decl
 
 #if 0
 /* Same, but tells if this field is private in current context.  */
-#define DECL_PRIVATE(NODE) (DECL_LANG_FLAG_5 (NODE))
+#define DECL_PRIVATE(NODE) NOTHING
 
 /* Same, but tells if this field is private in current context.  */
 #define DECL_PROTECTED(NODE) (DECL_LANG_FLAG_6 (NODE))
@@ -1253,11 +1260,11 @@ struct lang_decl
 
 /* Macros for a DECL or TYPE generated from a template to indicate that it
    was explicitly instantiated.  */
-#define DECL_EXPLICITLY_INSTANTIATED(NODE) (DECL_LANG_FLAG_4 (NODE))
+#define DECL_EXPLICITLY_INSTANTIATED(NODE) (DECL_LANG_FLAG_5 (NODE))
 #define CLASSTYPE_EXPLICITLY_INSTANTIATED(NODE) \
   (DECL_EXPLICITLY_INSTANTIATED (TYPE_NAME (NODE)))
 
-#define THUNK_DELTA(DECL) ((DECL)->decl.frame_size.u)
+#define THUNK_DELTA(DECL) ((DECL)->decl.frame_size.i)
 
 /* ...and for unexpanded-parameterized-type nodes.  */
 #define UPT_TEMPLATE(NODE)      TREE_PURPOSE(TYPE_VALUES(NODE))
@@ -1442,7 +1449,7 @@ extern int current_function_parms_stored;
 #define AUTO_TEMP_NAME "_$tmp_"
 #define AUTO_TEMP_FORMAT "_$tmp_%d"
 #define VTABLE_BASE "$vb"
-#define VTABLE_NAME_FORMAT "_vt$%s"
+#define VTABLE_NAME_FORMAT (flag_vtable_thunks ? "_VT$%s" : "_vt$%s")
 #define VFIELD_BASE "$vf"
 #define VFIELD_NAME "_vptr$"
 #define VFIELD_NAME_FORMAT "_vptr$%s"
@@ -1464,7 +1471,7 @@ extern int current_function_parms_stored;
 #define AUTO_TEMP_NAME "_.tmp_"
 #define AUTO_TEMP_FORMAT "_.tmp_%d"
 #define VTABLE_BASE ".vb"
-#define VTABLE_NAME_FORMAT "_vt.%s"
+#define VTABLE_NAME_FORMAT (flag_vtable_thunks ? "_VT.%s" : "_vt.%s")
 #define VFIELD_BASE ".vf"
 #define VFIELD_NAME "_vptr."
 #define VFIELD_NAME_FORMAT "_vptr.%s"
@@ -1493,7 +1500,7 @@ extern int current_function_parms_stored;
 #define AUTO_TEMP_FORMAT "__tmp_%d"
 #define VTABLE_BASE "__vtb"
 #define VTABLE_NAME "__vt_"
-#define VTABLE_NAME_FORMAT "__vt_%s"
+#define VTABLE_NAME_FORMAT (flag_vtable_thunks ? "_VT_%s" : "_vt_%s")
 #define VTABLE_NAME_P(ID_NODE) \
   (!strncmp (IDENTIFIER_POINTER (ID_NODE), VTABLE_NAME, \
             sizeof (VTABLE_NAME) - 1))
@@ -1784,6 +1791,7 @@ extern tree convert_force                 PROTO((tree, tree));
 extern tree build_type_conversion              PROTO((enum tree_code, tree, tree, int));
 extern int build_default_binary_type_conversion        PROTO((enum tree_code, tree *, tree *));
 extern int build_default_unary_type_conversion PROTO((enum tree_code, tree *));
+extern tree type_promotes_to                   PROTO((tree));
 
 /* decl.c */
 extern int global_bindings_p                   PROTO((void));
@@ -2272,6 +2280,18 @@ extern void GNU_xref_assign                      PROTO((tree));
 extern void GNU_xref_hier                      PROTO((char *, char *, int, int, int));
 extern void GNU_xref_member                    PROTO((tree, tree));
 
+#define in_try_block(X) (0)
+#define in_exception_handler(X) (0)
+#define expand_raise(X) (0)
+#define expand_start_try(A,B,C) ((void)0)
+#define expand_end_try() ((void)0)
+#define expand_start_except(A,B) ((void)0)
+#define expand_escape_except() (0)
+#define expand_end_except() (NULL_TREE)
+#define expand_catch(X) (0)
+#define expand_catch_default() (0)
+#define expand_end_catch() (0)
+
 /* -- end of C++ */
 
 #endif /* not _CP_TREE_H */
index 10e17e2..bcf21c1 100644 (file)
@@ -579,7 +579,7 @@ build_up_reference (type, arg, flags, checkconst)
  done:
   if (TYPE_USES_COMPLEX_INHERITANCE (argtype))
     {
-      TREE_TYPE (rval) = TYPE_POINTER_TO (argtype);
+      TREE_TYPE (rval) = build_pointer_type (argtype);
       if (flags & LOOKUP_PROTECT)
        rval = convert_pointer_to (target_type, rval);
       else
@@ -618,8 +618,11 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
   register enum tree_code form = TREE_CODE (intype);
   tree rval = NULL_TREE;
 
+#if 0
   if (TREE_CODE (type) == ARRAY_TYPE)
     type = build_pointer_type (TREE_TYPE (type));
+#endif
+  
   if (form == REFERENCE_TYPE)
     intype = TREE_TYPE (intype);
   intype = TYPE_MAIN_VARIANT (intype);
@@ -642,12 +645,18 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
             convert_for_assignment, we have to do this checking here.
             FIXME: We should have a common routine between here and
             convert_for_assignment.  */
+
+         tree ttl = TREE_TYPE (reftype);
+         tree ttr;
+         
          if (form == REFERENCE_TYPE)
-           {
-             register tree ttl = TREE_TYPE (reftype);
-             register tree ttr = TREE_TYPE (TREE_TYPE (expr));
+           ttr = TREE_TYPE (TREE_TYPE (expr));
+         else
+           ttr = TREE_TYPE (expr);
 
-             if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
+         if (! TYPE_READONLY (ttl))
+           {
+             if (TYPE_READONLY (ttr) && decl != NULL_TREE)
                {
                  if (fndecl)
                    cp_pedwarn ("passing `%T' as argument %P of `%D' discards const",
@@ -656,29 +665,29 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
                    cp_pedwarn ("%s to `%T' from `%T' discards const",
                                errtype, reftype, TREE_TYPE (expr));
                }
-             if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
+             else if (! lvalue_p (expr))
                {
+                 /* Ensure semantics of 8.4.3 */
                  if (fndecl)
-                   cp_pedwarn ("passing `%T' as argument %P of `%D' discards volatile",
+                   cp_pedwarn ("ANSI C++ forbids passing non-lvalue `%T' as argument %P of `%D' into non-const &",
                                TREE_TYPE (expr), parmnum, fndecl);
                  else
-                   cp_pedwarn ("%s to `%T' from `%T' discards volatile",
+                   cp_pedwarn ("ANSI C++ forbids %s to `%T' from non-lvalue `%T'",
                                errtype, reftype, TREE_TYPE (expr));
                }
-         } else if (TREE_CODE (reftype) == REFERENCE_TYPE
-                    && ! TREE_READONLY (TREE_TYPE (reftype))
-                    && ! lvalue_p (expr))
+           }
+         else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)
+                  && decl != NULL_TREE)
            {
-             /* Ensure semantics of 8.4.3 */
              if (fndecl)
-               cp_pedwarn ("ANSI C++ forbids passing non-lvalue `%T' as argument %P of `%D' into non-const &",
+               cp_pedwarn ("passing `%T' as argument %P of `%D' discards volatile",
                            TREE_TYPE (expr), parmnum, fndecl);
              else
-               cp_pedwarn ("ANSI C++ forbids %s to `%T' from non-lvalue `%T'",
+               cp_pedwarn ("%s to `%T' from `%T' discards volatile",
                            errtype, reftype, TREE_TYPE (expr));
            }
        }
-
+      
       /* If EXPR is of aggregate type, and is really a CALL_EXPR,
         then we don't need to convert it to reference type if
         it is only being used to initialize DECL which is also
@@ -857,7 +866,7 @@ convert_from_reference (val)
          return nval;
        }
 
-      nval = build1 (INDIRECT_REF, TYPE_MAIN_VARIANT (target_type), val);
+      nval = build1 (INDIRECT_REF, target_type, val);
 
       TREE_THIS_VOLATILE (nval) = TYPE_VOLATILE (target_type);
       TREE_SIDE_EFFECTS (nval) = TYPE_VOLATILE (target_type);
@@ -1459,7 +1468,7 @@ convert_force (type, expr)
 
   if (code == REFERENCE_TYPE)
     return fold (convert_to_reference (0, type, e, NULL_TREE, -1,
-                                      NULL, -1, LOOKUP_COMPLAIN));
+                                      "casting", -1, LOOKUP_COMPLAIN));
   else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE)
     e = convert_from_reference (e);
 
@@ -1706,19 +1715,18 @@ build_type_conversion (code, xtype, expr, for_sure)
 
  try_pointer:
 
-  if (type == ptr_type_node)
+  if (TREE_CODE (type) == POINTER_TYPE && TYPE_READONLY (TREE_TYPE (type)))
     {
-      /* Try converting to some other pointer type
-        with which void* is compatible, or in situations
-        in which void* is appropriate (such as &&,||, and !).  */
+      /* Try converting to some other const pointer type and then using
+         standard conversions. */
 
       while (TYPE_HAS_CONVERSION (basetype))
        {
-         if (CLASSTYPE_CONVERSION (basetype, ptr_conv) != 0)
+         if (CLASSTYPE_CONVERSION (basetype, constptr_conv) != 0)
            {
-             if (CLASSTYPE_CONVERSION (basetype, ptr_conv) == error_mark_node)
+             if (CLASSTYPE_CONVERSION (basetype, constptr_conv) == error_mark_node)
                return error_mark_node;
-             typename = DECL_NAME (CLASSTYPE_CONVERSION (basetype, ptr_conv));
+             typename = DECL_NAME (CLASSTYPE_CONVERSION (basetype, constptr_conv));
              return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);
            }
          if (TYPE_BINFO_BASETYPES (basetype))
@@ -1727,20 +1735,18 @@ build_type_conversion (code, xtype, expr, for_sure)
            break;
        }
     }
-  if (TREE_CODE (type) == POINTER_TYPE
-      && TYPE_READONLY (TREE_TYPE (type))
-      && TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
+  if (TREE_CODE (type) == POINTER_TYPE)
     {
-      /* Try converting to some other pointer type
-        with which const void* is compatible.  */
+      /* Try converting to some other pointer type and then using standard
+        conversions.  */
 
       while (TYPE_HAS_CONVERSION (basetype))
        {
-         if (CLASSTYPE_CONVERSION (basetype, constptr_conv) != 0)
+         if (CLASSTYPE_CONVERSION (basetype, ptr_conv) != 0)
            {
-             if (CLASSTYPE_CONVERSION (basetype, constptr_conv) == error_mark_node)
+             if (CLASSTYPE_CONVERSION (basetype, ptr_conv) == error_mark_node)
                return error_mark_node;
-             typename = DECL_NAME (CLASSTYPE_CONVERSION (basetype, constptr_conv));
+             typename = DECL_NAME (CLASSTYPE_CONVERSION (basetype, ptr_conv));
              return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);
            }
          if (TYPE_BINFO_BASETYPES (basetype))
@@ -1749,6 +1755,7 @@ build_type_conversion (code, xtype, expr, for_sure)
            break;
        }
     }
+
   /* Use the longer or shorter conversion that is appropriate.  Have
      to check against 0 because the conversion may come from a baseclass.  */
   if (TREE_CODE (type) == INTEGER_TYPE
@@ -2020,3 +2027,39 @@ build_default_unary_type_conversion (code, arg)
     }
   return 1;
 }
+
+/* Implements integral promotion (4.1) and float->double promotion. */
+tree
+type_promotes_to (type)
+     tree type;
+{
+  int constp = TYPE_READONLY (type);
+  int volatilep = TYPE_VOLATILE (type);
+  type = TYPE_MAIN_VARIANT (type);
+  
+  /* Normally convert enums to int,
+     but convert wide enums to something wider.  */
+  if (TREE_CODE (type) == ENUMERAL_TYPE
+      || type == wchar_type_node)
+    type = type_for_size (MAX (TYPE_PRECISION (type),
+                              TYPE_PRECISION (integer_type_node)),
+                         ((flag_traditional
+                           || (TYPE_PRECISION (type)
+                               >= TYPE_PRECISION (integer_type_node)))
+                          && TREE_UNSIGNED (type)));
+  else if (C_PROMOTING_INTEGER_TYPE_P (type))
+    {
+      /* Traditionally, unsignedness is preserved in default promotions.
+         Otherwise, retain unsignedness if really not getting bigger.  */
+      if (TREE_UNSIGNED (type)
+         && (flag_traditional
+             || TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))
+       type = unsigned_type_node;
+      else
+       type = integer_type_node;
+    }
+  else if (type == float_type_node)
+    type = double_type_node;
+
+  return build_type_variant (type, constp, volatilep);
+}
index 5dd571d..5af301b 100644 (file)
@@ -1998,8 +1998,7 @@ decls_match (newdecl, olddecl)
          return 0;
        }
 
-      if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (f1)),
-                    TYPE_MAIN_VARIANT (TREE_TYPE (f2)), 2))
+      if (comptypes (TREE_TYPE (f1), TREE_TYPE (f2), 1))
        {
          if (! strict_prototypes_lang_c && DECL_LANGUAGE (olddecl) == lang_c
              && p2 == NULL_TREE)
@@ -2147,35 +2146,13 @@ duplicate_decls (newdecl, olddecl)
          && TREE_CODE (TREE_TYPE (olddecl)) == ERROR_MARK))
     types_match = 1;
 
-  if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
-    {
-      if ((TREE_CODE (newdecl) == FUNCTION_DECL
-          && TREE_CODE (olddecl) == TEMPLATE_DECL
-          && ! DECL_TEMPLATE_IS_CLASS (olddecl))
-         || (TREE_CODE (olddecl) == FUNCTION_DECL
-             && TREE_CODE (newdecl) == TEMPLATE_DECL
-             && ! DECL_TEMPLATE_IS_CLASS (newdecl)))
-       return 0;
-      
-      cp_error ("`%#D' redeclared as different kind of symbol", newdecl);
-      if (TREE_CODE (olddecl) == TREE_LIST)
-       olddecl = TREE_VALUE (olddecl);
-      cp_error_at ("previous declaration of `%#D'", olddecl);
-
-      /* New decl is completely inconsistent with the old one =>
-        tell caller to replace the old one.  */
-
-      return 0;
-    }
-
   if (flag_traditional && TREE_CODE (newdecl) == FUNCTION_DECL
       && IDENTIFIER_IMPLICIT_DECL (DECL_ASSEMBLER_NAME (newdecl)) == olddecl)
     /* If -traditional, avoid error for redeclaring fcn
        after implicit decl.  */
     ;
   else if (TREE_CODE (olddecl) == FUNCTION_DECL
-          && (DECL_BUILT_IN (olddecl)
-              || DECL_BUILT_IN_NONANSI (olddecl))
+          && (DECL_BUILT_IN (olddecl) || DECL_BUILT_IN_NONANSI (olddecl))
           && DECL_ASSEMBLER_NAME (newdecl) == DECL_ASSEMBLER_NAME (olddecl))
     {
       /* If you declare a built-in or predefined function name as static,
@@ -2188,21 +2165,38 @@ duplicate_decls (newdecl, olddecl)
                        DECL_BUILT_IN (olddecl) ? "built-in" : "library",
                        newdecl);
          /* Discard the old built-in function.  */
-         return 0;
        }
-      /* Likewise, if the built-in is not ansi, then programs can
-        override it even globally without an error.  */
-      else if (! DECL_BUILT_IN (olddecl))
-       cp_warning ("library function `%#D' declared as non-function",
-                   newdecl);
-
-      if (!types_match)
+      else if (! types_match)
        {
          cp_warning ("declaration of `%#D'", newdecl);
          cp_warning ("conflicts with built-in declaration `%#D'",
                      olddecl);
-         return 0;
        }
+      if (TREE_CODE (newdecl) != FUNCTION_DECL)
+       return 0;
+
+      if (! types_match)
+       TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
+    }
+  else if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
+    {
+      if ((TREE_CODE (newdecl) == FUNCTION_DECL
+          && TREE_CODE (olddecl) == TEMPLATE_DECL
+          && ! DECL_TEMPLATE_IS_CLASS (olddecl))
+         || (TREE_CODE (olddecl) == FUNCTION_DECL
+             && TREE_CODE (newdecl) == TEMPLATE_DECL
+             && ! DECL_TEMPLATE_IS_CLASS (newdecl)))
+       return 0;
+      
+      cp_error ("`%#D' redeclared as different kind of symbol", newdecl);
+      if (TREE_CODE (olddecl) == TREE_LIST)
+       olddecl = TREE_VALUE (olddecl);
+      cp_error_at ("previous declaration of `%#D'", olddecl);
+
+      /* New decl is completely inconsistent with the old one =>
+        tell caller to replace the old one.  */
+
+      return 0;
     }
   else if (!types_match)
     {
@@ -2358,6 +2352,17 @@ duplicate_decls (newdecl, olddecl)
       /* Merge the data types specified in the two decls.  */
       tree newtype = common_type (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
 
+      /* Make sure we put the new type in the same obstack as the old ones.
+        If the old types are not both in the same obstack, use the permanent
+        one.  */
+      if (oldtype && TYPE_OBSTACK (oldtype) == TYPE_OBSTACK (newtype))
+       push_obstacks (TYPE_OBSTACK (oldtype), TYPE_OBSTACK (oldtype));
+      else
+       {
+         push_obstacks_nochange ();
+         end_temporary_allocation ();
+       }
+
       if (TREE_CODE (newdecl) == VAR_DECL)
        DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl);
       /* Do this after calling `common_type' so that default
@@ -2413,12 +2418,22 @@ duplicate_decls (newdecl, olddecl)
          DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
          DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
        }
+
+      /* Merge the section attribute.
+         We want to issue an error if the sections conflict but that must be
+        done later in decl_attributes since we are called before attributes
+        are assigned.  */
+      if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
+       DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
+
       /* Keep the old rtl since we can safely use it, unless it's the
         call to abort() used for abstract virtuals.  */
       if ((DECL_LANG_SPECIFIC (olddecl)
           && !DECL_ABSTRACT_VIRTUAL_P (olddecl))
          || DECL_RTL (olddecl) != DECL_RTL (abort_fndecl))
        DECL_RTL (newdecl) = DECL_RTL (olddecl);
+
+      pop_obstacks ();
     }
   /* If cannot merge, then use the new type and qualifiers,
      and don't preserve the old rtl.  */
@@ -2486,7 +2501,7 @@ duplicate_decls (newdecl, olddecl)
          if (DECL_BUILT_IN (olddecl))
            {
              DECL_BUILT_IN (newdecl) = 1;
-             DECL_SET_FUNCTION_CODE (newdecl, DECL_FUNCTION_CODE (olddecl));
+             DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
              /* If we're keeping the built-in definition, keep the rtl,
                 regardless of declaration matches.  */
              DECL_RTL (newdecl) = DECL_RTL (olddecl);
@@ -2645,7 +2660,10 @@ pushdecl (x)
       char *file;
       int line;
 
-      t = lookup_name_current_level (name);
+      if (DECL_EXTERNAL (x))
+       t = lookup_name (name, 0);
+      else
+       t = lookup_name_current_level (name);
       if (t == error_mark_node)
        {
          /* error_mark_node is 0 for a while during initialization!  */
@@ -2663,7 +2681,9 @@ pushdecl (x)
          file = DECL_SOURCE_FILE (t);
          line = DECL_SOURCE_LINE (t);
 
-         if (TREE_CODE (x) == FUNCTION_DECL && DECL_LANGUAGE (x) == lang_c
+         if (((TREE_CODE (x) == FUNCTION_DECL && DECL_LANGUAGE (x) == lang_c)
+              || (TREE_CODE (x) == TEMPLATE_DECL
+                  && ! DECL_TEMPLATE_IS_CLASS (x)))
              && is_overloaded_fn (t))
            /* don't do anything just yet */;
          else if (TREE_CODE (t) != TREE_CODE (x))
@@ -2771,8 +2791,10 @@ pushdecl (x)
       /* Multiple external decls of the same identifier ought to match.
 
         We get warnings about inline functions where they are defined.
+        We get warnings about other functions from push_overloaded_decl.
+        
         Avoid duplicate warnings where they are used.  */
-      if (TREE_PUBLIC (x) && !DECL_INLINE (x))
+      if (TREE_PUBLIC (x) && TREE_CODE (x) != FUNCTION_DECL)
        {
          tree decl;
 
@@ -2783,11 +2805,10 @@ pushdecl (x)
          else
            decl = NULL_TREE;
 
-         if (decl && ! comptypes (TREE_TYPE (x), TREE_TYPE (decl), 1)
+         if (decl
              /* If different sort of thing, we already gave an error.  */
              && TREE_CODE (decl) == TREE_CODE (x)
-             /* If old decl is built-in, we already warned if we should.  */
-             && !DECL_BUILT_IN (decl))
+             && ! comptypes (TREE_TYPE (x), TREE_TYPE (decl), 1))
            {
              cp_pedwarn ("type mismatch with previous external decl", x);
              cp_pedwarn_at ("previous external decl of `%#D'", decl);
@@ -2893,7 +2914,7 @@ pushdecl (x)
                  if (DECL_BUILT_IN (oldglobal))
                    {
                      DECL_BUILT_IN (x) = DECL_BUILT_IN (oldglobal);
-                     DECL_SET_FUNCTION_CODE (x, DECL_FUNCTION_CODE (oldglobal));
+                     DECL_FUNCTION_CODE (x) = DECL_FUNCTION_CODE (oldglobal);
                    }
                  /* Keep the arg types from a file-scope fcn defn.  */
                  if (TYPE_ARG_TYPES (TREE_TYPE (oldglobal)) != NULL_TREE
@@ -4593,6 +4614,7 @@ init_decl_processing ()
                        unknown_type_node));
   /* Make sure the "unknown type" typedecl gets ignored for debug info.  */
   DECL_IGNORED_P (decl) = 1;
+  TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
 #endif
   TYPE_SIZE (unknown_type_node) = TYPE_SIZE (void_type_node);
   TYPE_ALIGN (unknown_type_node) = 1;
@@ -4905,7 +4927,7 @@ define_function (name, type, function_code, pfn, library_name)
   if (function_code != NOT_BUILT_IN)
     {
       DECL_BUILT_IN (decl) = 1;
-      DECL_SET_FUNCTION_CODE (decl, function_code);
+      DECL_FUNCTION_CODE (decl) = function_code;
     }
   return decl;
 }
@@ -6332,6 +6354,23 @@ finish_decl (decl, init, asmspec_tree, need_pop)
 
  finish_end:
 
+  /* If requested, warn about definitions of large data objects.  */
+
+  if (warn_larger_than
+      && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
+      && !DECL_EXTERNAL (decl))
+    {
+      register tree decl_size = DECL_SIZE (decl);
+
+      if (decl_size && TREE_CODE (decl_size) == INTEGER_CST)
+       {
+         unsigned units = TREE_INT_CST_LOW (decl_size) / BITS_PER_UNIT;
+
+         if (units > larger_than_size)
+           warning_with_decl (decl, "size of `%s' is %u bytes", units);
+       }
+    }
+
   if (need_pop)
     {
       /* Resume permanent allocation, if not within a function.  */
@@ -7073,17 +7112,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
          dname = decl;
          decl = NULL_TREE;
 
-         /* This may just be a variable starting with __op.  */
-         if (IDENTIFIER_TYPENAME_P (dname) && TREE_TYPE (dname))
+         if (IDENTIFIER_OPNAME_P (dname))
            {
-             my_friendly_assert (flags == NO_SPECIAL, 154);
-             flags = TYPENAME_FLAG;
-             ctor_return_type = TREE_TYPE (dname);
-             return_type = return_conversion;
+             if (IDENTIFIER_TYPENAME_P (dname))
+               {
+                 my_friendly_assert (flags == NO_SPECIAL, 154);
+                 flags = TYPENAME_FLAG;
+                 ctor_return_type = TREE_TYPE (dname);
+                 return_type = return_conversion;
+               }
+             name = operator_name_string (dname);
            }
-
-         if (IDENTIFIER_OPNAME_P (dname))
-           name = operator_name_string (dname);
          else
            name = IDENTIFIER_POINTER (dname);
          break;
@@ -8639,45 +8678,25 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
 
     if (decl_context == PARM)
       {
-       tree parmtype = type;
-
        if (ctype)
          error ("cannot use `::' in parameter declaration");
 
        /* A parameter declared as an array of T is really a pointer to T.
           One declared as a function is really a pointer to a function.
-          One declared as a member is really a pointer to member.
-
-          Don't be misled by references.  */
-
-       if (TREE_CODE (type) == REFERENCE_TYPE)
-         type = TREE_TYPE (type);
+          One declared as a member is really a pointer to member.  */
 
        if (TREE_CODE (type) == ARRAY_TYPE)
          {
-           if (parmtype == type)
-             {
-               /* Transfer const-ness of array into that of type
-                  pointed to.  */
-               type = build_pointer_type
-                 (build_type_variant (TREE_TYPE (type), constp, volatilep));
-               volatilep = constp = 0;
-             }
-           else
-             type = build_pointer_type (TREE_TYPE (type));
+           /* Transfer const-ness of array into that of type pointed to. */
+           type = build_pointer_type
+             (build_type_variant (TREE_TYPE (type), constp, volatilep));
+           volatilep = constp = 0;
          }
        else if (TREE_CODE (type) == FUNCTION_TYPE)
          type = build_pointer_type (type);
        else if (TREE_CODE (type) == OFFSET_TYPE)
          type = build_pointer_type (type);
 
-       if (TREE_CODE (parmtype) == REFERENCE_TYPE)
-         {
-           /* Transfer const-ness of reference into that of type pointed to.  */
-           type = build_type_variant (build_reference_type (type), constp, volatilep);
-           constp = volatilep = 0;
-         }
-
        decl = build_decl (PARM_DECL, declarator, type);
 
        bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE,
@@ -8698,28 +8717,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
           (For example, shorts and chars are passed as ints.)
           When there is a prototype, this is overridden later.  */
 
-       DECL_ARG_TYPE (decl) = type;
-       if (TYPE_MAIN_VARIANT (type) == float_type_node)
-         DECL_ARG_TYPE (decl) = build_type_variant (double_type_node,
-                                                    TYPE_READONLY (type),
-                                                    TYPE_VOLATILE (type));
-       else if (C_PROMOTING_INTEGER_TYPE_P (type))
-         {
-           tree argtype;
-
-           /* Retain unsignedness if traditional or if not really
-              getting wider.  */
-           if (TREE_UNSIGNED (type)
-               && (flag_traditional
-                   || TYPE_PRECISION (type)
-                       == TYPE_PRECISION (integer_type_node)))
-             argtype = unsigned_type_node;
-           else
-             argtype = integer_type_node;
-           DECL_ARG_TYPE (decl) = build_type_variant (argtype,
-                                                      TYPE_READONLY (type),
-                                                      TYPE_VOLATILE (type));
-         }
+       DECL_ARG_TYPE (decl) = type_promotes_to (type);
       }
     else if (decl_context == FIELD)
       {
@@ -9593,6 +9591,10 @@ grok_op_properties (decl, virtualp, friendp)
          || name == ansi_opname[(int) METHOD_CALL_EXPR])
        return;                 /* no restrictions on args */
 
+      if (IDENTIFIER_TYPENAME_P (name)
+         && TREE_CODE (TREE_TYPE (name)) == VOID_TYPE)
+       error ("void is not a valid type conversion operator");
+      
       if (name == ansi_opname[(int) MODIFY_EXPR])
        {
          tree parmtype;
@@ -9813,8 +9815,15 @@ xref_tag (code_type_node, name, binfo, globalize)
       /* If we know we are defining this tag, only look it up in this scope
        * and don't try to find it as a type. */
       xref_next_defn = 0;
-      if (t && TYPE_CONTEXT(t) && strstr(IDENTIFIER_POINTER(name), "::"))
-       ref = t;
+      if (t && TYPE_CONTEXT(t))
+       { 
+         extern char *index();
+         char *p;
+         if ((p = index(IDENTIFIER_POINTER(name), ':')) && *(p+1) == ':')
+           ref = t;
+         else
+           ref = lookup_tag (code, name, b, 1);
+       }
       else
        ref = lookup_tag (code, name, b, 1);
     }
@@ -10220,7 +10229,11 @@ finish_enum (enumtype, values)
 
   if (flag_short_enums)
     {
-      /* Determine the precision this type needs, lay it out, and define it.  */
+      /* Determine the precision this type needs, lay it out, and define
+         it.  */
+
+      /* First reset precision */
+      TYPE_PRECISION (enumtype) = 0;
 
       for (i = maxvalue; i; i >>= 1)
        TYPE_PRECISION (enumtype)++;
index 294201f..1fbf21a 100644 (file)
@@ -330,6 +330,10 @@ dump_type_prefix (t, v)
              case METHOD_TYPE:
                break;
                
+             case ARRAY_TYPE:
+               OB_PUTC2 (' ', '(');
+               break;
+
              case POINTER_TYPE:
                /* We don't want "char * *" */
                if (! (TYPE_READONLY (sub) || TYPE_VOLATILE (sub)))
@@ -433,6 +437,8 @@ dump_type_suffix (t, v)
     case POINTER_TYPE:
     case REFERENCE_TYPE:
     case OFFSET_TYPE:
+      if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
+       OB_PUTC (')');
       dump_type_suffix (TREE_TYPE (t), v);
       break;
 
index d0fe130..4a7d0f8 100644 (file)
@@ -615,7 +615,6 @@ void
 cplus_expand_end_except (dfault)
      tree dfault;
 {
-  extern tree expand_end_except (); /* stmt.c.  */
   tree decls, raised;
 
   if (dfault == NULL_TREE)
index ffe3a0f..07de74c 100644 (file)
@@ -1879,7 +1879,7 @@ build_member_call (cname, name, parmlist)
 
   if (dont_use_this)
     {
-      basetype_path = NULL_TREE;
+      basetype_path = TYPE_BINFO (type);
       decl = build1 (NOP_EXPR, TYPE_POINTER_TO (type), error_mark_node);
     }
   else if (current_class_decl == 0)
@@ -1903,7 +1903,7 @@ build_member_call (cname, name, parmlist)
 
   decl = build_indirect_ref (decl, NULL_PTR);
 
-  if (t = lookup_fnfields (TYPE_BINFO (type), method_name, 0))
+  if (t = lookup_fnfields (basetype_path, method_name, 0))
     return build_method_call (decl, method_name, parmlist, basetype_path,
                              LOOKUP_NORMAL|LOOKUP_NONVIRTUAL);
   if (TREE_CODE (name) == IDENTIFIER_NODE
@@ -1994,10 +1994,12 @@ build_offset_ref (cname, name)
       return error_mark_node;
     }
 
+#if 0
   if (TREE_CODE (name) == TYPE_EXPR)
     /* Pass a TYPE_DECL to build_component_type_expr.  */
     return build_component_type_expr (TYPE_NAME (TREE_TYPE (cname)),
                                      name, NULL_TREE, 1);
+#endif
 
   fnfields = lookup_fnfields (TYPE_BINFO (type), name, 1);
   fields = lookup_field (type, name, 0, 0);
@@ -2115,7 +2117,7 @@ build_offset_ref (cname, name)
   if (t == NULL_TREE)
     {
       cp_error ("`%D' is not a member of type `%T'", name,
-                 IDENTIFIER_TYPE_VALUE (cname));
+               IDENTIFIER_TYPE_VALUE (cname));
       return error_mark_node;
     }
 
@@ -2274,13 +2276,11 @@ resolve_offset_ref (exp)
       enum access_type access;
 
       if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
-       {
-         basetype = TYPE_OFFSET_BASETYPE (type);
-         base = convert_pointer_to (basetype, current_class_decl);
-       }
+       basetype = TYPE_OFFSET_BASETYPE (type);
       else
-       base = current_class_decl;
-      basetype = DECL_CONTEXT (member);
+       basetype = DECL_CONTEXT (member);
+
+      base = current_class_decl;
       
       if (get_base_distance (basetype, TREE_TYPE (TREE_TYPE (base)), 0, &basetype_path) < 0)
        {
index 16dead8..c61bf48 100644 (file)
@@ -1521,6 +1521,7 @@ hack_identifier (value, name, yychar)
 }
 
 \f
+#if 0
 /* Given an object OF, and a type conversion operator COMPONENT
    build a call to the conversion operator, if a call is requested,
    or return the address (as a pointer to member function) if one is not.
@@ -1653,6 +1654,7 @@ build_component_type_expr (of, component, basetype_path, protect)
            TREE_TYPE (name));
   return error_mark_node;
 }
+#endif
 \f
 static char *
 thunk_printable_name (decl)
index 11ee26b..ed57b7f 100644 (file)
@@ -244,12 +244,12 @@ empty_parms ()
 %type <ttype> maybe_raises raise_identifier raise_identifiers ansi_raise_identifier ansi_raise_identifiers
 %type <ttype> component_declarator0
 %type <ttype> forhead.1 operator_name
-%type <ttype> new object aggr
-%type <itype> delete
+%type <ttype> object aggr
+%type <itype> new delete
 /* %type <ttype> primary_no_id */
 %type <ttype> nonmomentary_expr
 %type <itype> forhead.2 initdcl0 notype_initdcl0 member_init_list
-%type <itype> .scope try ansi_try
+%type <itype> try ansi_try
 %type <ttype> template_header template_parm_list template_parm
 %type <ttype> template_type template_arg_list template_arg
 %type <ttype> template_instantiation template_type_name tmpl.2
@@ -262,6 +262,7 @@ empty_parms ()
 %type <ttype> qualified_type_name complete_type_name notype_identifier
 %type <ttype> complex_type_name nested_name_specifier_1
 %type <itype> nomods_initdecls nomods_initdcl0
+%type <ttype> new_initializer new_placement
 
 /* in order to recognize aggr tags as defining and thus shadowing. */
 %token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN
@@ -1022,8 +1023,10 @@ nonnull_exprlist:
 unary_expr:
          primary %prec UNARY
                {
+#if 0
                  if (TREE_CODE ($$) == TYPE_EXPR)
                    $$ = build_component_type_expr (C_C_D, $$, NULL_TREE, 1);
+#endif
                }
        /* __extension__ turns off -pedantic for following primary.  */
        | EXTENSION
@@ -1039,7 +1042,7 @@ unary_expr:
        | '~' cast_expr
                { $$ = build_x_unary_op (BIT_NOT_EXPR, $2); }
        | unop cast_expr  %prec UNARY
-               { $$ = build_x_unary_op ((enum tree_code) $$, $2);
+               { $$ = build_x_unary_op ($1, $2);
                  if ($1 == NEGATE_EXPR && TREE_CODE ($2) == INTEGER_CST)
                    TREE_NEGATED_INT ($$) = 1;
                  overflow_warning ($$);
@@ -1083,41 +1086,25 @@ unary_expr:
        | ALIGNOF '(' type_id ')'  %prec HYPERUNARY
                { $$ = c_alignof (groktypename ($3)); }
 
-       | .scope new new_type_id %prec '='
-               { $$ = build_new ($2, $3, NULL_TREE, $$ != NULL_TREE); }
-       | .scope new '(' nonnull_exprlist ')' new_type_id %prec '='
-               { $$ = build_new ($4, $6, NULL_TREE, $$ != NULL_TREE); }
-       | .scope new typespec '(' nonnull_exprlist ')'
-               { $$ = build_new ($2, $3, $5, $$ != NULL_TREE); }
-       | .scope new typespec '(' typespec ')'
-               { cp_error ("`%T' is not a valid expression", $5);
-                 $$ = error_mark_node; }
-       | .scope new '(' nonnull_exprlist ')' typespec '(' nonnull_exprlist ')'
-               { $$ = build_new ($4, $6, $8, $$ != NULL_TREE); }
-       | .scope new typespec LEFT_RIGHT
-               { $$ = build_new ($2, $3, NULL_TREE, $$ != NULL_TREE); }
-       | .scope new '(' nonnull_exprlist ')' typespec LEFT_RIGHT
-               { $$ = build_new ($4, $6, NULL_TREE, $$ != NULL_TREE); }
-       | .scope new new_type_id '=' init %prec '='
-               { $$ = build_new ($2, $3, $5, $$ != NULL_TREE); }
-       | .scope new '(' nonnull_exprlist ')' new_type_id '=' init %prec '='
-               { $$ = build_new ($4, $6, $8, $$ != NULL_TREE); }
-       /* If you don't understand why this is illegal, read 5.3.4. (jason) */
-       | .scope new '(' type_id ')' '[' nonmomentary_expr ']'
-               { 
-                 tree absdcl, typename;
-
-                 absdcl = build_parse_node (ARRAY_REF, TREE_VALUE ($4), $7);
-                 typename = build_decl_list (TREE_PURPOSE ($4), absdcl);
-                 pedwarn ("ANSI C++ forbids array dimensions with parenthesized type");
-                 $$ = build_new ($2, typename, NULL_TREE, $$ != NULL_TREE);
-               }
-       | .scope new '(' type_id ')'
-               { $$ = build_new ($2, groktypename ($4), NULL_TREE,
-                                 $$ != NULL_TREE); }
-       | .scope new '(' nonnull_exprlist ')' '(' type_id ')'
-               { $$ = build_new ($4, groktypename ($7), NULL_TREE,
-                                 $$ != NULL_TREE); }
+       /* The %prec EMPTY's here are required by the = init initializer
+          syntax extension; see below.  */
+       | new new_type_id %prec EMPTY
+               { $$ = build_new (NULL_TREE, $2, NULL_TREE, $1); }
+       | new new_type_id new_initializer
+               { $$ = build_new (NULL_TREE, $2, $3, $1); }
+       | new new_placement new_type_id %prec EMPTY
+               { $$ = build_new ($2, $3, NULL_TREE, $1); }
+       | new new_placement new_type_id new_initializer
+               { $$ = build_new ($2, $3, $4, $1); }
+       | new '(' type_id ')' %prec EMPTY
+               { $$ = build_new (NULL_TREE, groktypename($3),
+                                 NULL_TREE, $1); }
+       | new '(' type_id ')' new_initializer
+               { $$ = build_new (NULL_TREE, groktypename($3), $5, $1); }
+       | new new_placement '(' type_id ')' %prec EMPTY
+               { $$ = build_new ($2, groktypename($4), NULL_TREE, $1); }
+       | new new_placement '(' type_id ')' new_initializer
+               { $$ = build_new ($2, groktypename($4), $6, $1); }
 
        | delete cast_expr  %prec UNARY
                { $$ = delete_sanity ($2, NULL_TREE, 0, $1); }
@@ -1131,6 +1118,37 @@ unary_expr:
                    yychar = YYLEX; }
        ;
 
+new_placement:
+         '(' nonnull_exprlist ')'
+               { $$ = $2; }
+       | '{' nonnull_exprlist '}'
+               {
+                 $$ = $2; 
+                 pedwarn ("old style placement syntax, use () instead");
+               }
+       ;
+
+new_initializer:
+         '(' nonnull_exprlist ')'
+               { $$ = $2; }
+       | LEFT_RIGHT
+               { $$ = NULL_TREE; }
+       | '(' typespec ')'
+               {
+                 cp_error ("`%T' is not a valid expression", $2);
+                 $$ = error_mark_node;
+               }
+       /* GNU extension so people can use initializer lists.  Note that
+          this alters the meaning of `new int = 1', which was previously
+          syntactically valid but semantically invalid.  */
+       | '=' init
+               {
+                 if (pedantic || flag_ansi)
+                   pedwarn ("ANSI C++ forbids initialization of new expression with `='");
+                 $$ = $2;
+               }
+       ;
+
 /* This is necessary to postpone reduction of `int ((int)(int)(int))'.  */
 regcast_or_absdcl:
          '(' type_id ')' %prec EMPTY
@@ -1615,18 +1633,8 @@ primary_no_id:
 */
 
 new:     NEW
-               { $$ = NULL_TREE; }
-       | NEW '{' nonnull_exprlist '}'
-               {
-                 $$ = $3;
-                 pedwarn ("old style placement syntax, use () instead");
-               }
-       ;
-
-.scope:
-       /* empty  */
                { $$ = 0; }
-       | global_scope
+       | global_scope NEW
                { got_scope = NULL_TREE; $$ = 1; }
        ;
 
@@ -1997,27 +2005,28 @@ attribute_list
     ;
 
 attrib
-    : TYPE_QUAL
-    | IDENTIFIER
+    : identifier
        { if (strcmp (IDENTIFIER_POINTER ($1), "packed")
              && strcmp (IDENTIFIER_POINTER ($1), "noreturn"))
            warning ("`%s' attribute directive ignored",
                     IDENTIFIER_POINTER ($1));
          $$ = $1; }
-    | IDENTIFIER '(' IDENTIFIER ')'
-       { /* If not "mode (m)", then issue warning.  */
-         if (strcmp (IDENTIFIER_POINTER ($1), "mode") != 0)
+    | TYPE_QUAL
+    | identifier '(' expr_no_commas ')'
+       { /* If not aligned(n), section(name), or mode(name),
+            then issue warning */
+         if (strcmp (IDENTIFIER_POINTER ($1), "section") == 0
+             || strcmp (IDENTIFIER_POINTER ($1), "mode") == 0)
            {
-             warning ("`%s' attribute directive ignored",
-                      IDENTIFIER_POINTER ($1));
-             $$ = $1;
+             if (TREE_CODE ($3) != STRING_CST)
+               {
+                 error ("invalid argument in `%s' attribute",
+                        IDENTIFIER_POINTER ($1));
+                 $$ = $1;
+               }
+             $$ = tree_cons ($1, $3, NULL_TREE);
            }
-         else
-           $$ = tree_cons ($1, $3, NULL_TREE); }
-    | IDENTIFIER '(' CONSTANT ')'
-       { /* if not "aligned(n)", then issue warning */
-         if (strcmp (IDENTIFIER_POINTER ($1), "aligned") != 0
-             || TREE_CODE ($3) != INTEGER_CST)
+         else if (strcmp (IDENTIFIER_POINTER ($1), "aligned") != 0)
            {
              warning ("`%s' attribute directive ignored",
                       IDENTIFIER_POINTER ($1));
@@ -2025,18 +2034,20 @@ attrib
            }
          else
            $$ = tree_cons ($1, $3, NULL_TREE); }
-    | IDENTIFIER '(' IDENTIFIER ',' CONSTANT ',' CONSTANT ')'
+    | identifier '(' IDENTIFIER ',' expr_no_commas ',' expr_no_commas ')'
        { /* if not "format(...)", then issue warning */
-         if (strcmp (IDENTIFIER_POINTER ($1), "format") != 0
-             || TREE_CODE ($5) != INTEGER_CST
-             || TREE_CODE ($7) != INTEGER_CST)
+         if (strcmp (IDENTIFIER_POINTER ($1), "format") != 0)
            {
              warning ("`%s' attribute directive ignored",
                       IDENTIFIER_POINTER ($1));
              $$ = $1;
            }
          else
-           $$ = tree_cons ($1, tree_cons ($3, tree_cons ($5, $7, NULL_TREE), NULL_TREE), NULL_TREE); }
+           $$ = tree_cons ($1,
+                           tree_cons ($3,
+                                      tree_cons ($5, $7, NULL_TREE),
+                                      NULL_TREE),
+                           NULL_TREE); }
     ;
 
 /* A nonempty list of identifiers, including typenames.  */
@@ -2623,7 +2634,7 @@ notype_component_declarator0:
                  cplus_decl_attributes ($$, $4); }
        | ':' expr_no_commas maybe_attribute
                { current_declspecs = $<ttype>0;
-                 $$ = grokbitfield (NULL_TREE, NULL_TREE, $2);
+                 $$ = grokbitfield (NULL_TREE, current_declspecs, $2);
                  cplus_decl_attributes ($$, $3); }
        ;
 
@@ -2650,7 +2661,7 @@ notype_component_declarator:
                { $$ = grokbitfield ($$, current_declspecs, $3);
                  cplus_decl_attributes ($$, $4); }
        | ':' expr_no_commas maybe_attribute
-               { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2);
+               { $$ = grokbitfield (NULL_TREE, current_declspecs, $2);
                  cplus_decl_attributes ($$, $3); }
        ;
 
@@ -2681,6 +2692,15 @@ new_type_id:
                { $$ = build_decl_list ($$, NULL_TREE); }
        | nonempty_type_quals %prec EMPTY
                { $$ = build_decl_list ($$, NULL_TREE); }
+       /* GNU extension to allow arrays of arbitrary types with
+          non-constant dimension.  */
+       | '(' type_id ')' '[' expr ']'
+               {
+                 if (pedantic || flag_ansi)
+                   pedwarn ("ANSI C++ forbids array dimensions with parenthesized type in new");
+                 $$ = build_parse_node (ARRAY_REF, TREE_VALUE ($2), $5);
+                 $$ = build_decl_list (TREE_PURPOSE ($2), $$);
+               }
        ;
 
 type_quals:
index 23ef5ae..b601075 100644 (file)
@@ -574,10 +574,7 @@ get_base_distance_recursive (binfo, depth, is_private, basetype_path, rval,
    PARENT can also be a binfo, in which case that exact parent is found
    and no other.  convert_pointer_to_real uses this functionality.
 
-   If BINFO is a binfo, its BINFO_INHERITANCE_CHAIN will be left alone.
-
-   Code in prepare_fresh_vtable relies upon the path being built even
-   when -2 is returned.  */
+   If BINFO is a binfo, its BINFO_INHERITANCE_CHAIN will be left alone.  */
 
 int
 get_base_distance (parent, binfo, protect, path_ptr)
@@ -633,6 +630,16 @@ get_base_distance (parent, binfo, protect, path_ptr)
   if (rval && protect && rval_private)
     return -3;
 
+  /* find real virtual base classes. */
+  if (rval == -1 && TREE_CODE (parent) == TREE_VEC
+      && parent == binfo_member (BINFO_TYPE (parent),
+                                CLASSTYPE_VBASECLASSES (type)))
+    {
+      BINFO_INHERITANCE_CHAIN (parent) = binfo;
+      new_binfo = parent;
+      rval = 1;
+    }
+
   if (path_ptr)
     *path_ptr = new_binfo;
   return rval;
@@ -765,6 +772,9 @@ compute_access (basetype_path, field)
   /* Replaces static decl above.  */
   tree previous_scope;
 #endif
+  int static_mem =
+    ((TREE_CODE (field) == FUNCTION_DECL && DECL_STATIC_FUNCTION_P (field))
+     || (TREE_CODE (field) != FUNCTION_DECL && TREE_STATIC (field)));
 
   /* The field lives in the current class.  */
   if (BINFO_TYPE (basetype_path) == current_class_type)
@@ -803,7 +813,7 @@ compute_access (basetype_path, field)
     PUBLIC_RETURN;
 
   /* Member found immediately within object.  */
-  if (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE)
+  if (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE || static_mem)
     {
       /* Are we (or an enclosing scope) friends with the class that has
          FIELD? */
@@ -822,9 +832,7 @@ compute_access (basetype_path, field)
       else if (TREE_PROTECTED (field))
        {
          if (current_class_type
-             && ((TREE_CODE (field) != FUNCTION_DECL && TREE_STATIC (field))
-                 || (TREE_CODE (field) == FUNCTION_DECL
-                     && DECL_STATIC_FUNCTION_P (field)))
+             && static_mem
              && ACCESSIBLY_DERIVED_FROM_P (context, current_class_type))
            PUBLIC_RETURN;
          else
@@ -839,8 +847,7 @@ compute_access (basetype_path, field)
   types = basetype_path;
   via_protected = 0;
   access = access_default;
-  protected_ok = current_class_type
-    && ACCESSIBLY_UNIQUELY_DERIVED_P (BINFO_TYPE (types), current_class_type);
+  protected_ok = 0;
 
   while (1)
     {
@@ -1031,15 +1038,16 @@ lookup_field (xbasetype, name, protect, want_type)
 
   if (TREE_CODE (xbasetype) == TREE_VEC)
     {
-      extern struct obstack temporary_obstack;
-      struct obstack *tmp = current_obstack;
-      current_obstack = &temporary_obstack;
-      basetype_path = copy_binfo (xbasetype);
-      current_obstack = tmp;
       type = BINFO_TYPE (xbasetype);
+      basetype_path = xbasetype;
     }
   else if (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)))
-    basetype_path = TYPE_BINFO (xbasetype), type = xbasetype;
+    {
+      type = xbasetype;
+      basetype_path = TYPE_BINFO (xbasetype);
+      BINFO_VIA_PUBLIC (basetype_path) = 1;
+      BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;
+    }
   else my_friendly_abort (97);
 
   if (CLASSTYPE_MTABLE_ENTRY (type))
@@ -1132,14 +1140,14 @@ lookup_field (xbasetype, name, protect, want_type)
       return rval;
     }
 
-  basetype_chain = CLASSTYPE_BINFO_AS_LIST (type);
-  TREE_VIA_PUBLIC (basetype_chain) = 1;
+  basetype_chain = build_tree_list (NULL_TREE, basetype_path);
+  TREE_VIA_PUBLIC (basetype_chain) = TREE_VIA_PUBLIC (basetype_path);
+  TREE_VIA_PROTECTED (basetype_chain) = TREE_VIA_PROTECTED (basetype_path);
+  TREE_VIA_VIRTUAL (basetype_chain) = TREE_VIA_VIRTUAL (basetype_path);
 
   /* The ambiguity check relies upon breadth first searching. */
 
   search_stack = push_search_level (search_stack, &search_obstack);
-  BINFO_VIA_PUBLIC (basetype_path) = 1;
-  BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;
   binfo = basetype_path;
   binfo_h = binfo;
 
@@ -1579,14 +1587,24 @@ lookup_fnfields (basetype_path, name, complain)
     }
   rval = NULL_TREE;
 
-  basetype_chain = CLASSTYPE_BINFO_AS_LIST (type);
-  TREE_VIA_PUBLIC (basetype_chain) = 1;
+  if (basetype_path == TYPE_BINFO (type))
+    {
+      basetype_chain = CLASSTYPE_BINFO_AS_LIST (type);
+      TREE_VIA_PUBLIC (basetype_chain) = 1;
+      BINFO_VIA_PUBLIC (basetype_path) = 1;
+      BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;
+    }
+  else
+    {
+      basetype_chain = build_tree_list (NULL_TREE, basetype_path);
+      TREE_VIA_PUBLIC (basetype_chain) = TREE_VIA_PUBLIC (basetype_path);
+      TREE_VIA_PROTECTED (basetype_chain) = TREE_VIA_PROTECTED (basetype_path);
+      TREE_VIA_VIRTUAL (basetype_chain) = TREE_VIA_VIRTUAL (basetype_path);
+    }
 
   /* The ambiguity check relies upon breadth first searching. */
 
   search_stack = push_search_level (search_stack, &search_obstack);
-  BINFO_VIA_PUBLIC (basetype_path) = 1;
-  BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;
   binfo = basetype_path;
   binfo_h = binfo;
 
@@ -2502,13 +2520,13 @@ expand_indirect_vtbls_init (binfo, true_exp, decl_ptr, use_computed_offsets)
        }
 
       /* Initialized with vtables of type TYPE.  */
-      while (vbases)
+      for (; vbases; vbases = TREE_CHAIN (vbases))
        {
          tree addr;
          if (use_computed_offsets)
            addr = (tree)CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vbases));
          else
-           addr = convert_pointer_to (vbases, vbase_decl_ptr);
+           addr = convert_pointer_to_real (vbases, vbase_decl_ptr);
          if (addr == error_mark_node)
            continue;
 
@@ -2517,7 +2535,6 @@ expand_indirect_vtbls_init (binfo, true_exp, decl_ptr, use_computed_offsets)
             binfos.  (in the CLASSTPE_VFIELD_PARENT sense)  */
          expand_direct_vtbls_init (vbases, TYPE_BINFO (BINFO_TYPE (vbases)),
                                    1, 0, addr);
-         vbases = TREE_CHAIN (vbases);
        }
 
       dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep);
index 092fc93..f035d6d 100644 (file)
@@ -38,66 +38,69 @@ lvalue_p (ref)
   register enum tree_code code = TREE_CODE (ref);
 
   if (language_lvalue_valid (ref))
-    switch (code)
-      {
-       /* preincrements and predecrements are valid lvals, provided
-          what they refer to are valid lvals. */
-      case PREINCREMENT_EXPR:
-      case PREDECREMENT_EXPR:
-      case COMPONENT_REF:
-      case SAVE_EXPR:
-       return lvalue_p (TREE_OPERAND (ref, 0));
-
-      case STRING_CST:
+    {
+      if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
        return 1;
-
-      case VAR_DECL:
-       if (TREE_READONLY (ref) && ! TREE_STATIC (ref)
-           && DECL_LANG_SPECIFIC (ref)
-           && DECL_IN_AGGR_P (ref))
-         return 0;
-      case INDIRECT_REF:
-      case ARRAY_REF:
-      case PARM_DECL:
-      case RESULT_DECL:
-      case ERROR_MARK:
-       if (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
-           && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE)
+      
+      switch (code)
+       {
+         /* preincrements and predecrements are valid lvals, provided
+            what they refer to are valid lvals. */
+       case PREINCREMENT_EXPR:
+       case PREDECREMENT_EXPR:
+       case COMPONENT_REF:
+       case SAVE_EXPR:
+         return lvalue_p (TREE_OPERAND (ref, 0));
+
+       case STRING_CST:
          return 1;
-       break;
 
-      case TARGET_EXPR:
-      case WITH_CLEANUP_EXPR:
-       return 1;
+       case VAR_DECL:
+         if (TREE_READONLY (ref) && ! TREE_STATIC (ref)
+             && DECL_LANG_SPECIFIC (ref)
+             && DECL_IN_AGGR_P (ref))
+           return 0;
+       case INDIRECT_REF:
+       case ARRAY_REF:
+       case PARM_DECL:
+       case RESULT_DECL:
+       case ERROR_MARK:
+         if (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
+             && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE)
+           return 1;
+         break;
 
-      case CALL_EXPR:
-       if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE
-           /* unary_complex_lvalue knows how to deal with this case.  */
-           || TREE_ADDRESSABLE (TREE_TYPE (ref)))
+       case TARGET_EXPR:
+       case WITH_CLEANUP_EXPR:
          return 1;
-       break;
 
-       /* A currently unresolved scope ref.  */
-      case SCOPE_REF:
-       my_friendly_abort (103);
-      case OFFSET_REF:
-       if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL)
-         return 1;
-       return lvalue_p (TREE_OPERAND (ref, 0))
-         && lvalue_p (TREE_OPERAND (ref, 1));
-       break;
-
-      case ADDR_EXPR:
-       /* ANSI C++ June 5 1992 WP 5.4.14.  The result of a cast to a
-          reference is an lvalue.  */
-       if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
+       case CALL_EXPR:
+         /* unary_complex_lvalue knows how to deal with this case.  */
+         if (TREE_ADDRESSABLE (TREE_TYPE (ref)))
+           return 1;
+         break;
+
+         /* A currently unresolved scope ref.  */
+       case SCOPE_REF:
+         my_friendly_abort (103);
+       case OFFSET_REF:
+         if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL)
+           return 1;
+         return lvalue_p (TREE_OPERAND (ref, 0))
+           && lvalue_p (TREE_OPERAND (ref, 1));
+         break;
+
+       case COND_EXPR:
+         return (lvalue_p (TREE_OPERAND (ref, 1))
+                 && lvalue_p (TREE_OPERAND (ref, 2)));
+
+       case MODIFY_EXPR:
          return 1;
-       break;
 
-      case COND_EXPR:
-       return (lvalue_p (TREE_OPERAND (ref, 1))
-               && lvalue_p (TREE_OPERAND (ref, 2)));
-      }
+       case COMPOUND_EXPR:
+         return lvalue_p (TREE_OPERAND (ref, 1));
+       }
+    }
   return 0;
 }
 
index 4cb6506..9ea4408 100644 (file)
@@ -1035,7 +1035,7 @@ signed_or_unsigned_type (unsignedp, type)
      int unsignedp;
      tree type;
 {
-  if (TREE_CODE (type) != INTEGER_TYPE)
+  if (! INTEGRAL_TYPE_P (type))
     return type;
   if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
     return unsignedp ? unsigned_char_type_node : signed_char_type_node;
@@ -1134,9 +1134,11 @@ c_sizeof_nowarn (type)
 
   if (TYPE_SIZE (type) == 0)
     {
+#if 0
       /* ??? Tiemann, why have any diagnostic here?
         There is none in the corresponding function for C.  */
       warning ("sizeof applied to an incomplete type");
+#endif
       return size_int (0);
     }
 
@@ -1223,27 +1225,11 @@ default_conversion (exp)
   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
      Leave such NOP_EXPRs, since RHS is being used in non-lvalue context.  */
 
-  /* Normally convert enums to int,
-     but convert wide enums to something wider.  */
-  if (code == ENUMERAL_TYPE)
-    {
-      type = type_for_size (MAX (TYPE_PRECISION (type),
-                                TYPE_PRECISION (integer_type_node)),
-                           ((flag_traditional
-                             || TYPE_PRECISION (type) >= TYPE_PRECISION (integer_type_node))
-                            && TREE_UNSIGNED (type)));
-      return convert (type, exp);
-    }
-
-  if (C_PROMOTING_INTEGER_TYPE_P (type))
+  if (code == ENUMERAL_TYPE || code == INTEGER_TYPE)
     {
-      /* Traditionally, unsignedness is preserved in default promotions.
-         Otherwise, retain unsignedness if really not getting bigger.  */
-      if (TREE_UNSIGNED (type)
-         && (flag_traditional
-             || TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))
-       return convert (unsigned_type_node, exp);
-      return convert (integer_type_node, exp);
+      tree t = type_promotes_to (type);
+      if (t != TYPE_MAIN_VARIANT (type))
+       return convert (t, exp);
     }
   if (flag_traditional
       && TYPE_MAIN_VARIANT (type) == float_type_node)
@@ -1498,8 +1484,10 @@ build_component_ref (datum, component, basetype_path, protect)
                && DECL_CHAIN (TREE_VALUE (component)) == NULL_TREE), 309);
       return build (COMPONENT_REF, TREE_TYPE (component), datum, component);
     }
+#if 0
   if (TREE_CODE (component) == TYPE_EXPR)
     return build_component_type_expr (datum, component, NULL_TREE, protect);
+#endif
 
   if (! IS_AGGR_TYPE_CODE (code))
     {
@@ -1590,9 +1578,11 @@ build_component_ref (datum, component, basetype_path, protect)
                return build (COMPONENT_REF, unknown_type_node, datum, fndecls);
            }
 
+#if 0
          if (component == ansi_opname[(int) TYPE_EXPR])
            cp_error ("`%#T' has no such type conversion operator", basetype);
          else
+#endif
            cp_error ("`%#T' has no member named `%D'", basetype, component);
          return error_mark_node;
        }
@@ -2296,7 +2286,7 @@ tree
 build_function_call (function, params)
      tree function, params;
 {
-  return build_function_call_real (function, params, 1, 0);
+  return build_function_call_real (function, params, 1, LOOKUP_NORMAL);
 }
      
 tree
@@ -2702,17 +2692,14 @@ build_binary_op (code, arg1, arg2, convert_p)
    multiple inheritance, and deal with pointer to member functions.  */
 
 tree
-build_binary_op_nodefault (code, op0, op1, error_code)
+build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
      enum tree_code code;
-     tree op0, op1;
+     tree orig_op0, orig_op1;
      enum tree_code error_code;
 {
-  tree type0 = TREE_TYPE (op0), type1 = TREE_TYPE (op1);
-
-  /* The expression codes of the data types of the arguments tell us
-     whether the arguments are integers, floating, pointers, etc.  */
-  register enum tree_code code0 = TREE_CODE (type0);
-  register enum tree_code code1 = TREE_CODE (type1);
+  tree op0, op1;
+  register enum tree_code code0, code1;
+  tree type0, type1;
 
   /* Expression code to give to the expression when it is built.
      Normally this is CODE, which is what the caller asked for,
@@ -2752,6 +2739,18 @@ build_binary_op_nodefault (code, op0, op1, error_code)
   /* Nonzero means set RESULT_TYPE to the common type of the args.  */
   int common = 0;
 
+  /* Apply default conversions.  */
+  op0 = default_conversion (orig_op0);
+  op1 = default_conversion (orig_op1);
+
+  type0 = TREE_TYPE (op0);
+  type1 = TREE_TYPE (op1);
+
+  /* The expression codes of the data types of the arguments tell us
+     whether the arguments are integers, floating, pointers, etc.  */
+  code0 = TREE_CODE (type0);
+  code1 = TREE_CODE (type1);
+
   /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
   STRIP_TYPE_NOPS (op0);
   STRIP_TYPE_NOPS (op1);
@@ -3507,10 +3506,13 @@ pointer_int_sum (resultcode, ptrop, intop)
   if (TYPE_PRECISION (TREE_TYPE (intop)) != POINTER_SIZE)
     intop = convert (type_for_size (POINTER_SIZE, 0), intop);
 
-  /* Replace the integer argument
-     with a suitable product by the object size.  */
+  /* Replace the integer argument with a suitable product by the object size.
+     Do this multiplication as signed, then convert to the appropriate
+     pointer type (actually unsigned integral).  */
 
-  intop = build_binary_op (MULT_EXPR, intop, size_exp, 1);
+  intop = convert (result_type,
+                  build_binary_op (MULT_EXPR, intop,
+                                   convert (TREE_TYPE (intop), size_exp), 1));
 
   /* Create the sum or difference.  */
 
@@ -3564,7 +3566,7 @@ pointer_diff (op0, op1)
 
   /* Do the division.  */
 
-  result = build (EXACT_DIV_EXPR, restype, op0, op1);
+  result = build (EXACT_DIV_EXPR, restype, op0, convert (restype, op1));
 
   folded = fold (result);
   if (folded == result)
@@ -3841,12 +3843,17 @@ build_unary_op (code, xarg, noconvert)
        if (typecode == POINTER_TYPE)
          {
            enum tree_code tmp = TREE_CODE (TREE_TYPE (argtype));
-           if (tmp == FUNCTION_TYPE || tmp == METHOD_TYPE
-               || tmp == VOID_TYPE || tmp == OFFSET_TYPE)
+           if (TYPE_SIZE (TREE_TYPE (argtype)) == 0)
+             cp_error ("cannot %s a pointer to incomplete type `%T'",
+                       ((code == PREINCREMENT_EXPR
+                         || code == POSTINCREMENT_EXPR)
+                        ? "increment" : "decrement"), TREE_TYPE (argtype));
+           else if (tmp == FUNCTION_TYPE || tmp == METHOD_TYPE
+                    || tmp == VOID_TYPE || tmp == OFFSET_TYPE)
              cp_pedwarn ("ANSI C++ forbids %sing a pointer of type `%T'",
-                           ((code == PREINCREMENT_EXPR
-                             || code == POSTINCREMENT_EXPR)
-                            ? "increment" : "decrement"), argtype);
+                         ((code == PREINCREMENT_EXPR
+                           || code == POSTINCREMENT_EXPR)
+                          ? "increment" : "decrement"), argtype);
            inc = c_sizeof_nowarn (TREE_TYPE (argtype));
          }
        else
@@ -3901,12 +3908,7 @@ build_unary_op (code, xarg, noconvert)
       /* Note that this operation never does default_conversion
         regardless of NOCONVERT.  */
 
-      if (TREE_REFERENCE_EXPR (arg))
-       {
-         error ("references are not lvalues");
-         return error_mark_node;
-       }
-      else if (typecode == REFERENCE_TYPE)
+      if (typecode == REFERENCE_TYPE)
        {
          arg = build1 (CONVERT_EXPR, build_pointer_type (TREE_TYPE (TREE_TYPE (arg))), arg);
          TREE_REFERENCE_EXPR (arg) = 1;
@@ -4623,7 +4625,6 @@ build_conditional_expr (ifexp, op1, op2)
 #endif
        }
       result_type = type2;
-      op1 = null_pointer_node;
     }
 
   if (!result_type)
@@ -4852,7 +4853,9 @@ build_c_cast (type, expr)
   if (TREE_READONLY_DECL_P (value))
     value = decl_constant_value (value);
 
-  if (TREE_TYPE (value) == NULL_TREE
+  if (TREE_CODE (type) == VOID_TYPE)
+    value = build1 (NOP_EXPR, type, value);
+  else if (TREE_TYPE (value) == NULL_TREE
       || type_unknown_p (value))
     {
       value = instantiate_type (type, value, 1);
@@ -5665,6 +5668,11 @@ build_modify_expr (lhs, modifycode, rhs)
 
   if (TREE_CODE (lhstype) == ARRAY_TYPE)
     {
+      /* Allow array assignment in compiler-generated code.  */
+      if ((pedantic || flag_ansi)
+         && ! DECL_SYNTHESIZED (current_function_decl))
+       pedwarn ("ANSI C++ forbids assignment between arrays");
+
       /* Have to wrap this in RTL_EXPR for two cases:
         in base or member initialization and if we
         are a branch of a ?: operator.  Since we
@@ -6774,7 +6782,7 @@ c_expand_return (retval)
         "may or may not return a value" in finish_function.  */
       returns_value = 0;
 
-      if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
+      if (retval)
        pedwarn ("`return' with a value, in function returning void");
       expand_return (retval);
     }
index a6e08b5..fd426a4 100644 (file)
@@ -218,7 +218,7 @@ signature_error (decl, type)
        cp_error ("invalid return type for function `%#D'", decl);
     }
   else
-    error ("cannot allocate an object of signature type `%T'", type);
+    cp_error ("cannot allocate an object of signature type `%T'", type);
 }
 
 /* Print an error message for invalid use of an incomplete type.