OSDN Git Service

41st Cygnus<->FSF merge
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 24 Jun 1994 00:54:38 +0000 (00:54 +0000)
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 24 Jun 1994 00:54:38 +0000 (00:54 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@7553 138bc75d-0d04-0410-961f-82ee72b054a4

12 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/decl2.c
gcc/cp/init.c
gcc/cp/pt.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/cp/typeck2.c

index cddc168..e894e63 100644 (file)
@@ -1,3 +1,91 @@
+Thu Jun 23 00:22:28 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * decl.c (grokdeclarator): Set explicit_int for decls that just
+       specify, say, 'long'.
+
+       * init.c (do_friend): Do overload C functions (or call pushdecl,
+        anyaway).
+
+Wed Jun 22 13:40:49 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * cvt.c (build_up_reference): Don't call readonly_error.
+       (convert_to_reference): Propagate const and volatile from expr to
+       its type.
+
+       * tree.c (lvalue_p): Random CALL_EXPRs are not lvalues.
+
+       * cvt.c (build_up_reference): Break out WITH_CLEANUP_EXPR when
+       creating a temporary.
+       (convert_to_reference): Lose excessive and incorrect trickiness.
+       (cp_convert): Call build_cplus_new with with_cleanup_p set.
+
+       * typeck2.c (build_functional_cast): Ditto.
+
+Tue Jun 21 17:38:38 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * decl.c (grokdeclarator): signed, unsigned, long and short all
+       imply 'int'.
+
+       * decl.c (grokdeclarator): Allow "this is a type" syntax.
+       (grok_reference_init): Simplify and fix.
+
+Sun Jun 19 17:08:48 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * decl.c (grokdeclarator): pedwarn about a typedef that specifies no
+       type.
+
+Sat Jun 18 04:16:50 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * decl.c (start_function): Move TREE_PUBLIC and DECL_EXTERNAL
+       tinkering to after call to pushdecl.
+
+Fri Jun 17 14:48:28 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * call.c (build_method_call): Handle destructors for non-aggregate
+       types properly.
+
+Thu Jun 16 16:48:05 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * call.c (build_method_call): Make sure that the name given for the
+       destructor matches the constructor_name of the instance.
+
+       * pt.c (do_function_instantiation): A non-extern instantiation
+       overrides a later extern one.
+       (do_type_instantiation): Ditto.
+
+Wed Jun 15 19:34:54 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * init.c (expand_aggr_init): Use TYPE_MAIN_VARIANT to get the
+       unqualified array type.
+
+       * cp-tree.h (EMPTY_CONSTRUCTOR_P): Tests whether NODE is a
+       CONSTRUCTOR with no elements.
+
+       * decl.c (various): Lose empty_init_node.
+       (finish_decl): Use EMPTY_CONSTRUCTOR_P, do the empty CONSTRUCTOR
+       thing depending on the value of DECL_COMMON instead of
+       flag_conserve_space, do the empty CONSTRUCTOR thing for types that
+       don't have constructors, don't treat a real empty CONSTRUCTOR
+       specially.
+
+       * typeck2.c (process_init_constructor): Don't treat empty_init_node
+       specially.
+
+Wed Jun 15 19:05:25 1994  Mike Stump  (mrs@cygnus.com)
+
+       * class.c (override_one_vtable): Don't forget to merge in an old
+       overrider when we wanted to reuse a vtable, but couldn't.
+
+Wed Jun 15 15:03:16 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * decl.c (start_decl): Put statics in common again.
+
+       * decl.c (grokdeclarator): Return NULL_TREE for an error rather than
+       setting the type to error_mark_node.
+
+       * typeck.c (build_modify_expr): Build up a COMPOUND_EXPR for enum
+       bitfield assignments.
+
 Tue Jun 14 12:23:38 1994  Jason Merrill  (jason@deneb.cygnus.com)
 
        * decl.c (grok_op_properties): Const objects can be passed by value.
index 6d2b26c..75c5635 100644 (file)
@@ -1603,14 +1603,22 @@ build_method_call (instance, name, parms, basetype_path, flags)
       name = TREE_OPERAND (name, 0);
       if (parms)
        error ("destructors take no parameters");
-      basetype = get_type_value (name);
-      if (basetype == NULL_TREE)
+      basetype = TREE_TYPE (instance);
+      if (IS_AGGR_TYPE (basetype))
+       {
+         if (name == constructor_name (basetype))
+           goto huzzah;
+       }
+      else
        {
-         cp_error ("call to destructor for non-type `%D'", name);
-         return void_zero_node;
+         if (basetype == get_type_value (name))
+           goto huzzah;
        }
-      if (basetype != TREE_TYPE(instance))
-       basetype = TREE_TYPE(instance);
+      cp_error ("destructor name `~%D' does not match type `%T' of expression",
+               name, basetype);
+      return void_zero_node;
+
+    huzzah:
       if (! TYPE_HAS_DESTRUCTOR (basetype))
        return void_zero_node;
       instance = default_conversion (instance);
index 1d27681..62eff53 100644 (file)
@@ -2400,6 +2400,10 @@ override_one_vtable (binfo, old, t)
                }
              TREE_VALUE (virtuals) = TREE_VALUE (old_virtuals);
            }
+         else if (choose == NEITHER)
+           {
+             TREE_VALUE (virtuals) = TREE_VALUE (old_virtuals);
+           }  
        }
       else
        {
index 9ba72b0..5a7c353 100644 (file)
@@ -1167,6 +1167,9 @@ struct lang_decl
    has been duly initialized in its constructor.  */
 #define TREE_HAS_CONSTRUCTOR(NODE) (TREE_LANG_FLAG_4(NODE))
 
+#define EMPTY_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == CONSTRUCTOR \
+                                  && CONSTRUCTOR_ELTS (NODE) == NULL_TREE)
+
 /* Indicates that a NON_LVALUE_EXPR came from a C++ reference.
    Used to generate more helpful error message in case somebody
    tries to take its address.  */
index 3750221..0b08f05 100644 (file)
@@ -337,7 +337,20 @@ build_up_reference (type, arg, flags, checkconst)
          TREE_READONLY (arg) = 0;
        }
 
+#if 0
+      if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE)
+       {
+         rval = copy_node (arg);
+         TREE_TYPE (rval) = build_pointer_type (TREE_TYPE (TREE_TYPE (arg)));
+       }
+      else
+       rval = arg;
+
+      rval = convert (build_pointer_type (TREE_TYPE (type)), rval);
+      TREE_TYPE (rval) = type;
+#else
       rval = build1 (CONVERT_EXPR, type, arg);
+#endif
       TREE_REFERENCE_EXPR (rval) = 1;
 
       /* propagate the const flag on something like:
@@ -372,7 +385,7 @@ build_up_reference (type, arg, flags, checkconst)
        }
       literal_flag = TREE_CONSTANT (arg);
 
-      goto done_but_maybe_warn;
+      goto done;
 
       /* Get this out of a register if we happened to be in one by accident.
         Also, build up references to non-lvalues it we must.  */
@@ -409,7 +422,7 @@ build_up_reference (type, arg, flags, checkconst)
       TREE_TYPE (rval) = type;
       literal_flag = staticp (TREE_OPERAND (targ, 0));
 
-      goto done_but_maybe_warn;
+      goto done;
 
       /* Anything not already handled and not a true memory reference
         needs to have a reference built up.  Do so silently for
@@ -537,7 +550,12 @@ build_up_reference (type, arg, flags, checkconst)
       if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (argtype))
        {
          temp = build_cplus_new (argtype, targ, 1);
-         rval = build1 (ADDR_EXPR, type, temp);
+         if (TREE_CODE (temp) == WITH_CLEANUP_EXPR)
+           rval = build (WITH_CLEANUP_EXPR, type,
+                         build1 (ADDR_EXPR, type, TREE_OPERAND (temp, 0)),
+                         0, TREE_OPERAND (temp, 2));
+         else
+           rval = build1 (ADDR_EXPR, type, temp);
          goto done;
        }
       else
@@ -572,10 +590,6 @@ build_up_reference (type, arg, flags, checkconst)
   else
     rval = build1 (ADDR_EXPR, type, arg);
 
- done_but_maybe_warn:
-  if (checkconst && TREE_READONLY (arg) && ! TYPE_READONLY (target_type))
-    readonly_error (arg, "conversion to reference", 1);
-
  done:
   if (TYPE_USES_COMPLEX_INHERITANCE (argtype))
     {
@@ -636,7 +650,11 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
          if (form == REFERENCE_TYPE)
            ttr = TREE_TYPE (TREE_TYPE (expr));
          else
-           ttr = TREE_TYPE (expr);
+           {
+             int r = TREE_READONLY (expr);
+             int v = TREE_THIS_VOLATILE (expr);
+             ttr = c_build_type_variant (TREE_TYPE (expr), r, v);
+           }
 
          if (! lvalue_p (expr) &&
              (decl == NULL_TREE || ! TYPE_READONLY (ttl)))
@@ -653,46 +671,20 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
            {
              if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
                cp_pedwarn ("conversion from `%T' to `%T' discards const",
-                           TREE_TYPE (expr), reftype);
+                           ttr, reftype);
              else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
                cp_pedwarn ("conversion from `%T' to `%T' discards volatile",
-                           TREE_TYPE (expr), reftype);
-           }
-       }
-      
-      /* If EXPR is of aggregate type, and is really a CALL_EXPR,
-        then we don't need to convert it to reference type if
-        it is only being used to initialize DECL which is also
-        of the same aggregate type.  */
-      if (decl != NULL_TREE && decl != error_mark_node
-         && IS_AGGR_TYPE (type)
-         && TREE_CODE (expr) == CALL_EXPR
-         && TYPE_MAIN_VARIANT (type) == intype)
-       {
-         tree e1 = build (INIT_EXPR, void_type_node, decl, expr);
-         tree e2;
-
-         TREE_SIDE_EFFECTS (e1) = 1;
-         if (form == REFERENCE_TYPE)
-           e2 = build1 (NOP_EXPR, reftype, decl);
-         else
-           {
-             e2 = build_unary_op (ADDR_EXPR, decl, 0);
-             TREE_TYPE (e2) = reftype;
-             TREE_REFERENCE_EXPR (e2) = 1;
+                           ttr, reftype);
            }
-         return build_compound_expr
-           (tree_cons (NULL_TREE, e1, build_tree_list (NULL_TREE, e2)));
        }
 
-      else if (form == REFERENCE_TYPE)
+      if (form == REFERENCE_TYPE)
        {
-         rval = build1 (NOP_EXPR,
-                        build_pointer_type (TREE_TYPE (TREE_TYPE (expr))),
-                        expr);
+         rval = copy_node (expr);
+         TREE_TYPE (rval) = build_pointer_type (TREE_TYPE (TREE_TYPE (expr)));
          rval = cp_convert (build_pointer_type (TREE_TYPE (reftype)), rval,
                             convtype, flags);
-         rval = build1 (NOP_EXPR, reftype, rval);
+         TREE_TYPE (rval) = reftype;
          return rval;
        }
 
@@ -1364,7 +1356,7 @@ cp_convert (type, expr, convtype, flags)
                      return error_mark_node;
                    }
                  /* call to constructor successful.  */
-                 rval = build_cplus_new (type, rval, 0);
+                 rval = build_cplus_new (type, rval, 1);
                  return rval;
                }
            }
@@ -1415,7 +1407,7 @@ cp_convert (type, expr, convtype, flags)
              cp_error ("in conversion to type `%T'", type);
              return error_mark_node;
            }
-         rval = build_cplus_new (type, init, 0);
+         rval = build_cplus_new (type, init, 1);
          return rval;
        }
     }
index 4bbfec9..5a20953 100644 (file)
@@ -244,15 +244,6 @@ tree maybe_gc_cleanup;
 /* Array type `vtable_entry_type[]' */
 tree vtbl_type_node;
 
-/* Static decls which do not have static initializers have no
-   initializers as far as GNU C is concerned.  EMPTY_INIT_NODE
-   is a static initializer which makes varasm code place the decl
-   in data rather than in bss space.  Such gymnastics are necessary
-   to avoid the problem that the linker will not include a library
-   file if all the library appears to contribute are bss variables.  */
-
-tree empty_init_node;
-
 /* In a destructor, the point at which all derived class destroying
    has been done, just before any base class destroying will be done.  */
 
@@ -4376,7 +4367,6 @@ init_decl_processing ()
   TREE_TYPE (integer_two_node) = integer_type_node;
   integer_three_node = build_int_2 (3, 0);
   TREE_TYPE (integer_three_node) = integer_type_node;
-  empty_init_node = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE);
 
   bool_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
   TREE_SET_CODE (bool_type_node, BOOLEAN_TYPE);
@@ -5385,8 +5375,14 @@ start_decl (declarator, declspecs, initialized, raises)
   else
     tem = pushdecl (decl);
             
-  /* Tell the back-end to use or not use .common as appropriate.  */
-  DECL_COMMON (tem) = flag_conserve_space;
+  /* Tell the back-end to use or not use .common as appropriate.  If we say
+     -fconserve-space, we want this to save space, at the expense of wrong
+     semantics.  If we say -fno-conserve-space, we want this to produce
+     errors about redefs; to do this we force variables into the data
+     segment.  Common storage is okay for non-public uninitialized data;
+     the linker can't match it with storage from other files, and we may
+     save some disk space.  */
+  DECL_COMMON (tem) = flag_conserve_space || ! TREE_PUBLIC (tem);
 
 #if 0
   /* We don't do this yet for GNU C++.  */
@@ -5556,10 +5552,7 @@ grok_reference_init (decl, type, init, cleanupp)
      tree decl, type, init;
      tree *cleanupp;
 {
-  char *errstr = NULL;
-  int is_reference;
   tree tmp;
-  tree this_ptr_type, actual_init = NULL_TREE;
 
   if (init == NULL_TREE)
     {
@@ -5585,56 +5578,22 @@ grok_reference_init (decl, type, init, cleanupp)
 
   if (TREE_CODE (init) == TREE_LIST)
     init = build_compound_expr (init);
-  is_reference = TREE_CODE (TREE_TYPE (init)) == REFERENCE_TYPE;
-  tmp = is_reference ? convert_from_reference (init) : init;
 
   if (TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE
       && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE)
     {
-      /* Note: default conversion is only called in very
-        special cases.  */
+      /* Note: default conversion is only called in very special cases.  */
       init = default_conversion (init);
     }
 
-  /* Can we just enreference this lvalue?  */
-  if ((is_reference || lvalue_p (init)
-       || (actual_init = unary_complex_lvalue (ADDR_EXPR, init)))
-      && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (type)),
-                   TYPE_MAIN_VARIANT (TREE_TYPE (tmp)), 0))
-    {
-      /* This section implements ANSI C++ June 5 1992 WP 8.4.3.5. */
+  tmp = convert_to_reference
+    (type, init, CONV_IMPLICIT, LOOKUP_SPECULATIVELY|LOOKUP_NORMAL, decl);
 
-      /* A reference to a volatile T cannot be initialized with
-        a const T, and vice-versa.  */
-      if (TYPE_VOLATILE (TREE_TYPE (type)) && TREE_READONLY (init))
-       errstr = "cannot initialize a reference to a volatile `%T' with a const `%T'";
-      else if (TYPE_READONLY (TREE_TYPE (type)) && TREE_THIS_VOLATILE (init))
-       errstr = "cannot initialize a reference to a const `%T' with a volatile `%T'";
-      /* A reference to a plain T can be initialized only with a plain T. */
-      else if (!TYPE_VOLATILE (TREE_TYPE (type))
-              && !TYPE_READONLY (TREE_TYPE (type)))
-       {
-         if (TREE_READONLY (init))
-           errstr = "cannot initialize a reference to `%T' with a const `%T'";
-         else if (TREE_THIS_VOLATILE (init))
-           errstr = "cannot initialize a reference to `%T' with a volatile `%T'";
-       }
-      if (errstr)
-       {
-         cp_error (errstr, TREE_TYPE (type), TREE_TYPE (tmp));
-         goto fail;
-       }
-    }
-  /* OK, can we generate a reference then?  */
-  else if ((actual_init = convert_to_reference
-           (type, init, CONV_IMPLICIT,
-            LOOKUP_SPECULATIVELY|LOOKUP_NORMAL, decl)))
+  if (tmp == error_mark_node)
+    goto fail;
+  else if (tmp != NULL_TREE)
     {
-      if (actual_init == error_mark_node)
-       goto fail;
-
-      init = actual_init;
-      is_reference = 1;
+      init = tmp;
 
       if (TREE_CODE (init) == WITH_CLEANUP_EXPR)
        {
@@ -5643,61 +5602,17 @@ grok_reference_init (decl, type, init, cleanupp)
          *cleanupp = TREE_OPERAND (init, 2);
          TREE_OPERAND (init, 2) = error_mark_node;
        }
-    }
-  else
-    {
-      cp_error ("cannot initialize `%T' from `%T'", type, TREE_TYPE (init));
-      goto fail;
-    }
 
-  /* In the case of initialization, it is permissible
-     to assign one reference to another.  */
-  this_ptr_type = build_pointer_type (TREE_TYPE (type));
-
-  if (is_reference)
-    {
       if (TREE_SIDE_EFFECTS (init))
        DECL_INITIAL (decl) = save_expr (init);
       else
        DECL_INITIAL (decl) = init;
     }
-  else if (lvalue_p (init))
+  else
     {
-      tmp = build_unary_op (ADDR_EXPR, init, 0);
-      if (TREE_CODE (tmp) == ADDR_EXPR
-         && TREE_CODE (TREE_OPERAND (tmp, 0)) == WITH_CLEANUP_EXPR)
-       {
-         if (*cleanupp) my_friendly_abort (1);
-         *cleanupp = TREE_OPERAND (TREE_OPERAND (tmp, 0), 2);
-         TREE_OPERAND (TREE_OPERAND (tmp, 0), 2) = error_mark_node;
-       }
-      if (IS_AGGR_TYPE (TREE_TYPE (this_ptr_type)))
-       DECL_INITIAL (decl) = convert_pointer_to (TREE_TYPE (this_ptr_type),
-                                                 tmp);
-      else
-       DECL_INITIAL (decl) = convert (this_ptr_type, tmp);
-
-      DECL_INITIAL (decl) = save_expr (DECL_INITIAL (decl));
-      if (DECL_INITIAL (decl) == current_class_decl)
-       DECL_INITIAL (decl) = copy_node (current_class_decl);
-      TREE_TYPE (DECL_INITIAL (decl)) = type;
-    }
-  /* If actual_init is set here, it is set from the first check above.  */
-  else if (actual_init)
-    {
-      /* The initializer for this decl goes into its
-        DECL_REFERENCE_SLOT.  Make sure that we can handle
-        multiple evaluations without ill effect.  */
-      if (TREE_CODE (actual_init) == ADDR_EXPR
-         && TREE_CODE (TREE_OPERAND (actual_init, 0)) == TARGET_EXPR)
-       actual_init = save_expr (actual_init);
-      DECL_INITIAL (decl) = convert_pointer_to (TREE_TYPE (this_ptr_type),
-                                               actual_init);
-      DECL_INITIAL (decl) = save_expr (DECL_INITIAL (decl));
-      TREE_TYPE (DECL_INITIAL (decl)) = type;
+      cp_error ("cannot initialize `%T' from `%T'", type, TREE_TYPE (init));
+      goto fail;
     }
-  else
-    my_friendly_abort (1);
 
   /* ?? Can this be optimized in some cases to
      hand back the DECL_INITIAL slot??  */
@@ -5892,8 +5807,7 @@ finish_decl (decl, init, asmspec_tree, need_pop)
        {
          if (TREE_CODE (type) == ARRAY_TYPE)
            init = digest_init (type, init, (tree *) 0);
-         else if (TREE_CODE (init) == CONSTRUCTOR
-                  && CONSTRUCTOR_ELTS (init) != NULL_TREE)
+         else if (TREE_CODE (init) == CONSTRUCTOR)
            {
              if (TYPE_NEEDS_CONSTRUCTING (type))
                {
@@ -5951,16 +5865,11 @@ finish_decl (decl, init, asmspec_tree, need_pop)
          if (current_binding_level == global_binding_level)
            {
              tree value;
-             if (flag_conserve_space)
-               /* If we say -fconserve-space, we want this to save
-                  space, at the expense of wrong semantics. */
+             if (DECL_COMMON (decl))
                /* Should this be a NULL_TREE? */
                value = error_mark_node;
              else
-               /* If we say -fno-conserve-space, we want this to
-                  produce errors about redefs, to do this we make it
-                  go in the data space */
-               value = digest_init (type, empty_init_node, (tree *) 0);
+               value = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
              DECL_INITIAL (decl) = value;
            }
          else
@@ -5972,10 +5881,17 @@ finish_decl (decl, init, asmspec_tree, need_pop)
          if (TREE_CODE (init) != TREE_VEC)
            init = store_init_value (decl, init);
 
+         /* Don't let anyone try to initialize this variable
+            until we are ready to do so.  */
          if (init)
-           /* Don't let anyone try to initialize this variable
-              until we are ready to do so.  */
-           DECL_INITIAL (decl) = error_mark_node;
+           {
+             tree value;
+             if (DECL_COMMON (decl))
+               value = error_mark_node;
+             else
+               value = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
+             DECL_INITIAL (decl) = value;
+           }
        }
     }
   else if (DECL_EXTERNAL (decl))
@@ -6002,27 +5918,19 @@ finish_decl (decl, init, asmspec_tree, need_pop)
        cp_error ("uninitialized const `%D'", decl);
 
       /* Initialize variables in need of static initialization with
-        `empty_init_node' to keep assemble_variable from putting them in
-        the wrong program space.  Common storage is okay for non-public
-        uninitialized data; the linker can't match it with storage from
-        other files, and we may save some disk space.  Consts have to go
-        into data, though, since the backend would put them in text
-        otherwise.  */
+        an empty CONSTRUCTOR to keep assemble_variable from putting them in
+        the wrong program space.  */
       if (flag_pic == 0
          && TREE_STATIC (decl)
-         && (TREE_PUBLIC (decl) || was_readonly)
+         && TREE_PUBLIC (decl)
          && ! DECL_EXTERNAL (decl)
          && TREE_CODE (decl) == VAR_DECL
          && TYPE_NEEDS_CONSTRUCTING (type)
          && (DECL_INITIAL (decl) == NULL_TREE
              || DECL_INITIAL (decl) == error_mark_node)
-         /* If we say -fconserve-space, we want this to save space,
-            at the expense of wrong semantics. */
-         && ! flag_conserve_space)
-       {
-         tree value = digest_init (type, empty_init_node, (tree *) 0);
-         DECL_INITIAL (decl) = value;
-       }
+         && ! DECL_COMMON (decl))
+       DECL_INITIAL (decl) = build (CONSTRUCTOR, type, NULL_TREE,
+                                    NULL_TREE);
     }
   else if (TREE_CODE (decl) == VAR_DECL
           && TREE_CODE (type) != REFERENCE_TYPE
@@ -6182,7 +6090,7 @@ finish_decl (decl, init, asmspec_tree, need_pop)
               && TREE_READONLY (decl)
               && DECL_INITIAL (decl) != NULL_TREE
               && DECL_INITIAL (decl) != error_mark_node
-              && DECL_INITIAL (decl) != empty_init_node)
+              && ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl)))
        {
          DECL_INITIAL (decl) = save_expr (DECL_INITIAL (decl));
 
@@ -6889,9 +6797,8 @@ grokvardecl (type, declarator, specbits, initialized)
          if (initialized && DECL_INITIAL (decl)
              /* Complain about multiply-initialized
                 member variables, but don't be faked
-                out if initializer is faked up from `empty_init_node'.  */
-             && (TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR
-                 || CONSTRUCTOR_ELTS (DECL_INITIAL (decl)) != NULL_TREE))
+                out if initializer is empty.  */
+             && ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl)))
            error_with_aggr_type (DECL_CONTEXT (decl),
                                  "multiple initializations of static member `%s::%s'",
                                  IDENTIFIER_POINTER (DECL_NAME (decl)));
@@ -7358,44 +7265,19 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
 
       if (TREE_CODE (id) == IDENTIFIER_NODE)
        {
-         if (id == ridpointers[(int) RID_INT])
-           {
-             if (type)
-               error ("extraneous `int' ignored");
-             else
-               {
-                 explicit_int = 1;
-                 type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id));
-               }
-             goto found;
-           }
-         if (id == ridpointers[(int) RID_CHAR])
-           {
-             if (type)
-               error ("extraneous `char' ignored");
-             else
-               {
-                 explicit_char = 1;
-                 type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id));
-               }
-             goto found;
-           }
-         if (id == ridpointers[(int) RID_BOOL])
-           {
-             if (type)
-               error ("extraneous `bool' ignored");
-             else
-               {
-                 type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id));
-               }
-             goto found;
-           }
-         if (id == ridpointers[(int) RID_WCHAR])
+         if (id == ridpointers[(int) RID_INT]
+             || id == ridpointers[(int) RID_CHAR]
+             || id == ridpointers[(int) RID_BOOL]
+             || id == ridpointers[(int) RID_WCHAR])
            {
              if (type)
-               error ("extraneous `__wchar_t' ignored");
+               error ("extraneous `%T' ignored", id);
              else
                {
+                 if (id == ridpointers[(int) RID_INT])
+                   explicit_int = 1;
+                 else if (id == ridpointers[(int) RID_CHAR])
+                   explicit_char = 1;
                  type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id));
                }
              goto found;
@@ -7459,6 +7341,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
      which case the type defaults to `unknown type' and is
      instantiated when assigning to a signature pointer or ref.  */
 
+  if (type == NULL_TREE
+      && (RIDBIT_SETP (RID_SIGNED, specbits)
+         || RIDBIT_SETP (RID_UNSIGNED, specbits)
+         || RIDBIT_SETP (RID_LONG, specbits)
+         || RIDBIT_SETP (RID_SHORT, specbits)))
+    {
+      /* These imply 'int'.  */
+      type = integer_type_node;
+      explicit_int = 1;
+    }
+
   if (type == NULL_TREE)
     {
       explicit_int = -1;
@@ -7478,22 +7371,21 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
          opaque_typedef = 1;
          type = copy_node (opaque_type_node);
        }
+      /* access declaration */
+      else if (decl_context == FIELD && declarator
+              && TREE_CODE (declarator) == SCOPE_REF)
+       type = void_type_node;
       else
        {
          if (funcdef_flag)
            {
              if (warn_return_type
-                 && return_type == return_normal
-                 && ! (RIDBIT_SETP (RID_SIGNED, specbits)
-                       || RIDBIT_SETP (RID_UNSIGNED, specbits)
-                       || RIDBIT_SETP (RID_LONG, specbits)
-                       || RIDBIT_SETP (RID_SHORT, specbits)))
+                 && return_type == return_normal)
                /* Save warning until we know what is really going on.  */
                warn_about_return_type = 1;
            }
-         else if (decl_context == FIELD && declarator
-                  && TREE_CODE (declarator) == SCOPE_REF)
-           /* OK -- access declaration */;
+         else if (RIDBIT_SETP (RID_TYPEDEF, specbits))
+           pedwarn ("ANSI C++ forbids typedef which does not specify a type");
          else if (declspecs == NULL_TREE &&
                   (innermost_code != CALL_EXPR || pedantic))
            cp_pedwarn ("ANSI C++ forbids declaration `%D' with no type or storage class",
@@ -7522,6 +7414,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
 
       type = ctor_return_type;
     }
+  /* Catch typedefs that only specify a type, like 'typedef int;'.  */
+  else if (RIDBIT_SETP (RID_TYPEDEF, specbits) && declarator == NULL_TREE)
+    {
+      /* Template "this is a type" syntax; just ignore for now.  */
+      if (processing_template_defn)
+       return void_type_node;
+    }
 
   ctype = NULL_TREE;
 
@@ -8481,16 +8380,16 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
                                                      TREE_TYPE (type), TYPE_ARG_TYPES (type));
                    else
                      {
-                       error ("cannot declare member function `%s::%s' within this class",
-                              TYPE_NAME_STRING (ctype), name);
+                       cp_error ("cannot declare member function `%T::%D' within `%T'",
+                                 ctype, name, current_class_type);
                        return void_type_node;
                      }
                  }
                else if (TYPE_MAIN_VARIANT (ctype) == current_class_type)
                  {
                    if (extra_warnings)
-                     warning ("extra qualification `%s' on member `%s' ignored",
-                              TYPE_NAME_STRING (ctype), name);
+                     cp_warning ("redundant qualification `%T' on member `%D' ignored",
+                                 ctype, name);
                    type = build_offset_type (ctype, type);
                  }
                else if (TYPE_SIZE (ctype) != NULL_TREE
@@ -8659,7 +8558,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
       if (TREE_CODE (type) == OFFSET_TYPE || TREE_CODE (type) == METHOD_TYPE)
        {
          cp_error_at ("typedef name may not be class-qualified", decl);
-         TREE_TYPE (decl) = error_mark_node;
+         return NULL_TREE;
        }
       else if (quals)
        {
@@ -10773,6 +10672,19 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
      (This does not mean `static' in the C sense!)  */
   TREE_STATIC (decl1) = 1;
 
+  /* Record the decl so that the function name is defined.
+     If we already have a decl for this name, and it is a FUNCTION_DECL,
+     use the old decl.  */
+
+  if (pre_parsed_p == 0)
+    {
+      current_function_decl = decl1 = pushdecl (decl1);
+      DECL_MAIN_VARIANT (decl1) = decl1;
+      fntype = TREE_TYPE (decl1);
+    }
+  else
+    current_function_decl = decl1;
+
   /* If this function belongs to an interface, it is public.
      If it belongs to someone else's interface, it is also external.
      It doesn't matter whether it's inline or not.  */
@@ -10800,19 +10712,6 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
 #endif
     }
 
-  /* Record the decl so that the function name is defined.
-     If we already have a decl for this name, and it is a FUNCTION_DECL,
-     use the old decl.  */
-
-  if (pre_parsed_p == 0)
-    {
-      current_function_decl = decl1 = pushdecl (decl1);
-      DECL_MAIN_VARIANT (decl1) = decl1;
-      fntype = TREE_TYPE (decl1);
-    }
-  else
-    current_function_decl = decl1;
-
   if (ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1))
     {
       if (TREE_CODE (fntype) == METHOD_TYPE)
index 964615e..35d408b 100644 (file)
@@ -215,7 +215,7 @@ int warn_extern_inline;
 #endif
 int dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
 
-/* Nonzero for -no-strict-prototype switch: do not consider empty
+/* Nonzero for -fno-strict-prototype switch: do not consider empty
    argument prototype to mean function takes no arguments.  */
 
 int strict_prototype = 1;
index 084eebd..5e5d580 100644 (file)
@@ -1117,13 +1117,7 @@ expand_aggr_init (exp, init, alias_this)
       int was_const_elts = TYPE_READONLY (TREE_TYPE (type));
       tree itype = init ? TREE_TYPE (init) : NULL_TREE;
       if (was_const_elts)
-       {
-         tree atype = build_cplus_array_type (TYPE_MAIN_VARIANT (TREE_TYPE (type)),
-                                              TYPE_DOMAIN (type));
-         if (init && (TREE_TYPE (exp) == TREE_TYPE (init)))
-           TREE_TYPE (init) = atype;
-         TREE_TYPE (exp) = atype;
-       }
+       TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
       if (init && TREE_TYPE (init) == NULL_TREE)
        {
          /* Handle bad initializers like:
@@ -2613,40 +2607,9 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
      enum overload_flags flags;
      tree quals;
 {
-  /* first, lets find out if what we are making a friend needs overloading */
-  tree previous_decl;
-  int was_c_linkage = 0;
-
   /* Every decl that gets here is a friend of something.  */
   DECL_FRIEND_P (decl) = 1;
 
-  /* If we find something in scope, let see if it has extern "C" linkage.  */
-  /* This code is pretty general and should be ripped out and reused
-     as a separate function. */
-  if (DECL_NAME (decl))
-    {
-      previous_decl = lookup_name (DECL_NAME (decl), 0);
-      if (previous_decl && TREE_CODE (previous_decl) == TREE_LIST)
-       {
-         do
-           {
-             if (TREE_TYPE (TREE_VALUE (previous_decl)) == TREE_TYPE (decl))
-               {
-                 previous_decl = TREE_VALUE (previous_decl);
-                 break;
-               }
-             previous_decl = TREE_CHAIN (previous_decl);
-           }
-         while (previous_decl);
-       }
-
-      /* It had extern "C" linkage, so don't overload this.  */
-      if (previous_decl && TREE_CODE (previous_decl) == FUNCTION_DECL
-         && TREE_TYPE (decl) == TREE_TYPE (previous_decl)
-         && DECL_LANGUAGE (previous_decl) == lang_c)
-       was_c_linkage = 1;
-    }
-         
   if (ctype)
     {
       tree cname = TYPE_NAME (ctype);
@@ -2711,7 +2674,6 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
          decl = void_type_node;
        }
     }
-  /* never overload C functions */
   else if (TREE_CODE (decl) == FUNCTION_DECL
           && ((IDENTIFIER_LENGTH (declarator) == 4
                && IDENTIFIER_POINTER (declarator)[0] == 'm'
@@ -2720,8 +2682,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
                   && IDENTIFIER_POINTER (declarator)[0] == '_'
                   && IDENTIFIER_POINTER (declarator)[1] == '_'
                   && strncmp (IDENTIFIER_POINTER (declarator)+2,
-                              "builtin_", 8) == 0)
-              || was_c_linkage))
+                              "builtin_", 8) == 0)))
     {
       /* raw "main", and builtin functions never gets overloaded,
         but they can become friends.  */
index 79d37f7..827ee35 100644 (file)
@@ -2377,6 +2377,9 @@ do_function_instantiation (declspecs, declarator, storage)
   if (flag_external_templates)
     return;
 
+  if (DECL_EXPLICIT_INSTANTIATION (result) && ! DECL_EXTERNAL (result))
+    return;
+
   SET_DECL_EXPLICIT_INSTANTIATION (result);
   TREE_PUBLIC (result) = 1;
 
@@ -2399,6 +2402,9 @@ do_type_instantiation (name, storage)
   if (flag_external_templates)
     return;
 
+  if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && ! CLASSTYPE_INTERFACE_ONLY (t))
+    return;
+
   if (TYPE_SIZE (t) == NULL_TREE)
     {
       cp_error ("explicit instantiation of `%#T' before definition of template",
index 5805d36..832d965 100644 (file)
@@ -74,12 +74,6 @@ lvalue_p (ref)
        case WITH_CLEANUP_EXPR:
          return 1;
 
-       case CALL_EXPR:
-         /* unary_complex_lvalue knows how to deal with this case.  */
-         if (TREE_ADDRESSABLE (TREE_TYPE (ref)))
-           return 1;
-         break;
-
          /* A currently unresolved scope ref.  */
        case SCOPE_REF:
          my_friendly_abort (103);
index 746bcd8..840abe6 100644 (file)
@@ -5336,6 +5336,7 @@ build_modify_expr (lhs, modifycode, rhs)
   tree newrhs = rhs;
   tree lhstype = TREE_TYPE (lhs);
   tree olhstype = lhstype;
+  tree olhs = lhs;
 
   /* Types that aren't fully specified cannot be used in assignments.  */
   lhs = require_complete_type (lhs);
@@ -5933,7 +5934,11 @@ build_modify_expr (lhs, modifycode, rhs)
      for enum bit fields. */
   if (TREE_CODE (TREE_TYPE (result)) == INTEGER_TYPE
       && TREE_CODE (olhstype) == ENUMERAL_TYPE)
-    return convert_force (olhstype, result);
+    {
+      result = build (COMPOUND_EXPR, olhstype, result, olhs);
+      TREE_NO_UNUSED_WARNING (result) = 1;
+      return result;
+    }
   return convert_for_assignment (olhstype, result, "assignment",
                                 NULL_TREE, 0);
 }
index 2fe6040..df76845 100644 (file)
@@ -844,7 +844,6 @@ static tree
 process_init_constructor (type, init, elts)
      tree type, init, *elts;
 {
-  extern tree empty_init_node;
   register tree tail;
   /* List of the elements of the result constructor,
      in reverse order.  */
@@ -917,7 +916,7 @@ process_init_constructor (type, init, elts)
          members = tree_cons (NULL_TREE, next1, members);
        }
     }
-  if (TREE_CODE (type) == RECORD_TYPE && init != empty_init_node)
+  if (TREE_CODE (type) == RECORD_TYPE)
     {
       register tree field;
 
@@ -1010,7 +1009,7 @@ process_init_constructor (type, init, elts)
        }
     }
 
-  if (TREE_CODE (type) == UNION_TYPE && init != empty_init_node)
+  if (TREE_CODE (type) == UNION_TYPE)
     {
       register tree field = TYPE_FIELDS (type);
       register tree next1;
@@ -1438,7 +1437,7 @@ build_functional_cast (exp, parms)
     return error_mark_node;
 
   if (current_function_decl)
-    return build_cplus_new (type, expr_as_ctor, 0);
+    return build_cplus_new (type, expr_as_ctor, 1);
 
   {
     register tree parm = TREE_OPERAND (expr_as_ctor, 1);