]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
38th Cygnus<->FSF merge
authorMike Stump <mrs@gcc.gnu.org>
Thu, 19 May 1994 20:19:03 +0000 (20:19 +0000)
committerMike Stump <mrs@gcc.gnu.org>
Thu, 19 May 1994 20:19:03 +0000 (20:19 +0000)
From-SVN: r7337

22 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/class.h
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/errfn.c
gcc/cp/error.c
gcc/cp/gxx.gperf
gcc/cp/hash.h
gcc/cp/init.c
gcc/cp/lex.c
gcc/cp/lex.h
gcc/cp/method.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/search.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/cp/typeck2.c

index bd2be26f9cab41fb3f3acd2d8769152b21838fc1..f4b142407d38504d7c0f20e8382efe725730bd76 100644 (file)
@@ -1,3 +1,207 @@
+Thu May 19 12:08:48 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * cvt.c (type_promotes_to): Make sure bool promotes to int rather
+       than unsigned on platforms where sizeof(char)==sizeof(int).
+
+Wed May 18 14:27:06 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * typeck.c (build_c_cast): Tack on a NOP_EXPR when casting to
+       another variant.
+       (build_modify_expr): Don't strip NOP_EXPRs, and don't get tricky
+       and treat them as lvalues.
+
+       * decl.c (shadow_tag): Do complain about forward declarations of
+       enums and empty declarations.
+       * parse.y: Don't complain about forward declarations of enums and
+       empty declarations.
+
+       * typeck.c (convert_for_assignment): Complain about changing
+       the signedness of a pointer's target type.
+
+       * parse.y (stmt): Move duplicated code for checking case values from
+       here.
+       * decl2.c (check_cp_case_value): To here.  And add a call to
+       constant_expression_warning.
+
+       * typeck.c (convert_for_assignment): Don't complain about assigning
+       a negative value to bool.
+
+       * decl.c (init_decl_processing): Make bool unsigned.
+
+       * class.c (finish_struct): Allow bool bitfields.
+
+Wed May 18 14:41:59 1994  Mike Stump  (mrs@cygnus.com)
+
+       * class.c (finish_base_struct): Make sure we set BINFO_VTABLE and
+       BINFO_VIRTUALS when we choose a new base class to inherit from.
+       * class.c (modify_one_vtable): Use get_vfield_offset to get the
+       offset to the most base class subobject that we derived this binfo
+       from.
+       * class.c (finish_struct): Move code to calculate the
+       DECL_FIELD_BITPOS of the vfield up, as we need might need it for
+       new calls to get_vfield_offset in modify_one_vtable.
+
+Wed May 18 12:35:27 1994  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
+
+       * Make-lang.in (c++.install-man): Get g++.1 from $(srcdir)/cp.
+
+Wed May 18 03:28:35 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * cvt.c (build_type_conversion): Lose special handling of
+       truthvalues.
+
+       * search.c (dfs_pushdecls): Improve shadowing warning.
+
+Tue May 17 13:34:46 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * init.c (build_delete): Throw away const and volatile on `this'.
+
+       * decl.c (finish_enum): Put the constants in TYPE_VALUES again,
+       rather than the enumerators.
+       (pushtag): s/cdecl/c_decl/g
+
+Mon May 16 23:04:01 1994  Stephen R. van den Berg  (berg@pool.informatik.rwth-aachen.de)
+
+        * cp/typeck.c (common_type): Attribute merging.
+        (comp_types): Utilise COMP_TYPE_ATTRIBUTES macro.
+
+        * cp/parse.y: Revamp attribute parsing.
+
+Mon May 16 01:40:34 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * decl.c (shadow_tag): Also check for inappropriate use of auto and
+       register.
+
+       * method.c (build_overload_name): Clarify that the illegal case is a
+       pointer or reference to array of unknown bound.
+
+       * error.c (dump_type_prefix): Print references to arrays properly.
+
+       * typeck.c (various): Be more helpful in pointer
+       comparison diagnostics.
+
+       * tree.c (lvalue_p): MODIFY_EXPRs are lvalues again.  Isn't this
+       fun?
+
+       * parse.y: Also catch an error after valid stmts.
+
+       * search.c (dfs_init_vbase_pointers): Don't abort because `this' is
+       const.
+
+       * typeck.c (convert_for_initialization): If call to
+       convert_to_reference generated a diagnostic, print out the parm
+       number and function decl if any.
+
+       * errfn.c (cp_thing): Check atarg1 to determine whether or not we're
+       specifying a line, not atarg.
+
+       * tree.c (build_cplus_method_type): Always make `this' const.
+
+       * decl2.c (grokclassfn): If -fthis-is-variable and this function is
+       a constructor or destructor, make `this' non-const.
+
+       * typeck.c (build_modify_expr): Don't warn specially about
+       assignment to `this' here anymore, since it will be caught by the
+       usual machinery.
+
+       * various: Disallow specific GNU extensions (variable-size arrays,
+       etc.) when flag_ansi is set, not necessarily when pedantic is set,
+       so that people can compile with -pedantic-errors for tighter const
+       checking and such without losing desirable extensions.
+
+       * typeck2.c (build_functional_cast): Call build_method_call with
+       LOOKUP_PROTECT.
+       (process_init_constructor): Only process FIELD_DECLs.
+
+       * decl.c (finish_decl): Also force static consts with no explicit
+       initializer that need constructing into the data segment.
+
+       * init.c (build_delete): Undo last patch, as it interferes with
+       automatic cleanups.
+
+Sat May 14 01:59:31 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * call.c, class.h, cp-tree.h, cvt.c, decl2.c: Lose old overloading
+       code.
+
+       * init.c (build_delete): pedwarn about using plain delete to delete
+       an array.
+
+Fri May 13 16:45:07 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * typeck.c (comp_target_types): Be more helpful in contravariance
+       warnings, and make them pedwarns.
+
+       * decl.c (grokdeclarator): Use decl_context to decide whether or not
+       this is an access declaration.
+
+       * class.c (finish_struct_bits): Set TYPE_HAS_INT_CONVERSION if it
+       has a conversion to enum or bool, too.
+
+Fri May 13 16:31:27 1994  Mike Stump  (mrs@cygnus.com)
+
+       * method.c (emit_thunk):  Make declaration for
+       current_call_is_indirect local (needed for hppa).
+
+Fri May 13 16:16:37 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * pt.c (uses_template_parms): Grok BOOLEAN_TYPE.
+       (tsubst): Ditto.
+
+Fri May 13 16:23:32 1994  Mike Stump  (mrs@cygnus.com)
+
+       * pt.c (tsubst): If there is already a function for this expansion,
+       use it.
+       * pt.c (instantiate_template): Ditto.
+
+Fri May 13 10:30:42 1994  Brendan Kehoe  (brendan@lisa.cygnus.com)
+
+       * parse.y (implicitly_scoped_stmt, simple_stmt case): Use
+       kept_level_p for MARK_ENDS argument to expand_end_bindings, to avoid
+       generating debug info for unemitted symbols on some systems.
+
+       * cp-tree.h (build_static_cast, build_reinterpret_cast,
+       build_const_cast): Add declarations.
+
+Fri May 13 09:50:31 1994  Mike Stump  (mrs@cygnus.com)
+
+       * search.c (expand_indirect_vtbls_init): Fix breakage from Apr 27
+       fix.  We now try get_binfo, and if that doesn't find what we want,
+       we go back to the old method, which still sometimes fails.
+
+Fri May 13 01:43:18 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * parse.y (initdcl): Call cplus_decl_attributes on the right
+       variable.
+       * decl2.c (cplus_decl_attributes): Don't call decl_attributes for
+       void_type_node.
+
+       * typeck.c (build_binary_op_nodefault): Change result_type for
+       comparison ops to bool.
+       (build_binary_op): Convert args of && and || to bool.
+       * cvt.c (build_default_binary_type_conversion): Convert args of &&
+       and || to bool.
+       (build_default_unary_type_conversion): Convert arg of ! to bool.
+       (type_promotes_to): bool promotes to int.
+
+Fri May 13 01:43:18 1994  Mike Stump  (mrs@cygnus.com)
+
+       Implement the new builtin `bool' type.
+       * typeck.c (build_binary_op_nodefault): Convert args of && and || to
+       bool.
+       (build_unary_op): Convert arg of ! to bool.
+       * parse.y: Know true and false.  Use bool_truthvalue_conversion.
+       * method.c (build_overload_value): Know bool.
+       (build_overload_name): Ditto.
+       * lex.c (init_lex): Set up RID_BOOL.
+       * gxx.gperf: Add bool, true, false.
+       * error.c (*): Know bool.
+       * decl.c (init_decl_processing): Set up bool, true, false.
+       * cvt.c (cp_convert): Handle conversion to bool.
+       (build_type_conversion): Ditto.
+       * *.c: Accept bool where integers and enums are accepted (use
+       INTEGRAL_CODE_P macro).
+
 Thu May 12 19:13:54 1994  Richard Earnshaw  (rwe11@cl.cam.ac.uk)
 
        * g++.c: Use #ifdef for __MSDOS__, not #if.
index 6700f87e87e2a90f48b282cd0e7045dc58c27b19..e957776711d4f0082768d3a1c9cc005843cad460 100644 (file)
@@ -44,38 +44,17 @@ extern tree unary_complex_lvalue ();
 
 /* Compute the ease with which a conversion can be performed
    between an expected and the given type.  */
-static int convert_harshness_old ();
-static struct harshness_code convert_harshness_ansi ();
-
-/* OLD METHOD */
-/* Note the old method also uses USER_HARSHNESS, BASE_DERIVED_HARSHNESS,
-   CONST_HARSHNESS.  */
-#define EVIL 1
-#define TRIVIAL 0
-#define EVIL_HARSHNESS(ARG) ((ARG) & 1)
-#define ELLIPSIS_HARSHNESS(ARG) ((ARG) & 2)
-#define CONTRAVARIANT_HARSHNESS(ARG) ((ARG) & 8)
-#define INT_TO_BD_HARSHNESS(ARG) (((ARG) << 5) | 16)
-#define INT_FROM_BD_HARSHNESS(ARG) ((ARG) >> 5)
-#define INT_TO_EASY_HARSHNESS(ARG) ((ARG) << 5)
-#define INT_FROM_EASY_HARSHNESS(ARG) ((ARG) >> 5)
-#define ONLY_EASY_HARSHNESS(ARG) (((ARG) & 31) == 0)
-
-
-/* NEW METHOD */
+static struct harshness_code convert_harshness ();
+
 #define EVIL_RETURN(ARG)       ((ARG).code = EVIL_CODE, (ARG))
 #define QUAL_RETURN(ARG)       ((ARG).code = QUAL_CODE, (ARG))
 #define TRIVIAL_RETURN(ARG)    ((ARG).code = TRIVIAL_CODE, (ARG))
 #define ZERO_RETURN(ARG)       ((ARG).code = 0, (ARG))
 
-#define USER_HARSHNESS(ARG) ((ARG) & 4)
-#define BASE_DERIVED_HARSHNESS(ARG) ((ARG) & 16)
-#define CONST_HARSHNESS(ARG) ((ARG) & 2048)
-
 /* Ordering function for overload resolution.  Compare two candidates
    by gross quality.  */
 int
-rank_for_overload_ansi (x, y)
+rank_for_overload (x, y)
      struct candidate *x, *y;
 {
   if (y->h.code & (EVIL_CODE|ELLIPSIS_CODE|USER_CODE))
@@ -85,8 +64,8 @@ rank_for_overload_ansi (x, y)
 
   /* This is set by compute_conversion_costs, for calling a non-const
      member function from a const member function.  */
-  if ((y->v.ansi_harshness[0].code & CONST_CODE) ^ (x->v.ansi_harshness[0].code & CONST_CODE))
-    return y->v.ansi_harshness[0].code - x->v.ansi_harshness[0].code;
+  if ((y->harshness[0].code & CONST_CODE) ^ (x->harshness[0].code & CONST_CODE))
+    return y->harshness[0].code - x->harshness[0].code;
 
   if (y->h.code & STD_CODE)
     {
@@ -100,33 +79,6 @@ rank_for_overload_ansi (x, y)
   return y->h.code - x->h.code;
 }
 
-int
-rank_for_overload_old (x, y)
-     struct candidate *x, *y;
-{
-  if (y->evil - x->evil)
-    return y->evil - x->evil;
-  if (CONST_HARSHNESS (y->v.old_harshness[0]) ^ CONST_HARSHNESS (x->v.old_harshness[0]))
-    return y->v.old_harshness[0] - x->v.old_harshness[0];
-  if (y->ellipsis - x->ellipsis)
-    return y->ellipsis - x->ellipsis;
-  if (y->user - x->user)
-    return y->user - x->user;
-  if (y->b_or_d - x->b_or_d)
-    return y->b_or_d - x->b_or_d;
-  return y->easy - x->easy;
-}
-
-int
-rank_for_overload (x, y)
-     struct candidate *x, *y;
-{
-  if (flag_ansi_overloading)
-    return rank_for_overload_ansi (x, y);
-  else
-    return rank_for_overload_old (x, y);
-}
-
 /* Compare two candidates, argument by argument.  */
 int
 rank_for_ideal (x, y)
@@ -139,17 +91,17 @@ rank_for_ideal (x, y)
 
   for (i = 0; i < x->h_len; i++)
     {
-      if (y->v.ansi_harshness[i].code - x->v.ansi_harshness[i].code)
-       return y->v.ansi_harshness[i].code - x->v.ansi_harshness[i].code;
-      if ((y->v.ansi_harshness[i].code & STD_CODE)
-         && (y->v.ansi_harshness[i].distance - x->v.ansi_harshness[i].distance))
-       return y->v.ansi_harshness[i].distance - x->v.ansi_harshness[i].distance;
+      if (y->harshness[i].code - x->harshness[i].code)
+       return y->harshness[i].code - x->harshness[i].code;
+      if ((y->harshness[i].code & STD_CODE)
+         && (y->harshness[i].distance - x->harshness[i].distance))
+       return y->harshness[i].distance - x->harshness[i].distance;
 
       /* They're both the same code.  Now see if we're dealing with an
         integral promotion that needs a finer grain of accuracy.  */
-      if (y->v.ansi_harshness[0].code & PROMO_CODE
-         && (y->v.ansi_harshness[i].int_penalty ^ x->v.ansi_harshness[i].int_penalty))
-       return y->v.ansi_harshness[i].int_penalty - x->v.ansi_harshness[i].int_penalty;
+      if (y->harshness[0].code & PROMO_CODE
+         && (y->harshness[i].int_penalty ^ x->harshness[i].int_penalty))
+       return y->harshness[i].int_penalty - x->harshness[i].int_penalty;
     }
   return 0;
 }
@@ -158,7 +110,7 @@ rank_for_ideal (x, y)
    we have to work with.  We use a somewhat arbitrary cost function
    to measure this conversion.  */
 static struct harshness_code
-convert_harshness_ansi (type, parmtype, parm)
+convert_harshness (type, parmtype, parm)
      register tree type, parmtype;
      tree parm;
 {
@@ -213,7 +165,7 @@ convert_harshness_ansi (type, parmtype, parm)
       /* Compare return types.  */
       p1 = TREE_TYPE (type);
       p2 = TREE_TYPE (parmtype);
-      h2 = convert_harshness_ansi (p1, p2, NULL_TREE);
+      h2 = convert_harshness (p1, p2, NULL_TREE);
       if (h2.code & EVIL_CODE)
        return h2;
 
@@ -262,7 +214,7 @@ convert_harshness_ansi (type, parmtype, parm)
       while (p1 && TREE_VALUE (p1) != void_type_node
             && p2 && TREE_VALUE (p2) != void_type_node)
        {
-         h2 = convert_harshness_ansi (TREE_VALUE (p1), TREE_VALUE (p2),
+         h2 = convert_harshness (TREE_VALUE (p1), TREE_VALUE (p2),
                                       NULL_TREE);
          if (h2.code & EVIL_CODE)
            return h2;
@@ -341,7 +293,7 @@ convert_harshness_ansi (type, parmtype, parm)
   if (coder == VOID_TYPE)
     return EVIL_RETURN (h);
 
-  if (codel == ENUMERAL_TYPE || codel == INTEGER_TYPE)
+  if (INTEGRAL_CODE_P (codel))
     {
       /* Control equivalence of ints an enums.  */
 
@@ -356,7 +308,7 @@ convert_harshness_ansi (type, parmtype, parm)
 
       /* else enums and ints (almost) freely interconvert.  */
 
-      if (coder == INTEGER_TYPE || coder == ENUMERAL_TYPE)
+      if (INTEGRAL_CODE_P (coder))
        {
          if (TYPE_MAIN_VARIANT (type)
              == TYPE_MAIN_VARIANT (type_promotes_to (parmtype)))
@@ -395,7 +347,7 @@ convert_harshness_ansi (type, parmtype, parm)
            
          return h;
        }
-      else if (coder == INTEGER_TYPE || coder == ENUMERAL_TYPE)
+      else if (INTEGRAL_CODE_P (coder))
        {
          h.code = STD_CODE;
          h.distance = 0;
@@ -625,12 +577,11 @@ convert_harshness_ansi (type, parmtype, parm)
           matter if we make life easier for the programmer
           by creating a temporary variable with which to
           hold the result.  */
-       if (parm && (coder == INTEGER_TYPE
-                    || coder == ENUMERAL_TYPE
+       if (parm && (INTEGRAL_CODE_P (coder)
                     || coder == REAL_TYPE)
            && ! lvalue_p (parm))
          {
-           h = convert_harshness_ansi (ttl, ttr, NULL_TREE);
+           h = convert_harshness (ttl, ttr, NULL_TREE);
            if (penalty > 2 || h.code != 0)
              h.code |= STD_CODE;
            else
@@ -672,7 +623,7 @@ convert_harshness_ansi (type, parmtype, parm)
 
        if (parm && codel != REFERENCE_TYPE)
          {
-           h = convert_harshness_ansi (ttl, ttr, NULL_TREE);
+           h = convert_harshness (ttl, ttr, NULL_TREE);
            if (penalty == 2)
              h.code |= QUAL_CODE;
            else if (penalty == 4)
@@ -731,967 +682,215 @@ convert_harshness_ansi (type, parmtype, parm)
   return EVIL_RETURN (h);
 }
 
-/* TYPE is the type we wish to convert to.  PARM is the parameter
-   we have to work with.  We use a somewhat arbitrary cost function
-   to measure this conversion.  */
-static int
-convert_harshness_old (type, parmtype, parm)
-     register tree type, parmtype;
-     tree parm;
+#ifdef DEBUG_MATCHING
+static char *
+print_harshness (h)
+     struct harshness_code *h;
 {
-  register enum tree_code codel;
-  register enum tree_code coder;
+  static char buf[1024];
+  char tmp[1024];
 
-#ifdef GATHER_STATISTICS
-  n_convert_harshness++;
-#endif
+  bzero (buf, 1024 * sizeof (char));
+  strcat (buf, "codes=[");
+  if (h->code & EVIL_CODE)
+    strcat (buf, "EVIL");
+  if (h->code & CONST_CODE)
+    strcat (buf, " CONST");
+  if (h->code & ELLIPSIS_CODE)
+    strcat (buf, " ELLIPSIS");
+  if (h->code & USER_CODE)
+    strcat (buf, " USER");
+  if (h->code & STD_CODE)
+    strcat (buf, " STD");
+  if (h->code & PROMO_CODE)
+    strcat (buf, " PROMO");
+  if (h->code & QUAL_CODE)
+    strcat (buf, " QUAL");
+  if (h->code & TRIVIAL_CODE)
+    strcat (buf, " TRIVIAL");
+  if (buf[0] == '\0')
+    strcat (buf, "0");
 
-  if (TYPE_PTRMEMFUNC_P (type))
-    type = TYPE_PTRMEMFUNC_FN_TYPE (type);
-  if (TYPE_PTRMEMFUNC_P (parmtype))
-    parmtype = TYPE_PTRMEMFUNC_FN_TYPE (parmtype);
+  sprintf (tmp, "] distance=%d int_penalty=%d", h->distance, h->int_penalty);
 
-  codel = TREE_CODE (type);
-  coder = TREE_CODE (parmtype);
+  strcat (buf, tmp);
 
-  if (TYPE_MAIN_VARIANT (parmtype) == TYPE_MAIN_VARIANT (type))
-    return TRIVIAL;
+  return buf;
+}
+#endif
 
-  if (coder == ERROR_MARK)
-    return EVIL;
+/* Algorithm: For each argument, calculate how difficult it is to
+   make FUNCTION accept that argument.  If we can easily tell that
+   FUNCTION won't be acceptable to one of the arguments, then we
+   don't need to compute the ease of converting the other arguments,
+   since it will never show up in the intersection of all arguments'
+   favorite functions.
 
-  if (codel == POINTER_TYPE && fntype_p (parmtype))
-    {
-      tree p1, p2;
-      int harshness, new_harshness;
+   Conversions between builtin and user-defined types are allowed, but
+   no function involving such a conversion is preferred to one which
+   does not require such a conversion.  Furthermore, such conversions
+   must be unique.  */
 
-      /* Get to the METHOD_TYPE or FUNCTION_TYPE that this might be.  */
-      type = TREE_TYPE (type);
+void
+compute_conversion_costs (function, tta_in, cp, arglen)
+     tree function;
+     tree tta_in;
+     struct candidate *cp;
+     int arglen;
+{
+  tree ttf_in = TYPE_ARG_TYPES (TREE_TYPE (function));
+  tree ttf = ttf_in;
+  tree tta = tta_in;
 
-      if (coder == POINTER_TYPE)
-       {
-         parmtype = TREE_TYPE (parmtype);
-         coder = TREE_CODE (parmtype);
-       }
+  /* Start out with no strikes against.  */
+  int evil_strikes = 0;
+  int ellipsis_strikes = 0;
+  int user_strikes = 0;
+  int b_or_d_strikes = 0;
+  int easy_strikes = 0;
 
-      if (coder != TREE_CODE (type))
-       return EVIL;
+  int strike_index = 0, win;
+  struct harshness_code lose;
 
-      harshness = 0;
+#ifdef GATHER_STATISTICS
+  n_compute_conversion_costs++;
+#endif
 
-      /* We allow the default conversion between function type
-        and pointer-to-function type for free.  */
-      if (type == parmtype)
-       return TRIVIAL;
+  cp->function = function;
+  cp->arg = tta ? TREE_VALUE (tta) : NULL_TREE;
+  cp->u.bad_arg = 0;           /* optimistic!  */
 
-      /* Compare return types.  */
-      p1 = TREE_TYPE (type);
-      p2 = TREE_TYPE (parmtype);
-      new_harshness = convert_harshness_old (p1, p2, NULL_TREE);
-      if (EVIL_HARSHNESS (new_harshness))
-       return EVIL;
+  cp->h.code = 0;
+  cp->h.distance = 0;
+  cp->h.int_penalty = 0;
+  bzero (cp->harshness,
+        (cp->h_len + 1) * sizeof (struct harshness_code));
 
-      if (BASE_DERIVED_HARSHNESS (new_harshness))
-       {
-         tree binfo;
+  while (ttf && tta)
+    {
+      struct harshness_code h;
 
-         /* This only works for pointers.  */
-         if (TREE_CODE (p1) != POINTER_TYPE
-             && TREE_CODE (p1) != REFERENCE_TYPE)
-           return EVIL;
+      if (ttf == void_list_node)
+       break;
 
-         p1 = TREE_TYPE (p1);
-         p2 = TREE_TYPE (p2);
-         /* Don't die if we happen to be dealing with void*.  */
-         if (!IS_AGGR_TYPE (p1) || !IS_AGGR_TYPE (p2))
-           return EVIL;
-         if (CONTRAVARIANT_HARSHNESS (new_harshness))
-           binfo = get_binfo (p2, p1, 0);
-         else
-           binfo = get_binfo (p1, p2, 0);
+      if (type_unknown_p (TREE_VALUE (tta)))
+       {         
+         /* Must perform some instantiation here.  */
+         tree rhs = TREE_VALUE (tta);
+         tree lhstype = TREE_VALUE (ttf);
 
-         if (! BINFO_OFFSET_ZEROP (binfo))
-           {
-             static int explained = 0;
-             if (CONTRAVARIANT_HARSHNESS (new_harshness))
-               message_2_types (sorry, "cannot cast `%d' to `%d' at function call site", p2, p1);
-             else
-               message_2_types (sorry, "cannot cast `%d' to `%d' at function call site", p1, p2);
+         /* Keep quiet about possible contravariance violations.  */
+         int old_inhibit_warnings = inhibit_warnings;
+         inhibit_warnings = 1;
 
-             if (! explained++)
-               sorry ("(because pointer values change during conversion)");
-             return EVIL;
-           }
-       }
+         /* @@ This is to undo what `grokdeclarator' does to
+            parameter types.  It really should go through
+            something more general.  */
 
-      harshness |= new_harshness;
+         TREE_TYPE (tta) = unknown_type_node;
+         rhs = instantiate_type (lhstype, rhs, 0);
+         inhibit_warnings = old_inhibit_warnings;
 
-      p1 = TYPE_ARG_TYPES (type);
-      p2 = TYPE_ARG_TYPES (parmtype);
-      while (p1 && TREE_VALUE (p1) != void_type_node
-            && p2 && TREE_VALUE (p2) != void_type_node)
+         if (TREE_CODE (rhs) == ERROR_MARK)
+           h.code = EVIL_CODE;
+         else
+           h = convert_harshness (lhstype, TREE_TYPE (rhs), rhs);
+       }
+      else
        {
-         new_harshness = convert_harshness_old (TREE_VALUE (p1),
-                                                TREE_VALUE (p2), NULL_TREE);
-         if (EVIL_HARSHNESS (new_harshness))
-           return EVIL;
+#ifdef DEBUG_MATCHING
+         static tree old_function = NULL_TREE;
 
-         if (BASE_DERIVED_HARSHNESS (new_harshness))
+         if (!old_function || function != old_function)
            {
-             /* This only works for pointers and references. */
-             if (TREE_CODE (TREE_VALUE (p1)) != POINTER_TYPE
-                 && TREE_CODE (TREE_VALUE (p1)) != REFERENCE_TYPE)
-               return EVIL;
-             new_harshness ^= CONTRAVARIANT_HARSHNESS (new_harshness);
-             harshness |= new_harshness;
+             cp_error ("trying %D", function);
+             old_function = function;
            }
-         /* This trick allows use to accumulate easy type
-            conversions without messing up the bits that encode
-            info about more involved things.  */
-         else if (ONLY_EASY_HARSHNESS (new_harshness))
-           harshness += new_harshness;
-         else
-           harshness |= new_harshness;
-         p1 = TREE_CHAIN (p1);
-         p2 = TREE_CHAIN (p2);
-       }
-      if (p1 == p2)
-       return harshness;
-      if (p2)
-       return p1 ? EVIL : (harshness | ELLIPSIS_HARSHNESS (-1));
-      if (p1)
-       return harshness | (TREE_PURPOSE (p1) == NULL_TREE);
-    }
-  else if (codel == POINTER_TYPE && coder == OFFSET_TYPE)
-    {
-      /* XXX: Note this is set a few times, but it's never actually
-        used! (bpk) */
-      int harshness;
 
-      /* Get to the OFFSET_TYPE that this might be.  */
-      type = TREE_TYPE (type);
+         cp_error ("      doing (%T) %E against arg %T",
+                   TREE_TYPE (TREE_VALUE (tta)), TREE_VALUE (tta),
+                   TREE_VALUE (ttf));
+#endif
 
-      if (coder != TREE_CODE (type))
-       return EVIL;
+         h = convert_harshness (TREE_VALUE (ttf),
+                                     TREE_TYPE (TREE_VALUE (tta)),
+                                     TREE_VALUE (tta));
 
-      harshness = 0;
+#ifdef DEBUG_MATCHING
+         cp_error ("     evaluated %s", print_harshness (&h));
+#endif
+       }
 
-      if (TYPE_OFFSET_BASETYPE (type) == TYPE_OFFSET_BASETYPE (parmtype))
-       harshness = 0;
-      else if (UNIQUELY_DERIVED_FROM_P (TYPE_OFFSET_BASETYPE (type),
-                              TYPE_OFFSET_BASETYPE (parmtype)))
-       harshness = INT_TO_BD_HARSHNESS (1);
-      else if (UNIQUELY_DERIVED_FROM_P (TYPE_OFFSET_BASETYPE (parmtype),
-                              TYPE_OFFSET_BASETYPE (type)))
-       harshness = CONTRAVARIANT_HARSHNESS (-1);
+      cp->harshness[strike_index] = h;
+      if ((h.code & EVIL_CODE)
+         || ((h.code & STD_CODE) && h.distance < 0))
+       {
+         cp->u.bad_arg = strike_index;
+         evil_strikes = 1;
+       }
+     else if (h.code & ELLIPSIS_CODE)
+       ellipsis_strikes += 1;
+#if 0
+      /* This is never set by `convert_harshness'.  */
+      else if (h.code & USER_CODE)
+       {
+         user_strikes += 1;
+       }
+#endif
       else
-       return EVIL;
-      /* Now test the OFFSET_TYPE's target compatibility.  */
-      type = TREE_TYPE (type);
-      parmtype = TREE_TYPE (parmtype);
-    }
+       {
+         if ((h.code & STD_CODE) && h.distance)
+           {
+             if (h.distance > b_or_d_strikes)
+               b_or_d_strikes = h.distance;
+           }
+         else
+           easy_strikes += (h.code & (STD_CODE|PROMO_CODE|TRIVIAL_CODE));
+         cp->h.code |= h.code;
+         /* Make sure we communicate this.  */
+         cp->h.int_penalty += h.int_penalty;
+       }
 
-  if (coder == UNKNOWN_TYPE)
-    {
-      if (codel == FUNCTION_TYPE
-         || codel == METHOD_TYPE
-         || (codel == POINTER_TYPE
-             && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
-                 || TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)))
-       return TRIVIAL;
-      return EVIL;
+      ttf = TREE_CHAIN (ttf);
+      tta = TREE_CHAIN (tta);
+      strike_index += 1;
     }
 
-  if (coder == VOID_TYPE)
-    return EVIL;
-
-  if (codel == ENUMERAL_TYPE || codel == INTEGER_TYPE)
+  if (tta)
     {
-      /* Control equivalence of ints an enums.  */
-
-      if (codel == ENUMERAL_TYPE
-         && flag_int_enum_equivalence == 0)
-       {
-         /* Enums can be converted to ints, but not vice-versa.  */
-         if (coder != ENUMERAL_TYPE
-             || TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (parmtype))
-           return EVIL;
-       }
-
-      /* else enums and ints (almost) freely interconvert.  */
-
-      if (coder == INTEGER_TYPE || coder == ENUMERAL_TYPE)
-       {
-         int easy = TREE_UNSIGNED (type) ^ TREE_UNSIGNED (parmtype);
-         if (codel != coder)
-           easy += 1;
-         if (TYPE_MODE (type) != TYPE_MODE (parmtype))
-           easy += 2;
-         return INT_TO_EASY_HARSHNESS (easy);
-       }
-      else if (coder == REAL_TYPE)
-       return INT_TO_EASY_HARSHNESS (4);
-    }
-
-  if (codel == REAL_TYPE)
-    if (coder == REAL_TYPE)
-      /* Shun converting between float and double if a choice exists.  */
-      {
-       if (TYPE_MODE (type) != TYPE_MODE (parmtype))
-         return INT_TO_EASY_HARSHNESS (2);
-       return TRIVIAL;
-      }
-    else if (coder == INTEGER_TYPE || coder == ENUMERAL_TYPE)
-      return INT_TO_EASY_HARSHNESS (4);
-
-  /* convert arrays which have not previously been converted.  */
-  if (codel == ARRAY_TYPE)
-    codel = POINTER_TYPE;
-  if (coder == ARRAY_TYPE)
-    coder = POINTER_TYPE;
-
-  /* Conversions among pointers */
-  if (codel == POINTER_TYPE && coder == POINTER_TYPE)
-    {
-      register tree ttl = TYPE_MAIN_VARIANT (TREE_TYPE (type));
-      register tree ttr = TYPE_MAIN_VARIANT (TREE_TYPE (parmtype));
-      int penalty = 4 * (ttl != ttr);
-      /* Anything converts to void *.  void * converts to anything.
-        Since these may be `const void *' (etc.) use VOID_TYPE
-        instead of void_type_node.
-        Otherwise, the targets must be the same,
-        except that we do allow (at some cost) conversion
-        between signed and unsinged pointer types.  */
-
-      if ((TREE_CODE (ttl) == METHOD_TYPE
-          || TREE_CODE (ttl) == FUNCTION_TYPE)
-         && TREE_CODE (ttl) == TREE_CODE (ttr))
-       {
-         if (comptypes (ttl, ttr, -1))
-           return INT_TO_EASY_HARSHNESS (penalty);
-         return EVIL;
-       }
-
-      if (!(TREE_CODE (ttl) == VOID_TYPE
-           || TREE_CODE (ttr) == VOID_TYPE
-           || (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (ttr)
-               && (ttl = unsigned_type (ttl),
-                   ttr = unsigned_type (ttr),
-                   penalty = 10, 0))
-           || (comp_target_types (ttl, ttr, 0))))
-       return EVIL;
-
-      if (penalty == 10)
-       return INT_TO_EASY_HARSHNESS (10);
-      if (ttr == ttl)
-       return INT_TO_BD_HARSHNESS (0);
-
-      if (TREE_CODE (ttl) == RECORD_TYPE && TREE_CODE (ttr) == RECORD_TYPE)
-       {
-         int b_or_d = get_base_distance (ttl, ttr, 0, 0);
-         if (b_or_d < 0)
-           {
-             b_or_d = get_base_distance (ttr, ttl, 0, 0);
-             if (b_or_d < 0)
-               return EVIL;
-             return CONTRAVARIANT_HARSHNESS (-1);
-           }
-         return INT_TO_BD_HARSHNESS (b_or_d);
-       }
-      /* If converting from a `class*' to a `void*', make it
-        less favorable than any inheritance relationship.  */
-      if (TREE_CODE (ttl) == VOID_TYPE && IS_AGGR_TYPE (ttr))
-       return INT_TO_BD_HARSHNESS (CLASSTYPE_MAX_DEPTH (ttr)+1);
-      return INT_TO_EASY_HARSHNESS (penalty);
-    }
-
-  if (codel == POINTER_TYPE && coder == INTEGER_TYPE)
-    {
-      /* This is not a bad match, but don't let it beat
-        integer-enum combinations.  */
-      if (parm && integer_zerop (parm))
-       return INT_TO_EASY_HARSHNESS (4);
-    }
-
-  /* C++: Since the `this' parameter of a signature member function
-     is represented as a signature pointer to handle default implementations
-     correctly, we can have the case that `type' is a signature pointer
-     while `parmtype' is a pointer to a signature table.  We don't really
-     do any conversions in this case, so just return 0.  */
-
-  if (codel == RECORD_TYPE && coder == POINTER_TYPE
-      && IS_SIGNATURE_POINTER (type) && IS_SIGNATURE (TREE_TYPE (parmtype)))
-    return 0;
-
-  /* C++: one of the types must be a reference type.  */
-  {
-    tree ttl, ttr;
-    register tree intype = TYPE_MAIN_VARIANT (parmtype);
-    register enum tree_code form = TREE_CODE (intype);
-    int penalty;
-
-    if (codel == REFERENCE_TYPE || coder == REFERENCE_TYPE)
-      {
-       ttl = TYPE_MAIN_VARIANT (type);
-
-       if (codel == REFERENCE_TYPE)
-         {
-           ttl = TREE_TYPE (ttl);
-
-           /* When passing a non-const argument into a const reference,
-              dig it a little, so a non-const reference is preferred over
-              this one. (mrs) */
-           if (parm && TREE_READONLY (ttl) && ! TREE_READONLY (parm))
-             penalty = 2;
-           else
-             penalty = 0;
-
-           ttl = TYPE_MAIN_VARIANT (ttl);
-
-           if (form == OFFSET_TYPE)
-             {
-               intype = TREE_TYPE (intype);
-               form = TREE_CODE (intype);
-             }
-
-           if (form == REFERENCE_TYPE)
-             {
-               intype = TYPE_MAIN_VARIANT (TREE_TYPE (intype));
-
-               if (ttl == intype)
-                 return TRIVIAL;
-               penalty = 2;
-             }
-           else
-             {
-               /* Can reference be built up?  */
-               if (ttl == intype && penalty == 0) {
-                 /* Because the READONLY bits and VIRTUAL bits are not always
-                    in the type, this extra check is necessary.  The problem
-                    should be fixed someplace else, and this extra code
-                    removed.
-
-                    Also, if type if a reference, the readonly bits could
-                    either be in the outer type (with reference) or on the
-                    inner type (the thing being referenced).  (mrs)  */
-                 if (parm
-                     && ((TREE_READONLY (parm)
-                          && ! (TYPE_READONLY (type)
-                                || (TREE_CODE (type) == REFERENCE_TYPE
-                                    && TYPE_READONLY (TREE_TYPE (type)))))
-                         || (TREE_SIDE_EFFECTS (parm)
-                             && ! (TYPE_VOLATILE (type)
-                                   || (TREE_CODE (type) == REFERENCE_TYPE
-                                       && TYPE_VOLATILE (TREE_TYPE (type)))))))
-                   penalty = 2;
-                 else
-                   return TRIVIAL;
-               }
-               else
-                 penalty = 2;
-             }
-         }
-       else if (form == REFERENCE_TYPE)
-         {
-           if (parm)
-             {
-               tree tmp = convert_from_reference (parm);
-               intype = TYPE_MAIN_VARIANT (TREE_TYPE (tmp));
-             }
-           else
-             {
-               intype = parmtype;
-               do
-                 {
-                   intype = TREE_TYPE (intype);
-                 }
-               while (TREE_CODE (intype) == REFERENCE_TYPE);
-               intype = TYPE_MAIN_VARIANT (intype);
-             }
-
-           if (ttl == intype)
-             return TRIVIAL;
-           else
-             penalty = 2;
-         }
-
-       if (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (intype))
-         {
-           ttl = unsigned_type (ttl);
-           intype = unsigned_type (intype);
-           penalty += 2;
-         }
-
-       ttr = intype;
-
-       /* If the initializer is not an lvalue, then it does not
-          matter if we make life easier for the programmer
-          by creating a temporary variable with which to
-          hold the result.  */
-       if (parm && (coder == INTEGER_TYPE
-                    || coder == ENUMERAL_TYPE
-                    || coder == REAL_TYPE)
-           && ! lvalue_p (parm))
-         return (convert_harshness_old (ttl, ttr, NULL_TREE)
-                 | INT_TO_EASY_HARSHNESS (penalty));
-
-       if (ttl == ttr)
-         {
-           if (penalty)
-             return INT_TO_EASY_HARSHNESS (penalty);
-           return INT_TO_BD_HARSHNESS (0);
-         }
-
-       /* Pointers to voids always convert for pointers.  But
-          make them less natural than more specific matches.  */
-       if (TREE_CODE (ttl) == POINTER_TYPE && TREE_CODE (ttr) == POINTER_TYPE)
-         if (TREE_TYPE (ttl) == void_type_node
-             || TREE_TYPE (ttr) == void_type_node)
-           return INT_TO_EASY_HARSHNESS (penalty+1);
-
-       if (parm && codel != REFERENCE_TYPE)
-         return (convert_harshness_old (ttl, ttr, NULL_TREE)
-                 | INT_TO_EASY_HARSHNESS (penalty));
-
-       /* Here it does matter.  If this conversion is from
-          derived to base, allow it.  Otherwise, types must
-          be compatible in the strong sense.  */
-       if (TREE_CODE (ttl) == RECORD_TYPE && TREE_CODE (ttr) == RECORD_TYPE)
-         {
-           int b_or_d = get_base_distance (ttl, ttr, 0, 0);
-           if (b_or_d < 0)
-             {
-               b_or_d = get_base_distance (ttr, ttl, 0, 0);
-               if (b_or_d < 0)
-                 return EVIL;
-               return CONTRAVARIANT_HARSHNESS (-1);
-             }
-           /* Say that this conversion is relatively painless.
-              If it turns out that there is a user-defined X(X&)
-              constructor, then that will be invoked, but that's
-              preferable to dealing with other user-defined conversions
-              that may produce surprising results.  */
-           return INT_TO_BD_HARSHNESS (b_or_d);
-         }
-
-       if (comp_target_types (ttl, intype, 1))
-         return INT_TO_EASY_HARSHNESS (penalty);
-      }
-  }
-  if (codel == RECORD_TYPE && coder == RECORD_TYPE)
-    {
-      int b_or_d = get_base_distance (type, parmtype, 0, 0);
-      if (b_or_d < 0)
-       {
-         b_or_d = get_base_distance (parmtype, type, 0, 0);
-         if (b_or_d < 0)
-           return EVIL;
-         return CONTRAVARIANT_HARSHNESS (-1);
-       }
-      return INT_TO_BD_HARSHNESS (b_or_d);
-    }
-  return EVIL;
-}
-
-#ifdef DEBUG_MATCHING
-static char *
-print_harshness (h)
-     struct harshness_code *h;
-{
-  static char buf[1024];
-  char tmp[1024];
-
-  bzero (buf, 1024 * sizeof (char));
-  strcat (buf, "codes=[");
-  if (h->code & EVIL_CODE)
-    strcat (buf, "EVIL");
-  if (h->code & CONST_CODE)
-    strcat (buf, " CONST");
-  if (h->code & ELLIPSIS_CODE)
-    strcat (buf, " ELLIPSIS");
-  if (h->code & USER_CODE)
-    strcat (buf, " USER");
-  if (h->code & STD_CODE)
-    strcat (buf, " STD");
-  if (h->code & PROMO_CODE)
-    strcat (buf, " PROMO");
-  if (h->code & QUAL_CODE)
-    strcat (buf, " QUAL");
-  if (h->code & TRIVIAL_CODE)
-    strcat (buf, " TRIVIAL");
-  if (buf[0] == '\0')
-    strcat (buf, "0");
-
-  sprintf (tmp, "] distance=%d int_penalty=%d", h->distance, h->int_penalty);
-
-  strcat (buf, tmp);
-
-  return buf;
-}
-#endif
-
-/* Algorithm: For each argument, calculate how difficult it is to
-   make FUNCTION accept that argument.  If we can easily tell that
-   FUNCTION won't be acceptable to one of the arguments, then we
-   don't need to compute the ease of converting the other arguments,
-   since it will never show up in the intersection of all arguments'
-   favorite functions.
-
-   Conversions between builtin and user-defined types are allowed, but
-   no function involving such a conversion is preferred to one which
-   does not require such a conversion.  Furthermore, such conversions
-   must be unique.  */
-
-void
-compute_conversion_costs_ansi (function, tta_in, cp, arglen)
-     tree function;
-     tree tta_in;
-     struct candidate *cp;
-     int arglen;
-{
-  tree ttf_in = TYPE_ARG_TYPES (TREE_TYPE (function));
-  tree ttf = ttf_in;
-  tree tta = tta_in;
-
-  /* Start out with no strikes against.  */
-  int evil_strikes = 0;
-  int ellipsis_strikes = 0;
-  int user_strikes = 0;
-  int b_or_d_strikes = 0;
-  int easy_strikes = 0;
-
-  int strike_index = 0, win;
-  struct harshness_code lose;
-
-#ifdef GATHER_STATISTICS
-  n_compute_conversion_costs++;
-#endif
-
-  cp->function = function;
-  cp->arg = tta ? TREE_VALUE (tta) : NULL_TREE;
-  cp->u.bad_arg = 0;           /* optimistic!  */
-
-  cp->h.code = 0;
-  cp->h.distance = 0;
-  cp->h.int_penalty = 0;
-  bzero (cp->v.ansi_harshness,
-        (cp->h_len + 1) * sizeof (struct harshness_code));
-
-  while (ttf && tta)
-    {
-      struct harshness_code h;
-
-      if (ttf == void_list_node)
-       break;
-
-      if (type_unknown_p (TREE_VALUE (tta)))
-       {         
-         /* Must perform some instantiation here.  */
-         tree rhs = TREE_VALUE (tta);
-         tree lhstype = TREE_VALUE (ttf);
-
-         /* Keep quiet about possible contravariance violations.  */
-         int old_inhibit_warnings = inhibit_warnings;
-         inhibit_warnings = 1;
-
-         /* @@ This is to undo what `grokdeclarator' does to
-            parameter types.  It really should go through
-            something more general.  */
-
-         TREE_TYPE (tta) = unknown_type_node;
-         rhs = instantiate_type (lhstype, rhs, 0);
-         inhibit_warnings = old_inhibit_warnings;
-
-         if (TREE_CODE (rhs) == ERROR_MARK)
-           h.code = EVIL_CODE;
-         else
-           h = convert_harshness_ansi (lhstype, TREE_TYPE (rhs), rhs);
-       }
-      else
-       {
-#ifdef DEBUG_MATCHING
-         static tree old_function = NULL_TREE;
-
-         if (!old_function || function != old_function)
-           {
-             cp_error ("trying %D", function);
-             old_function = function;
-           }
-
-         cp_error ("      doing (%T) %E against arg %T",
-                   TREE_TYPE (TREE_VALUE (tta)), TREE_VALUE (tta),
-                   TREE_VALUE (ttf));
-#endif
-
-         h = convert_harshness_ansi (TREE_VALUE (ttf),
-                                     TREE_TYPE (TREE_VALUE (tta)),
-                                     TREE_VALUE (tta));
-
-#ifdef DEBUG_MATCHING
-         cp_error ("     evaluated %s", print_harshness (&h));
-#endif
-       }
-
-      cp->v.ansi_harshness[strike_index] = h;
-      if ((h.code & EVIL_CODE)
-         || ((h.code & STD_CODE) && h.distance < 0))
-       {
-         cp->u.bad_arg = strike_index;
-         evil_strikes = 1;
-       }
-     else if (h.code & ELLIPSIS_CODE)
-       ellipsis_strikes += 1;
-#if 0
-      /* This is never set by `convert_harshness_ansi'.  */
-      else if (h.code & USER_CODE)
-       {
-         user_strikes += 1;
-       }
-#endif
-      else
-       {
-         if ((h.code & STD_CODE) && h.distance)
-           {
-             if (h.distance > b_or_d_strikes)
-               b_or_d_strikes = h.distance;
-           }
-         else
-           easy_strikes += (h.code & (STD_CODE|PROMO_CODE|TRIVIAL_CODE));
-         cp->h.code |= h.code;
-         /* Make sure we communicate this.  */
-         cp->h.int_penalty += h.int_penalty;
-       }
-
-      ttf = TREE_CHAIN (ttf);
-      tta = TREE_CHAIN (tta);
-      strike_index += 1;
-    }
-
-  if (tta)
-    {
-      /* ran out of formals, and parmlist is fixed size.  */
-      if (ttf /* == void_type_node */)
-       {
-         cp->h.code = EVIL_CODE;
-         cp->u.bad_arg = -1;
-         return;
-       }
-      else
-       {
-         struct harshness_code h;
-         int l = list_length (tta);
-         ellipsis_strikes += l;
-         h.code = ELLIPSIS_CODE;
-         h.distance = 0;
-         h.int_penalty = 0;
-         for (; l; --l)
-           cp->v.ansi_harshness[strike_index++] = h;
-       }
-    }
-  else if (ttf && ttf != void_list_node)
-    {
-      /* ran out of actuals, and no defaults.  */
-      if (TREE_PURPOSE (ttf) == NULL_TREE)
-       {
-         cp->h.code = EVIL_CODE;
-         cp->u.bad_arg = -2;
-         return;
-       }
-      /* Store index of first default.  */
-      cp->v.ansi_harshness[arglen].distance = strike_index+1;
-    }
-  else
-    cp->v.ansi_harshness[arglen].distance = 0;
-
-  /* Argument list lengths work out, so don't need to check them again.  */
-  if (evil_strikes)
-    {
-      /* We do not check for derived->base conversions here, since in
-        no case would they give evil strike counts, unless such conversions
-        are somehow ambiguous.  */
-
-      /* See if any user-defined conversions apply.
-         But make sure that we do not loop.  */
-      static int dont_convert_types = 0;
-
-      if (dont_convert_types)
+      /* ran out of formals, and parmlist is fixed size.  */
+      if (ttf /* == void_type_node */)
        {
          cp->h.code = EVIL_CODE;
+         cp->u.bad_arg = -1;
          return;
        }
-
-      win = 0;                 /* Only get one chance to win.  */
-      ttf = TYPE_ARG_TYPES (TREE_TYPE (function));
-      tta = tta_in;
-      strike_index = 0;
-      evil_strikes = 0;
-
-      while (ttf && tta)
-       {
-         if (ttf == void_list_node)
-           break;
-
-         lose = cp->v.ansi_harshness[strike_index];
-         if ((lose.code & EVIL_CODE)
-             || ((lose.code & STD_CODE) && lose.distance < 0))
-           {
-             tree actual_type = TREE_TYPE (TREE_VALUE (tta));
-             tree formal_type = TREE_VALUE (ttf);
-             int extra_conversions = 0;
-
-             dont_convert_types = 1;
-
-             if (TREE_CODE (formal_type) == REFERENCE_TYPE)
-               formal_type = TREE_TYPE (formal_type);
-             if (TREE_CODE (actual_type) == REFERENCE_TYPE)
-               actual_type = TREE_TYPE (actual_type);
-
-             if (formal_type != error_mark_node
-                 && actual_type != error_mark_node)
-               {
-                 formal_type = TYPE_MAIN_VARIANT (formal_type);
-                 actual_type = TYPE_MAIN_VARIANT (actual_type);
-
-                 if (TYPE_HAS_CONSTRUCTOR (formal_type))
-                   {
-                     /* If it has a constructor for this type,
-                        try to use it.  */
-                     /* @@ There is no way to save this result yet, so
-                        success is a NULL_TREE for now.  */
-                     if (convert_to_aggr (formal_type, TREE_VALUE (tta), 0, 1)
-                         != error_mark_node)
-                       win++;
-                   }
-                 if (TYPE_LANG_SPECIFIC (actual_type)
-                     && TYPE_HAS_CONVERSION (actual_type))
-                   {
-                     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)
-                       {
-                         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++;
-                                 if (TREE_CODE (conv) != CALL_EXPR)
-                                   extra_conversions = 1;
-                               }
-                           }
-                       }
-                   }
-               }
-             dont_convert_types = 0;
-
-             if (win == 1)
-               {
-                 user_strikes += 1;
-                 cp->v.ansi_harshness[strike_index].code
-                   = USER_CODE | (extra_conversions ? STD_CODE : 0);
-                 win = 0;
-               }
-             else
-               {
-                 if (cp->u.bad_arg > strike_index)
-                   cp->u.bad_arg = strike_index;
-
-                 evil_strikes = win ? 2 : 1;
-                 break;
-               }
-           }
-
-         ttf = TREE_CHAIN (ttf);
-         tta = TREE_CHAIN (tta);
-         strike_index += 1;
-       }
-    }
-
-  /* Const member functions get a small penalty because defaulting
-     to const is less useful than defaulting to non-const. */
-  /* This is bogus, it does not correspond to anything in the ARM.
-     This code will be fixed when this entire section is rewritten
-     to conform to the ARM.  (mrs)  */
-  if (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
-    {
-      tree this_parm = TREE_VALUE (ttf_in);
-
-      if (TREE_CODE (this_parm) == RECORD_TYPE /* Is `this' a sig ptr?  */
-           ? TYPE_READONLY (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (this_parm))))
-           : TYPE_READONLY (TREE_TYPE (this_parm)))
-       {
-         cp->v.ansi_harshness[0].code |= TRIVIAL_CODE;
-         ++easy_strikes;
-       }
-      else
-       {
-         /* Calling a non-const member function from a const member function
-            is probably invalid, but for now we let it only draw a warning.
-            We indicate that such a mismatch has occurred by setting the
-            harshness to a maximum value.  */
-         if (TREE_CODE (TREE_TYPE (TREE_VALUE (tta_in))) == POINTER_TYPE
-             && (TYPE_READONLY (TREE_TYPE (TREE_TYPE (TREE_VALUE (tta_in))))))
-           cp->v.ansi_harshness[0].code |= CONST_CODE;
-       }
-    }
-
-  if (evil_strikes)
-    cp->h.code = EVIL_CODE;
-  if (ellipsis_strikes)
-    cp->h.code |= ELLIPSIS_CODE;
-  if (user_strikes)
-    cp->h.code |= USER_CODE;
-#ifdef DEBUG_MATCHING
-  cp_error ("final eval %s", print_harshness (&cp->h));
-#endif
-}
-
-void
-compute_conversion_costs_old (function, tta_in, cp, arglen)
-     tree function;
-     tree tta_in;
-     struct candidate *cp;
-     int arglen;
-{
-  tree ttf_in = TYPE_ARG_TYPES (TREE_TYPE (function));
-  tree ttf = ttf_in;
-  tree tta = tta_in;
-
-  /* Start out with no strikes against.  */
-  int evil_strikes = 0;
-  int ellipsis_strikes = 0;
-  int user_strikes = 0;
-  int b_or_d_strikes = 0;
-  int easy_strikes = 0;
-
-  int strike_index = 0, win, lose;
-
-#ifdef GATHER_STATISTICS
-  n_compute_conversion_costs++;
-#endif
-
-  cp->function = function;
-  cp->arg = tta ? TREE_VALUE (tta) : NULL_TREE;
-  cp->u.bad_arg = 0;           /* optimistic!  */
-
-  bzero (cp->v.old_harshness, (cp->h_len + 1) * sizeof (unsigned short));
-
-  while (ttf && tta)
-    {
-      int harshness;
-
-      if (ttf == void_list_node)
-       break;
-
-      if (type_unknown_p (TREE_VALUE (tta)))
-       {         
-         /* Must perform some instantiation here.  */
-         tree rhs = TREE_VALUE (tta);
-         tree lhstype = TREE_VALUE (ttf);
-
-         /* Keep quiet about possible contravariance violations.  */
-         int old_inhibit_warnings = inhibit_warnings;
-         inhibit_warnings = 1;
-
-         /* @@ This is to undo what `grokdeclarator' does to
-            parameter types.  It really should go through
-            something more general.  */
-
-         TREE_TYPE (tta) = unknown_type_node;
-         rhs = instantiate_type (lhstype, rhs, 0);
-         inhibit_warnings = old_inhibit_warnings;
-
-         if (TREE_CODE (rhs) == ERROR_MARK)
-           harshness = 1;
-         else
-           {
-             harshness = convert_harshness_old (lhstype, TREE_TYPE (rhs),
-                                                rhs);
-             /* harshness |= 2; */
-           }
-       }
-      else
-       harshness = convert_harshness_old (TREE_VALUE (ttf),
-                                          TREE_TYPE (TREE_VALUE (tta)),
-                                          TREE_VALUE (tta));
-
-      cp->v.old_harshness[strike_index] = harshness;
-      if (EVIL_HARSHNESS (harshness)
-         || CONTRAVARIANT_HARSHNESS (harshness))
-       {
-         cp->u.bad_arg = strike_index;
-         evil_strikes = 1;
-       }
-     else if (ELLIPSIS_HARSHNESS (harshness))
-       {
-         ellipsis_strikes += 1;
-       }
-#if 0
-      /* This is never set by `convert_harshness_old'.  */
-      else if (USER_HARSHNESS (harshness))
-       {
-         user_strikes += 1;
-       }
-#endif
-      else if (BASE_DERIVED_HARSHNESS (harshness))
-       {
-         b_or_d_strikes += INT_FROM_BD_HARSHNESS (harshness);
-       }
       else
-       easy_strikes += INT_FROM_EASY_HARSHNESS (harshness);
-      ttf = TREE_CHAIN (ttf);
-      tta = TREE_CHAIN (tta);
-      strike_index += 1;
-    }
-
-  if (tta)
-    {
-      /* ran out of formals, and parmlist is fixed size.  */
-      if (ttf /* == void_type_node */)
-       {
-         cp->evil = 1;
-         cp->u.bad_arg = -1;
-         return;
+       {
+         struct harshness_code h;
+         int l = list_length (tta);
+         ellipsis_strikes += l;
+         h.code = ELLIPSIS_CODE;
+         h.distance = 0;
+         h.int_penalty = 0;
+         for (; l; --l)
+           cp->harshness[strike_index++] = h;
        }
-      else ellipsis_strikes += list_length (tta);
     }
   else if (ttf && ttf != void_list_node)
     {
       /* ran out of actuals, and no defaults.  */
       if (TREE_PURPOSE (ttf) == NULL_TREE)
        {
-         cp->evil = 1;
+         cp->h.code = EVIL_CODE;
          cp->u.bad_arg = -2;
          return;
        }
       /* Store index of first default.  */
-      cp->v.old_harshness[arglen] = strike_index+1;
+      cp->harshness[arglen].distance = strike_index+1;
     }
   else
-    cp->v.old_harshness[arglen] = 0;
+    cp->harshness[arglen].distance = 0;
 
   /* Argument list lengths work out, so don't need to check them again.  */
   if (evil_strikes)
@@ -1706,7 +905,7 @@ compute_conversion_costs_old (function, tta_in, cp, arglen)
 
       if (dont_convert_types)
        {
-         cp->evil = 1;
+         cp->h.code = EVIL_CODE;
          return;
        }
 
@@ -1721,12 +920,13 @@ compute_conversion_costs_old (function, tta_in, cp, arglen)
          if (ttf == void_list_node)
            break;
 
-         lose = cp->v.old_harshness[strike_index];
-         if (EVIL_HARSHNESS (lose)
-             || CONTRAVARIANT_HARSHNESS (lose))
+         lose = cp->harshness[strike_index];
+         if ((lose.code & EVIL_CODE)
+             || ((lose.code & STD_CODE) && lose.distance < 0))
            {
              tree actual_type = TREE_TYPE (TREE_VALUE (tta));
              tree formal_type = TREE_VALUE (ttf);
+             int extra_conversions = 0;
 
              dont_convert_types = 1;
 
@@ -1743,42 +943,52 @@ compute_conversion_costs_old (function, tta_in, cp, arglen)
 
                  if (TYPE_HAS_CONSTRUCTOR (formal_type))
                    {
-                     /* If it has a constructor for this type, try to use it.  */
+                     /* If it has a constructor for this type,
+                        try to use it.  */
+                     /* @@ There is no way to save this result yet, so
+                        success is a NULL_TREE for now.  */
                      if (convert_to_aggr (formal_type, TREE_VALUE (tta), 0, 1)
                          != error_mark_node)
-                       {
-                         /* @@ There is no way to save this result yet.
-                            @@ So success is NULL_TREE for now.  */
-                         win++;
-                       }
+                       win++;
                    }
-                 if (TYPE_LANG_SPECIFIC (actual_type) && TYPE_HAS_CONVERSION (actual_type))
+                 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)
+                       {
+                         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)
                        {
-                         tree conv = build_type_conversion (CALL_EXPR, TREE_VALUE (ttf), TREE_VALUE (tta), 0);
+                         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;
                                }
                            }
                        }
@@ -1789,7 +999,8 @@ compute_conversion_costs_old (function, tta_in, cp, arglen)
              if (win == 1)
                {
                  user_strikes += 1;
-                 cp->v.old_harshness[strike_index] = USER_HARSHNESS (-1);
+                 cp->harshness[strike_index].code
+                   = USER_CODE | (extra_conversions ? STD_CODE : 0);
                  win = 0;
                }
              else
@@ -1821,7 +1032,7 @@ compute_conversion_costs_old (function, tta_in, cp, arglen)
            ? TYPE_READONLY (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (this_parm))))
            : TYPE_READONLY (TREE_TYPE (this_parm)))
        {
-         cp->v.old_harshness[0] += INT_TO_EASY_HARSHNESS (1);
+         cp->harshness[0].code |= TRIVIAL_CODE;
          ++easy_strikes;
        }
       else
@@ -1832,371 +1043,19 @@ compute_conversion_costs_old (function, tta_in, cp, arglen)
             harshness to a maximum value.  */
          if (TREE_CODE (TREE_TYPE (TREE_VALUE (tta_in))) == POINTER_TYPE
              && (TYPE_READONLY (TREE_TYPE (TREE_TYPE (TREE_VALUE (tta_in))))))
-           cp->v.old_harshness[0] |= CONST_HARSHNESS (-1);
-       }
-    }
-
-  cp->evil = evil_strikes;
-  cp->ellipsis = ellipsis_strikes;
-  cp->user = user_strikes;
-  cp->b_or_d = b_or_d_strikes;
-  cp->easy = easy_strikes;
-}
-
-void
-compute_conversion_costs (function, tta_in, cp, arglen)
-     tree function;
-     tree tta_in;
-     struct candidate *cp;
-     int arglen;
-{
-  if (flag_ansi_overloading)
-    compute_conversion_costs_ansi (function, tta_in, cp, arglen);
-  else
-    compute_conversion_costs_old (function, tta_in, cp, arglen);
-}
-
-/* When one of several possible overloaded functions and/or methods
-   can be called, choose the best candidate for overloading.
-
-   BASETYPE is the context from which we start method resolution
-   or NULL if we are comparing overloaded functions.
-   CANDIDATES is the array of candidates we have to choose from.
-   N_CANDIDATES is the length of CANDIDATES.
-   PARMS is a TREE_LIST of parameters to the function we'll ultimately
-   choose.  It is modified in place when resolving methods.  It is not
-   modified in place when resolving overloaded functions.
-   LEN is the length of the parameter list.  */
-
-static struct candidate *
-ideal_candidate_old (basetype, candidates, n_candidates, parms, len)
-     tree basetype;
-     struct candidate *candidates;
-     int n_candidates;
-     tree parms;
-     int len;
-{
-  struct candidate *cp = candidates + n_candidates;
-  int index, i;
-  tree ttf;
-
-  qsort (candidates,           /* char *base */
-        n_candidates,          /* int nel */
-        sizeof (struct candidate), /* int width */
-        rank_for_overload);    /* int (*compar)() */
-
-  /* If the best candidate requires user-defined conversions,
-     and its user-defined conversions are a strict subset
-     of all other candidates requiring user-defined conversions,
-     then it is, in fact, the best.  */
-  for (i = -1; cp + i != candidates; i--)
-    if (cp[i].user == 0)
-      break;
-
-  if (i < -1)
-    {
-      tree ttf0;
-
-      /* Check that every other candidate requires those conversions
-        as a strict subset of their conversions.  */
-      if (cp[i].user == cp[-1].user)
-       goto non_subset;
-
-      /* Look at subset relationship more closely.  */
-      while (i != -1)
-       {
-         for (ttf = TYPE_ARG_TYPES (TREE_TYPE (cp[i].function)),
-              ttf0 = TYPE_ARG_TYPES (TREE_TYPE (cp[-1].function)),
-              index = 0; index < len; index++)
-           {
-             if (USER_HARSHNESS (cp[i].v.old_harshness[index]))
-               {
-                 /* If our "best" candidate also needs a conversion,
-                    it must be the same one.  */
-                 if (USER_HARSHNESS (cp[-1].v.old_harshness[index])
-                     && TREE_VALUE (ttf) != TREE_VALUE (ttf0))
-                   goto non_subset;
-               }
-             ttf = TREE_CHAIN (ttf);
-             ttf0 = TREE_CHAIN (ttf0);
-             /* Handle `...' gracefully.  */
-             if (ttf == NULL_TREE || ttf0 == NULL_TREE)
-               break;
-           }
-         i++;
+           cp->harshness[0].code |= CONST_CODE;
        }
-      /* The best was the best.  */
-      return cp - 1;
-    non_subset:
-      /* Use other rules for determining "bestness".  */
-      ;
     }
 
-  /* If the best two candidates we find require user-defined
-     conversions, we may need to report and error message.  */
-  if (cp[-1].user && cp[-2].user
-      && (cp[-1].b_or_d || cp[-2].b_or_d == 0))
-    {
-      /* If the best two methods found involved user-defined
-        type conversions, then we must see whether one
-        of them is exactly what we wanted.  If not, then
-        we have an ambiguity.  */
-      int best = 0;
-      tree tta = parms;
-      tree f1;
-#if 0
-      /* for LUCID */
-      tree p1;
-#endif
-
-      /* Stash all of our parameters in safe places
-        so that we can perform type conversions in place.  */
-      while (tta)
-       {
-         TREE_PURPOSE (tta) = TREE_VALUE (tta);
-         tta = TREE_CHAIN (tta);
-       }
-
-      i = 0;
-      do
-       {
-         int exact_conversions = 0;
-
-         i -= 1;
-         tta = parms;
-         if (DECL_STATIC_FUNCTION_P (cp[i].function))
-           tta = TREE_CHAIN (tta);
-         /* special note, we don't go through len parameters, because we
-            may only need len-1 parameters because of a call to a static
-            member. */
-         for (ttf = TYPE_ARG_TYPES (TREE_TYPE (cp[i].function)), index = 0;
-              tta;
-              tta = TREE_CHAIN (tta), ttf = TREE_CHAIN (ttf), index++)
-           {
-             /* If this is a varargs function, there's no conversion to do,
-                but don't accept an arg that needs a copy ctor.  */
-             if (ttf == NULL_TREE)
-               {
-                 /* FIXME: verify that we cannot get here with an
-                    arg that needs a ctor.  */
-                 break;
-               }
-
-             if (USER_HARSHNESS (cp[i].v.old_harshness[index]))
-               {
-                 tree this_parm = build_type_conversion (CALL_EXPR, TREE_VALUE (ttf), TREE_PURPOSE (tta), 2);
-                 if (basetype != NULL_TREE)
-                   TREE_VALUE (tta) = this_parm;
-                 if (this_parm)
-                   {
-                     if (TREE_CODE (this_parm) != CONVERT_EXPR
-                         && (TREE_CODE (this_parm) != NOP_EXPR
-                             || comp_target_types (TREE_TYPE (this_parm),
-                                                   TREE_TYPE (TREE_OPERAND (this_parm, 0)), 1)))
-                       exact_conversions += 1;
-                   }
-                 else if (PROMOTES_TO_AGGR_TYPE (TREE_VALUE (ttf), REFERENCE_TYPE))
-                   {
-                     /* To get here we had to have succeeded via
-                        a constructor.  */
-                     TREE_VALUE (tta) = TREE_PURPOSE (tta);
-                     exact_conversions += 1;
-                   }
-               }
-           }
-         if (exact_conversions == cp[i].user)
-           {
-             if (best == 0)
-               {
-                 best = i;
-                 f1 = cp[best].function;
-#if 0
-                 /* For LUCID */
-                 p1 = TYPE_ARG_TYPES (TREE_TYPE (f1));
-#endif
-               }
-             else
-               {
-                 /* Don't complain if next best is from base class.  */
-                 tree f2 = cp[i].function;
-
-                 if (TREE_CODE (TREE_TYPE (f1)) == METHOD_TYPE
-                     && TREE_CODE (TREE_TYPE (f2)) == METHOD_TYPE
-                     && BASE_DERIVED_HARSHNESS (cp[i].v.old_harshness[0])
-                     && cp[best].v.old_harshness[0] < cp[i].v.old_harshness[0])
-                   {
-#if 0
-                     tree p2 = TYPE_ARG_TYPES (TREE_TYPE (f2));
-                     /* For LUCID.  */
-                     if (! compparms (TREE_CHAIN (p1), TREE_CHAIN (p2), 1))
-                       goto ret0;
-                     else
+  if (evil_strikes)
+    cp->h.code = EVIL_CODE;
+  if (ellipsis_strikes)
+    cp->h.code |= ELLIPSIS_CODE;
+  if (user_strikes)
+    cp->h.code |= USER_CODE;
+#ifdef DEBUG_MATCHING
+  cp_error ("final eval %s", print_harshness (&cp->h));
 #endif
-                       continue;
-                   }
-                 else
-                   {
-                     /* Ensure that there's nothing ambiguous about these
-                        two fns.  */
-                     int identical = 1;
-                     for (index = 0; index < len; index++)
-                       {
-                         /* Type conversions must be piecewise equivalent.  */
-                         if (USER_HARSHNESS (cp[best].v.old_harshness[index])
-                             != USER_HARSHNESS (cp[i].v.old_harshness[index]))
-                           goto ret0;
-                         /* If there's anything we like better about the
-                            other function, consider it ambiguous.  */
-                         if (cp[i].v.old_harshness[index] < cp[best].v.old_harshness[index])
-                           goto ret0;
-                         /* If any single one it diffent, then the whole is
-                            not identical.  */
-                         if (cp[i].v.old_harshness[index] != cp[best].v.old_harshness[index])
-                           identical = 0;
-                       }
-
-                     /* If we can't tell the difference between the two, it
-                        is ambiguous.  */
-                     if (identical)
-                       goto ret0;
-
-                     /* If we made it to here, it means we're satisfied that
-                        BEST is still best.  */
-                     continue;
-                   }
-               }
-           }
-       } while (cp + i != candidates);
-
-      if (best)
-       {
-         int exact_conversions = cp[best].user;
-         tta = parms;
-         if (DECL_STATIC_FUNCTION_P (cp[best].function))
-           tta = TREE_CHAIN (parms);
-         for (ttf = TYPE_ARG_TYPES (TREE_TYPE (cp[best].function)), index = 0;
-              exact_conversions > 0;
-              tta = TREE_CHAIN (tta), ttf = TREE_CHAIN (ttf), index++)
-           {
-             if (USER_HARSHNESS (cp[best].v.old_harshness[index]))
-               {
-                 /* We must now fill in the slot we left behind.
-                    @@ This could be optimized to use the value previously
-                    @@ computed by build_type_conversion in some cases.  */
-                 if (basetype != NULL_TREE)
-                   TREE_VALUE (tta) = convert (TREE_VALUE (ttf), TREE_PURPOSE (tta));
-                 exact_conversions -= 1;
-               }
-             else
-               TREE_VALUE (tta) = TREE_PURPOSE (tta);
-           }
-         return cp + best;
-       }
-      goto ret0;
-    }
-  /* If the best two candidates we find both use default parameters,
-     we may need to report and error.  Don't need to worry if next-best
-     candidate is forced to use user-defined conversion when best is not.  */
-  if (cp[-2].user == 0
-      && cp[-1].v.old_harshness[len] != 0 && cp[-2].v.old_harshness[len] != 0)
-    {
-      tree tt1 = TYPE_ARG_TYPES (TREE_TYPE (cp[-1].function));
-      tree tt2 = TYPE_ARG_TYPES (TREE_TYPE (cp[-2].function));
-      unsigned i = cp[-1].v.old_harshness[len];
-
-      if (cp[-2].v.old_harshness[len] < i)
-       i = cp[-2].v.old_harshness[len];
-      while (--i > 0)
-       {
-         if (TYPE_MAIN_VARIANT (TREE_VALUE (tt1))
-             != TYPE_MAIN_VARIANT (TREE_VALUE (tt2)))
-           /* These lists are not identical, so we can choose our best candidate.  */
-           return cp - 1;
-         tt1 = TREE_CHAIN (tt1);
-         tt2 = TREE_CHAIN (tt2);
-       }
-      /* To get here, both lists had the same parameters up to the defaults
-        which were used.  This is an ambiguous request.  */
-      goto ret0;
-    }
-
-  /* Otherwise, return our best candidate.  Note that if we get candidates
-     from independent base classes, we have an ambiguity, even if one
-     argument list look a little better than another one.  */
-  if (cp[-1].b_or_d && basetype && TYPE_USES_MULTIPLE_INHERITANCE (basetype))
-    {
-      int i = n_candidates - 1, best = i;
-      tree base1 = NULL_TREE;
-
-      if (TREE_CODE (TREE_TYPE (candidates[i].function)) == FUNCTION_TYPE)
-       return cp - 1;
-
-      for (; i >= 0 && candidates[i].user == 0 && candidates[i].evil == 0; i--)
-       {
-         if (TREE_CODE (TREE_TYPE (candidates[i].function)) == METHOD_TYPE)
-           {
-             tree newbase = DECL_CLASS_CONTEXT (candidates[i].function);
-
-             if (base1 != NULL_TREE)
-               {
-                 /* newbase could be a base or a parent of base1 */
-                 if (newbase != base1 && ! UNIQUELY_DERIVED_FROM_P (newbase, base1)
-                     && ! UNIQUELY_DERIVED_FROM_P (base1, newbase))
-                   {
-                     cp_error ("ambiguous request for function from distinct base classes of type `%T'", basetype);
-                     cp_error_at ("  first candidate is `%#D'",
-                                    candidates[best].function);
-                     cp_error_at ("  second candidate is `%#D'",
-                                    candidates[i].function);
-                     cp[-1].evil = 1;
-                     return cp - 1;
-                   }
-               }
-             else
-               {
-                 best = i;
-                 base1 = newbase;
-               }
-           }
-         else
-           return cp - 1;
-       }
-    }
-
-  /* Don't accept a candidate as being ideal if it's indistinguishable
-     from another candidate.  */
-  if (rank_for_overload (cp-1, cp-2) == 0)
-    {
-      /* If the types are distinguishably different (like
-        `long' vs. `unsigned long'), that's ok.  But if they are arbitrarily
-        different, such as `int (*)(void)' vs. `void (*)(int)',
-        that's not ok.  */
-      tree p1 = TYPE_ARG_TYPES (TREE_TYPE (cp[-1].function));
-      tree p2 = TYPE_ARG_TYPES (TREE_TYPE (cp[-2].function));
-      while (p1 && p2)
-       {
-         if (TREE_CODE (TREE_VALUE (p1)) == POINTER_TYPE
-             && TREE_CODE (TREE_TYPE (TREE_VALUE (p1))) == FUNCTION_TYPE
-             && TREE_VALUE (p1) != TREE_VALUE (p2))
-           return NULL;
-         p1 = TREE_CHAIN (p1);
-         p2 = TREE_CHAIN (p2);
-       }
-      if (p1 || p2)
-       return NULL;
-    }
-
-  return cp - 1;
-
- ret0:
-  /* In the case where there is no ideal candidate, restore
-     TREE_VALUE slots of PARMS from TREE_PURPOSE slots.  */
-  while (parms)
-    {
-      TREE_VALUE (parms) = TREE_PURPOSE (parms);
-      parms = TREE_CHAIN (parms);
-    }
-  return NULL;
 }
 
 /* Subroutine of ideal_candidate.  See if X or Y is a better match
@@ -2216,8 +1075,20 @@ strictly_better (x, y)
   return 0;
 }
 
+/* When one of several possible overloaded functions and/or methods
+   can be called, choose the best candidate for overloading.
+
+   BASETYPE is the context from which we start method resolution
+   or NULL if we are comparing overloaded functions.
+   CANDIDATES is the array of candidates we have to choose from.
+   N_CANDIDATES is the length of CANDIDATES.
+   PARMS is a TREE_LIST of parameters to the function we'll ultimately
+   choose.  It is modified in place when resolving methods.  It is not
+   modified in place when resolving overloaded functions.
+   LEN is the length of the parameter list.  */
+
 static struct candidate *
-ideal_candidate_ansi (basetype, candidates, n_candidates, parms, len)
+ideal_candidate (basetype, candidates, n_candidates, parms, len)
      tree basetype;
      struct candidate *candidates;
      int n_candidates;
@@ -2278,27 +1149,27 @@ ideal_candidate_ansi (basetype, candidates, n_candidates, parms, len)
             rank_for_ideal);
       for (i = 0; i < len; i++)
        {
-         if (cp[-1].v.ansi_harshness[i].code < cp[-2].v.ansi_harshness[i].code)
+         if (cp[-1].harshness[i].code < cp[-2].harshness[i].code)
            better = 1;
-         else if (cp[-1].v.ansi_harshness[i].code > cp[-2].v.ansi_harshness[i].code)
+         else if (cp[-1].harshness[i].code > cp[-2].harshness[i].code)
            worse = 1;
-         else if (cp[-1].v.ansi_harshness[i].code & STD_CODE)
+         else if (cp[-1].harshness[i].code & STD_CODE)
            {
              /* If it involves a standard conversion, let the
                 inheritance lattice be the final arbiter.  */
-             if (cp[-1].v.ansi_harshness[i].distance > cp[-2].v.ansi_harshness[i].distance)
+             if (cp[-1].harshness[i].distance > cp[-2].harshness[i].distance)
                worse = 1;
-             else if (cp[-1].v.ansi_harshness[i].distance < cp[-2].v.ansi_harshness[i].distance)
+             else if (cp[-1].harshness[i].distance < cp[-2].harshness[i].distance)
                better = 1;
            }
-         else if (cp[-1].v.ansi_harshness[i].code & PROMO_CODE)
+         else if (cp[-1].harshness[i].code & PROMO_CODE)
            {
              /* For integral promotions, take into account a finer
                 granularity for determining which types should be favored
                 over others in such promotions.  */
-             if (cp[-1].v.ansi_harshness[i].int_penalty > cp[-2].v.ansi_harshness[i].int_penalty)
+             if (cp[-1].harshness[i].int_penalty > cp[-2].harshness[i].int_penalty)
                worse = 1;
-             else if (cp[-1].v.ansi_harshness[i].int_penalty < cp[-2].v.ansi_harshness[i].int_penalty)
+             else if (cp[-1].harshness[i].int_penalty < cp[-2].harshness[i].int_penalty)
                better = 1;
            }
        }
@@ -2309,22 +1180,6 @@ ideal_candidate_ansi (basetype, candidates, n_candidates, parms, len)
   return cp-1;
 }
 
-static struct candidate *
-ideal_candidate (basetype, candidates, n_candidates, parms, len)
-     tree basetype;
-     struct candidate *candidates;
-     int n_candidates;
-     tree parms;
-     int len;
-{
-  if (flag_ansi_overloading)
-    return ideal_candidate_ansi (basetype, candidates, n_candidates, parms,
-                                len);
-  else
-    return ideal_candidate_old (basetype, candidates, n_candidates, parms,
-                               len);
-}
-
 /* Assume that if the class referred to is not in the
    current class hierarchy, that it may be remote.
    PARENT is assumed to be of aggregate type here.  */
@@ -3252,12 +2107,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
                my_friendly_abort (167);
 
              cp->h_len = len;
-             if (flag_ansi_overloading)
-               cp->v.ansi_harshness = (struct harshness_code *)
-                 alloca ((len + 1) * sizeof (struct harshness_code));
-             else
-               cp->v.old_harshness = (unsigned short *)
-                 alloca ((len + 1) * sizeof (unsigned short));
+             cp->harshness = (struct harshness_code *)
+               alloca ((len + 1) * sizeof (struct harshness_code));
 
              result = build_overload_call (name, friend_parms, 0, cp);
              /* If it turns out to be the one we were actually looking for
@@ -3266,30 +2117,16 @@ build_method_call (instance, name, parms, basetype_path, flags)
              if (TREE_CODE (result) == CALL_EXPR)
                return result;
 
-             if (flag_ansi_overloading)
-               while ((cp->h.code & EVIL_CODE) == 0)
-                 {
-                   /* non-standard uses: set the field to 0 to indicate
-                      we are using a non-member function.  */
-                   cp->u.field = 0;
-                   if (cp->v.ansi_harshness[len].distance == 0
-                       && cp->h.code < best)
-                     best = cp->h.code;
-                   cp += 1;
-                 }
-             else
-               while (cp->evil == 0)
-                 {
-                   /* non-standard uses: set the field to 0 to indicate
-                      we are using a non-member function.  */
-                   cp->u.field = 0;
-                   if (cp->v.old_harshness[len] == 0
-                       && cp->v.old_harshness[len] == 0
-                       && cp->ellipsis == 0 && cp->user == 0 && cp->b_or_d == 0
-                       && cp->easy < best)
-                     best = cp->easy;
-                   cp += 1;
-                 }
+             while ((cp->h.code & EVIL_CODE) == 0)
+               {
+                 /* non-standard uses: set the field to 0 to indicate
+                    we are using a non-member function.  */
+                 cp->u.field = 0;
+                 if (cp->harshness[len].distance == 0
+                     && cp->h.code < best)
+                   best = cp->h.code;
+                 cp += 1;
+               }
            }
        }
 
@@ -3357,22 +2194,14 @@ build_method_call (instance, name, parms, basetype_path, flags)
                  n_inner_fields_searched++;
 #endif
                  cp->h_len = len;
-                 if (flag_ansi_overloading)
-                   cp->v.ansi_harshness = (struct harshness_code *)
-                     alloca ((len + 1) * sizeof (struct harshness_code));
-                 else
-                   cp->v.old_harshness = (unsigned short *)
-                     alloca ((len + 1) * sizeof (unsigned short));
+                 cp->harshness = (struct harshness_code *)
+                   alloca ((len + 1) * sizeof (struct harshness_code));
 
                  if (DECL_STATIC_FUNCTION_P (function))
                    these_parms = TREE_CHAIN (these_parms);
                  compute_conversion_costs (function, these_parms, cp, len);
 
-                 if (!flag_ansi_overloading)
-                     cp->b_or_d += b_or_d;
-
-                 if ((flag_ansi_overloading && (cp->h.code & EVIL_CODE) == 0)
-                     || (!flag_ansi_overloading && cp->evil == 0))
+                 if ((cp->h.code & EVIL_CODE) == 0)
                    {
                      cp->u.field = function;
                      cp->function = function;
@@ -3380,10 +2209,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
 
                      /* No "two-level" conversions.  */
                      if (flags & LOOKUP_NO_CONVERSION
-                         && ((flag_ansi_overloading
-                              && (cp->h.code & USER_CODE))
-                             || (!flag_ansi_overloading
-                                 && cp->user != 0)))
+                         && (cp->h.code & USER_CODE))
                        continue;
 
                      /* If we used default parameters, we must
@@ -3391,14 +2217,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
                         use them also, and report a possible
                         ambiguity.  */
                      if (! TYPE_USES_MULTIPLE_INHERITANCE (save_basetype)
-                         && ((flag_ansi_overloading
-                              && cp->v.ansi_harshness[len].distance == 0
-                              && cp->h.code < best)
-                             || (!flag_ansi_overloading
-                                 && cp->v.old_harshness[len] == 0
-                                 && CONST_HARSHNESS (cp->v.old_harshness[0]) == 0
-                                 && cp->ellipsis == 0 && cp->user == 0 && cp->b_or_d == 0
-                                 && cp->easy < best)))
+                         && cp->harshness[len].distance == 0
+                         && cp->h.code < best)
                        {
                          if (! DECL_STATIC_FUNCTION_P (function))
                            TREE_VALUE (parms) = cp->arg;
@@ -3472,12 +2292,10 @@ build_method_call (instance, name, parms, basetype_path, flags)
                    }
                  return error_mark_node;
                }
-             if ((flag_ansi_overloading && (cp->h.code & EVIL_CODE))
-                 || (!flag_ansi_overloading && cp->evil))
+             if (cp->h.code & EVIL_CODE)
                return error_mark_node;
            }
-         else if ((flag_ansi_overloading && (cp[-1].h.code & EVIL_CODE))
-                  || (!flag_ansi_overloading && cp[-1].evil == 2))
+         else if (cp[-1].h.code & EVIL_CODE)
            {
              if (flags & LOOKUP_COMPLAIN)
                cp_error ("ambiguous type conversion requested for %s `%D'",
@@ -3546,10 +2364,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
       continue;
 
     found_and_maybe_warn:
-      if (((flag_ansi_overloading
-           && (cp->v.ansi_harshness[0].code & CONST_CODE))
-          || (!flag_ansi_overloading
-              && CONST_HARSHNESS (cp->v.old_harshness[0])))
+      if ((cp->harshness[0].code & CONST_CODE)
          /* 12.1p2: Constructors can be called for const objects.  */
          && ! DECL_CONSTRUCTOR_P (cp->function))
        {
@@ -3869,24 +2684,11 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
 
   if (final_cp)
     {
-      if (flag_ansi_overloading)
-       {
-         final_cp[0].h.code = 0;
-         final_cp[0].h.distance = 0;
-         final_cp[0].function = 0;
-         /* end marker.  */
-         final_cp[1].h.code = EVIL_CODE;
-       }
-      else
-       {
-         final_cp[0].evil = 0;
-         final_cp[0].user = 0;
-         final_cp[0].b_or_d = 0;
-         final_cp[0].easy = 0;
-         final_cp[0].function = 0;
-         /* end marker.  */
-         final_cp[1].evil = 1;
-       }
+      final_cp[0].h.code = 0;
+      final_cp[0].h.distance = 0;
+      final_cp[0].function = 0;
+      /* end marker.  */
+      final_cp[1].h.code = EVIL_CODE;
     }
 
   for (parm = parms; parm; parm = TREE_CHAIN (parm))
@@ -3896,12 +2698,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
       if (t == error_mark_node)
        {
          if (final_cp)
-           {
-             if (flag_ansi_overloading)
-               final_cp->h.code = EVIL_CODE;
-             else
-               final_cp->evil = 1;
-           }
+           final_cp->h.code = EVIL_CODE;
          return error_mark_node;
        }
       if (TREE_CODE (t) == ARRAY_TYPE || TREE_CODE (t) == OFFSET_TYPE)
@@ -3920,26 +2717,6 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
   else
     parmtypes = void_list_node;
 
-  if (! flag_ansi_overloading)
-    {
-      tree fn;
-
-      /* This is a speed improvement that ends up not working properly in
-        the situation of fns with and without default parameters.  I turned
-        this off in the new method so it'll go through the argument matching
-        code to properly diagnose a match/failure. (bpk)  */
-      overload_name = build_decl_overload (fnname, parmtypes, 0);
-      fn = lookup_name_nonclass (overload_name);
-
-      /* Now check to see whether or not we can win.
-        Note that if we are called from `build_method_call',
-        then we cannot have a mis-match, because we would have
-        already found such a winning case.  */
-
-      if (fn && TREE_CODE (fn) == FUNCTION_DECL)
-       return build_function_call (DECL_MAIN_VARIANT (fn), parms);
-    }
-
   functions = lookup_name_nonclass (fnname);
 
   if (functions == NULL_TREE)
@@ -3949,12 +2726,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
       if (flags & LOOKUP_COMPLAIN)
        error ("only member functions apply");
       if (final_cp)
-       {
-         if (flag_ansi_overloading)
-           final_cp->h.code = EVIL_CODE;
-         else
-           final_cp->evil = 1;
-       }
+       final_cp->h.code = EVIL_CODE;
       return error_mark_node;
     }
 
@@ -3982,12 +2754,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
        cp_error ("function `%D' declared overloaded, but no instances of that function declared",
                  TREE_PURPOSE (functions));
       if (final_cp)
-       {
-         if (flag_ansi_overloading)
-           final_cp->h.code = EVIL_CODE;
-         else
-           final_cp->evil = 1;
-       }
+       final_cp->h.code = EVIL_CODE;
       return error_mark_node;
     }
 
@@ -4061,10 +2828,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
          /* Unconverted template -- failed match.  */
          cp->function = function;
          cp->u.bad_arg = -4;
-         if (flag_ansi_overloading)
-           cp->h.code = EVIL_CODE;
-         else
-           cp->evil = 1;
+         cp->h.code = EVIL_CODE;
        }
       else
        {
@@ -4086,60 +2850,30 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
          /* Can't use alloca here, since result might be
             passed to calling function.  */
          cp->h_len = parmlength;
-         if (flag_ansi_overloading)
-           cp->v.ansi_harshness = (struct harshness_code *)
-             oballoc ((parmlength + 1) * sizeof (struct harshness_code));
-         else
-           cp->v.old_harshness = (unsigned short *)
-             oballoc ((parmlength + 1) * sizeof (unsigned short));
+         cp->harshness = (struct harshness_code *)
+           oballoc ((parmlength + 1) * sizeof (struct harshness_code));
 
          compute_conversion_costs (function, parms, cp, parmlength);
 
-         if (flag_ansi_overloading)
-           /* Make sure this is clear as well.  */
-           cp->h.int_penalty += template_cost;
-         else
-           /* Should really add another field...  */
-           cp->easy = cp->easy * 128 + template_cost;
+         /* Make sure this is clear as well.  */
+         cp->h.int_penalty += template_cost;
 
-         /* It seemed easier to have both if stmts in here, rather
-            than excluding the hell out of it with flag_ansi_overloading
-            everywhere. (bpk) */
-         if (flag_ansi_overloading)
-           {
-             if ((cp[0].h.code & EVIL_CODE) == 0)
-               {
-                 cp[1].h.code = EVIL_CODE;
-
-                 /* int_penalty is set by convert_harshness_ansi for cases
-                    where we need to know about any penalties that would
-                    otherwise make a TRIVIAL_CODE pass.  */
-                 if (final_cp
-                     && template_cost == 0
-                     && cp[0].h.code <= TRIVIAL_CODE
-                     && cp[0].h.int_penalty == 0)
-                   {
-                     final_cp[0].h = cp[0].h;
-                     return function;
-                   }
-                 cp++;
-               }
-           }
-         else
+         if ((cp[0].h.code & EVIL_CODE) == 0)
            {
-             if (cp[0].evil == 0)
+             cp[1].h.code = EVIL_CODE;
+
+             /* int_penalty is set by convert_harshness_ansi for cases
+                where we need to know about any penalties that would
+                otherwise make a TRIVIAL_CODE pass.  */
+             if (final_cp
+                 && template_cost == 0
+                 && cp[0].h.code <= TRIVIAL_CODE
+                 && cp[0].h.int_penalty == 0)
                {
-                 cp[1].evil = 1;
-                 if (final_cp
-                     && cp[0].user == 0 && cp[0].b_or_d == 0
-                     && template_cost == 0
-                     && cp[0].easy <= 1)
-                   {
-                     final_cp[0].easy = cp[0].easy;
-                     return function;
-                   }
-                 cp++;
+                 final_cp[0].h = cp[0].h;
+                 return function;
                }
+             cp++;
            }
        }
     }
@@ -4149,10 +2883,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
       tree rval = error_mark_node;
 
       /* Leave marker.  */
-      if (flag_ansi_overloading)
-       cp[0].h.code = EVIL_CODE;
-      else
-       cp[0].evil = 1;
+      cp[0].h.code = EVIL_CODE;
       if (cp - candidates > 1)
        {
          struct candidate *best_cp
@@ -4173,8 +2904,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
       else
        {
          cp -= 1;
-         if ((flag_ansi_overloading && (cp->h.code & EVIL_CODE))
-             || (!flag_ansi_overloading && cp->evil > 1))
+         if (cp->h.code & EVIL_CODE)
            {
              if (flags & LOOKUP_COMPLAIN)
                error ("type conversion ambiguous");
index 27e9a4b0d8ce11e023432144ab214a6128c7042b..4fab523b25f541817a1382f6f3f6e113635e6a9d 100644 (file)
@@ -1490,6 +1490,12 @@ finish_base_struct (t, b, t_binfo)
              if (b->has_virtual == 0)
                {
                  first_vfn_base_index = i;
+
+                 /* Update these two, now that we know what vtable we are
+                    going to extend.  This is so that we can add virtual
+                    functions, and override them properly.  */
+                 BINFO_VTABLE (t_binfo) = TYPE_BINFO_VTABLE (basetype);
+                 BINFO_VIRTUALS (t_binfo) = TYPE_BINFO_VIRTUALS (basetype);
                  b->has_virtual = CLASSTYPE_VSIZE (basetype);
                  b->vfield = CLASSTYPE_VFIELD (basetype);
                  CLASSTYPE_VFIELD (t) = b->vfield;
@@ -1678,7 +1684,9 @@ finish_struct_bits (t, max_has_virtual)
                  else
                    conv_index = ptr_conv;
                }
-             else if (typecode_p (return_type, INTEGER_TYPE))
+             else if (typecode_p (return_type, INTEGER_TYPE)
+                      || typecode_p (return_type, BOOLEAN_TYPE)
+                      || typecode_p (return_type, ENUMERAL_TYPE))
                {
                  TYPE_HAS_INT_CONVERSION (t) = 1;
                  conv_index = int_conv;
@@ -2160,9 +2168,11 @@ modify_one_vtable (binfo, t, fndecl, pfn)
                }
            }
 
-         /* Find the right offset for the this pointer based on the base
-            class we just found.  */
-         base_offset = BINFO_OFFSET (binfo);
+         /* Find the right offset for the this pointer based on the
+            base class we just found.  We have to take into
+            consideration the virtual base class pointers that we
+            stick in before the virtual function table pointer.  */
+         base_offset = get_vfield_offset (binfo);
          this_offset = size_binop (MINUS_EXPR, offset, base_offset);
 
          /* Make sure we can modify the derived association with immunity.  */
@@ -2929,10 +2939,9 @@ finish_struct (t, list_of_fieldlists, warn_anon)
              /* Invalid bit-field size done by grokfield.  */
              /* Detect invalid bit-field type.  */
              if (DECL_INITIAL (x)
-                 && TREE_CODE (TREE_TYPE (x)) != INTEGER_TYPE
-                 && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE)
+                 && ! INTEGRAL_TYPE_P (TREE_TYPE (x)))
                {
-                 cp_error_at ("bit-field `%D' has invalid type", x);
+                 cp_error_at ("bit-field `%#D' with non-integral type", x);
                  DECL_INITIAL (x) = NULL;
                }
 
@@ -3499,6 +3508,27 @@ finish_struct (t, list_of_fieldlists, warn_anon)
        }
     }
 
+  /* Set up the DECL_FIELD_BITPOS of the vfield if we need to, as we
+     might need to know it for setting up the offsets in the vtable
+     (or in thunks) below.  */
+  if (vfield != NULL_TREE
+      && DECL_FIELD_CONTEXT (vfield) != t)
+    {
+      tree binfo = get_binfo (DECL_FIELD_CONTEXT (vfield), t, 0);
+      tree offset = BINFO_OFFSET (binfo);
+
+      vfield = copy_node (vfield);
+      copy_lang_decl (vfield);
+
+      if (! integer_zerop (offset))
+       offset = size_binop (MULT_EXPR, offset, size_int (BITS_PER_UNIT));
+      DECL_FIELD_CONTEXT (vfield) = t;
+      DECL_CLASS_CONTEXT (vfield) = t;
+      DECL_FIELD_BITPOS (vfield)
+       = size_binop (PLUS_EXPR, offset, DECL_FIELD_BITPOS (vfield));
+      CLASSTYPE_VFIELD (t) = vfield;
+    }
+    
 #ifdef NOTQUITE
   cp_warning ("Doing hard virtuals for %T...", t);
 #endif
@@ -3739,6 +3769,8 @@ finish_struct (t, list_of_fieldlists, warn_anon)
          DECL_REGISTER (vtbl_ptr) = 1;
          CLASSTYPE_VTBL_PTR (t) = vtbl_ptr;
        }
+#if 0
+      /* This is now done above. */
       if (DECL_FIELD_CONTEXT (vfield) != t)
        {
          tree binfo = get_binfo (DECL_FIELD_CONTEXT (vfield), t, 0);
@@ -3755,6 +3787,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
            = size_binop (PLUS_EXPR, offset, DECL_FIELD_BITPOS (vfield));
          CLASSTYPE_VFIELD (t) = vfield;
        }
+#endif
 
       /* In addition to this one, all the other vfields should be listed. */
       /* Before that can be done, we have to have FIELD_DECLs for them, and
index 7e138243c011732a779d734c787cc399ff461d5f..6f31e15ee83c6f8ced1740fdaf7723d1df1ffe7e 100644 (file)
@@ -39,34 +39,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
    and one uses pointers of strictly higher type (derived where
    another uses base), then that alternative is silently chosen.
 
-   If two candidates have a non-monotonic derived/base pointer
-   relationship, and/or a non-monotonic easy conversion relationship,
-   then a warning is emitted to show which paths are possible, and
-   which one is being chosen.
-
-   For example:
-
-   int i;
-   double x;
-
-   overload f;
-   int f (int, int);
-   double f (double, double);
-
-   f (i, x);   // draws a warning
-
-   struct B
-   {
-     f (int);
-   } *bb;
-   struct D : B
-   {
-     f (double);
-   } *dd;
-
-   dd->f (x);  // exact match
-   dd->f (i);  // draws warning
-
    Note that this technique really only works for 255 arguments.  Perhaps
    this is not enough.  */
 
@@ -102,36 +74,19 @@ struct harshness_code
 
 struct candidate
 {
-  /* OLD METHOD */
-  unsigned char evil;        /* !0 if this will never convert.  */
-  unsigned char ellipsis;     /* !0 if a match against an ellipsis occurred */
-  unsigned char user;        /* !0 if at least one user-defined type conv.  */
-  unsigned short b_or_d;      /* count number of derived->base or
-                                base->derived conv.  */
-  unsigned short easy;       /* count number of builtin type conv.  */
-
-  /* NEW METHOD */
   struct harshness_code h;     /* Used for single-argument conversions.  */
 
   int h_len;                   /* The length of the harshness vector.  */
 
-  /* Both methods.  */
   tree function;               /* A FUNCTION_DECL */
   tree basetypes;              /* The path to function. */
   tree arg;                    /* first parm to function.  */
 
-  /* This union is only here while we maintain both the old and new
-     argument matching schemes.  When it goes away, all v.ansi_harshness
-     references will be just `harshness'.  */
-  union
-    {
-      /* Indexed by argument number, encodes evil, user, d_to_b, and easy
-        strikes for that argument.  At end of array, we store the index+1
-        of where we started using default parameters, or 0 if there are
-        none.  */
-      struct harshness_code *ansi_harshness; /* NEW METHOD */
-      unsigned short *old_harshness;  /* OLD METHOD */
-    } v;
+  /* Indexed by argument number, encodes evil, user, d_to_b, and easy
+     strikes for that argument.  At end of array, we store the index+1
+     of where we started using default parameters, or 0 if there are
+     none.  */
+  struct harshness_code *harshness;
 
   union
     {
index 5d7cfa763d799a519da7394debbd8f0975758d7a..061c7f1e28ac5c2fc5d7f30841f5790b3f5652a7 100644 (file)
@@ -280,11 +280,6 @@ extern int flag_ansi;
 
 extern int flag_handle_exceptions;
 
-/* Nonzero means do argument matching for overloading according to the
-   ANSI rules, rather than what g++ used to believe to be correct.  */
-
-extern int flag_ansi_overloading;
-
 /* Nonzero means recognize and handle signature language constructs.  */
 
 extern int flag_handle_signatures;
@@ -1132,6 +1127,10 @@ struct lang_decl
        || TYPE_MAIN_VARIANT (t) == short_integer_type_node     \
        || TYPE_MAIN_VARIANT (t) == short_unsigned_type_node))
 
+#define INTEGRAL_CODE_P(CODE) \
+  (CODE == INTEGER_TYPE || CODE == ENUMERAL_TYPE || CODE == BOOLEAN_TYPE)
+#define ARITHMETIC_TYPE_P(TYPE) (INTEGRAL_TYPE_P (TYPE) || FLOAT_TYPE_P (TYPE))
+
 /* Mark which labels are explicitly declared.
    These may be shadowed, and may be referenced from nested functions.  */
 #define C_DECLARED_LABEL_FLAG(label) TREE_LANG_FLAG_1 (label)
@@ -1367,6 +1366,7 @@ extern tree delta_type_node;
 extern tree long_long_integer_type_node, long_long_unsigned_type_node;
 /* For building calls to `delete'.  */
 extern tree integer_two_node, integer_three_node;
+extern tree bool_type_node, true_node, false_node;
 
 /* in except.c */
 extern tree current_exception_type;
@@ -1938,6 +1938,7 @@ extern tree reparse_absdcl_as_casts               PROTO((tree, tree));
 extern tree reparse_decl_as_expr               PROTO((tree, tree));
 extern tree finish_decl_parsing                        PROTO((tree));
 extern tree lookup_name_nonclass               PROTO((tree));
+extern tree check_cp_case_value                        PROTO((tree));
 
 /* in edsel.c */
 
@@ -2217,6 +2218,7 @@ extern tree array_type_nelts_total                PROTO((tree));
 extern tree array_type_nelts_top               PROTO((tree));
 
 /* in typeck.c */
+extern tree bool_truthvalue_conversion         PROTO((tree));
 extern tree target_type                                PROTO((tree));
 extern tree require_complete_type              PROTO((tree));
 extern int type_unknown_p                      PROTO((tree));
@@ -2262,6 +2264,9 @@ extern tree build_x_conditional_expr              PROTO((tree, tree, tree));
 extern tree build_conditional_expr             PROTO((tree, tree, tree));
 extern tree build_x_compound_expr              PROTO((tree));
 extern tree build_compound_expr                        PROTO((tree));
+extern tree build_static_cast                  PROTO((tree, tree));
+extern tree build_reinterpret_cast             PROTO((tree, tree));
+extern tree build_const_cast                   PROTO((tree, tree));
 extern tree build_c_cast                       PROTO((tree, tree));
 extern tree build_modify_expr                  PROTO((tree, enum tree_code, tree));
 extern int language_lvalue_valid               PROTO((tree));
index d614c70dbb8f2f2828a107e5a7c04a420e274afe..7bfe80233a8add6859d13cb5809da4b098599b7b 100644 (file)
@@ -186,7 +186,7 @@ cp_convert_to_pointer (type, expr)
       return expr;
     }
 
-  if (form == INTEGER_TYPE || form == ENUMERAL_TYPE)
+  if (INTEGRAL_CODE_P (form))
     {
       if (type_precision (intype) == POINTER_SIZE)
        return build1 (CONVERT_EXPR, type, expr);
@@ -950,16 +950,11 @@ convert_to_aggr (type, expr, msgp, protect)
       {
        function = fndecl;
        cp->h_len = 2;
-       if (flag_ansi_overloading)
-         cp->v.ansi_harshness = (struct harshness_code *)
-           alloca (3 * sizeof (struct harshness_code));
-       else
-         cp->v.old_harshness = (unsigned short *)
-           alloca (3 * sizeof (short));
+       cp->harshness = (struct harshness_code *)
+         alloca (3 * sizeof (struct harshness_code));
 
        compute_conversion_costs (fndecl, parmlist, cp, 2);
-       if ((flag_ansi_overloading && (cp->h.code & EVIL_CODE) == 0)
-           || (!flag_ansi_overloading && cp->evil == 0))
+       if ((cp->h.code & EVIL_CODE) == 0)
          {
            cp->u.field = fndecl;
            if (protect)
@@ -983,10 +978,7 @@ convert_to_aggr (type, expr, msgp, protect)
                   || purpose_member (basetype, DECL_ACCESS (fndecl)))
                : 1)
              {
-               if ((flag_ansi_overloading && cp->h.code <= TRIVIAL_CODE)
-                   || (!flag_ansi_overloading
-                       && cp->user == 0 && cp->b_or_d == 0
-                       && cp->easy <= 1))
+               if (cp->h.code <= TRIVIAL_CODE)
                  goto found_and_ok;
                cp++;
              }
@@ -1014,8 +1006,7 @@ convert_to_aggr (type, expr, msgp, protect)
                 rank_for_overload); /* int (*compar)() */
 
        --cp;
-       if ((flag_ansi_overloading && (cp->h.code & EVIL_CODE))
-           || (!flag_ansi_overloading && cp->evil > 1))
+       if (cp->h.code & EVIL_CODE)
          {
            if (msgp)
              *msgp = "ambiguous type conversion possible for `%s'";
@@ -1235,15 +1226,14 @@ cp_convert (type, expr, convtype, flags)
   else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE)
     e = convert_from_reference (e);
 
-  if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
+  if (INTEGRAL_CODE_P (code))
     {
       tree intype = TREE_TYPE (expr);
       enum tree_code form = TREE_CODE (intype);
       /* enum = enum, enum = int, enum = float are all errors. */
       if (flag_int_enum_equivalence == 0
          && TREE_CODE (type) == ENUMERAL_TYPE
-         && (form == INTEGER_TYPE || form == REAL_TYPE
-             || form == ENUMERAL_TYPE))
+         && ARITHMETIC_TYPE_P (intype))
        {
          cp_pedwarn ("conversion from `%#T' to `%#T'", intype, type);
 
@@ -1258,9 +1248,23 @@ cp_convert (type, expr, convtype, flags)
          tree rval;
          rval = build_type_conversion (CONVERT_EXPR, type, expr, 1);
          if (rval) return rval;
-         cp_error ("`%#T' used where an `int' was expected", intype);
+         if (code == BOOLEAN_TYPE)
+           cp_error ("`%#T' used where a `bool' was expected", intype);
+         else
+           cp_error ("`%#T' used where an `int' was expected", intype);
          return error_mark_node;
        }
+      if (code == BOOLEAN_TYPE)
+       {
+         tree newe = truthvalue_conversion (e);
+         /* Avoid stupid (infinite) recursion from backend. */
+         if (TREE_CODE (newe) != NOP_EXPR || e != TREE_OPERAND (newe, 0))
+           e = newe;
+         if (TREE_TYPE (e) == bool_type_node)
+           return e;
+         else
+           return build1 (NOP_EXPR, bool_type_node, e);
+       }
       return fold (convert_to_integer (type, e));
     }
   if (code == POINTER_TYPE)
@@ -1554,6 +1558,14 @@ build_type_conversion (code, xtype, expr, for_sure)
   if (TREE_CODE (basetype) == REFERENCE_TYPE)
     basetype = TREE_TYPE (basetype);
 
+  if (TYPE_PTRMEMFUNC_P (basetype) && TREE_CODE (xtype) == BOOLEAN_TYPE)
+    {
+      /* We convert a pointer to member function into a boolean,
+        by just checking the index value, for == 0, we want false, for
+        != 0, we want true.  */
+      return convert (xtype, build_component_ref (expr, index_identifier, 0, 0));
+    }
+
   basetype = TYPE_MAIN_VARIANT (basetype);
   if (! TYPE_LANG_SPECIFIC (basetype) || ! TYPE_HAS_CONVERSION (basetype))
     return NULL_TREE;
@@ -1651,6 +1663,30 @@ build_type_conversion (code, xtype, expr, for_sure)
   if (exact_conversion)
     return NULL_TREE;
 
+  if (TREE_CODE (type) == BOOLEAN_TYPE)
+    {
+      tree as_int = build_type_conversion (code, long_long_unsigned_type_node, expr, 0);
+      tree as_ptr = build_type_conversion (code, ptr_type_node, expr, 0);
+      /* We are missing the conversion to pointer to member type. */
+      /* We are missing the conversion to floating type. */
+      if (as_int && as_ptr && for_sure)
+       {
+         cp_error ("ambiguous conversion from `%T' to `bool', can convert to integral type or pointer", TREE_TYPE (expr));
+         return error_mark_node;
+       }
+      if (as_int)
+       {
+         as_int = build_type_conversion (code, long_long_unsigned_type_node, expr, for_sure+exact_conversion*2);
+         return convert (xtype, as_int);
+       }
+      if (as_ptr)
+       {
+         as_ptr = build_type_conversion (code, ptr_type_node, expr, for_sure+exact_conversion*2);
+         return convert (xtype, as_ptr);
+       }
+      return NULL_TREE;
+    }
+
   /* No perfect match found, try default.  */
 #if 0 /* This is wrong; there is no standard conversion from void* to
          anything.  -jason */
@@ -1686,8 +1722,6 @@ build_type_conversion (code, xtype, expr, for_sure)
        }
     }
 
- try_pointer:
-
   if (TREE_CODE (type) == POINTER_TYPE && TYPE_READONLY (TREE_TYPE (type)))
     {
       /* Try converting to some other const pointer type and then using
@@ -1747,7 +1781,7 @@ build_type_conversion (code, xtype, expr, for_sure)
     {
       /* Only accept using an operator double() if there isn't a conflicting
         operator int().  */
-      if (flag_ansi_overloading && TYPE_HAS_INT_CONVERSION (basetype))
+      if (TYPE_HAS_INT_CONVERSION (basetype))
        {
          error ("two possible conversions for type `%s'",
                 TYPE_NAME_STRING (type));
@@ -1758,17 +1792,6 @@ build_type_conversion (code, xtype, expr, for_sure)
       return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);
     }
 
-  /* THIS IS A KLUDGE.  */
-  if (TREE_CODE (type) != POINTER_TYPE
-      && (code == TRUTH_ANDIF_EXPR
-         || code == TRUTH_ORIF_EXPR
-         || code == TRUTH_NOT_EXPR))
-    {
-      /* Here's when we can convert to a pointer.  */
-      type = ptr_type_node;
-      goto try_pointer;
-    }
-
   /* THESE ARE TOTAL KLUDGES.  */
   /* Default promotion yields no new alternatives, try
      conversions which are anti-default, such as
@@ -1777,7 +1800,7 @@ build_type_conversion (code, xtype, expr, for_sure)
 
      */
   if (type_default == type
-      && (TREE_CODE (type) == INTEGER_TYPE || TREE_CODE (type) == REAL_TYPE))
+      && (INTEGRAL_TYPE_P (type) || TREE_CODE (type) == REAL_TYPE))
     {
       int not_again = 0;
 
@@ -1819,19 +1842,10 @@ build_type_conversion (code, xtype, expr, for_sure)
   /* Now, try C promotions...
 
      float -> int
-     int -> float, void *
-     void * -> int
-
-     Truthvalue conversions let us try to convert
-     to pointer if we were going for int, and to int
-     if we were looking for pointer.  */
+     int -> float  */
 
     basetype = save_basetype;
-    if (TREE_CODE (type) == REAL_TYPE
-       || (TREE_CODE (type) == POINTER_TYPE
-           && (code == TRUTH_ANDIF_EXPR
-               || code == TRUTH_ORIF_EXPR
-               || code == TRUTH_NOT_EXPR)))
+    if (TREE_CODE (type) == REAL_TYPE)
       type = integer_type_node;
     else if (TREE_CODE (type) == INTEGER_TYPE)
       if (TYPE_HAS_REAL_CONVERSION (basetype))
@@ -1917,11 +1931,17 @@ build_default_binary_type_conversion (code, arg1, arg2)
       return 0;
     }
 
-  if (TYPE_HAS_INT_CONVERSION (type1) && TYPE_HAS_REAL_CONVERSION (type1))
-    cp_warning ("ambiguous type conversion for type `%T', defaulting to int",
-               type1);
-  if (TYPE_HAS_INT_CONVERSION (type1))
+  if (code == TRUTH_ANDIF_EXPR
+      || code == TRUTH_ORIF_EXPR)
     {
+      *arg1 = convert (bool_type_node, *arg1);
+      *arg2 = convert (bool_type_node, *arg2);
+    }
+  else if (TYPE_HAS_INT_CONVERSION (type1))
+    {
+      if (TYPE_HAS_REAL_CONVERSION (type1))
+       cp_pedwarn ("ambiguous type conversion for type `%T', defaulting to int",
+                   type1);
       *arg1 = build_type_conversion (code, integer_type_node, *arg1, 1);
       *arg2 = build_type_conversion (code, integer_type_node, *arg2, 1);
     }
@@ -1956,7 +1976,7 @@ build_default_binary_type_conversion (code, arg1, arg2)
   return 1;
 }
 
-/* Must convert two aggregate types to non-aggregate type.
+/* Must convert an aggregate type to non-aggregate type.
    Attempts to find a non-ambiguous, "best" type conversion.
 
    Return 1 on success, 0 on failure.
@@ -1970,21 +1990,22 @@ build_default_unary_type_conversion (code, arg)
      tree *arg;
 {
   tree type = TREE_TYPE (*arg);
-  tree id = TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
-    ? TYPE_IDENTIFIER (type) : TYPE_NAME (type);
-  char *name = IDENTIFIER_POINTER (id);
 
   if (! TYPE_HAS_CONVERSION (type))
     {
-      error ("type conversion required for type `%s'", name);
+      cp_error ("type conversion required for type `%T'", type);
       return 0;
     }
 
-  if (TYPE_HAS_INT_CONVERSION (type) && TYPE_HAS_REAL_CONVERSION (type))
-    warning ("ambiguous type conversion for type `%s', defaulting to int",
-            name);
-  if (TYPE_HAS_INT_CONVERSION (type))
-    *arg = build_type_conversion (code, integer_type_node, *arg, 1);
+  if (code == TRUTH_NOT_EXPR)
+    *arg = convert (bool_type_node, *arg);
+  else if (TYPE_HAS_INT_CONVERSION (type))
+    {
+      if (TYPE_HAS_REAL_CONVERSION (type))
+       cp_pedwarn ("ambiguous type conversion for type `%T', defaulting to int",
+                   type);
+      *arg = build_type_conversion (code, integer_type_node, *arg, 1);
+    }
   else if (TYPE_HAS_REAL_CONVERSION (type))
     *arg = build_type_conversion (code, double_type_node, *arg, 1);
   else
@@ -1995,7 +2016,7 @@ build_default_unary_type_conversion (code, arg)
     }
   if (*arg == NULL_TREE)
     {
-      error ("default type conversion for type `%s' failed", name);
+      cp_error ("default type conversion for type `%T' failed", type);
       return 0;
     }
   return 1;
@@ -2009,17 +2030,21 @@ type_promotes_to (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)));
+
+  /* bool always promotes to int (not unsigned), even if it's the same
+     size.  */
+  if (type == bool_type_node)
+    type = integer_type_node;
+
+  /* Normally convert enums to int, but convert wide enums to something
+     wider.  */
+  else 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.
index 1c9905f7b3638c62ed6df0bd088dee16c6dda484..fd73388d65ddd4cf866c7885a494d8c0cf937123 100644 (file)
@@ -204,6 +204,9 @@ tree int_array_type_node;
 
 tree wchar_array_type_node;
 
+/* The bool data type, and constants */
+tree bool_type_node, true_node, false_node;
+
 /* type `int ()' -- used for implicit declaration of functions.  */
 
 tree default_function_type;
@@ -412,9 +415,7 @@ extern int flag_no_builtin;
 
 extern int flag_implement_inlines;
 
-/* Nonzero means handle things in ANSI, instead of GNU fashion.  This
-   flag should be tested for language behavior that's different between
-   ANSI and GNU, but not so horrible as to merit a PEDANTIC label.  */
+/* Nonzero means disable GNU extensions.  */
 
 extern int flag_ansi;
 
@@ -1709,7 +1710,7 @@ pushtag (name, type, globalize)
 {
   register struct binding_level *b;
   tree context = 0;
-  tree cdecl = 0;
+  tree c_decl = 0;
 
   b = inner_binding_level;
   while (b->tag_transparent
@@ -1727,7 +1728,7 @@ pushtag (name, type, globalize)
       if (! context && ! globalize)
         context = current_scope ();
       if (context)
-       cdecl = TREE_CODE (context) == FUNCTION_DECL
+       c_decl = TREE_CODE (context) == FUNCTION_DECL
          ? context : TYPE_NAME (context);
 
       /* Record the identifier as the type's name if it has none.  */
@@ -1746,7 +1747,7 @@ pushtag (name, type, globalize)
          if (b->parm_flag != 2
              || TYPE_SIZE (current_class_type) != NULL_TREE)
            {
-             d = lookup_nested_type (type, cdecl);
+             d = lookup_nested_type (type, c_decl);
 
              if (d == NULL_TREE)
                {
@@ -1824,7 +1825,7 @@ pushtag (name, type, globalize)
          else if (context && TREE_CODE (context) == FUNCTION_DECL)
            {
              /* Function-nested class.  */
-             set_nested_typename (d, DECL_ASSEMBLER_NAME (cdecl),
+             set_nested_typename (d, DECL_ASSEMBLER_NAME (c_decl),
                                   name, type);
              /* This builds the links for classes nested in fn scope.  */
              DECL_CONTEXT (d) = context;
@@ -1834,7 +1835,7 @@ pushtag (name, type, globalize)
          else if (context && TREE_CODE (context) == RECORD_TYPE)
            {
              /* Class-nested class.  */
-             set_nested_typename (d, DECL_NESTED_TYPENAME (cdecl),
+             set_nested_typename (d, DECL_NESTED_TYPENAME (c_decl),
                                   name, type);
              /* This builds the links for classes nested in type scope.  */
              DECL_CONTEXT (d) = context;
@@ -4373,6 +4374,14 @@ init_decl_processing ()
   TREE_TYPE (integer_three_node) = integer_type_node;
   empty_init_node = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE);
 
+  bool_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
+  TREE_SET_CODE (bool_type_node, BOOLEAN_TYPE);
+  record_builtin_type (RID_BOOL, "bool", bool_type_node);
+  false_node = build_int_2 (0, 0);
+  TREE_TYPE (false_node) = bool_type_node;
+  true_node = build_int_2 (1, 0);
+  TREE_TYPE (true_node) = bool_type_node;
+
   /* These are needed by stor-layout.c.  */
   size_zero_node = size_int (0);
   size_one_node = size_int (1);
@@ -5007,7 +5016,7 @@ shadow_tag (declspecs)
 {
   int found_tag = 0;
   int warned = 0;
-  int static_or_extern = 0;
+  tree ob_modifier = NULL_TREE;
   register tree link;
   register enum tree_code code, ok_code = ERROR_MARK;
   register tree t = NULL_TREE;
@@ -5018,11 +5027,12 @@ shadow_tag (declspecs)
 
       code = TREE_CODE (value);
       if (IS_AGGR_TYPE_CODE (code) || code == ENUMERAL_TYPE)
-       /* Used to test also that TYPE_SIZE (value) != 0.
-          That caused warning for `struct foo;' at top level in the file.  */
        {
          register tree name = TYPE_NAME (value);
 
+         if (code == ENUMERAL_TYPE && TYPE_SIZE (value) == 0)
+           cp_error ("forward declaration of `%#T'", value);
+
          if (name == NULL_TREE)
            name = lookup_tag_reverse (value, NULL_TREE);
 
@@ -5041,7 +5051,6 @@ shadow_tag (declspecs)
              pushtag (name, t, 0);
              pop_obstacks ();
              ok_code = code;
-             break;
            }
          else if (name != NULL_TREE || code == ENUMERAL_TYPE)
            ok_code = code;
@@ -5056,8 +5065,10 @@ shadow_tag (declspecs)
            }
        }
       else if (value == ridpointers[(int) RID_STATIC]
-              || value == ridpointers[(int) RID_EXTERN])
-       static_or_extern = 1;
+              || value == ridpointers[(int) RID_EXTERN]
+              || value == ridpointers[(int) RID_AUTO]
+              || value == ridpointers[(int) RID_REGISTER])
+       ob_modifier = value;
     }
 
   /* This is where the variables in an anonymous union are
@@ -5086,9 +5097,10 @@ shadow_tag (declspecs)
   else
     {
       /* Anonymous unions are objects, that's why we only check for
-        static/extern specifiers in this branch.  */
-      if (static_or_extern)
-       error ("static/extern can only be specified for objects and functions");
+        inappropriate specifiers in this branch.  */
+      if (ob_modifier)
+       cp_error ("`%D' can only be specified for objects and functions",
+                 ob_modifier);
 
       if (ok_code == RECORD_TYPE
          && found_tag == 1
@@ -5113,8 +5125,10 @@ shadow_tag (declspecs)
              pop_obstacks ();
            }
        }
+      else if (found_tag == 0)
+       pedwarn ("abstract declarator used as declaration");
       else if (!warned && found_tag > 1)
-       warning ("multiple types in one declaration");
+       pedwarn ("multiple types in one declaration");
     }
 }
 \f
@@ -5967,14 +5981,16 @@ finish_decl (decl, init, asmspec_tree, need_pop)
          && (TYPE_READONLY (type) || TREE_READONLY (decl)))
        cp_error ("uninitialized const `%D'", decl);
 
-      /* Initialize variables in need of static initialization
-        with `empty_init_node' to keep assemble_variable from putting them
-        in the wrong program space.  (Common storage is okay for non-public
-        uninitialized data; the linker can't match it with storage from other
-        files, and we may save some disk space.)  */
+      /* Initialize variables in need of static initialization with
+        `empty_init_node' to keep assemble_variable from putting them in
+        the wrong program space.  Common storage is okay for non-public
+        uninitialized data; the linker can't match it with storage from
+        other files, and we may save some disk space.  Consts have to go
+        into data, though, since the backend would put them in text
+        otherwise.  */
       if (flag_pic == 0
          && TREE_STATIC (decl)
-         && TREE_PUBLIC (decl)
+         && (TREE_PUBLIC (decl) || was_readonly)
          && ! DECL_EXTERNAL (decl)
          && TREE_CODE (decl) == VAR_DECL
          && TYPE_NEEDS_CONSTRUCTING (type)
@@ -7341,6 +7357,16 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
                }
              goto found;
            }
+         if (id == ridpointers[(int) RID_BOOL])
+           {
+             if (type)
+               error ("extraneous `bool' ignored");
+             else
+               {
+                 type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id));
+               }
+             goto found;
+           }
          if (id == ridpointers[(int) RID_WCHAR])
            {
              if (type)
@@ -7445,7 +7471,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
                /* Save warning until we know what is really going on.  */
                warn_about_return_type = 1;
            }
-         else if (class_binding_level && declarator
+         else if (decl_context == FIELD && declarator
                   && TREE_CODE (declarator) == SCOPE_REF)
            /* OK -- access declaration */;
          else if (declspecs == NULL_TREE &&
@@ -8007,7 +8033,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
                  }
                if (TREE_READONLY_DECL_P (size))
                  size = decl_constant_value (size);
-               if (pedantic && integer_zerop (size))
+               if (flag_ansi && integer_zerop (size))
                  cp_pedwarn ("ANSI C++ forbids zero-size array `%D'", dname);
                if (TREE_CONSTANT (size))
                  {
@@ -8022,7 +8048,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
                  }
                else
                  {
-                   if (pedantic)
+                   if (flag_ansi)
                      cp_pedwarn ("ANSI C++ forbids variable-size array `%D'",
                                  dname);
                  dont_grok_size:
@@ -8909,7 +8935,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
                   initialize the named nonstatic member....  This (or an
                   initializer list) is the only way to initialize
                   nonstatic const and reference members.  */
-               else if (pedantic || flag_ansi || ! constp)
+               else if (flag_ansi || ! constp)
                  pedwarn ("ANSI C++ forbids initialization of %s `%s'",
                           constp ? "const member" : "member",
                           IDENTIFIER_POINTER (declarator));
@@ -9061,7 +9087,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
            if (RIDBIT_SETP (RID_EXTERN, specbits))
              {
                current_extern_inline = 1;
-               if (flag_ansi || pedantic || flag_pedantic_errors)
+               if (flag_ansi)
                  pedwarn ("ANSI C++ does not permit `extern inline'");
              }
          }
@@ -10245,31 +10271,34 @@ finish_enum (enumtype, values)
   register HOST_WIDE_INT minvalue = 0;
   register HOST_WIDE_INT i;
 
-  TYPE_VALUES (enumtype) = values;
-
   /* Calculate the maximum value of any enumerator in this type.  */
 
   if (values)
     {
       /* Speed up the main loop by performing some precalculations */
 
-      HOST_WIDE_INT value = TREE_INT_CST_LOW (TREE_VALUE (values));
+      HOST_WIDE_INT value;
       TREE_TYPE (TREE_VALUE (values)) = enumtype;
       TREE_TYPE (DECL_INITIAL (TREE_VALUE (values))) = enumtype;
+      TREE_VALUE (values) = DECL_INITIAL (TREE_VALUE (values));
+      value = TREE_INT_CST_LOW (TREE_VALUE (values));
       minvalue = maxvalue = value;
       
       for (pair = TREE_CHAIN (values); pair; pair = TREE_CHAIN (pair))
        {
+         TREE_TYPE (TREE_VALUE (pair)) = enumtype;
+         TREE_TYPE (DECL_INITIAL (TREE_VALUE (pair))) = enumtype;
+         TREE_VALUE (pair) = DECL_INITIAL (TREE_VALUE (pair));
          value = TREE_INT_CST_LOW (TREE_VALUE (pair));
          if (value > maxvalue)
            maxvalue = value;
          else if (value < minvalue)
            minvalue = value;
-         TREE_TYPE (TREE_VALUE (pair)) = enumtype;
-         TREE_TYPE (DECL_INITIAL (TREE_VALUE (pair))) = enumtype;
        }
     }
 
+  TYPE_VALUES (enumtype) = values;
+
   if (flag_short_enums)
     {
       /* Determine the precision this type needs, lay it out, and define
@@ -10970,7 +10999,7 @@ store_return_init (return_id, init)
 {
   tree decl = DECL_RESULT (current_function_decl);
 
-  if (pedantic)
+  if (flag_ansi)
     /* Give this error as many times as there are occurrences,
        so that users can use Emacs compilation buffers to find
        and fix all such places.  */
index c5ab8dbd7fc95d3fb199a32c7f18ff2791741a27..55414dfba2a8508759f946824b1cf422a468e2e1 100644 (file)
@@ -96,17 +96,10 @@ int flag_signed_bitfields = 1;
 
 int flag_no_ident = 0;
 
-/* Nonzero means handle things in ANSI, instead of GNU fashion.  This
-   flag should be tested for language behavior that's different between
-   ANSI and GNU, but not so horrible as to merit a PEDANTIC label.  */
+/* Nonzero means disable GNU extensions.  */
 
 int flag_ansi = 0;
 
-/* Nonzero means do argument matching for overloading according to the
-   ANSI rules, rather than what g++ used to believe to be correct.  */
-
-int flag_ansi_overloading = 1;
-
 /* Nonzero means do emit exported implementations of functions even if
    they can be inlined.  */
 
@@ -359,7 +352,6 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
   {"nonnull-objects", &flag_assume_nonnull_objects, 1},
   {"implement-inlines", &flag_implement_inlines, 1},
   {"external-templates", &flag_external_templates, 1},
-  {"ansi-overloading", &flag_ansi_overloading, 1},
   {"huge-objects", &flag_huge_objects, 1},
   {"conserve-space", &flag_conserve_space, 1},
   {"vtable-thunks", &flag_vtable_thunks, 1},
@@ -797,9 +789,11 @@ grokclassfn (ctype, cname, function, flags, quals)
         we may wish to make it special.  */
       tree type = TREE_VALUE (arg_types);
 
-      if (flags == DTOR_FLAG)
+      if ((flag_this_is_variable > 0)
+         && (flags == DTOR_FLAG || DECL_CONSTRUCTOR_P (function)))
        type = TYPE_MAIN_VARIANT (type);
-      else if (DECL_CONSTRUCTOR_P (function))
+
+      if (DECL_CONSTRUCTOR_P (function))
        {
          if (TYPE_USES_VIRTUAL_BASECLASSES (ctype))
            {
@@ -824,14 +818,7 @@ grokclassfn (ctype, cname, function, flags, quals)
       /* We can make this a register, so long as we don't
         accidentally complain if someone tries to take its address.  */
       DECL_REGISTER (parm) = 1;
-#if 0
-      /* it is wrong to flag the object as readonly, when
-        flag_this_is_variable is 0. */
-      if (flags != DTOR_FLAG
-         && (flag_this_is_variable <= 0 || TYPE_READONLY (type)))
-#else
-      if (flags != DTOR_FLAG && TYPE_READONLY (type))
-#endif
+      if (TYPE_READONLY (type))
        TREE_READONLY (parm) = 1;
       TREE_CHAIN (parm) = last_function_parms;
       last_function_parms = parm;
@@ -1044,7 +1031,7 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
     case 2:
       maxindex = build_binary_op (MINUS_EXPR, size, integer_one_node, 1);
       if (! flag_traditional)
-       pedwarn ("ANSI C++ forbids array size in vector delete");
+       pedwarn ("anachronistic use of array size in vector delete");
       /* Fall through.  */
     case 1:
       elt_size = c_sizeof (type);
@@ -1800,7 +1787,7 @@ build_push_scope (cname, name)
 void cplus_decl_attributes (decl, attributes)
      tree decl, attributes;
 {
-  if (decl)
+  if (decl && decl != void_type_node)
     decl_attributes (decl, attributes);
 }
 \f
@@ -2952,3 +2939,43 @@ finish_decl_parsing (decl)
       return NULL_TREE;
     }
 }
+
+tree
+check_cp_case_value (value)
+     tree value;
+{
+  if (value == NULL_TREE)
+    return value;
+
+  /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
+     Strip such NOP_EXPRs.  */
+  if (TREE_CODE (value) == NOP_EXPR
+      && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
+    value = TREE_OPERAND (value, 0);
+
+  if (TREE_READONLY_DECL_P (value))
+    {
+      value = decl_constant_value (value);
+      /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
+        Strip such NOP_EXPRs.  */
+      if (TREE_CODE (value) == NOP_EXPR
+         && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
+       value = TREE_OPERAND (value, 0);
+    }
+  value = fold (value);
+
+  if (TREE_CODE (value) != INTEGER_CST
+      && value != error_mark_node)
+    {
+      cp_error ("case label `%E' does not reduce to an integer constant",
+               value);
+      value = error_mark_node;
+    }
+  else
+    /* Promote char or short to int.  */
+    value = default_conversion (value);
+
+  constant_expression_warning (value);
+
+  return value;
+}
index 2cf2b87ff2329922b38ecd6fe85c75c303b7f8b6..1b345fda9c2adaf026d75450ba1ed19fa2c76f3b 100644 (file)
@@ -120,7 +120,7 @@ cp_thing (errfn, atarg1, format, arglist)
 
          if (arg >= NARGS) abort ();
          
-         if (maybe_here && atarg)
+         if (maybe_here && atarg1)
            atarg = args[arg];
 
          /* Must use a temporary to avoid calling *function twice */
index 629c70b92b1bbc73668e23a7857fa4628b1d812d..6d2ec7fc8b8515a7648a8ad6508ad9c47bc876f6 100644 (file)
@@ -198,6 +198,7 @@ dump_type (t, v)
       /* fall through.  */
     case REAL_TYPE:
     case VOID_TYPE:
+    case BOOLEAN_TYPE:
       dump_readonly_or_volatile (t, after);
       OB_PUTID (TYPE_IDENTIFIER (t));
       break;
@@ -356,6 +357,10 @@ dump_type_prefix (t, v)
 
        switch (TREE_CODE (sub))
          {
+         case ARRAY_TYPE:
+           OB_PUTC2 (' ', '(');
+           break;
+
          case POINTER_TYPE:
            /* We don't want "char * &" */
            if (! (TYPE_READONLY (sub) || TYPE_VOLATILE (sub)))
@@ -405,6 +410,7 @@ dump_type_prefix (t, v)
     case ERROR_MARK:
     case IDENTIFIER_NODE:
     case INTEGER_TYPE:
+    case BOOLEAN_TYPE:
     case REAL_TYPE:
     case RECORD_TYPE:
     case TEMPLATE_TYPE_PARM:
@@ -476,6 +482,7 @@ dump_type_suffix (t, v)
     case ERROR_MARK:
     case IDENTIFIER_NODE:
     case INTEGER_TYPE:
+    case BOOLEAN_TYPE:
     case REAL_TYPE:
     case RECORD_TYPE:
     case TEMPLATE_TYPE_PARM:
index a35853416148f59d1cf93119412dad0ba3d8e929..aa59484a3059f13329a89eaff11e28e7e06b1028 100644 (file)
@@ -28,6 +28,7 @@ __volatile__, TYPE_QUAL, RID_VOLATILE
 __wchar_t, TYPESPEC, RID_WCHAR  /* Unique to ANSI C++ */,
 asm, ASM_KEYWORD, NORID,
 auto, SCSPEC, RID_AUTO,
+bool, TYPESPEC, RID_BOOL,
 break, BREAK, NORID,
 case, CASE, NORID,
 catch, CATCH, NORID,
@@ -45,6 +46,7 @@ dynamic_cast, DYNAMIC_CAST, NORID,
 else, ELSE, NORID,
 enum, ENUM, NORID,
 extern, SCSPEC, RID_EXTERN,
+false, CXX_FALSE, NORID,
 float, TYPESPEC, RID_FLOAT,
 for, FOR, NORID,
 friend, SCSPEC, RID_FRIEND,
@@ -76,6 +78,7 @@ switch, SWITCH, NORID,
 this, THIS, NORID,
 throw, THROW, NORID,
 template, TEMPLATE, RID_TEMPLATE,
+true, CXX_TRUE, NORID,
 try, TRY, NORID,
 typedef, SCSPEC, RID_TYPEDEF,
 typeof, TYPEOF, NORID,
index 0780d025d326142869d8f716ae1a98f2c06119a6..8453c4bec35548c7271560d33b369922d4064fae 100644 (file)
@@ -3,12 +3,12 @@
 /* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf  */
 struct resword { char *name; short token; enum rid rid;};
 
-#define TOTAL_KEYWORDS 83
+#define TOTAL_KEYWORDS 86
 #define MIN_WORD_LENGTH 2
 #define MAX_WORD_LENGTH 16
 #define MIN_HASH_VALUE 4
-#define MAX_HASH_VALUE 170
-/* maximum key range = 167, duplicates = 0 */
+#define MAX_HASH_VALUE 171
+/* maximum key range = 168, duplicates = 0 */
 
 #ifdef __GNUC__
 inline
@@ -20,19 +20,19 @@ hash (str, len)
 {
   static unsigned char asso_values[] =
     {
-     171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
-     171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
-     171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
-     171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
-     171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
-     171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
-     171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
-     171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
-     171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
-     171, 171, 171, 171, 171,   0, 171,  62,   5,  65,
-      27,   0,  18,   7,  10,  48, 171,   1,  30,   7,
-      79,   0,  33, 171,  18,   0,   4,  26,  13,   0,
-       1,  24, 171, 171, 171, 171, 171, 171,
+     172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+     172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+     172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+     172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+     172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+     172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+     172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+     172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+     172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+     172, 172, 172, 172, 172,   0, 172,  36,   1,  61,
+       0,   0,  30,  44,  44,  35, 172,   7,  12,  53,
+      40,  17,   6, 172,  28,   2,   4,  35,  31,  51,
+       5,   7, 172, 172, 172, 172, 172, 172,
     };
   register int hval = len;
 
@@ -65,120 +65,120 @@ is_reserved_word (str, len)
     {
       {"",}, {"",}, {"",}, {"",}, 
       {"else",  ELSE, NORID,},
-      {"",}, {"",}, 
+      {"",}, 
+      {"delete",  DELETE, NORID,},
+      {"double",  TYPESPEC, RID_DOUBLE,},
+      {"true",  CXX_TRUE, NORID,},
       {"__asm__",  GCC_ASM_KEYWORD, NORID},
+      {"typeid",  TYPEID, NORID,},
+      {"",}, 
       {"this",  THIS, NORID,},
-      {"throw",  THROW, NORID,},
+      {"",}, 
+      {"try",  TRY, NORID,},
+      {"",}, {"",}, {"",}, {"",}, 
+      {"do",  DO, NORID,},
+      {"",}, 
+      {"static_cast",  STATIC_CAST, NORID,},
+      {"template",  TEMPLATE, RID_TEMPLATE,},
+      {"protected",  VISSPEC, RID_PROTECTED,},
+      {"",}, 
+      {"__classof__",  CLASSOF, NORID},
+      {"",}, 
       {"__headof__",  HEADOF, NORID},
-      {"goto",  GOTO, NORID,},
-      {"__asm",  GCC_ASM_KEYWORD, NORID},
+      {"",}, 
+      {"bool",  TYPESPEC, RID_BOOL,},
       {"__const__",  TYPE_QUAL, RID_CONST},
       {"__volatile",  TYPE_QUAL, RID_VOLATILE},
       {"__const",  TYPE_QUAL, RID_CONST},
       {"__volatile__",  TYPE_QUAL, RID_VOLATILE},
-      {"",}, 
-      {"enum",  ENUM, NORID,},
-      {"static_cast",  STATIC_CAST, NORID,},
-      {"switch",  SWITCH, NORID,},
-      {"",}, {"",}, 
-      {"sigof",  SIGOF, NORID          /* Extension */,},
+      {"__typeof__",  TYPEOF, NORID},
+      {"void",  TYPESPEC, RID_VOID,},
+      {"friend",  SCSPEC, RID_FRIEND,},
+      {"false",  CXX_FALSE, NORID,},
       {"sizeof",  SIZEOF, NORID,},
-      {"",}, 
-      {"__headof",  HEADOF, NORID},
       {"short",  TYPESPEC, RID_SHORT,},
       {"typeof",  TYPEOF, NORID,},
-      {"do",  DO, NORID,},
-      {"",}, 
-      {"try",  TRY, NORID,},
-      {"",}, 
-      {"delete",  DELETE, NORID,},
-      {"__typeof__",  TYPEOF, NORID},
-      {"while",  WHILE, NORID,},
-      {"struct",  AGGR, RID_RECORD,},
-      {"typeid",  TYPEID, NORID,},
-      {"double",  TYPESPEC, RID_DOUBLE,},
-      {"for",  FOR, NORID,},
-      {"",}, 
-      {"__classof__",  CLASSOF, NORID},
-      {"",}, {"",}, 
-      {"operator",  OPERATOR, NORID,},
-      {"",}, {"",}, 
-      {"typedef",  SCSPEC, RID_TYPEDEF,},
-      {"long",  TYPESPEC, RID_LONG,},
-      {"template",  TEMPLATE, RID_TEMPLATE,},
-      {"__typeof",  TYPEOF, NORID},
-      {"friend",  SCSPEC, RID_FRIEND,},
-      {"",}, 
-      {"private",  VISSPEC, RID_PRIVATE,},
       {"",}, 
       {"int",  TYPESPEC, RID_INT,},
-      {"",}, 
-      {"__classof",  CLASSOF, NORID},
+      {"__signed",  TYPESPEC, RID_SIGNED},
+      {"private",  VISSPEC, RID_PRIVATE,},
       {"__signed__",  TYPESPEC, RID_SIGNED},
-      {"",}, {"",}, 
-      {"headof",  HEADOF, NORID,},
-      {"",}, 
+      {"extern",  SCSPEC, RID_EXTERN,},
+      {"struct",  AGGR, RID_RECORD,},
+      {"signed",  TYPESPEC, RID_SIGNED,},
+      {"break",  BREAK, NORID,},
       {"__attribute",  ATTRIBUTE, NORID},
-      {"",}, 
+      {"default",  DEFAULT, NORID,},
       {"__attribute__",  ATTRIBUTE, NORID},
-      {"auto",  SCSPEC, RID_AUTO,},
+      {"__classof",  CLASSOF, NORID},
+      {"sigof",  SIGOF, NORID          /* Extension */,},
+      {"__headof",  HEADOF, NORID},
+      {"switch",  SWITCH, NORID,},
+      {"__label__",  LABEL, NORID},
+      {"__extension__",  EXTENSION, NORID},
+      {"",}, 
+      {"__asm",  GCC_ASM_KEYWORD, NORID},
+      {"for",  FOR, NORID,},
+      {"__typeof",  TYPEOF, NORID},
+      {"__alignof__",  ALIGNOF, NORID},
       {"",}, 
-      {"if",  IF, NORID,},
       {"case",  CASE, NORID,},
+      {"virtual",  SCSPEC, RID_VIRTUAL,},
+      {"if",  IF, NORID,},
+      {"while",  WHILE, NORID,},
+      {"",}, 
       {"class",  AGGR, RID_CLASS,},
-      {"void",  TYPESPEC, RID_VOID,},
-      {"asm",  ASM_KEYWORD, NORID,},
-      {"break",  BREAK, NORID,},
+      {"typedef",  SCSPEC, RID_TYPEDEF,},
       {"const",  TYPE_QUAL, RID_CONST,},
       {"static",  SCSPEC, RID_STATIC,},
-      {"mutable",  SCSPEC, RID_MUTABLE,},
-      {"protected",  VISSPEC, RID_PROTECTED,},
-      {"",}, {"",}, {"",}, {"",}, 
-      {"new",  NEW, NORID,},
-      {"__signed",  TYPESPEC, RID_SIGNED},
-      {"virtual",  SCSPEC, RID_VIRTUAL,},
-      {"extern",  SCSPEC, RID_EXTERN,},
-      {"",}, {"",}, {"",}, 
+      {"auto",  SCSPEC, RID_AUTO,},
       {"float",  TYPESPEC, RID_FLOAT,},
+      {"inline",  SCSPEC, RID_INLINE,},
+      {"throw",  THROW, NORID,},
+      {"unsigned",  TYPESPEC, RID_UNSIGNED,},
+      {"",}, 
+      {"headof",  HEADOF, NORID,},
+      {"",}, 
+      {"goto",  GOTO, NORID,},
       {"",}, {"",}, 
+      {"public",  VISSPEC, RID_PUBLIC,},
+      {"signature",  AGGR, RID_SIGNATURE       /* Extension */,},
+      {"volatile",  TYPE_QUAL, RID_VOLATILE,},
+      {"__inline",  SCSPEC, RID_INLINE},
+      {"overload",  OVERLOAD, NORID,},
+      {"__inline__",  SCSPEC, RID_INLINE},
+      {"__alignof",  ALIGNOF, NORID},
+      {"asm",  ASM_KEYWORD, NORID,},
+      {"",}, 
+      {"new",  NEW, NORID,},
+      {"",}, 
+      {"mutable",  SCSPEC, RID_MUTABLE,},
+      {"union",  AGGR, RID_UNION,},
+      {"operator",  OPERATOR, NORID,},
       {"register",  SCSPEC, RID_REGISTER,},
-      {"__extension__",  EXTENSION, NORID},
       {"",}, {"",}, 
       {"__wchar_t",  TYPESPEC, RID_WCHAR  /* Unique to ANSI C++ */,},
-      {"",}, {"",}, {"",}, {"",}, 
-      {"__label__",  LABEL, NORID},
-      {"inline",  SCSPEC, RID_INLINE,},
+      {"",}, 
+      {"long",  TYPESPEC, RID_LONG,},
+      {"",}, {"",}, {"",}, 
       {"continue",  CONTINUE, NORID,},
-      {"default",  DEFAULT, NORID,},
-      {"char",  TYPESPEC, RID_CHAR,},
+      {"return",  RETURN, NORID,},
+      {"enum",  ENUM, NORID,},
       {"",}, {"",}, 
-      {"classof",  CLASSOF, NORID,},
-      {"unsigned",  TYPESPEC, RID_UNSIGNED,},
-      {"union",  AGGR, RID_UNION,},
-      {"",}, 
-      {"signed",  TYPESPEC, RID_SIGNED,},
-      {"volatile",  TYPE_QUAL, RID_VOLATILE,},
-      {"signature",  AGGR, RID_SIGNATURE       /* Extension */,},
-      {"overload",  OVERLOAD, NORID,},
+      {"dynamic_cast",  DYNAMIC_CAST, NORID,},
+      {"",}, {"",}, 
+      {"reinterpret_cast",  REINTERPRET_CAST, NORID,},
       {"",}, {"",}, {"",}, {"",}, 
-      {"__alignof__",  ALIGNOF, NORID},
+      {"char",  TYPESPEC, RID_CHAR,},
       {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
-      {"return",  RETURN, NORID,},
-      {"",}, {"",}, {"",}, {"",}, 
-      {"public",  VISSPEC, RID_PUBLIC,},
-      {"reinterpret_cast",  REINTERPRET_CAST, NORID,},
-      {"__alignof",  ALIGNOF, NORID},
+      {"classof",  CLASSOF, NORID,},
       {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
       {"const_cast",  CONST_CAST, NORID,},
-      {"catch",  CATCH, NORID,},
       {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
       {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
-      {"",}, {"",}, 
-      {"__inline",  SCSPEC, RID_INLINE},
-      {"",}, 
-      {"__inline__",  SCSPEC, RID_INLINE},
-      {"",}, 
-      {"dynamic_cast",  DYNAMIC_CAST, NORID,},
+      {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
+      {"",}, {"",}, {"",}, {"",}, {"",}, 
+      {"catch",  CATCH, NORID,},
     };
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
index 6ce92a3d0d4cd02970d74a11c42495d6b1fc805d..186741421c211dcfc380a687d1ae9a799109b157 100644 (file)
@@ -3566,7 +3566,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
 
   if (TREE_CODE (type) == POINTER_TYPE)
     {
-      type = TREE_TYPE (type);
+      type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
       if (TYPE_SIZE (type) == 0)
        {
          incomplete_type_error (0, type);
@@ -3582,6 +3582,9 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
        }
       if (TREE_SIDE_EFFECTS (addr))
        addr = save_expr (addr);
+
+      /* throw away const and volatile on target type of addr */
+      addr = convert_force (build_pointer_type (type), addr);
       ref = build_indirect_ref (addr, NULL_PTR);
       ptr = 1;
     }
index 22cf0a51cd8b2026f269f9d7a247f7638801a2cf..595ba8266675040bb03497e5362dc7f327c837d8 100644 (file)
@@ -577,6 +577,9 @@ init_lex ()
   ridpointers[(int) RID_INT] = get_identifier ("int");
   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INT],
                          build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]));
+  ridpointers[(int) RID_BOOL] = get_identifier ("bool");
+  SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_BOOL],
+                         build_tree_list (NULL_TREE, ridpointers[(int) RID_BOOL]));
   ridpointers[(int) RID_CHAR] = get_identifier ("char");
   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CHAR],
                          build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]));
@@ -4442,9 +4445,9 @@ real_yylex ()
                value = MIN_MAX;
                nextchar = c1;
              }
-           if (pedantic)
-             error ("use of `operator %s' is not standard C++",
-                    token_buffer);
+           if (flag_ansi)
+             pedwarn ("use of `operator %s' is not standard C++",
+                      token_buffer);
            goto done;
          }
 
index f9bf3f1aea3d216458492f5f21fd1cf1e467fc0b..a9ea60efa0a5f8360b34d733fca5f5f69d80ef2f 100644 (file)
@@ -26,6 +26,7 @@ enum rid
 {
   RID_UNUSED,
   RID_INT,
+  RID_BOOL,
   RID_CHAR,
   RID_WCHAR,
   RID_FLOAT,
index d4ce558abb98f66a3713280984201a23a41e38df..d0b847e87891ce79e3b946bb54ccdd5c21e8c334 100644 (file)
@@ -366,6 +366,11 @@ build_overload_value (type, value)
        icat (TREE_INT_CST_LOW (value));
        return;
       }
+    case BOOLEAN_TYPE:
+      {
+       icat (TREE_INT_CST_LOW (value));
+       return;
+      }
 #ifndef REAL_IS_NOT_DOUBLE
     case REAL_TYPE:
       {
@@ -587,10 +592,7 @@ build_overload_name (parmtypes, begin, end)
 
            OB_PUTC ('A');
            if (TYPE_DOMAIN (parmtype) == NULL_TREE)
-             {
-               error ("parameter type with unspecified array bounds invalid");
-               icat (1);
-             }
+             error ("pointer or reference to array of unknown bound in parm type");
            else
              {
                length = array_type_nelts (parmtype);
@@ -701,6 +703,10 @@ build_overload_name (parmtypes, begin, end)
            my_friendly_abort (73);
          break;
 
+       case BOOLEAN_TYPE:
+         OB_PUTC ('b');
+         break;
+
        case REAL_TYPE:
          parmtype = TYPE_MAIN_VARIANT (parmtype);
          if (parmtype == long_double_type_node)
@@ -1703,7 +1709,7 @@ emit_thunk (thunk_fndecl)
   int delta = THUNK_DELTA (thunk_fndecl);
   int tem;
   int failure = 0;
-  extern int current_call_is_indirect; /* Needed for (at least) HPPA. */
+  int current_call_is_indirect = 0;    /* needed for HPPA FUNCTION_ARG */
 
   /* Used to remember which regs we need to emit a USE rtx for. */
   rtx need_use[FIRST_PSEUDO_REGISTER];
index dd8a96ab5c6fbdc272d7c538be96d54366b6508b..30e076c657926a03b9baa67c45e7d0222e923f16 100644 (file)
@@ -149,7 +149,7 @@ empty_parms ()
 /* the reserved words... C++ extensions */
 %token <ttype> AGGR
 %token <itype> VISSPEC
-%token DELETE NEW OVERLOAD THIS OPERATOR
+%token DELETE NEW OVERLOAD THIS OPERATOR CXX_TRUE CXX_FALSE
 %token LEFT_RIGHT TEMPLATE
 %token TYPEID DYNAMIC_CAST STATIC_CAST REINTERPRET_CAST CONST_CAST
 %token <itype> SCOPE
@@ -197,14 +197,15 @@ empty_parms ()
 %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist
 %type <ttype> paren_expr_or_null nontrivial_exprlist
 %type <ttype> expr_no_commas cast_expr unary_expr primary string STRING
-%type <ttype> typed_declspecs reserved_declspecs
+%type <ttype> typed_declspecs reserved_declspecs boolean.literal
 %type <ttype> typed_typespecs reserved_typespecquals
 %type <ttype> declmods typespec typespecqual_reserved
 %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual
 %type <itype> initdecls notype_initdecls initdcl       /* C++ modification */
 %type <ttype> init initlist maybeasm
 %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
-%type <ttype> maybe_attribute attribute_list attrib
+%type <ttype> maybe_attribute attributes attribute attribute_list attrib
+%type <ttype> any_word
 
 %type <ttype> compstmt implicitly_scoped_stmt
 
@@ -284,7 +285,6 @@ static tree current_aggr;
 #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
 extern void yyprint ();
 extern tree combine_strings            PROTO((tree));
-extern tree truthvalue_conversion      PROTO((tree));
 %}
 \f
 %%
@@ -320,8 +320,7 @@ extdefs:
        ;
 
 asm_keyword:
-       ASM_KEYWORD { if (pedantic)
-                     pedwarn ("ANSI C++ forbids use of `asm' keyword"); }
+         ASM_KEYWORD
        | GCC_ASM_KEYWORD
        ;
 
@@ -551,15 +550,6 @@ datadef:
                    else if (CLASSTYPE_USE_TEMPLATE (t) == 1)
                      error ("override declaration for already-expanded template");
                  }
-               else if (TREE_CODE (t) == ENUMERAL_TYPE
-                        && !TYPE_SIZE (t))
-                 cp_error ("forward declaration of `%#T'", t);
-               else if (TREE_CODE (t) == IDENTIFIER_NODE)
-                 {
-                   tree v = lookup_name (t, 1);
-                   cp_error ("abstract declarator `%T' used as declaration",
-                             v);
-                 }
              }
            note_list_got_semicolon ($<ttype>$);
          }
@@ -1098,7 +1088,7 @@ new_initializer:
           syntactically valid but semantically invalid.  */
        | '=' init
                {
-                 if (pedantic || flag_ansi)
+                 if (flag_ansi)
                    pedwarn ("ANSI C++ forbids initialization of new expression with `='");
                  $$ = $2;
                }
@@ -1125,7 +1115,7 @@ cast_expr:
                { 
                  tree init = build_nt (CONSTRUCTOR, NULL_TREE,
                                        nreverse ($3)); 
-                 if (pedantic)
+                 if (flag_ansi)
                    pedwarn ("ANSI C++ forbids constructor-expressions");
                  /* Indicate that this was a GNU C constructor expression.  */
                  TREE_HAS_CONSTRUCTOR (init) = 1;
@@ -1279,6 +1269,7 @@ primary:
                    $$ = do_identifier ($$);
                }               
        | CONSTANT
+       | boolean.literal
        | string
                { $$ = combine_strings ($$); }
        | '(' expr ')'
@@ -1295,7 +1286,7 @@ primary:
                  $<ttype>$ = expand_start_stmt_expr (); }
          compstmt ')'
                { tree rtl_exp;
-                 if (pedantic)
+                 if (flag_ansi)
                    pedwarn ("ANSI C++ forbids braced-groups within expressions");
                  rtl_exp = expand_end_stmt_expr ($<ttype>2);
                  /* The statements have side effects, so the group does.  */
@@ -1576,7 +1567,7 @@ primary_no_id:
                    }
                  $<ttype>$ = expand_start_stmt_expr (); }
          compstmt ')'
-               { if (pedantic)
+               { if (flag_ansi)
                    pedwarn ("ANSI C++ forbids braced-groups within expressions");
                  $$ = expand_end_stmt_expr ($<ttype>2); }
        | primary_no_id '(' nonnull_exprlist ')'
@@ -1611,6 +1602,13 @@ delete:    DELETE
                { got_scope = NULL_TREE; $$ = 1; }
        ;
 
+boolean.literal:
+         CXX_TRUE
+               { $$ = true_node; }
+       | CXX_FALSE
+               { $$ = false_node; }
+       ;
+
 /* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it.  */
 string:
          STRING
@@ -1802,11 +1800,11 @@ typespec: structsp
        | complete_type_name
        | TYPEOF '(' expr ')'
                { $$ = TREE_TYPE ($3);
-                 if (pedantic)
+                 if (flag_ansi)
                    pedwarn ("ANSI C++ forbids `typeof'"); }
        | TYPEOF '(' type_id ')'
                { $$ = groktypename ($3);
-                 if (pedantic)
+                 if (flag_ansi)
                    pedwarn ("ANSI C++ forbids `typeof'"); }
        | SIGOF '(' expr ')'
                { tree type = TREE_TYPE ($3);
@@ -1912,9 +1910,9 @@ initdcl:
 /* Note how the declaration of the variable is in effect while its init is parsed! */
                { finish_decl ($<ttype>6, $7, $3, 0); }
        | declarator maybe_raises maybeasm maybe_attribute
-               { tree d = start_decl ($<ttype>1, current_declspecs, 0, $2);
+               { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 0, $2);
                  cplus_decl_attributes ($<ttype>$, $4);
-                 finish_decl (d, NULL_TREE, $3, 0); }
+                 finish_decl ($<ttype>$, NULL_TREE, $3, 0); }
        ;
 
 notype_initdcl0:
@@ -1958,64 +1956,53 @@ nomods_initdcl0:
 /* the * rules are dummies to accept the Apollo extended syntax
    so that the header files compile. */
 maybe_attribute:
+      /* empty */
+               { $$ = NULL_TREE; }
+       | attributes
+               { $$ = $1; }
+       ;
+attributes:
+      attribute
+               { $$ = $1; }
+       | attributes attribute
+               { $$ = chainon ($1, $2); }
+       ;
+
+attribute:
+      ATTRIBUTE '(' '(' attribute_list ')' ')'
+               { $$ = $4; }
+       ;
+
+attribute_list:
+      attrib
+               { $$ = build_tree_list (NULL_TREE, $1); }
+       | attribute_list ',' attrib
+               { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
+       ;
+attrib:
     /* empty */
-       { $$ = NULL_TREE; }
-    | maybe_attribute ATTRIBUTE '(' '(' attribute_list ')' ')'
-       { $$ = chainon ($5, $1); }
-    ;
-
-attribute_list
-    : attrib
-       { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
-    | attribute_list ',' attrib
-       { $$ = tree_cons (NULL_TREE, $3, $1); }
-    ;
-
-attrib
-    : identifier
-       { if (strcmp (IDENTIFIER_POINTER ($1), "packed")
-             && strcmp (IDENTIFIER_POINTER ($1), "noreturn"))
-           warning ("`%s' attribute directive ignored",
-                    IDENTIFIER_POINTER ($1));
-         $$ = $1; }
-    | 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)
-           {
-             if (TREE_CODE ($3) != STRING_CST)
-               {
-                 error ("invalid argument in `%s' attribute",
-                        IDENTIFIER_POINTER ($1));
-                 $$ = $1;
-               }
-             $$ = tree_cons ($1, $3, NULL_TREE);
-           }
-         else if (strcmp (IDENTIFIER_POINTER ($1), "aligned") != 0)
-           {
-             warning ("`%s' attribute directive ignored",
-                      IDENTIFIER_POINTER ($1));
-             $$ = $1;
-           }
-         else
-           $$ = tree_cons ($1, $3, NULL_TREE); }
-    | identifier '(' IDENTIFIER ',' expr_no_commas ',' expr_no_commas ')'
-       { /* if not "format(...)", then issue warning */
-         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); }
-    ;
+               { $$ = NULL_TREE; }
+       | any_word
+               { $$ = $1; }
+       | any_word '(' IDENTIFIER ')'
+               { $$ = tree_cons ($1, NULL_TREE, build_tree_list (NULL_TREE, $3)); }
+       | any_word '(' IDENTIFIER ',' nonnull_exprlist ')'
+               { $$ = tree_cons ($1, NULL_TREE, tree_cons (NULL_TREE, $3, $5)); }
+       | any_word '(' nonnull_exprlist ')'
+               { $$ = tree_cons ($1, NULL_TREE, $3); }
+       ;
+
+/* This still leaves out most reserved keywords,
+   shouldn't we include them?  */
+
+any_word:
+         identifier
+       | SCSPEC
+       | TYPESPEC
+       | TYPE_QUAL
+       ;
 
 /* A nonempty list of identifiers, including typenames.  */
 identifiers_or_typenames:
@@ -2663,7 +2650,7 @@ new_type_id:
           non-constant dimension.  */
        | '(' type_id ')' '[' expr ']'
                {
-                 if (pedantic || flag_ansi)
+                 if (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), $$);
@@ -3003,7 +2990,7 @@ errstmt:  error ';'
 maybe_label_decls:
          /* empty */
        | label_decls
-               { if (pedantic)
+               { if (flag_ansi)
                    pedwarn ("ANSI C++ forbids label declarations"); }
        ;
 
@@ -3040,6 +3027,10 @@ compstmt: '{' .pushlevel '}'
                { expand_end_bindings (getdecls (), kept_level_p(), 1);
                  $$ = poplevel (kept_level_p (), 1, 0);
                  pop_momentary (); }
+       | '{' .pushlevel maybe_label_decls stmts error '}'
+               { expand_end_bindings (getdecls (), kept_level_p(), 1);
+                 $$ = poplevel (kept_level_p (), 0, 0);
+                 pop_momentary (); }
        | '{' .pushlevel maybe_label_decls error '}'
                { expand_end_bindings (getdecls (), kept_level_p(), 1);
                  $$ = poplevel (kept_level_p (), 0, 0);
@@ -3051,7 +3042,7 @@ simple_if:
                { cond_stmt_keyword = "if"; }
          .pushlevel paren_cond_or_null
                { emit_line_note (input_filename, lineno);
-                 expand_start_cond (truthvalue_conversion ($4), 0); }
+                 expand_start_cond (bool_truthvalue_conversion ($4), 0); }
          implicitly_scoped_stmt
        ;
 
@@ -3059,7 +3050,7 @@ implicitly_scoped_stmt:
          compstmt
                { finish_stmt (); }
        | .pushlevel simple_stmt
-               { expand_end_bindings (getdecls (), getdecls() != NULL_TREE, 1);
+               { expand_end_bindings (getdecls (), kept_level_p (), 1);
                  $$ = poplevel (kept_level_p (), 1, 0);
                  pop_momentary (); }
        ;
@@ -3106,7 +3097,7 @@ simple_stmt:
                  expand_start_loop (1);
                  cond_stmt_keyword = "while"; }
          .pushlevel paren_cond_or_null
-               { expand_exit_loop_if_false (0, truthvalue_conversion ($4)); }
+               { expand_exit_loop_if_false (0, bool_truthvalue_conversion ($4)); }
          already_scoped_stmt
                { expand_end_bindings (getdecls (), kept_level_p (), 1);
                  poplevel (kept_level_p (), 1, 0);
@@ -3122,7 +3113,7 @@ simple_stmt:
                  cond_stmt_keyword = "do"; }
          paren_expr_or_null ';'
                { emit_line_note (input_filename, lineno);
-                 expand_exit_loop_if_false (0, truthvalue_conversion ($6));
+                 expand_exit_loop_if_false (0, bool_truthvalue_conversion ($6));
                  expand_end_loop ();
                  clear_momentary ();
                  finish_stmt (); }
@@ -3133,7 +3124,7 @@ simple_stmt:
                  expand_start_loop_continue_elsewhere (1); }
          .pushlevel xcond ';'
                { emit_line_note (input_filename, lineno);
-                 if ($4) expand_exit_loop_if_false (0, truthvalue_conversion ($4)); }
+                 if ($4) expand_exit_loop_if_false (0, bool_truthvalue_conversion ($4)); }
          xexpr ')'
                /* Don't let the tree nodes for $7 be discarded
                   by clear_momentary during the parsing of the next stmt.  */
@@ -3154,7 +3145,7 @@ simple_stmt:
                  expand_start_loop_continue_elsewhere (1); }
          .pushlevel xcond ';'
                { emit_line_note (input_filename, lineno);
-                 if ($4) expand_exit_loop_if_false (0, truthvalue_conversion ($4)); }
+                 if ($4) expand_exit_loop_if_false (0, bool_truthvalue_conversion ($4)); }
          xexpr ')'
                /* Don't let the tree nodes for $7 be discarded
                   by clear_momentary during the parsing of the next stmt.  */
@@ -3185,36 +3176,10 @@ simple_stmt:
                  pop_momentary ();
                  finish_stmt (); }
        | CASE expr_no_commas ':'
-               { register tree value = $2;
+               { register tree value = check_cp_case_value ($2);
                  register tree label
                    = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
 
-                 /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
-                    Strip such NOP_EXPRs.  */
-                 if (TREE_CODE (value) == NOP_EXPR
-                     && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
-                   value = TREE_OPERAND (value, 0);
-
-                 if (TREE_READONLY_DECL_P (value))
-                   {
-                     value = decl_constant_value (value);
-                     /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
-                        Strip such NOP_EXPRs.  */
-                     if (TREE_CODE (value) == NOP_EXPR
-                         && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
-                       value = TREE_OPERAND (value, 0);
-                   }
-                 value = fold (value);
-
-                 if (TREE_CODE (value) != INTEGER_CST
-                     && value != error_mark_node)
-                   {
-                     cp_error ("case label `%E' does not reduce to an integer constant", $2);
-                     value = error_mark_node;
-                   }
-                 else
-                   /* Promote char or short to int.  */
-                   value = default_conversion (value);
                  if (value != error_mark_node)
                    {
                      tree duplicate;
@@ -3236,61 +3201,13 @@ simple_stmt:
                }
          stmt
        | CASE expr_no_commas RANGE expr_no_commas ':'
-               { register tree value1 = $2;
-                 register tree value2 = $4;
+               { register tree value1 = check_cp_case_value ($2);
+                 register tree value2 = check_cp_case_value ($4);
                  register tree label
                    = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
 
-                 if (pedantic)
+                 if (flag_ansi)
                    pedwarn ("ANSI C++ forbids range expressions in switch statement");
-
-                 /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
-                    Strip such NOP_EXPRs.  */
-                 if (TREE_CODE (value1) == NOP_EXPR
-                     && TREE_TYPE (value1) == TREE_TYPE (TREE_OPERAND (value1, 0)))
-                   value1 = TREE_OPERAND (value1, 0);
-
-                 if (TREE_READONLY_DECL_P (value1))
-                   {
-                     value1 = decl_constant_value (value1);
-                     /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
-                        Strip such NOP_EXPRs.  */
-                     if (TREE_CODE (value1) == NOP_EXPR
-                         && TREE_TYPE (value1) == TREE_TYPE (TREE_OPERAND (value1, 0)))
-                       value1 = TREE_OPERAND (value1, 0);
-                   }
-                 value1 = fold (value1);
-
-                 /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
-                    Strip such NOP_EXPRs.  */
-                 if (TREE_CODE (value2) == NOP_EXPR
-                     && TREE_TYPE (value2) == TREE_TYPE (TREE_OPERAND (value2, 0)))
-                   value2 = TREE_OPERAND (value2, 0);
-
-                 if (TREE_READONLY_DECL_P (value2))
-                   {
-                     value2 = decl_constant_value (value2);
-                     /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
-                        Strip such NOP_EXPRs.  */
-                     if (TREE_CODE (value2) == NOP_EXPR
-                         && TREE_TYPE (value2) == TREE_TYPE (TREE_OPERAND (value2, 0)))
-                       value2 = TREE_OPERAND (value2, 0);
-                   }
-                 value2 = fold (value2);
-
-
-                 if (TREE_CODE (value1) != INTEGER_CST
-                     && value1 != error_mark_node)
-                   {
-                     error ("case label does not reduce to an integer constant");
-                     value1 = error_mark_node;
-                   }
-                 if (TREE_CODE (value2) != INTEGER_CST
-                     && value2 != error_mark_node)
-                   {
-                     error ("case label does not reduce to an integer constant");
-                     value2 = error_mark_node;
-                   }
                  if (value1 != error_mark_node
                      && value2 != error_mark_node)
                    {
index 528bbdd34dc1bd0e6e5af48475a2ae4f28cf24e9..997941c5a02521be0320c164eb77a242edc38ace 100644 (file)
@@ -782,6 +782,7 @@ uses_template_parms (t)
     case REAL_TYPE:
     case VOID_TYPE:
     case ENUMERAL_TYPE:
+    case BOOLEAN_TYPE:
       return 0;
 
       /* constants */
@@ -1142,6 +1143,7 @@ tsubst (t, args, nargs, in_decl)
     case VOID_TYPE:
     case REAL_TYPE:
     case ENUMERAL_TYPE:
+    case BOOLEAN_TYPE:
     case INTEGER_CST:
     case REAL_CST:
     case STRING_CST:
@@ -1351,6 +1353,11 @@ tsubst (t, args, nargs, in_decl)
                                           DECL_CONTEXT (t) != NULL_TREE);
                  r = build_lang_decl (FUNCTION_DECL, r, type);
                }
+             else if (DECL_INLINE (r) && DECL_SAVED_INSNS (r))
+               {
+                 /* This overrides the template version, use it. */
+                 return r;
+               }
            }
          }
        TREE_PUBLIC (r) = TREE_PUBLIC (t);
@@ -1638,8 +1645,10 @@ instantiate_template (tmpl, targ_ptr)
       DECL_ARGUMENTS (fndecl) = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
     }
      
+  /* If we have a preexisting version of this function, don't expand
+     the template version, use the other instead.  */
   t = DECL_TEMPLATE_INFO (tmpl);
-  if (t->text)
+  if (t->text && !(DECL_INLINE (fndecl) && DECL_SAVED_INSNS (fndecl)))
     {
       p = (struct pending_inline *) permalloc (sizeof (struct pending_inline));
       p->parm_vec = t->parm_vec;
index c81f1e1488d01abc91d008f5e904b9629097d294..ea7de8f9f6f37c352e36e1afe065fd472133b232 100644 (file)
@@ -2426,7 +2426,7 @@ dfs_init_vbase_pointers (binfo)
 
   this_vbase_ptr = vbase_decl_ptr_intermediate;
 
-  if (TYPE_POINTER_TO (type) != TREE_TYPE (this_vbase_ptr))
+  if (TYPE_POINTER_TO (type) != TYPE_MAIN_VARIANT (TREE_TYPE (this_vbase_ptr)))
     my_friendly_abort (125);
 
   while (fields && DECL_NAME (fields)
@@ -2525,9 +2525,30 @@ expand_indirect_vtbls_init (binfo, true_exp, decl_ptr, use_computed_offsets)
          if (use_computed_offsets)
            addr = (tree)CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vbases));
          else
-           addr = convert_pointer_to_real (vbases, vbase_decl_ptr);
-         if (addr == error_mark_node)
-           continue;
+           {
+             tree vbinfo = get_binfo (TREE_TYPE (vbases),
+                                      TREE_TYPE (vbase_decl),
+                                      0);
+
+             /* See is we can get lucky.  */
+             if (TREE_VIA_VIRTUAL (vbinfo))
+               addr = convert_pointer_to_real (vbinfo, vbase_decl_ptr);
+             else
+               {
+                 /* We go through all these contortions to avoid this
+                    call, as it will fail when the virtual base type
+                    is ambiguous from here.  We don't yet have a way
+                    to search for and find just an instance of the
+                    virtual base class.  Searching for the binfo in
+                    vbases won't work, as we don't have the vbase
+                    pointer field, for all vbases in the main class,
+                    only direct vbases.  */
+                 addr = convert_pointer_to_real (TREE_TYPE (vbases),
+                                                 vbase_decl_ptr);
+                 if (addr == error_mark_node)
+                   continue;
+               }
+           }
 
          /* Do all vtables from this virtual base. */
          /* This assumes that virtual bases can never serve as parent
@@ -2877,12 +2898,16 @@ dfs_pushdecls (binfo)
                {
                  /* Only complain if we shadow something we can access.  */
                  if (old
+                     && warn_shadow
                      && ((DECL_LANG_SPECIFIC (old)
                           && DECL_CLASS_CONTEXT (old) == current_class_type)
                          || ! TREE_PRIVATE (old)))
                    /* Should figure out access control more accurately.  */
-                   cp_warning ("shadowing member `%#D' with member function `%#D'",
-                               old, *methods);
+                   {
+                     cp_warning_at ("member `%#D' is shadowed", old);
+                     cp_warning_at ("by member function `%#D'", *methods);
+                     warning ("in this context");
+                   }
                  tmp = build_tree_list (DECL_NAME (*methods), *methods);
                }
              pop_obstacks ();
index d8df8e48df83ed6f80edc6288e7d7b52ae23e02d..b4712a6ac4d6e1816563bc22ddd91496be79ecce 100644 (file)
@@ -94,6 +94,9 @@ lvalue_p (ref)
          return (lvalue_p (TREE_OPERAND (ref, 1))
                  && lvalue_p (TREE_OPERAND (ref, 2)));
 
+       case MODIFY_EXPR:
+         return 1;
+
        case COMPOUND_EXPR:
          return lvalue_p (TREE_OPERAND (ref, 1));
        }
@@ -111,7 +114,7 @@ lvalue_or_else (ref, string)
 {
   int win = lvalue_p (ref);
   if (! win)
-    error ("invalid lvalue in %s", string);
+    error ("non-lvalue in %s", string);
   return win;
 }
 
@@ -305,13 +308,7 @@ build_cplus_method_type (basetype, rettype, argtypes)
   else
     {
       ptype = build_pointer_type (basetype);
-#if 0
-      /* it is wrong to flag the object the pointer points to as readonly
-        when flag_this_is_variable is 0. */
-      ptype = build_type_variant (ptype, flag_this_is_variable <= 0, 0);
-#else
-      ptype = build_type_variant (ptype, 0, 0);
-#endif
+      ptype = build_type_variant (ptype, 1, 0);
     }
   /* The actual arglist for this function includes a "hidden" argument
      which is "this".  Put it into the list of argument types.  */
index 490d9988f0746b3ec4b728fb73324e2c2cc6be4c..f2b375bf40f9fbbf7ae8a21297754ab3d0811758 100644 (file)
@@ -47,7 +47,6 @@ static tree pointer_int_sum ();
 static tree pointer_diff ();
 static tree convert_sequence ();
 /* static */ tree unary_complex_lvalue ();
-tree truthvalue_conversion ();
 
 extern rtx original_result_rtx;
 
@@ -258,6 +257,7 @@ common_type (t1, t2)
 {
   register enum tree_code code1;
   register enum tree_code code2;
+  tree attributes;
 
   /* Save time if the two types are the same.  */
 
@@ -269,6 +269,40 @@ common_type (t1, t2)
   if (t2 == error_mark_node)
     return t1;
 
+  /* Merge the attributes */
+
+  { register tree a1, a2;
+    a1 = TYPE_ATTRIBUTES (t1);
+    a2 = TYPE_ATTRIBUTES (t2);
+
+    /* Either one unset?  Take the set one.  */
+
+    if (!(attributes = a1))
+       attributes = a2;
+
+    /* One that completely contains the other?  Take it.  */
+
+    else if (a2 && !attribute_list_contained (a1, a2))
+       if (attribute_list_contained (a2, a1))
+         attributes = a2;
+       else
+       {
+         /* Pick the longest list, and hang on the other
+            list.  */
+       
+         if (list_length (a1) < list_length (a2))
+            attributes = a2, a2 = a1;
+
+         for (; a2; a2 = TREE_CHAIN (a2))
+            if (!value_member (attributes, a2))
+             {
+               a1 = copy_node (a2);
+               TREE_CHAIN (a1) = attributes;
+               attributes = a1;
+             }
+       }
+  }
+
   /* Treat an enum type as the unsigned integer type of the same width.  */
 
   if (TREE_CODE (t1) == ENUMERAL_TYPE)
@@ -286,23 +320,24 @@ common_type (t1, t2)
       /* If only one is real, use it as the result.  */
 
       if (code1 == REAL_TYPE && code2 != REAL_TYPE)
-       return t1;
+       return build_type_attribute_variant (t1, attributes);
 
       if (code2 == REAL_TYPE && code1 != REAL_TYPE)
-       return t2;
+        return build_type_attribute_variant (t2, attributes);
 
       /* Both real or both integers; use the one with greater precision.  */
 
       if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
-       return t1;
+       return build_type_attribute_variant (t1, attributes);
       else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
-       return t2;
+        return build_type_attribute_variant (t2, attributes);
 
       /* Same precision.  Prefer longs to ints even when same size.  */
-
+  
       if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node
          || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node)
-       return long_unsigned_type_node;
+        return build_type_attribute_variant (long_unsigned_type_node,
+                                            attributes);
 
       if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node
          || TYPE_MAIN_VARIANT (t2) == long_integer_type_node)
@@ -310,15 +345,18 @@ common_type (t1, t2)
          /* But preserve unsignedness from the other type,
             since long cannot hold all the values of an unsigned int.  */
          if (TREE_UNSIGNED (t1) || TREE_UNSIGNED (t2))
-           return long_unsigned_type_node;
-         return long_integer_type_node;
+            t1 = long_unsigned_type_node;
+         else
+            t1 = long_integer_type_node;
+         return build_type_attribute_variant (t1, attributes);
        }
 
       /* Otherwise prefer the unsigned one.  */
 
       if (TREE_UNSIGNED (t1))
-       return t1;
-      else return t2;
+       return build_type_attribute_variant (t1, attributes);
+      else
+       return build_type_attribute_variant (t2, attributes);
 
     case POINTER_TYPE:
     case REFERENCE_TYPE:
@@ -336,16 +374,19 @@ common_type (t1, t2)
          = TYPE_VOLATILE (TREE_TYPE (t1)) || TYPE_VOLATILE (TREE_TYPE (t2));
        target = build_type_variant (target, constp, volatilep);
        if (code1 == POINTER_TYPE)
-         return build_pointer_type (target);
+         t1 = build_pointer_type (target);
        else
-         return build_reference_type (target);
+         t1 = build_reference_type (target);
+       return build_type_attribute_variant (t1, attributes);
       }
 #if 0
     case POINTER_TYPE:
-      return build_pointer_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2)));
+      t1 = build_pointer_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2)));
+      return build_type_attribute_variant (t1, attributes);
 
     case REFERENCE_TYPE:
-      return build_reference_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2)));
+      t1 = build_reference_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2)));
+      return build_type_attribute_variant (t1, attributes);
 #endif
 
     case ARRAY_TYPE:
@@ -353,11 +394,12 @@ common_type (t1, t2)
        tree elt = common_type (TREE_TYPE (t1), TREE_TYPE (t2));
        /* Save space: see if the result is identical to one of the args.  */
        if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
-         return t1;
+         return build_type_attribute_variant (t1, attributes);
        if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2))
-         return t2;
+         return build_type_attribute_variant (t2, attributes);
        /* Merge the element types, and have a size if either arg has one.  */
-       return build_array_type (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
+       t1 = build_array_type (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
+       return build_type_attribute_variant (t1, attributes);
       }
 
     case FUNCTION_TYPE:
@@ -371,9 +413,9 @@ common_type (t1, t2)
 
        /* Save space: see if the result is identical to one of the args.  */
        if (valtype == TREE_TYPE (t1) && ! p2)
-         return t1;
+         return build_type_attribute_variant (t1, attributes);
        if (valtype == TREE_TYPE (t2) && ! p1)
-         return t2;
+         return build_type_attribute_variant (t2, attributes);
 
        /* Simple way if one arg fails to specify argument types.  */
        if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node)
@@ -381,7 +423,7 @@ common_type (t1, t2)
            rval = build_function_type (valtype, p2);
            if ((raises = TYPE_RAISES_EXCEPTIONS (t2)))
              rval = build_exception_variant (NULL_TREE, rval, raises);
-           return rval;
+           return build_type_attribute_variant (rval, attributes);
          }
        raises = TYPE_RAISES_EXCEPTIONS (t1);
        if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
@@ -389,11 +431,12 @@ common_type (t1, t2)
            rval = build_function_type (valtype, p1);
            if (raises)
              rval = build_exception_variant (NULL_TREE, rval, raises);
-           return rval;
+           return build_type_attribute_variant (rval, attributes);
          }
 
        rval = build_function_type (valtype, commonparms (p1, p2));
-       return build_exception_variant (NULL_TREE, rval, raises);
+       rval = build_exception_variant (NULL_TREE, rval, raises);
+       return build_type_attribute_variant (rval, attributes);
       }
 
     case RECORD_TYPE:
@@ -401,10 +444,9 @@ common_type (t1, t2)
       my_friendly_assert (TYPE_MAIN_VARIANT (t1) == t1
                          && TYPE_MAIN_VARIANT (t2) == t2, 306);
 
-      if (binfo_or_else (t1, t2))
-       return t1;
-      compiler_error ("common_type called with uncommon aggregate types");
-      return t1;
+      if (! binfo_or_else (t1, t2))
+         compiler_error ("common_type called with uncommon aggregate types");
+      return build_type_attribute_variant (t1, attributes);
 
     case METHOD_TYPE:
       if (comptypes (TYPE_METHOD_BASETYPE (t1), TYPE_METHOD_BASETYPE (t2), 1)
@@ -424,24 +466,28 @@ common_type (t1, t2)
          t2 = build_function_type (TREE_TYPE (t2), TREE_CHAIN (TYPE_ARG_TYPES (t2)));
          t3 = common_type (t1, t2);
          t3 = build_cplus_method_type (basetype, TREE_TYPE (t3), TYPE_ARG_TYPES (t3));
-         return build_exception_variant (basetype, t3, raises);
+         t1 = build_exception_variant (basetype, t3, raises);
        }
-      compiler_error ("common_type called with uncommon method types");
-      return t1;
+      else
+        compiler_error ("common_type called with uncommon method types");
+
+      return build_type_attribute_variant (t1, attributes);
 
     case OFFSET_TYPE:
       if (TYPE_OFFSET_BASETYPE (t1) == TYPE_OFFSET_BASETYPE (t2)
          && TREE_CODE (TREE_TYPE (t1)) == TREE_CODE (TREE_TYPE (t2)))
        {
          tree basetype = TYPE_OFFSET_BASETYPE (t1);
-         return build_offset_type (basetype,
+         t1 = build_offset_type (basetype,
                                    common_type (TREE_TYPE (t1), TREE_TYPE (t2)));
        }
-      compiler_error ("common_type called with uncommon member types");
-      return t1;
+      else
+        compiler_error ("common_type called with uncommon member types");
+
+      /* ... falls through ... */
 
     default:
-      return t1;
+      return build_type_attribute_variant (t1, attributes);
     }
 }
 \f
@@ -514,6 +560,7 @@ comptypes (type1, type2, strict)
 {
   register tree t1 = type1;
   register tree t2 = type2;
+  int attrval, val;
 
   /* Suppress errors caused by previously reported errors */
 
@@ -571,20 +618,30 @@ comptypes (type1, type2, strict)
   if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
     return 1;
 
+#ifdef COMP_TYPE_ATTRIBUTES
+  if (! (attrval = COMP_TYPE_ATTRIBUTES (t1, t2)))
+     return 0;
+#else
+  /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
+  attrval = 1;
+#endif
+
+  /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
+  val = 0;
+
   switch (TREE_CODE (t1))
     {
     case RECORD_TYPE:
     case UNION_TYPE:
-      if (t1 == t2)
-       return 1;
       if (strict <= 0)
        goto look_hard;
       return 0;
 
     case OFFSET_TYPE:
-      return (comptypes (TYPE_POINTER_TO (TYPE_OFFSET_BASETYPE (t1)),
+      val = (comptypes (TYPE_POINTER_TO (TYPE_OFFSET_BASETYPE (t1)),
                         TYPE_POINTER_TO (TYPE_OFFSET_BASETYPE (t2)), strict)
              && comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict));
+      break;
 
     case METHOD_TYPE:
       if (! compexcepttypes (t1, t2, strict))
@@ -595,17 +652,22 @@ comptypes (type1, type2, strict)
         to something expecting a derived member (or member function),
         but not vice-versa!  */
 
-      return (comptypes (TYPE_POINTER_TO (TYPE_METHOD_BASETYPE (t2)),
+      val = (comptypes (TYPE_POINTER_TO (TYPE_METHOD_BASETYPE (t2)),
                         TYPE_POINTER_TO (TYPE_METHOD_BASETYPE (t1)), strict)
              && comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict)
              && compparms (TREE_CHAIN (TYPE_ARG_TYPES (t1)),
                            TREE_CHAIN (TYPE_ARG_TYPES (t2)), strict));
+      break;
+
     case POINTER_TYPE:
     case REFERENCE_TYPE:
       t1 = TREE_TYPE (t1);
       t2 = TREE_TYPE (t2);
       if (t1 == t2)
-       return 1;
+       {
+         val = 1;
+         break;
+       }
       if (strict <= 0)
        {
          if (TREE_CODE (t1) == RECORD_TYPE && TREE_CODE (t2) == RECORD_TYPE)
@@ -615,26 +677,35 @@ comptypes (type1, type2, strict)
              rval = t1 == t2 || UNIQUELY_DERIVED_FROM_P (t1, t2);
 
              if (rval)
-               return 1;
+               {
+                 val = 1;
+                 break;
+               }
              if (strict < 0)
-               return UNIQUELY_DERIVED_FROM_P (t2, t1);
+               {
+                 val = UNIQUELY_DERIVED_FROM_P (t2, t1);
+                 break;
+               }
            }
          return 0;
        }
       else
-       return comptypes (t1, t2, strict);
+       val = comptypes (t1, t2, strict);
+      break;
 
     case FUNCTION_TYPE:
       if (! compexcepttypes (t1, t2, strict))
        return 0;
 
-      return ((TREE_TYPE (t1) == TREE_TYPE (t2)
-              || comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict))
-             && compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2), strict));
+      val = ((TREE_TYPE (t1) == TREE_TYPE (t2)
+             || comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict))
+            && compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2), strict));
+      break;
 
     case ARRAY_TYPE:
       /* Target types must match incl. qualifiers.  */
-      return comp_array_types (comptypes, t1, t2, strict);
+      val = comp_array_types (comptypes, t1, t2, strict);
+      break;
 
     case TEMPLATE_TYPE_PARM:
       return 1;
@@ -642,7 +713,7 @@ comptypes (type1, type2, strict)
     case UNINSTANTIATED_P_TYPE:
       return UPT_TEMPLATE (t1) == UPT_TEMPLATE (t2);
     }
-  return 0;
+  return attrval == 2 && val == 1 ? 2 : val;
 }
 
 /* Return 1 if TTL and TTR are pointers to types that are equivalent,
@@ -683,7 +754,8 @@ comp_target_types (ttl, ttr, nptrs)
        case 1:
          return 1;
        case 2:
-         warning ("contravariance violation for method types ignored");
+         cp_pedwarn ("converting `%T' to `%T' is a contravariance violation",
+                     ttr, ttl);
          return 1;
        default:
          my_friendly_abort (112);
@@ -702,7 +774,8 @@ comp_target_types (ttl, ttr, nptrs)
       else if (comptypes (TYPE_OFFSET_BASETYPE (ttl), TYPE_OFFSET_BASETYPE (ttr), 0)
               && comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), nptrs))
        {
-         warning ("contravariance violation for member types ignored");
+         cp_pedwarn ("converting `%T' to `%T' is a contravariance violation",
+                     ttr, ttl);
          return 1;
        }
     }
@@ -1224,7 +1297,7 @@ 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.  */
 
-  if (code == ENUMERAL_TYPE || code == INTEGER_TYPE)
+  if (INTEGRAL_CODE_P (code))
     {
       tree t = type_promotes_to (type);
       if (t != TYPE_MAIN_VARIANT (type))
@@ -2656,14 +2729,21 @@ build_binary_op (code, arg1, arg2, convert_p)
          tree types[2], try;
          
          types[0] = type1; types[1] = type2;
-         try = build_type_conversion (code, types[convert_index ^ 1],
-                                      args[convert_index], 1);
-         
-         if (try == 0
-             && args[1] == integer_zero_node
-             && (code == NE_EXPR || code == EQ_EXPR))
-           try = build_type_conversion (code, ptr_type_node,
+         if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
+           try = build_type_conversion (code, bool_type_node,
                                         args[convert_index], 1);
+         else
+           {
+             try = build_type_conversion (code, types[convert_index ^ 1],
+                                          args[convert_index], 1);
+         
+             if (try == 0
+                 && args[1] == integer_zero_node
+                 && (code == NE_EXPR || code == EQ_EXPR))
+               try = build_type_conversion (code, ptr_type_node,
+                                            args[convert_index], 1);
+           }
+
          if (try == 0)
            {
              cp_error ("no match for `%O(%#T, %#T)'", code,
@@ -2875,17 +2955,10 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
     case TRUTH_ORIF_EXPR:
     case TRUTH_AND_EXPR:
     case TRUTH_OR_EXPR:
-      if ((code0 == INTEGER_TYPE || code0 == POINTER_TYPE || code0 == REAL_TYPE)
-         && (code1 == INTEGER_TYPE || code1 == POINTER_TYPE || code1 == REAL_TYPE))
-       {
-         /* Result of these operations is always an int,
-            but that does not mean the operands should be
-            converted to ints!  */
-         result_type = integer_type_node;
-         op0 = truthvalue_conversion (op0);
-         op1 = truthvalue_conversion (op1);
-         converted = 1;
-       }
+      result_type = bool_type_node;
+      op0 = bool_truthvalue_conversion (op0);
+      op1 = bool_truthvalue_conversion (op1);
+      converted = 1;
       break;
 
       /* Shift operations: result has same type as first operand;
@@ -2966,9 +3039,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
 
     case EQ_EXPR:
     case NE_EXPR:
-      /* Result of comparison is always int,
-        but don't convert the args to int!  */
-      result_type = integer_type_node;
+      result_type = bool_type_node;
       converted = 1;
       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
          && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
@@ -2984,10 +3055,10 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
            {
              tree base = common_base_type (tt0, tt1);
              if (base == NULL_TREE)
-               warning ("comparison of distinct object pointer types");
+               cp_warning ("comparison of distinct object pointer types `%T' and `%T'", type0, type1);
              else if (base == error_mark_node)
                {
-                 message_2_types (error, "comparison of pointer types `%s*' and `%s*' requires conversion to ambiguous supertype", tt0, tt1);
+                 cp_error ("comparison of pointer types `%T' and `%T' requires conversion to ambiguous supertype", type0, type1);
                  return error_mark_node;
                }
              else
@@ -3017,9 +3088,13 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
                pedwarn ("ANSI C++ forbids comparison of `void *' with function pointer");
            }
          else if ((TYPE_SIZE (tt0) != 0) != (TYPE_SIZE (tt1) != 0))
-           pedwarn ("comparison of complete and incomplete pointers");
+           cp_pedwarn ("comparison of %scomplete and %scomplete pointers `%T' and `%T'",
+                       TYPE_SIZE (tt0) == 0 ? "in" : "",
+                       TYPE_SIZE (tt1) == 0 ? "in" : "",
+                       type0, type1);
          else
-           pedwarn ("comparison of distinct pointer types lacks a cast");
+           cp_pedwarn ("comparison of distinct pointer types `%T' and `%T' lacks a cast",
+                       type0, type1);
        }
       else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
               && integer_zerop (op1))
@@ -3137,10 +3212,14 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
        {
          if (! comp_target_types (type0, type1, 1))
-           pedwarn ("comparison of distinct pointer types lacks a cast");
+           cp_pedwarn ("comparison of distinct pointer types `%T' and `%T' lacks a cast",
+                       type0, type1);
          else if ((TYPE_SIZE (TREE_TYPE (type0)) != 0)
                   != (TYPE_SIZE (TREE_TYPE (type1)) != 0))
-           pedwarn ("comparison of complete and incomplete pointers");
+           cp_pedwarn ("comparison of %scomplete and %scomplete pointers",
+                       TYPE_SIZE (TREE_TYPE (type0)) == 0 ? "in" : "",
+                       TYPE_SIZE (TREE_TYPE (type1)) == 0 ? "in" : "",
+                       type0, type1);
          else if (pedantic
                   && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
            pedwarn ("ANSI C++ forbids ordered comparisons of pointers to functions");
@@ -3158,19 +3237,21 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
        {
          if (! comp_target_types (type0, type1, 1))
-           pedwarn ("comparison of distinct pointer types lacks a cast");
+           cp_pedwarn ("comparison of distinct pointer types `%T' and `%T' lacks a cast",
+                       type0, type1);
          else if ((TYPE_SIZE (TREE_TYPE (type0)) != 0)
                   != (TYPE_SIZE (TREE_TYPE (type1)) != 0))
-           pedwarn ("comparison of complete and incomplete pointers");
+           cp_pedwarn ("comparison of %scomplete and %scomplete pointers",
+                       TYPE_SIZE (TREE_TYPE (type0)) == 0 ? "in" : "",
+                       TYPE_SIZE (TREE_TYPE (type1)) == 0 ? "in" : "",
+                       type0, type1);
          else if (pedantic 
                   && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
            pedwarn ("ANSI C++ forbids ordered comparisons of pointers to functions");
-         result_type = integer_type_node;
        }
       else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
               && integer_zerop (op1))
        {
-         result_type = integer_type_node;
          op1 = null_pointer_node;
          if (pedantic)
            pedwarn ("ordered comparison of pointer with integer zero");
@@ -3178,14 +3259,12 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
       else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
               && integer_zerop (op0))
        {
-         result_type = integer_type_node;
          op0 = null_pointer_node;
          if (pedantic)
            pedwarn ("ANSI C++ forbids ordered comparison of pointer with integer zero");
        }
       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
        {
-         result_type = integer_type_node;
          if (pedantic)
            pedwarn ("ANSI C++ forbids comparison between pointer and integer");
          else if (! flag_traditional)
@@ -3194,13 +3273,13 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
        }
       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
        {
-         result_type = integer_type_node;
          if (pedantic)
            pedwarn ("ANSI C++ forbids comparison between pointer and integer");
          else if (! flag_traditional)
            warning ("comparison between pointer and integer");
          op0 = convert (TREE_TYPE (op1), op0);
        }
+      result_type = bool_type_node;
       converted = 1;
       break;
     }
@@ -3332,8 +3411,8 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
          tree val 
            = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode);
          if (val != 0)
-           return val;
-         op0 = xop0, op1 = xop1, result_type = xresult_type;
+           return convert (bool_type_node, val);
+         op0 = xop0, op1 = xop1, result_type = bool_type_node;
          resultcode = xresultcode;
        }
 
@@ -3659,6 +3738,17 @@ build_x_unary_op (code, xarg)
   return build_unary_op (code, xarg, 0);
 }
 
+/* Just like truthvalue_conversion, but we want a BOOLEAN_TYPE */
+tree
+bool_truthvalue_conversion (expr)
+     tree expr;
+{
+  /* We really want to preform the optimizations in truthvalue_conversion
+     but, not this way. */
+  /* expr = truthvalue_conversion (expr); */
+  return convert (bool_type_node, expr);
+}
+
 /* C++: Must handle pointers to members.
 
    Perhaps type instantiation should be extended to handle conversion
@@ -3771,23 +3861,11 @@ build_unary_op (code, xarg, noconvert)
       break;
 
     case TRUTH_NOT_EXPR:
-      if (isaggrtype)
-       {
-         arg = truthvalue_conversion (arg);
-         typecode = TREE_CODE (TREE_TYPE (arg));
-       }
-
-      if (typecode != INTEGER_TYPE
-         && typecode != REAL_TYPE && typecode != POINTER_TYPE
-         /* These will convert to a pointer.  */
-         && typecode != ARRAY_TYPE && typecode != FUNCTION_TYPE)
-       {
-         errstring = "wrong type argument to unary exclamation mark";
-         break;
-       }
-      arg = truthvalue_conversion (arg);
+      arg = bool_truthvalue_conversion (arg);
       val = invert_truthvalue (arg);
-      if (val) return val;
+      if (arg != error_mark_node)
+       return val;
+      errstring = "in argument to unary !";
       break;
 
     case NOP_EXPR:
@@ -4426,7 +4504,7 @@ build_conditional_expr (ifexp, op1, op2)
       ifexp = op1 = save_expr (ifexp);
     }
 
-  ifexp = truthvalue_conversion (default_conversion (ifexp));
+  ifexp = bool_truthvalue_conversion (default_conversion (ifexp));
 
   if (TREE_CODE (ifexp) == ERROR_MARK)
     return error_mark_node;
@@ -4841,21 +4919,7 @@ build_c_cast (type, expr)
 
   if (TREE_TYPE (value)
       && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (value)))
-    {
-      /* For C++, we must copy the constness of TYPE into VALUE.  */
-      if (TREE_READONLY (value) != TYPE_READONLY (type))
-       {
-         value = copy_node (value);
-         TREE_READONLY (value) = TYPE_READONLY (type);
-       }
-      else if (pedantic)
-       {
-         if (TREE_CODE (type) == RECORD_TYPE
-             || TREE_CODE (type) == UNION_TYPE)
-           pedwarn ("ANSI C++ forbids casting nonscalar to the same type");
-       }
-      return value;
-    }
+    return build1 (NOP_EXPR, type, value);
 
   /* If there's only one function in the overloaded space,
      just take it.  */
@@ -5262,12 +5326,6 @@ build_modify_expr (lhs, modifycode, rhs)
   if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK)
     return error_mark_node;
 
-  /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
-     Strip such NOP_EXPRs, since RHS is being used in non-lvalue context.  */
-  if (TREE_CODE (rhs) == NOP_EXPR
-      && TREE_TYPE (rhs) == TREE_TYPE (TREE_OPERAND (rhs, 0)))
-    rhs = TREE_OPERAND (rhs, 0);
-
   /* Decide early if we are going to protect RHS from GC
      before assigning it to LHS.  */
   if (type_needs_gc_entry (TREE_TYPE (rhs))
@@ -5432,6 +5490,7 @@ build_modify_expr (lhs, modifycode, rhs)
       newrhs = build_binary_op (modifycode, lhs, rhs, 1);
     }
 
+#if 0
   /* Handle a cast used as an "lvalue".
      We have already performed any binary operator using the value as cast.
      Now convert the result to the cast type of the lhs,
@@ -5464,6 +5523,7 @@ build_modify_expr (lhs, modifycode, rhs)
        return convert_force (TREE_TYPE (lhs), result);
       }
     }
+#endif
 
   if (TREE_CODE (lhs) == OFFSET_REF)
     {
@@ -5521,16 +5581,10 @@ build_modify_expr (lhs, modifycode, rhs)
   /* check to see if there is an assignment to `this' */
   if (lhs == current_class_decl)
     {
-      if (DECL_NAME (current_function_decl) != NULL_TREE)
-       {
-         /* ARM 18.3.3 and draft standard section C.11 say that assigning
-            something to this is an anachronism.  */
-         if (pedantic)
-           warning ("anachronistic assignment to `this' pointer");
-         else if (flag_this_is_variable > 0
-                  && current_class_name != DECL_NAME (current_function_decl))
-           warning ("assignment to `this' not in constructor or destructor");
-       }
+      if (flag_this_is_variable > 0
+         && DECL_NAME (current_function_decl) != NULL_TREE
+         && current_class_name != DECL_NAME (current_function_decl))
+       warning ("assignment to `this' not in constructor or destructor");
       current_function_just_assigned_this = 1;
     }
 
@@ -6151,8 +6205,8 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
       return error_mark_node;
     }
   /* Arithmetic types all interconvert.  */
-  if ((codel == INTEGER_TYPE || codel == REAL_TYPE)
-       && (coder == INTEGER_TYPE || coder == REAL_TYPE))
+  if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == BOOLEAN_TYPE)
+       && (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == BOOLEAN_TYPE))
     {
       /* But we should warn if assigning REAL_TYPE to INTEGER_TYPE.  */
       if (coder == REAL_TYPE && codel == INTEGER_TYPE)
@@ -6165,7 +6219,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
        }
       /* And we should warn if assigning a negative value to
         an unsigned variable.  */
-      else if (TREE_UNSIGNED (type))
+      else if (TREE_UNSIGNED (type) && codel != BOOLEAN_TYPE)
        {
          if (TREE_CODE (rhs) == INTEGER_CST
              && TREE_NEGATED_INT (rhs))
@@ -6268,12 +6322,14 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
          if (TYPE_MAIN_VARIANT (ttl) != void_type_node
              && TYPE_MAIN_VARIANT (ttr) == void_type_node
              && rhs != null_pointer_node)
-           if (coder == RECORD_TYPE)
-             pedwarn ("implicit conversion of signature pointer to type `%s'",
-                      type_as_string (type, 0));
-           else
-             pedwarn ("ANSI C++ forbids implicit conversion from `void *' in %s",
-                      errtype);
+           {
+             if (coder == RECORD_TYPE)
+               pedwarn ("implicit conversion of signature pointer to type `%s'",
+                        type_as_string (type, 0));
+             else
+               pedwarn ("ANSI C++ forbids implicit conversion from `void *' in %s",
+                        errtype);
+           }
          /* Const and volatile mean something different for function types,
             so the usual warnings are not appropriate.  */
          else if ((TREE_CODE (ttr) != FUNCTION_TYPE && TREE_CODE (ttr) != METHOD_TYPE)
@@ -6286,7 +6342,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
                  sorry ("%s between pointer to members converting across virtual baseclasses", errtype);
                  return error_mark_node;
                }
-             if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
+             else if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
                {
                  if (fndecl)
                    cp_pedwarn ("passing `%T' as argument %P of `%D' discards const",
@@ -6295,7 +6351,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
                    cp_pedwarn ("%s to `%T' from `%T' discards const",
                                errtype, type, rhstype);
                }
-             if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
+             else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
                {
                  if (fndecl)
                    cp_pedwarn ("passing `%T' as argument %P of `%D' discards volatile",
@@ -6304,6 +6360,16 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
                    cp_pedwarn ("%s to `%T' from `%T' discards volatile",
                                errtype, type, rhstype);
                }
+             else if (TREE_CODE (ttl) == TREE_CODE (ttr)
+                      && ! comp_target_types (type, rhstype, 1))
+               {
+                 if (fndecl)
+                   cp_pedwarn ("passing `%T' as argument %P of `%D' changes signedness",
+                               rhstype, parmnum, fndecl);
+                 else
+                   cp_pedwarn ("%s to `%T' from `%T' changes signedness",
+                               errtype, type, rhstype);
+               }
            }
        }
       else if (TREE_CODE (ttr) == OFFSET_TYPE
@@ -6570,8 +6636,24 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
      return here before checking if RHS is of complete type.  */
      
   if (codel == REFERENCE_TYPE)
-    return convert_to_reference (type, rhs, CONV_IMPLICIT, flags,
-                                exp ? exp : error_mark_node);
+    {
+      /* This should eventually happen in convert_arguments.  */
+      extern int warningcount, errorcount;
+      int savew, savee;
+
+      if (fndecl)
+       savew = warningcount, savee = errorcount;
+      rhs = convert_to_reference (type, rhs, CONV_IMPLICIT, flags,
+                                 exp ? exp : error_mark_node);
+      if (fndecl)
+       {
+         if (warningcount > savew)
+           cp_warning_at ("in passing argument %P of `%+D'", parmnum, fndecl);
+         else if (errorcount > savee)
+           cp_error_at ("in passing argument %P of `%+D'", parmnum, fndecl);
+       }
+      return rhs;
+    }      
 
   rhs = require_complete_type (rhs);
   if (rhs == error_mark_node)
index 858896a4f11a536e56b177add0267fc8f5fe2eab..baf55a41b9f170c612bef8494dfbb7baa2727efe 100644 (file)
@@ -766,6 +766,7 @@ digest_init (type, init, tail)
 
   if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE
       || code == ENUMERAL_TYPE || code == REFERENCE_TYPE
+      || code == BOOLEAN_TYPE
       || (code == RECORD_TYPE && ! raw_constructor
          && (IS_SIGNATURE_POINTER (type) || IS_SIGNATURE_REFERENCE (type))))
     {
@@ -951,13 +952,7 @@ process_init_constructor (type, init, elts)
              continue;
            }
 
-         if (TREE_CODE (field) == CONST_DECL || TREE_CODE (field) == TYPE_DECL)
-           continue;
-
-         /* A static member isn't considered "part of the object", so
-            it has no business even thinking about involving itself in
-            what an initializer-list is trying to do.  */
-         if (TREE_CODE (field) == VAR_DECL && TREE_STATIC (field))
+         if (TREE_CODE (field) != FIELD_DECL)
            continue;
 
          if (TREE_VALUE (tail) != 0)
@@ -1462,16 +1457,18 @@ build_functional_cast (exp, parms)
     }
 
   {
-    int flags = LOOKUP_SPECULATIVELY|LOOKUP_COMPLAIN;
+    int flags = LOOKUP_SPECULATIVELY|LOOKUP_NORMAL;
 
     if (parms && TREE_CHAIN (parms) == NULL_TREE)
       flags |= LOOKUP_NO_CONVERSION;
 
-  try_again:
     expr_as_ctor = build_method_call (NULL_TREE, name, parms,
                                      NULL_TREE, flags);
 
-    if (expr_as_ctor && expr_as_ctor != error_mark_node)
+    if (expr_as_ctor == error_mark_node)
+      return error_mark_node;
+
+    else if (expr_as_ctor)
       {
        if (expr_as_conversion && expr_as_conversion != error_mark_node)
          {
@@ -1514,18 +1511,6 @@ build_functional_cast (exp, parms)
        return expr_as_ctor;
       }
 
-    /* If it didn't work going through constructor, try type conversion.  */
-    if (! (flags & LOOKUP_COMPLAIN))
-      {
-       if (expr_as_conversion)
-         return expr_as_conversion;
-       if (flags & LOOKUP_NO_CONVERSION)
-         {
-           flags = LOOKUP_NORMAL;
-           goto try_again;
-         }
-      }
-
     if (expr_as_conversion)
       return expr_as_conversion;