OSDN Git Service

* c-opts.c (set_std_cxx98, set_std_c89): New.
[pf3gnuchains/gcc-fork.git] / gcc / cp / class.c
index aa83b8d..db8cfa7 100644 (file)
@@ -33,10 +33,7 @@ Boston, MA 02111-1307, USA.  */
 #include "toplev.h"
 #include "ggc.h"
 #include "lex.h"
-
-#include "obstack.h"
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
+#include "target.h"
 
 /* The number of nested classes being processed.  If we are not in the
    scope of any class, this is zero.  */
@@ -113,7 +110,6 @@ static int build_primary_vtable PARAMS ((tree, tree));
 static int build_secondary_vtable PARAMS ((tree, tree));
 static void finish_vtbls PARAMS ((tree));
 static void modify_vtable_entry PARAMS ((tree, tree, tree, tree, tree *));
-static void add_virtual_function PARAMS ((tree *, tree *, int *, tree, tree));
 static tree delete_duplicate_fields_1 PARAMS ((tree, tree));
 static void delete_duplicate_fields PARAMS ((tree));
 static void finish_struct_bits PARAMS ((tree));
@@ -149,8 +145,8 @@ static void check_methods PARAMS ((tree));
 static void remove_zero_width_bit_fields PARAMS ((tree));
 static void check_bases PARAMS ((tree, int *, int *, int *));
 static void check_bases_and_members PARAMS ((tree, int *));
-static tree create_vtable_ptr PARAMS ((tree, int *, int *, tree *, tree *));
-static void layout_class_type PARAMS ((tree, int *, int *, tree *, tree *));
+static tree create_vtable_ptr PARAMS ((tree, int *, tree *));
+static void layout_class_type PARAMS ((tree, int *, int *, tree *));
 static void fixup_pending_inline PARAMS ((tree));
 static void fixup_inline_methods PARAMS ((tree));
 static void set_primary_base PARAMS ((tree, tree, int *));
@@ -289,12 +285,9 @@ build_base_path (code, expr, binfo, nonnull)
     }
 
   fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
-  if (fixed_type_p < 0)
-    /* Virtual base layout is not fixed, even in ctors and dtors. */
-    fixed_type_p = 0;
-  if (!fixed_type_p && TREE_SIDE_EFFECTS (expr))
+  if (fixed_type_p <= 0 && TREE_SIDE_EFFECTS (expr))
     expr = save_expr (expr);
-    
+
   if (!want_pointer)
     expr = build_unary_op (ADDR_EXPR, expr, 0);
   else if (!nonnull)
@@ -302,7 +295,7 @@ build_base_path (code, expr, binfo, nonnull)
   
   offset = BINFO_OFFSET (binfo);
   
-  if (v_binfo && !fixed_type_p)
+  if (v_binfo && fixed_type_p <= 0)
     {
       /* Going via virtual base V_BINFO.  We need the static offset
          from V_BINFO to BINFO, and the dynamic offset from D_BINFO to
@@ -318,12 +311,23 @@ build_base_path (code, expr, binfo, nonnull)
                         build_pointer_type (ptrdiff_type_node),
                         v_offset);
       v_offset = build_indirect_ref (v_offset, NULL);
-      
+      TREE_CONSTANT (v_offset) = 1;
+
       offset = cp_convert (ptrdiff_type_node,
                           size_diffop (offset, BINFO_OFFSET (v_binfo)));
 
       if (!integer_zerop (offset))
-       offset = build (code, ptrdiff_type_node, v_offset, offset);
+       v_offset = build (code, ptrdiff_type_node, v_offset, offset);
+
+      if (fixed_type_p < 0)
+       /* Negative fixed_type_p means this is a constructor or destructor;
+          virtual base layout is fixed in in-charge [cd]tors, but not in
+          base [cd]tors.  */
+       offset = build (COND_EXPR, ptrdiff_type_node,
+                       build (EQ_EXPR, boolean_type_node,
+                              current_in_charge_parm, integer_zero_node),
+                       v_offset,
+                       BINFO_OFFSET (binfo));
       else
        offset = v_offset;
     }
@@ -350,10 +354,28 @@ build_base_path (code, expr, binfo, nonnull)
     expr = build (COND_EXPR, target_type, null_test,
                  build1 (NOP_EXPR, target_type, integer_zero_node),
                  expr);
-  
+
   return expr;
 }
 
+/* Convert OBJECT to the base TYPE.  If CHECK_ACCESS is true, an error
+   message is emitted if TYPE is inaccessible.  OBJECT is assumed to
+   be non-NULL.  */
+
+tree
+convert_to_base (tree object, tree type, bool check_access)
+{
+  tree binfo;
+
+  binfo = lookup_base (TREE_TYPE (object), type, 
+                      check_access ? ba_check : ba_ignore, 
+                      NULL);
+  if (!binfo || binfo == error_mark_node)
+    return error_mark_node;
+
+  return build_base_path (PLUS_EXPR, object, binfo, /*nonnull=*/1);
+}
+
 \f
 /* Virtual function things.  */
 
@@ -393,75 +415,36 @@ static tree
 build_vtbl_ref_1 (instance, idx)
      tree instance, idx;
 {
-  tree vtbl, aref;
-  tree basetype = TREE_TYPE (instance);
+  tree aref;
+  tree vtbl = NULL_TREE;
+
+  /* Try to figure out what a reference refers to, and
+     access its virtual function table directly.  */
+
+  int cdtorp = 0;
+  tree fixed_type = fixed_type_or_null (instance, NULL, &cdtorp);
 
+  tree basetype = TREE_TYPE (instance);
   if (TREE_CODE (basetype) == REFERENCE_TYPE)
     basetype = TREE_TYPE (basetype);
 
-  if (instance == current_class_ref)
-    vtbl = build_vfield_ref (instance, basetype);
-  else
+  if (fixed_type && !cdtorp)
     {
-      if (optimize)
-       {
-         /* Try to figure out what a reference refers to, and
-            access its virtual function table directly.  */
-         tree ref = NULL_TREE;
-
-         if (TREE_CODE (instance) == INDIRECT_REF
-             && TREE_CODE (TREE_TYPE (TREE_OPERAND (instance, 0))) == REFERENCE_TYPE)
-           ref = TREE_OPERAND (instance, 0);
-         else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
-           ref = instance;
-
-         if (ref && TREE_CODE (ref) == VAR_DECL
-             && DECL_INITIAL (ref))
-           {
-             tree init = DECL_INITIAL (ref);
-
-             while (TREE_CODE (init) == NOP_EXPR
-                    || TREE_CODE (init) == NON_LVALUE_EXPR)
-               init = TREE_OPERAND (init, 0);
-             if (TREE_CODE (init) == ADDR_EXPR)
-               {
-                 init = TREE_OPERAND (init, 0);
-                 if (IS_AGGR_TYPE (TREE_TYPE (init))
-                     && (TREE_CODE (init) == PARM_DECL
-                         || TREE_CODE (init) == VAR_DECL))
-                   instance = init;
-               }
-           }
-       }
+      tree binfo = lookup_base (fixed_type, basetype,
+                               ba_ignore|ba_quiet, NULL);
+      if (binfo)
+       vtbl = BINFO_VTABLE (binfo);
+    }
 
-      if (IS_AGGR_TYPE (TREE_TYPE (instance))
-         && (TREE_CODE (instance) == RESULT_DECL
-             || TREE_CODE (instance) == PARM_DECL
-             || TREE_CODE (instance) == VAR_DECL))
-       {
-         vtbl = TYPE_BINFO_VTABLE (basetype);
-         /* Knowing the dynamic type of INSTANCE we can easily obtain
-            the correct vtable entry.  We resolve this back to be in
-            terms of the primary vtable.  */
-         if (TREE_CODE (vtbl) == PLUS_EXPR)
-           {
-             idx = fold (build (PLUS_EXPR,
-                                TREE_TYPE (idx),
-                                idx,
-                                build (EXACT_DIV_EXPR,
-                                       TREE_TYPE (idx),
-                                       TREE_OPERAND (vtbl, 1),
-                                       TYPE_SIZE_UNIT (vtable_entry_type))));
-             vtbl = get_vtbl_decl_for_binfo (TYPE_BINFO (basetype));
-           }
-       }
-      else
-       vtbl = build_vfield_ref (instance, basetype);
+  if (!vtbl)
+    {
+      vtbl = build_vfield_ref (instance, basetype);
     }
 
   assemble_external (vtbl);
 
   aref = build_array_ref (vtbl, idx);
+  TREE_CONSTANT (aref) = 1;
 
   return aref;
 }
@@ -540,6 +523,8 @@ build_vtable (class_type, name, vtable_type)
   TREE_STATIC (decl) = 1;
   TREE_READONLY (decl) = 1;
   DECL_VIRTUAL_P (decl) = 1;
+  DECL_ALIGN (decl) = TARGET_VTABLE_ENTRY_ALIGN;
+
   import_export_vtable (decl, class_type, 0);
 
   return decl;
@@ -784,61 +769,6 @@ set_vindex (decl, vfuns_p)
               ? TARGET_VTABLE_USES_DESCRIPTORS : 1);
   DECL_VINDEX (decl) = build_shared_int_cst (vindex);
 }
-
-/* Add a virtual function to all the appropriate vtables for the class
-   T.  DECL_VINDEX(X) should be error_mark_node, if we want to
-   allocate a new slot in our table.  If it is error_mark_node, we
-   know that no other function from another vtable is overridden by X.
-   VFUNS_P keeps track of how many virtuals there are in our
-   main vtable for the type, and we build upon the NEW_VIRTUALS list
-   and return it.  */
-
-static void
-add_virtual_function (new_virtuals_p, overridden_virtuals_p,
-                     vfuns_p, fndecl, t)
-     tree *new_virtuals_p;
-     tree *overridden_virtuals_p;
-     int *vfuns_p;
-     tree fndecl;
-     tree t; /* Structure type.  */
-{
-  tree new_virtual;
-
-  /* If this function doesn't override anything from a base class, we
-     can just assign it a new DECL_VINDEX now.  Otherwise, if it does
-     override something, we keep it around and assign its DECL_VINDEX
-     later, in modify_all_vtables.  */
-  if (TREE_CODE (DECL_VINDEX (fndecl)) == INTEGER_CST)
-    /* We've already dealt with this function.  */
-    return;
-
-  new_virtual = make_node (TREE_LIST);
-  BV_FN (new_virtual) = fndecl;
-  BV_DELTA (new_virtual) = integer_zero_node;
-
-  if (DECL_VINDEX (fndecl) == error_mark_node)
-    {
-      /* FNDECL is a new virtual function; it doesn't override any
-        virtual function in a base class.  */
-
-      /* We remember that this was the base sub-object for rtti.  */
-      CLASSTYPE_RTTI (t) = t;
-
-      /* Now assign virtual dispatch information.  */
-      set_vindex (fndecl, vfuns_p);
-      DECL_VIRTUAL_CONTEXT (fndecl) = t;
-
-      /* Save the state we've computed on the NEW_VIRTUALS list.  */
-      TREE_CHAIN (new_virtual) = *new_virtuals_p;
-      *new_virtuals_p = new_virtual;
-    }
-  else
-    {
-      /* FNDECL overrides a function from a base class.  */
-      TREE_CHAIN (new_virtual) = *overridden_virtuals_p;
-      *overridden_virtuals_p = new_virtual;
-    }
-}
 \f
 /* Add method METHOD to class TYPE.  If ERROR_P is true, we are adding
    the method after the class has already been defined because a
@@ -855,6 +785,8 @@ add_method (type, method, error_p)
   int len;
   int slot;
   tree method_vec;
+  int template_conv_p = (TREE_CODE (method) == TEMPLATE_DECL
+                        && DECL_TEMPLATE_CONV_FN_P (method));
 
   if (!CLASSTYPE_METHOD_VEC (type))
     /* Make a new method vector.  We start with 8 entries.  We must
@@ -879,14 +811,36 @@ add_method (type, method, error_p)
     slot = CLASSTYPE_DESTRUCTOR_SLOT;
   else
     {
+      int have_template_convs_p = 0;
+      
       /* See if we already have an entry with this name.  */
       for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT; slot < len; ++slot)
-       if (!TREE_VEC_ELT (method_vec, slot)
-           || (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, 
-                                                     slot))) 
-               == DECL_NAME (method)))
-         break;
-               
+       {
+         tree m = TREE_VEC_ELT (method_vec, slot);
+
+         if (!m)
+           break;
+         m = OVL_CURRENT (m);
+         
+         if (template_conv_p)
+           {
+             have_template_convs_p = (TREE_CODE (m) == TEMPLATE_DECL
+                                      && DECL_TEMPLATE_CONV_FN_P (m));
+             
+             /* If we need to move things up, see if there's
+                space. */
+             if (!have_template_convs_p)
+               {
+                 slot = len - 1;
+                 if (TREE_VEC_ELT (method_vec, slot))
+                   slot++;
+               }
+             break;
+           }
+         if (DECL_NAME (m) == DECL_NAME (method))
+           break;
+       }
+      
       if (slot == len)
        {
          /* We need a bigger method vector.  */
@@ -919,22 +873,27 @@ add_method (type, method, error_p)
             slide some of the vector elements up.  In theory, this
             makes this algorithm O(N^2) but we don't expect many
             conversion operators.  */
-         for (slot = 2; slot < len; ++slot)
-           {
-             tree fn = TREE_VEC_ELT (method_vec, slot);
+         if (template_conv_p)
+           slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
+         else
+           for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT; slot < len; ++slot)
+             {
+               tree fn = TREE_VEC_ELT (method_vec, slot);
   
-             if (!fn)
-               /* There are no more entries in the vector, so we
-                  can insert the new conversion operator here.  */
-               break;
+               if (!fn)
+                 /* There are no more entries in the vector, so we
+                    can insert the new conversion operator here.  */
+                 break;
                  
-             if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
-               /* We can insert the new function right at the
-                  SLOTth position.  */
-               break;
-           }
-  
-         if (!TREE_VEC_ELT (method_vec, slot))
+               if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
+                 /* We can insert the new function right at the
+                    SLOTth position.  */
+                 break;
+             }
+
+         if (template_conv_p && have_template_convs_p)
+           /*OK*/;
+         else if (!TREE_VEC_ELT (method_vec, slot))
            /* There is nothing in the Ith slot, so we can avoid
               moving anything.  */
                ; 
@@ -965,69 +924,60 @@ add_method (type, method, error_p)
           fns = OVL_NEXT (fns))
        {
          tree fn = OVL_CURRENT (fns);
-                
+         tree parms1;
+         tree parms2;
+         bool same = 1;
+
          if (TREE_CODE (fn) != TREE_CODE (method))
            continue;
 
-         if (TREE_CODE (method) != TEMPLATE_DECL)
+         /* [over.load] Member function declarations with the
+            same name and the same parameter types cannot be
+            overloaded if any of them is a static member
+            function declaration.
+
+            [namespace.udecl] When a using-declaration brings names
+            from a base class into a derived class scope, member
+            functions in the derived class override and/or hide member
+            functions with the same name and parameter types in a base
+            class (rather than conflicting).  */
+         parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn));
+         parms2 = TYPE_ARG_TYPES (TREE_TYPE (method));
+
+         /* Compare the quals on the 'this' parm.  Don't compare
+            the whole types, as used functions are treated as
+            coming from the using class in overload resolution.  */
+         if (! DECL_STATIC_FUNCTION_P (fn)
+             && ! DECL_STATIC_FUNCTION_P (method)
+             && (TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms1)))
+                 != TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms2)))))
+           same = 0;
+         if (! DECL_STATIC_FUNCTION_P (fn))
+           parms1 = TREE_CHAIN (parms1);
+         if (! DECL_STATIC_FUNCTION_P (method))
+           parms2 = TREE_CHAIN (parms2);
+
+         if (same && compparms (parms1, parms2) 
+             && (!DECL_CONV_FN_P (fn) 
+                 || same_type_p (TREE_TYPE (TREE_TYPE (fn)),
+                                 TREE_TYPE (TREE_TYPE (method)))))
            {
-             /* [over.load] Member function declarations with the
-                same name and the same parameter types cannot be
-                overloaded if any of them is a static member
-                function declaration.
-
-                [namespace.udecl] When a using-declaration brings names
-                from a base class into a derived class scope, member
-                functions in the derived class override and/or hide member
-                functions with the same name and parameter types in a base
-                class (rather than conflicting).  */
-             if ((DECL_STATIC_FUNCTION_P (fn)
-                  != DECL_STATIC_FUNCTION_P (method))
-                 || using)
+             if (using && DECL_CONTEXT (fn) == type)
+               /* Defer to the local function.  */
+               return;
+             else
                {
-                 tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn));
-                 tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (method));
-                 int same = 1;
-
-                 /* Compare the quals on the 'this' parm.  Don't compare
-                    the whole types, as used functions are treated as
-                    coming from the using class in overload resolution.  */
-                 if (using
-                     && ! DECL_STATIC_FUNCTION_P (fn)
-                     && ! DECL_STATIC_FUNCTION_P (method)
-                     && (TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms1)))
-                         != TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms2)))))
-                   same = 0;
-                 if (! DECL_STATIC_FUNCTION_P (fn))
-                   parms1 = TREE_CHAIN (parms1);
-                 if (! DECL_STATIC_FUNCTION_P (method))
-                   parms2 = TREE_CHAIN (parms2);
-
-                 if (same && compparms (parms1, parms2))
-                   {
-                     if (using && DECL_CONTEXT (fn) == type)
-                       /* Defer to the local function.  */
-                       return;
-                     else
-                       error ("`%#D' and `%#D' cannot be overloaded",
-                                 fn, method);
-                   }
+                 cp_error_at ("`%#D' and `%#D' cannot be overloaded",
+                              method, fn, method);
+
+                 /* We don't call duplicate_decls here to merge
+                    the declarations because that will confuse
+                    things if the methods have inline
+                    definitions.  In particular, we will crash
+                    while processing the definitions.  */
+                 return;
                }
            }
-
-         if (!decls_match (fn, method))
-           continue;
-
-         /* There has already been a declaration of this method
-            or member template.  */
-         cp_error_at ("`%D' has already been declared in `%T'", 
-                      method, type);
-
-         /* We don't call duplicate_decls here to merge the
-            declarations because that will confuse things if the
-            methods have inline definitions.  In particular, we
-            will crash while processing the definitions.  */
-         return;
        }
     }
 
@@ -1035,7 +985,7 @@ add_method (type, method, error_p)
   TREE_VEC_ELT (method_vec, slot) 
     = build_overload (method, TREE_VEC_ELT (method_vec, slot));
 
-      /* Add the new binding.  */ 
+  /* Add the new binding.  */ 
   if (!DECL_CONSTRUCTOR_P (method)
       && !DECL_DESTRUCTOR_P (method))
     push_class_level_binding (DECL_NAME (method),
@@ -1211,14 +1161,12 @@ handle_using_decl (using_decl, t)
   if (! binfo)
     return;
   
-  if (name == constructor_name (ctype)
-      || name == constructor_name_full (ctype))
+  if (constructor_name_p (name, ctype))
     {
       cp_error_at ("`%D' names constructor", using_decl);
       return;
     }
-  if (name == constructor_name (t)
-      || name == constructor_name_full (t))
+  if (constructor_name_p (name, t))
     {
       cp_error_at ("`%D' invalid in `%T'", using_decl, t);
       return;
@@ -1234,7 +1182,7 @@ handle_using_decl (using_decl, t)
 
   if (BASELINK_P (fdecl))
     /* Ignore base type this came from. */
-    fdecl = TREE_VALUE (fdecl);
+    fdecl = BASELINK_FUNCTIONS (fdecl);
 
   old_value = IDENTIFIER_CLASS_VALUE (name);
   if (old_value)
@@ -1842,17 +1790,11 @@ finish_struct_bits (t)
        }
     }
 
-  /* If this type has a copy constructor, force its mode to be BLKmode, and
-     force its TREE_ADDRESSABLE bit to be nonzero.  This will cause it to
-     be passed by invisible reference and prevent it from being returned in
-     a register.
-
-     Also do this if the class has BLKmode but can still be returned in
-     registers, since function_cannot_inline_p won't let us inline
-     functions returning such a type.  This affects the HP-PA.  */
-  if (! TYPE_HAS_TRIVIAL_INIT_REF (t)
-      || (TYPE_MODE (t) == BLKmode && ! aggregate_value_p (t)
-         && CLASSTYPE_NON_AGGREGATE (t)))
+  /* If this type has a copy constructor or a destructor, force its mode to
+     be BLKmode, and force its TREE_ADDRESSABLE bit to be nonzero.  This
+     will cause it to be passed by invisible reference and prevent it from
+     being returned in a register.  */
+  if (! TYPE_HAS_TRIVIAL_INIT_REF (t) || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
     {
       tree variants;
       DECL_MODE (TYPE_MAIN_DECL (t)) = BLKmode;
@@ -2164,6 +2106,7 @@ duplicate_tag_error (t)
       memset ((char *) TYPE_LANG_SPECIFIC (t), 0, sizeof (struct lang_type));
       BINFO_BASETYPES(binfo) = NULL_TREE;
 
+      TYPE_LANG_SPECIFIC (t)->u.h.is_lang_type_class = 1;
       TYPE_BINFO (t) = binfo;
       CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
       SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
@@ -2423,7 +2366,7 @@ find_final_overrider (t, binfo, fn)
 {
   find_final_overrider_data ffod;
 
-  /* Getting this right is a little tricky.  This is legal:
+  /* Getting this right is a little tricky.  This is valid:
 
        struct S { virtual void f (); };
        struct T { virtual void f (); };
@@ -2517,6 +2460,10 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
   if (overrider == error_mark_node)
     return;
 
+  /* Check for unsupported covariant returns again now that we've
+     calculated the base offsets.  */
+  check_final_overrider (TREE_PURPOSE (overrider), fn);
+
   /* Assume that we will produce a thunk that convert all the way to
      the final overrider, and not to an intermediate virtual base.  */
   virtual_base = NULL_TREE;
@@ -2639,18 +2586,18 @@ dfs_modify_vtables (binfo, data)
 
 /* Update all of the primary and secondary vtables for T.  Create new
    vtables as required, and initialize their RTTI information.  Each
-   of the functions in OVERRIDDEN_VIRTUALS overrides a virtual
-   function from a base class; find and modify the appropriate entries
-   to point to the overriding functions.  Returns a list, in
-   declaration order, of the functions that are overridden in this
-   class, but do not appear in the primary base class vtable, and
-   which should therefore be appended to the end of the vtable for T.  */
+   of the functions in VIRTUALS is declared in T and may override a
+   virtual function from a base class; find and modify the appropriate
+   entries to point to the overriding functions.  Returns a list, in
+   declaration order, of the virtual functions that are declared in T,
+   but do not appear in the primary base class vtable, and which
+   should therefore be appended to the end of the vtable for T.  */
 
 static tree
-modify_all_vtables (t, vfuns_p, overridden_virtuals)
+modify_all_vtables (t, vfuns_p, virtuals)
      tree t;
      int *vfuns_p;
-     tree overridden_virtuals;
+     tree virtuals;
 {
   tree binfo = TYPE_BINFO (t);
   tree *fnsp;
@@ -2662,14 +2609,16 @@ modify_all_vtables (t, vfuns_p, overridden_virtuals)
            t);
   dfs_walk (binfo, dfs_unmark, dfs_marked_real_bases_queue_p, t);
 
-  /* Include overriding functions for secondary vtables in our primary
-     vtable.  */
-  for (fnsp = &overridden_virtuals; *fnsp; )
+  /* Add virtual functions not already in our primary vtable. These
+     will be both those introduced by this class, and those overridden
+     from secondary bases.  It does not include virtuals merely
+     inherited from secondary bases.  */
+  for (fnsp = &virtuals; *fnsp; )
     {
       tree fn = TREE_VALUE (*fnsp);
 
-      if (!BINFO_VIRTUALS (binfo)
-         || !value_member (fn, BINFO_VIRTUALS (binfo)))
+      if (!value_member (fn, BINFO_VIRTUALS (binfo))
+         || DECL_VINDEX (fn) == error_mark_node)
        {
          /* Set the vtable index.  */
          set_vindex (fn, vfuns_p);
@@ -2682,8 +2631,7 @@ modify_all_vtables (t, vfuns_p, overridden_virtuals)
          BV_DELTA (*fnsp) = integer_zero_node;
          BV_VCALL_INDEX (*fnsp) = NULL_TREE;
 
-         /* This is an overridden function not already in our
-            vtable.  Keep it.  */
+         /* This is a function not already in our vtable.  Keep it.  */
          fnsp = &TREE_CHAIN (*fnsp);
        }
       else
@@ -2691,7 +2639,7 @@ modify_all_vtables (t, vfuns_p, overridden_virtuals)
        *fnsp = TREE_CHAIN (*fnsp);
     }
   
-  return overridden_virtuals;
+  return virtuals;
 }
 
 /* Here, we already know that they match in every respect.
@@ -2761,16 +2709,14 @@ check_for_override (decl, ctype)
        || IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)))
       && look_for_overrides (ctype, decl)
       && !DECL_STATIC_FUNCTION_P (decl))
-    {
-      /* Set DECL_VINDEX to a value that is neither an
-        INTEGER_CST nor the error_mark_node so that
-        add_virtual_function will realize this is an
-        overriding function.  */
-      DECL_VINDEX (decl) = decl;
-    }
+    /* Set DECL_VINDEX to a value that is neither an INTEGER_CST nor
+       the error_mark_node so that we know it is an overriding
+       function.  */
+    DECL_VINDEX (decl) = decl;
+
   if (DECL_VIRTUAL_P (decl))
     {
-      if (DECL_VINDEX (decl) == NULL_TREE)
+      if (!DECL_VINDEX (decl))
        DECL_VINDEX (decl) = error_mark_node;
       IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
     }
@@ -3106,7 +3052,8 @@ check_bitfield_decl (field)
       DECL_SIZE (field) = convert (bitsizetype, w);
       DECL_BIT_FIELD (field) = 1;
 
-      if (integer_zerop (w))
+      if (integer_zerop (w)
+         && ! (* targetm.ms_bitfield_layout_p) (DECL_FIELD_CONTEXT (field)))
        {
 #ifdef EMPTY_FIELD_BOUNDARY
          DECL_ALIGN (field) = MAX (DECL_ALIGN (field), 
@@ -3284,8 +3231,6 @@ check_field_decls (t, access_decls, empty_p,
       tree x = *field;
       tree type = TREE_TYPE (x);
 
-      GNU_xref_member (current_class_name, x);
-
       next = &TREE_CHAIN (x);
 
       if (TREE_CODE (x) == FIELD_DECL)
@@ -3409,6 +3354,9 @@ check_field_decls (t, access_decls, empty_p,
            to be allowed in POD structs.  */
        CLASSTYPE_NON_POD_P (t) = 1;
 
+      if (! zero_init_p (type))
+       CLASSTYPE_NON_ZERO_INIT_P (t) = 1;
+
       /* If any field is const, the structure type is pseudo-const.  */
       if (CP_TYPE_CONST_P (type))
        {
@@ -3835,6 +3783,8 @@ build_base_field (rli, binfo, empty_p, offsets, t)
   DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
   DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype);
   DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);
+  /* Tell the backend not to round up to TYPE_ALIGN.  */
+  DECL_PACKED (decl) = 1;
   
   if (!integer_zerop (DECL_SIZE (decl)))
     {
@@ -3925,8 +3875,6 @@ check_methods (t)
 
   for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x))
     {
-      GNU_xref_member (current_class_name, x);
-
       /* If this was an evil function, don't keep it in class.  */
       if (DECL_ASSEMBLER_NAME_SET_P (x) 
          && IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (x)))
@@ -4040,7 +3988,7 @@ build_clone (fn, name)
       for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms))
        {
          DECL_CONTEXT (parms) = clone;
-         copy_lang_decl (parms);
+         cxx_dup_lang_specific_decl (parms);
        }
     }
 
@@ -4271,7 +4219,7 @@ type_requires_array_cookie (type)
   if (!fns || fns == error_mark_node)
     return false;
   /* Loop through all of the functions.  */
-  for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns))
+  for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns))
     {
       tree fn;
       tree second_parm;
@@ -4382,7 +4330,7 @@ check_bases_and_members (t, empty_p)
 
   /* Figure out whether or not we will need a cookie when dynamically
      allocating an array of this type.  */
-  TYPE_LANG_SPECIFIC (t)->vec_new_uses_cookie
+  TYPE_LANG_SPECIFIC (t)->u.c.vec_new_uses_cookie
     = type_requires_array_cookie (t);
 }
 
@@ -4390,31 +4338,36 @@ check_bases_and_members (t, empty_p)
    accordingly.  If a new vfield was created (because T doesn't have a
    primary base class), then the newly created field is returned.  It
    is not added to the TYPE_FIELDS list; it is the caller's
-   responsibility to do that.  */
+   responsibility to do that.  Accumulate declared virtual functions
+   on VIRTUALS_P.  */
 
 static tree
-create_vtable_ptr (t, empty_p, vfuns_p,
-                  new_virtuals_p, overridden_virtuals_p)
+create_vtable_ptr (t, empty_p, virtuals_p)
      tree t;
      int *empty_p;
-     int *vfuns_p;
-     tree *new_virtuals_p;
-     tree *overridden_virtuals_p;
+     tree *virtuals_p;
 {
   tree fn;
 
-  /* Loop over the virtual functions, adding them to our various
-     vtables.  */
+  /* Collect the virtual functions declared in T.  */
   for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
-    if (DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
-      add_virtual_function (new_virtuals_p, overridden_virtuals_p,
-                           vfuns_p, fn, t);
+    if (DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)
+       && TREE_CODE (DECL_VINDEX (fn)) != INTEGER_CST)
+      {
+       tree new_virtual = make_node (TREE_LIST);
+       
+       BV_FN (new_virtual) = fn;
+       BV_DELTA (new_virtual) = integer_zero_node;
 
+       TREE_CHAIN (new_virtual) = *virtuals_p;
+       *virtuals_p = new_virtual;
+      }
+  
   /* If we couldn't find an appropriate base class, create a new field
      here.  Even if there weren't any new virtual functions, we might need a
      new virtual function table if we're supposed to include vptrs in
      all classes that need them.  */
-  if (!TYPE_VFIELD (t) && (*vfuns_p || TYPE_CONTAINS_VPTR_P (t)))
+  if (!TYPE_VFIELD (t) && (*virtuals_p || TYPE_CONTAINS_VPTR_P (t)))
     {
       /* We build this decl with vtbl_ptr_type_node, which is a
         `vtable_entry_type*'.  It might seem more precise to use
@@ -4607,8 +4560,7 @@ layout_virtual_bases (t, offsets)
      tree t;
      splay_tree offsets;
 {
-  tree vbases;
-  unsigned HOST_WIDE_INT dsize;
+  tree vbases, dsize;
   unsigned HOST_WIDE_INT eoc;
 
   if (CLASSTYPE_N_BASECLASSES (t) == 0)
@@ -4621,7 +4573,7 @@ layout_virtual_bases (t, offsets)
 #endif
 
   /* DSIZE is the size of the class without the virtual bases.  */
-  dsize = tree_low_cst (TYPE_SIZE (t), 1);
+  dsize = TYPE_SIZE (t);
 
   /* Make every class have alignment of at least one.  */
   TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), BITS_PER_UNIT);
@@ -4643,7 +4595,7 @@ layout_virtual_bases (t, offsets)
        {
          /* This virtual base is not a primary base of any class in the
             hierarchy, so we have to add space for it.  */
-         tree basetype;
+         tree basetype, usize;
          unsigned int desired_align;
 
          basetype = BINFO_TYPE (vbase);
@@ -4653,19 +4605,21 @@ layout_virtual_bases (t, offsets)
 
          /* Add padding so that we can put the virtual base class at an
             appropriately aligned offset.  */
-         dsize = CEIL (dsize, desired_align) * desired_align;
+         dsize = round_up (dsize, desired_align);
+
+         usize = size_binop (CEIL_DIV_EXPR, dsize, bitsize_unit_node);
 
          /* We try to squish empty virtual bases in just like
             ordinary empty bases.  */
          if (is_empty_class (basetype))
            layout_empty_base (vbase,
-                              size_int (CEIL (dsize, BITS_PER_UNIT)),
+                              convert (sizetype, usize),
                               offsets, t);
          else
            {
              tree offset;
 
-             offset = ssize_int (CEIL (dsize, BITS_PER_UNIT));
+             offset = convert (ssizetype, usize);
              offset = size_diffop (offset, 
                                    convert (ssizetype, 
                                             BINFO_OFFSET (vbase)));
@@ -4675,8 +4629,9 @@ layout_virtual_bases (t, offsets)
              /* Every virtual baseclass takes a least a UNIT, so that
                 we can take it's address and get something different
                 for each base.  */
-             dsize += MAX (BITS_PER_UNIT,
-                           tree_low_cst (CLASSTYPE_SIZE (basetype), 0));
+             dsize = size_binop (PLUS_EXPR, dsize,
+                                 size_binop (MAX_EXPR, bitsize_unit_node,
+                                             CLASSTYPE_SIZE (basetype)));
            }
 
          /* Keep track of the offsets assigned to this virtual base.  */
@@ -4698,13 +4653,12 @@ layout_virtual_bases (t, offsets)
      class, we didn't update DSIZE above; we were hoping to overlay
      multiple such bases at the same location.  */
   eoc = end_of_class (t, /*include_virtuals_p=*/1);
-  if (eoc * BITS_PER_UNIT > dsize)
-    dsize = eoc * BITS_PER_UNIT;
+  dsize = size_binop (MAX_EXPR, dsize, bitsize_int (eoc * BITS_PER_UNIT));
 
   /* Now, make sure that the total size of the type is a multiple of
      its alignment.  */
-  dsize = CEIL (dsize, TYPE_ALIGN (t)) * TYPE_ALIGN (t);
-  TYPE_SIZE (t) = bitsize_int (dsize);
+  dsize = round_up (dsize, TYPE_ALIGN (t));
+  TYPE_SIZE (t) = dsize;
   TYPE_SIZE_UNIT (t) = convert (sizetype,
                                size_binop (CEIL_DIV_EXPR, TYPE_SIZE (t),
                                            bitsize_unit_node));
@@ -4805,16 +4759,14 @@ splay_tree_compare_integer_csts (k1, k2)
 
 /* Calculate the TYPE_SIZE, TYPE_ALIGN, etc for T.  Calculate
    BINFO_OFFSETs for all of the base-classes.  Position the vtable
-   pointer.  */
+   pointer.  Accumulate declared virtual functions on VIRTUALS_P. */
 
 static void
-layout_class_type (t, empty_p, vfuns_p, 
-                  new_virtuals_p, overridden_virtuals_p)
+layout_class_type (t, empty_p, vfuns_p, virtuals_p)
      tree t;
      int *empty_p;
      int *vfuns_p;
-     tree *new_virtuals_p;
-     tree *overridden_virtuals_p;
+     tree *virtuals_p;
 {
   tree non_static_data_members;
   tree field;
@@ -4836,8 +4788,7 @@ layout_class_type (t, empty_p, vfuns_p,
   determine_primary_base (t, vfuns_p);
 
   /* Create a pointer to our virtual function table.  */
-  vptr = create_vtable_ptr (t, empty_p, vfuns_p,
-                           new_virtuals_p, overridden_virtuals_p);
+  vptr = create_vtable_ptr (t, empty_p, virtuals_p);
 
   /* The vptr is always the first thing in the class.  */
   if (vptr)
@@ -4863,6 +4814,18 @@ layout_class_type (t, empty_p, vfuns_p,
       if (TREE_CODE (field) != FIELD_DECL)
        {
          place_field (rli, field);
+         /* If the static data member has incomplete type, keep track
+            of it so that it can be completed later.  (The handling 
+            of pending statics in finish_record_layout is
+            insufficient; consider:
+
+              struct S1;
+              struct S2 { static S1 s1; };
+              
+             At this point, finish_record_layout will be called, but
+            S1 is still incomplete.)  */
+         if (TREE_CODE (field) == VAR_DECL)
+           maybe_register_incomplete_var (field);
          continue;
        }
 
@@ -4965,6 +4928,12 @@ layout_class_type (t, empty_p, vfuns_p,
       CLASSTYPE_SIZE (t) = bitsize_zero_node;
       CLASSTYPE_SIZE_UNIT (t) = size_zero_node;
     }
+  /* If this is a POD, we can't reuse its tail padding.  */
+  else if (!CLASSTYPE_NON_POD_P (t))
+    {
+      CLASSTYPE_SIZE (t) = TYPE_SIZE (t);
+      CLASSTYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (t);
+    }
   else
     {
       CLASSTYPE_SIZE (t) = TYPE_BINFO_SIZE (t);
@@ -5026,15 +4995,8 @@ finish_struct_1 (t)
 {
   tree x;
   int vfuns;
-  /* The NEW_VIRTUALS is a TREE_LIST.  The TREE_VALUE of each node is
-     a FUNCTION_DECL.  Each of these functions is a virtual function
-     declared in T that does not override any virtual function from a
-     base class.  */
-  tree new_virtuals = NULL_TREE;
-  /* The OVERRIDDEN_VIRTUALS list is like the NEW_VIRTUALS list,
-     except that each declaration here overrides the declaration from
-     a base class.  */
-  tree overridden_virtuals = NULL_TREE;
+  /* A TREE_LIST.  The TREE_VALUE of each node is a FUNCTION_DECL. */
+  tree virtuals = NULL_TREE;
   int n_fields = 0;
   tree vfield;
   int empty = 1;
@@ -5049,8 +5011,6 @@ finish_struct_1 (t)
       return;
     }
 
-  GNU_xref_decl (current_function_decl, t);
-
   /* If this type was previously laid out as a forward reference,
      make sure we lay it out again.  */
   TYPE_SIZE (t) = NULL_TREE;
@@ -5066,8 +5026,7 @@ finish_struct_1 (t)
   check_bases_and_members (t, &empty);
 
   /* Layout the class itself.  */
-  layout_class_type (t, &empty, &vfuns,
-                    &new_virtuals, &overridden_virtuals);
+  layout_class_type (t, &empty, &vfuns, &virtuals);
 
   /* Make sure that we get our own copy of the vfield FIELD_DECL.  */
   vfield = TYPE_VFIELD (t);
@@ -5091,8 +5050,7 @@ finish_struct_1 (t)
   else
     my_friendly_assert (!vfield || DECL_FIELD_CONTEXT (vfield) == t, 20010726);
 
-  overridden_virtuals 
-    = modify_all_vtables (t, &vfuns, nreverse (overridden_virtuals));
+  virtuals = modify_all_vtables (t, &vfuns, nreverse (virtuals));
 
   /* If we created a new vtbl pointer for this class, add it to the
      list.  */
@@ -5101,9 +5059,8 @@ finish_struct_1 (t)
       = chainon (CLASSTYPE_VFIELDS (t), build_tree_list (NULL_TREE, t));
 
   /* If necessary, create the primary vtable for this class.  */
-  if (new_virtuals || overridden_virtuals || TYPE_CONTAINS_VPTR_P (t))
+  if (virtuals || TYPE_CONTAINS_VPTR_P (t))
     {
-      new_virtuals = nreverse (new_virtuals);
       /* We must enter these virtuals into the table.  */
       if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
        build_primary_vtable (NULL_TREE, t);
@@ -5116,7 +5073,6 @@ finish_struct_1 (t)
         constructors might clobber the virtual function table.  But
         they don't if the derived class shares the exact vtable of the base
         class.  */
-
       CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1;
     }
   /* If we didn't need a new vtable, see if we should copy one from
@@ -5142,14 +5098,8 @@ finish_struct_1 (t)
                            20000116);
 
       CLASSTYPE_VSIZE (t) = vfuns;
-      /* Entries for virtual functions defined in the primary base are
-        followed by entries for new functions unique to this class.  */
-      TYPE_BINFO_VIRTUALS (t) 
-       = chainon (TYPE_BINFO_VIRTUALS (t), new_virtuals);
-      /* Finally, add entries for functions that override virtuals
-        from non-primary bases.  */
-      TYPE_BINFO_VIRTUALS (t) 
-       = chainon (TYPE_BINFO_VIRTUALS (t), overridden_virtuals);
+      /* Add entries for virtual functions introduced by this class.  */
+      TYPE_BINFO_VIRTUALS (t) = chainon (TYPE_BINFO_VIRTUALS (t), virtuals);
     }
 
   finish_struct_bits (t);
@@ -5158,7 +5108,7 @@ finish_struct_1 (t)
      working on.  */
   for (x = TYPE_FIELDS (t); x; x = TREE_CHAIN (x))
     if (TREE_CODE (x) == VAR_DECL && TREE_STATIC (x)
-       && TREE_TYPE (x) == t)
+       && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (x)), t))
       DECL_MODE (x) = TYPE_MODE (t);
 
   /* Done with FIELDS...now decide whether to sort these for
@@ -5185,15 +5135,13 @@ finish_struct_1 (t)
     {
       tree vfields = CLASSTYPE_VFIELDS (t);
 
-      while (vfields)
-       {
-         /* Mark the fact that constructor for T
-            could affect anybody inheriting from T
-            who wants to initialize vtables for VFIELDS's type.  */
-         if (VF_DERIVED_VALUE (vfields))
-           TREE_ADDRESSABLE (vfields) = 1;
-         vfields = TREE_CHAIN (vfields);
-       }
+      for (vfields = CLASSTYPE_VFIELDS (t);
+          vfields; vfields = TREE_CHAIN (vfields))
+       /* Mark the fact that constructor for T could affect anybody
+          inheriting from T who wants to initialize vtables for
+          VFIELDS's type.  */
+       if (VF_BINFO_VALUE (vfields))
+         TREE_ADDRESSABLE (vfields) = 1;
     }
 
   /* Make the rtl for any new vtables we have created, and unmark
@@ -5207,7 +5155,7 @@ finish_struct_1 (t)
       && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1)) == NULL_TREE)
     warning ("`%#T' has virtual functions but non-virtual destructor", t);
 
-  hack_incomplete_structures (t);
+  complete_vars (t);
 
   if (warn_overloaded_virtual)
     warn_hidden (t);
@@ -5291,12 +5239,8 @@ finish_struct (t, attributes)
   else
     error ("trying to finish struct, but kicked out due to previous parse errors");
 
-  if (processing_template_decl)
-    {
-      tree scope = current_scope ();
-      if (scope && TREE_CODE (scope) == FUNCTION_DECL)
-       add_stmt (build_min (TAG_DEFN, t));
-    }
+  if (processing_template_decl && at_function_scope_p ())
+    add_stmt (build_min (TAG_DEFN, t));
 
   return t;
 }
@@ -5353,7 +5297,7 @@ fixed_type_or_null (instance, nonnull, cdtorp)
        return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
       if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST)
        /* Propagate nonnull.  */
-       fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
+       return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
       return NULL_TREE;
 
     case NOP_EXPR:
@@ -5380,6 +5324,7 @@ fixed_type_or_null (instance, nonnull, cdtorp)
       /* fall through...  */
     case TARGET_EXPR:
     case PARM_DECL:
+    case RESULT_DECL:
       if (IS_AGGR_TYPE (TREE_TYPE (instance)))
        {
          if (nonnull)
@@ -5406,6 +5351,11 @@ fixed_type_or_null (instance, nonnull, cdtorp)
           /* Reference variables should be references to objects.  */
           if (nonnull)
            *nonnull = 1;
+
+         if (TREE_CODE (instance) == VAR_DECL
+             && DECL_INITIAL (instance))
+           return fixed_type_or_null (DECL_INITIAL (instance),
+                                      nonnull, cdtorp);
        }
       return NULL_TREE;
 
@@ -5456,7 +5406,6 @@ init_class_processing ()
     = (class_stack_node_t) xmalloc (current_class_stack_size 
                                    * sizeof (struct class_stack_node));
   VARRAY_TREE_INIT (local_classes, 8, "local_classes");
-  ggc_add_tree_varray_root (&local_classes, 1);
 
   access_default_node = build_int_2 (0, 0);
   access_public_node = build_int_2 (ak_public, 0);
@@ -5613,8 +5562,6 @@ void
 popclass ()
 {
   poplevel_class ();
-  /* Since poplevel_class does the popping of class decls nowadays,
-     this really only frees the obstack used for these decls.  */
   pop_class_decls ();
 
   current_class_depth--;
@@ -6028,7 +5975,7 @@ cannot resolve overloaded function `%D' based on conversion to type `%T'",
       /* The target must be a REFERENCE_TYPE.  Above, build_unary_op
         will mark the function as addressed, but here we must do it
         explicitly.  */
-      mark_addressable (fn);
+      cxx_mark_addressable (fn);
 
       return fn;
     }
@@ -6047,14 +5994,14 @@ cannot resolve overloaded function `%D' based on conversion to type `%T'",
 tree
 instantiate_type (lhstype, rhs, flags)
      tree lhstype, rhs;
-     enum instantiate_type_flags flags;
+     tsubst_flags_t flags;
 {
-  int complain = (flags & itf_complain);
-  int strict = (flags & itf_no_attributes)
+  int complain = (flags & tf_error);
+  int strict = (flags & tf_no_attributes)
                ? COMPARE_NO_ATTRIBUTES : COMPARE_STRICT;
-  int allow_ptrmem = flags & itf_ptrmem_ok;
+  int allow_ptrmem = flags & tf_ptrmem_ok;
   
-  flags &= ~itf_ptrmem_ok;
+  flags &= ~tf_ptrmem_ok;
   
   if (TREE_CODE (lhstype) == UNKNOWN_TYPE)
     {
@@ -6073,6 +6020,9 @@ instantiate_type (lhstype, rhs, flags)
       return error_mark_node;
     }
 
+  if (TREE_CODE (rhs) == BASELINK)
+    rhs = BASELINK_FUNCTIONS (rhs);
+
   /* We don't overwrite rhs if it is an overloaded function.
      Copying it would destroy the tree link.  */
   if (TREE_CODE (rhs) != OVERLOAD)
@@ -6119,7 +6069,7 @@ instantiate_type (lhstype, rhs, flags)
     case OFFSET_REF:
       rhs = TREE_OPERAND (rhs, 1);
       if (BASELINK_P (rhs))
-       return instantiate_type (lhstype, TREE_VALUE (rhs),
+       return instantiate_type (lhstype, BASELINK_FUNCTIONS (rhs),
                                 flags | allow_ptrmem);
 
       /* This can happen if we are forming a pointer-to-member for a
@@ -6155,7 +6105,7 @@ instantiate_type (lhstype, rhs, flags)
       /* Now we should have a baselink. */
       my_friendly_assert (BASELINK_P (rhs), 990412);
 
-      return instantiate_type (lhstype, TREE_VALUE (rhs), flags);
+      return instantiate_type (lhstype, BASELINK_FUNCTIONS (rhs), flags);
 
     case CALL_EXPR:
       /* This is too hard for now.  */
@@ -6261,7 +6211,7 @@ instantiate_type (lhstype, rhs, flags)
     case ADDR_EXPR:
     {
       if (PTRMEM_OK_P (rhs))
-        flags |= itf_ptrmem_ok;
+        flags |= tf_ptrmem_ok;
       
       return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
     }
@@ -6299,7 +6249,8 @@ get_vfield_name (type)
   type = BINFO_TYPE (binfo);
   buf = (char *) alloca (sizeof (VFIELD_NAME_FORMAT)
                         + TYPE_NAME_LENGTH (type) + 2);
-  sprintf (buf, VFIELD_NAME_FORMAT, TYPE_NAME_STRING (type));
+  sprintf (buf, VFIELD_NAME_FORMAT,
+          IDENTIFIER_POINTER (constructor_name (type)));
   return get_identifier (buf);
 }
 
@@ -6438,7 +6389,7 @@ maybe_note_name_used_in_class (name, decl)
 }
 
 /* Note that NAME was declared (as DECL) in the current class.  Check
-   to see that the declaration is legal.  */
+   to see that the declaration is valid.  */
 
 void
 note_name_declared_in_class (name, decl)
@@ -7485,7 +7436,7 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p)
   vid.primary_vtbl_p = (binfo == TYPE_BINFO (t));
   vid.ctor_vtbl_p = !same_type_p (BINFO_TYPE (rtti_binfo), t);
   /* The first vbase or vcall offset is at index -3 in the vtable.  */
-  vid.index = ssize_int (-3);
+  vid.index = ssize_int (-3 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
 
   /* Add entries to the vtable for RTTI.  */
   build_rtti_vtbl_entries (binfo, &vid);
@@ -7496,8 +7447,6 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p)
   VARRAY_TREE_INIT (vid.fns, 32, "fns");
   /* Add the vcall and vbase offset entries.  */
   build_vcall_and_vbase_vtbl_entries (binfo, &vid);
-  /* Clean up.  */
-  VARRAY_FREE (vid.fns);
   /* Clear BINFO_VTABLE_PATH_MARKED; it's set by
      build_vbase_offset_vtbl_entries.  */
   for (vbase = CLASSTYPE_VBASECLASSES (t); 
@@ -7505,6 +7454,22 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p)
        vbase = TREE_CHAIN (vbase))
     CLEAR_BINFO_VTABLE_PATH_MARKED (TREE_VALUE (vbase));
 
+  /* If the target requires padding between data entries, add that now.  */
+  if (TARGET_VTABLE_DATA_ENTRY_DISTANCE > 1)
+    {
+      tree cur, *prev;
+
+      for (prev = &vid.inits; (cur = *prev); prev = &TREE_CHAIN (cur))
+       {
+         tree add = cur;
+         int i;
+
+         for (i = 1; i < TARGET_VTABLE_DATA_ENTRY_DISTANCE; ++i)
+           add = tree_cons (NULL_TREE, null_pointer_node, add);
+         *prev = add;
+       }
+    }
+
   if (non_fn_entries_p)
     *non_fn_entries_p = list_length (vid.inits);
 
@@ -7722,7 +7687,8 @@ build_vbase_offset_vtbl_entries (binfo, vid)
        }
 
       /* The next vbase will come at a more negative offset.  */
-      vid->index = size_binop (MINUS_EXPR, vid->index, ssize_int (1));
+      vid->index = size_binop (MINUS_EXPR, vid->index,
+                              ssize_int (TARGET_VTABLE_DATA_ENTRY_DISTANCE));
 
       /* The initializer is the delta from BINFO to this virtual base.
         The vbase offsets go in reverse inheritance-graph order, and