OSDN Git Service

2008-01-04 Paolo Carlini <pcarlini@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / cp / class.c
index dceeffe..6e67157 100644 (file)
@@ -1,13 +1,14 @@
 /* Functions related to building classes and their related objects.
    Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
+   Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -16,9 +17,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 
 /* High-level class interface.  */
@@ -60,6 +60,10 @@ typedef struct class_stack_node {
 
   /* If were defining TYPE, the names used in this class.  */
   splay_tree names_used;
+
+  /* Nonzero if this class is no longer open, because of a call to
+     push_to_top_level.  */
+  size_t hidden;
 }* class_stack_node_t;
 
 typedef struct vtbl_init_data_s
@@ -103,6 +107,9 @@ typedef int (*subobject_offset_fn) (tree, tree, splay_tree);
 static int current_class_stack_size;
 static class_stack_node_t current_class_stack;
 
+/* The size of the largest empty class seen in this translation unit.  */
+static GTY (()) tree sizeof_biggest_empty_class;
+
 /* An array of all local classes present in this translation unit, in
    declaration order.  */
 VEC(tree,gc) *local_classes;
@@ -127,14 +134,12 @@ static int method_name_cmp (const void *, const void *);
 static int resort_method_name_cmp (const void *, const void *);
 static void add_implicitly_declared_members (tree, int, int);
 static tree fixed_type_or_null (tree, int *, int *);
-static tree resolve_address_of_overloaded_function (tree, tree, tsubst_flags_t,
-                                                   bool, tree);
 static tree build_simple_base_path (tree expr, tree binfo);
 static tree build_vtbl_ref_1 (tree, tree);
 static tree build_vtbl_initializer (tree, tree, tree, tree, int *);
 static int count_fields (tree);
 static int add_fields_to_record_type (tree, struct sorted_fields_type*, int);
-static void check_bitfield_decl (tree);
+static bool check_bitfield_decl (tree);
 static void check_field_decl (tree, tree, int *, int *, int *);
 static void check_field_decls (tree, tree *, int *, int *);
 static tree *build_base_field (record_layout_info, tree, splay_tree, tree *);
@@ -160,6 +165,7 @@ static tree dfs_find_final_overrider_pre (tree, void *);
 static tree dfs_find_final_overrider_post (tree, void *);
 static tree find_final_overrider (tree, tree, tree);
 static int make_new_vtable (tree, tree);
+static tree get_primary_binfo (tree);
 static int maybe_indent_hierarchy (FILE *, int, int);
 static tree dump_class_hierarchy_r (FILE *, int, tree, tree, int);
 static void dump_class_hierarchy (tree);
@@ -173,7 +179,7 @@ static void initialize_vtable (tree, tree);
 static void layout_nonempty_base_or_field (record_layout_info,
                                           tree, tree, splay_tree);
 static tree end_of_class (tree, int);
-static bool layout_empty_base (tree, tree, splay_tree);
+static bool layout_empty_base (record_layout_info, tree, tree, splay_tree);
 static void accumulate_vtbl_inits (tree, tree, tree, tree, tree);
 static tree dfs_accumulate_vtbl_inits (tree, tree, tree, tree,
                                               tree);
@@ -192,7 +198,7 @@ static int record_subobject_offset (tree, tree, splay_tree);
 static int check_subobject_offset (tree, tree, splay_tree);
 static int walk_subobject_offsets (tree, subobject_offset_fn,
                                   tree, splay_tree, tree, int);
-static void record_subobject_offsets (tree, tree, splay_tree, int);
+static void record_subobject_offsets (tree, tree, splay_tree, bool);
 static int layout_conflict_p (tree, tree, splay_tree, int);
 static int splay_tree_compare_integer_csts (splay_tree_key k1,
                                            splay_tree_key k2);
@@ -282,13 +288,34 @@ build_base_path (enum tree_code code,
 
   offset = BINFO_OFFSET (binfo);
   fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
+  target_type = code == PLUS_EXPR ? BINFO_TYPE (binfo) : BINFO_TYPE (d_binfo);
 
   /* Do we need to look in the vtable for the real offset?  */
   virtual_access = (v_binfo && fixed_type_p <= 0);
 
   /* Do we need to check for a null pointer?  */
-  if (want_pointer && !nonnull && (virtual_access || !integer_zerop (offset)))
-    null_test = error_mark_node;
+  if (want_pointer && !nonnull)
+    {
+      /* If we know the conversion will not actually change the value
+        of EXPR, then we can avoid testing the expression for NULL.
+        We have to avoid generating a COMPONENT_REF for a base class
+        field, because other parts of the compiler know that such
+        expressions are always non-NULL.  */
+      if (!virtual_access && integer_zerop (offset))
+       {
+         tree class_type;
+         /* TARGET_TYPE has been extracted from BINFO, and, is
+            therefore always cv-unqualified.  Extract the
+            cv-qualifiers from EXPR so that the expression returned
+            matches the input.  */
+         class_type = TREE_TYPE (TREE_TYPE (expr));
+         target_type
+           = cp_build_qualified_type (target_type,
+                                      cp_type_quals (class_type));
+         return build_nop (build_pointer_type (target_type), expr);
+       }
+      null_test = error_mark_node;
+    }
 
   /* Protect against multiple evaluation if necessary.  */
   if (TREE_SIDE_EFFECTS (expr) && (null_test || virtual_access))
@@ -325,24 +352,22 @@ build_base_path (enum tree_code code,
 
       if (fixed_type_p < 0 && in_base_initializer)
        {
-         /* In a base member initializer, we cannot rely on
-            the vtable being set up. We have to use the vtt_parm.  */
-         tree derived = BINFO_INHERITANCE_CHAIN (v_binfo);
+         /* In a base member initializer, we cannot rely on the
+            vtable being set up.  We have to indirect via the
+            vtt_parm.  */
          tree t;
 
-         t = TREE_TYPE (TYPE_VFIELD (BINFO_TYPE (derived)));
+         t = TREE_TYPE (TYPE_VFIELD (current_class_type));
          t = build_pointer_type (t);
          v_offset = convert (t, current_vtt_parm);
-         v_offset = build2 (PLUS_EXPR, t, v_offset,
-                            BINFO_VPTR_INDEX (derived));
          v_offset = build_indirect_ref (v_offset, NULL);
        }
       else
        v_offset = build_vfield_ref (build_indirect_ref (expr, NULL),
                                     TREE_TYPE (TREE_TYPE (expr)));
 
-      v_offset = build2 (PLUS_EXPR, TREE_TYPE (v_offset),
-                        v_offset,  BINFO_VPTR_FIELD (v_binfo));
+      v_offset = build2 (POINTER_PLUS_EXPR, TREE_TYPE (v_offset),
+                        v_offset, fold_convert (sizetype, BINFO_VPTR_FIELD (v_binfo)));
       v_offset = build1 (NOP_EXPR,
                         build_pointer_type (ptrdiff_type_node),
                         v_offset);
@@ -371,8 +396,6 @@ build_base_path (enum tree_code code,
        offset = v_offset;
     }
 
-  target_type = code == PLUS_EXPR ? BINFO_TYPE (binfo) : BINFO_TYPE (d_binfo);
-
   target_type = cp_build_qualified_type
     (target_type, cp_type_quals (TREE_TYPE (TREE_TYPE (expr))));
   ptr_target_type = build_pointer_type (target_type);
@@ -382,7 +405,12 @@ build_base_path (enum tree_code code,
   expr = build1 (NOP_EXPR, ptr_target_type, expr);
 
   if (!integer_zerop (offset))
-    expr = build2 (code, ptr_target_type, expr, offset);
+    {
+      offset = fold_convert (sizetype, offset);
+      if (code == MINUS_EXPR)
+       offset = fold_build1 (NEGATE_EXPR, sizetype, offset);
+      expr = build2 (POINTER_PLUS_EXPR, ptr_target_type, expr, offset);
+    }
   else
     null_test = NULL;
 
@@ -417,8 +445,8 @@ build_simple_base_path (tree expr, tree binfo)
 
       /* Transform `(a, b).x' into `(*(a, &b)).x', `(a ? b : c).x'
         into `(*(a ?  &b : &c)).x', and so on.  A COND_EXPR is only
-        an lvalue in the frontend; only _DECLs and _REFs are lvalues
-        in the backend.  */
+        an lvalue in the front end; only _DECLs and _REFs are lvalues
+        in the back end.  */
       temp = unary_complex_lvalue (ADDR_EXPR, expr);
       if (temp)
        expr = build_indirect_ref (temp, NULL);
@@ -507,12 +535,18 @@ convert_to_base_statically (tree expr, tree base)
       tree pointer_type;
 
       pointer_type = build_pointer_type (expr_type);
+
+      /* We use fold_build2 and fold_convert below to simplify the trees
+        provided to the optimizers.  It is not safe to call these functions
+        when processing a template because they do not handle C++-specific
+        trees.  */
+      gcc_assert (!processing_template_decl);
       expr = build_unary_op (ADDR_EXPR, expr, /*noconvert=*/1);
       if (!integer_zerop (BINFO_OFFSET (base)))
-         expr = build2 (PLUS_EXPR, pointer_type, expr,
-                        build_nop (pointer_type, BINFO_OFFSET (base)));
-      expr = build_nop (build_pointer_type (BINFO_TYPE (base)), expr);
-      expr = build1 (INDIRECT_REF, BINFO_TYPE (base), expr);
+        expr = fold_build2 (POINTER_PLUS_EXPR, pointer_type, expr,
+                           fold_convert (sizetype, BINFO_OFFSET (base)));
+      expr = fold_convert (build_pointer_type (BINFO_TYPE (base)), expr);
+      expr = build_fold_indirect_ref (expr);
     }
 
   return expr;
@@ -627,15 +661,6 @@ get_vtable_name (tree type)
   return mangle_vtbl_for_type (type);
 }
 
-/* Return an IDENTIFIER_NODE for the name of the virtual table table
-   for TYPE.  */
-
-tree
-get_vtt_name (tree type)
-{
-  return mangle_vtt_for_type (type);
-}
-
 /* DECL is an entity associated with TYPE, like a virtual table or an
    implicitly generated constructor.  Determine whether or not DECL
    should have external or internal linkage at the object file
@@ -736,7 +761,7 @@ get_vtable_decl (tree type, int complete)
   if (complete)
     {
       DECL_EXTERNAL (decl) = 1;
-      cp_finish_decl (decl, NULL_TREE, NULL_TREE, 0);
+      finish_decl (decl, NULL_TREE, NULL_TREE);
     }
 
   return decl;
@@ -881,9 +906,10 @@ modify_vtable_entry (tree t,
 
 \f
 /* Add method METHOD to class TYPE.  If USING_DECL is non-null, it is
-   the USING_DECL naming METHOD.  */
+   the USING_DECL naming METHOD.  Returns true if the method could be
+   added to the method vec.  */
 
-void
+bool
 add_method (tree type, tree method, tree using_decl)
 {
   unsigned slot;
@@ -894,9 +920,10 @@ add_method (tree type, tree method, tree using_decl)
   bool complete_p;
   bool insert_p = false;
   tree current_fns;
+  tree fns;
 
   if (method == error_mark_node)
-    return;
+    return false;
 
   complete_p = COMPLETE_TYPE_P (type);
   conv_p = DECL_CONV_FN_P (method);
@@ -918,6 +945,9 @@ add_method (tree type, tree method, tree using_decl)
       CLASSTYPE_METHOD_VEC (type) = method_vec;
     }
 
+  /* Maintain TYPE_HAS_CONSTRUCTOR, etc.  */
+  grok_special_member_properties (method);
+
   /* Constructors and destructors go in special slots.  */
   if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (method))
     slot = CLASSTYPE_CONSTRUCTOR_SLOT;
@@ -968,100 +998,109 @@ add_method (tree type, tree method, tree using_decl)
     }
   current_fns = insert_p ? NULL_TREE : VEC_index (tree, method_vec, slot);
 
-  if (processing_template_decl)
-    /* TYPE is a template class.  Don't issue any errors now; wait
-       until instantiation time to complain.  */
-    ;
-  else
+  /* Check to see if we've already got this method.  */
+  for (fns = current_fns; fns; fns = OVL_NEXT (fns))
     {
-      tree fns;
+      tree fn = OVL_CURRENT (fns);
+      tree fn_type;
+      tree method_type;
+      tree parms1;
+      tree parms2;
 
-      /* Check to see if we've already got this method.  */
-      for (fns = current_fns; fns; 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 (fn) != TREE_CODE (method))
-           continue;
+      /* [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).  */
+      fn_type = TREE_TYPE (fn);
+      method_type = TREE_TYPE (method);
+      parms1 = TYPE_ARG_TYPES (fn_type);
+      parms2 = TYPE_ARG_TYPES (method_type);
+
+      /* 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)))))
+       continue;
 
-         /* [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;
-
-         /* For templates, the template parms must be identical.  */
-         if (TREE_CODE (fn) == TEMPLATE_DECL
-             && !comp_template_parms (DECL_TEMPLATE_PARMS (fn),
-                                      DECL_TEMPLATE_PARMS (method)))
-           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)))))
+      /* For templates, the return type and template parameters
+        must be identical.  */
+      if (TREE_CODE (fn) == TEMPLATE_DECL
+         && (!same_type_p (TREE_TYPE (fn_type),
+                           TREE_TYPE (method_type))
+             || !comp_template_parms (DECL_TEMPLATE_PARMS (fn),
+                                      DECL_TEMPLATE_PARMS (method))))
+       continue;
+
+      if (! DECL_STATIC_FUNCTION_P (fn))
+       parms1 = TREE_CHAIN (parms1);
+      if (! DECL_STATIC_FUNCTION_P (method))
+       parms2 = TREE_CHAIN (parms2);
+
+      if (compparms (parms1, parms2)
+         && (!DECL_CONV_FN_P (fn)
+             || same_type_p (TREE_TYPE (fn_type),
+                             TREE_TYPE (method_type))))
+       {
+         if (using_decl)
            {
-             if (using_decl)
-               {
-                 if (DECL_CONTEXT (fn) == type)
-                   /* Defer to the local function.  */
-                   return;
-                 if (DECL_CONTEXT (fn) == DECL_CONTEXT (method))
-                   error ("repeated using declaration %q+D", using_decl);
-                 else
-                   error ("using declaration %q+D conflicts with a previous using declaration",
-                          using_decl);
-               }
+             if (DECL_CONTEXT (fn) == type)
+               /* Defer to the local function.  */
+               return false;
+             if (DECL_CONTEXT (fn) == DECL_CONTEXT (method))
+               error ("repeated using declaration %q+D", using_decl);
              else
-               {
-                 error ("%q+#D cannot be overloaded", method);
-                 error ("with %q+#D", fn);
-               }
-
-             /* 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;
+               error ("using declaration %q+D conflicts with a previous using declaration",
+                      using_decl);
+           }
+         else
+           {
+             error ("%q+#D cannot be overloaded", method);
+             error ("with %q+#D", fn);
            }
+
+         /* 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 false;
        }
     }
 
+  /* A class should never have more than one destructor.  */
+  if (current_fns && DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (method))
+    return false;
+
   /* Add the new binding.  */
   overload = build_overload (method, current_fns);
 
-  if (!conv_p && slot >= CLASSTYPE_FIRST_CONVERSION_SLOT && !complete_p)
+  if (conv_p)
+    TYPE_HAS_CONVERSION (type) = 1;
+  else if (slot >= CLASSTYPE_FIRST_CONVERSION_SLOT && !complete_p)
     push_class_level_binding (DECL_NAME (method), overload);
 
   if (insert_p)
     {
+      bool reallocated;
+
       /* We only expect to add few methods in the COMPLETE_P case, so
         just make room for one more method in that case.  */
-      if (VEC_reserve (tree, gc, method_vec, complete_p ? -1 : 1))
+      if (complete_p)
+       reallocated = VEC_reserve_exact (tree, gc, method_vec, 1);
+      else
+       reallocated = VEC_reserve (tree, gc, method_vec, 1);
+      if (reallocated)
        CLASSTYPE_METHOD_VEC (type) = method_vec;
       if (slot == VEC_length (tree, method_vec))
        VEC_quick_push (tree, method_vec, overload);
@@ -1071,6 +1110,7 @@ add_method (tree type, tree method, tree using_decl)
   else
     /* Replace the current slot.  */
     VEC_replace (tree, method_vec, slot, overload);
+  return true;
 }
 
 /* Subroutines of finish_struct.  */
@@ -1109,7 +1149,7 @@ alter_access (tree t, tree fdecl, tree access)
     }
   else
     {
-      perform_or_defer_access_check (TYPE_BINFO (t), fdecl);
+      perform_or_defer_access_check (TYPE_BINFO (t), fdecl, fdecl);
       DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
       return 1;
     }
@@ -1144,7 +1184,7 @@ handle_using_decl (tree using_decl, tree t)
        old_value = NULL_TREE;
     }
 
-  cp_emit_debug_info_for_using (decl, current_class_type);
+  cp_emit_debug_info_for_using (decl, USING_DECL_SCOPE (using_decl));
 
   if (is_overloaded_fn (decl))
     flist = decl;
@@ -1208,8 +1248,9 @@ check_bases (tree t,
       /* Effective C++ rule 14.  We only need to check TYPE_POLYMORPHIC_P
         here because the case of virtual functions but non-virtual
         dtor is handled in finish_struct_1.  */
-      if (warn_ecpp && ! TYPE_POLYMORPHIC_P (basetype))
-       warning (0, "base class %q#T has a non-virtual destructor", basetype);
+      if (!TYPE_POLYMORPHIC_P (basetype))
+       warning (OPT_Weffc__,
+                "base class %q#T has a non-virtual destructor", basetype);
 
       /* If the base class doesn't have copy constructors or
         assignment operators that take const references, then the
@@ -1250,6 +1291,7 @@ check_bases (tree t,
       TYPE_POLYMORPHIC_P (t) |= TYPE_POLYMORPHIC_P (basetype);
       CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t)
        |= CLASSTYPE_CONTAINS_EMPTY_CLASS_P (basetype);
+      TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_HAS_COMPLEX_DFLT (basetype);      
     }
 }
 
@@ -1410,8 +1452,9 @@ finish_struct_bits (tree t)
       TYPE_VFIELD (variants) = TYPE_VFIELD (t);
       TYPE_METHODS (variants) = TYPE_METHODS (t);
       TYPE_FIELDS (variants) = TYPE_FIELDS (t);
-      TYPE_SIZE (variants) = TYPE_SIZE (t);
-      TYPE_SIZE_UNIT (variants) = TYPE_SIZE_UNIT (t);
+
+      /* All variants of a class have the same attributes.  */
+      TYPE_ATTRIBUTES (variants) = TYPE_ATTRIBUTES (t);
     }
 
   if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) && TYPE_POLYMORPHIC_P (t))
@@ -1523,7 +1566,8 @@ maybe_warn_about_overly_private_class (tree t)
          }
       if (!has_nonprivate_method)
        {
-         warning (0, "all member functions in class %qT are private", t);
+         warning (OPT_Wctor_dtor_privacy,
+                  "all member functions in class %qT are private", t);
          return;
        }
     }
@@ -1534,12 +1578,16 @@ maybe_warn_about_overly_private_class (tree t)
   fn = CLASSTYPE_DESTRUCTORS (t);
   if (fn && TREE_PRIVATE (fn))
     {
-      warning (0, "%q#T only defines a private destructor and has no friends",
+      warning (OPT_Wctor_dtor_privacy,
+              "%q#T only defines a private destructor and has no friends",
               t);
       return;
     }
 
-  if (TYPE_HAS_CONSTRUCTOR (t))
+  if (TYPE_HAS_CONSTRUCTOR (t)
+      /* Implicitly generated constructors are always public.  */
+      && (!CLASSTYPE_LAZY_DEFAULT_CTOR (t)
+         || !CLASSTYPE_LAZY_COPY_CTOR (t)))
     {
       int nonprivate_ctor = 0;
 
@@ -1574,7 +1622,8 @@ maybe_warn_about_overly_private_class (tree t)
 
       if (nonprivate_ctor == 0)
        {
-         warning (0, "%q#T only defines private constructors and has no friends",
+         warning (OPT_Wctor_dtor_privacy,
+                  "%q#T only defines private constructors and has no friends",
                   t);
          return;
        }
@@ -1591,8 +1640,8 @@ static struct {
 static int
 method_name_cmp (const void* m1_p, const void* m2_p)
 {
-  const tree *const m1 = m1_p;
-  const tree *const m2 = m2_p;
+  const tree *const m1 = (const tree *) m1_p;
+  const tree *const m2 = (const tree *) m2_p;
 
   if (*m1 == NULL_TREE && *m2 == NULL_TREE)
     return 0;
@@ -1611,8 +1660,8 @@ method_name_cmp (const void* m1_p, const void* m2_p)
 static int
 resort_method_name_cmp (const void* m1_p, const void* m2_p)
 {
-  const tree *const m1 = m1_p;
-  const tree *const m2 = m2_p;
+  const tree *const m1 = (const tree *) m1_p;
+  const tree *const m2 = (const tree *) m2_p;
   if (*m1 == NULL_TREE && *m2 == NULL_TREE)
     return 0;
   if (*m1 == NULL_TREE)
@@ -1701,7 +1750,7 @@ finish_struct_methods (tree t)
 }
 
 /* Make BINFO's vtable have N entries, including RTTI entries,
-   vbase and vcall offsets, etc.  Set its type and call the backend
+   vbase and vcall offsets, etc.  Set its type and call the back end
    to lay it out.  */
 
 static void
@@ -1728,7 +1777,7 @@ layout_vtable_decl (tree binfo, int n)
    have the same signature.  */
 
 int
-same_signature_p (tree fndecl, tree base_fndecl)
+same_signature_p (const_tree fndecl, const_tree base_fndecl)
 {
   /* One destructor overrides another if they are the same kind of
      destructor.  */
@@ -1979,7 +2028,9 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
   if (POINTER_TYPE_P (over_return)
       && TREE_CODE (over_return) == TREE_CODE (base_return)
       && CLASS_TYPE_P (TREE_TYPE (over_return))
-      && CLASS_TYPE_P (TREE_TYPE (base_return)))
+      && CLASS_TYPE_P (TREE_TYPE (base_return))
+      /* If the overrider is invalid, don't even try.  */
+      && !DECL_INVALID_OVERRIDER_P (overrider_target))
     {
       /* If FN is a covariant thunk, we must figure out the adjustment
         to the final base FN was converting to. As OVERRIDER_TARGET might
@@ -2071,7 +2122,8 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
                                   fixed_offset, virtual_offset);
     }
   else
-    gcc_assert (!DECL_THUNK_P (fn));
+    gcc_assert (DECL_INVALID_OVERRIDER_P (overrider_target) ||
+               !DECL_THUNK_P (fn));
 
   /* Assume that we will produce a thunk that convert all the way to
      the final overrider, and not to an intermediate virtual base.  */
@@ -2321,7 +2373,7 @@ check_for_override (tree decl, tree ctype)
 /* Warn about hidden virtual functions that are not overridden in t.
    We know that constructors and destructors don't apply.  */
 
-void
+static void
 warn_hidden (tree t)
 {
   VEC(tree,gc) *method_vec = CLASSTYPE_METHOD_VEC (t);
@@ -2384,8 +2436,8 @@ warn_hidden (tree t)
       while (base_fndecls)
        {
          /* Here we know it is a hider, and no overrider exists.  */
-         warning (0, "%q+D was hidden", TREE_VALUE (base_fndecls));
-         warning (0, "  by %q+D", fns);
+         warning (OPT_Woverloaded_virtual, "%q+D was hidden", TREE_VALUE (base_fndecls));
+         warning (OPT_Woverloaded_virtual, "  by %q+D", fns);
          base_fndecls = TREE_CHAIN (base_fndecls);
        }
     }
@@ -2409,6 +2461,7 @@ finish_struct_anon (tree t)
       if (DECL_NAME (field) == NULL_TREE
          && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
        {
+         bool is_union = TREE_CODE (TREE_TYPE (field)) == UNION_TYPE;
          tree elt = TYPE_FIELDS (TREE_TYPE (field));
          for (; elt; elt = TREE_CHAIN (elt))
            {
@@ -2426,15 +2479,29 @@ finish_struct_anon (tree t)
 
              if (TREE_CODE (elt) != FIELD_DECL)
                {
-                 pedwarn ("%q+#D invalid; an anonymous union can "
-                          "only have non-static data members", elt);
+                 if (is_union)
+                   pedwarn ("%q+#D invalid; an anonymous union can "
+                            "only have non-static data members", elt);
+                 else
+                   pedwarn ("%q+#D invalid; an anonymous struct can "
+                            "only have non-static data members", elt);
                  continue;
                }
 
              if (TREE_PRIVATE (elt))
-               pedwarn ("private member %q+#D in anonymous union", elt);
+               {
+                 if (is_union)
+                   pedwarn ("private member %q+#D in anonymous union", elt);
+                 else
+                   pedwarn ("private member %q+#D in anonymous struct", elt);
+               }
              else if (TREE_PROTECTED (elt))
-               pedwarn ("protected member %q+#D in anonymous union", elt);
+               {
+                 if (is_union)
+                   pedwarn ("protected member %q+#D in anonymous union", elt);
+                 else
+                   pedwarn ("protected member %q+#D in anonymous struct", elt);
+               }
 
              TREE_PRIVATE (elt) = TREE_PRIVATE (field);
              TREE_PROTECTED (elt) = TREE_PROTECTED (field);
@@ -2588,27 +2655,30 @@ add_fields_to_record_type (tree fields, struct sorted_fields_type *field_vec, in
 
 /* FIELD is a bit-field.  We are finishing the processing for its
    enclosing type.  Issue any appropriate messages and set appropriate
-   flags.  */
+   flags.  Returns false if an error has been diagnosed.  */
 
-static void
+static bool
 check_bitfield_decl (tree field)
 {
   tree type = TREE_TYPE (field);
-  tree w = NULL_TREE;
+  tree w;
+
+  /* Extract the declared width of the bitfield, which has been
+     temporarily stashed in DECL_INITIAL.  */
+  w = DECL_INITIAL (field);
+  gcc_assert (w != NULL_TREE);
+  /* Remove the bit-field width indicator so that the rest of the
+     compiler does not treat that value as an initializer.  */
+  DECL_INITIAL (field) = NULL_TREE;
 
   /* Detect invalid bit-field type.  */
-  if (DECL_INITIAL (field)
-      && ! INTEGRAL_TYPE_P (TREE_TYPE (field)))
+  if (!INTEGRAL_TYPE_P (type))
     {
       error ("bit-field %q+#D with non-integral type", field);
       w = error_mark_node;
     }
-
-  /* Detect and ignore out of range field width.  */
-  if (DECL_INITIAL (field))
+  else
     {
-      w = DECL_INITIAL (field);
-
       /* Avoid the non_lvalue wrapper added by fold for PLUS_EXPRs.  */
       STRIP_NOPS (w);
 
@@ -2645,20 +2715,18 @@ check_bitfield_decl (tree field)
        warning (0, "%q+D is too small to hold all values of %q#T", field, type);
     }
 
-  /* Remove the bit-field width indicator so that the rest of the
-     compiler does not treat that value as an initializer.  */
-  DECL_INITIAL (field) = NULL_TREE;
-
   if (w != error_mark_node)
     {
       DECL_SIZE (field) = convert (bitsizetype, w);
       DECL_BIT_FIELD (field) = 1;
+      return true;
     }
   else
     {
       /* Non-bit-fields are aligned for their type.  */
       DECL_BIT_FIELD (field) = 0;
       CLEAR_DECL_C_BIT_FIELD (field);
+      return false;
     }
 }
 
@@ -2716,6 +2784,7 @@ check_field_decl (tree field,
            |= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type);
          TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_COMPLEX_ASSIGN_REF (type);
          TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (type);
+         TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_HAS_COMPLEX_DFLT (type);
        }
 
       if (!TYPE_HAS_CONST_INIT_REF (type))
@@ -2768,6 +2837,7 @@ check_field_decls (tree t, tree *access_decls,
   tree *next;
   bool has_pointers;
   int any_default_members;
+  int cant_pack = 0;
 
   /* Assume there are no access declarations.  */
   *access_decls = NULL_TREE;
@@ -2784,40 +2854,6 @@ check_field_decls (tree t, tree *access_decls,
 
       next = &TREE_CHAIN (x);
 
-      if (TREE_CODE (x) == FIELD_DECL)
-       {
-         if (TYPE_PACKED (t))
-           {
-             if (!pod_type_p (TREE_TYPE (x)) && !TYPE_PACKED (TREE_TYPE (x)))
-               warning
-                 (0,
-                  "ignoring packed attribute on unpacked non-POD field %q+#D",
-                  x);
-             else
-               DECL_PACKED (x) = 1;
-           }
-
-         if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x)))
-           /* We don't treat zero-width bitfields as making a class
-              non-empty.  */
-           ;
-         else
-           {
-             tree element_type;
-
-             /* The class is non-empty.  */
-             CLASSTYPE_EMPTY_P (t) = 0;
-             /* The class is not even nearly empty.  */
-             CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
-             /* If one of the data members contains an empty class,
-                so does T.  */
-             element_type = strip_array_types (type);
-             if (CLASS_TYPE_P (element_type)
-                 && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type))
-               CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
-           }
-       }
-
       if (TREE_CODE (x) == USING_DECL)
        {
          /* Prune the access declaration from the list of fields.  */
@@ -2863,10 +2899,6 @@ check_field_decls (tree t, tree *access_decls,
            }
        }
 
-      /* ``A local class cannot have static data members.'' ARM 9.4 */
-      if (current_function_decl && TREE_STATIC (x))
-       error ("field %q+D in local class cannot be static", x);
-
       /* Perform error checking that did not get done in
         grokdeclarator.  */
       if (TREE_CODE (type) == FUNCTION_TYPE)
@@ -2909,11 +2941,42 @@ check_field_decls (tree t, tree *access_decls,
 
          if (! TYPE_HAS_CONSTRUCTOR (t) && CLASSTYPE_NON_AGGREGATE (t)
              && extra_warnings)
-           warning (0, "non-static reference %q+#D in class without a constructor", x);
+           warning (OPT_Wextra, "non-static reference %q+#D in class without a constructor", x);
        }
 
       type = strip_array_types (type);
 
+      if (TYPE_PACKED (t))
+       {
+         if (!pod_type_p (type) && !TYPE_PACKED (type))
+           {
+             warning
+               (0,
+                "ignoring packed attribute because of unpacked non-POD field %q+#D",
+                x);
+             cant_pack = 1;
+           }
+         else if (TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT)
+           DECL_PACKED (x) = 1;
+       }
+
+      if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x)))
+       /* We don't treat zero-width bitfields as making a class
+          non-empty.  */
+       ;
+      else
+       {
+         /* The class is non-empty.  */
+         CLASSTYPE_EMPTY_P (t) = 0;
+         /* The class is not even nearly empty.  */
+         CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+         /* If one of the data members contains an empty class,
+            so does T.  */
+         if (CLASS_TYPE_P (type)
+             && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (type))
+           CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
+       }
+
       /* This is used by -Weffc++ (see below). Warn only for pointers
         to members which might hold dynamic memory. So do not warn
         for pointers to functions or pointers to members.  */
@@ -2956,7 +3019,7 @@ check_field_decls (tree t, tree *access_decls,
 
          if (! TYPE_HAS_CONSTRUCTOR (t) && CLASSTYPE_NON_AGGREGATE (t)
              && extra_warnings)
-           warning (0, "non-static const member %q+#D in class without a constructor", x);
+           warning (OPT_Wextra, "non-static const member %q+#D in class without a constructor", x);
        }
       /* A field that is pseudo-const makes the structure likewise.  */
       else if (CLASS_TYPE_P (type))
@@ -2975,9 +3038,7 @@ check_field_decls (tree t, tree *access_decls,
 
       /* We set DECL_C_BIT_FIELD in grokbitfield.
         If the type and width are valid, we'll also set DECL_BIT_FIELD.  */
-      if (DECL_C_BIT_FIELD (x))
-       check_bitfield_decl (x);
-      else
+      if (! DECL_C_BIT_FIELD (x) || ! check_bitfield_decl (x))
        check_field_decl (x, t,
                          cant_have_const_ctor_p,
                          no_const_asn_ref_p,
@@ -2998,24 +3059,29 @@ check_field_decls (tree t, tree *access_decls,
        is needed to free dynamic memory.
 
      This seems enough for practical purposes.  */
-    if (warn_ecpp
-       && has_pointers
-       && TYPE_HAS_CONSTRUCTOR (t)
-       && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
-       && !(TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t)))
+  if (warn_ecpp
+      && has_pointers
+      && TYPE_HAS_CONSTRUCTOR (t)
+      && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
+      && !(TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t)))
     {
-      warning (0, "%q#T has pointer data members", t);
+      warning (OPT_Weffc__, "%q#T has pointer data members", t);
 
       if (! TYPE_HAS_INIT_REF (t))
        {
-         warning (0, "  but does not override %<%T(const %T&)%>", t, t);
-         if (! TYPE_HAS_ASSIGN_REF (t))
-           warning (0, "  or %<operator=(const %T&)%>", t);
+         warning (OPT_Weffc__,
+                  "  but does not override %<%T(const %T&)%>", t, t);
+         if (!TYPE_HAS_ASSIGN_REF (t))
+           warning (OPT_Weffc__, "  or %<operator=(const %T&)%>", t);
        }
       else if (! TYPE_HAS_ASSIGN_REF (t))
-       warning (0, "  but does not override %<operator=(const %T&)%>", t);
+       warning (OPT_Weffc__,
+                "  but does not override %<operator=(const %T&)%>", t);
     }
 
+  /* If any of the fields couldn't be packed, unset TYPE_PACKED.  */
+  if (cant_pack)
+    TYPE_PACKED (t) = 0;
 
   /* Check anonymous struct/anonymous union fields.  */
   finish_struct_anon (t);
@@ -3103,7 +3169,7 @@ walk_subobject_offsets (tree type,
 
   if (type == error_mark_node)
     return 0;
-  
+
   if (!TYPE_P (type))
     {
       if (abi_version_at_least (2))
@@ -3278,18 +3344,38 @@ walk_subobject_offsets (tree type,
   return 0;
 }
 
-/* Record all of the empty subobjects of TYPE (located at OFFSET) in
-   OFFSETS.  If VBASES_P is nonzero, virtual bases of TYPE are
-   examined.  */
+/* Record all of the empty subobjects of TYPE (either a type or a
+   binfo).  If IS_DATA_MEMBER is true, then a non-static data member
+   is being placed at OFFSET; otherwise, it is a base class that is
+   being placed at OFFSET.  */
 
 static void
 record_subobject_offsets (tree type,
                          tree offset,
                          splay_tree offsets,
-                         int vbases_p)
-{
+                         bool is_data_member)
+{
+  tree max_offset;
+  /* If recording subobjects for a non-static data member or a
+     non-empty base class , we do not need to record offsets beyond
+     the size of the biggest empty class.  Additional data members
+     will go at the end of the class.  Additional base classes will go
+     either at offset zero (if empty, in which case they cannot
+     overlap with offsets past the size of the biggest empty class) or
+     at the end of the class.
+
+     However, if we are placing an empty base class, then we must record
+     all offsets, as either the empty class is at offset zero (where
+     other empty classes might later be placed) or at the end of the
+     class (where other objects might then be placed, so other empty
+     subobjects might later overlap).  */
+  if (is_data_member
+      || !is_empty_class (BINFO_TYPE (type)))
+    max_offset = sizeof_biggest_empty_class;
+  else
+    max_offset = NULL_TREE;
   walk_subobject_offsets (type, record_subobject_offset, offset,
-                         offsets, /*max_offset=*/NULL_TREE, vbases_p);
+                         offsets, max_offset, is_data_member);
 }
 
 /* Returns nonzero if any of the empty subobjects of TYPE (located at
@@ -3433,7 +3519,8 @@ empty_base_at_nonzero_offset_p (tree type,
    type.  Return nonzero iff we added it at the end.  */
 
 static bool
-layout_empty_base (tree binfo, tree eoc, splay_tree offsets)
+layout_empty_base (record_layout_info rli, tree binfo,
+                  tree eoc, splay_tree offsets)
 {
   tree alignment;
   tree basetype = BINFO_TYPE (binfo);
@@ -3448,8 +3535,9 @@ layout_empty_base (tree binfo, tree eoc, splay_tree offsets)
       if (abi_version_at_least (2))
        propagate_binfo_offsets
          (binfo, size_diffop (size_zero_node, BINFO_OFFSET (binfo)));
-      else if (warn_abi)
-       warning (0, "offset of empty base %qT may not be ABI-compliant and may"
+      else
+       warning (OPT_Wabi,
+                "offset of empty base %qT may not be ABI-compliant and may"
                 "change in a future version of GCC",
                 BINFO_TYPE (binfo));
     }
@@ -3478,6 +3566,15 @@ layout_empty_base (tree binfo, tree eoc, splay_tree offsets)
          propagate_binfo_offsets (binfo, alignment);
        }
     }
+
+  if (CLASSTYPE_USER_ALIGN (basetype))
+    {
+      rli->record_align = MAX (rli->record_align, CLASSTYPE_ALIGN (basetype));
+      if (warn_packed)
+       rli->unpacked_align = MAX (rli->unpacked_align, CLASSTYPE_ALIGN (basetype));
+      TYPE_USER_ALIGN (rli->t) = 1;
+    }
+
   return atend;
 }
 
@@ -3516,21 +3613,24 @@ build_base_field (record_layout_info rli, tree binfo,
       DECL_ARTIFICIAL (decl) = 1;
       DECL_IGNORED_P (decl) = 1;
       DECL_FIELD_CONTEXT (decl) = t;
-      DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
-      DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
-      DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype);
-      DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);
-      DECL_MODE (decl) = TYPE_MODE (basetype);
-      DECL_FIELD_IS_BASE (decl) = 1;
-
-      /* Try to place the field.  It may take more than one try if we
-        have a hard time placing the field without putting two
-        objects of the same type at the same address.  */
-      layout_nonempty_base_or_field (rli, decl, binfo, offsets);
-      /* Add the new FIELD_DECL to the list of fields for T.  */
-      TREE_CHAIN (decl) = *next_field;
-      *next_field = decl;
-      next_field = &TREE_CHAIN (decl);
+      if (CLASSTYPE_AS_BASE (basetype))
+       {
+         DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
+         DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
+         DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype);
+         DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);
+         DECL_MODE (decl) = TYPE_MODE (basetype);
+         DECL_FIELD_IS_BASE (decl) = 1;
+
+         /* Try to place the field.  It may take more than one try if we
+            have a hard time placing the field without putting two
+            objects of the same type at the same address.  */
+         layout_nonempty_base_or_field (rli, decl, binfo, offsets);
+         /* Add the new FIELD_DECL to the list of fields for T.  */
+         TREE_CHAIN (decl) = *next_field;
+         *next_field = decl;
+         next_field = &TREE_CHAIN (decl);
+       }
     }
   else
     {
@@ -3541,14 +3641,14 @@ build_base_field (record_layout_info rli, tree binfo,
         byte-aligned.  */
       eoc = round_up (rli_size_unit_so_far (rli),
                      CLASSTYPE_ALIGN_UNIT (basetype));
-      atend = layout_empty_base (binfo, eoc, offsets);
+      atend = layout_empty_base (rli, binfo, eoc, offsets);
       /* A nearly-empty class "has no proper base class that is empty,
         not morally virtual, and at an offset other than zero."  */
       if (!BINFO_VIRTUAL_P (binfo) && CLASSTYPE_NEARLY_EMPTY_P (t))
        {
          if (atend)
            CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
-         /* The check above (used in G++ 3.2) is insufficient  because
+         /* The check above (used in G++ 3.2) is insufficient because
             an empty class placed at offset zero might itself have an
             empty base at a nonzero offset.  */
          else if (walk_subobject_offsets (basetype,
@@ -3560,8 +3660,9 @@ build_base_field (record_layout_info rli, tree binfo,
            {
              if (abi_version_at_least (2))
                CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
-             else if (warn_abi)
-               warning (0, "class %qT will be considered nearly empty in a "
+             else
+               warning (OPT_Wabi,
+                        "class %qT will be considered nearly empty in a "
                         "future version of GCC", t);
            }
        }
@@ -3582,7 +3683,7 @@ build_base_field (record_layout_info rli, tree binfo,
   record_subobject_offsets (binfo,
                            BINFO_OFFSET (binfo),
                            offsets,
-                           /*vbases_p=*/0);
+                           /*is_data_member=*/false);
 
   return next_field;
 }
@@ -3992,7 +4093,7 @@ type_requires_array_cookie (tree type)
         argument is `size_t', it will be the usual deallocation
         function -- unless there is one-argument function, too.  */
       if (TREE_CHAIN (second_parm) == void_list_node
-         && same_type_p (TREE_VALUE (second_parm), sizetype))
+         && same_type_p (TREE_VALUE (second_parm), size_type_node))
        has_two_argument_delete_p = true;
     }
 
@@ -4055,6 +4156,8 @@ check_bases_and_members (tree t)
        || TYPE_HAS_ASSIGN_REF (t));
   TYPE_HAS_COMPLEX_ASSIGN_REF (t)
     |= TYPE_HAS_ASSIGN_REF (t) || TYPE_CONTAINS_VPTR_P (t);
+  TYPE_HAS_COMPLEX_DFLT (t)
+    |= (TYPE_HAS_DEFAULT_CONSTRUCTOR (t) || TYPE_CONTAINS_VPTR_P (t));
 
   /* Synthesize any needed methods.  */
   add_implicitly_declared_members (t,
@@ -4305,7 +4408,8 @@ layout_virtual_bases (record_layout_info rli, splay_tree offsets)
                                         CLASSTYPE_ALIGN (basetype)),
                               bitsize_unit_node),
                   BINFO_OFFSET (vbase))))
-           warning (0, "offset of virtual base %qT is not ABI-compliant and "
+           warning (OPT_Wabi,
+                    "offset of virtual base %qT is not ABI-compliant and "
                     "may change in a future version of GCC",
                     basetype);
 
@@ -4322,7 +4426,9 @@ end_of_base (tree binfo)
 {
   tree size;
 
-  if (is_empty_class (BINFO_TYPE (binfo)))
+  if (!CLASSTYPE_AS_BASE (BINFO_TYPE (binfo)))
+    size = TYPE_SIZE_UNIT (char_type_node);
+  else if (is_empty_class (BINFO_TYPE (binfo)))
     /* An empty class has zero CLASSTYPE_SIZE_UNIT, but we need to
        allocate some space for it. It cannot have virtual bases, so
        TYPE_SIZE_UNIT is fine.  */
@@ -4416,7 +4522,7 @@ warn_about_ambiguous_bases (tree t)
        basetype = BINFO_TYPE (binfo);
 
        if (!lookup_base (t, basetype, ba_unique | ba_quiet, NULL))
-         warning (0, "virtual base %qT inaccessible in %qT due to ambiguity",
+         warning (OPT_Wextra, "virtual base %qT inaccessible in %qT due to ambiguity",
                   basetype, t);
       }
 }
@@ -4528,7 +4634,7 @@ layout_class_type (tree t, tree *virtuals_p)
       tree padding;
 
       /* We still pass things that aren't non-static data members to
-        the back-end, in case it wants to do something with them.  */
+        the back end, in case it wants to do something with them.  */
       if (TREE_CODE (field) != FIELD_DECL)
        {
          place_field (rli, field);
@@ -4554,6 +4660,8 @@ layout_class_type (tree t, tree *virtuals_p)
        }
 
       type = TREE_TYPE (field);
+      if (type == error_mark_node)
+       continue;
 
       padding = NULL_TREE;
 
@@ -4592,8 +4700,8 @@ layout_class_type (tree t, tree *virtuals_p)
                padding = DECL_SIZE (field);
              else
                {
-                 if (warn_abi && TREE_CODE (t) == UNION_TYPE)
-                   warning (0, "size assigned to %qT may not be "
+                 if (TREE_CODE (t) == UNION_TYPE)
+                   warning (OPT_Wabi, "size assigned to %qT may not be "
                             "ABI-compliant and may change in a future "
                             "version of GCC",
                             t);
@@ -4632,7 +4740,8 @@ layout_class_type (tree t, tree *virtuals_p)
                   && DECL_MODE (field) != TYPE_MODE (type))
            /* Versions of G++ before G++ 3.4 did not reset the
               DECL_MODE.  */
-           warning (0, "the offset of %qD may not be ABI-compliant and may "
+           warning (OPT_Wabi,
+                    "the offset of %qD may not be ABI-compliant and may "
                     "change in a future version of GCC", field);
        }
       else
@@ -4644,7 +4753,7 @@ layout_class_type (tree t, tree *virtuals_p)
        record_subobject_offsets (TREE_TYPE (field),
                                  byte_position(field),
                                  empty_base_offsets,
-                                 /*vbases_p=*/1);
+                                 /*is_data_member=*/true);
 
       /* If a bit-field does not immediately follow another bit-field,
         and yet it starts in the middle of a byte, we have failed to
@@ -4660,7 +4769,7 @@ layout_class_type (tree t, tree *virtuals_p)
          && !integer_zerop (size_binop (TRUNC_MOD_EXPR,
                                         DECL_FIELD_BIT_OFFSET (field),
                                         bitsize_unit_node)))
-       warning (0, "offset of %q+D is not ABI-compliant and may "
+       warning (OPT_Wabi, "offset of %q+D is not ABI-compliant and may "
                 "change in a future version of GCC", field);
 
       /* G++ used to use DECL_FIELD_OFFSET as if it were the byte
@@ -4669,10 +4778,33 @@ layout_class_type (tree t, tree *virtuals_p)
          && !tree_int_cst_equal (DECL_FIELD_OFFSET (field),
                                  byte_position (field))
          && contains_empty_class_p (TREE_TYPE (field)))
-       warning (0, "%q+D contains empty classes which may cause base "
+       warning (OPT_Wabi, "%q+D contains empty classes which may cause base "
                 "classes to be placed at different locations in a "
                 "future version of GCC", field);
 
+      /* The middle end uses the type of expressions to determine the
+        possible range of expression values.  In order to optimize
+        "x.i > 7" to "false" for a 2-bit bitfield "i", the middle end
+        must be made aware of the width of "i", via its type.
+
+        Because C++ does not have integer types of arbitrary width,
+        we must (for the purposes of the front end) convert from the
+        type assigned here to the declared type of the bitfield
+        whenever a bitfield expression is used as an rvalue.
+        Similarly, when assigning a value to a bitfield, the value
+        must be converted to the type given the bitfield here.  */
+      if (DECL_C_BIT_FIELD (field))
+       {
+         tree ftype;
+         unsigned HOST_WIDE_INT width;
+         ftype = TREE_TYPE (field);
+         width = tree_low_cst (DECL_SIZE (field), /*unsignedp=*/1);
+         if (width != TYPE_PRECISION (ftype))
+           TREE_TYPE (field)
+             = c_build_bitfield_integer_type (width,
+                                              TYPE_UNSIGNED (ftype));
+       }
+
       /* If we needed additional padding after this field, add it
         now.  */
       if (padding)
@@ -4728,7 +4860,8 @@ layout_class_type (tree t, tree *virtuals_p)
          TYPE_SIZE (base_t) = bitsize_zero_node;
          TYPE_SIZE_UNIT (base_t) = size_zero_node;
          if (warn_abi && !integer_zerop (rli_size_unit_so_far (rli)))
-           warning (0, "layout of classes derived from empty class %qT "
+           warning (OPT_Wabi,
+                    "layout of classes derived from empty class %qT "
                     "may change in a future version of GCC",
                     t);
        }
@@ -4809,7 +4942,7 @@ layout_class_type (tree t, tree *virtuals_p)
     place_field (rli,
                 build_decl (FIELD_DECL, NULL_TREE, char_type_node));
 
-  /* Let the back-end lay out the type.  */
+  /* Let the back end lay out the type.  */
   finish_record_layout (rli, /*free_p=*/true);
 
   /* Warn about bases that can't be talked about due to ambiguity.  */
@@ -4822,6 +4955,11 @@ layout_class_type (tree t, tree *virtuals_p)
 
   /* Clean up.  */
   splay_tree_delete (empty_base_offsets);
+
+  if (CLASSTYPE_EMPTY_P (t)
+      && tree_int_cst_lt (sizeof_biggest_empty_class,
+                         TYPE_SIZE_UNIT (t)))
+    sizeof_biggest_empty_class = TYPE_SIZE_UNIT (t);
 }
 
 /* Determine the "key method" for the class type indicated by TYPE,
@@ -4971,6 +5109,7 @@ finish_struct_1 (tree 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) != error_mark_node
        && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (x)), t))
       DECL_MODE (x) = TYPE_MODE (t);
 
@@ -4996,6 +5135,9 @@ finish_struct_1 (tree t)
       DECL_SORTED_FIELDS (TYPE_MAIN_DECL (t)) = field_vec;
     }
 
+  /* Complain if one of the field types requires lower visibility.  */
+  constrain_class_visibility (t);
+
   /* Make the rtl for any new vtables we have created, and unmark
      the base types we marked.  */
   finish_vtbls (t);
@@ -5010,17 +5152,19 @@ finish_struct_1 (tree t)
       tree dtor;
 
       dtor = CLASSTYPE_DESTRUCTORS (t);
-      /* Warn only if the dtor is non-private or the class has
-        friends.  */
       if (/* An implicitly declared destructor is always public.  And,
             if it were virtual, we would have created it by now.  */
          !dtor
          || (!DECL_VINDEX (dtor)
-             && (!TREE_PRIVATE (dtor)
-                 || CLASSTYPE_FRIEND_CLASSES (t)
-                 || DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))))
-       warning (0, "%q#T has virtual functions but non-virtual destructor",
-                t);
+             && (/* public non-virtual */
+                 (!TREE_PRIVATE (dtor) && !TREE_PROTECTED (dtor))
+                  || (/* non-public non-virtual with friends */
+                      (TREE_PRIVATE (dtor) || TREE_PROTECTED (dtor))
+                       && (CLASSTYPE_FRIEND_CLASSES (t)
+                       || DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))))))
+       warning (OPT_Wnon_virtual_dtor,
+                "%q#T has virtual functions and accessible"
+                " non-virtual destructor", t);
     }
 
   complete_vars (t);
@@ -5138,16 +5282,17 @@ finish_struct (tree t, tree attributes)
    before this function is called.  */
 
 static tree
-fixed_type_or_null (tree instance, int* nonnull, int* cdtorp)
+fixed_type_or_null (tree instance, int *nonnull, int *cdtorp)
 {
+#define RECUR(T) fixed_type_or_null((T), nonnull, cdtorp)
+
   switch (TREE_CODE (instance))
     {
     case INDIRECT_REF:
       if (POINTER_TYPE_P (TREE_TYPE (instance)))
        return NULL_TREE;
       else
-       return fixed_type_or_null (TREE_OPERAND (instance, 0),
-                                  nonnull, cdtorp);
+       return RECUR (TREE_OPERAND (instance, 0));
 
     case CALL_EXPR:
       /* This is a call to a constructor, hence it's never zero.  */
@@ -5167,20 +5312,22 @@ fixed_type_or_null (tree instance, int* nonnull, int* cdtorp)
            *nonnull = 1;
          return TREE_TYPE (instance);
        }
-      return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
+      return RECUR (TREE_OPERAND (instance, 0));
 
+    case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
     case MINUS_EXPR:
       if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR)
-       return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
+       return RECUR (TREE_OPERAND (instance, 0));
       if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST)
        /* Propagate nonnull.  */
-       return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
+       return RECUR (TREE_OPERAND (instance, 0));
+
       return NULL_TREE;
 
     case NOP_EXPR:
     case CONVERT_EXPR:
-      return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
+      return RECUR (TREE_OPERAND (instance, 0));
 
     case ADDR_EXPR:
       instance = TREE_OPERAND (instance, 0);
@@ -5193,14 +5340,14 @@ fixed_type_or_null (tree instance, int* nonnull, int* cdtorp)
          if (t && DECL_P (t))
            *nonnull = 1;
        }
-      return fixed_type_or_null (instance, nonnull, cdtorp);
+      return RECUR (instance);
 
     case COMPONENT_REF:
       /* If this component is really a base class reference, then the field
         itself isn't definitive.  */
       if (DECL_FIELD_IS_BASE (TREE_OPERAND (instance, 1)))
-       return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
-      return fixed_type_or_null (TREE_OPERAND (instance, 1), nonnull, cdtorp);
+       return RECUR (TREE_OPERAND (instance, 0));
+      return RECUR (TREE_OPERAND (instance, 1));
 
     case VAR_DECL:
     case FIELD_DECL:
@@ -5238,22 +5385,33 @@ fixed_type_or_null (tree instance, int* nonnull, int* cdtorp)
        }
       else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
        {
+         /* We only need one hash table because it is always left empty.  */
+         static htab_t ht;
+         if (!ht)
+           ht = htab_create (37, 
+                             htab_hash_pointer,
+                             htab_eq_pointer,
+                             /*htab_del=*/NULL);
+
          /* Reference variables should be references to objects.  */
          if (nonnull)
            *nonnull = 1;
 
-         /* DECL_VAR_MARKED_P is used to prevent recursion; a
+         /* Enter the INSTANCE in a table to prevent recursion; a
             variable's initializer may refer to the variable
             itself.  */
          if (TREE_CODE (instance) == VAR_DECL
              && DECL_INITIAL (instance)
-             && !DECL_VAR_MARKED_P (instance))
+             && !htab_find (ht, instance))
            {
              tree type;
-             DECL_VAR_MARKED_P (instance) = 1;
-             type = fixed_type_or_null (DECL_INITIAL (instance),
-                                        nonnull, cdtorp);
-             DECL_VAR_MARKED_P (instance) = 0;
+             void **slot;
+
+             slot = htab_find_slot (ht, instance, INSERT);
+             *slot = instance;
+             type = RECUR (DECL_INITIAL (instance));
+             htab_remove_elt (ht, instance);
+
              return type;
            }
        }
@@ -5262,6 +5420,7 @@ fixed_type_or_null (tree instance, int* nonnull, int* cdtorp)
     default:
       return NULL_TREE;
     }
+#undef RECUR
 }
 
 /* Return nonzero if the dynamic type of INSTANCE is known, and
@@ -5283,7 +5442,6 @@ resolves_to_fixed_type_p (tree instance, int* nonnull)
 {
   tree t = TREE_TYPE (instance);
   int cdtorp = 0;
-
   tree fixed = fixed_type_or_null (instance, nonnull, &cdtorp);
   if (fixed == NULL_TREE)
     return 0;
@@ -5301,8 +5459,9 @@ init_class_processing (void)
   current_class_depth = 0;
   current_class_stack_size = 10;
   current_class_stack
-    = xmalloc (current_class_stack_size * sizeof (struct class_stack_node));
+    = XNEWVEC (struct class_stack_node, current_class_stack_size);
   local_classes = VEC_alloc (tree, gc, 8);
+  sizeof_biggest_empty_class = size_zero_node;
 
   ridpointers[(int) RID_PUBLIC] = access_public_node;
   ridpointers[(int) RID_PRIVATE] = access_private_node;
@@ -5341,6 +5500,8 @@ restore_class_cache (void)
 void
 pushclass (tree type)
 {
+  class_stack_node_t csn;
+
   type = TYPE_MAIN_VARIANT (type);
 
   /* Make sure there is enough room for the new entry on the stack.  */
@@ -5348,16 +5509,17 @@ pushclass (tree type)
     {
       current_class_stack_size *= 2;
       current_class_stack
-       = xrealloc (current_class_stack,
-                   current_class_stack_size
-                   * sizeof (struct class_stack_node));
+       = XRESIZEVEC (struct class_stack_node, current_class_stack,
+                     current_class_stack_size);
     }
 
   /* Insert a new entry on the class stack.  */
-  current_class_stack[current_class_depth].name = current_class_name;
-  current_class_stack[current_class_depth].type = current_class_type;
-  current_class_stack[current_class_depth].access = current_access_specifier;
-  current_class_stack[current_class_depth].names_used = 0;
+  csn = current_class_stack + current_class_depth;
+  csn->name = current_class_name;
+  csn->type = current_class_type;
+  csn->access = current_access_specifier;
+  csn->names_used = 0;
+  csn->hidden = 0;
   current_class_depth++;
 
   /* Now set up the new type.  */
@@ -5414,21 +5576,51 @@ popclass (void)
     splay_tree_delete (current_class_stack[current_class_depth].names_used);
 }
 
-/* Returns 1 if current_class_type is either T or a nested type of T.
-   We start looking from 1 because entry 0 is from global scope, and has
-   no type.  */
+/* Mark the top of the class stack as hidden.  */
 
-int
+void
+push_class_stack (void)
+{
+  if (current_class_depth)
+    ++current_class_stack[current_class_depth - 1].hidden;
+}
+
+/* Mark the top of the class stack as un-hidden.  */
+
+void
+pop_class_stack (void)
+{
+  if (current_class_depth)
+    --current_class_stack[current_class_depth - 1].hidden;
+}
+
+/* Returns 1 if the class type currently being defined is either T or
+   a nested type of T.  */
+
+bool
 currently_open_class (tree t)
 {
   int i;
-  if (current_class_type && same_type_p (t, current_class_type))
-    return 1;
-  for (i = 1; i < current_class_depth; ++i)
-    if (current_class_stack[i].type
-       && same_type_p (current_class_stack [i].type, t))
-      return 1;
-  return 0;
+
+  /* We start looking from 1 because entry 0 is from global scope,
+     and has no type.  */
+  for (i = current_class_depth; i > 0; --i)
+    {
+      tree c;
+      if (i == current_class_depth)
+       c = current_class_type;
+      else
+       {
+         if (current_class_stack[i].hidden)
+           break;
+         c = current_class_stack[i].type;
+       }
+      if (!c)
+       continue;
+      if (same_type_p (c, t))
+       return true;
+    }
+  return false;
 }
 
 /* If either current_class_type or one of its enclosing classes are derived
@@ -5451,8 +5643,12 @@ currently_open_derived_class (tree t)
     return current_class_type;
 
   for (i = current_class_depth - 1; i > 0; --i)
-    if (DERIVED_FROM_P (t, current_class_stack[i].type))
-      return current_class_stack[i].type;
+    {
+      if (current_class_stack[i].hidden)
+       break;
+      if (DERIVED_FROM_P (t, current_class_stack[i].type))
+       return current_class_stack[i].type;
+    }
 
   return NULL_TREE;
 }
@@ -5466,21 +5662,13 @@ currently_open_derived_class (tree t)
 void
 push_nested_class (tree type)
 {
-  tree context;
-
   /* A namespace might be passed in error cases, like A::B:C.  */
   if (type == NULL_TREE
-      || type == error_mark_node
-      || TREE_CODE (type) == NAMESPACE_DECL
-      || ! IS_AGGR_TYPE (type)
-      || TREE_CODE (type) == TEMPLATE_TYPE_PARM
-      || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
+      || !CLASS_TYPE_P (type))
     return;
 
-  context = DECL_CONTEXT (TYPE_MAIN_DECL (type));
+  push_nested_class (DECL_CONTEXT (TYPE_MAIN_DECL (type)));
 
-  if (context && CLASS_TYPE_P (context))
-    push_nested_class (context);
   pushclass (type);
 }
 
@@ -5552,18 +5740,21 @@ pop_lang_context (void)
 
 /* Given an OVERLOAD and a TARGET_TYPE, return the function that
    matches the TARGET_TYPE.  If there is no satisfactory match, return
-   error_mark_node, and issue an error & warning messages under control
-   of FLAGS.  Permit pointers to member function if FLAGS permits.  If
-   TEMPLATE_ONLY, the name of the overloaded function was a
-   template-id, and EXPLICIT_TARGS are the explicitly provided
-   template arguments.  */
+   error_mark_node, and issue an error & warning messages under
+   control of FLAGS.  Permit pointers to member function if FLAGS
+   permits.  If TEMPLATE_ONLY, the name of the overloaded function was
+   a template-id, and EXPLICIT_TARGS are the explicitly provided
+   template arguments.  If OVERLOAD is for one or more member
+   functions, then ACCESS_PATH is the base path used to reference
+   those member functions.  */
 
 static tree
 resolve_address_of_overloaded_function (tree target_type,
                                        tree overload,
                                        tsubst_flags_t flags,
                                        bool template_only,
-                                       tree explicit_targs)
+                                       tree explicit_targs,
+                                       tree access_path)
 {
   /* Here's what the standard says:
 
@@ -5729,7 +5920,7 @@ resolve_address_of_overloaded_function (tree target_type,
              build_ptrmemfunc_type (build_pointer_type (instantiation_type));
          else if (!is_reference)
            instantiation_type = build_pointer_type (instantiation_type);
-         if (can_convert_arg (target_type, instantiation_type, instantiation, 
+         if (can_convert_arg (target_type, instantiation_type, instantiation,
                               LOOKUP_NORMAL))
            matches = tree_cons (instantiation, fn, matches);
        }
@@ -5740,7 +5931,9 @@ resolve_address_of_overloaded_function (tree target_type,
          tree match = most_specialized_instantiation (matches);
 
          if (match != error_mark_node)
-           matches = tree_cons (match, NULL_TREE, NULL_TREE);
+           matches = tree_cons (TREE_PURPOSE (match),
+                                NULL_TREE,
+                                NULL_TREE);
        }
     }
 
@@ -5812,7 +6005,17 @@ resolve_address_of_overloaded_function (tree target_type,
      function used.  If this conversion sequence is selected, the
      function will be marked as used at this point.  */
   if (!(flags & tf_conv))
-    mark_used (fn);
+    {
+      mark_used (fn);
+      /* We could not check access when this expression was originally
+        created since we did not know at that time to which function
+        the expression referred.  */
+      if (DECL_FUNCTION_MEMBER_P (fn))
+       {
+         gcc_assert (access_path);
+         perform_or_defer_access_check (access_path, fn, fn);
+       }
+    }
 
   if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
     return build_unary_op (ADDR_EXPR, fn, 0);
@@ -5841,6 +6044,7 @@ tree
 instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
 {
   tsubst_flags_t flags_in = flags;
+  tree access_path = NULL_TREE;
 
   flags &= ~tf_ptrmem_ok;
 
@@ -5871,7 +6075,10 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
     }
 
   if (TREE_CODE (rhs) == BASELINK)
-    rhs = BASELINK_FUNCTIONS (rhs);
+    {
+      access_path = BASELINK_ACCESS_BINFO (rhs);
+      rhs = BASELINK_FUNCTIONS (rhs);
+    }
 
   /* If we are in a template, and have a NON_DEPENDENT_EXPR, we cannot
      deduce any type information.  */
@@ -5882,6 +6089,13 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
       return error_mark_node;
     }
 
+  /* There only a few kinds of expressions that may have a type
+     dependent on overload resolution.  */
+  gcc_assert (TREE_CODE (rhs) == ADDR_EXPR
+             || TREE_CODE (rhs) == COMPONENT_REF
+             || TREE_CODE (rhs) == COMPOUND_EXPR
+             || really_overloaded_fn (rhs));
+
   /* We don't overwrite rhs if it is an overloaded function.
      Copying it would destroy the tree link.  */
   if (TREE_CODE (rhs) != OVERLOAD)
@@ -5894,32 +6108,6 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
 
   switch (TREE_CODE (rhs))
     {
-    case TYPE_EXPR:
-    case CONVERT_EXPR:
-    case SAVE_EXPR:
-    case CONSTRUCTOR:
-      gcc_unreachable ();
-
-    case INDIRECT_REF:
-    case ARRAY_REF:
-      {
-       tree new_rhs;
-
-       new_rhs = instantiate_type (build_pointer_type (lhstype),
-                                   TREE_OPERAND (rhs, 0), flags);
-       if (new_rhs == error_mark_node)
-         return error_mark_node;
-
-       TREE_TYPE (rhs) = lhstype;
-       TREE_OPERAND (rhs, 0) = new_rhs;
-       return rhs;
-      }
-
-    case NOP_EXPR:
-      rhs = copy_node (TREE_OPERAND (rhs, 0));
-      TREE_TYPE (rhs) = unknown_type_node;
-      return instantiate_type (lhstype, rhs, flags);
-
     case COMPONENT_REF:
       {
        tree member = TREE_OPERAND (rhs, 1);
@@ -5936,7 +6124,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
     case OFFSET_REF:
       rhs = TREE_OPERAND (rhs, 1);
       if (BASELINK_P (rhs))
-       return instantiate_type (lhstype, BASELINK_FUNCTIONS (rhs), flags_in);
+       return instantiate_type (lhstype, rhs, flags_in);
 
       /* This can happen if we are forming a pointer-to-member for a
         member template.  */
@@ -5952,7 +6140,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
        return
          resolve_address_of_overloaded_function (lhstype, fns, flags_in,
                                                  /*template_only=*/true,
-                                                 args);
+                                                 args, access_path);
       }
 
     case OVERLOAD:
@@ -5960,14 +6148,9 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
       return
        resolve_address_of_overloaded_function (lhstype, rhs, flags_in,
                                                /*template_only=*/false,
-                                               /*explicit_targs=*/NULL_TREE);
-
-    case CALL_EXPR:
-      /* This is too hard for now.  */
-      gcc_unreachable ();
+                                               /*explicit_targs=*/NULL_TREE,
+                                               access_path);
 
-    case PLUS_EXPR:
-    case MINUS_EXPR:
     case COMPOUND_EXPR:
       TREE_OPERAND (rhs, 0)
        = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
@@ -5981,86 +6164,6 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
       TREE_TYPE (rhs) = lhstype;
       return rhs;
 
-    case MULT_EXPR:
-    case TRUNC_DIV_EXPR:
-    case FLOOR_DIV_EXPR:
-    case CEIL_DIV_EXPR:
-    case ROUND_DIV_EXPR:
-    case RDIV_EXPR:
-    case TRUNC_MOD_EXPR:
-    case FLOOR_MOD_EXPR:
-    case CEIL_MOD_EXPR:
-    case ROUND_MOD_EXPR:
-    case FIX_ROUND_EXPR:
-    case FIX_FLOOR_EXPR:
-    case FIX_CEIL_EXPR:
-    case FIX_TRUNC_EXPR:
-    case FLOAT_EXPR:
-    case NEGATE_EXPR:
-    case ABS_EXPR:
-    case MAX_EXPR:
-    case MIN_EXPR:
-
-    case BIT_AND_EXPR:
-    case BIT_IOR_EXPR:
-    case BIT_XOR_EXPR:
-    case LSHIFT_EXPR:
-    case RSHIFT_EXPR:
-    case LROTATE_EXPR:
-    case RROTATE_EXPR:
-
-    case PREINCREMENT_EXPR:
-    case PREDECREMENT_EXPR:
-    case POSTINCREMENT_EXPR:
-    case POSTDECREMENT_EXPR:
-      if (flags & tf_error)
-       error ("invalid operation on uninstantiated type");
-      return error_mark_node;
-
-    case TRUTH_AND_EXPR:
-    case TRUTH_OR_EXPR:
-    case TRUTH_XOR_EXPR:
-    case LT_EXPR:
-    case LE_EXPR:
-    case GT_EXPR:
-    case GE_EXPR:
-    case EQ_EXPR:
-    case NE_EXPR:
-    case TRUTH_ANDIF_EXPR:
-    case TRUTH_ORIF_EXPR:
-    case TRUTH_NOT_EXPR:
-      if (flags & tf_error)
-       error ("not enough type information");
-      return error_mark_node;
-
-    case COND_EXPR:
-      if (type_unknown_p (TREE_OPERAND (rhs, 0)))
-       {
-         if (flags & tf_error)
-           error ("not enough type information");
-         return error_mark_node;
-       }
-      TREE_OPERAND (rhs, 1)
-       = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
-      if (TREE_OPERAND (rhs, 1) == error_mark_node)
-       return error_mark_node;
-      TREE_OPERAND (rhs, 2)
-       = instantiate_type (lhstype, TREE_OPERAND (rhs, 2), flags);
-      if (TREE_OPERAND (rhs, 2) == error_mark_node)
-       return error_mark_node;
-
-      TREE_TYPE (rhs) = lhstype;
-      return rhs;
-
-    case MODIFY_EXPR:
-      TREE_OPERAND (rhs, 1)
-       = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
-      if (TREE_OPERAND (rhs, 1) == error_mark_node)
-       return error_mark_node;
-
-      TREE_TYPE (rhs) = lhstype;
-      return rhs;
-
     case ADDR_EXPR:
     {
       if (PTRMEM_OK_P (rhs))
@@ -6102,7 +6205,8 @@ get_vfield_name (tree type)
     }
 
   type = BINFO_TYPE (binfo);
-  buf = alloca (sizeof (VFIELD_NAME_FORMAT) + TYPE_NAME_LENGTH (type) + 2);
+  buf = (char *) alloca (sizeof (VFIELD_NAME_FORMAT)
+                        + TYPE_NAME_LENGTH (type) + 2);
   sprintf (buf, VFIELD_NAME_FORMAT,
           IDENTIFIER_POINTER (constructor_name (type)));
   return get_identifier (buf);
@@ -6251,9 +6355,9 @@ note_name_declared_in_class (tree name, tree decl)
         A name N used in a class S shall refer to the same declaration
         in its context and when re-evaluated in the completed scope of
         S.  */
-      error ("declaration of %q#D", decl);
-      error ("changes meaning of %qD from %q+#D",
-            DECL_NAME (OVL_CURRENT (decl)), (tree) n->value);
+      pedwarn ("declaration of %q#D", decl);
+      pedwarn ("changes meaning of %qD from %q+#D",
+              DECL_NAME (OVL_CURRENT (decl)), (tree) n->value);
     }
 }
 
@@ -6267,7 +6371,7 @@ get_vtbl_decl_for_binfo (tree binfo)
   tree decl;
 
   decl = BINFO_VTABLE (binfo);
-  if (decl && TREE_CODE (decl) == PLUS_EXPR)
+  if (decl && TREE_CODE (decl) == POINTER_PLUS_EXPR)
     {
       gcc_assert (TREE_CODE (TREE_OPERAND (decl, 0)) == ADDR_EXPR);
       decl = TREE_OPERAND (TREE_OPERAND (decl, 0), 0);
@@ -6284,18 +6388,16 @@ get_vtbl_decl_for_binfo (tree binfo)
    BINFO in the complete object.  Check BINFO_PRIMARY_P or
    BINFO_LOST_PRIMARY_P to be sure.  */
 
-tree
+static tree
 get_primary_binfo (tree binfo)
 {
   tree primary_base;
-  tree result;
 
   primary_base = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (binfo));
   if (!primary_base)
     return NULL_TREE;
 
-  result = copied_binfo (primary_base, binfo);
-  return result;
+  return copied_binfo (primary_base, binfo);
 }
 
 /* If INDENTED_P is zero, indent to INDENT. Return nonzero.  */
@@ -6425,7 +6527,7 @@ dump_class_hierarchy_1 (FILE *stream, int flags, tree t)
 
 /* Debug interface to hierarchy dumping.  */
 
-extern void
+void
 debug_class (tree t)
 {
   dump_class_hierarchy_1 (stderr, TDF_SLIM, t);
@@ -6555,7 +6657,7 @@ dump_thunk (FILE *stream, int indent, tree thunk)
 
 /* Dump the thunks for FN.  */
 
-extern void
+void
 debug_thunks (tree fn)
 {
   dump_thunk (stderr, 0, fn);
@@ -6638,7 +6740,7 @@ build_vtt (tree t)
   type = build_cplus_array_type (const_ptr_type_node, type);
 
   /* Now, build the VTT object itself.  */
-  vtt = build_vtable (t, get_vtt_name (t), type);
+  vtt = build_vtable (t, mangle_vtt_for_type (t), type);
   initialize_artificial_var (vtt, inits);
   /* Add the VTT to the vtables list.  */
   TREE_CHAIN (vtt) = TREE_CHAIN (CLASSTYPE_VTABLES (t));
@@ -6904,7 +7006,10 @@ build_ctor_vtbl_group (tree binfo, tree t)
   /* Figure out the type of the construction vtable.  */
   type = build_index_type (size_int (list_length (inits) - 1));
   type = build_cplus_array_type (vtable_entry_type, type);
+  layout_type (type);
   TREE_TYPE (vtbl) = type;
+  DECL_SIZE (vtbl) = DECL_SIZE_UNIT (vtbl) = NULL_TREE;
+  layout_decl (vtbl, 0);
 
   /* Initialize the construction vtable.  */
   CLASSTYPE_VTABLES (t) = chainon (CLASSTYPE_VTABLES (t), vtbl);
@@ -7055,7 +7160,7 @@ dfs_accumulate_vtbl_inits (tree binfo,
       index = size_binop (MULT_EXPR,
                          TYPE_SIZE_UNIT (vtable_entry_type),
                          index);
-      vtbl = build2 (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, index);
+      vtbl = build2 (POINTER_PLUS_EXPR, TREE_TYPE (vtbl), vtbl, index);
     }
 
   if (ctor_vtbl_p)
@@ -7402,7 +7507,14 @@ build_vcall_offset_vtbl_entries (tree binfo, vtbl_init_data* vid)
   /* We only need these entries if this base is a virtual base.  We
      compute the indices -- but do not add to the vtable -- when
      building the main vtable for a class.  */
-  if (BINFO_VIRTUAL_P (binfo) || binfo == TYPE_BINFO (vid->derived))
+  if (binfo == TYPE_BINFO (vid->derived)
+      || (BINFO_VIRTUAL_P (binfo) 
+         /* If BINFO is RTTI_BINFO, then (since BINFO does not
+            correspond to VID->DERIVED), we are building a primary
+            construction virtual table.  Since this is a primary
+            virtual table, we do not need the vcall offsets for
+            BINFO.  */
+         && binfo != vid->rtti_binfo))
     {
       /* We need a vcall offset for each of the virtual functions in this
         vtable.  For example: