OSDN Git Service

81st Cygnus<->FSF merge
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Feb 1996 22:43:25 +0000 (22:43 +0000)
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Feb 1996 22:43:25 +0000 (22:43 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@11187 138bc75d-0d04-0410-961f-82ee72b054a4

14 files changed:
gcc/cp/ChangeLog
gcc/cp/Makefile.in
gcc/cp/class.c
gcc/cp/cp-tree.def
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/error.c
gcc/cp/init.c
gcc/cp/lex.c
gcc/cp/parse.y
gcc/cp/tree.c
gcc/cp/typeck.c

index b745716..72617e0 100644 (file)
@@ -1,3 +1,92 @@
+Thu Feb  8 15:15:14 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * decl.c (grokfndecl): Move code that looks for virtuals in base
+       classes...
+       * class.c (fixup_virtual): ... to a new function.
+       (finish_struct_1): Call it.
+
+       * cp-tree.h: Declare warn_sign_compare.
+
+       * typeck.c (build_binary_op_nodefault): Check warn_sign_compare
+        rather than extra_warnings to decide whether to warn about
+        comparison of signed and unsigned.
+
+       * decl2.c (lang_decode_option): Handle warn_sign_compare.  -Wall
+        implies -Wsign-compare.  -Wall doesn't imply -W.
+
+Wed Feb  7 15:27:57 1996  Mike Stump  <mrs@cygnus.com>
+
+       * typeck.c (build_component_ref): Fix to handle anon unions in base
+       classes as well.
+
+Wed Feb  7 14:29:12 1996  Brendan Kehoe  <brendan@lisa.cygnus.com>
+
+       * class.c (resolves_to_fixed_type_p): Delete code dealing with
+       a WITH_CLEANUP_EXPR, since we don't generate them any more.
+       * cvt.c (build_up_reference): Likewise.
+       * decl.c (grok_reference_init): Likewise.
+       (cp_finish_decl): Likewise.
+       * error.c (dump_expr): Likewise.
+       * tree.c (real_lvalue_p): Likewise.
+       (lvalue_p): Likewise.
+       (build_cplus_new): Likewise.
+       (unsave_expr_now): Likewise.
+       * typeck.c (unary_complex_lvalue, build_modify_expr,
+       c_expand_return): Likewise.
+
+Tue Feb  6 13:39:22 1996  Brendan Kehoe  <brendan@lisa.cygnus.com>
+
+       Make the C++ front-end pay attention to attributes for structures.
+       * class.c (finish_struct): New argument ATTRIBUTES, passed down into
+       finish_struct_1.
+       (finish_struct_1): New argument ATTRIBUTES; call cplus_decl_attributes.
+       Take out old round_up_size use and setting the DECL_ALIGN possibly
+       using it.  Take out setting of TYPE_ALIGN to round_up_size, which
+       can override what the attribute set.
+       * cp-tree.h (finish_struct): Update prototype.
+       * parse.y (template_instantiate_once): Pass a NULL_TREE for the
+       attributes to finish_struct.
+       (structsp): For a CLASS decl, add maybe_attribute to rule and pass that
+       value down into finish_struct.
+       * Makefile.in (CONFLICTS): Switch to 7 shift/reduce conflicts.
+
+Tue Feb  6 13:12:15 1996  Per Bothner  <bothner@kalessin.cygnus.com>
+
+       * decl.c (poplevel):  Re-word dead for local handling.
+       (pushdecl):  Remove useless DECL_DEAD_FOR_LOCAL test.
+       (cp_finish_decl):  If is_for_scope, check for duplicates so
+       we can disable is_for_scope.  Otherwise, preserve_temp_slots.
+
+       * lex.c (do_identifier):  Use global binding in preference of
+       dead for local variable.
+
+Mon Feb  5 17:46:46 1996  Mike Stump  <mrs@cygnus.com>
+
+       * init.c (initializing_context): Handle anon union changes, the
+       context where fields of anon unions can be initialized now has to be
+       found by walking up the TYPE_CONTEXT chain.
+
+Fri Feb  2 14:54:04 1996  Doug Evans  <dje@charmed.cygnus.com>
+
+       * decl.c (start_decl): #ifdef out code to set DECL_COMMON
+       if ASM_OUTPUT{,_ALIGNED}_BSS is defined.
+       (obscure_complex_init): If bss is supported, always set
+       DECL_INITIAL to error_mark_node.
+
+Thu Feb  1 16:19:56 1996  Brendan Kehoe  <brendan@lisa.cygnus.com>
+
+       * init.c (is_friend): Make sure there's a context before we see if
+       it's an aggr type.
+
+Thu Feb  1 15:44:53 1996  Mike Stump  <mrs@cygnus.com>
+
+       * init.c (is_friend): Classes are not friendly with nested classes.
+
+Thu Feb  1 15:27:37 1996  Doug Evans  <dje@charmed.cygnus.com>
+
+       * lex.c (check_newline): Pass last character read to HANDLE_PRAGMA,
+       and record its result.
+
 Thu Feb  1 09:27:01 1996  Mike Stump  <mrs@cygnus.com>
 
        * class.c (finish_struct_anon): Switch around code to not move anon
@@ -10187,9 +10276,3 @@ Mon Nov  8 13:50:49 1993  Jason Merrill  (jason@deneb.cygnus.com)
 Tue Sep  7 20:03:33 1993  Jason Merrill  (jason@deneb.cygnus.com)
 
        * cp-decl.c: Allow references and template type parameters as well
-
-Local Variables:
-eval: (auto-fill-mode)
-left-margin: 8
-fill-column: 76
-End:
index 7ba077e..8bfbb12 100644 (file)
@@ -196,7 +196,7 @@ parse.o : $(PARSE_C) $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h
        $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \
   `echo $(PARSE_C) | sed 's,^\./,,'`
 
-CONFLICTS = expect 5 shift/reduce conflicts and 38 reduce/reduce conflicts.
+CONFLICTS = expect 7 shift/reduce conflicts and 38 reduce/reduce conflicts.
 $(PARSE_H) : $(PARSE_C)
 $(PARSE_C) : $(srcdir)/parse.y
        @echo $(CONFLICTS)
index 929e5b1..a5c8f38 100644 (file)
@@ -2753,6 +2753,77 @@ mark_overriders (fndecl, base_fndecls)
     }
 }
 
+/* If this declaration supersedes the declaration of
+   a method declared virtual in the base class, then
+   mark this field as being virtual as well.  */
+
+void
+fixup_virtual (decl, ctype)
+     tree decl, ctype;
+{
+  tree binfos = BINFO_BASETYPES (TYPE_BINFO (ctype));
+  int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
+  int virtualp = DECL_VIRTUAL_P (decl);
+
+  for (i = 0; i < n_baselinks; i++)
+    {
+      tree base_binfo = TREE_VEC_ELT (binfos, i);
+      if (TYPE_VIRTUAL_P (BINFO_TYPE (base_binfo))
+         || flag_all_virtual == 1)
+       {
+         tree tmp = get_matching_virtual
+           (base_binfo, decl,
+            DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)));
+         if (tmp)
+           {
+             /* If this function overrides some virtual in some base
+                class, then the function itself is also necessarily
+                virtual, even if the user didn't explicitly say so.  */
+             DECL_VIRTUAL_P (decl) = 1;
+
+             /* The TMP we really want is the one from the deepest
+                baseclass on this path, taking care not to
+                duplicate if we have already found it (via another
+                path to its virtual baseclass.  */
+             if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE)
+               {
+                 cp_error_at ("method `%D' may not be declared static",
+                              decl);
+                 cp_error_at ("(since `%D' declared virtual in base class.)",
+                              tmp);
+                 break;
+               }
+             virtualp = 1;
+
+             {
+               /* The argument types may have changed... */
+               tree type = TREE_TYPE (decl);
+               tree argtypes = TYPE_ARG_TYPES (type);
+               tree base_variant = TREE_TYPE (TREE_VALUE (argtypes));
+               tree raises = TYPE_RAISES_EXCEPTIONS (type);
+
+               argtypes = commonparms (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (tmp))),
+                                       TREE_CHAIN (argtypes));
+               /* But the return type has not.  */
+               type = build_cplus_method_type (base_variant, TREE_TYPE (type), argtypes);
+               if (raises)
+                 type = build_exception_variant (type, raises);
+               TREE_TYPE (decl) = type;
+               DECL_VINDEX (decl)
+                 = tree_cons (NULL_TREE, tmp, DECL_VINDEX (decl));
+             }
+             break;
+           }
+       }
+    }
+  if (virtualp)
+    {
+      if (DECL_VINDEX (decl) == NULL_TREE)
+       DECL_VINDEX (decl) = error_mark_node;
+      IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
+    }
+}
+
 /* Warn about hidden virtual functions that are not overridden in t.  */
 void
 warn_hidden (t)
@@ -2889,6 +2960,8 @@ extern int interface_only, interface_unknown;
    TREE_LIST elements, whose TREE_PURPOSE field tells what access
    the list has, and the TREE_VALUE slot gives the actual fields.
 
+   ATTRIBUTES is the set of decl attributes to be applied, if any.
+
    If flag_all_virtual == 1, then we lay all functions into
    the virtual function table, as though they were declared
    virtual.  Constructors do not lay down in the virtual function table.
@@ -2920,13 +2993,11 @@ extern int interface_only, interface_unknown;
    or otherwise in a type-consistent manner.  */
 
 tree
-finish_struct_1 (t, warn_anon)
-     tree t;
+finish_struct_1 (t, attributes, warn_anon)
+     tree t, attributes;
      int warn_anon;
 {
   int old;
-  int round_up_size = 1;
-
   tree name = TYPE_IDENTIFIER (t);
   enum tree_code code = TREE_CODE (t);
   tree fields = TYPE_FIELDS (t);
@@ -2986,6 +3057,8 @@ finish_struct_1 (t, warn_anon)
   TYPE_SIZE (t) = NULL_TREE;
   CLASSTYPE_GOT_SEMICOLON (t) = 0;
 
+  cplus_decl_attributes (t, attributes, NULL_TREE);
+
 #if 0
   /* This is in general too late to do this.  I moved the main case up to
      left_curly, what else needs to move?  */
@@ -3104,6 +3177,8 @@ finish_struct_1 (t, warn_anon)
       DECL_SAVED_INSNS (x) = NULL_RTX;
       DECL_FIELD_SIZE (x) = 0;
 
+      fixup_virtual (x, t);
+
       /* The name of the field is the original field name
         Save this in auxiliary field for later overloading.  */
       if (DECL_VINDEX (x)
@@ -3329,13 +3404,7 @@ finish_struct_1 (t, warn_anon)
              if (width == 0)
                {
 #ifdef EMPTY_FIELD_BOUNDARY
-                 /* field size 0 => mark following field as "aligned" */
-                 if (TREE_CHAIN (x))
-                   DECL_ALIGN (TREE_CHAIN (x))
-                     = MAX (DECL_ALIGN (TREE_CHAIN (x)), EMPTY_FIELD_BOUNDARY);
-                 /* field of size 0 at the end => round up the size.  */
-                 else
-                   round_up_size = EMPTY_FIELD_BOUNDARY;
+                 DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY);
 #endif
 #ifdef PCC_BITFIELD_TYPE_MATTERS
                  DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
@@ -3716,10 +3785,6 @@ finish_struct_1 (t, warn_anon)
 
   TYPE_FIELDS (t) = fields;
 
-  /* If there's a :0 field at the end, round the size to the
-     EMPTY_FIELD_BOUNDARY.  */
-  TYPE_ALIGN (t) = round_up_size;
-
   /* Pass layout information about base classes to layout_type, if any.  */
   if (n_baseclasses)
     {
@@ -4168,9 +4233,8 @@ finish_struct_1 (t, warn_anon)
 }
 
 tree
-finish_struct (t, list_of_fieldlists, warn_anon)
-     tree t;
-     tree list_of_fieldlists;
+finish_struct (t, list_of_fieldlists, attributes, warn_anon)
+     tree t, list_of_fieldlists, attributes;
      int warn_anon;
 {
   tree fields = NULL_TREE;
@@ -4301,7 +4365,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
       return t;
     }
   else
-    return finish_struct_1 (t, warn_anon);
+    return finish_struct_1 (t, attributes, warn_anon);
 }
 \f
 /* Return non-zero if the effective type of INSTANCE is static.
@@ -4374,10 +4438,6 @@ resolves_to_fixed_type_p (instance, nonnull)
     case COMPONENT_REF:
       return resolves_to_fixed_type_p (TREE_OPERAND (instance, 1), nonnull);
 
-    case WITH_CLEANUP_EXPR:
-      if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR)
-       return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull);
-      /* fall through... */
     case VAR_DECL:
     case FIELD_DECL:
       if (TREE_CODE (TREE_TYPE (instance)) == ARRAY_TYPE
index 82b7954..fabc3e1 100644 (file)
@@ -37,7 +37,7 @@ DEFTREECODE (VEC_DELETE_EXPR, "vec_dl_expr", "e", 2)
 
 /* For a UNSAVE_EXPR, operand 0 is the value to unsave.  By unsave, we
    mean that all _EXPRs such as TARGET_EXPRs, SAVE_EXPRs,
-   WITH_CLEANUP_EXPRs, CALL_EXPRs and RTL_EXPRs, that are protected
+   CALL_EXPRs and RTL_EXPRs, that are protected
    from being evaluated more than once should be reset so that a new
    expand_expr call of this expr will cause those to be re-evaluated.
    This is useful when we want to reuse a tree in different places,
index e9b4a28..05f12b9 100644 (file)
@@ -219,6 +219,10 @@ extern int warn_redundant_decls;
 
 extern int warn_missing_braces;
 
+/* Warn about comparison of signed and unsigned values.  */
+
+extern int warn_sign_compare;
+
 /* Warn about a subscript that has type char.  */
 
 extern int warn_char_subscripts;
@@ -1061,7 +1065,7 @@ struct lang_decl
 #endif
 
 /* In a VAR_DECL for a variable declared in a for statement,
-   this is the shadowed variable. */
+   this is the shadowed (local) variable. */
 #define DECL_SHADOWED_FOR_VAR(NODE) DECL_RESULT(NODE)
 
 /* Points back to the decl which caused this lang_decl to be allocated.  */
@@ -1936,7 +1940,7 @@ extern tree build_vfn_ref                 PROTO((tree *, tree, tree));
 extern void add_method                         PROTO((tree, tree *, tree));
 extern tree get_vfield_offset                  PROTO((tree));
 extern void duplicate_tag_error                        PROTO((tree));
-extern tree finish_struct                      PROTO((tree, tree, int));
+extern tree finish_struct                      PROTO((tree, tree, tree, int));
 extern int resolves_to_fixed_type_p            PROTO((tree, int *));
 extern void init_class_processing              PROTO((void));
 extern void pushclass                          PROTO((tree, int));
index f793bce..b45823d 100644 (file)
@@ -565,12 +565,6 @@ build_up_reference (type, arg, flags, checkconst)
                    build_up_reference (type, TREE_OPERAND (targ, 1),
                                        LOOKUP_PROTECT, checkconst));
 
-    case WITH_CLEANUP_EXPR:
-      return build (WITH_CLEANUP_EXPR, type,
-                   build_up_reference (type, TREE_OPERAND (targ, 0),
-                                       LOOKUP_PROTECT, checkconst),
-                   0, TREE_OPERAND (targ, 2));
-
     case BIND_EXPR:
       arg = TREE_OPERAND (targ, 1);
       if (arg == NULL_TREE)
@@ -593,12 +587,7 @@ build_up_reference (type, arg, flags, checkconst)
       if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (argtype))
        {
          temp = build_cplus_new (argtype, targ, 1);
-         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);
+         rval = build1 (ADDR_EXPR, type, temp);
          goto done;
        }
       else if (flags&INDIRECT_BIND)
index 8becd0f..f3f16f8 100644 (file)
@@ -580,7 +580,8 @@ struct binding_level
     /* This is set for a namespace binding level.  */
     unsigned namespace_p : 1;
 
-    /* True if this level is that of a for-statement. */
+    /* True if this level is that of a for-statement where we need to
+       worry about ambiguous (traditional or ANSI) scope rules. */
     unsigned is_for_scope : 1;
 
     /* One bit left for this word.  */
@@ -1086,26 +1087,31 @@ poplevel (keep, reverse, functionbody)
 
   /* Clear out the meanings of the local variables of this level.  */
 
-  for (link = current_binding_level->dead_vars_from_for;
-       link != NULL_TREE; link = TREE_CHAIN (link))
-    {
-      if (DECL_DEAD_FOR_LOCAL (link))
-       {
-         tree id = DECL_NAME (link);
-         if (IDENTIFIER_LOCAL_VALUE (id) == link)
-           IDENTIFIER_LOCAL_VALUE (id) = DECL_SHADOWED_FOR_VAR (link);
-       }
-    }
-
   if (current_binding_level->is_for_scope && flag_new_for_scope == 1)
     {
+      struct binding_level *outer = current_binding_level->level_chain;
       for (link = decls; link; link = TREE_CHAIN (link))
        {
          if (TREE_CODE (link) == VAR_DECL)
            DECL_DEAD_FOR_LOCAL (link) = 1;
        }
+
+      /* Save declarations made in a 'for' statement so we can support pre-ANSI
+        'for' scoping semantics. */
+
+      for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link))
+       {
+         tree id = TREE_PURPOSE (link);
+         tree decl = IDENTIFIER_LOCAL_VALUE (id);
+
+         /* In this case keep the dead for-decl visible,
+            but remember what (if anything) it shadowed. */
+         DECL_SHADOWED_FOR_VAR (decl) = TREE_VALUE (link);
+         TREE_CHAIN (decl) = outer->dead_vars_from_for;
+         outer->dead_vars_from_for = decl;
+       }
     }
-  else
+  else /* Not special for scope. */
     {
       for (link = decls; link; link = TREE_CHAIN (link))
        {
@@ -1123,50 +1129,42 @@ poplevel (keep, reverse, functionbody)
              IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = NULL_TREE;
            }
        }
-    }
 
-  /* Restore all name-meanings of the outer levels
-     that were shadowed by this level.  */
+      /* Restore all name-meanings of the outer levels
+        that were shadowed by this level.  */
 
-  if (current_binding_level->is_for_scope && flag_new_for_scope == 1)
-    {
-      struct binding_level *outer = current_binding_level->level_chain;
-      for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link))
+      for (link = current_binding_level->shadowed;
+          link; link = TREE_CHAIN (link))
+       IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
+
+      /* We first restore the regular decls and *then* the dead_vars_from_for
+        to handle this case:
+
+        int i; // i#1
+        {
+          for (int i; ; ) { ...} // i#2
+           int i; // i#3
+        } // we are here
+
+        In this case, we want remove the binding for i#3, restoring
+        that of i#2.  Then we want to remove the binding for i#2,
+        and restore that of i#1. */
+
+      link = current_binding_level->dead_vars_from_for;
+      for (; link != NULL_TREE; link = TREE_CHAIN (link))
        {
-         tree id = TREE_PURPOSE (link);
-         tree decl = IDENTIFIER_LOCAL_VALUE (id);
-         if (DECL_DEAD_FOR_LOCAL (decl))
-           DECL_SHADOWED_FOR_VAR (decl) = TREE_VALUE (link);
-         else
-           IDENTIFIER_LOCAL_VALUE (id) = TREE_VALUE (link);
+         tree id = DECL_NAME (link);
+         if (IDENTIFIER_LOCAL_VALUE (id) == link)
+           IDENTIFIER_LOCAL_VALUE (id) = DECL_SHADOWED_FOR_VAR (link);
        }
 
-      /* Save declarations made in a 'for' statement so we can support pre-ANSI
-        'for' scoping semantics. */
-
-      /* We append the current names of for-variables to those from previous
-        declarations, so that when we get around to do an poplevel
-        on the OUTER level, we restore the any shadowed readl bindings.
-        Note that the new names are put first on the combined list,
-        so they get to be restored first.  This is important if there are
-        two for-loops using the same for-variable in the same block.
-        The binding we really want restored is whatever binding was shadowed
-        by the *first* for-variable, not the binding shadowed by the
-        second for-variable (which would be the first for-variable). */
-      outer->dead_vars_from_for
-       = chainon (current_binding_level->names, outer->dead_vars_from_for);
-    }
-  else
-    {
-      for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link))
-       IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
+      for (link = current_binding_level->class_shadowed;
+          link; link = TREE_CHAIN (link))
+       IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
+      for (link = current_binding_level->type_shadowed;
+          link; link = TREE_CHAIN (link))
+       IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
     }
-  for (link = current_binding_level->class_shadowed;
-       link; link = TREE_CHAIN (link))
-    IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
-  for (link = current_binding_level->type_shadowed;
-       link; link = TREE_CHAIN (link))
-    IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
 
   /* If the level being exited is the top level of a function,
      check over all the labels.  */
@@ -3003,9 +3001,7 @@ pushdecl (x)
        {
          file = DECL_SOURCE_FILE (t);
          line = DECL_SOURCE_LINE (t);
-         if (TREE_CODE (x) == VAR_DECL && DECL_DEAD_FOR_LOCAL (x))
-           ; /* This is OK. */
-         else if (TREE_CODE (t) == PARM_DECL)
+         if (TREE_CODE (t) == PARM_DECL)
            {
              if (DECL_CONTEXT (t) == NULL_TREE)
                fatal ("parse errors have confused me too much");
@@ -5821,7 +5817,8 @@ start_decl (declarator, declspecs, initialized, raises)
     tem = decl;
   else
     tem = pushdecl (decl);
-            
+
+#if ! defined (ASM_OUTPUT_BSS) && ! defined (ASM_OUTPUT_ALIGNED_BSS)
   /* 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
@@ -5830,6 +5827,7 @@ start_decl (declarator, declspecs, initialized, raises)
      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);
+#endif
 
   if (TREE_CODE (decl) == TEMPLATE_DECL)
     {
@@ -5957,23 +5955,15 @@ grok_reference_init (decl, type, init, cleanupp)
         don't get burned by "aggressive" cleanup policy.  */
       if (TYPE_NEEDS_DESTRUCTOR (subtype))
        {
-         if (TREE_CODE (init) == WITH_CLEANUP_EXPR)
+         if (TREE_CODE (tmp) == ADDR_EXPR)
+           tmp = TREE_OPERAND (tmp, 0);
+         if (TREE_CODE (tmp) == TARGET_EXPR)
            {
-             *cleanupp = TREE_OPERAND (init, 2);
-             TREE_OPERAND (init, 2) = error_mark_node;
-           }
-         else
-           {
-             if (TREE_CODE (tmp) == ADDR_EXPR)
-               tmp = TREE_OPERAND (tmp, 0);
-             if (TREE_CODE (tmp) == TARGET_EXPR)
-               {
-                 *cleanupp = build_delete
-                   (build_pointer_type (subtype),
-                    build_unary_op (ADDR_EXPR, TREE_OPERAND (tmp, 0), 0),
-                    integer_two_node, LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0);
-                 TREE_OPERAND (tmp, 2) = error_mark_node;
-               }
+             *cleanupp = build_delete
+               (build_pointer_type (subtype),
+                build_unary_op (ADDR_EXPR, TREE_OPERAND (tmp, 0), 0),
+                integer_two_node, LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0);
+             TREE_OPERAND (tmp, 2) = error_mark_node;
            }
        }
 
@@ -6024,10 +6014,12 @@ obscure_complex_init (decl, init)
        return NULL_TREE;
     }
 
+#if ! defined (ASM_OUTPUT_BSS) && ! defined (ASM_OUTPUT_ALIGNED_BSS)
   if (toplevel_bindings_p () && ! DECL_COMMON (decl))
     DECL_INITIAL (decl) = build (CONSTRUCTOR, TREE_TYPE (decl), NULL_TREE,
                                 NULL_TREE);
   else
+#endif
     DECL_INITIAL (decl) = error_mark_node;
 
   return init;
@@ -6346,18 +6338,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
       if (!DECL_EXTERNAL (decl) && TYPE_NEEDS_DESTRUCTOR (type))
        {
          int yes = suspend_momentary ();
-
-         /* If INIT comes from a functional cast, use the cleanup
-            we built for that.  Otherwise, make our own cleanup.  */
-         if (init && TREE_CODE (init) == WITH_CLEANUP_EXPR
-             && comptypes (TREE_TYPE (decl), TREE_TYPE (init), 1))
-           {
-             cleanup = TREE_OPERAND (init, 2);
-             init = TREE_OPERAND (init, 0);
-             current_binding_level->have_cleanups = 1;
-           }
-         else
-           cleanup = maybe_build_cleanup (decl);
+         cleanup = maybe_build_cleanup (decl);
          resume_momentary (yes);
        }
     }
@@ -6532,6 +6513,52 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
                }
            }
 
+         if (current_binding_level->is_for_scope)
+           {
+             struct binding_level *outer = current_binding_level->level_chain;
+
+             /* Check to see if the same name is already bound at
+                the outer level, either because it was directly declared,
+                or because a dead for-decl got preserved.  In either case,
+                the code would not have been valid under the traditional
+                scope rules, so clear is_for_scope for the
+                current_binding_level.
+
+                Otherwise, we need to preserve the temp slot for decl
+                to last into the outer binding level. */
+
+             int handling_dead_for_vars = 0;
+             tree link = outer->names;
+             for (; ; link = TREE_CHAIN (link))
+               {
+                 if (link == NULL && handling_dead_for_vars == 0)
+                   {
+                     link = outer->dead_vars_from_for;
+                     handling_dead_for_vars = 1;
+                   }
+                 if (link == NULL)
+                   {
+                     if (DECL_RTL (decl) && GET_CODE (DECL_RTL (decl)) == MEM)
+                       preserve_temp_slots (DECL_RTL (decl));
+                     break;
+                   }
+                 if (DECL_NAME (link) == DECL_NAME (decl))
+                   {
+                     if (handling_dead_for_vars)
+                       {
+                         tree shadowing
+                           = purpose_member (DECL_NAME (decl),
+                                             current_binding_level->shadowed);
+                         if (shadowing && TREE_VALUE (shadowing) == link)
+                           TREE_VALUE (shadowing)
+                             = DECL_SHADOWED_FOR_VAR (link);
+                       }
+                     current_binding_level->is_for_scope = 0;
+                     break;
+                   }
+               }
+           }
+
          push_temp_slots ();
          push_temp_slots ();
          target_temp_slot_level = temp_slot_level;
@@ -7027,81 +7054,12 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals,
                                   TREE_VALUE (attrlist));
          make_decl_rtl (decl, NULL_PTR, 1);
        }
-
-      /* If this declaration supersedes the declaration of
-        a method declared virtual in the base class, then
-        mark this field as being virtual as well.  */
-      {
-       tree binfos = BINFO_BASETYPES (TYPE_BINFO (ctype));
-       int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
-
-       for (i = 0; i < n_baselinks; i++)
-         {
-           tree base_binfo = TREE_VEC_ELT (binfos, i);
-           if (TYPE_VIRTUAL_P (BINFO_TYPE (base_binfo))
-               || flag_all_virtual == 1)
-             {
-               tmp = get_matching_virtual (base_binfo, decl,
-                                           flags == DTOR_FLAG);
-               if (tmp)
-                 {
-                   /* If this function overrides some virtual in some base
-                      class, then the function itself is also necessarily
-                      virtual, even if the user didn't explicitly say so.  */
-                   DECL_VIRTUAL_P (decl) = 1;
-
-                   /* The TMP we really want is the one from the deepest
-                      baseclass on this path, taking care not to
-                      duplicate if we have already found it (via another
-                      path to its virtual baseclass.  */
-                   if (staticp)
-                     {
-                       cp_error ("method `%D' may not be declared static",
-                                 decl);
-                       cp_error_at ("(since `%D' declared virtual in base class.)",
-                                    tmp);
-                       break;
-                     }
-                   virtualp = 1;
-
-                   {
-                     /* The argument types may have changed... */
-                     tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
-                     tree base_variant = TREE_TYPE (TREE_VALUE (argtypes));
-
-                     argtypes = commonparms (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (tmp))),
-                                             TREE_CHAIN (argtypes));
-                     /* But the return type has not.  */
-                     type = build_cplus_method_type (base_variant, TREE_TYPE (type), argtypes);
-                     if (raises)
-                       {
-                         type = build_exception_variant (type, raises);
-                         raises = TYPE_RAISES_EXCEPTIONS (type);
-                       }
-                     TREE_TYPE (decl) = type;
-                     DECL_VINDEX (decl)
-                       = tree_cons (NULL_TREE, tmp, DECL_VINDEX (decl));
-                   }
-                   break;
-                 }
-             }
-         }
-      }
       if (virtualp)
        {
+         DECL_VIRTUAL_P (decl) = 1;
          if (DECL_VINDEX (decl) == NULL_TREE)
            DECL_VINDEX (decl) = error_mark_node;
          IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
-         if (ctype && CLASSTYPE_VTABLE_NEEDS_WRITING (ctype)
-             /* If this function is derived from a template, don't
-                make it public.  This shouldn't be here, but there's
-                no good way to override the interface pragmas for one
-                function or class only.  Bletch.  */
-             && IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (ctype)) == NULL_TREE
-             && (write_virtuals == 2
-                 || (write_virtuals == 3
-                     && CLASSTYPE_INTERFACE_KNOWN (ctype))))
-           TREE_PUBLIC (decl) = 1;
        }
     }
   return decl;
index 58cdf5c..b7ce4f0 100644 (file)
@@ -196,6 +196,10 @@ int warn_redundant_decls;
 
 int warn_missing_braces;
 
+/* Warn about comparison of signed and unsigned values.  */
+
+int warn_sign_compare;
+
 /* Warn about *printf or *scanf format/argument anomalies. */
 
 int warn_format;
@@ -541,6 +545,8 @@ lang_decode_option (p)
        warn_redundant_decls = setting;
       else if (!strcmp (p, "missing-braces"))
        warn_missing_braces = setting;
+      else if (!strcmp (p, "sign-compare"))
+       warn_sign_compare = setting;
       else if (!strcmp (p, "format"))
        warn_format = setting;
       else if (!strcmp (p, "conversion"))
@@ -565,7 +571,6 @@ lang_decode_option (p)
        ;                       /* cpp handles this one.  */
       else if (!strcmp (p, "all"))
        {
-         extra_warnings = setting;
          warn_return_type = setting;
          warn_unused = setting;
          warn_implicit = setting;
@@ -574,6 +579,7 @@ lang_decode_option (p)
          warn_format = setting;
          warn_parentheses = setting;
          warn_missing_braces = setting;
+         warn_sign_compare = setting;
          warn_extern_inline = setting;
          warn_nonvdtor = setting;
          /* We save the value of warn_uninitialized, since if they put
index c6653e7..a2d786c 100644 (file)
@@ -1082,12 +1082,6 @@ dump_expr (t, nop)
       }
       break;
 
-    case WITH_CLEANUP_EXPR:
-      /* Note that this only works for G++ cleanups.  If somebody
-        builds a general cleanup, there's no way to represent it.  */
-      dump_expr (TREE_OPERAND (t, 0), 0);
-      break;
-
     case TARGET_EXPR:
       /* Note that this only works for G++ target exprs.  If somebody
         builds a general TARGET_EXPR, there's no way to represent that
index bc0dc51..c5ec252 100644 (file)
@@ -865,6 +865,20 @@ do_member_init (s_id, name, init)
   expand_member_init (build_indirect_ref (base, NULL_PTR), name, init);
 }
 
+/* Find the context in which this FIELD can be initialized.  */
+static tree
+initializing_context (field)
+     tree field;
+{
+  tree t = DECL_CONTEXT (field);
+
+  /* Anonymous union members can be initialized in the first enclosing
+     non-anonymous union context.  */
+  while (t && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
+    t = TYPE_CONTEXT (t);
+  return t;
+}
+
 /* Function to give error message if member initialization specification
    is erroneous.  FIELD is the member we decided to initialize.
    TYPE is the type for which the initialization is being performed.
@@ -880,7 +894,7 @@ member_init_ok_or_else (field, type, member_name)
 {
   if (field == error_mark_node)
     return 0;
-  if (field == NULL_TREE || DECL_CONTEXT (field) != type)
+  if (field == NULL_TREE || initializing_context (field) != type)
     {
       cp_error ("class `%T' does not have any field named `%s'", type,
                member_name);
@@ -2204,7 +2218,14 @@ is_friend (type, supplicant)
     tree context;
 
     if (! declp)
-      context = DECL_CONTEXT (TYPE_NAME (supplicant));
+      {
+       /* Are we a nested or local class?  If so, we aren't friends
+           with the CONTEXT.  */
+       if (IS_AGGR_TYPE (supplicant))
+         context = NULL_TREE;
+       else
+         context = DECL_CONTEXT (TYPE_NAME (supplicant));
+      }
     else if (DECL_FUNCTION_MEMBER_P (supplicant))
       context = DECL_CLASS_CONTEXT (supplicant);
     else
index 8fca04f..7febe10 100644 (file)
@@ -2283,8 +2283,7 @@ check_newline ()
                  tricks.  */
              else
                {
-                 ungetc (c, finput);
-                 HANDLE_PRAGMA (finput);
+                 c = HANDLE_PRAGMA (finput, c);
                }
 #endif
 #endif
@@ -2940,6 +2939,11 @@ do_identifier (token)
   if (TREE_CODE (id) == VAR_DECL && DECL_DEAD_FOR_LOCAL (id))
     {
       tree shadowed = DECL_SHADOWED_FOR_VAR (id);
+      while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL
+            && DECL_DEAD_FOR_LOCAL (shadowed))
+       shadowed = DECL_SHADOWED_FOR_VAR (shadowed);
+      if (!shadowed)
+       shadowed = IDENTIFIER_GLOBAL_VALUE (DECL_NAME (id));
       if (shadowed)
        {
          if (!DECL_ERROR_REPORTED (id))
index d40424c..49e7dd2 100644 (file)
@@ -901,7 +901,7 @@ template_instantiate_once:
                }
          left_curly opt.component_decl_list '}'
                {
-                 tree t = finish_struct ($<ttype>3, $5, 0);
+                 tree t = finish_struct ($<ttype>3, $5, NULL_TREE, 0);
 
                  pop_obstacks ();
                  end_template_instantiation ($1);
@@ -2187,7 +2187,7 @@ structsp:
        | TYPENAME_KEYWORD complex_type_name
                { $$ = $2; }
        /* C++ extensions, merged with C to avoid shift/reduce conflicts */
-       | class_head left_curly opt.component_decl_list '}'
+       | class_head left_curly opt.component_decl_list '}' maybe_attribute
                {
                  int semi;
                  tree id;
@@ -2209,7 +2209,7 @@ structsp:
                    /* $$ = $1 from default rule.  */;
                  else
                    {
-                     $$ = finish_struct ($$, $3, semi);
+                     $$ = finish_struct ($$, $3, $5, semi);
                      if (semi) note_got_semicolon ($$);
                    }
 
index 85f07cc..e34cf5b 100644 (file)
@@ -74,9 +74,6 @@ real_lvalue_p (ref)
        return 1;
       break;
 
-    case WITH_CLEANUP_EXPR:
-      return real_lvalue_p (TREE_OPERAND (ref, 0));
-
       /* A currently unresolved scope ref.  */
     case SCOPE_REF:
       my_friendly_abort (103);
@@ -147,9 +144,6 @@ lvalue_p (ref)
        return 1;
       break;
 
-    case WITH_CLEANUP_EXPR:
-      return lvalue_p (TREE_OPERAND (ref, 0));
-
     case TARGET_EXPR:
       return 1;
 
@@ -206,12 +200,7 @@ lvalue_or_else (ref, string)
 
    Build an encapsulation of the initialization to perform
    and return it so that it can be processed by language-independent
-   and language-specific expression expanders.
-
-   If WITH_CLEANUP_P is nonzero, we build a cleanup for this expression.
-   Otherwise, cleanups are not built here.  For example, when building
-   an initialization for a stack slot, since the called function handles
-   the cleanup, we would not want to do it here.  */
+   and language-specific expression expanders.  */
 tree
 build_cplus_new (type, init, with_cleanup_p)
      tree type;
@@ -231,19 +220,6 @@ build_cplus_new (type, init, with_cleanup_p)
   TREE_SIDE_EFFECTS (rval) = 1;
   TREE_ADDRESSABLE (rval) = 1;
 
-#if 0
-  if (with_cleanup_p && TYPE_NEEDS_DESTRUCTOR (type))
-    {
-      TREE_OPERAND (rval, 2) = error_mark_node;
-      rval = build (WITH_CLEANUP_EXPR, type, rval, 0,
-                   build_delete (build_pointer_type (type),
-                                 build_unary_op (ADDR_EXPR, slot, 0),
-                                 integer_two_node,
-                                 LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0));
-      TREE_SIDE_EFFECTS (rval) = 1;
-      TREE_ADDRESSABLE (rval) = 1;
-    }
-#endif
   return rval;
 }
 
@@ -1808,11 +1784,6 @@ unsave_expr_now (expr)
            }
        }
       break;
-      
-    case WITH_CLEANUP_EXPR:
-      warning ("WITH_CLEANUP_EXPR reused inside UNSAVE_EXPR");
-      RTL_EXPR_RTL (expr) = NULL_RTX;
-      break;
     }
 
   switch (TREE_CODE_CLASS (code))
index e182563..0c47de9 100644 (file)
@@ -1798,9 +1798,42 @@ build_component_ref (datum, component, basetype_path, protect)
        }
     }
 
+  /* See if we have to do any conversions so that we pick up the field from the
+     right context.  */
   if (DECL_FIELD_CONTEXT (field) != basetype)
     {
       tree context = DECL_FIELD_CONTEXT (field);
+      tree base = context;
+      while (base != basetype && ANON_AGGRNAME_P (TYPE_IDENTIFIER (base)))
+       {
+         base = TYPE_CONTEXT (base);
+       }
+
+      /* Handle base classes here...  */
+      if (base != basetype && TYPE_USES_COMPLEX_INHERITANCE (basetype))
+       {
+         tree addr = build_unary_op (ADDR_EXPR, datum, 0);
+         if (integer_zerop (addr))
+           {
+             error ("invalid reference to NULL ptr, use ptr-to-member instead");
+             return error_mark_node;
+           }
+         if (VBASE_NAME_P (DECL_NAME (field)))
+           {
+             /* It doesn't matter which vbase pointer we grab, just
+                find one of them.  */
+             tree binfo = get_binfo (base,
+                                     TREE_TYPE (TREE_TYPE (addr)), 0);
+             addr = convert_pointer_to_real (binfo, addr);
+           }
+         else
+           addr = convert_pointer_to (base, addr);
+         datum = build_indirect_ref (addr, NULL_PTR);
+         my_friendly_assert (datum != error_mark_node, 311);
+       }
+      basetype = base;
+      /* Handle things from anon unions here...  */
       if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (context)))
        {
          tree subfield = lookup_anon_field (basetype, context);
@@ -1810,28 +1843,6 @@ build_component_ref (datum, component, basetype_path, protect)
        }
     }
 
-  if (DECL_FIELD_CONTEXT (field) != basetype
-      && TYPE_USES_COMPLEX_INHERITANCE (basetype))
-    {
-      tree addr = build_unary_op (ADDR_EXPR, datum, 0);
-      if (integer_zerop (addr))
-       {
-         error ("invalid reference to NULL ptr, use ptr-to-member instead");
-         return error_mark_node;
-       }
-      if (VBASE_NAME_P (DECL_NAME (field)))
-         {
-           /* It doesn't matter which vbase pointer we grab, just
-              find one of them.  */
-           tree binfo = get_binfo (DECL_FIELD_CONTEXT (field),
-                                   TREE_TYPE (TREE_TYPE (addr)), 0);
-           addr = convert_pointer_to_real (binfo, addr);
-         }
-       else
-         addr = convert_pointer_to (DECL_FIELD_CONTEXT (field), addr);
-      datum = build_indirect_ref (addr, NULL_PTR);
-      my_friendly_assert (datum != error_mark_node, 311);
-    }
   ref = fold (build (COMPONENT_REF, TREE_TYPE (field),
                     break_out_cleanups (datum), field));
 
@@ -3486,7 +3497,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
          resultcode = xresultcode;
        }
 
-      if (short_compare && extra_warnings)
+      if (short_compare && warn_sign_compare)
        {
          int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0));
          int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1));
@@ -4308,14 +4319,6 @@ unary_complex_lvalue (code, arg)
       return build (COMPOUND_EXPR, TREE_TYPE (real_result), arg, real_result);
     }
 
-  if (TREE_CODE (arg) == WITH_CLEANUP_EXPR)
-    {
-      tree real_result = build_unary_op (code, TREE_OPERAND (arg, 0), 0);
-      real_result = build (WITH_CLEANUP_EXPR, TREE_TYPE (real_result),
-                          real_result, 0, TREE_OPERAND (arg, 2));
-      return real_result;
-    }
-
   if (TREE_CODE (TREE_TYPE (arg)) == FUNCTION_TYPE
       || TREE_CODE (TREE_TYPE (arg)) == METHOD_TYPE
       || TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE)
@@ -4402,17 +4405,6 @@ unary_complex_lvalue (code, arg)
     if (TREE_CODE (arg) == SAVE_EXPR && TREE_CODE (targ) == INDIRECT_REF)
       return build (SAVE_EXPR, build_pointer_type (TREE_TYPE (arg)),
                     TREE_OPERAND (targ, 0), current_function_decl, NULL);
-
-    /* We shouldn't wrap WITH_CLEANUP_EXPRs inside of SAVE_EXPRs, but in case
-       we do, here's how to handle it.  */
-    if (TREE_CODE (arg) == SAVE_EXPR && TREE_CODE (targ) == WITH_CLEANUP_EXPR)
-      {
-#if 0
-       /* Not really a bug, but something to turn on when testing.  */
-       compiler_error ("WITH_CLEANUP_EXPR wrapped in SAVE_EXPR");
-#endif
-       return unary_complex_lvalue (ADDR_EXPR, targ);
-      }
   }
 
   /* Don't let anything else be handled specially.  */
@@ -5661,38 +5653,10 @@ build_modify_expr (lhs, modifycode, rhs)
                                                 TREE_OPERAND (newrhs, 2))));
        }
     }
-  else if (modifycode != INIT_EXPR && TREE_CODE (newrhs) == WITH_CLEANUP_EXPR)
-    {
-      tree cleanup = TREE_OPERAND (newrhs, 2);
-      tree slot;
-
-      /* Finish up by running cleanups and having the "value" of the lhs.  */
-      tree exprlist = tree_cons (NULL_TREE, cleanup,
-                                build_tree_list (NULL_TREE, lhs));
-      newrhs = TREE_OPERAND (newrhs, 0);
-      if (TREE_CODE (newrhs) == TARGET_EXPR)
-         slot = TREE_OPERAND (newrhs, 0);
-      else if (TREE_CODE (newrhs) == ADDR_EXPR)
-       {
-         /* Bad but valid.  */
-         slot = newrhs;
-         warning ("address taken of temporary object");
-       }
-      else
-       my_friendly_abort (118);
-
-      /* Copy the value computed in SLOT into LHS.  */
-      exprlist = tree_cons (NULL_TREE,
-                           build_modify_expr (lhs, modifycode, slot),
-                           exprlist);
-      /* Evaluate the expression that needs CLEANUP.  This will
-        compute the value into SLOT.  */
-      exprlist = tree_cons (NULL_TREE, newrhs, exprlist);
-      result = convert (lhstype, build_compound_expr (exprlist));
-    }
   else
     result = build (modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR,
                    lhstype, lhs, newrhs);
+
   TREE_SIDE_EFFECTS (result) = 1;
 
   /* If we got the LHS in a different type for storing in,
@@ -6788,8 +6752,7 @@ c_expand_return (retval)
        {
          whats_returned = TREE_OPERAND (whats_returned, 0);
          while (TREE_CODE (whats_returned) == NEW_EXPR
-                || TREE_CODE (whats_returned) == TARGET_EXPR
-                || TREE_CODE (whats_returned) == WITH_CLEANUP_EXPR)
+                || TREE_CODE (whats_returned) == TARGET_EXPR)
            {
              /* Get the target.  */
              whats_returned = TREE_OPERAND (whats_returned, 0);