45th Cygnus<->FSF merge
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 5 Aug 1994 20:25:20 +0000 (20:25 +0000)
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 5 Aug 1994 20:25:20 +0000 (20:25 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@7862 138bc75d-0d04-0410-961f-82ee72b054a4

18 files changed:
gcc/cp/ChangeLog
gcc/cp/Makefile.in
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/error.c
gcc/cp/init.c
gcc/cp/lex.c
gcc/cp/method.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/search.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/cp/typeck2.c

index 8a5d7fd..7ee24e6 100644 (file)
+Fri Aug  5 01:12:20 1994  Mike Stump  (mrs@cygnus.com)
+
+       * class.c (get_class_offset_1, get_class_offset): New routine to
+       find the offset of the class where a virtual function is defined,
+       from the complete type.
+       * class.c (modify_one_vtable, fixup_vtable_deltas): Use
+       get_class_offset instead of virtual_offset as get_class_offset will
+       always provide the right answer.
+       * tree.c (virtual_offset): Remove.  It only ever worked some of the
+       time.
+
+Tue Aug  2 12:44:21 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * call.c (build_method_call): Put back unary_complex_lvalue call
+       that I thought was redundant.
+
+       * typeck.c (c_expand_return): Fix a case I missed before.
+
+Sun Jul 31 17:54:02 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * pt.c (unify): Strip cv-quals from template type arguments (when
+       'const T*' is matched to 'const char*', that does not mean that T is
+       'const char').
+
+Fri Jul 29 01:03:06 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * pt.c (do_type_instantiation): Instantiate nested TAGS, not
+       typedefs.  Third time's the charm?
+
+       * parse.y (template_parm): Support default template parms.
+       * pt.c (process_template_parm): Ditto.
+       (end_template_parm_list): Ditto.
+       (coerce_template_parms): Ditto.
+       (mangle_class_name_for_template): Ditto.
+       (push_template_decls): Ditto.
+       (unify): Ditto.
+       * method.c (build_overload_identifier): Ditto.
+       * error.c (dump_decl): Ditto.
+
+Wed Jul 27 17:47:00 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * pt.c (do_type_instantiation): Only instantiate nested *classes*.
+
+Tue Jul 26 13:22:40 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * search.c (note_debug_info_needed): Also emit debugging information
+       for the types of fields.
+
+Mon Jul 25 00:34:44 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * pt.c (lookup_template_class): Pass 'template' to
+       coerce_template_parms instead of 'in_decl', since it's a more
+       meaningful context.
+
+       * typeck.c (c_expand_return): Make sure any cleanups for the return
+       expression get run.
+       (build_c_cast): Use CONVERT_EXPR for conversion to void.
+
+       * pt.c (do_type_instantiation): Also instantiate nested types.
+
+       * typeck.c (convert_for_assignment): Don't die when comparing
+       pointers with different levels of indirection.
+
+       * decl.c (grokdeclarator): The sub-call to grokdeclarator for
+       class-local typedefs sets DECL_ARGUMENTS, so we need to clear it
+       out.
+
+       * decl2.c (finish_anon_union): Don't die if the union has no
+       members.
+
+       * decl.c (grokdeclarator): Undo changes to declspecs when we're done
+       so that 'typedef int foo, bar;' will work.
+
+       * decl2.c (finish_file): Don't call expand_aggr_init for
+       non-aggregates.
+
+Mon Jul 25 00:03:10 1994  Teemu Torma  (tot@trema.fi)
+
+       * decl.c (finish_function): We can't inline constructors and
+       destructors under some conditions with -fpic, but don't unset
+       DECL_INLINE.
+
+Mon Jul 25 00:03:10 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * typeck.c (build_object_ref): Make sure 'datum' is a valid object.
+
+Sun Jul 24 14:19:31 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * class.c (finish_struct): Don't set DECL_FIELD_BITPOS on
+       non-fields.
+       (finish_struct_methods): Use copy_assignment_arg_p.
+
+       * cvt.c (cp_convert): If expr is an OFFSET_REF, resolve it instead
+       of giving an error.
+
+       * typeck.c (build_binary_op_nodefault): Don't set result_type if we
+       don't know how to compare the operands.
+
+       * decl.c (grokdeclarator): Avoid seg fault when someone uses '__op'
+       as a declarator-id in their program.  Like the Linux headers do.
+       Arrgh.
+
+       * tree.c (lvalue_p): Treat calls to functions returning objects by
+       value as lvalues again.
+
+       * typeck.c (build_component_addr): Use convert_force to convert the
+       pointer in case the component type is also a private base class.
+
+       * search.c (get_matching_virtual): Fix bogus warning of overloaded
+       virtual.
+
+       * pt.c (overload_template_name): Set DECL_ARTIFICIAL on the created
+       TYPE_DECL to fix bogus shadowing warnings.
+
+Fri Jul 22 01:15:32 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * init.c (expand_aggr_init_1): const and volatile mismatches do not
+       prevent a TARGET_EXPR from initializing an object directly.
+
+Tue Jul 19 17:55:37 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * cvt.c (build_up_reference): Allow building up references to
+       `this', don't warn about making references to artificial variables
+       (like `this').
+
+       * tree.c (lvalue_p): `this' is not an lvalue.
+
+       * call.c (build_method_call): Accept using a typedef name (or
+       template type parameter) for explicit destructor calls.
+
 Wed Jul 13 03:57:54 1994  Jason Merrill  (jason@deneb.cygnus.com)
 
-        * method.c (hack_identifier): Put back old code so lists of
-        non-functions will be handled properly.
+       * method.c (hack_identifier): Put back old code so lists of
+       non-functions will be handled properly.
 
-        * cp-tree.h (TYPE_NEEDS_CONSTRUCTING): #if 0 out; this macro is now
-        defined in the language-independent tree.h.
+       * cp-tree.h (TYPE_NEEDS_CONSTRUCTING): #if 0 out; this macro is now
+       defined in the language-independent tree.h.
 
-        * tree.c (count_functions): Avoid bogus warning when compiling this
-        function.
+       * tree.c (count_functions): Avoid bogus warning when compiling this
+       function.
 
 Mon Jul 11 18:37:20 1994  Jason Merrill  (jason@deneb.cygnus.com)
 
-        * decl.c (grok_reference_init): Always save the initializer of a
-        reference.
+       * decl.c (grok_reference_init): Always save the initializer of a
+       reference.
 
 Fri Jul  8 17:41:46 1994  Mike Stump  (mrs@cygnus.com)
 
@@ -36,7 +166,7 @@ Fri Jul  8 02:27:41 1994  Jason Merrill  (jason@deneb.cygnus.com)
 
        * decl.c (push_overloaded_decl): Don't create overloads of one when
        shadowing a class type.
-       * typeck.c (build_x_function_call): Complain about overloads of one
+       * typeck.c (build_x_function_call): Complain about overloads of one.
 
        * decl.c (grokdeclarator): Don't try to treat a char* as a tree.
        (grokdeclarator): Fix setting of TREE_STATIC.
index 231d1a3..fa0bd49 100644 (file)
@@ -193,7 +193,7 @@ parse.o : $(srcdir)/parse.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h
   `echo $(srcdir)/parse.c | sed 's,^\./,,'`
 
 $(srcdir)/parse.c $(srcdir)/parse.h : $(srcdir)/parse.y
-       @echo expect 1 shift/reduce confict and 33 reduce/reduce conflicts.
+       @echo expect 1 shift/reduce confict and 34 reduce/reduce conflicts.
        cd $(srcdir); $(BISON) $(BISONFLAGS) -d -o parse.c parse.y
        cd $(srcdir); grep '^#define[   ]*YYEMPTY' parse.c >>parse.h
 
index 3392a7a..254fd34 100644 (file)
@@ -1604,21 +1604,15 @@ build_method_call (instance, name, parms, basetype_path, flags)
       if (parms)
        error ("destructors take no parameters");
       basetype = TREE_TYPE (instance);
-      if (IS_AGGR_TYPE (basetype))
+      if (! ((IS_AGGR_TYPE (basetype)
+             && name == constructor_name (basetype))
+            || basetype == get_type_value (name)))
        {
-         if (name == constructor_name (basetype))
-           goto huzzah;
+         cp_error ("destructor name `~%D' does not match type `%T' of expression",
+                   name, basetype);
+         return void_zero_node;
        }
-      else
-       {
-         if (basetype == get_type_value (name))
-           goto huzzah;
-       }
-      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 e715c89..6c767bb 100644 (file)
@@ -1830,8 +1830,7 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
        {
          tree parmtype = TREE_VALUE (FUNCTION_ARG_CHAIN (fn_fields));
 
-         if (TREE_CODE (parmtype) == REFERENCE_TYPE
-             && TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)) == t)
+         if (copy_assignment_arg_p (parmtype, DECL_VIRTUAL_P (fn_fields)))
            {
              if (TREE_PROTECTED (fn_fields))
                TYPE_HAS_NONPUBLIC_ASSIGN_REF (t) = 1;
@@ -2151,6 +2150,86 @@ overrides (fndecl, base_fndecl)
   return 0;
 }
 
+static tree
+get_class_offset_1 (parent, binfo, context, t, fndecl)
+     tree parent, binfo, context, t, fndecl;
+{
+  tree binfos = BINFO_BASETYPES (binfo);
+  int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
+  tree rval = NULL_TREE;
+
+  if (binfo == parent)
+    return error_mark_node;
+
+  for (i = 0; i < n_baselinks; i++)
+    {
+      tree base_binfo = TREE_VEC_ELT (binfos, i);
+      tree nrval;
+
+      if (TREE_VIA_VIRTUAL (base_binfo))
+       base_binfo = binfo_member (BINFO_TYPE (base_binfo),
+                                  CLASSTYPE_VBASECLASSES (t));
+      nrval = get_class_offset_1 (parent, base_binfo, context, t, fndecl);
+      /* See if we have a new value */
+      if (nrval && (nrval != error_mark_node || rval==0))
+       {
+         /* Only compare if we have two offsets */
+         if (rval && rval != error_mark_node
+             && ! tree_int_cst_equal (nrval, rval))
+           {
+             /* Only give error if the two offsets are different */
+             error ("every virtual function must have a unique final overrider");
+             cp_error ("  found two (or more) `%T' class subobjects in `%T'", context, t);
+             cp_error ("  with virtual `%D' from virtual base class", fndecl);
+             return rval;
+           }
+         rval = nrval;
+       }
+       
+      if (rval && BINFO_TYPE (binfo) == context)
+       {
+         my_friendly_assert (rval == error_mark_node
+                             || tree_int_cst_equal (rval, BINFO_OFFSET (binfo)), 999);
+         rval = BINFO_OFFSET (binfo);
+       }
+    }
+  return rval;
+}
+
+/* Get the offset to the CONTEXT subobject that is related to the
+   given BINFO.  */
+static tree
+get_class_offset (context, t, binfo, fndecl)
+     tree context, t, binfo, fndecl;
+{
+  tree first_binfo = binfo;
+  tree offset;
+  int i;
+
+  if (context == t)
+    return integer_zero_node;
+
+  if (BINFO_TYPE (binfo) == context)
+    return BINFO_OFFSET (binfo);
+
+  /* Check less derived binfos first.  */
+  while (BINFO_BASETYPES (binfo)
+        && (i=CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo))) != -1)
+    {
+      tree binfos = BINFO_BASETYPES (binfo);
+      binfo = TREE_VEC_ELT (binfos, i);
+      if (BINFO_TYPE (binfo) == context)
+       return BINFO_OFFSET (binfo);
+    }
+
+  /* Ok, not found in the less derived binfos, now check the more
+     derived binfos. */
+  offset = get_class_offset_1 (first_binfo, TYPE_BINFO (t), context, t, fndecl);
+  if (offset==0 || TREE_CODE (offset) != INTEGER_CST)
+    my_friendly_abort (999);   /* we have to find it.  */
+  return offset;
+}
+
 static void
 modify_one_vtable (binfo, t, fndecl, pfn)
      tree binfo, t, fndecl, pfn;
@@ -2174,16 +2253,7 @@ modify_one_vtable (binfo, t, fndecl, pfn)
          tree vfield = CLASSTYPE_VFIELD (t);
          tree this_offset;
 
-         offset = integer_zero_node;
-         if (context != t && TYPE_USES_COMPLEX_INHERITANCE (t))
-           {
-             offset = virtual_offset (context, CLASSTYPE_VBASECLASSES (t), offset);
-             if (offset == NULL_TREE)
-               {
-                 tree binfo = get_binfo (context, t, 0);
-                 offset = BINFO_OFFSET (binfo);
-               }
-           }
+         offset = get_class_offset (context, t, binfo, fndecl);
 
          /* Find the right offset for the this pointer based on the
             base class we just found.  We have to take into
@@ -2288,16 +2358,7 @@ fixup_vtable_deltas (binfo, t)
          tree vfield = CLASSTYPE_VFIELD (t);
          tree this_offset;
 
-         offset = integer_zero_node;
-         if (context != t && TYPE_USES_COMPLEX_INHERITANCE (t))
-           {
-             offset = virtual_offset (context, CLASSTYPE_VBASECLASSES (t), offset);
-             if (offset == NULL_TREE)
-               {
-                 tree binfo = get_binfo (context, t, 0);
-                 offset = BINFO_OFFSET (binfo);
-               }
-           }
+         offset = get_class_offset (context, t, binfo, fndecl);
 
          /* Find the right offset for the this pointer based on the
             base class we just found.  We have to take into
@@ -3498,6 +3559,9 @@ finish_struct (t, list_of_fieldlists, warn_anon)
            tree uelt = TYPE_FIELDS (TREE_TYPE (field));
            for (; uelt; uelt = TREE_CHAIN (uelt))
              {
+               if (TREE_CODE (uelt) != FIELD_DECL)
+                 continue;
+
                DECL_FIELD_CONTEXT (uelt) = DECL_FIELD_CONTEXT (field);
                DECL_FIELD_BITPOS (uelt) = DECL_FIELD_BITPOS (field);
              }
@@ -3552,6 +3616,9 @@ finish_struct (t, list_of_fieldlists, warn_anon)
            tree uelt = TYPE_FIELDS (TREE_TYPE (field));
            for (; uelt; uelt = TREE_CHAIN (uelt))
              {
+               if (TREE_CODE (uelt) != FIELD_DECL)
+                 continue;
+
                DECL_FIELD_CONTEXT (uelt) = DECL_FIELD_CONTEXT (field);
                DECL_FIELD_BITPOS (uelt) = DECL_FIELD_BITPOS (field);
              }
index 80fd832..b6db695 100644 (file)
@@ -2254,7 +2254,6 @@ extern tree copy_binfo                            PROTO((tree));
 extern tree binfo_value                                PROTO((tree, tree));
 extern tree reverse_path                       PROTO((tree));
 extern tree virtual_member                     PROTO((tree, tree));
-extern tree virtual_offset                     PROTO((tree, tree, tree));
 extern void debug_binfo                                PROTO((tree));
 extern int decl_list_length                    PROTO((tree));
 extern int count_functions                     PROTO((tree));
index cb8d968..04f9bd3 100644 (file)
@@ -425,10 +425,11 @@ build_up_reference (type, arg, flags, checkconst)
       break;
 
     case PARM_DECL:
+#if 0
       if (targ == current_class_decl)
        {
          error ("address of `this' not available");
-#if 0
+/* #if 0 */      
          /* This code makes the following core dump the compiler on a sun4,
             if the code below is used.
 
@@ -465,16 +466,18 @@ build_up_reference (type, arg, flags, checkconst)
          TREE_ADDRESSABLE (targ) = 1; /* so compiler doesn't die later */
          put_var_into_stack (targ);
          break;
-#else
+/* #else */
          return error_mark_node;
-#endif
+/* #endif */     
        }
+#endif
       /* Fall through.  */
     case VAR_DECL:
     case CONST_DECL:
-      if (DECL_REGISTER (targ) && !TREE_ADDRESSABLE (targ))
-       warning ("address needed to build reference for `%s', which is declared `register'",
-                IDENTIFIER_POINTER (DECL_NAME (targ)));
+      if (DECL_REGISTER (targ) && !TREE_ADDRESSABLE (targ)
+         && !DECL_ARTIFICIAL (targ))
+       cp_warning ("address needed to build reference for `%D', which is declared `register'",
+                   targ);
       else if (staticp (targ))
        literal_flag = 1;
 
@@ -1206,6 +1209,9 @@ cp_convert (type, expr, convtype, flags)
   else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE)
     e = convert_from_reference (e);
 
+  if (TREE_CODE (e) == OFFSET_REF)
+    e = resolve_offset_ref (e);
+
   if (TREE_READONLY_DECL_P (e))
     e = decl_constant_value (e);
 
@@ -1223,10 +1229,7 @@ cp_convert (type, expr, convtype, flags)
          if (flag_pedantic_errors)
            return error_mark_node;
        }
-      if (form == OFFSET_TYPE)
-       cp_error_at ("pointer-to-member expression object not composed with type `%D' object",
-                    TYPE_NAME (TYPE_OFFSET_BASETYPE (intype)));
-      else if (IS_AGGR_TYPE (intype))
+      if (IS_AGGR_TYPE (intype))
        {
          tree rval;
          rval = build_type_conversion (CONVERT_EXPR, type, e, 1);
index 0690340..11ea6a2 100644 (file)
@@ -7091,7 +7091,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
          dname = decl;
          decl = NULL_TREE;
 
-         if (IDENTIFIER_OPNAME_P (dname))
+         if (! IDENTIFIER_OPNAME_P (dname)
+             /* Linux headers use '__op'.  Arrgh.  */
+             || IDENTIFIER_TYPENAME_P (dname) && ! TREE_TYPE (dname))
+           name = IDENTIFIER_POINTER (dname);
+         else
            {
              if (IDENTIFIER_TYPENAME_P (dname))
                {
@@ -7102,8 +7106,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
                }
              name = operator_name_string (dname);
            }
-         else
-           name = IDENTIFIER_POINTER (dname);
          break;
 
        case RECORD_TYPE:
@@ -7688,17 +7690,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
                break;
            }
 
-         if (scanner == IDENTIFIER_AS_LIST (ridpointers [(int) RID_TYPEDEF]))
-           {
-             if (previous_declspec)
-               TREE_CHAIN (previous_declspec)
-                 = IDENTIFIER_AS_LIST (ridpointers [(int) RID_STATIC]);
-             else
-               declspecs
-                 = IDENTIFIER_AS_LIST (ridpointers [(int) RID_STATIC]);
-           }
+         if (previous_declspec)
+           TREE_CHAIN (previous_declspec) = TREE_CHAIN (scanner);
          else
-           TREE_VALUE (scanner) = ridpointers[(int) RID_STATIC];
+           declspecs = TREE_CHAIN (scanner);
+
+         declspecs = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
+                                declspecs);
 
          /* In the recursive call to grokdeclarator we need to know
             whether we are working on a signature-local typedef.  */
@@ -7707,6 +7705,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
   
          loc_typedecl =
            grokdeclarator (declarator, declspecs, FIELD, 0, NULL_TREE);
+
+         if (previous_declspec)
+           TREE_CHAIN (previous_declspec) = scanner;
   
          if (loc_typedecl != error_mark_node)
            {
@@ -7714,6 +7715,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
              register int *pi;
   
              TREE_SET_CODE (loc_typedecl, TYPE_DECL);
+             /* This is the same field as DECL_ARGUMENTS, which is set for
+                function typedefs by the above grokdeclarator.  */
+             DECL_NESTED_TYPENAME (loc_typedecl) = 0;
   
              pi = (int *) permalloc (sizeof (struct lang_decl_flags));
              while (i > 0)
@@ -11529,20 +11533,19 @@ finish_function (lineno, call_poplevel)
   /* So we can tell if jump_optimize sets it to 1.  */
   can_reach_end = 0;
 
-  /* ??? Compensate for Sun brain damage in dealing with data segments
-     of PIC code.  */
-  if (flag_pic
-      && (DECL_CONSTRUCTOR_P (fndecl)
-         || DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
-      && CLASSTYPE_NEEDS_VIRTUAL_REINIT (TYPE_METHOD_BASETYPE (fntype)))
-    DECL_INLINE (fndecl) = 0;
-
   if (DECL_EXTERNAL (fndecl)
       /* This function is just along for the ride.  If we can make
         it inline, that's great.  Otherwise, just punt it.  */
       && (DECL_INLINE (fndecl) == 0
          || flag_no_inline
-         || function_cannot_inline_p (fndecl)))
+         || function_cannot_inline_p (fndecl)
+         /* ??? Compensate for Sun brain damage in dealing with
+            data segments of PIC code.  */
+         || (flag_pic
+             && (DECL_CONSTRUCTOR_P (fndecl)
+                 || DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
+             && CLASSTYPE_NEEDS_VIRTUAL_REINIT (TYPE_METHOD_BASETYPE (fntype)))))
+
     {
       extern int rtl_dump_and_exit;
       int old_rtl_dump_and_exit = rtl_dump_and_exit;
index 2b9f8a7..6579fe7 100644 (file)
@@ -2100,8 +2100,16 @@ finish_anon_union (anon_union_decl)
     }
   if (static_p)
     {
-      make_decl_rtl (main_decl, 0, global_bindings_p ());
-      DECL_RTL (anon_union_decl) = DECL_RTL (main_decl);
+      if (main_decl)
+       {
+         make_decl_rtl (main_decl, 0, global_bindings_p ());
+         DECL_RTL (anon_union_decl) = DECL_RTL (main_decl);
+       }
+      else
+       {
+         warning ("anonymous union with no members");
+         return;
+       }
     }
 
   /* The following call assumes that there are never any cleanups
@@ -2712,7 +2720,6 @@ finish_file ()
                    }
                }
              if (IS_AGGR_TYPE (TREE_TYPE (decl))
-                 || init == 0
                  || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
                expand_aggr_init (decl, init, 0);
              else if (TREE_CODE (init) == TREE_VEC)
index f431f6a..c427243 100644 (file)
@@ -671,13 +671,22 @@ dump_decl (t, v)
        for (i = 0; i < len; i++)
          {
            tree arg = TREE_VEC_ELT (args, i);
-           if (TREE_CODE (arg) == IDENTIFIER_NODE)
+           tree defval = TREE_PURPOSE (arg);
+           arg = TREE_VALUE (arg);
+           if (TREE_CODE (arg) == TYPE_DECL)
              {
                OB_PUTS ("class ");
-               OB_PUTID (arg);
+               OB_PUTID (DECL_NAME (arg));
              }
            else
              dump_decl (arg, 1);
+
+           if (defval)
+             {
+               OB_PUTS (" = ");
+               dump_decl (defval, 1);
+             }
+               
            OB_PUTC2 (',', ' ');
          }
        OB_UNPUT (2);
index 5e5d580..4aec96a 100644 (file)
@@ -1392,7 +1392,7 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags)
             separately from the object being initialized.  */
          if (TREE_CODE (init) == TARGET_EXPR)
            {
-             if (init_type == type)
+             if (TYPE_MAIN_VARIANT (init_type) == TYPE_MAIN_VARIANT (type))
                {
                  if (TREE_CODE (exp) == VAR_DECL
                      || TREE_CODE (exp) == RESULT_DECL)
index 5edf659..2d41cc6 100644 (file)
@@ -2875,7 +2875,7 @@ linenum:
                  if (c_header_level && --c_header_level == 0)
                    {
                      if (entering_c_header)
-                       warning ("Badly nested C headers from preprocessor");
+                       warning ("badly nested C headers from preprocessor");
                      --pending_lang_change;
                    }
                  if (flag_cadillac)
index f64a16a..853ada1 100644 (file)
@@ -463,9 +463,9 @@ build_overload_identifier (name)
       icat (nparms);
       for (i = 0; i < nparms; i++)
        {
-         tree parm = TREE_VEC_ELT (parmlist, i);
+         tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i));
          tree arg = TREE_VEC_ELT (arglist, i);
-         if (TREE_CODE (parm) == IDENTIFIER_NODE)
+         if (TREE_CODE (parm) == TYPE_DECL)
            {
              /* This parameter is a type.  */
              OB_PUTC ('Z');
index d30e511..9251a34 100644 (file)
@@ -221,7 +221,7 @@ empty_parms ()
 %type <ttype> type_id absdcl type_quals
 %type <ttype> direct_abstract_declarator conversion_declarator
 %type <ttype> new_type_id new_declarator direct_new_declarator
-%type <ttype> xexpr parmlist parms parm bad_parm
+%type <ttype> xexpr parmlist parms parm bad_parm full_parm
 %type <ttype> identifiers_or_typenames
 %type <ttype> fcast_or_absdcl regcast_or_absdcl sub_cast_expr
 %type <ttype> expr_or_declarator complex_notype_declarator
@@ -250,6 +250,7 @@ empty_parms ()
 %type <ttype> nonmomentary_expr
 %type <itype> forhead.2 initdcl0 notype_initdcl0 member_init_list
 %type <ttype> template_header template_parm_list template_parm
+%type <ttype> template_type_parm
 %type <ttype> template_type template_arg_list template_arg
 %type <ttype> template_instantiation template_type_name tmpl.2
 %type <ttype> template_instantiate_once template_instantiate_some
@@ -373,6 +374,20 @@ template_parm_list:
                { $$ = process_template_parm ($1, $3); }
        ;
 
+template_type_parm:
+         aggr
+               { 
+                 $$ = build_tree_list ($1, NULL_TREE);
+                ttpa:
+                 if (TREE_PURPOSE ($$) == signature_type_node)
+                   sorry ("signature as template type parameter");
+                 else if (TREE_PURPOSE ($$) != class_type_node)
+                   pedwarn ("template type parameters must use the keyword `class'");
+               }
+       | aggr identifier
+               { $$ = build_tree_list ($1, $2); goto ttpa; }
+       ;
+
 template_parm:
        /* The following rules introduce a new reduce/reduce
           conflict on the ',' and '>' input tokens: they are valid
@@ -381,24 +396,11 @@ template_parm:
           By putting them before the `parm' rule, we get
           their match before considering them nameless parameter
           declarations.  */
-         aggr identifier
-               {
-                 if ($1 == signature_type_node)
-                   sorry ("signature as template type parameter");
-                 else if ($1 != class_type_node)
-                   error ("template type parameter must use keyword `class'");
-                 $$ = build_tree_list ($2, NULL_TREE);
-               }
-       | aggr identifier_defn ':' base_class.1
-               {
-                 if ($1 == signature_type_node)
-                   sorry ("signature as template type parameter");
-                 else if ($1 != class_type_node)
-                   error ("template type parameter must use keyword `class'");
-                 warning ("restricted template type parameters not yet implemented");
-                 $$ = build_tree_list ($2, $4);
-               }
-       | parm
+         template_type_parm
+               { $$ = build_tree_list (NULL_TREE, $$); }
+       | template_type_parm '=' typespec
+               { $$ = build_tree_list ($3, $$); }
+       | full_parm
        ;
 
 overloaddef:
@@ -782,6 +784,8 @@ template_type:
 template_type_name:
          PTYPENAME '<' template_arg_list '>'
                { $$ = lookup_template_class ($$, $3, NULL_TREE); }
+       | PTYPENAME '<' '>'
+               { $$ = lookup_template_class ($$, NULL_TREE, NULL_TREE); }
        | TYPENAME  '<' template_arg_list '>'
                { $$ = lookup_template_class ($$, $3, NULL_TREE); }
        ;
@@ -3550,10 +3554,8 @@ parms:
                { $$ = build_tree_list (NULL_TREE, $$); }
        | parm '=' init
                { $$ = build_tree_list ($3, $$); }
-       | parms_comma parm
-               { $$ = chainon ($$, build_tree_list (NULL_TREE, $2)); }
-       | parms_comma parm '=' init
-               { $$ = chainon ($$, build_tree_list ($4, $2)); }
+       | parms_comma full_parm
+               { $$ = chainon ($$, $2); }
        | parms_comma bad_parm
                { $$ = chainon ($$, build_tree_list (NULL_TREE, $2)); }
        | parms_comma bad_parm '=' init
@@ -3599,6 +3601,13 @@ named_parm:
                { $$ = build_tree_list ($$, $2); }
        ;
 
+full_parm:
+         parm
+               { $$ = build_tree_list (NULL_TREE, $$); }
+       | parm '=' init
+               { $$ = build_tree_list ($3, $$); }
+       ;
+
 parm:
        named_parm
        | type_id
index c808cf4..e17354a 100644 (file)
@@ -81,18 +81,19 @@ process_template_parm (list, next)
 {
   tree parm;
   tree decl = 0;
+  tree defval;
   int is_type;
   parm = next;
   my_friendly_assert (TREE_CODE (parm) == TREE_LIST, 259);
-  is_type = TREE_CODE (TREE_PURPOSE (parm)) == IDENTIFIER_NODE;
+  defval = TREE_PURPOSE (parm);
+  parm = TREE_VALUE (parm);
+  is_type = TREE_PURPOSE (parm) == class_type_node;
   if (!is_type)
     {
       tree tinfo = 0;
-      parm = TREE_PURPOSE (parm);
-      my_friendly_assert (TREE_CODE (parm) == TREE_LIST, 260);
-      parm = TREE_VALUE (parm);
+      my_friendly_assert (TREE_CODE (TREE_PURPOSE (parm)) == TREE_LIST, 260);
       /* is a const-param */
-      parm = grokdeclarator (TREE_VALUE (next), TREE_PURPOSE (next),
+      parm = grokdeclarator (TREE_VALUE (parm), TREE_PURPOSE (parm),
                             PARM, 0, NULL_TREE);
       /* A template parameter is not modifiable.  */
       TREE_READONLY (parm) = 1;
@@ -117,11 +118,19 @@ process_template_parm (list, next)
   else
     {
       tree t = make_node (TEMPLATE_TYPE_PARM);
-      decl = build_decl (TYPE_DECL, TREE_PURPOSE (parm), t);
-      TYPE_NAME (t) = decl;
-      TREE_VALUE (parm) = t;
+      decl = build_decl (TYPE_DECL, TREE_VALUE (parm), t);
+      TYPE_MAIN_DECL (t) = decl;
+      parm = decl;
+      if (defval)
+       {
+         if (IDENTIFIER_HAS_TYPE_VALUE (defval))
+           defval = IDENTIFIER_TYPE_VALUE (defval);
+         else
+           defval = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (defval));
+       }
     }
   pushdecl (decl);
+  parm = build_tree_list (defval, parm);
   return chainon (list, parm);
 }
 
@@ -135,6 +144,7 @@ end_template_parm_list (parms)
      tree parms;
 {
   int nparms = 0;
+  int saw_default = 0;
   tree saved_parmlist;
   tree parm;
   for (parm = parms; parm; parm = TREE_CHAIN (parm))
@@ -143,13 +153,19 @@ end_template_parm_list (parms)
 
   for (parm = parms, nparms = 0; parm; parm = TREE_CHAIN (parm), nparms++)
     {
-      tree p = parm;
-      if (TREE_CODE (p) == TREE_LIST)
+      tree p = TREE_VALUE (parm);
+      if (TREE_PURPOSE (parm))
+       saw_default = 1;
+      else if (saw_default)
+       {
+         error ("if a default argument is given for one template parameter");
+         error ("default arguments must be given for all subsequent");
+         error ("parameters as well");
+       }
+
+      if (TREE_CODE (p) == TYPE_DECL)
        {
-         tree t = TREE_VALUE (p);
-         TREE_VALUE (p) = NULL_TREE;
-         p = TREE_PURPOSE (p);
-         my_friendly_assert (TREE_CODE (p) == IDENTIFIER_NODE, 261);
+         tree t = TREE_TYPE (p);
          TEMPLATE_TYPE_SET_INFO (t, saved_parmlist, nparms);
        }
       else
@@ -158,7 +174,7 @@ end_template_parm_list (parms)
          DECL_INITIAL (p) = NULL_TREE;
          TEMPLATE_CONST_SET_INFO (tinfo, saved_parmlist, nparms);
        }
-      TREE_VEC_ELT (saved_parmlist, nparms) = p;
+      TREE_VEC_ELT (saved_parmlist, nparms) = parm;
     }
   set_current_level_tags_transparency (1);
   processing_template_decl++;
@@ -354,47 +370,63 @@ coerce_template_parms (parms, arglist, in_decl)
      tree parms, arglist;
      tree in_decl;
 {
-  int nparms, i, lost = 0;
+  int nparms, nargs, i, lost = 0;
   tree vec;
 
-  if (TREE_CODE (arglist) == TREE_VEC)
-    nparms = TREE_VEC_LENGTH (arglist);
+  if (arglist == NULL_TREE)
+    nargs = 0;
+  else if (TREE_CODE (arglist) == TREE_VEC)
+    nargs = TREE_VEC_LENGTH (arglist);
   else
-    nparms = list_length (arglist);
-  if (nparms != TREE_VEC_LENGTH (parms))
+    nargs = list_length (arglist);
+
+  nparms = TREE_VEC_LENGTH (parms);
+
+  if (nargs > nparms
+      || (nargs < nparms
+         && TREE_PURPOSE (TREE_VEC_ELT (parms, nargs)) == NULL_TREE))
     {
       error ("incorrect number of parameters (%d, should be %d)",
-            nparms, TREE_VEC_LENGTH (parms));
+            nargs, nparms);
       if (in_decl)
        cp_error_at ("in template expansion for decl `%D'", in_decl);
       return error_mark_node;
     }
 
-  if (TREE_CODE (arglist) == TREE_VEC)
+  if (arglist && TREE_CODE (arglist) == TREE_VEC)
     vec = copy_node (arglist);
   else
     {
       vec = make_tree_vec (nparms);
       for (i = 0; i < nparms; i++)
        {
-         tree arg = arglist;
-         arglist = TREE_CHAIN (arglist);
-         if (arg == error_mark_node)
-           lost++;
+         tree arg;
+
+         if (arglist)
+           {
+             arg = arglist;
+             arglist = TREE_CHAIN (arglist);
+
+             if (arg == error_mark_node)
+               lost++;
+             else
+               arg = TREE_VALUE (arg);
+           }
          else
-           arg = TREE_VALUE (arg);
+           arg = TREE_PURPOSE (TREE_VEC_ELT (parms, i));
+
          TREE_VEC_ELT (vec, i) = arg;
        }
     }
   for (i = 0; i < nparms; i++)
     {
       tree arg = TREE_VEC_ELT (vec, i);
-      tree parm = TREE_VEC_ELT (parms, i);
+      tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
       tree val = 0;
       int is_type, requires_type;
 
       is_type = TREE_CODE_CLASS (TREE_CODE (arg)) == 't';
-      requires_type = TREE_CODE (parm) == IDENTIFIER_NODE;
+      requires_type = TREE_CODE (parm) == TYPE_DECL;
       if (is_type != requires_type)
        {
          if (in_decl)
@@ -415,7 +447,7 @@ coerce_template_parms (parms, arglist, in_decl)
        {
          grok_template_type (vec, &TREE_TYPE (parm));
          val = digest_init (TREE_TYPE (parm), arg, (tree *) 0);
-         
+
          if (val == error_mark_node)
            ;
 
@@ -489,12 +521,13 @@ mangle_class_name_for_template (name, parms, arglist)
   my_friendly_assert (nparms == TREE_VEC_LENGTH (arglist), 268);
   for (i = 0; i < nparms; i++)
     {
-      tree parm = TREE_VEC_ELT (parms, i), arg = TREE_VEC_ELT (arglist, i);
+      tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+      tree arg = TREE_VEC_ELT (arglist, i);
 
       if (i)
        ccat (',');
 
-      if (TREE_CODE (parm) == IDENTIFIER_NODE)
+      if (TREE_CODE (parm) == TYPE_DECL)
        {
          cat (type_as_string (arg, 0));
          continue;
@@ -573,7 +606,7 @@ lookup_template_class (d1, arglist, in_decl)
     }
   parmlist = DECL_TEMPLATE_PARMS (template);
 
-  arglist = coerce_template_parms (parmlist, arglist, in_decl);
+  arglist = coerce_template_parms (parmlist, arglist, template);
   if (arglist == error_mark_node)
     return error_mark_node;
   if (uses_template_parms (arglist))
@@ -619,11 +652,11 @@ push_template_decls (parmlist, arglist, class_level)
   for (i = 0; i < nparms; i++)
     {
       int requires_type, is_type;
-      tree parm = TREE_VEC_ELT (parmlist, i);
+      tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i));
       tree arg = TREE_VEC_ELT (arglist, i);
       tree decl = 0;
 
-      requires_type = TREE_CODE (parm) == IDENTIFIER_NODE;
+      requires_type = TREE_CODE (parm) == TYPE_DECL;
       is_type = TREE_CODE_CLASS (TREE_CODE (arg)) == 't';
       if (is_type)
        {
@@ -635,7 +668,7 @@ push_template_decls (parmlist, arglist, class_level)
            }
          decl = arg;
          my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 't', 273);
-         decl = build_decl (TYPE_DECL, parm, decl);
+         decl = build_decl (TYPE_DECL, DECL_NAME (parm), decl);
        }
       else
        {
@@ -878,9 +911,8 @@ instantiate_member_templates (classname)
        case 1:
          /* Failure.  */
        failure:
-         cp_error ("type unification error instantiating %T::%D",
-                     classname, tdecl);
-         cp_error_at ("for template declaration `%D'", tdecl);
+         cp_error_at ("type unification error instantiating `%D'", tdecl);
+         cp_error ("while instantiating members of `%T'", classname);
 
          continue /* loop of members */;
        default:
@@ -1781,6 +1813,7 @@ overload_template_name (id, classlevel)
                      || TREE_CODE (t) == UNINSTANTIATED_P_TYPE, 286);
 
   decl = build_decl (TYPE_DECL, template, t);
+  SET_DECL_ARTIFICIAL (decl);
 
 #if 0 /* fix this later */
   /* We don't want to call here if the work has already been done.  */
@@ -2035,22 +2068,20 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
          return 1;
        }
       idx = TEMPLATE_TYPE_IDX (parm);
+      /* Template type parameters cannot contain cv-quals; i.e.
+         template <class T> void f (T& a, T& b) will not generate
+        void f (const int& a, const int& b).  */
+      if (TYPE_READONLY (arg) > TYPE_READONLY (parm)
+         || TYPE_VOLATILE (arg) > TYPE_VOLATILE (parm))
+       return 1;
+      arg = TYPE_MAIN_VARIANT (arg);
       /* Simple cases: Value already set, does match or doesn't.  */
       if (targs[idx] == arg)
        return 0;
       else if (targs[idx])
-       {
-         if (TYPE_MAIN_VARIANT (targs[idx]) == TYPE_MAIN_VARIANT (arg))
-           /* allow different parms to have different cv-qualifiers */;
-         else
-           return 1;
-       }
-      /* Check for mixed types and values.  */
-      if (TREE_CODE (TREE_VEC_ELT (tparms, idx)) != IDENTIFIER_NODE)
        return 1;
-      /* Allow trivial conversions.  */
-      if (TYPE_READONLY (parm) < TYPE_READONLY (arg)
-         || TYPE_VOLATILE (parm) < TYPE_VOLATILE (arg))
+      /* Check for mixed types and values.  */
+      if (TREE_CODE (TREE_VALUE (TREE_VEC_ELT (tparms, idx))) != TYPE_DECL)
        return 1;
       targs[idx] = arg;
       return 0;
@@ -2399,12 +2430,11 @@ do_type_instantiation (name, storage)
   tree t = TREE_TYPE (name);
   int extern_p;
 
+  /* With -fexternal-templates, explicit instantiations are treated the same
+     as implicit ones.  */
   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",
@@ -2423,6 +2453,14 @@ do_type_instantiation (name, storage)
       extern_p = 0;
     }
 
+  /* We've already instantiated this.  */
+  if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && ! CLASSTYPE_INTERFACE_ONLY (t))
+    {
+      if (! extern_p)
+       cp_pedwarn ("multiple explicit instantiation of `%#T'", t);
+      return;
+    }
+
   SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t);
   CLASSTYPE_VTABLE_NEEDS_WRITING (t) = ! extern_p;
   SET_CLASSTYPE_INTERFACE_KNOWN (t);
@@ -2436,17 +2474,26 @@ do_type_instantiation (name, storage)
 
   /* this should really be done by instantiate_member_templates */
   {
-    tree method = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0);
-    for (; method; method = TREE_CHAIN (method))
+    tree tmp = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0);
+    for (; tmp; tmp = TREE_CHAIN (tmp))
       {
-       SET_DECL_EXPLICIT_INSTANTIATION (method);
-       TREE_PUBLIC (method) = 1;
-       DECL_EXTERNAL (method)
-         = (extern_p || (DECL_INLINE (method) && ! flag_implement_inlines));
+       SET_DECL_EXPLICIT_INSTANTIATION (tmp);
+       TREE_PUBLIC (tmp) = 1;
+       DECL_EXTERNAL (tmp)
+         = (extern_p || (DECL_INLINE (tmp) && ! flag_implement_inlines));
       }
-  }
 
-  /* and data member templates, too */
+#if 0
+    for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp))
+      {
+       if (TREE_CODE (tmp) == VAR_DECL)
+         /* eventually do something */;
+      }
+#endif
+
+    for (tmp = CLASSTYPE_TAGS (t); tmp; tmp = TREE_CHAIN (tmp))
+      do_type_instantiation (TREE_VALUE (tmp), storage);
+  }
 }
 
 tree
index c4c6a4e..6623ab4 100644 (file)
@@ -1913,6 +1913,10 @@ get_matching_virtual (binfo, fndecl, dtorp)
       if (IDENTIFIER_VIRTUAL_P (declarator) == 0)
        return NULL_TREE;
 
+      baselink = get_virtuals_named_this (binfo);
+      if (baselink == NULL_TREE)
+       return NULL_TREE;
+
       drettype = TREE_TYPE (TREE_TYPE (fndecl));
       dtypes = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
       if (DECL_STATIC_FUNCTION_P (fndecl))
@@ -1920,8 +1924,7 @@ get_matching_virtual (binfo, fndecl, dtorp)
       else
        instptr_type = TREE_TYPE (TREE_VALUE (dtypes));
 
-      for (baselink = get_virtuals_named_this (binfo);
-          baselink; baselink = next_baselink (baselink))
+      for (; baselink; baselink = next_baselink (baselink))
        {
          for (tmp = TREE_VALUE (baselink); tmp; tmp = DECL_CHAIN (tmp))
            {
@@ -1945,7 +1948,7 @@ get_matching_virtual (binfo, fndecl, dtorp)
                      && ! comptypes (TREE_TYPE (TREE_TYPE (tmp)), drettype, 1))
                    {
                      cp_error ("conflicting return type specified for virtual function `%#D'", fndecl);
-                     cp_error ("overriding definition as `%#D'", tmp);
+                     cp_error_at ("overriding definition as `%#D'", tmp);
                      SET_IDENTIFIER_ERROR_LOCUS (name, basetype);
                    }
                  break;
@@ -2697,13 +2700,22 @@ free_mi_matrix ()
 /* If we want debug info for a type TYPE, make sure all its base types
    are also marked as being potentially interesting.  This avoids
    the problem of not writing any debug info for intermediate basetypes
-   that have abstract virtual functions.  */
+   that have abstract virtual functions.  Also mark member types.  */
 
 void
 note_debug_info_needed (type)
      tree type;
 {
+  tree field;
   dfs_walk (TYPE_BINFO (type), dfs_debug_mark, dfs_debug_unmarkedp);
+  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+    {
+      tree ttype;
+      if (TREE_CODE (field) == FIELD_DECL
+         && IS_AGGR_TYPE (ttype = target_type (TREE_TYPE (field)))
+         && dfs_debug_unmarkedp (TYPE_BINFO (ttype)))
+       note_debug_info_needed (ttype);
+    }
 }
 \f
 /* Subroutines of push_class_decls ().  */
index 88466b8..7d92b4e 100644 (file)
@@ -35,66 +35,75 @@ int
 lvalue_p (ref)
      tree ref;
 {
-  register enum tree_code code = TREE_CODE (ref);
+  if (! language_lvalue_valid (ref))
+    return 0;
+  
+  if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
+    return 1;
 
-  if (language_lvalue_valid (ref))
+  if (ref == current_class_decl && flag_this_is_variable <= 0)
+    return 0;
+
+  switch (TREE_CODE (ref))
     {
-      if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
+      /* preincrements and predecrements are valid lvals, provided
+        what they refer to are valid lvals. */
+    case PREINCREMENT_EXPR:
+    case PREDECREMENT_EXPR:
+    case COMPONENT_REF:
+    case SAVE_EXPR:
+      return lvalue_p (TREE_OPERAND (ref, 0));
+
+    case STRING_CST:
+      return 1;
+
+    case VAR_DECL:
+      if (TREE_READONLY (ref) && ! TREE_STATIC (ref)
+         && DECL_LANG_SPECIFIC (ref)
+         && DECL_IN_AGGR_P (ref))
+       return 0;
+    case INDIRECT_REF:
+    case ARRAY_REF:
+    case PARM_DECL:
+    case RESULT_DECL:
+    case ERROR_MARK:
+      if (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
+         && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE)
        return 1;
-      
-      switch (code)
-       {
-         /* preincrements and predecrements are valid lvals, provided
-            what they refer to are valid lvals. */
-       case PREINCREMENT_EXPR:
-       case PREDECREMENT_EXPR:
-       case COMPONENT_REF:
-       case SAVE_EXPR:
-         return lvalue_p (TREE_OPERAND (ref, 0));
-
-       case STRING_CST:
-         return 1;
-
-       case VAR_DECL:
-         if (TREE_READONLY (ref) && ! TREE_STATIC (ref)
-             && DECL_LANG_SPECIFIC (ref)
-             && DECL_IN_AGGR_P (ref))
-           return 0;
-       case INDIRECT_REF:
-       case ARRAY_REF:
-       case PARM_DECL:
-       case RESULT_DECL:
-       case ERROR_MARK:
-         if (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
-             && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE)
-           return 1;
-         break;
+      break;
 
-       case TARGET_EXPR:
-       case WITH_CLEANUP_EXPR:
-         return 1;
-
-         /* A currently unresolved scope ref.  */
-       case SCOPE_REF:
-         my_friendly_abort (103);
-       case OFFSET_REF:
-         if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL)
-           return 1;
-         return lvalue_p (TREE_OPERAND (ref, 0))
-           && lvalue_p (TREE_OPERAND (ref, 1));
-         break;
+    case WITH_CLEANUP_EXPR:
+      return lvalue_p (TREE_OPERAND (ref, 0));
+
+    case TARGET_EXPR:
+      return 1;
 
-       case COND_EXPR:
-         return (lvalue_p (TREE_OPERAND (ref, 1))
-                 && lvalue_p (TREE_OPERAND (ref, 2)));
+    case CALL_EXPR:
+      if (TREE_ADDRESSABLE (TREE_TYPE (ref)))
+       return 1;
+      break;
 
-       case MODIFY_EXPR:
-         return 1;
+      /* A currently unresolved scope ref.  */
+    case SCOPE_REF:
+      my_friendly_abort (103);
+    case OFFSET_REF:
+      if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL)
+       return 1;
+      return lvalue_p (TREE_OPERAND (ref, 0))
+       && lvalue_p (TREE_OPERAND (ref, 1));
+      break;
 
-       case COMPOUND_EXPR:
-         return lvalue_p (TREE_OPERAND (ref, 1));
-       }
+    case COND_EXPR:
+      return (lvalue_p (TREE_OPERAND (ref, 1))
+             && lvalue_p (TREE_OPERAND (ref, 2)));
+
+    case MODIFY_EXPR:
+      return 1;
+
+    case COMPOUND_EXPR:
+      return lvalue_p (TREE_OPERAND (ref, 1));
     }
+
   return 0;
 }
 
@@ -1184,50 +1193,6 @@ virtual_member (elem, list)
   return rval;
 }
 
-/* Return the offset (as an INTEGER_CST) for ELEM in LIST.
-   INITIAL_OFFSET is the value to add to the offset that ELEM's
-   binfo entry in LIST provides.
-
-   Returns NULL if ELEM does not have an binfo value in LIST.  */
-
-tree
-virtual_offset (elem, list, initial_offset)
-     tree elem;
-     tree list;
-     tree initial_offset;
-{
-  tree vb, offset;
-  tree rval, nval;
-
-  for (vb = list; vb; vb = TREE_CHAIN (vb))
-    if (elem == BINFO_TYPE (vb))
-      return size_binop (PLUS_EXPR, initial_offset, BINFO_OFFSET (vb));
-  rval = 0;
-  for (vb = list; vb; vb = TREE_CHAIN (vb))
-    {
-      tree binfos = BINFO_BASETYPES (vb);
-      int i;
-
-      if (binfos == NULL_TREE)
-       continue;
-
-      for (i = TREE_VEC_LENGTH (binfos)-1; i >= 0; i--)
-       {
-         nval = binfo_value (elem, BINFO_TYPE (TREE_VEC_ELT (binfos, i)));
-         if (nval)
-           {
-             if (rval && BINFO_OFFSET (nval) != BINFO_OFFSET (rval))
-               my_friendly_abort (105);
-             offset = BINFO_OFFSET (vb);
-             rval = nval;
-           }
-       }
-    }
-  if (rval == NULL_TREE)
-    return rval;
-  return size_binop (PLUS_EXPR, offset, BINFO_OFFSET (rval));
-}
-
 void
 debug_binfo (elem)
      tree elem;
index fe8e7ba..a25e143 100644 (file)
@@ -1410,8 +1410,19 @@ tree
 build_object_ref (datum, basetype, field)
      tree datum, basetype, field;
 {
+  tree dtype;
   if (datum == error_mark_node)
     return error_mark_node;
+
+  dtype = TREE_TYPE (datum);
+  if (TREE_CODE (dtype) == REFERENCE_TYPE)
+    dtype = TREE_TYPE (dtype);
+  if (! IS_AGGR_TYPE_CODE (TREE_CODE (dtype)))
+    {
+      cp_error ("request for member `%T::%D' in expression of non-aggregate type `%T'",
+               basetype, field, dtype);
+      return error_mark_node;
+    }
   else if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (basetype)))
     {
       warning ("signature name in scope resolution ignored");
@@ -3247,6 +3258,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
     case GE_EXPR:
     case LT_EXPR:
     case GT_EXPR:
+      result_type = bool_type_node;
       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
           && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
        short_compare = 1;
@@ -3295,7 +3307,8 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
            warning ("comparison between pointer and integer");
          op0 = convert (TREE_TYPE (op1), op0);
        }
-      result_type = bool_type_node;
+      else
+       result_type = 0;
       converted = 1;
       break;
     }
@@ -3717,7 +3730,7 @@ build_component_addr (arg, argtype, msg)
     }
   else
     /* This conversion is harmless.  */
-    rval = convert (argtype, rval);
+    rval = convert_force (argtype, rval);
 
   if (! integer_zerop (DECL_FIELD_BITPOS (field)))
     {
@@ -4939,7 +4952,7 @@ build_c_cast (type, expr)
     value = TREE_VALUE (value);
 
   if (TREE_CODE (type) == VOID_TYPE)
-    value = build1 (NOP_EXPR, type, value);
+    value = build1 (CONVERT_EXPR, type, value);
   else if (TREE_TYPE (value) == NULL_TREE
       || type_unknown_p (value))
     {
@@ -6445,7 +6458,8 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
                add_quals = 1;
              left_const &= TYPE_READONLY (ttl);
 
-             if (TREE_CODE (ttl) != POINTER_TYPE)
+             if (TREE_CODE (ttl) != POINTER_TYPE
+                 || TREE_CODE (ttr) != POINTER_TYPE)
                break;
            }
          unsigned_parity = TREE_UNSIGNED (ttl) - TREE_UNSIGNED (ttr);
@@ -7028,6 +7042,7 @@ c_expand_return (retval)
          && TREE_CODE (TREE_OPERAND (retval, 0)) == TARGET_EXPR)
        retval = TREE_OPERAND (retval, 0);
       expand_aggr_init (result, retval, 0);
+      expand_cleanups_to (NULL_TREE);
       DECL_INITIAL (result) = NULL_TREE;
       retval = 0;
     }
@@ -7046,6 +7061,7 @@ c_expand_return (retval)
               && any_pending_cleanups (1))
        {
          retval = get_temp_regvar (valtype, retval);
+         expand_cleanups_to (NULL_TREE);
          use_temp = obey_regdecls;
          result = 0;
        }
@@ -7071,7 +7087,10 @@ c_expand_return (retval)
     {
       /* Everything's great--RETVAL is in RESULT.  */
       if (original_result_rtx)
-       store_expr (result, original_result_rtx, 0);
+       {
+         store_expr (result, original_result_rtx, 0);
+         expand_cleanups_to (NULL_TREE);
+       }
       else if (retval && retval != result)
        {
          /* Clear this out so the later call to decl_function_context
@@ -7083,6 +7102,7 @@ c_expand_return (retval)
             RESULT from cleanups.  */
          retval = build (INIT_EXPR, TREE_TYPE (result), result, retval);
          TREE_SIDE_EFFECTS (retval) = 1;
+         retval = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (result), retval);
          expand_return (retval);
        }
       else
index 871173f..87cf58c 100644 (file)
@@ -329,7 +329,7 @@ ack (s, v, v2)
    silly.  So instead, we just do the equivalent of a call to fatal in the
    same situation (call exit).  */
 
-/* First used: 0 (reserved), Last used: 360.  Free:  */
+/* First used: 0 (reserved), Last used: 360.  Free: 261.  */
 
 static int abortcount = 0;