OSDN Git Service

86th Cygnus<->FSF merge
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 Apr 1996 21:44:27 +0000 (21:44 +0000)
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 Apr 1996 21:44:27 +0000 (21:44 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@11654 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/error.c
gcc/cp/init.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/typeck.c

index d428c02..1548a58 100644 (file)
-Fri Mar 29 09:41:02 1996  Jeffrey A. Law  <law@cygnus.com
+Mon Apr  1 09:03:13 1996  Bob Manson  <manson@charmed.cygnus.com>
+
+       * class.c (finish_struct_1): Propagate the TYPE_PACKED
+       flag for the type to the type's fields.
+
+Sat Mar 30 12:14:33 1996  Brendan Kehoe  <brendan@lisa.cygnus.com>
+
+       * parse.y (complex_parmlist, ELLIPSES): Take out ARM-based warning.
+
+Fri Mar 29 15:51:36 1996  Bob Manson  <manson@charmed.cygnus.com>
+
+       * class.c (base_info, finish_base_struct): Replace 
+       needs_virtual_dtor with base_has_virtual.
+
+       (finish_struct_1): Remove the old code that tried to make default
+       destructors virtual. Use base_has_virtual when checking if we need
+       to add a vtable entry for the rtti code.
+
+Fri Mar 29 14:02:36 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * pt.c (push_template_decl): Complain about template decl with
+       inappropriate declaration.
+
+Fri Mar 29 12:15:35 1996  Bob Manson  <manson@charmed.cygnus.com>
+
+       * typeck.c (build_x_unary_op): Remove bogus check for taking
+       the address of a member function.
+
+Fri Mar 29 11:56:02 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * parse.y (constructor_declarator): Only push the class if
+       we are not already in the class.
+
+Fri Mar 29 09:41:02 1996  Jeffrey A. Law  <law@cygnus.com>
 
        * method.c (emit_thunk): Remove current_call_is_indirect nonsense.
        Add additional argument to INIT_CUMULATIVE_ARGS.
 
+Thu Mar 28 16:41:39 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * decl.c (shadow_tag): Fix error about anon union with methods.
+
+       * parse.y (self_reference): Only generate a self-reference if this
+       is a non-template class.
+       (opt.component_decl_list): Only use it if it was generated.
+
+       * parse.y (component_decl_1): Use constructor_declarator.
+       (fn.def2): Ditto.
+       (notype_component_declarator0): Ditto.
+
+Thu Mar 28 15:11:35 1996  Bob Manson  <manson@charmed.cygnus.com>
+
+       * typeck.c (build_x_unary_op): Add checks for taking the address
+       of a TARGET_EXPR or of a member function, and give appropriate
+       warnings.
+
+Thu Mar 28 14:49:26 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * pt.c (process_template_parm): Allow template type parms to be
+       used as types for template const parms.
+
+Wed Mar 27 15:51:19 1996  Mike Stump  <mrs@cygnus.com>
+
+       * init.c (expand_vec_init): Ensure the eh cleanups are on the
+       function_obstack.
+
+Wed Mar 27 10:14:30 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * decl.c (lookup_name_real): Be even more picky about the
+       ambiguous lookup warning.
+       (grokdeclarator): Tweak SCOPE_REF constructor declarators here.
+       * parse.y (constructor_declarator): Rather than here.
+
+       * parse.y (constructor_declarator): New nonterminal.
+       (fn.def1): Use it.
+       (explicit_instantiation): Ditto.
+
+Tue Mar 26 13:41:33 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       Add implicit declaration of class name at class scope.
+       * decl.c (lookup_name_real): Restrict pedwarn about ambiguous lookup.
+       * parse.y (self_reference): New nonterminal.
+       (opt.component_decl_list): Use it.
+       (fn.def1): Add nested_name_specifier type_name cases.
+       * class.c (build_self_reference): New function.
+       (finish_struct): Handle access_default later, move self-reference
+       decl to the end.
+       * pt.c (lookup_template_class): Handle getting a TYPE_DECL.
+       * cp-tree.h: Adjust.
+
+       * pt.c (do_function_instantiation): Separate handling of member
+       functions and non-member functions properly.
+
+Mon Mar 25 14:23:22 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * pt.c (process_template_parm): Improve error for 'volatile class K'.
+
+       * class.c (finish_struct_1): Check the right slot for destructors.
+
+       * decl.c (start_enum): Complain about enum templates.
+
+Mon Mar 25 13:25:31 1996  Mike Stump  <mrs@cygnus.com>
+
+       * init.c (resolve_offset_ref): Offset pointers to member data by one.
+       * typeck.c (unary_complex_lvalue): Ditto.
+
+Mon Mar 25 13:30:42 1996  Bob Manson  <manson@charmed.cygnus.com>
+
+       * typeck.c (c_expand_return): Check for a returned local
+       array name, similar to the check for an ADDR_EXPR.
+
+Mon Mar 25 13:07:19 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * decl.c (cp_finish_decl): Don't build cleanups for static
+       variables here.
+
+Fri Mar 22 17:57:55 1996  Mike Stump  <mrs@cygnus.com>
+
+       * typeck.c (build_modify_expr): Fix error messages to be more
+       accurate.
+       * cp-tree.h (assop_as_string): Parallel to op_as_string, but for
+       assignment operators.
+       * error.c (assop_as_string): Ditto.  Add support for `%Q' for
+       assignment operators.
+
 Fri Mar 22 13:48:29 1996  Jason Merrill  <jason@yorick.cygnus.com>
 
+       * decl.c (grokdeclarator): Call bad_specifiers for typedefs.  Also
+       give an error if initialized.  Pedwarn about nested type with the
+       same name as its enclosing class.
+
        * pt.c (tsubst, case TYPE_DECL): Set DECL_CONTEXT.
 
        * typeck.c (require_complete_type): Be sure to instantiate the
index ffe0104..76377e1 100644 (file)
@@ -1384,7 +1384,7 @@ struct base_info
   char cant_synth_copy_ctor;
   char cant_synth_asn_ref;
   char no_const_asn_ref;
-  char needs_virtual_dtor;
+  char base_has_virtual;
 };
 
 /* Record information about type T derived from its base classes.
@@ -1520,9 +1520,8 @@ finish_base_struct (t, b, t_binfo)
 
       if (TYPE_VIRTUAL_P (basetype))
        {
-         /* If there's going to be a destructor needed, make
-            sure it will be virtual.  */
-         b->needs_virtual_dtor = 1;
+         /* Remember that the baseclass has virtual members. */
+         b->base_has_virtual = 1;
 
          /* Don't borrow virtuals from virtual baseclasses.  */
          if (TREE_VIA_VIRTUAL (base_binfo))
@@ -2973,7 +2972,7 @@ finish_struct_1 (t, attributes, warn_anon)
   tree fields = TYPE_FIELDS (t);
   tree fn_fields = TYPE_METHODS (t);
   tree x, last_x, method_vec;
-  int needs_virtual_dtor;
+  int base_has_virtual;
   int all_virtual;
   int has_virtual;
   int max_has_virtual;
@@ -3083,7 +3082,7 @@ finish_struct_1 (t, attributes, warn_anon)
       cant_synth_copy_ctor = base_info.cant_synth_copy_ctor;
       cant_synth_asn_ref = base_info.cant_synth_asn_ref;
       no_const_asn_ref = base_info.no_const_asn_ref;
-      needs_virtual_dtor = base_info.needs_virtual_dtor;
+      base_has_virtual = base_info.base_has_virtual;
       n_baseclasses = TREE_VEC_LENGTH (BINFO_BASETYPES (t_binfo));
       aggregate = 0;
     }
@@ -3100,7 +3099,7 @@ finish_struct_1 (t, attributes, warn_anon)
       cant_synth_copy_ctor = 0;
       cant_synth_asn_ref = 0;
       no_const_asn_ref = 0;
-      needs_virtual_dtor = 0;
+      base_has_virtual = 0;
     }
 
 #if 0
@@ -3172,6 +3171,9 @@ finish_struct_1 (t, attributes, warn_anon)
     {
       GNU_xref_member (current_class_name, x);
 
+      if (TREE_CODE (x) == FIELD_DECL)
+       DECL_PACKED (x) |= TYPE_PACKED (t);
+
       /* Handle access declarations.  */
       if (TREE_CODE (x) == USING_DECL)
        {
@@ -3537,7 +3539,7 @@ finish_struct_1 (t, attributes, warn_anon)
       && !IS_SIGNATURE (t))
     {
       /* Here we must cons up a destructor on the fly.  */
-      tree dtor = cons_up_default_function (t, name, needs_virtual_dtor != 0);
+      tree dtor = cons_up_default_function (t, name, 0);
       check_for_override (dtor, t);
 
       /* If we couldn't make it work, then pretend we didn't need it.  */
@@ -3550,11 +3552,6 @@ finish_struct_1 (t, attributes, warn_anon)
          TREE_CHAIN (dtor) = fn_fields;
          fn_fields = dtor;
 
-         if (DECL_VINDEX (dtor) == NULL_TREE
-             && (needs_virtual_dtor
-                 || pending_virtuals != NULL_TREE
-                 || pending_hard_virtuals != NULL_TREE))
-           DECL_VINDEX (dtor) = error_mark_node;
          if (DECL_VINDEX (dtor))
            pending_virtuals = add_virtual_function (pending_virtuals,
                                                     &has_virtual, dtor, t);
@@ -3563,7 +3560,7 @@ finish_struct_1 (t, attributes, warn_anon)
     }
 
   TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_HAS_DESTRUCTOR (t);
-  if (flag_rtti && (max_has_virtual > 0 || needs_virtual_dtor) && 
+  if (flag_rtti && (max_has_virtual > 0 || base_has_virtual) && 
        has_virtual == 0)
     has_virtual = 1;
 
@@ -4132,7 +4129,7 @@ finish_struct_1 (t, attributes, warn_anon)
       TYPE_NONCOPIED_PARTS (t) = build_tree_list (default_conversion (TYPE_BINFO_VTABLE (t)), vfield);
 
       if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (t)
-         && DECL_VINDEX (TREE_VEC_ELT (method_vec, 0)) == NULL_TREE)
+         && DECL_VINDEX (TREE_VEC_ELT (method_vec, 1)) == NULL_TREE)
        cp_warning ("`%#T' has virtual functions but non-virtual destructor",
                    t);
     }
@@ -4212,6 +4209,7 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
   tree name = TYPE_NAME (t);
   tree x, last_x = NULL_TREE;
   tree access;
+  tree dummy = NULL_TREE;
 
   if (TREE_CODE (name) == TYPE_DECL)
     {
@@ -4233,25 +4231,33 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
   if (IS_SIGNATURE (t))
     append_signature_fields (list_of_fieldlists);
 
-  if (last_x && list_of_fieldlists)
-    TREE_CHAIN (last_x) = TREE_VALUE (list_of_fieldlists);
-
-  /* For signatures, we made all methods `public' in the parser and
-     reported an error if a access specifier was used.  */
-  if (CLASSTYPE_DECLARED_CLASS (t) == 0)
+  /* Move our self-reference declaration to the end of the field list so
+     any real field with the same name takes precedence.  */
+  if (list_of_fieldlists
+      && TREE_VALUE (list_of_fieldlists)
+      && DECL_ARTIFICIAL (TREE_VALUE (list_of_fieldlists)))
     {
-      if (list_of_fieldlists
-         && TREE_PURPOSE (list_of_fieldlists) == access_default_node)
-       TREE_PURPOSE (list_of_fieldlists) = access_public_node;
+      dummy = TREE_VALUE (list_of_fieldlists);
+      list_of_fieldlists = TREE_CHAIN (list_of_fieldlists);
     }
-  else if (list_of_fieldlists
-          && TREE_PURPOSE (list_of_fieldlists) == access_default_node)
-    TREE_PURPOSE (list_of_fieldlists) = access_private_node;
+
+  if (last_x && list_of_fieldlists)
+    TREE_CHAIN (last_x) = TREE_VALUE (list_of_fieldlists);
 
   while (list_of_fieldlists)
     {
       access = TREE_PURPOSE (list_of_fieldlists);
 
+      /* For signatures, we made all methods `public' in the parser and
+        reported an error if a access specifier was used.  */
+      if (access == access_default_node)
+       {
+         if (CLASSTYPE_DECLARED_CLASS (t) == 0)
+           access = access_public_node;
+         else
+           access = access_private_node;
+       }
+
       for (x = TREE_VALUE (list_of_fieldlists); x; x = TREE_CHAIN (x))
        {
          TREE_PRIVATE (x) = access == access_private_node;
@@ -4298,16 +4304,6 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
              continue;
            }
 
-#if 0
-         /* Handle access declarations.  */
-         if (DECL_NAME (x) && TREE_CODE (DECL_NAME (x)) == SCOPE_REF)
-           {
-             tree n = DECL_NAME (x);
-             x = build_decl
-               (USING_DECL, DECL_NAME (TREE_OPERAND (n, 1)), TREE_TYPE (x));
-             DECL_RESULT (x) = n;
-           }
-#endif
          if (TREE_CODE (x) != TYPE_DECL)
            DECL_FIELD_CONTEXT (x) = t;
 
@@ -4330,7 +4326,7 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
 
   /* Now add the tags, if any, to the list of TYPE_DECLs
      defined for this type.  */
-  if (CLASSTYPE_TAGS (t))
+  if (CLASSTYPE_TAGS (t) || dummy)
     {
       x = CLASSTYPE_TAGS (t);
       while (x)
@@ -4350,6 +4346,8 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
          x = TREE_CHAIN (x);
          last_x = chainon (last_x, tag);
        }
+      if (dummy)
+       last_x = chainon (last_x, dummy);
       if (fields == NULL_TREE)
        fields = last_x;
       CLASSTYPE_LOCAL_TYPEDECLS (t) = 1;
@@ -5298,6 +5296,7 @@ print_class_statistics ()
    decls that may be cached in the previous_class_values list.  For now, let's
    use the permanent obstack, later we may create a dedicated obstack just
    for this purpose.  The effect is undone by pop_obstacks.  */
+
 void
 maybe_push_cache_obstack ()
 {
@@ -5305,3 +5304,24 @@ maybe_push_cache_obstack ()
   if (current_class_depth == 1)
     current_obstack = &permanent_obstack;
 }
+
+/* Build a dummy reference to ourselves so Derived::Base (and A::A) works,
+   according to [class]:
+                                          The class-name is also inserted
+   into  the scope of the class itself.  For purposes of access checking,
+   the inserted class name is treated as if it were a public member name.  */
+
+tree
+build_self_reference ()
+{
+  tree name = constructor_name (current_class_type);
+  tree value = build_lang_decl (TYPE_DECL, name, current_class_type);
+  DECL_NONLOCAL (value) = 1;
+  DECL_CONTEXT (value) = current_class_type;
+  DECL_CLASS_CONTEXT (value) = current_class_type;
+  CLASSTYPE_LOCAL_TYPEDECLS (current_class_type) = 1;
+  DECL_ARTIFICIAL (value) = 1;
+
+  pushdecl_class_level (value);
+  return value;
+}
index 7d9f12c..4f3212c 100644 (file)
@@ -1967,6 +1967,7 @@ extern tree instantiate_type                      PROTO((tree, tree, int));
 extern void print_class_statistics             PROTO((void));
 extern void maybe_push_cache_obstack           PROTO((void));
 extern unsigned HOST_WIDE_INT skip_rtti_stuff  PROTO((tree *));
+extern tree build_self_reference               PROTO((void));
 
 /* in cvt.c */
 extern tree convert_to_reference               PROTO((tree, tree, int, int, tree));
@@ -2254,6 +2255,7 @@ extern char *code_as_string                       PROTO((enum tree_code, int));
 extern char *language_as_string                        PROTO((enum languages, int));
 extern char *parm_as_string                    PROTO((int, int));
 extern char *op_as_string                      PROTO((enum tree_code, int));
+extern char *assop_as_string                   PROTO((enum tree_code, int));
 extern char *cv_as_string                      PROTO((tree, int));
 
 /* in method.c */
@@ -2290,7 +2292,6 @@ extern tree lookup_template_class         PROTO((tree, tree, tree));
 extern int uses_template_parms                 PROTO((tree));
 extern tree instantiate_class_template         PROTO((tree));
 extern tree instantiate_template               PROTO((tree, tree *));
-extern void overload_template_name             PROTO((tree));
 extern int type_unification                    PROTO((tree, tree *, tree, tree, int *, int));
 struct tinst_level *tinst_for_decl             PROTO((void));
 extern void mark_decl_instantiated             PROTO((tree, int));
index 10cf2a6..93585de 100644 (file)
@@ -4501,12 +4501,18 @@ lookup_name_real (name, prefer_type, nonclass)
  done:
   if (val)
     {
+      /* This should only warn about types used in qualified-ids.  */
       if (from_obj && from_obj != val)
        {
-         cp_pedwarn ("lookup of `%D' in the scope of `%#T' (`%D')",
-                     name, got_object, from_obj);
-         cp_pedwarn ("  does not match lookup in the current scope (`%D')",
-                     val);
+         if (looking_for_typename && TREE_CODE (from_obj) == TYPE_DECL
+             && TREE_CODE (val) == TYPE_DECL
+             && TREE_TYPE (from_obj) != TREE_TYPE (val))
+           {
+             cp_pedwarn ("lookup of `%D' in the scope of `%#T' (`%#T')",
+                         name, got_object, TREE_TYPE (from_obj));
+             cp_pedwarn ("  does not match lookup in the current scope (`%#T')",
+                         TREE_TYPE (val));
+           }
        }
 
       if ((TREE_CODE (val) == TEMPLATE_DECL && looking_for_template)
@@ -5700,14 +5706,15 @@ shadow_tag (declspecs)
     {
       /* ANSI C++ June 5 1992 WP 9.5.3.  Anonymous unions may not have
         function members.  */
+      if (TYPE_METHODS (t))
+       error ("an anonymous union cannot have function members");
+
       if (TYPE_FIELDS (t))
        {
          tree decl = grokdeclarator (NULL_TREE, declspecs, NORMAL, 0,
                                      NULL_TREE, NULL_TREE);
          finish_anon_union (decl);
        }
-      else
-       error ("anonymous union cannot have a function member");
     }
   else
     {
@@ -6525,7 +6532,9 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
            cp_error ("storage size of `%D' isn't constant", decl);
        }
 
-      if (!DECL_EXTERNAL (decl) && TYPE_NEEDS_DESTRUCTOR (type))
+      if (! DECL_EXTERNAL (decl) && TYPE_NEEDS_DESTRUCTOR (type)
+         /* Cleanups for static variables are handled by `finish_file'.  */
+         && ! TREE_STATIC (decl))
        {
          int yes = suspend_momentary ();
          cleanup = maybe_build_cleanup (decl);
@@ -7676,8 +7685,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
                    ctype = cname;
                }
 
-             if (ctype
-                 && TREE_OPERAND (decl, 1) == constructor_name_full (ctype))
+             if (ctype && TREE_CODE (TREE_OPERAND (decl, 1)) == TYPE_DECL
+                 && ((DECL_NAME (TREE_OPERAND (decl, 1))
+                      == constructor_name_full (ctype))
+                     || (DECL_NAME (TREE_OPERAND (decl, 1))
+                         == constructor_name (ctype))))
                TREE_OPERAND (decl, 1) = constructor_name (ctype);
              next = &TREE_OPERAND (decl, 1);
              decl = *next;
@@ -9030,6 +9042,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
 
       if (decl_context == FIELD)
        {
+         if (declarator == current_class_name)
+           cp_pedwarn ("ANSI C++ forbids nested type `%D' with same name as enclosing class",
+                       declarator);
          decl = build_lang_decl (TYPE_DECL, declarator, type);
          if (IS_SIGNATURE (current_class_type) && opaque_typedef)
            SIGNATURE_HAS_OPAQUE_TYPEDECLS (current_class_type) = 1;
@@ -9064,6 +9079,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
          error ("non-object member `%s' cannot be declared mutable", name);
        }
 
+      bad_specifiers (decl, "type", virtualp, quals != NULL_TREE,
+                     inlinep, friendp, raises != NULL_TREE);
+
+      if (initialized)
+       error ("typedef declaration includes an initializer");
+
       return decl;
     }
 
@@ -10597,15 +10618,19 @@ start_enum (name)
     enumtype = lookup_tag (ENUMERAL_TYPE, name, b, 1);
 
   if (enumtype != NULL_TREE && TREE_CODE (enumtype) == ENUMERAL_TYPE)
-    cp_error ("multiple definition of enum `%T'", enumtype);
+    cp_error ("multiple definition of `%#T'", enumtype);
   else
     {
       enumtype = make_node (ENUMERAL_TYPE);
       pushtag (name, enumtype, 0);
     }
 
+  if (b->pseudo_global)
+    cp_error ("template declaration of `%#T'", enumtype);
+
   if (current_class_type)
     TREE_ADDRESSABLE (b->tags) = 1;
+
   current_local_enum = NULL_TREE;
 
   /* We copy this value because enumerated type constants
index bb93dd4..652ed3f 100644 (file)
@@ -34,6 +34,7 @@ typedef char* cp_printer ();
 #define L language_as_string
 #define O op_as_string
 #define P parm_as_string
+#define Q assop_as_string
 #define T type_as_string
 #define V cv_as_string
 
@@ -46,7 +47,7 @@ cp_printer * cp_printers[256] =
   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x20 */
   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x30 */
   _, A, _, C, D, E, _, _, _, _, _, _, L, _, _, O, /* 0x40 */
-  P, _, _, _, T, _, V, _, _, _, _, _, _, _, _, _, /* 0x50 */
+  P, Q, _, _, T, _, V, _, _, _, _, _, _, _, _, _, /* 0x50 */
   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x60 */
   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x70 */
 };
@@ -56,6 +57,7 @@ cp_printer * cp_printers[256] =
 #undef L
 #undef O
 #undef P
+#undef Q
 #undef T
 #undef V
 #undef _
@@ -1504,6 +1506,20 @@ op_as_string (p, v)
 }
 
 char *
+assop_as_string (p, v)
+     enum tree_code p;
+     int v;
+{
+  static char buf[] = "operator                ";
+
+  if (p == 0)
+    return "{unknown}";
+  
+  strcpy (buf + 9, assignop_tab [p]);
+  return buf;
+}
+
+char *
 args_as_string (p, v)
      tree p;
      int v;
index 289cef8..b8d0dad 100644 (file)
@@ -2071,6 +2071,14 @@ resolve_offset_ref (exp)
       addr = convert_pointer_to (basetype, addr);
       member = 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),
+                               0);
+
       return build1 (INDIRECT_REF, type,
                     build (PLUS_EXPR, build_pointer_type (type),
                            addr, member));
@@ -3399,13 +3407,31 @@ expand_vec_init (decl, base, maxindex, init, from_array)
            use_variable (DECL_RTL (base2));
        }
       expand_end_loop ();
-      if (TYPE_NEEDS_DESTRUCTOR (type))
-       end_protect (build_array_eh_cleanup (rval,
-                                            build_binary_op (MINUS_EXPR,
-                                                             maxindex,
-                                                             iterator,
-                                                             1),
-                                            type));
+      if (TYPE_NEEDS_DESTRUCTOR (type) && flag_handle_exceptions)
+       {
+         /* We have to ensure that this can live to the cleanup
+            expansion time, since we know it is only ever needed
+            once, generate code now.  */
+         push_obstacks_nochange ();
+         resume_temporary_allocation ();
+         {
+           tree e1, e2 = make_node (RTL_EXPR);
+           TREE_TYPE (e2) = void_type_node;
+           RTL_EXPR_RTL (e2) = const0_rtx;
+           TREE_SIDE_EFFECTS (e2) = 1;
+           start_sequence_for_rtl_expr (e2);
+
+           e1 = build_array_eh_cleanup
+             (rval,
+              build_binary_op (MINUS_EXPR, maxindex, iterator, 1),
+              type);
+           expand_expr (e1, const0_rtx, VOIDmode, 0);
+           RTL_EXPR_SEQUENCE (e2) = get_insns ();
+           end_sequence ();
+           end_protect (e2);
+         }
+         pop_obstacks ();
+       }
       expand_end_cond ();
       if (obey_regdecls)
        use_variable (DECL_RTL (iterator));
index d2b6f95..fa521a3 100644 (file)
@@ -210,7 +210,7 @@ empty_parms ()
 
 %type <ttype> structsp opt.component_decl_list component_decl_list
 %type <ttype> component_decl component_decl_1 components notype_components
-%type <ttype> component_declarator component_declarator0
+%type <ttype> component_declarator component_declarator0 self_reference
 %type <ttype> notype_component_declarator notype_component_declarator0
 %type <ttype> after_type_component_declarator after_type_component_declarator0
 %type <ttype> enumlist enumerator
@@ -231,7 +231,7 @@ empty_parms ()
 %token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL
 %token <ttype> PRE_PARSED_CLASS_DECL
 %type <ttype> fn.def1 /* Not really! */
-%type <ttype> fn.def2 return_id fn.defpen
+%type <ttype> fn.def2 return_id fn.defpen constructor_declarator
 %type <itype> ctor_initializer_opt
 %type <ttype> named_class_head named_class_head_sans_basetype
 %type <ttype> named_complex_class_head_sans_basetype
@@ -551,6 +551,51 @@ fndef:
                {}
        ;
 
+constructor_declarator:
+         nested_name_specifier type_name '(' 
+               {
+                 $$ = build_parse_node (SCOPE_REF, $1, $2);
+                 if ($1 != current_class_type)
+                   {
+                     push_nested_class ($1, 3);
+                     TREE_COMPLEXITY ($$) = current_class_depth;
+                   }
+               }
+         parmlist ')' type_quals
+               { $$ = build_parse_node (CALL_EXPR, $<ttype>4, $5, $7); }
+       | nested_name_specifier type_name LEFT_RIGHT type_quals
+               {
+                 $$ = build_parse_node (SCOPE_REF, $1, $2);
+                 if ($1 != current_class_type)
+                   {
+                     push_nested_class ($1, 3);
+                     TREE_COMPLEXITY ($$) = current_class_depth;
+                   }
+                 $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $4);
+               }
+       | global_scope nested_name_specifier type_name '(' 
+               {
+                 $$ = build_parse_node (SCOPE_REF, $2, $3);
+                 if ($2 != current_class_type)
+                   {
+                     push_nested_class ($2, 3);
+                     TREE_COMPLEXITY ($$) = current_class_depth;
+                   }
+               }
+        parmlist ')' type_quals
+               { $$ = build_parse_node (CALL_EXPR, $<ttype>5, $6, $8); }
+       | global_scope nested_name_specifier type_name LEFT_RIGHT type_quals
+               {
+                 $$ = build_parse_node (SCOPE_REF, $2, $3);
+                 if ($2 != current_class_type)
+                   {
+                     push_nested_class ($2, 3);
+                     TREE_COMPLEXITY ($$) = current_class_depth;
+                   }
+                 $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $5);
+               }
+       ;
+
 fn.def1:
          typed_declspecs declarator exception_specification_opt
                { tree specs, attrs;
@@ -571,6 +616,18 @@ fn.def1:
                    YYERROR1;
                  reinit_parse_for_function ();
                  $$ = NULL_TREE; }
+       | declmods constructor_declarator exception_specification_opt
+               { tree specs, attrs;
+                 split_specs_attrs ($1, &specs, &attrs);
+                 if (! start_function (specs, $2, $3, attrs, 0))
+                   YYERROR1;
+                 reinit_parse_for_function ();
+                 $$ = NULL_TREE; }
+       | constructor_declarator exception_specification_opt
+               { if (! start_function (NULL_TREE, $$, $2, NULL_TREE, 0))
+                   YYERROR1;
+                 reinit_parse_for_function ();
+                 $$ = NULL_TREE; }
        ;
 
 /* more C++ complexity.  See component_decl for a comment on the
@@ -578,13 +635,6 @@ fn.def1:
 fn.def2:
          typed_declspecs '(' parmlist ')' type_quals exception_specification_opt
                { tree specs = strip_attrs ($1);
-                 if (TREE_VALUE (specs) == current_class_type)
-                   {
-                     if (TREE_CHAIN (specs) == NULL_TREE)
-                       specs = get_decl_list (current_class_name);
-                     else
-                       TREE_VALUE (specs) = current_class_name;
-                   } 
                  $$ = build_parse_node (CALL_EXPR, TREE_VALUE (specs), $3, $5);
                  $$ = start_method (TREE_CHAIN (specs), $$, $6);
                 rest_of_mdef:
@@ -608,6 +658,11 @@ fn.def2:
                  $$ = start_method (specs, $2, $3); goto rest_of_mdef; }
        | notype_declarator exception_specification_opt
                { $$ = start_method (NULL_TREE, $$, $2); goto rest_of_mdef; }
+       | declmods constructor_declarator exception_specification_opt
+               { tree specs = strip_attrs ($1);
+                 $$ = start_method (specs, $2, $3); goto rest_of_mdef; }
+       | constructor_declarator exception_specification_opt
+               { $$ = start_method (NULL_TREE, $$, $2); goto rest_of_mdef; }
        ;
 
 return_id: RETURN IDENTIFIER
@@ -726,6 +781,8 @@ explicit_instantiation:
                  do_function_instantiation (specs, $3, NULL_TREE); }
        | TEMPLATE notype_declarator
                { do_function_instantiation (NULL_TREE, $2, NULL_TREE); }
+       | TEMPLATE constructor_declarator
+               { do_function_instantiation (NULL_TREE, $2, NULL_TREE); }
        | SCSPEC TEMPLATE aggr template_type
                { do_type_instantiation ($4, $1); }
        | SCSPEC TEMPLATE typed_declspecs declarator
@@ -733,6 +790,8 @@ explicit_instantiation:
                  do_function_instantiation (specs, $4, $1); }
        | SCSPEC TEMPLATE notype_declarator
                { do_function_instantiation (NULL_TREE, $3, $1); }
+       | SCSPEC TEMPLATE constructor_declarator
+               { do_function_instantiation (NULL_TREE, $3, $1); }
        ;
 
 /* The TYPENAME expansions are to deal with use of a template class name as
@@ -2408,15 +2467,26 @@ left_curly: '{'
                }
        ;
 
+self_reference:
+         /* empty */
+               {
+                 if (CLASSTYPE_TEMPLATE_INFO (current_class_type))
+                   $$ = NULL_TREE;
+                 else
+                   $$ = build_self_reference ();
+               }
+       ;
+
 opt.component_decl_list:
-       /* empty */
-               { $$ = NULL_TREE; }
-       | component_decl_list
+         self_reference
+               { if ($$) $$ = build_tree_list (access_public_node, $$); }
+       | self_reference component_decl_list
                {
                  if (current_aggr == signature_type_node)
-                   $$ = build_tree_list (access_public_node, $$);
+                   $$ = build_tree_list (access_public_node, $2);
                  else
-                   $$ = build_tree_list (access_default_node, $$);
+                   $$ = build_tree_list (access_default_node, $2);
+                 if ($1) $$ = tree_cons (access_public_node, $1, $$);
                }
        | opt.component_decl_list VISSPEC ':' component_decl_list
                {
@@ -2488,6 +2558,9 @@ component_decl_1:
        | notype_declarator exception_specification_opt maybeasm maybe_attribute maybe_init
                { $$ = grokfield ($$, NULL_TREE, $2, $5, $3,
                                  build_tree_list ($4, NULL_TREE)); }
+       | constructor_declarator exception_specification_opt maybeasm maybe_attribute maybe_init
+               { $$ = grokfield ($$, NULL_TREE, $2, $5, $3,
+                                 build_tree_list ($4, NULL_TREE)); }
        | ':' expr_no_commas
                { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
        | error
@@ -2597,6 +2670,12 @@ notype_component_declarator0:
                  $<ttype>0 = current_declspecs;
                  $$ = grokfield ($$, current_declspecs, $2, $5, $3,
                                  build_tree_list ($4, prefix_attributes)); }
+       | constructor_declarator exception_specification_opt maybeasm maybe_attribute maybe_init
+               { split_specs_attrs ($<ttype>0, &current_declspecs,
+                                    &prefix_attributes);
+                 $<ttype>0 = current_declspecs;
+                 $$ = grokfield ($$, current_declspecs, $2, $5, $3,
+                                 build_tree_list ($4, prefix_attributes)); }
        | IDENTIFIER ':' expr_no_commas maybe_attribute
                { split_specs_attrs ($<ttype>0, &current_declspecs,
                                     &prefix_attributes);
@@ -2781,7 +2860,7 @@ direct_after_type_declarator:
        | '(' after_type_declarator ')'
                { $$ = $2; }
        | nested_name_specifier type_name %prec EMPTY
-               { push_nested_class (TREE_TYPE ($$), 3);
+               { push_nested_class ($1, 3);
                  $$ = build_parse_node (SCOPE_REF, $$, $2);
                  TREE_COMPLEXITY ($$) = current_class_depth; }
        | type_name %prec EMPTY
@@ -3694,9 +3773,6 @@ complex_parmlist:
                }
        | ELLIPSIS
                {
-                 /* ARM $8.2.5 has this as a boxed-off comment.  */
-                 if (pedantic)
-                   warning ("use of `...' without a first argument is non-portable");
                  $$ = NULL_TREE;
                }
        | TYPENAME_ELLIPSIS
index f3307a1..c4b58a4 100644 (file)
@@ -114,9 +114,13 @@ process_template_parm (list, next)
                             PARM, 0, NULL_TREE, NULL_TREE);
       /* A template parameter is not modifiable.  */
       TREE_READONLY (parm) = 1;
-      if (IS_AGGR_TYPE (TREE_TYPE (parm)))
+      if (IS_AGGR_TYPE (TREE_TYPE (parm))
+         && TREE_CODE (TREE_TYPE (parm)) != TEMPLATE_TYPE_PARM)
        {
-         sorry ("aggregate template parameter types");
+         cp_error ("`%#T' is not a valid type for a template constant parameter",
+                   TREE_TYPE (parm));
+         if (DECL_NAME (parm) == NULL_TREE)
+           error ("  a template type parameter must begin with `class' or `typename'");
          TREE_TYPE (parm) = void_type_node;
        }
       tinfo = make_node (TEMPLATE_CONST_PARM);
@@ -235,8 +239,10 @@ push_template_decl (decl)
       if (TREE_CODE (decl) == TYPE_DECL)
        tmpl = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl));
       else if (! DECL_TEMPLATE_INFO (decl))
-       /* A member definition that doesn't match anything in the class.  */
-       return;
+       {
+         cp_error ("template definition of non-template `%#D'", decl);
+         return;
+       }
       else
        tmpl = DECL_TI_TEMPLATE (decl);
     }
@@ -609,6 +615,11 @@ lookup_template_class (d1, arglist, in_decl)
       if (! template)
        template = IDENTIFIER_CLASS_VALUE (d1);
     }
+  else if (TREE_CODE (d1) == TYPE_DECL && IS_AGGR_TYPE (TREE_TYPE (d1)))
+    {
+      template = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (d1));
+      d1 = DECL_NAME (template);
+    }
   else if (TREE_CODE_CLASS (TREE_CODE (d1)) == 't' && IS_AGGR_TYPE (d1))
     {
       template = CLASSTYPE_TI_TEMPLATE (d1);
@@ -2728,12 +2739,15 @@ do_function_instantiation (declspecs, declarator, storage)
     }
 
   /* If we've already seen this template instance, use it.  */
-  if (name = DECL_ASSEMBLER_NAME (decl),
-      fn = IDENTIFIER_GLOBAL_VALUE (name),
-      fn && DECL_TEMPLATE_INSTANTIATION (fn))
-    result = fn;
-  else if (fn && DECL_CONTEXT (fn))
-    ;
+  if (DECL_FUNCTION_MEMBER_P (decl))
+    {
+      if (DECL_TEMPLATE_INSTANTIATION (decl))
+       result = decl;
+      else if (name = DECL_ASSEMBLER_NAME (decl),
+              fn = IDENTIFIER_GLOBAL_VALUE (name),
+              fn && DECL_TEMPLATE_INSTANTIATION (fn))
+       result = fn;
+    }
   else if (name = DECL_NAME (decl), fn = IDENTIFIER_GLOBAL_VALUE (name), fn)
     {
       for (fn = get_first_fn (fn); fn; fn = DECL_CHAIN (fn))
@@ -2779,10 +2793,10 @@ do_function_instantiation (declspecs, declarator, storage)
     cp_error ("storage class `%D' applied to template instantiation",
              storage);
 
-  if (! extern_p)
-    instantiate_decl (result);
   mark_decl_instantiated (result, extern_p);
   repo_template_instantiated (result, extern_p);
+  if (! extern_p)
+    instantiate_decl (result);
 }
 
 void
index 498f293..05e757f 100644 (file)
@@ -3999,6 +3999,13 @@ build_x_unary_op (code, xarg)
        return build_opfncall (code, LOOKUP_NORMAL, xarg,
                               NULL_TREE, NULL_TREE);
     }
+
+  if (code == ADDR_EXPR)
+    {
+      if (TREE_CODE (xarg) == TARGET_EXPR)
+       warning ("taking address of temporary");
+    }
+
   return build_unary_op (code, xarg, 0);
 }
 
@@ -4499,17 +4506,30 @@ unary_complex_lvalue (code, arg)
                return error_mark_node;
              }
 
+         /* Add in the offset to the right subobject.  */
          offset = get_delta_difference (DECL_FIELD_CONTEXT (t), 
                                         TREE_TYPE (TREE_OPERAND (arg, 0)),
                                         0);
+
+         /* Add in the offset to the field.  */
          offset = size_binop (PLUS_EXPR, offset,
                               size_binop (EASY_DIV_EXPR,
                                           DECL_FIELD_BITPOS (t),
                                           size_int (BITS_PER_UNIT)));
+
+         /* We offset all pointer to data memebers by 1 so that we can
+            distinguish between a null pointer to data member and the first
+            data member of a structure.  */
+         offset = size_binop (PLUS_EXPR, offset, size_int (1));
+
          return convert (build_pointer_type (TREE_TYPE (arg)), offset);
        }
     }
 
+  
+#if 0
+  /* This seems to be obsolete now (and posssibly wrong, compare with
+     resolve_offset_ref).  */
   if (TREE_CODE (arg) == OFFSET_REF)
     {
       tree left = TREE_OPERAND (arg, 0), left_addr;
@@ -4530,6 +4550,7 @@ unary_complex_lvalue (code, arg)
                    build1 (NOP_EXPR, integer_type_node, left_addr),
                    build1 (NOP_EXPR, integer_type_node, right_addr));
     }
+#endif
 
   /* We permit compiler to make function calls returning
      objects of aggregate type look like lvalues.  */
@@ -5558,7 +5579,7 @@ build_modify_expr (lhs, modifycode, rhs)
        }
       else
        {
-         cp_error ("no match for `%O(%#T, %#T)'", modifycode,
+         cp_error ("no match for `%Q(%#T, %#T)'", modifycode,
                    TREE_TYPE (lhs), TREE_TYPE (rhs));
          return error_mark_node;
        }
@@ -5567,6 +5588,12 @@ build_modify_expr (lhs, modifycode, rhs)
     {
       lhs = stabilize_reference (lhs);
       newrhs = build_binary_op (modifycode, lhs, rhs, 1);
+      if (newrhs == error_mark_node)
+       {
+         cp_error ("  in evaluation of `%Q(%#T, %#T)'", modifycode,
+                   TREE_TYPE (lhs), TREE_TYPE (rhs));
+         return error_mark_node;
+       }
     }
 
   /* Handle a cast used as an "lvalue".
@@ -6977,6 +7004,15 @@ c_expand_return (retval)
          && !TREE_PUBLIC (whats_returned))
        cp_warning_at ("address of local variable `%D' returned", whats_returned);
     }
+  else if (TREE_CODE (retval) == VAR_DECL)
+    {
+      if (TREE_CODE (TREE_TYPE (retval)) == ARRAY_TYPE
+         && DECL_NAME (retval)
+         && IDENTIFIER_LOCAL_VALUE (DECL_NAME (retval))
+         && !TREE_STATIC (retval)
+         && !TREE_PUBLIC (retval))
+       cp_warning_at ("address of local array `%D' returned", retval);
+    }
   
   /* Now deal with possible C++ hair:
      (1) Compute the return value.