91th Cygnus<->FSF quick merge
authorMike Stump <mrs@gcc.gnu.org>
Wed, 28 May 1997 23:20:02 +0000 (23:20 +0000)
committerMike Stump <mrs@gcc.gnu.org>
Wed, 28 May 1997 23:20:02 +0000 (23:20 +0000)
From-SVN: r14134

21 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/error.c
gcc/cp/gxx.gperf
gcc/cp/hash.h
gcc/cp/init.c
gcc/cp/lang-specs.h
gcc/cp/lex.c
gcc/cp/lex.h
gcc/cp/method.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/rtti.c
gcc/cp/sig.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/cp/typeck2.c

index 79e655c..a61f4ee 100644 (file)
@@ -1,3 +1,91 @@
+Tue May 27 19:49:19 1997  Mike Stump  <mrs@cygnus.com>
+
+       * cvt.c (convert): Don't do any extra work, if we can avoid it
+       easily.
+
+Tue May 27 18:21:47 1997  Mike Stump  <mrs@cygnus.com>
+
+       * *.[chy]: Change cp_convert to ocp_convert, change convert to
+       cp_convert.  convert is now reserved for the backend, and doesn't
+       have the semantics a frontend person should ever want.
+
+Fri May 23 10:58:31 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * lang-specs.h: Define __EXCEPTIONS if exceptions are enabled.
+       Lose -traditional support.
+
+Thu May 22 15:41:28 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * rtti.c (get_tinfo_var): Use TYPE_PRECISION (sizetype).
+
+       * parse.y (self_reference): Do it for templates, too.
+       * class.c (pushclass): Don't overload_template_name; the alias
+       generated by build_self_reference serves the same purpose.
+
+       * tree.c (list_hash): Make static, take more args.
+       (list_hash_lookup): Likewise.
+       (list_hash_add): Make static.
+       (list_hash_canon): Lose.
+       (hash_tree_cons): Only build a new node if one isn't already in the
+       hashtable.
+       (hash_tree_chain): Use hash_tree_cons.
+       * cp-tree.h: Adjust.
+       * decl.c (grokfndecl): Just check IDENTIFIER_GLOBAL_VALUE instead
+       of calling lookup_name.
+
+Wed May 21 18:24:19 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * pt.c (instantiate_class_template): TYPE_VALUES for an enum
+       doesn't refer to the CONST_DECLs.
+
+Tue May 20 21:09:32 1997  Bob Manson  <manson@charmed.cygnus.com>
+
+       * rtti.c (get_tinfo_var): Either INT_TYPE_SIZE or 32, whichever
+       is bigger.
+       (expand_class_desc): Convert the last argument to a sizetype.
+
+Tue May 20 13:55:57 1997  Brendan Kehoe  <brendan@lisa.cygnus.com>
+
+       * gxx.gperf (__complex, __complex__, __imag, __imag__, __real,
+       __real__): Add reswords.
+       * hash.h: Regenerate.
+       * lex.h (rid): Add RID_COMPLEX.
+       (RID_LAST_MODIFIER): Set to RID_COMPLEX.
+       * lex.c (init_lex): Add building of RID_COMPLEX.  Unset reserved
+       word "complex" if -fno-gnu-keywords.
+       (real_yylex): General cleanup in line with what c-lex.c also has,
+       sans the cruft for traditional; add handling of SPEC_IMAG, complex
+       types, and imaginary numeric constants.
+       * parse.y (REALPART, IMAGPART): Add tokens.
+       (unary_expr): Add REALPART and IMAGPART rules.
+       * cp-tree.h (complex_{integer,float,double,long}_type_node): Declare.
+       * decl.c (complex_{integer,float,double,long}_type_node): Define
+       types.
+       (init_decl_processing): Set up the types.
+       (grokdeclarator): Add handling of RID_COMPLEX.  Set and use
+       DEFAULTED_INT instead of EXPLICIT_INT when we default to int type.
+       * call.c (build_new_op): Add REALPART_EXPR and IMAGPART_EXPR cases.
+       * cvt.c (cp_convert): Handle COMPLEX_TYPE.
+       * error.c (dump_type_prefix, dump_type, dump_type_suffix): Add
+       COMPLEX_TYPE case.
+       * method.c (build_overload_name): Add handling of the different
+       COMPLEX_TYPEs, prefixing them with `J'.
+       * pt.c (process_template_parm): Don't let them use a COMPLEX_TYPE
+       as a template parm.
+       (uses_template_parms, tsubst, unify): Add COMPLEX_TYPE case.
+       * tree.c (lvalue_p): Add REALPART_EXPR and IMAGPART_EXPR cases.
+       (mapcar): Handle COMPLEX_CST.
+       * typeck.c (build_binary_op_nodefault): Handle COMPLEX_TYPE.
+       (common_type): Add code for complex types.
+       (build_unary_op): Add REALPART_EXPR and IMAGPART_EXPR cases.
+       (convert_for_assignment): Likewise.
+       (mark_addressable): Add REALPART_EXPR and IMAGPART_EXPR cases.
+
+Mon May 19 12:26:27 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * pt.c (tsubst): Don't pass the MINUS_EXPR for an array domain to
+       tsubst_expr, as it might try to do overload resolution.
+
 Sat May 17 10:48:31 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
        * pt.c (instantiate_class_template): Oops.
@@ -38,10 +126,10 @@ Mon May  5 14:46:53 1997  Jason Merrill  <jason@yorick.cygnus.com>
 Thu May  1 18:26:37 1997  Mike Stump  <mrs@cygnus.com>
 
        * except.c (expand_exception_blocks): Ensure that we flow through
-       the end of the exception region for the exception specification.
-       Move exception region for the exception specification in, so that
-       it doesn't protect the parm cleanup.  Remove some obsolete code.
-       * decl.c (store_parm_decls): Likewise.
+       the end of the exception region for the exception specification.
+       Move exception region for the exception specification in, so that
+       it doesn't protect the parm cleanup.  Remove some obsolete code.
+       * decl.c (store_parm_decls): Likewise.
        (finish_function): Likewise.
 
 Tue Apr 29 15:38:54 1997  Jason Merrill  <jason@yorick.cygnus.com>
@@ -64,7 +152,7 @@ Fri Apr 25 11:55:23 1997  Jason Merrill  <jason@yorick.cygnus.com>
        to -Weffc++.
 
        * decl2.c (finish_prevtable_vardecl): Change NO_LINKAGE_HEURISTICS
-       to MULTIPLE_SYMBOL_SPACES.
+       to MULTIPLE_SYMBOL_SPACES.
 
 Wed Apr 23 18:06:50 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
@@ -89,7 +177,7 @@ Wed Apr 23 14:43:06 1997  Mike Stump  <mrs@cygnus.com>
        * exception.cc (__default_terminate): Likewise.
 
        * init.c (perform_member_init): Use new method of expr level
-       cleanups, instead of cleanups_this_call and friends.
+       cleanups, instead of cleanups_this_call and friends.
        (emit_base_init): Likewise.
        (expand_aggr_vbase_init_1): Likewise.
        (expand_vec_init): Likewise.
@@ -111,7 +199,7 @@ Wed Apr 23 04:12:06 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
        * tree.c (varargs_function_p): New fn.
        * method.c (emit_thunk): Replace broken generic code with code to
-       generate a heavyweight thunk function.
+       generate a heavyweight thunk function.
 
 Tue Apr 22 02:45:18 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
@@ -124,28 +212,28 @@ Tue Apr 22 02:45:18 1997  Jason Merrill  <jason@yorick.cygnus.com>
 Mon Apr 21 15:42:27 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
        * class.c (check_for_override): The signature of an overriding
-       function is not changed.
+       function is not changed.
 
        * call.c (build_over_call): Move setting of conv into the loop.
 
 Sun Apr 20 16:24:29 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
        * call.c (build_user_type_conversion_1): Really ignore rvalue
-       conversions when looking for a REFERENCE_TYPE.
+       conversions when looking for a REFERENCE_TYPE.
 
        * cvt.c (build_up_reference): Eviscerate, use build_unary_op.
        * cp-tree.h (TREE_REFERENCE_EXPR): #if 0.
        * typeck.c (decay_conversion): Don't set TREE_REFERENCE_EXPR.
        (build_unary_op): Likewise.
        * call.c (build_over_call): See through a CONVERT_EXPR around the
-       ADDR_EXPR for on a temporary.
+       ADDR_EXPR for on a temporary.
        * typeck.c (c_expand_return): See through a CONVERT_EXPR around
-       the ADDR_EXPR for a local variable.
+       the ADDR_EXPR for a local variable.
 
 Fri Apr 18 12:11:33 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
        * call.c (build_user_type_conversion_1): If we're trying to
-       convert to a REFERENCE_TYPE, only consider lvalue conversions.
+       convert to a REFERENCE_TYPE, only consider lvalue conversions.
        (build_new_function_call): Print candidates.
        (implicit_conversion): Try a temp binding if the lvalue conv is BAD.
        (reference_binding): Binding a temporary of a reference-related type
@@ -163,7 +251,7 @@ Mon Apr 14 12:38:17 1997  Jason Merrill  <jason@yorick.cygnus.com>
 Fri Apr 11 02:18:30 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
        * call.c (implicit_conversion): Try to find a reference conversion
-       before binding a const reference to a temporary.
+       before binding a const reference to a temporary.
 
 Wed Apr  2 12:51:36 1997  Mike Stump  <mrs@cygnus.com>
 
@@ -12223,7 +12311,7 @@ Tue Apr  5 17:48:41 1994  Per Bothner  <bothner@kalessin.cygnus.com>
        * decl2.c (write_vtable_entries, finish_vtable_typedecl):  Removed.
 
        * cp-tree.h, class.c, decl2.c, search.c:  Remove -fvtable-hack
-       and flag_vtable_hack.   Use -fvtable-thunks and flag_vtable_thunks
+       and flag_vtable_hack.  Use -fvtable-thunks and flag_vtable_thunks
        instead.  (The rationale is that these optimizations both break binary
        compatibility, but should become the default in a future release.)
 
index a469e04..0e36807 100644 (file)
@@ -1448,7 +1448,7 @@ build_scoped_method_call (exp, basetype, name, parms)
       if (basetype != name && basetype != get_type_value (name))
        cp_error ("qualified type `%T' does not match destructor name `~%T'",
                  basetype, name);
-      return convert (void_type_node, exp);
+      return cp_convert (void_type_node, exp);
     }
 
   if (! is_aggr_type (basetype, 1))
@@ -1494,7 +1494,7 @@ build_scoped_method_call (exp, basetype, name, parms)
              return error_mark_node;
            }
          if (! TYPE_HAS_DESTRUCTOR (TREE_TYPE (decl)))
-           return convert (void_type_node, exp);
+           return cp_convert (void_type_node, exp);
          
          return build_delete (TREE_TYPE (decl), decl, integer_two_node,
                               LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR,
@@ -1751,11 +1751,11 @@ build_method_call (instance, name, parms, basetype_path, flags)
        {
          cp_error ("destructor name `~%D' does not match type `%T' of expression",
                    name, basetype);
-         return convert (void_type_node, instance);
+         return cp_convert (void_type_node, instance);
        }
 
       if (! TYPE_HAS_DESTRUCTOR (basetype))
-       return convert (void_type_node, instance);
+       return cp_convert (void_type_node, instance);
       instance = default_conversion (instance);
       instance_ptr = build_unary_op (ADDR_EXPR, instance, 0);
       return build_delete (build_pointer_type (basetype),
@@ -1986,7 +1986,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
            basetype = inst_ptr_basetype;
          else
            {
-             instance_ptr = convert (build_pointer_type (basetype), instance_ptr);
+             instance_ptr = cp_convert (build_pointer_type (basetype), instance_ptr);
              if (instance_ptr == error_mark_node)
                return error_mark_node;
            }
@@ -4835,6 +4835,8 @@ builtin:
     case POSTINCREMENT_EXPR:
     case PREDECREMENT_EXPR:
     case POSTDECREMENT_EXPR:
+    case REALPART_EXPR:
+    case IMAGPART_EXPR:
       return build_unary_op (code, arg1, candidates != 0);
 
     case ARRAY_REF:
@@ -4972,8 +4974,8 @@ convert_like (convs, expr)
     case LVALUE_CONV:
       return decay_conversion (expr);
     }
-  return cp_convert (TREE_TYPE (convs), expr, CONV_IMPLICIT,
-                    LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
+  return ocp_convert (TREE_TYPE (convs), expr, CONV_IMPLICIT,
+                     LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
 }
 
 static tree
@@ -5125,7 +5127,7 @@ build_over_call (fn, convs, args, flags)
          && (TYPE_PRECISION (TREE_TYPE (val))
              < TYPE_PRECISION (double_type_node)))
        /* Convert `float' to `double'.  */
-       val = convert (double_type_node, val);
+       val = cp_convert (double_type_node, val);
       else if (TYPE_LANG_SPECIFIC (TREE_TYPE (val))
               && ! TYPE_HAS_TRIVIAL_INIT_REF (TREE_TYPE (val)))
        cp_warning ("cannot pass objects of type `%T' through `...'",
index 44483c0..37cdb6b 100644 (file)
@@ -322,8 +322,11 @@ build_vbase_path (code, type, expr, path, alias_this)
   if (TREE_INT_CST_LOW (offset))
     {
       /* Bash types to make the backend happy.  */
-      offset = convert (type, offset);
+      offset = cp_convert (type, offset);
+#if 0
+      /* This shouldn't be necessary.  (mrs) */
       expr = build1 (NOP_EXPR, type, expr);
+#endif
 
       /* For multiple inheritance: if `this' can be set by any
         function, then it could be 0 on entry to any function.
@@ -518,8 +521,8 @@ build_vfn_ref (ptr_to_instptr, instance, idx)
       *ptr_to_instptr
        = build (PLUS_EXPR, TREE_TYPE (*ptr_to_instptr),
                 *ptr_to_instptr,
-                convert (ptrdiff_type_node,
-                         build_component_ref (aref, delta_identifier, NULL_TREE, 0)));
+                cp_convert (ptrdiff_type_node,
+                            build_component_ref (aref, delta_identifier, NULL_TREE, 0)));
     }
 
   return build_component_ref (aref, pfn_identifier, NULL_TREE, 0);
@@ -4630,8 +4633,10 @@ pushclass (type, modify)
 
   pushlevel_class ();
 
+#if 0
   if (CLASSTYPE_TEMPLATE_INFO (type))
     overload_template_name (type);
+#endif
 
   if (modify)
     {
index 96dd147..677c0fa 100644 (file)
@@ -135,6 +135,12 @@ extern tree unsigned_type_node;
 extern tree string_type_node, char_array_type_node, int_array_type_node;
 extern tree wchar_array_type_node;
 extern tree wchar_type_node, signed_wchar_type_node, unsigned_wchar_type_node;
+
+extern tree complex_integer_type_node;
+extern tree complex_float_type_node;
+extern tree complex_double_type_node;
+extern tree complex_long_double_type_node;
+
 extern tree intQI_type_node, unsigned_intQI_type_node;
 extern tree intHI_type_node, unsigned_intHI_type_node;
 extern tree intSI_type_node, unsigned_intSI_type_node;
@@ -1969,7 +1975,8 @@ extern tree convert_from_reference                PROTO((tree));
 extern tree convert_to_aggr                    PROTO((tree, tree, char **, int));
 extern tree convert_pointer_to_real            PROTO((tree, tree));
 extern tree convert_pointer_to                 PROTO((tree, tree));
-extern tree cp_convert                         PROTO((tree, tree, int, int));
+extern tree ocp_convert                                PROTO((tree, tree, int, int));
+extern tree cp_convert                         PROTO((tree, tree));
 extern tree convert                            PROTO((tree, tree));
 extern tree convert_force                      PROTO((tree, tree, int));
 extern tree build_type_conversion              PROTO((enum tree_code, tree, tree, int));
@@ -2380,10 +2387,6 @@ extern tree build_cplus_array_type               PROTO((tree, tree));
 extern void propagate_binfo_offsets            PROTO((tree, tree));
 extern int layout_vbasetypes                   PROTO((tree, int));
 extern tree layout_basetypes                   PROTO((tree, tree));
-extern int list_hash                           PROTO((tree));
-extern tree list_hash_lookup                   PROTO((int, tree));
-extern void list_hash_add                      PROTO((int, tree));
-extern tree list_hash_canon                    PROTO((int, tree));
 extern tree hash_tree_cons                     PROTO((int, int, int, tree, tree, tree));
 extern tree hash_tree_chain                    PROTO((tree, tree));
 extern tree hash_chainon                       PROTO((tree, tree));
index e9054c2..26e388d 100644 (file)
@@ -283,7 +283,7 @@ cp_convert_to_pointer (type, expr)
     {
       if (type_precision (intype) == POINTER_SIZE)
        return build1 (CONVERT_EXPR, type, expr);
-      expr = convert (type_for_size (POINTER_SIZE, 0), expr);
+      expr = cp_convert (type_for_size (POINTER_SIZE, 0), expr);
       /* Modes may be different but sizes should be the same.  */
       if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr)))
          != GET_MODE_SIZE (TYPE_MODE (type)))
@@ -606,7 +606,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
        rval = rval_as_conversion;
       else if (! IS_AGGR_TYPE (type) && ! IS_AGGR_TYPE (intype))
        {
-         rval = convert (type, expr);
+         rval = cp_convert (type, expr);
          if (rval == error_mark_node)
            return error_mark_node;
          
@@ -922,12 +922,21 @@ convert_pointer_to (binfo, expr)
   return convert_pointer_to_real (type, expr);
 }
 \f
+/* C++ conversions, preference to static cast conversions.  */
+
+tree
+cp_convert (type, expr)
+     tree type, expr;
+{
+  return ocp_convert (type, expr, CONV_OLD_CONVERT, LOOKUP_NORMAL);
+}
+
 /* Conversion...
 
    FLAGS indicates how we should behave.  */
 
 tree
-cp_convert (type, expr, convtype, flags)
+ocp_convert (type, expr, convtype, flags)
      tree type, expr;
      int convtype, flags;
 {
@@ -951,7 +960,7 @@ cp_convert (type, expr, convtype, flags)
   /* This is incorrect.  A truncation can't be stripped this way.
      Extensions will be stripped by the use of get_unwidened.  */
   if (TREE_CODE (e) == NOP_EXPR)
-    return convert (type, TREE_OPERAND (e, 0));
+    return cp_convert (type, TREE_OPERAND (e, 0));
 #endif
 
   /* Just convert to the type of the member.  */
@@ -1014,7 +1023,7 @@ cp_convert (type, expr, convtype, flags)
   if (code == POINTER_TYPE || code == REFERENCE_TYPE
       || TYPE_PTRMEMFUNC_P (type))
     return fold (cp_convert_to_pointer (type, e));
-  if (code == REAL_TYPE)
+  if (code == REAL_TYPE || code == COMPLEX_TYPE)
     {
       if (IS_AGGR_TYPE (TREE_TYPE (e)))
        {
@@ -1027,7 +1036,10 @@ cp_convert (type, expr, convtype, flags)
              cp_error ("`%#T' used where a floating point value was expected",
                        TREE_TYPE (e));
        }
-      return fold (convert_to_real (type, e));
+      if (code == REAL_TYPE)
+       return fold (convert_to_real (type, e));
+      else if (code == COMPLEX_TYPE)
+       return fold (convert_to_complex (type, e));
     }
 
   /* New C++ semantics:  since assignment is now based on
@@ -1155,16 +1167,82 @@ cp_convert (type, expr, convtype, flags)
    converted to type TYPE.  The TREE_TYPE of the value
    is always TYPE.  This function implements all reasonable
    conversions; callers should filter out those that are
-   not permitted by the language being compiled.  */
+   not permitted by the language being compiled.
+
+   Most of this routine is from build_reinterpret_cast.
+
+   The backend cannot call cp_convert (what was convert) because
+   conversions to/from basetypes may involve memory references
+   (vbases) and adding or subtracting small values (multiple
+   inheritance), but it calls convert from the constant folding code
+   on subtrees of already build trees after it has ripped them apart.
+
+   Also, if we ever support range variables, we'll probably also have to
+   do a little bit more work.  */
 
 tree
 convert (type, expr)
      tree type, expr;
 {
-  return cp_convert (type, expr, CONV_OLD_CONVERT, LOOKUP_NORMAL);
+  tree intype;
+
+  if (type == error_mark_node || expr == error_mark_node)
+    return error_mark_node;
+
+  if (TREE_TYPE (expr) == type)
+    return expr;
+
+  if (TREE_CODE (type) != REFERENCE_TYPE)
+    {
+      expr = decay_conversion (expr);
+
+      /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
+        Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
+      if (TREE_CODE (expr) == NOP_EXPR
+         && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
+       expr = TREE_OPERAND (expr, 0);
+    }
+
+  intype = TREE_TYPE (expr);
+
+  if (TREE_CODE (type) == REFERENCE_TYPE)
+    {
+      expr = build_unary_op (ADDR_EXPR, expr, 0);
+      if (expr != error_mark_node)
+       expr = convert (build_pointer_type (TREE_TYPE (type)), expr);
+      if (expr != error_mark_node)
+       expr = build_indirect_ref (expr, 0);
+      return expr;
+    }
+  else if (comptypes (TYPE_MAIN_VARIANT (intype), TYPE_MAIN_VARIANT (type), 1))
+    return build_static_cast (type, expr);
+
+  if (TYPE_PTR_P (type) && (TREE_CODE (intype) == INTEGER_TYPE
+                           || TREE_CODE (intype) == ENUMERAL_TYPE))
+    /* OK */;
+  else if (TREE_CODE (type) == INTEGER_TYPE && TYPE_PTR_P (intype))
+    {
+    }
+  else if ((TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
+          || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
+    {
+      if (TREE_READONLY_DECL_P (expr))
+       expr = decl_constant_value (expr);
+      return fold (build1 (NOP_EXPR, type, expr));
+    }
+  else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
+          || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
+    {
+      if (TREE_READONLY_DECL_P (expr))
+       expr = decl_constant_value (expr);
+      return fold (build1 (NOP_EXPR, type, expr));
+    }
+
+  return ocp_convert (type, expr, CONV_OLD_CONVERT,
+                     LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
 }
 
-/* Like convert, except permit conversions to take place which
+/* Like cp_convert, except permit conversions to take place which
    are not normally allowed due to access restrictions
    (such as conversion from sub-type to private super-type).  */
 
@@ -1198,7 +1276,7 @@ convert_force (type, expr, convtype)
       return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), e, 1);
     }
 
-  return cp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL);
+  return ocp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL);
 }
 
 /* Subroutine of build_type_conversion.  */
@@ -1234,7 +1312,7 @@ build_type_conversion_1 (xtype, basetype, expr, typename, for_sure)
       && (TREE_READONLY (TREE_TYPE (TREE_TYPE (rval)))
          > TREE_READONLY (TREE_TYPE (xtype))))
     warning ("user-defined conversion casting away `const'");
-  return convert (xtype, rval);
+  return cp_convert (xtype, rval);
 }
 
 /* Convert an aggregate EXPR to type XTYPE.  If a conversion
@@ -1539,8 +1617,8 @@ build_default_binary_type_conversion (code, arg1, arg2)
 
     case TRUTH_ANDIF_EXPR:
     case TRUTH_ORIF_EXPR:
-      *arg1 = convert (boolean_type_node, *arg1);
-      *arg2 = convert (boolean_type_node, *arg2);
+      *arg1 = cp_convert (boolean_type_node, *arg1);
+      *arg2 = cp_convert (boolean_type_node, *arg2);
       break;
 
     default:
index 0ed77d4..41e6c15 100644 (file)
@@ -169,6 +169,11 @@ tree float_type_node;
 tree double_type_node;
 tree long_double_type_node;
 
+tree complex_integer_type_node;
+tree complex_float_type_node;
+tree complex_double_type_node;
+tree complex_long_double_type_node;
+
 tree intQI_type_node;
 tree intHI_type_node;
 tree intSI_type_node;
@@ -4805,6 +4810,30 @@ init_decl_processing ()
   record_builtin_type (RID_MAX, "long double", long_double_type_node);
   layout_type (long_double_type_node);
 
+  complex_integer_type_node = make_node (COMPLEX_TYPE);
+  pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
+                       complex_integer_type_node));
+  TREE_TYPE (complex_integer_type_node) = integer_type_node;
+  layout_type (complex_integer_type_node);
+
+  complex_float_type_node = make_node (COMPLEX_TYPE);
+  pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
+                       complex_float_type_node));
+  TREE_TYPE (complex_float_type_node) = float_type_node;
+  layout_type (complex_float_type_node);
+
+  complex_double_type_node = make_node (COMPLEX_TYPE);
+  pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
+                       complex_double_type_node));
+  TREE_TYPE (complex_double_type_node) = double_type_node;
+  layout_type (complex_double_type_node);
+
+  complex_long_double_type_node = make_node (COMPLEX_TYPE);
+  pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
+                       complex_long_double_type_node));
+  TREE_TYPE (complex_long_double_type_node) = long_double_type_node;
+  layout_type (complex_long_double_type_node);
+
   integer_zero_node = build_int_2 (0, 0);
   TREE_TYPE (integer_zero_node) = integer_type_node;
   integer_one_node = build_int_2 (1, 0);
@@ -7105,9 +7134,7 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals,
 
       if (check == 0 && ! current_function_decl)
        {
-         /* FIXME: this should only need to look at
-             IDENTIFIER_GLOBAL_VALUE.  */
-         tmp = lookup_name (DECL_ASSEMBLER_NAME (decl), 0);
+         tmp = IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl));
          if (tmp == NULL_TREE)
            IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl)) = decl;
          else if (TREE_CODE (tmp) != TREE_CODE (decl))
@@ -7379,6 +7406,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
   int virtualp, explicitp, friendp, inlinep, staticp;
   int explicit_int = 0;
   int explicit_char = 0;
+  int defaulted_int = 0;
   int opaque_typedef = 0;
   tree typedef_decl = NULL_TREE;
   char *name;
@@ -7808,7 +7836,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
 
   typedef_type = type;
 
-  /* No type at all: default to `int', and set EXPLICIT_INT
+  /* No type at all: default to `int', and set DEFAULTED_INT
      because it was not a user-defined typedef.
      Except when we have a `typedef' inside a signature, in
      which case the type defaults to `unknown type' and is
@@ -7822,7 +7850,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
     {
       /* These imply 'int'.  */
       type = integer_type_node;
-      explicit_int = 1;
+      defaulted_int = 1;
     }
 
   if (type == NULL_TREE)
@@ -7928,7 +7956,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
       else
        {
          ok = 1;
-         if (!explicit_int && !explicit_char && pedantic)
+         if (!explicit_int && !defaulted_int && !explicit_char && pedantic)
            {
              pedwarn ("long, short, signed or unsigned used invalidly for `%s'",
                       name);
@@ -7948,11 +7976,18 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
        }
     }
 
+  if (RIDBIT_SETP (RID_COMPLEX, specbits)
+      && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
+    {
+      error ("complex invalid for `%s'", name);
+      RIDBIT_RESET (RID_COMPLEX, specbits);
+    }
+
   /* Decide whether an integer type is signed or not.
      Optionally treat bitfields as signed by default.  */
   if (RIDBIT_SETP (RID_UNSIGNED, specbits)
       || (bitfield && ! flag_signed_bitfields
-         && (explicit_int || explicit_char
+         && (explicit_int || defaulted_int || explicit_char
              /* A typedef for plain `int' without `signed'
                 can be controlled just like plain `int'.  */
              || ! (typedef_decl != NULL_TREE
@@ -7983,6 +8018,31 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
   else if (RIDBIT_SETP (RID_SHORT, specbits))
     type = short_integer_type_node;
 
+  if (RIDBIT_SETP (RID_COMPLEX, specbits))
+    {
+      /* If we just have "complex", it is equivalent to
+        "complex double", but if any modifiers at all are specified it is
+        the complex form of TYPE.  E.g, "complex short" is
+        "complex short int".  */
+
+      if (defaulted_int && ! longlong
+         && ! (RIDBIT_SETP (RID_LONG, specbits)
+               || RIDBIT_SETP (RID_SHORT, specbits)
+               || RIDBIT_SETP (RID_SIGNED, specbits)
+               || RIDBIT_SETP (RID_UNSIGNED, specbits)))
+       type = complex_double_type_node;
+      else if (type == integer_type_node)
+       type = complex_integer_type_node;
+      else if (type == float_type_node)
+       type = complex_float_type_node;
+      else if (type == double_type_node)
+       type = complex_double_type_node;
+      else if (type == long_double_type_node)
+       type = complex_long_double_type_node;
+      else
+       type = build_complex_type (type);
+    }
+
   /* Set CONSTP if this declaration is `const', whether by
      explicit specification or via a typedef.
      Likewise for VOLATILEP.  */
@@ -8353,9 +8413,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
 
                itype
                  = fold (build_binary_op (MINUS_EXPR,
-                                          convert (index_type, size),
-                                          convert (index_type,
-                                                   integer_one_node), 1));
+                                          cp_convert (index_type, size),
+                                          cp_convert (index_type,
+                                                      integer_one_node), 1));
                if (! TREE_CONSTANT (itype))
                  itype = variable_size (itype);
                else if (TREE_OVERFLOW (itype))
index 8d9ade4..e8eac16 100644 (file)
@@ -197,6 +197,11 @@ dump_type (t, v)
       dump_decl (t, v);
       break;
 
+    case COMPLEX_TYPE:
+      OB_PUTS ("complex ");
+      dump_type (TREE_TYPE (t), v);
+      break;
+
     case INTEGER_TYPE:
       if (!TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && TREE_UNSIGNED (t))
        OB_PUTS ("unsigned ");
@@ -435,6 +440,7 @@ dump_type_prefix (t, v)
     case UNKNOWN_TYPE:
     case VOID_TYPE:
     case TYPENAME_TYPE:
+    case COMPLEX_TYPE:
       dump_type (t, v);
       break;
       
@@ -516,6 +522,7 @@ dump_type_suffix (t, v)
     case UNKNOWN_TYPE:
     case VOID_TYPE:
     case TYPENAME_TYPE:
+    case COMPLEX_TYPE:
       break;
 
     default:
index 6cb2a97..d9cad4a 100644 (file)
@@ -9,13 +9,19 @@ __asm, GCC_ASM_KEYWORD, NORID
 __asm__, GCC_ASM_KEYWORD, NORID
 __attribute, ATTRIBUTE, NORID
 __attribute__, ATTRIBUTE, NORID
+__complex, TYPESPEC, RID_COMPLEX
+__complex__, TYPESPEC, RID_COMPLEX
 __const, CV_QUALIFIER, RID_CONST
 __const__, CV_QUALIFIER, RID_CONST
 __extension__, EXTENSION, NORID
+__imag, IMAGPART, NORID
+__imag__, IMAGPART, NORID
 __inline, SCSPEC, RID_INLINE
 __inline__, SCSPEC, RID_INLINE
 __label__, LABEL, NORID
 __null, CONSTANT, RID_NULL
+__real, REALPART, NORID
+__real__, REALPART, NORID
 __signature__, AGGR, RID_SIGNATURE     /* Extension */,
 __signed, TYPESPEC, RID_SIGNED
 __signed__, TYPESPEC, RID_SIGNED
index d3f6be7..720890f 100644 (file)
@@ -1,14 +1,13 @@
 /* C code produced by gperf version 2.5 (GNU C++ version) */
-/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,7,$ ../../../devo/gcc/cp/gxx.gperf  */
-/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf  */
+/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gxx.gperf  */
 struct resword { char *name; short token; enum rid rid;};
 
-#define TOTAL_KEYWORDS 97
+#define TOTAL_KEYWORDS 103
 #define MIN_WORD_LENGTH 2
 #define MAX_WORD_LENGTH 16
 #define MIN_HASH_VALUE 4
-#define MAX_HASH_VALUE 202
-/* maximum key range = 199, duplicates = 0 */
+#define MAX_HASH_VALUE 195
+/* maximum key range = 192, duplicates = 0 */
 
 #ifdef __GNUC__
 inline
@@ -20,19 +19,19 @@ hash (str, len)
 {
   static unsigned char asso_values[] =
     {
-     203, 203, 203, 203, 203, 203, 203, 203, 203, 203,
-     203, 203, 203, 203, 203, 203, 203, 203, 203, 203,
-     203, 203, 203, 203, 203, 203, 203, 203, 203, 203,
-     203, 203, 203, 203, 203, 203, 203, 203, 203, 203,
-     203, 203, 203, 203, 203, 203, 203, 203, 203, 203,
-     203, 203, 203, 203, 203, 203, 203, 203, 203, 203,
-     203, 203, 203, 203, 203, 203, 203, 203, 203, 203,
-     203, 203, 203, 203, 203, 203, 203, 203, 203, 203,
-     203, 203, 203, 203, 203, 203, 203, 203, 203, 203,
-     203, 203, 203, 203, 203,   0, 203,  29,  22,  32,
-      35,   0,  73,   8,  19,  48, 203,   0,   7,  15,
-      11,  66,   9,  11,  19,  58,   1,   7,  83,  21,
-      89,   5, 203, 203, 203, 203, 203, 203,
+     196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+     196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+     196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+     196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+     196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+     196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+     196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+     196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+     196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+     196, 196, 196, 196, 196,   0, 196,  80,  26,  28,
+      44,   0,  49,  38,   6,  81, 196,   2,   0,  41,
+      16,  47,   4,  31,  32,   5,   6,  62,  20,  96,
+      17,  25, 196, 196, 196, 196, 196, 196,
     };
   register int hval = len;
 
@@ -66,133 +65,148 @@ is_reserved_word (str, len)
     {
       {"",}, {"",}, {"",}, {"",}, 
       {"else",  ELSE, NORID,},
+      {"",}, 
+      {"__real",  REALPART, NORID},
+      {"",}, 
+      {"__real__",  REALPART, NORID},
+      {"",}, 
       {"true",  CXX_TRUE, NORID,},
-      {"",}, {"",}, {"",}, 
-      {"try",  TRY, NORID,},
-      {"",}, {"",}, {"",}, {"",}, {"",}, 
-      {"not",  '!', NORID,},
       {"",}, 
-      {"extern",  SCSPEC, RID_EXTERN,},
+      {"__asm__",  GCC_ASM_KEYWORD, NORID},
+      {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
+      {"this",  THIS, NORID,},
       {"",}, 
+      {"extern",  SCSPEC, RID_EXTERN,},
+      {"switch",  SWITCH, NORID,},
       {"template",  TEMPLATE, RID_TEMPLATE,},
-      {"__null",  CONSTANT, RID_NULL},
-      {"",}, {"",}, {"",}, 
-      {"typename",  TYPENAME_KEYWORD, NORID,},
-      {"",}, {"",}, 
-      {"long",  TYPESPEC, RID_LONG,},
-      {"not_eq",  EQCOMPARE, NORID,},
+      {"not",  '!', NORID,},
+      {"",}, 
       {"__alignof__",  ALIGNOF, NORID},
+      {"static_cast",  STATIC_CAST, NORID,},
+      {"",}, 
+      {"bool",  TYPESPEC, RID_BOOL,},
+      {"private",  VISSPEC, RID_PRIVATE,},
+      {"case",  CASE, NORID,},
+      {"virtual",  SCSPEC, RID_VIRTUAL,},
+      {"try",  TRY, NORID,},
+      {"",}, {"",}, 
+      {"compl",  '~', NORID,},
+      {"public",  VISSPEC, RID_PUBLIC,},
+      {"",}, 
       {"__inline",  SCSPEC, RID_INLINE},
-      {"using",  USING, NORID,},
+      {"",}, 
       {"__inline__",  SCSPEC, RID_INLINE},
-      {"while",  WHILE, NORID,},
-      {"enum",  ENUM, NORID,},
-      {"new",  NEW, NORID,},
-      {"case",  CASE, NORID,},
-      {"",}, {"",}, {"",}, 
-      {"bool",  TYPESPEC, RID_BOOL,},
+      {"class",  AGGR, RID_CLASS,},
+      {"const",  CV_QUALIFIER, RID_CONST,},
+      {"static",  SCSPEC, RID_STATIC,},
+      {"__extension__",  EXTENSION, NORID},
+      {"",}, 
+      {"short",  TYPESPEC, RID_SHORT,},
+      {"__imag__",  IMAGPART, NORID},
       {"delete",  DELETE, NORID,},
+      {"__asm",  GCC_ASM_KEYWORD, NORID},
+      {"xor",  '^', NORID,},
+      {"not_eq",  EQCOMPARE, NORID,},
+      {"xor_eq",  ASSIGN, NORID,},
+      {"typename",  TYPENAME_KEYWORD, NORID,},
       {"typeid",  TYPEID, NORID,},
-      {"return",  RETURN, NORID,},
       {"",}, 
-      {"__label__",  LABEL, NORID},
-      {"and_eq",  ASSIGN, NORID,},
-      {"asm",  ASM_KEYWORD, NORID,},
-      {"continue",  CONTINUE, NORID,},
-      {"namespace",  NAMESPACE, NORID,},
+      {"__complex__",  TYPESPEC, RID_COMPLEX},
+      {"false",  CXX_FALSE, NORID,},
+      {"sizeof",  SIZEOF, NORID,},
+      {"typeof",  TYPEOF, NORID,},
+      {"__const__",  CV_QUALIFIER, RID_CONST},
+      {"__volatile",  CV_QUALIFIER, RID_VOLATILE},
       {"",}, 
-      {"mutable",  SCSPEC, RID_MUTABLE,},
-      {"int",  TYPESPEC, RID_INT,},
-      {"compl",  '~', NORID,},
-      {"public",  VISSPEC, RID_PUBLIC,},
+      {"__volatile__",  CV_QUALIFIER, RID_VOLATILE},
+      {"__const",  CV_QUALIFIER, RID_CONST},
+      {"catch",  CATCH, NORID,},
+      {"__null",  CONSTANT, RID_NULL},
       {"protected",  VISSPEC, RID_PROTECTED,},
-      {"break",  BREAK, NORID,},
       {"",}, 
-      {"__signed__",  TYPESPEC, RID_SIGNED},
+      {"signed",  TYPESPEC, RID_SIGNED,},
       {"",}, 
-      {"__attribute",  ATTRIBUTE, NORID},
+      {"__complex",  TYPESPEC, RID_COMPLEX},
+      {"__alignof",  ALIGNOF, NORID},
       {"__wchar_t",  TYPESPEC, RID_WCHAR  /* Unique to ANSI C++ */,},
-      {"__attribute__",  ATTRIBUTE, NORID},
       {"double",  TYPESPEC, RID_DOUBLE,},
-      {"explicit",  SCSPEC, RID_EXPLICIT,},
-      {"__asm__",  GCC_ASM_KEYWORD, NORID},
-      {"reinterpret_cast",  REINTERPRET_CAST, NORID,},
-      {"and",  ANDAND, NORID,},
-      {"",}, {"",}, {"",}, 
-      {"static_cast",  STATIC_CAST, NORID,},
+      {"const_cast",  CONST_CAST, NORID,},
+      {"",}, 
       {"struct",  AGGR, RID_RECORD,},
-      {"default",  DEFAULT, NORID,},
-      {"char",  TYPESPEC, RID_CHAR,},
-      {"__const",  CV_QUALIFIER, RID_CONST},
-      {"__const__",  CV_QUALIFIER, RID_CONST},
-      {"__volatile",  CV_QUALIFIER, RID_VOLATILE},
-      {"__asm",  GCC_ASM_KEYWORD, NORID},
-      {"__volatile__",  CV_QUALIFIER, RID_VOLATILE},
-      {"typeof",  TYPEOF, NORID,},
+      {"long",  TYPESPEC, RID_LONG,},
+      {"or",  OROR, NORID,},
       {"__typeof__",  TYPEOF, NORID},
       {"or_eq",  ASSIGN, NORID,},
-      {"short",  TYPESPEC, RID_SHORT,},
-      {"switch",  SWITCH, NORID,},
+      {"for",  FOR, NORID,},
+      {"__imag",  IMAGPART, NORID},
+      {"enum",  ENUM, NORID,},
+      {"",}, {"",}, 
+      {"__label__",  LABEL, NORID},
+      {"int",  TYPESPEC, RID_INT,},
+      {"__signed__",  TYPESPEC, RID_SIGNED},
       {"signature",  AGGR, RID_SIGNATURE       /* Extension */,},
+      {"do",  DO, NORID,},
       {"",}, 
-      {"or",  OROR, NORID,},
-      {"catch",  CATCH, NORID,},
-      {"union",  AGGR, RID_UNION,},
-      {"__signature__",  AGGR, RID_SIGNATURE   /* Extension */,},
-      {"__signed",  TYPESPEC, RID_SIGNED},
-      {"bitand",  '&', NORID,},
-      {"throw",  THROW, NORID,},
-      {"register",  SCSPEC, RID_REGISTER,},
-      {"for",  FOR, NORID,},
-      {"const",  CV_QUALIFIER, RID_CONST,},
-      {"static",  SCSPEC, RID_STATIC,},
-      {"unsigned",  TYPESPEC, RID_UNSIGNED,},
-      {"private",  VISSPEC, RID_PRIVATE,},
-      {"__alignof",  ALIGNOF, NORID},
+      {"explicit",  SCSPEC, RID_EXPLICIT,},
+      {"char",  TYPESPEC, RID_CHAR,},
       {"",}, 
-      {"inline",  SCSPEC, RID_INLINE,},
-      {"do",  DO, NORID,},
+      {"__attribute",  ATTRIBUTE, NORID},
+      {"friend",  SCSPEC, RID_FRIEND,},
+      {"__attribute__",  ATTRIBUTE, NORID},
+      {"while",  WHILE, NORID,},
+      {"reinterpret_cast",  REINTERPRET_CAST, NORID,},
       {"",}, 
-      {"virtual",  SCSPEC, RID_VIRTUAL,},
-      {"xor_eq",  ASSIGN, NORID,},
+      {"continue",  CONTINUE, NORID,},
+      {"namespace",  NAMESPACE, NORID,},
+      {"sigof",  SIGOF, NORID          /* Extension */,},
+      {"",}, 
+      {"volatile",  CV_QUALIFIER, RID_VOLATILE,},
       {"",}, 
-      {"float",  TYPESPEC, RID_FLOAT,},
-      {"dynamic_cast",  DYNAMIC_CAST, NORID,},
-      {"signed",  TYPESPEC, RID_SIGNED,},
-      {"xor",  '^', NORID,},
       {"bitor",  '|', NORID,},
-      {"__extension__",  EXTENSION, NORID},
-      {"friend",  SCSPEC, RID_FRIEND,},
-      {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
-      {"this",  THIS, NORID,},
+      {"typedef",  SCSPEC, RID_TYPEDEF,},
+      {"void",  TYPESPEC, RID_VOID,},
+      {"break",  BREAK, NORID,},
       {"",}, 
-      {"if",  IF, NORID,},
+      {"new",  NEW, NORID,},
+      {"return",  RETURN, NORID,},
+      {"and_eq",  ASSIGN, NORID,},
       {"",}, {"",}, {"",}, 
-      {"volatile",  CV_QUALIFIER, RID_VOLATILE,},
+      {"using",  USING, NORID,},
       {"",}, {"",}, 
-      {"__sigof__",  SIGOF, NORID              /* Extension */,},
+      {"asm",  ASM_KEYWORD, NORID,},
       {"",}, {"",}, 
-      {"const_cast",  CONST_CAST, NORID,},
+      {"and",  ANDAND, NORID,},
+      {"mutable",  SCSPEC, RID_MUTABLE,},
+      {"__typeof",  TYPEOF, NORID},
+      {"union",  AGGR, RID_UNION,},
+      {"",}, 
+      {"if",  IF, NORID,},
+      {"__signed",  TYPESPEC, RID_SIGNED},
       {"",}, {"",}, 
-      {"false",  CXX_FALSE, NORID,},
-      {"sizeof",  SIZEOF, NORID,},
-      {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
       {"goto",  GOTO, NORID,},
-      {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
-      {"__typeof",  TYPEOF, NORID},
-      {"class",  AGGR, RID_CLASS,},
-      {"typedef",  SCSPEC, RID_TYPEDEF,},
       {"",}, {"",}, 
-      {"void",  TYPESPEC, RID_VOID,},
-      {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
-      {"auto",  SCSPEC, RID_AUTO,},
+      {"__sigof__",  SIGOF, NORID              /* Extension */,},
+      {"float",  TYPESPEC, RID_FLOAT,},
+      {"",}, {"",}, 
+      {"default",  DEFAULT, NORID,},
       {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
-      {"",}, {"",}, {"",}, 
-      {"operator",  OPERATOR, NORID,},
+      {"register",  SCSPEC, RID_REGISTER,},
+      {"throw",  THROW, NORID,},
+      {"",}, 
+      {"bitand",  '&', NORID,},
       {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
+      {"operator",  OPERATOR, NORID,},
+      {"",}, 
+      {"inline",  SCSPEC, RID_INLINE,},
+      {"",}, 
+      {"dynamic_cast",  DYNAMIC_CAST, NORID,},
+      {"",}, {"",}, {"",}, 
+      {"__signature__",  AGGR, RID_SIGNATURE   /* Extension */,},
+      {"",}, {"",}, {"",}, 
+      {"auto",  SCSPEC, RID_AUTO,},
       {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
-      {"",}, {"",}, {"",}, {"",}, {"",}, 
-      {"sigof",  SIGOF, NORID          /* Extension */,},
+      {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
+      {"unsigned",  TYPESPEC, RID_UNSIGNED,},
     };
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
index 5c88256..378629c 100644 (file)
@@ -1252,7 +1252,7 @@ expand_default_init (binfo, true_exp, exp, init, alias_this, flags)
         via the copy constructor, even if the call is elided.  */
       if (! (TREE_CODE (exp) == VAR_DECL && DECL_ARTIFICIAL (exp)
             && TREE_CODE (init) == TARGET_EXPR && TREE_TYPE (init) == type))
-       init = cp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
+       init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
 
       expand_assignment (exp, init, 0, 0);
       return;
@@ -1512,7 +1512,7 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags)
          if (init_list && TREE_CHAIN (init_list))
            {
              warning ("initializer list being treated as compound expression");
-             init = convert (type, build_compound_expr (init_list));
+             init = cp_convert (type, build_compound_expr (init_list));
              if (init == error_mark_node)
                return;
            }
@@ -2101,14 +2101,14 @@ resolve_offset_ref (exp)
 
       basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (member));
       addr = convert_pointer_to (basetype, addr);
-      member = convert (ptrdiff_type_node,
-                       build_unary_op (ADDR_EXPR, member, 0));
+      member = cp_convert (ptrdiff_type_node,
+                          build_unary_op (ADDR_EXPR, member, 0));
       
       /* Pointer to data mebers are offset by one, so that a null
         pointer with a real value of 0 is distinguishable from an
         offset of the first member of a structure.  */
       member = build_binary_op (MINUS_EXPR, member,
-                               convert (ptrdiff_type_node, integer_one_node),
+                               cp_convert (ptrdiff_type_node, integer_one_node),
                                0);
 
       return build1 (INDIRECT_REF, type,
@@ -2269,7 +2269,7 @@ build_new (placement, decl, init, use_global_new)
                }
              else
                {
-                 this_nelts = save_expr (convert (sizetype, this_nelts));
+                 this_nelts = save_expr (cp_convert (sizetype, this_nelts));
                  absdcl = TREE_OPERAND (absdcl, 0);
                  if (this_nelts == integer_zero_node)
                    {
@@ -2464,7 +2464,7 @@ build_new (placement, decl, init, use_global_new)
     {
       rval = build_opfncall (code, LOOKUP_GLOBAL|LOOKUP_COMPLAIN,
                             ptr_type_node, size, placement);
-      rval = convert (build_pointer_type (true_type), rval);
+      rval = cp_convert (build_pointer_type (true_type), rval);
     }
   else if (! has_array && flag_this_is_variable > 0
           && TYPE_NEEDS_CONSTRUCTING (true_type) && init != void_type_node)
@@ -2498,8 +2498,8 @@ build_new (placement, decl, init, use_global_new)
     {
       tree extra = BI_header_size;
       tree cookie, exp1;
-      rval = convert (ptr_type_node, rval);    /* convert to void * first */
-      rval = convert (string_type_node, rval); /* lets not add void* and ints */
+      rval = cp_convert (ptr_type_node, rval);    /* convert to void * first */
+      rval = cp_convert (string_type_node, rval); /* lets not add void* and ints */
       rval = save_expr (build_binary_op (PLUS_EXPR, rval, extra, 1));
       /* Store header info.  */
       cookie = build_indirect_ref (build (MINUS_EXPR, build_pointer_type (BI_header_type),
@@ -2508,7 +2508,7 @@ build_new (placement, decl, init, use_global_new)
                    build_component_ref (cookie, nc_nelts_field_id, NULL_TREE, 0),
                    nelts);
       TREE_SIDE_EFFECTS (exp1) = 1;
-      rval = convert (build_pointer_type (true_type), rval);
+      rval = cp_convert (build_pointer_type (true_type), rval);
       TREE_CALLS_NEW (rval) = 1;
       TREE_SIDE_EFFECTS (rval) = 1;
       rval = build_compound_expr (tree_cons (NULL_TREE, exp1,
@@ -2751,11 +2751,11 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete,
   if (auto_delete != integer_zero_node
       && auto_delete != integer_two_node)
     {
-      tree base_tbd = convert (ptype,
-                              build_binary_op (MINUS_EXPR,
-                                               convert (ptr_type_node, base),
-                                               BI_header_size,
-                                               1));
+      tree base_tbd = cp_convert (ptype,
+                                 build_binary_op (MINUS_EXPR,
+                                                  cp_convert (ptr_type_node, base),
+                                                  BI_header_size,
+                                                  1));
       /* This is the real size */
       virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size);
       body = build_tree_list (NULL_TREE,
@@ -2808,11 +2808,11 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete,
        base_tbd = base;
       else
        {
-         base_tbd = convert (ptype,
-                             build_binary_op (MINUS_EXPR,
-                                              convert (string_type_node, base),
-                                              BI_header_size,
-                                              1));
+         base_tbd = cp_convert (ptype,
+                                build_binary_op (MINUS_EXPR,
+                                                 cp_convert (string_type_node, base),
+                                                 BI_header_size,
+                                                 1));
          /* True size with header.  */
          virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size);
        }
@@ -2847,7 +2847,7 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete,
       return controller;
     }
   else
-    return convert (void_type_node, body);
+    return cp_convert (void_type_node, body);
 }
 
 /* Build a tree to cleanup partially built arrays.
@@ -2891,7 +2891,7 @@ expand_vec_init (decl, base, maxindex, init, from_array)
   tree type = TREE_TYPE (TREE_TYPE (base));
   tree size;
 
-  maxindex = convert (ptrdiff_type_node, maxindex);
+  maxindex = cp_convert (ptrdiff_type_node, maxindex);
   if (maxindex == error_mark_node)
     return error_mark_node;
 
@@ -2909,9 +2909,9 @@ expand_vec_init (decl, base, maxindex, init, from_array)
   /* Set to zero in case size is <= 0.  Optimizer will delete this if
      it is not needed.  */
   rval = get_temp_regvar (build_pointer_type (type),
-                         convert (build_pointer_type (type), null_pointer_node));
+                         cp_convert (build_pointer_type (type), null_pointer_node));
   base = default_conversion (base);
-  base = convert (build_pointer_type (type), base);
+  base = cp_convert (build_pointer_type (type), base);
   expand_assignment (rval, base, 0, 0);
   base = get_temp_regvar (build_pointer_type (type), base);
 
index b3b6c0b..11f0db2 100644 (file)
@@ -33,14 +33,14 @@ Boston, MA 02111-1307, USA.  */
        %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
        -undef -D__GNUC__=%v1 -D__GNUG__=%v1 -D__cplusplus -D__GNUC_MINOR__=%v2\
        %{ansi:-trigraphs -$ -D__STRICT_ANSI__} %{!undef:%{!ansi:%p} %P}\
-        %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\
-        %{traditional-cpp:-traditional} %{trigraphs}\
+       %{!fno-exceptions:-D__EXCEPTIONS}\
+        %c %{O*:%{!O0:-D__OPTIMIZE__}} %{trigraphs}\
        %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
         %i %{!M:%{!MM:%{!E:%{!pipe:%g.ii}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
    "%{!M:%{!MM:%{!E:cc1plus %{!pipe:%g.ii} %1 %2\
                            %{!Q:-quiet} -dumpbase %b.cc %{d*} %{m*} %{a}\
                            %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi}\
-                           %{traditional} %{v:-version} %{pg:-p} %{p}\
+                           %{v:-version} %{pg:-p} %{p}\
                            %{f*} %{+e*} %{aux-info*}\
                            %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
                            %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}}|\n\
@@ -51,7 +51,7 @@ Boston, MA 02111-1307, USA.  */
   {"@c++-cpp-output",
    "%{!M:%{!MM:%{!E:cc1plus %i %1 %2 %{!Q:-quiet} %{d*} %{m*} %{a}\
                            %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi}\
-                           %{traditional} %{v:-version} %{pg:-p} %{p}\
+                           %{v:-version} %{pg:-p} %{p}\
                            %{f*} %{+e*} %{aux-info*}\
                            %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
                            %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
index befb5a1..39f41cb 100644 (file)
@@ -639,6 +639,9 @@ init_lex ()
   ridpointers[(int) RID_REGISTER] = get_identifier ("register");
   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_REGISTER],
                          build_tree_list (NULL_TREE, ridpointers[(int) RID_REGISTER]));
+  ridpointers[(int) RID_COMPLEX] = get_identifier ("complex");
+  SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_COMPLEX],
+                         build_tree_list (NULL_TREE, ridpointers[(int) RID_COMPLEX]));
 
   /* C++ extensions. These are probably not correctly named.  */
   ridpointers[(int) RID_WCHAR] = get_identifier ("__wchar_t");
@@ -806,6 +809,8 @@ init_lex ()
       UNSET_RESERVED_WORD ("signature");
       UNSET_RESERVED_WORD ("sigof");
     }
+  if (flag_no_gnu_keywords)
+    UNSET_RESERVED_WORD ("complex");
   if (flag_no_asm || flag_no_gnu_keywords)
     UNSET_RESERVED_WORD ("typeof");
   if (! flag_operator_names)
@@ -2861,7 +2866,7 @@ real_yylex ()
                  p = extend_token_buffer (p);
 
                *p++ = c;
-               c = getc (finput);
+               c = getch (finput);
              }
 
            if (linemode && c == '\n')
@@ -3148,12 +3153,12 @@ real_yylex ()
        enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
          = NOT_FLOAT;
 
-       p = token_buffer;
-       *p++ = c;
-
        for (count = 0; count < TOTAL_PARTS; count++)
          parts[count] = 0;
 
+       p = token_buffer;
+       *p++ = c;
+
        if (c == '0')
          {
            *p++ = (c = getch ());
@@ -3177,16 +3182,23 @@ real_yylex ()
        while (c == '.'
               || (isalnum (c) && (c != 'l') && (c != 'L')
                   && (c != 'u') && (c != 'U')
+                  && c != 'i' && c != 'I' && c != 'j' && c != 'J'
                   && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
          {
            if (c == '.')
              {
                if (base == 16)
                  error ("floating constant may not be in radix 16");
-               if (floatflag == AFTER_POINT)
+               if (floatflag == TOO_MANY_POINTS)
+                 /* We have already emitted an error.  Don't need another.  */
+                 ;
+               else if (floatflag == AFTER_POINT)
                  {
                    error ("malformed floating constant");
                    floatflag = TOO_MANY_POINTS;
+                   /* Avoid another error from atof by forcing all characters
+                      from here on to be ignored.  */
+                   p[-1] = '\0';
                  }
                else
                  floatflag = AFTER_POINT;
@@ -3286,9 +3298,8 @@ real_yylex ()
        if (floatflag != NOT_FLOAT)
          {
            tree type = double_type_node;
-           char f_seen = 0;
-           char l_seen = 0;
-           int garbage_chars = 0;
+           int exceeds_double = 0;
+           int imag = 0;
            REAL_VALUE_TYPE value;
            jmp_buf handler;
 
@@ -3327,76 +3338,117 @@ real_yylex ()
              }
            else
              {
+               int fflag = 0, lflag = 0;
+               /* Copy token_buffer now, while it has just the number
+                  and not the suffixes; once we add `f' or `i',
+                  REAL_VALUE_ATOF may not work any more.  */
+               char *copy = (char *) alloca (p - token_buffer + 1);
+               bcopy (token_buffer, copy, p - token_buffer + 1);
+
                set_float_handler (handler);
-               /*  The second argument, machine_mode, of REAL_VALUE_ATOF
-                   tells the desired precision of the binary result of
-                   decimal-to-binary conversion.  */
 
-               /* Read the suffixes to choose a data type.  */
-               switch (c)
+               while (1)
                  {
-                 case 'f': case 'F':
-                   type = float_type_node;
-                   value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
-                   garbage_chars = -1;
-                   break;
+                   int lose = 0;
 
-                 case 'l': case 'L':
-                   type = long_double_type_node;
-                   value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
-                   garbage_chars = -1;
-                   break;
+                   /* Read the suffixes to choose a data type.  */
+                   switch (c)
+                     {
+                     case 'f': case 'F':
+                       if (fflag)
+                         error ("more than one `f' in numeric constant");
+                       fflag = 1;
+                       break;
+
+                     case 'l': case 'L':
+                       if (lflag)
+                         error ("more than one `l' in numeric constant");
+                       lflag = 1;
+                       break;
+
+                     case 'i': case 'I':
+                       if (imag)
+                         error ("more than one `i' or `j' in numeric constant");
+                       else if (pedantic)
+                         pedwarn ("ANSI C++ forbids imaginary numeric constants");
+                       imag = 1;
+                       break;
+
+                     default:
+                       lose = 1;
+                     }
 
-                 default:
-                   value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
+                   if (lose)
+                     break;
+
+                   if (p >= token_buffer + maxtoken - 3)
+                     p = extend_token_buffer (p);
+                   *p++ = c;
+                   *p = 0;
+                   c = getch (finput);
+                 }
+
+               /* The second argument, machine_mode, of REAL_VALUE_ATOF
+                  tells the desired precision of the binary result
+                  of decimal-to-binary conversion.  */
+
+               if (fflag)
+                 {
+                   if (lflag)
+                     error ("both `f' and `l' in floating constant");
+
+                   type = float_type_node;
+                   value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
+                   /* A diagnostic is required here by some ANSI C testsuites.
+                      This is not pedwarn, become some people don't want
+                      an error for this.  */
+                   if (REAL_VALUE_ISINF (value) && pedantic)
+                     warning ("floating point number exceeds range of `float'");
+                 }
+               else if (lflag)
+                 {
+                   type = long_double_type_node;
+                   value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
+                   if (REAL_VALUE_ISINF (value) && pedantic)
+                     warning ("floating point number exceeds range of `long double'");
+                 }
+               else
+                 {
+                   value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
+                   if (REAL_VALUE_ISINF (value) && pedantic)
+                     warning ("floating point number exceeds range of `double'");
                  }
+
                set_float_handler (NULL_PTR);
              }
-           if (pedantic
-               && (REAL_VALUE_ISINF (value)
 #ifdef ERANGE
-                   || (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
-                       && errno == ERANGE
-                       /* ERANGE is also reported for underflow, so test the
-                          value to distinguish overflow from that.  */
-                       && (REAL_VALUES_LESS (dconst1, value)
-                           || REAL_VALUES_LESS (value, dconstm1)))
-#endif
-                   ))
+           if (errno == ERANGE && pedantic)
              {
-               pedwarn ("floating point number exceeds range of `%s'",
-                        IDENTIFIER_POINTER (TYPE_IDENTIFIER (type)));
-             }
-           /* Note: garbage_chars is -1 if first char is *not* garbage.  */
-           while (isalnum (c))
-             {
-               if (c == 'f' || c == 'F')
-                 {
-                   if (f_seen)
-                     error ("two `f's in floating constant");
-                   f_seen = 1;
-                 }
-               if (c == 'l' || c == 'L')
+               /* ERANGE is also reported for underflow,
+                  so test the value to distinguish overflow from that.  */
+               if (REAL_VALUES_LESS (dconst1, value)
+                   || REAL_VALUES_LESS (value, dconstm1))
                  {
-                   if (l_seen)
-                     error ("two `l's in floating constant");
-                   l_seen = 1;
+                   pedwarn ("floating point number exceeds range of `%s'",
+                            IDENTIFIER_POINTER (TYPE_IDENTIFIER (type)));
+                   exceeds_double = 1;
                  }
-               if (p >= token_buffer + maxtoken - 3)
-                 p = extend_token_buffer (p);
-               *p++ = c;
-               c = getch ();
-               garbage_chars++;
              }
+#endif
 
-           if (garbage_chars > 0)
-             error ("garbage at end of number");
+           /* If the result is not a number, assume it must have been
+              due to some error message above, so silently convert
+              it to a zero.  */
+           if (REAL_VALUE_ISNAN (value))
+             value = dconst0;
 
            /* Create a node with determined type and value.  */
-           yylval.ttype = build_real (type, value);
-
-           put_back (c);
-           *p = 0;
+           if (imag)
+             yylval.ttype = build_complex (NULL_TREE,
+                                           cp_convert (type, integer_zero_node),
+                                           build_real (type, value));
+           else
+             yylval.ttype = build_real (type, value);
          }
        else
          {
@@ -3405,6 +3457,7 @@ real_yylex ()
            int spec_unsigned = 0;
            int spec_long = 0;
            int spec_long_long = 0;
+           int spec_imag = 0;
            int bytes, warn;
 
            while (1)
@@ -3427,29 +3480,22 @@ real_yylex ()
                      }
                    spec_long = 1;
                  }
-               else
+               else if (c == 'i' || c == 'j' || c == 'I' || c == 'J')
                  {
-                   if (isalnum (c))
-                     {
-                       error ("garbage at end of number");
-                       while (isalnum (c))
-                         {
-                           if (p >= token_buffer + maxtoken - 3)
-                             p = extend_token_buffer (p);
-                           *p++ = c;
-                           c = getch ();
-                         }
-                     }
-                   break;
+                   if (spec_imag)
+                     error ("more than one `i' or `j' in numeric constant");
+                   else if (pedantic)
+                     pedwarn ("ANSI C++ forbids imaginary numeric constants");
+                   spec_imag = 1;
                  }
+               else
+                 break;
                if (p >= token_buffer + maxtoken - 3)
                  p = extend_token_buffer (p);
                *p++ = c;
-               c = getch ();
+               c = getch (finput);
              }
 
-           put_back (c);
-
            /* If the constant is not long long and it won't fit in an
               unsigned long, or if the constant is long long and won't fit
               in an unsigned long long, then warn that the constant is out
@@ -3499,23 +3545,17 @@ real_yylex ()
                /* Nondecimal constants try unsigned even in traditional C.  */
                type = unsigned_type_node;
              }
-
            else if (!spec_unsigned && !spec_long_long
                     && int_fits_type_p (yylval.ttype, long_integer_type_node))
              type = long_integer_type_node;
-
-           else if (! spec_long_long
-                    && int_fits_type_p (yylval.ttype,
-                                        long_unsigned_type_node))
+           else if (! spec_long_long)
              type = long_unsigned_type_node;
-
            else if (! spec_unsigned
                     /* Verify value does not overflow into sign bit.  */
                     && TREE_INT_CST_HIGH (yylval.ttype) >= 0
                     && int_fits_type_p (yylval.ttype,
                                         long_long_integer_type_node))
              type = long_long_integer_type_node;
-
            else if (int_fits_type_p (yylval.ttype,
                                      long_long_unsigned_type_node))
              type = long_long_unsigned_type_node;
@@ -3527,12 +3567,25 @@ real_yylex ()
 
                if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
                  warning ("decimal integer constant is so large that it is unsigned");
+               if (spec_imag)
+                 {
+                   if (TYPE_PRECISION (type)
+                       <= TYPE_PRECISION (integer_type_node))
+                     yylval.ttype
+                       = build_complex (NULL_TREE, integer_zero_node,
+                                        cp_convert (integer_type_node,
+                                                    yylval.ttype));
+                   else
+                     error ("complex integer constant is too wide for `complex int'");
+                 }
              }
 
            TREE_TYPE (yylval.ttype) = type;
-           *p = 0;
          }
 
+       put_back (c);
+       *p = 0;
+
        value = CONSTANT; break;
       }
 
index 4a2c7d1..fcea57a 100644 (file)
@@ -62,6 +62,7 @@ enum rid
   RID_SIGNED,
   RID_AUTO,
   RID_MUTABLE,
+  RID_COMPLEX,
 
   /* This is where grokdeclarator ends its search when setting the
      specbits.  */
@@ -81,7 +82,7 @@ enum rid
 #define NORID RID_UNUSED
 
 #define RID_FIRST_MODIFIER RID_EXTERN
-#define RID_LAST_MODIFIER RID_MUTABLE
+#define RID_LAST_MODIFIER RID_COMPLEX
 
 /* The type that can represent all values of RIDBIT.  */
 /* We assume that we can stick in at least 32 bits into this.  */
index 640b1bf..09acad4 100644 (file)
@@ -895,6 +895,11 @@ build_overload_name (parmtypes, begin, end)
          else my_friendly_abort (74);
          break;
 
+       case COMPLEX_TYPE:
+         OB_PUTC ('J');
+         build_overload_name (TREE_TYPE (parmtype), 0, 0);
+         break;
+
        case VOID_TYPE:
          if (! just_one)
            {
index 720c041..8a1ae5d 100644 (file)
@@ -140,6 +140,7 @@ empty_parms ()
 %token BREAK CONTINUE RETURN GOTO ASM_KEYWORD GCC_ASM_KEYWORD TYPEOF ALIGNOF
 %token SIGOF
 %token ATTRIBUTE EXTENSION LABEL
+%token REALPART IMAGPART
 
 /* the reserved words... C++ extensions */
 %token <ttype> AGGR
@@ -1104,6 +1105,10 @@ unary_expr:
                { $$ = delete_sanity ($5, $3, 2, $1);
                  if (yychar == YYEMPTY)
                    yychar = YYLEX; }
+       | REALPART cast_expr %prec UNARY
+               { $$ = build_x_unary_op (REALPART_EXPR, $2); }
+       | IMAGPART cast_expr %prec UNARY
+               { $$ = build_x_unary_op (IMAGPART_EXPR, $2); }
        ;
 
 new_placement:
@@ -1542,7 +1547,7 @@ primary:
                      && (TREE_CODE (TREE_TYPE ($1)) 
                          != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($3)))))
                    cp_error ("`%E' is not of type `%T'", $1, $3);
-                 $$ = convert (void_type_node, $1);
+                 $$ = cp_convert (void_type_node, $1);
                }
        | object TYPESPEC SCOPE '~' TYPESPEC LEFT_RIGHT
                {
@@ -1551,7 +1556,7 @@ primary:
                  if (TREE_CODE (TREE_TYPE ($1))
                      != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($2))))
                    cp_error ("`%E' is not of type `%T'", $1, $2);
-                 $$ = convert (void_type_node, $1);
+                 $$ = cp_convert (void_type_node, $1);
                }
        | object error
                {
@@ -2558,9 +2563,6 @@ left_curly:
 self_reference:
          /* empty */
                {
-                 if (CLASSTYPE_TEMPLATE_INFO (current_class_type))
-                   $$ = NULL_TREE;
-                 else
                    $$ = build_self_reference ();
                }
        ;
index 823116c..e06fa40 100644 (file)
@@ -133,7 +133,9 @@ process_template_parm (list, next)
            error ("  a template type parameter must begin with `class' or `typename'");
          TREE_TYPE (parm) = void_type_node;
        }
-      else if (pedantic && TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE)
+      else if (pedantic
+              && (TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE
+                  || TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE))
        cp_pedwarn ("`%T' is not a valid type for a template constant parameter",
                    TREE_TYPE (parm));
       tinfo = make_node (TEMPLATE_CONST_PARM);
@@ -916,6 +918,7 @@ uses_template_parms (t)
       return uses_template_parms (TYPE_MAX_VALUE (t));
 
     case REAL_TYPE:
+    case COMPLEX_TYPE:
     case VOID_TYPE:
     case ENUMERAL_TYPE:
     case BOOLEAN_TYPE:
@@ -1205,12 +1208,13 @@ instantiate_class_template (type)
        {
          tree e, newtag = tsubst_enum (tag, &TREE_VEC_ELT (args, 0),
                                        TREE_VEC_LENGTH (args));
-         for (e = TYPE_VALUES (newtag); e; e = TREE_CHAIN (e))
-           DECL_FIELD_CONTEXT (TREE_VALUE (e)) = type;
 
          *field_chain = grok_enum_decls (newtag, NULL_TREE);
          while (*field_chain)
-           field_chain = &TREE_CHAIN (*field_chain);
+           {
+             DECL_FIELD_CONTEXT (*field_chain) = type;
+             field_chain = &TREE_CHAIN (*field_chain);
+           }
        }
       else
        tsubst (tag, &TREE_VEC_ELT (args, 0),
@@ -1387,6 +1391,7 @@ tsubst (t, args, nargs, in_decl)
     case OP_IDENTIFIER:
     case VOID_TYPE:
     case REAL_TYPE:
+    case COMPLEX_TYPE:
     case BOOLEAN_TYPE:
     case INTEGER_CST:
     case REAL_CST:
@@ -1413,14 +1418,18 @@ tsubst (t, args, nargs, in_decl)
        return t;
 
       {
-       tree max = tsubst_expr (TYPE_MAX_VALUE (t), args, nargs, in_decl);
+       tree max = TREE_OPERAND (TYPE_MAX_VALUE (t), 0);
+       max = tsubst_expr (max, args, nargs, in_decl);
        if (processing_template_decl)
          {
            tree itype = make_node (INTEGER_TYPE);
            TYPE_MIN_VALUE (itype) = size_zero_node;
-           TYPE_MAX_VALUE (itype) = max;
+           TYPE_MAX_VALUE (itype) = build_min (MINUS_EXPR, sizetype, max,
+                                               integer_one_node);
            return itype;
          }
+
+       max = fold (build_binary_op (MINUS_EXPR, max, integer_one_node, 1));
        return build_index_2_type (size_zero_node, max);
       }
 
@@ -2796,6 +2805,7 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts, strict)
                    nsubsts, strict);
 
     case REAL_TYPE:
+    case COMPLEX_TYPE:
     case INTEGER_TYPE:
       if (TREE_CODE (arg) != TREE_CODE (parm))
        return 1;
index c1afbd6..92b2c57 100644 (file)
@@ -107,7 +107,7 @@ build_headof (exp)
   type = build_type_variant (ptr_type_node, TREE_READONLY (exp),
                             TREE_THIS_VOLATILE (exp));
   return build (PLUS_EXPR, type, exp,
-               convert (ptrdiff_type_node, offset));
+               cp_convert (ptrdiff_type_node, offset));
 }
 
 /* Build a call to a generic entry point taking and returning void.  */
@@ -240,7 +240,7 @@ build_x_typeid (exp)
       && ! nonnull)
     {
       exp = stabilize_reference (exp);
-      cond = convert (boolean_type_node, TREE_OPERAND (exp, 0));
+      cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0));
     }
 
   exp = get_tinfo_fn_dynamic (exp);
@@ -256,7 +256,7 @@ build_x_typeid (exp)
 
       bad = build_compound_expr
        (tree_cons (NULL_TREE, bad, build_tree_list
-                   (NULL_TREE, convert (type, integer_zero_node))));
+                   (NULL_TREE, cp_convert (type, integer_zero_node))));
       exp = build (COND_EXPR, type, cond, exp, bad);
     }
 
@@ -292,7 +292,7 @@ get_tinfo_var (type)
                   (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
        size = 3 * POINTER_SIZE;
       else
-       size = 3 * POINTER_SIZE + INT_TYPE_SIZE;
+       size = 3 * POINTER_SIZE + TYPE_PRECISION (sizetype);
     }
   else
     size = 2 * POINTER_SIZE;
@@ -398,7 +398,7 @@ ifnonnull (test, result)
 {
   return build (COND_EXPR, TREE_TYPE (result),
                build (EQ_EXPR, boolean_type_node, test, integer_zero_node),
-               convert (TREE_TYPE (result), integer_zero_node),
+               cp_convert (TREE_TYPE (result), integer_zero_node),
                result);
 }
 
@@ -611,15 +611,14 @@ build_dynamic_cast (type, expr)
              expr1 = throw_bad_cast ();
              expr1 = build_compound_expr
                (tree_cons (NULL_TREE, expr1,
-                           build_tree_list (NULL_TREE, convert
-                                            (type, integer_zero_node))));
+                           build_tree_list (NULL_TREE, cp_convert (type, integer_zero_node))));
              TREE_TYPE (expr1) = type;
              result = save_expr (result);
              return build (COND_EXPR, type, result, result, expr1);
            }
 
          /* Now back to the type we want from a void*.  */
-         result = convert (type, result);
+         result = cp_convert (type, result);
           return ifnonnull (expr, result);
        }
     }
@@ -842,7 +841,8 @@ expand_class_desc (tdecl, type)
     (NULL_TREE, decay_conversion (tdecl), tree_cons
      (NULL_TREE, decay_conversion (name_string), tree_cons
       (NULL_TREE, decay_conversion (elts), tree_cons
-       (NULL_TREE, build_int_2 (base_cnt, 0), NULL_TREE))));
+       (NULL_TREE, cp_convert (sizetype, build_int_2 (base_cnt, 0)),
+       NULL_TREE))));
 
   fn = get_identifier ("__rtti_class");
   if (IDENTIFIER_GLOBAL_VALUE (fn))
@@ -1043,7 +1043,7 @@ synthesize_tinfo_fn (fndecl)
   /* If the first word of the array (the vtable) is non-zero, we've already
      initialized the object, so don't do it again.  */
   addr = decay_conversion (tdecl);
-  tmp = convert (build_pointer_type (ptr_type_node), addr);
+  tmp = cp_convert (build_pointer_type (ptr_type_node), addr);
   tmp = build_indirect_ref (tmp, 0);
   tmp = build_binary_op (EQ_EXPR, tmp, integer_zero_node, 1);
   expand_start_cond (tmp, 0);
@@ -1084,7 +1084,7 @@ synthesize_tinfo_fn (fndecl)
   expand_end_cond ();
 
   /* OK, now return the type_info object.  */
-  tmp = convert (build_pointer_type (type_info_type_node), addr);
+  tmp = cp_convert (build_pointer_type (type_info_type_node), addr);
   tmp = build_indirect_ref (tmp, 0);
   c_expand_return (tmp);
   finish_function (lineno, 0, 0);
index 9d2322d..c52b1d6 100644 (file)
@@ -620,20 +620,20 @@ build_signature_table_constructor (sig_ty, rhs)
          pfn_decl = TREE_CHAIN (index_decl);
          vt_off_decl = TREE_CHAIN (pfn_decl);
          
-         tag = convert (TREE_TYPE (tag_decl), tag);
-         vb_off = convert (TREE_TYPE (vb_off_decl), vb_off);
-         delta = convert (TREE_TYPE (delta_decl), delta);
-         idx = convert (TREE_TYPE (index_decl), idx);
+         tag = cp_convert (TREE_TYPE (tag_decl), tag);
+         vb_off = cp_convert (TREE_TYPE (vb_off_decl), vb_off);
+         delta = cp_convert (TREE_TYPE (delta_decl), delta);
+         idx = cp_convert (TREE_TYPE (index_decl), idx);
 
          if (DECL_VINDEX (rhs_method))
            {
-             vt_off = convert (TREE_TYPE (vt_off_decl), vt_off);
+             vt_off = cp_convert (TREE_TYPE (vt_off_decl), vt_off);
 
              tbl_entry = build_tree_list (vt_off_decl, vt_off);
            }
          else
            {
-             pfn = convert (TREE_TYPE (pfn_decl), pfn);
+             pfn = cp_convert (TREE_TYPE (pfn_decl), pfn);
 
              tbl_entry = build_tree_list (pfn_decl, pfn);
            }
@@ -956,11 +956,11 @@ build_signature_method_call (function, parms)
     }
 
   new_object_ptr = build (PLUS_EXPR, build_pointer_type (basetype),
-                         convert (ptrdiff_type_node, object_ptr),
-                         convert (ptrdiff_type_node, delta));
+                         cp_convert (ptrdiff_type_node, object_ptr),
+                         cp_convert (ptrdiff_type_node, delta));
 
   parms = tree_cons (NULL_TREE,
-                    convert (build_pointer_type (basetype), object_ptr),
+                    cp_convert (build_pointer_type (basetype), object_ptr),
                     TREE_CHAIN (parms));
   new_parms = tree_cons (NULL_TREE, new_object_ptr, TREE_CHAIN (parms));
 
@@ -980,8 +980,8 @@ build_signature_method_call (function, parms)
 
       vfld = build (PLUS_EXPR,
                    build_pointer_type (build_pointer_type (vtbl_type_node)),
-                   convert (ptrdiff_type_node, object_ptr),
-                   convert (ptrdiff_type_node, vt_off));
+                   cp_convert (ptrdiff_type_node, object_ptr),
+                   cp_convert (ptrdiff_type_node, vt_off));
       vtbl = build_indirect_ref (build_indirect_ref (vfld, NULL_PTR),
                                 NULL_PTR);
       aref = build_array_ref (vtbl, idx);
index de9128f..a060530 100644 (file)
@@ -129,6 +129,8 @@ lvalue_p (ref)
         what they refer to are valid lvals.  */
     case PREINCREMENT_EXPR:
     case PREDECREMENT_EXPR:
+    case REALPART_EXPR:
+    case IMAGPART_EXPR:
     case COMPONENT_REF:
     case SAVE_EXPR:
       return lvalue_p (TREE_OPERAND (ref, 0));
@@ -925,27 +927,27 @@ struct list_hash
    and the hash code is computed differently for each of these.  */
 
 #define TYPE_HASH_SIZE 59
-struct list_hash *list_hash_table[TYPE_HASH_SIZE];
+static struct list_hash *list_hash_table[TYPE_HASH_SIZE];
 
 /* Compute a hash code for a list (chain of TREE_LIST nodes
    with goodies in the TREE_PURPOSE, TREE_VALUE, and bits of the
    TREE_COMMON slots), by adding the hash codes of the individual entries.  */
 
-int
-list_hash (list)
-     tree list;
+static int
+list_hash (purpose, value, chain)
+     tree purpose, value, chain;
 {
   register int hashcode = 0;
 
-  if (TREE_CHAIN (list))
-    hashcode += TYPE_HASH (TREE_CHAIN (list));
+  if (chain)
+    hashcode += TYPE_HASH (chain);
 
-  if (TREE_VALUE (list))
-    hashcode += TYPE_HASH (TREE_VALUE (list));
+  if (value)
+    hashcode += TYPE_HASH (value);
   else
     hashcode += 1007;
-  if (TREE_PURPOSE (list))
-    hashcode += TYPE_HASH (TREE_PURPOSE (list));
+  if (purpose)
+    hashcode += TYPE_HASH (purpose);
   else
     hashcode += 1009;
   return hashcode;
@@ -954,31 +956,30 @@ list_hash (list)
 /* Look in the type hash table for a type isomorphic to TYPE.
    If one is found, return it.  Otherwise return 0.  */
 
-tree
-list_hash_lookup (hashcode, list)
-     int hashcode;
-     tree list;
+static tree
+list_hash_lookup (hashcode, via_public, via_protected, via_virtual,
+                 purpose, value, chain)
+     int hashcode, via_public, via_virtual, via_protected;
+     tree purpose, value, chain;
 {
   register struct list_hash *h;
+
   for (h = list_hash_table[hashcode % TYPE_HASH_SIZE]; h; h = h->next)
     if (h->hashcode == hashcode
-       && TREE_VIA_VIRTUAL (h->list) == TREE_VIA_VIRTUAL (list)
-       && TREE_VIA_PUBLIC (h->list) == TREE_VIA_PUBLIC (list)
-       && TREE_VIA_PROTECTED (h->list) == TREE_VIA_PROTECTED (list)
-       && TREE_PURPOSE (h->list) == TREE_PURPOSE (list)
-       && TREE_VALUE (h->list) == TREE_VALUE (list)
-       && TREE_CHAIN (h->list) == TREE_CHAIN (list))
-      {
-       my_friendly_assert (TREE_TYPE (h->list) == TREE_TYPE (list), 299);
-       return h->list;
-      }
+       && TREE_VIA_VIRTUAL (h->list) == via_virtual
+       && TREE_VIA_PUBLIC (h->list) == via_public
+       && TREE_VIA_PROTECTED (h->list) == via_protected
+       && TREE_PURPOSE (h->list) == purpose
+       && TREE_VALUE (h->list) == value
+       && TREE_CHAIN (h->list) == chain)
+      return h->list;
   return 0;
 }
 
 /* Add an entry to the list-hash-table
    for a list TYPE whose hash code is HASHCODE.  */
 
-void
+static void
 list_hash_add (hashcode, list)
      int hashcode;
      tree list;
@@ -1008,29 +1009,6 @@ list_hash_add (hashcode, list)
 static int debug_no_list_hash = 0;
 
 tree
-list_hash_canon (hashcode, list)
-     int hashcode;
-     tree list;
-{
-  tree t1;
-
-  if (debug_no_list_hash)
-    return list;
-
-  t1 = list_hash_lookup (hashcode, list);
-  if (t1 != 0)
-    {
-      obstack_free (&class_obstack, list);
-      return t1;
-    }
-
-  /* If this is a new list, record it for later reuse.  */
-  list_hash_add (hashcode, list);
-
-  return list;
-}
-
-tree
 hash_tree_cons (via_public, via_virtual, via_protected, purpose, value, chain)
      int via_public, via_virtual, via_protected;
      tree purpose, value, chain;
@@ -1039,13 +1017,26 @@ hash_tree_cons (via_public, via_virtual, via_protected, purpose, value, chain)
   tree t;
   int hashcode;
 
+  if (! debug_no_list_hash)
+    {
+      hashcode = list_hash (purpose, value, chain);
+      t = list_hash_lookup (hashcode, via_public, via_protected, via_virtual,
+                           purpose, value, chain);
+      if (t)
+       return t;
+    }
+
   current_obstack = &class_obstack;
+
   t = tree_cons (purpose, value, chain);
   TREE_VIA_PUBLIC (t) = via_public;
   TREE_VIA_PROTECTED (t) = via_protected;
   TREE_VIA_VIRTUAL (t) = via_virtual;
-  hashcode = list_hash (t);
-  t = list_hash_canon (hashcode, t);
+
+  /* If this is a new list, record it for later reuse.  */
+  if (! debug_no_list_hash)
+    list_hash_add (hashcode, t);
+
   current_obstack = ambient_obstack;
   return t;
 }
@@ -1056,16 +1047,7 @@ tree
 hash_tree_chain (value, chain)
      tree value, chain;
 {
-  struct obstack *ambient_obstack = current_obstack;
-  tree t;
-  int hashcode;
-
-  current_obstack = &class_obstack;
-  t = tree_cons (NULL_TREE, value, chain);
-  hashcode = list_hash (t);
-  t = list_hash_canon (hashcode, t);
-  current_obstack = ambient_obstack;
-  return t;
+  return hash_tree_cons (0, 0, 0, NULL_TREE, value, chain);
 }
 
 /* Similar, but used for concatenating two lists.  */
@@ -1595,6 +1577,12 @@ mapcar (t, func)
         mapcar (TREE_CHAIN (TYPE_ARG_TYPES (t)), func));
       return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
 
+    case COMPLEX_CST:
+      t = copy_node (t);
+      TREE_REALPART (t) = mapcar (TREE_REALPART (t), func);
+      TREE_IMAGPART (t) = mapcar (TREE_REALPART (t), func);
+      return t;
+
     case CONSTRUCTOR:
       t = copy_node (t);
       CONSTRUCTOR_ELTS (t) = mapcar (CONSTRUCTOR_ELTS (t), func);
index f3779df..dd6415b 100644 (file)
@@ -355,6 +355,24 @@ common_type (t1, t2)
   code1 = TREE_CODE (t1);
   code2 = TREE_CODE (t2);
 
+  /* If one type is complex, form the common type of the non-complex
+     components, then make that complex.  Use T1 or T2 if it is the
+     required type.  */
+  if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
+    {
+      tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
+      tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
+      tree subtype = common_type (subtype1, subtype2);
+
+      if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
+       return build_type_attribute_variant (t1, attributes);
+      else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
+       return build_type_attribute_variant (t2, attributes);
+      else
+       return build_type_attribute_variant (build_complex_type (subtype),
+                                            attributes);
+    }
+
   switch (code1)
     {
     case INTEGER_TYPE:
@@ -1509,7 +1527,7 @@ decay_conversion (exp)
                              inner);
              TREE_CONSTANT (inner) = TREE_CONSTANT (TREE_OPERAND (inner, 0));
            }
-         return convert (build_pointer_type (TREE_TYPE (type)), inner);
+         return cp_convert (build_pointer_type (TREE_TYPE (type)), inner);
        }
 
       if (TREE_CODE (exp) == COMPOUND_EXPR)
@@ -1558,7 +1576,7 @@ decay_conversion (exp)
       /* This way is better for a COMPONENT_REF since it can
         simplify the offset for a component.  */
       adr = build_unary_op (ADDR_EXPR, exp, 1);
-      return convert (ptrtype, adr);
+      return cp_convert (ptrtype, adr);
     }
 
   return exp;
@@ -1580,7 +1598,7 @@ default_conversion (exp)
     {
       tree t = type_promotes_to (type);
       if (t != type)
-       return convert (t, exp);
+       return cp_convert (t, exp);
     }
 
   return exp;
@@ -2469,12 +2487,12 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
                                            index_identifier,
                                            NULL_TREE, 0));
       e1 = fold (build (GT_EXPR, boolean_type_node, idx,
-                       convert (delta_type_node, integer_zero_node)));
-      delta = convert (ptrdiff_type_node,
-                      build_component_ref (function, delta_identifier, NULL_TREE, 0));
+                       cp_convert (delta_type_node, integer_zero_node)));
+      delta = cp_convert (ptrdiff_type_node,
+                         build_component_ref (function, delta_identifier, NULL_TREE, 0));
       delta2 = DELTA2_FROM_PTRMEMFUNC (function);
 
-      /* convert down to the right base, before using the instance.  */
+      /* Convert down to the right base, before using the instance.  */
       instance
        = convert_pointer_to_real (TYPE_METHOD_BASETYPE (TREE_TYPE (fntype)),
                                   instance_ptr);
@@ -2485,7 +2503,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
       vtbl
        = build (PLUS_EXPR,
                 build_pointer_type (build_pointer_type (vtable_entry_type)),
-                vtbl, convert (ptrdiff_type_node, delta2));
+                vtbl, cp_convert (ptrdiff_type_node, delta2));
       vtbl = build_indirect_ref (vtbl, NULL_PTR);
       aref = build_array_ref (vtbl, build_binary_op (MINUS_EXPR,
                                                     idx,
@@ -2845,7 +2863,7 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
              && (TYPE_PRECISION (TREE_TYPE (val))
                  < TYPE_PRECISION (double_type_node)))
            /* Convert `float' to `double'.  */
-           result = tree_cons (NULL_TREE, convert (double_type_node, val), result);
+           result = tree_cons (NULL_TREE, cp_convert (double_type_node, val), result);
          else if (TYPE_LANG_SPECIFIC (TREE_TYPE (val))
                   && ! TYPE_HAS_TRIVIAL_INIT_REF (TREE_TYPE (val)))
            {
@@ -3139,8 +3157,10 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
     case FLOOR_DIV_EXPR:
     case ROUND_DIV_EXPR:
     case EXACT_DIV_EXPR:
-      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
-         && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
+      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
+          || code0 == COMPLEX_TYPE)
+         && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
+             || code1 == COMPLEX_TYPE))
        {
          if (TREE_CODE (op1) == INTEGER_CST && integer_zerop (op1))
            cp_warning ("division by zero in `%E / 0'", op0);
@@ -3249,7 +3269,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
          /* Convert the shift-count to an integer, regardless of
             size of value being shifted.  */
          if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
-           op1 = convert (integer_type_node, op1);
+           op1 = cp_convert (integer_type_node, op1);
          /* Avoid converting op1 to result_type later.  */
          converted = 1;
        }
@@ -3271,7 +3291,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
          /* Convert the shift-count to an integer, regardless of
             size of value being shifted.  */
          if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
-           op1 = convert (integer_type_node, op1);
+           op1 = cp_convert (integer_type_node, op1);
          /* Avoid converting op1 to result_type later.  */
          converted = 1;
        }
@@ -3296,15 +3316,17 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
          /* Convert the shift-count to an integer, regardless of
             size of value being shifted.  */
          if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
-           op1 = convert (integer_type_node, op1);
+           op1 = cp_convert (integer_type_node, op1);
        }
       break;
 
     case EQ_EXPR:
     case NE_EXPR:
       build_type = boolean_type_node; 
-      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
-         && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
+      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
+          || code0 == COMPLEX_TYPE)
+         && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
+             || code1 == COMPLEX_TYPE))
        short_compare = 1;
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
        {
@@ -3496,9 +3518,12 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
       break;
     }
 
-  if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
-      && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
+  if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
+      &&
+      (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
     {
+      int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
+
       if (shorten || common || short_compare)
        result_type = common_type (type0, type1);
 
@@ -3513,7 +3538,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
         Eg, (short)-1 | (unsigned short)-1 is (int)-1
         but calculated in (unsigned short) it would be (unsigned short)-1.  */
 
-      if (shorten)
+      if (shorten && none_complex)
        {
          int unsigned0, unsigned1;
          tree arg0 = get_narrower (op0, &unsigned0);
@@ -3608,7 +3633,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
                                           TREE_TYPE (arg0));
              /* Convert value-to-be-shifted to that type.  */
              if (TREE_TYPE (op0) != result_type)
-               op0 = convert (result_type, op0);
+               op0 = cp_convert (result_type, op0);
              converted = 1;
            }
        }
@@ -3627,7 +3652,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
          tree val 
            = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode);
          if (val != 0)
-           return convert (boolean_type_node, val);
+           return cp_convert (boolean_type_node, val);
          op0 = xop0, op1 = xop1;
          converted = 1;
          resultcode = xresultcode;
@@ -3758,9 +3783,9 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
   if (! converted)
     {
       if (TREE_TYPE (op0) != result_type)
-       op0 = convert (result_type, op0); 
+       op0 = cp_convert (result_type, op0); 
       if (TREE_TYPE (op1) != result_type)
-       op1 = convert (result_type, op1); 
+       op1 = cp_convert (result_type, op1); 
     }
 
   if (build_type == NULL_TREE)
@@ -3774,7 +3799,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
     if (folded == result)
       TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
     if (final_type != 0)
-      return convert (final_type, folded);
+      return cp_convert (final_type, folded);
     return folded;
   }
 }
@@ -3851,15 +3876,15 @@ pointer_int_sum (resultcode, ptrop, intop)
      so the multiply won't overflow spuriously.  */
 
   if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype))
-    intop = convert (type_for_size (TYPE_PRECISION (sizetype), 0), intop);
+    intop = cp_convert (type_for_size (TYPE_PRECISION (sizetype), 0), intop);
 
   /* Replace the integer argument with a suitable product by the object size.
      Do this multiplication as signed, then convert to the appropriate
      pointer type (actually unsigned integral).  */
 
-  intop = convert (result_type,
-                  build_binary_op (MULT_EXPR, intop,
-                                   convert (TREE_TYPE (intop), size_exp), 1));
+  intop = cp_convert (result_type,
+                     build_binary_op (MULT_EXPR, intop,
+                                      cp_convert (TREE_TYPE (intop), size_exp), 1));
 
   /* Create the sum or difference.  */
 
@@ -3898,7 +3923,7 @@ pointer_diff (op0, op1)
      then drop through to build the divide operator.  */
 
   op0 = build_binary_op (MINUS_EXPR,
-                        convert (restype, op0), convert (restype, op1), 1);
+                        cp_convert (restype, op0), cp_convert (restype, op1), 1);
 
   /* This generates an error if op1 is a pointer to an incomplete type.  */
   if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (op1))) == 0)
@@ -3913,7 +3938,7 @@ pointer_diff (op0, op1)
 
   /* Do the division.  */
 
-  result = build (EXACT_DIV_EXPR, restype, op0, convert (restype, op1));
+  result = build (EXACT_DIV_EXPR, restype, op0, cp_convert (restype, op1));
 
   folded = fold (result);
   if (folded == result)
@@ -3964,7 +3989,7 @@ build_component_addr (arg, argtype, msg)
                                size_int (BITS_PER_UNIT));
       int flag = TREE_CONSTANT (rval);
       rval = fold (build (PLUS_EXPR, argtype,
-                         rval, convert (argtype, offset)));
+                         rval, cp_convert (argtype, offset)));
       TREE_CONSTANT (rval) = flag;
     }
   return rval;
@@ -4028,7 +4053,7 @@ condition_conversion (expr)
   tree t;
   if (processing_template_decl)
     return expr;
-  t = convert (boolean_type_node, expr);
+  t = cp_convert (boolean_type_node, expr);
   t = fold (build1 (CLEANUP_POINT_EXPR, boolean_type_node, t));
   return t;
 }
@@ -4082,7 +4107,14 @@ build_unary_op (code, xarg, noconvert)
       break;
 
     case BIT_NOT_EXPR:
-      if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM, arg, 1)))
+      if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
+       {
+         code = CONJ_EXPR;
+         if (!noconvert)
+           arg = default_conversion (arg);
+       }
+      else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM,
+                                                  arg, 1)))
        errstring = "wrong type argument to bit-complement";
       else if (!noconvert)
        arg = default_conversion (arg);
@@ -4095,8 +4127,16 @@ build_unary_op (code, xarg, noconvert)
        arg = default_conversion (arg);
       break;
 
+    case CONJ_EXPR:
+      /* Conjugating a real value is a no-op, but allow it anyway.  */
+      if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, 1)))
+       errstring = "wrong type argument to conjugation";
+      else if (!noconvert)
+       arg = default_conversion (arg);
+      break;
+
     case TRUTH_NOT_EXPR:
-      arg = convert (boolean_type_node, arg);
+      arg = cp_convert (boolean_type_node, arg);
       val = invert_truthvalue (arg);
       if (arg != error_mark_node)
        return val;
@@ -4106,6 +4146,22 @@ build_unary_op (code, xarg, noconvert)
     case NOP_EXPR:
       break;
       
+    case REALPART_EXPR:
+      if (TREE_CODE (arg) == COMPLEX_CST)
+       return TREE_REALPART (arg);
+      else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
+       return fold (build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg));
+      else
+       return arg;
+
+    case IMAGPART_EXPR:
+      if (TREE_CODE (arg) == COMPLEX_CST)
+       return TREE_IMAGPART (arg);
+      else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
+       return fold (build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg));
+      else
+       return cp_convert (TREE_TYPE (arg), integer_zero_node);
+      
     case PREINCREMENT_EXPR:
     case POSTINCREMENT_EXPR:
     case PREDECREMENT_EXPR:
@@ -4117,6 +4173,19 @@ build_unary_op (code, xarg, noconvert)
       if (val != 0)
        return val;
 
+      /* Increment or decrement the real part of the value,
+        and don't change the imaginary part.  */
+      if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
+       {
+         tree real, imag;
+
+         arg = stabilize_reference (arg);
+         real = build_unary_op (REALPART_EXPR, arg, 1);
+         imag = build_unary_op (IMAGPART_EXPR, arg, 1);
+         return build (COMPLEX_EXPR, TREE_TYPE (arg),
+                       build_unary_op (code, real, 1), imag);
+       }
+
       /* Report invalid types.  */
 
       if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_POINTER,
@@ -4176,7 +4245,7 @@ build_unary_op (code, xarg, noconvert)
        else
          inc = integer_one_node;
 
-       inc = convert (argtype, inc);
+       inc = cp_convert (argtype, inc);
 
        /* Handle incrementing a cast-expression.  */
 
@@ -4251,7 +4320,7 @@ build_unary_op (code, xarg, noconvert)
          val = build (code, TREE_TYPE (arg), arg, inc);
 
        TREE_SIDE_EFFECTS (val) = 1;
-       return convert (result_type, val);
+       return cp_convert (result_type, val);
       }
 
     case ADDR_EXPR:
@@ -4438,9 +4507,9 @@ convert_sequence (conversions, arg)
     case FIX_FLOOR_EXPR:
     case FIX_ROUND_EXPR:
     case FIX_CEIL_EXPR:
-      return convert (TREE_TYPE (conversions),
-                     convert_sequence (TREE_OPERAND (conversions, 0),
-                                       arg));
+      return cp_convert (TREE_TYPE (conversions),
+                        convert_sequence (TREE_OPERAND (conversions, 0),
+                                          arg));
 
     default:
       return arg;
@@ -4556,7 +4625,7 @@ unary_complex_lvalue (code, arg)
             data member of a structure.  */
          offset = size_binop (PLUS_EXPR, offset, size_int (1));
 
-         return convert (build_pointer_type (TREE_TYPE (arg)), offset);
+         return cp_convert (build_pointer_type (TREE_TYPE (arg)), offset);
        }
     }
 
@@ -4608,6 +4677,8 @@ mark_addressable (exp)
       case ADDR_EXPR:
       case COMPONENT_REF:
       case ARRAY_REF:
+      case REALPART_EXPR:
+      case IMAGPART_EXPR:
        x = TREE_OPERAND (x, 0);
        break;
 
@@ -4731,7 +4802,7 @@ build_conditional_expr (ifexp, op1, op2)
       ifexp = op1 = save_expr (ifexp);
     }
 
-  ifexp = convert (boolean_type_node, ifexp);
+  ifexp = cp_convert (boolean_type_node, ifexp);
 
   if (TREE_CODE (ifexp) == ERROR_MARK)
     return error_mark_node;
@@ -5280,7 +5351,7 @@ build_reinterpret_cast (type, expr)
       return error_mark_node;
     }
       
-  return convert (type, expr);
+  return cp_convert (type, expr);
 }
 
 tree
@@ -5339,7 +5410,7 @@ build_const_cast (type, expr)
   else if (TREE_CODE (type) == POINTER_TYPE
           && TREE_CODE (intype) == POINTER_TYPE
           && comp_ptr_ttypes_const (TREE_TYPE (type), TREE_TYPE (intype)))
-    return convert (type, expr);
+    return cp_convert (type, expr);
 
   cp_error ("const_cast from `%T' to `%T'", intype, type);
   return error_mark_node;
@@ -5621,9 +5692,9 @@ build_modify_expr (lhs, modifycode, rhs)
           so the code to compute it is only emitted once.  */
        tree cond
          = build_conditional_expr (TREE_OPERAND (lhs, 0),
-                                   build_modify_expr (convert (TREE_TYPE (lhs), TREE_OPERAND (lhs, 1)),
+                                   build_modify_expr (cp_convert (TREE_TYPE (lhs), TREE_OPERAND (lhs, 1)),
                                                       modifycode, rhs),
-                                   build_modify_expr (convert (TREE_TYPE (lhs), TREE_OPERAND (lhs, 2)),
+                                   build_modify_expr (cp_convert (TREE_TYPE (lhs), TREE_OPERAND (lhs, 2)),
                                                       modifycode, rhs));
        if (cond == error_mark_node)
          return cond;
@@ -5632,7 +5703,7 @@ build_modify_expr (lhs, modifycode, rhs)
        return build (COMPOUND_EXPR, TREE_TYPE (lhs),
                      /* Case to void to suppress warning
                         from warn_if_unused_value.  */
-                     convert (void_type_node, rhs), cond);
+                     cp_convert (void_type_node, rhs), cond);
       }
     }
 
@@ -5779,11 +5850,11 @@ build_modify_expr (lhs, modifycode, rhs)
          pedwarn ("ANSI C++ forbids cast to non-reference type used as lvalue");
 
        result = build_modify_expr (inner_lhs, NOP_EXPR,
-                                   convert (TREE_TYPE (inner_lhs),
-                                            convert (lhstype, newrhs)));
+                                   cp_convert (TREE_TYPE (inner_lhs),
+                                               cp_convert (lhstype, newrhs)));
        if (result == error_mark_node)
          return result;
-       return convert (TREE_TYPE (lhs), result);
+       return cp_convert (TREE_TYPE (lhs), result);
       }
     }
 
@@ -5999,11 +6070,11 @@ build_modify_expr (lhs, modifycode, rhs)
          result
            = build (COND_EXPR, result_type, cond,
                     build_modify_expr (lhs, modifycode,
-                                       convert (result_type,
-                                                TREE_OPERAND (newrhs, 1))),
+                                       cp_convert (result_type,
+                                                   TREE_OPERAND (newrhs, 1))),
                     build_modify_expr (lhs1, modifycode,
-                                       convert (result_type,
-                                                TREE_OPERAND (newrhs, 2))));
+                                       cp_convert (result_type,
+                                                   TREE_OPERAND (newrhs, 2))));
        }
     }
   else
@@ -6116,7 +6187,7 @@ get_delta_difference (from, to, force)
          warning ("pointer to member conversion to virtual base class will only work if you are very careful");
        }
       delta = BINFO_OFFSET (binfo);
-      delta = convert (ptrdiff_type_node, delta);
+      delta = cp_convert (ptrdiff_type_node, delta);
       
       return build_binary_op (MINUS_EXPR,
                              integer_zero_node,
@@ -6234,8 +6305,8 @@ build_ptrmemfunc (type, pfn, force)
       if (type == TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (pfn)))
        return pfn;
 
-      ndelta = convert (ptrdiff_type_node, build_component_ref (pfn, delta_identifier, NULL_TREE, 0));
-      ndelta2 = convert (ptrdiff_type_node, DELTA2_FROM_PTRMEMFUNC (pfn));
+      ndelta = cp_convert (ptrdiff_type_node, build_component_ref (pfn, delta_identifier, NULL_TREE, 0));
+      ndelta2 = cp_convert (ptrdiff_type_node, DELTA2_FROM_PTRMEMFUNC (pfn));
       idx = build_component_ref (pfn, index_identifier, NULL_TREE, 0);
 
       n = get_delta_difference (TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (pfn)))),
@@ -6405,8 +6476,10 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
       return error_mark_node;
     }
   /* Arithmetic types all interconvert.  */
-  if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == BOOLEAN_TYPE)
-       && (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == BOOLEAN_TYPE))
+  if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == BOOLEAN_TYPE
+       || codel == COMPLEX_TYPE)
+       && (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == BOOLEAN_TYPE
+          || coder == COMPLEX_TYPE))
     {
       /* But we should warn if assigning REAL_TYPE to INTEGER_TYPE.  */
       if (coder == REAL_TYPE && codel == INTEGER_TYPE)
@@ -6444,7 +6517,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
           || (coder == ENUMERAL_TYPE
               && (INTEGRAL_CODE_P (codel) || codel == REAL_TYPE)))
     {
-      return cp_convert (type, rhs, CONV_IMPLICIT, LOOKUP_NORMAL);
+      return ocp_convert (type, rhs, CONV_IMPLICIT, LOOKUP_NORMAL);
     }
   /* Conversions among pointers */
   else if (codel == POINTER_TYPE
@@ -6678,7 +6751,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
              return error_mark_node;
            }
        }
-      return convert (type, rhs);
+      return cp_convert (type, rhs);
     }
   else if (codel == POINTER_TYPE && coder == INTEGER_TYPE)
     {
@@ -6693,7 +6766,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
            cp_pedwarn ("%s to `%T' from `%T' lacks a cast",
                        errtype, type, rhstype);
        }
-      return convert (type, rhs);
+      return cp_convert (type, rhs);
     }
   else if (codel == INTEGER_TYPE
           && (coder == POINTER_TYPE
@@ -6708,7 +6781,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
       else
        cp_pedwarn ("%s to `%T' from `%T' lacks a cast",
                    errtype, type, rhstype);
-      return convert (type, rhs);
+      return cp_convert (type, rhs);
     }
   else if (codel == BOOLEAN_TYPE
           && (coder == POINTER_TYPE
@@ -6716,7 +6789,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
                   && (IS_SIGNATURE_POINTER (rhstype)
                       || TYPE_PTRMEMFUNC_FLAG (rhstype)
                       || IS_SIGNATURE_REFERENCE (rhstype)))))
-    return convert (type, rhs);
+    return cp_convert (type, rhs);
 
   /* C++ */
   else if (((coder == POINTER_TYPE
@@ -6754,14 +6827,14 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
       return nrhs;
     }
   else if (TYPE_HAS_CONSTRUCTOR (type) || IS_AGGR_TYPE (TREE_TYPE (rhs)))
-    return convert (type, rhs);
+    return cp_convert (type, rhs);
   /* Handle anachronistic conversions from (::*)() to cv void* or (*)().  */
   else if (TREE_CODE (type) == POINTER_TYPE
           && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
               || TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
           && TREE_TYPE (rhs)
           && TYPE_PTRMEMFUNC_P (TREE_TYPE (rhs)))
-    return convert (type, rhs);
+    return cp_convert (type, rhs);
 
   cp_error ("%s to `%T' from `%T'", errtype, type, rhstype);
   return error_mark_node;
@@ -6881,7 +6954,7 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
       && (TYPE_NEEDS_CONSTRUCTING (type) || TREE_HAS_CONSTRUCTOR (rhs)))
     {
       if (flag_ansi_overloading)
-       return cp_convert (type, rhs, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
+       return ocp_convert (type, rhs, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
 
       if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype))
        {
@@ -6952,8 +7025,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
          return rhs;
        }
 
-      return cp_convert (type, rhs, CONV_OLD_CONVERT,
-                        flags | LOOKUP_NO_CONVERSION);
+      return ocp_convert (type, rhs, CONV_OLD_CONVERT,
+                         flags | LOOKUP_NO_CONVERSION);
     }
 
   if (type == TREE_TYPE (rhs))
index d499846..afd4cd8 100644 (file)
@@ -816,7 +816,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 == BOOLEAN_TYPE || code == COMPLEX_TYPE
       || (code == RECORD_TYPE && ! raw_constructor
          && (IS_SIGNATURE_POINTER (type) || IS_SIGNATURE_REFERENCE (type))))
     {