OSDN Git Service

PR c++/48948
[pf3gnuchains/gcc-fork.git] / gcc / cp / class.c
index 86dbcca..4e52b18 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, 2008, 2009, 2010
+   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.  */
@@ -30,13 +30,13 @@ Boston, MA 02110-1301, USA.  */
 #include "tree.h"
 #include "cp-tree.h"
 #include "flags.h"
-#include "rtl.h"
 #include "output.h"
 #include "toplev.h"
 #include "target.h"
 #include "convert.h"
 #include "cgraph.h"
 #include "tree-dump.h"
+#include "splay-tree.h"
 
 /* The number of nested classes being processed.  If we are not in the
    scope of any class, this is zero.  */
@@ -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
@@ -73,9 +77,7 @@ typedef struct vtbl_init_data_s
   tree rtti_binfo;
   /* The negative-index vtable initializers built up so far.  These
      are in order from least negative index to most negative index.  */
-  tree inits;
-  /* The last (i.e., most negative) entry in INITS.  */
-  tree* last_init;
+  VEC(constructor_elt,gc) *inits;
   /* The binfo for the virtual base for which we're building
      vcall offset initializers.  */
   tree vbase;
@@ -130,14 +132,13 @@ 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 void build_vtbl_initializer (tree, tree, tree, tree, int *,
+                                   VEC(constructor_elt,gc) **);
 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 *);
@@ -149,8 +150,6 @@ static void check_bases_and_members (tree);
 static tree create_vtable_ptr (tree, tree *);
 static void include_empty_classes (record_layout_info);
 static void layout_class_type (tree, tree *);
-static void fixup_pending_inline (tree);
-static void fixup_inline_methods (tree);
 static void propagate_binfo_offsets (tree, tree);
 static void layout_virtual_bases (record_layout_info, splay_tree);
 static void build_vbase_offset_vtbl_entries (tree, vtbl_init_data *);
@@ -163,6 +162,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);
@@ -172,14 +172,15 @@ static void dump_vtable (tree, tree, tree);
 static void dump_vtt (tree, tree);
 static void dump_thunk (FILE *, int, tree);
 static tree build_vtable (tree, tree, tree);
-static void initialize_vtable (tree, tree);
+static void initialize_vtable (tree, VEC(constructor_elt,gc) *);
 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 void accumulate_vtbl_inits (tree, tree, tree, tree, tree);
-static tree dfs_accumulate_vtbl_inits (tree, tree, tree, tree,
-                                              tree);
+static bool layout_empty_base (record_layout_info, tree, tree, splay_tree);
+static void accumulate_vtbl_inits (tree, tree, tree, tree, tree,
+                                  VEC(constructor_elt,gc) **);
+static void dfs_accumulate_vtbl_inits (tree, tree, tree, tree, tree,
+                                      VEC(constructor_elt,gc) **);
 static void build_rtti_vtbl_entries (tree, vtbl_init_data *);
 static void build_vcall_and_vbase_vtbl_entries (tree, vtbl_init_data *);
 static void clone_constructors_and_destructors (tree);
@@ -188,7 +189,7 @@ static void update_vtable_entry_for_fn (tree, tree, tree, tree *, unsigned);
 static void build_ctor_vtbl_group (tree, tree);
 static void build_vtt (tree);
 static tree binfo_ctor_vtable (tree);
-static tree *build_vtt_inits (tree, tree, tree *, tree *);
+static void build_vtt_inits (tree, tree, VEC(constructor_elt,gc) **, tree *);
 static tree dfs_build_secondary_vptr_vtt_inits (tree, void *);
 static tree dfs_fixup_binfo_vtbls (tree, void *);
 static int record_subobject_offset (tree, tree, splay_tree);
@@ -281,17 +282,50 @@ build_base_path (enum tree_code code,
 
   if (!want_pointer)
     /* This must happen before the call to save_expr.  */
-    expr = build_unary_op (ADDR_EXPR, expr, 0);
+    expr = cp_build_addr_expr (expr, tf_warning_or_error);
+  else
+    expr = mark_rvalue_use (expr);
 
   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);
 
+  /* Don't bother with the calculations inside sizeof; they'll ICE if the
+     source type is incomplete and the pointer value doesn't matter.  */
+  if (cp_unevaluated_operand != 0)
+    {
+      expr = build_nop (build_pointer_type (target_type), expr);
+      if (!want_pointer)
+       expr = build_indirect_ref (EXPR_LOCATION (expr), expr, RO_NULL);
+      return expr;
+    }
+
   /* 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))
@@ -301,7 +335,7 @@ build_base_path (enum tree_code code,
   if (null_test)
     {
       tree zero = cp_convert (TREE_TYPE (expr), integer_zero_node);
-      null_test = fold_build2 (NE_EXPR, boolean_type_node,
+      null_test = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
                               expr, zero);
     }
 
@@ -311,7 +345,7 @@ build_base_path (enum tree_code code,
         interesting to the optimizers anyway.  */
       && !has_empty)
     {
-      expr = build_indirect_ref (expr, NULL);
+      expr = cp_build_indirect_ref (expr, RO_NULL, tf_warning_or_error);
       expr = build_simple_base_path (expr, binfo);
       if (want_pointer)
        expr = build_address (expr);
@@ -336,23 +370,24 @@ build_base_path (enum tree_code code,
          t = TREE_TYPE (TYPE_VFIELD (current_class_type));
          t = build_pointer_type (t);
          v_offset = convert (t, current_vtt_parm);
-         v_offset = build_indirect_ref (v_offset, NULL);
+         v_offset = cp_build_indirect_ref (v_offset, RO_NULL, 
+                                            tf_warning_or_error);
        }
       else
-       v_offset = build_vfield_ref (build_indirect_ref (expr, NULL),
+       v_offset = build_vfield_ref (cp_build_indirect_ref (expr, RO_NULL,
+                                                            tf_warning_or_error),
                                     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);
-      v_offset = build_indirect_ref (v_offset, NULL);
+      v_offset = cp_build_indirect_ref (v_offset, RO_NULL, tf_warning_or_error);
       TREE_CONSTANT (v_offset) = 1;
-      TREE_INVARIANT (v_offset) = 1;
 
       offset = convert_to_integer (ptrdiff_type_node,
-                                  size_diffop (offset,
+                                  size_diffop_loc (input_location, offset,
                                                BINFO_OFFSET (v_binfo)));
 
       if (!integer_zerop (offset))
@@ -372,8 +407,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);
@@ -383,18 +416,22 @@ 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_loc (input_location, NEGATE_EXPR, sizetype, offset);
+      expr = build2 (POINTER_PLUS_EXPR, ptr_target_type, expr, offset);
+    }
   else
     null_test = NULL;
 
   if (!want_pointer)
-    expr = build_indirect_ref (expr, NULL);
+    expr = cp_build_indirect_ref (expr, RO_NULL, tf_warning_or_error);
 
  out:
   if (null_test)
-    expr = fold_build3 (COND_EXPR, target_type, null_test, expr,
-                       fold_build1 (NOP_EXPR, target_type,
-                                    integer_zero_node));
+    expr = fold_build3_loc (input_location, COND_EXPR, target_type, null_test, expr,
+                           build_zero_cst (target_type));
 
   return expr;
 }
@@ -418,11 +455,11 @@ 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);
+       expr = cp_build_indirect_ref (temp, RO_NULL, tf_warning_or_error);
 
       return expr;
     }
@@ -431,7 +468,7 @@ build_simple_base_path (tree expr, tree binfo)
   expr = build_simple_base_path (expr, d_binfo);
 
   for (field = TYPE_FIELDS (BINFO_TYPE (d_binfo));
-       field; field = TREE_CHAIN (field))
+       field; field = DECL_CHAIN (field))
     /* Is this the base field created by build_base_field?  */
     if (TREE_CODE (field) == FIELD_DECL
        && DECL_FIELD_IS_BASE (field)
@@ -470,10 +507,12 @@ build_simple_base_path (tree expr, tree binfo)
    assumed to be non-NULL.  */
 
 tree
-convert_to_base (tree object, tree type, bool check_access, bool nonnull)
+convert_to_base (tree object, tree type, bool check_access, bool nonnull,
+                tsubst_flags_t complain)
 {
   tree binfo;
   tree object_type;
+  base_access access;
 
   if (TYPE_PTR_P (TREE_TYPE (object)))
     {
@@ -483,8 +522,11 @@ convert_to_base (tree object, tree type, bool check_access, bool nonnull)
   else
     object_type = TREE_TYPE (object);
 
+  access = check_access ? ba_check : ba_unique;
+  if (!(complain & tf_error))
+    access |= ba_quiet;
   binfo = lookup_base (object_type, type,
-                      check_access ? ba_check : ba_unique,
+                      access,
                       NULL);
   if (!binfo || binfo == error_mark_node)
     return error_mark_node;
@@ -508,12 +550,19 @@ convert_to_base_statically (tree expr, tree base)
       tree pointer_type;
 
       pointer_type = build_pointer_type (expr_type);
-      expr = build_unary_op (ADDR_EXPR, expr, /*noconvert=*/1);
+
+      /* 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 = cp_build_addr_expr (expr, tf_warning_or_error);
       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_loc (input_location,
+                           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_loc (input_location, expr);
     }
 
   return expr;
@@ -531,7 +580,7 @@ build_vfield_ref (tree datum, tree type)
   /* First, convert to the requested type.  */
   if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type))
     datum = convert_to_base (datum, type, /*check_access=*/false,
-                            /*nonnull=*/true);
+                            /*nonnull=*/true, tf_warning_or_error);
 
   /* Second, the requested type may not be the owner of its own vptr.
      If not, convert to the base class that owns it.  We cannot use
@@ -580,11 +629,8 @@ build_vtbl_ref_1 (tree instance, tree idx)
   if (!vtbl)
     vtbl = build_vfield_ref (instance, basetype);
 
-  assemble_external (vtbl);
-
-  aref = build_array_ref (vtbl, idx);
+  aref = build_array_ref (input_location, vtbl, idx);
   TREE_CONSTANT (aref) |= TREE_CONSTANT (vtbl) && TREE_CONSTANT (idx);
-  TREE_INVARIANT (aref) = TREE_CONSTANT (aref);
 
   return aref;
 }
@@ -605,13 +651,15 @@ build_vfn_ref (tree instance_ptr, tree idx)
 {
   tree aref;
 
-  aref = build_vtbl_ref_1 (build_indirect_ref (instance_ptr, 0), idx);
+  aref = build_vtbl_ref_1 (cp_build_indirect_ref (instance_ptr, RO_NULL,
+                                                  tf_warning_or_error), 
+                           idx);
 
   /* When using function descriptors, the address of the
      vtable entry is treated as a function pointer.  */
   if (TARGET_VTABLE_USES_DESCRIPTORS)
     aref = build1 (NOP_EXPR, TREE_TYPE (aref),
-                  build_unary_op (ADDR_EXPR, aref, /*noconvert=*/1));
+                  cp_build_addr_expr (aref, tf_warning_or_error));
 
   /* Remember this as a method reference, for later devirtualization.  */
   aref = build3 (OBJ_TYPE_REF, TREE_TYPE (aref), aref, instance_ptr, idx);
@@ -628,15 +676,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
@@ -737,7 +776,7 @@ get_vtable_decl (tree type, int complete)
   if (complete)
     {
       DECL_EXTERNAL (decl) = 1;
-      cp_finish_decl (decl, NULL_TREE, NULL_TREE, 0);
+      cp_finish_decl (decl, NULL_TREE, false, NULL_TREE, 0);
     }
 
   return decl;
@@ -896,6 +935,7 @@ 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 false;
@@ -920,6 +960,9 @@ add_method (tree type, tree method, tree using_decl)
       CLASSTYPE_METHOD_VEC (type) = method_vec;
     }
 
+  /* Maintain TYPE_HAS_USER_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;
@@ -970,96 +1013,89 @@ 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;
-
-      /* 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 fn_type;
-         tree method_type;
-         tree parms1;
-         tree parms2;
+      tree fn = OVL_CURRENT (fns);
+      tree fn_type;
+      tree method_type;
+      tree parms1;
+      tree parms2;
 
-         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).  */
+      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)
+         && TREE_TYPE (TREE_VALUE (parms1)) != error_mark_node
+         && TREE_TYPE (TREE_VALUE (parms2)) != error_mark_node
+         && (cp_type_quals (TREE_TYPE (TREE_VALUE (parms1)))
+             != cp_type_quals (TREE_TYPE (TREE_VALUE (parms2)))))
+       continue;
 
-         /* 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;
+      /* 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 (! 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 (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 false;
-                 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 false;
+               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.  */ 
+  /* A class should never have more than one destructor.  */
   if (current_fns && DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (method))
     return false;
 
@@ -1073,9 +1109,15 @@ add_method (tree type, tree method, tree using_decl)
 
   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);
@@ -1124,7 +1166,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;
     }
@@ -1210,9 +1252,15 @@ check_bases (tree t,
   int seen_non_virtual_nearly_empty_base_p;
   tree base_binfo;
   tree binfo;
+  tree field = NULL_TREE;
 
   seen_non_virtual_nearly_empty_base_p = 0;
 
+  if (!CLASSTYPE_NON_STD_LAYOUT (t))
+    for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
+      if (TREE_CODE (field) == FIELD_DECL)
+       break;
+
   for (binfo = TYPE_BINFO (t), i = 0;
        BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
     {
@@ -1220,20 +1268,30 @@ check_bases (tree t,
 
       gcc_assert (COMPLETE_TYPE_P (basetype));
 
+      if (CLASSTYPE_FINAL (basetype))
+        error ("cannot derive from %<final%> base %qT in derived type %qT",
+               basetype, t);
+
+      /* If any base class is non-literal, so is the derived class.  */
+      if (!CLASSTYPE_LITERAL_P (basetype))
+        CLASSTYPE_LITERAL_P (t) = false;
+
       /* 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
         derived class cannot have such a member automatically
         generated.  */
-      if (! TYPE_HAS_CONST_INIT_REF (basetype))
+      if (TYPE_HAS_COPY_CTOR (basetype)
+         && ! TYPE_HAS_CONST_COPY_CTOR (basetype))
        *cant_have_const_ctor_p = 1;
-      if (TYPE_HAS_ASSIGN_REF (basetype)
-         && !TYPE_HAS_CONST_ASSIGN_REF (basetype))
+      if (TYPE_HAS_COPY_ASSIGN (basetype)
+         && !TYPE_HAS_CONST_COPY_ASSIGN (basetype))
        *no_const_asn_ref_p = 1;
 
       if (BINFO_VIRTUAL_P (base_binfo))
@@ -1259,12 +1317,49 @@ check_bases (tree t,
       TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype);
       TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
        |= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (basetype);
-      TYPE_HAS_COMPLEX_ASSIGN_REF (t)
-       |= TYPE_HAS_COMPLEX_ASSIGN_REF (basetype);
-      TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (basetype);
+      TYPE_HAS_COMPLEX_COPY_ASSIGN (t)
+       |= (TYPE_HAS_COMPLEX_COPY_ASSIGN (basetype)
+           || !TYPE_HAS_COPY_ASSIGN (basetype));
+      TYPE_HAS_COMPLEX_COPY_CTOR (t) |= (TYPE_HAS_COMPLEX_COPY_CTOR (basetype)
+                                        || !TYPE_HAS_COPY_CTOR (basetype));
+      TYPE_HAS_COMPLEX_MOVE_ASSIGN (t)
+       |= TYPE_HAS_COMPLEX_MOVE_ASSIGN (basetype);
+      TYPE_HAS_COMPLEX_MOVE_CTOR (t) |= TYPE_HAS_COMPLEX_MOVE_CTOR (basetype);
       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_DEFAULT_CONSTRUCTOR (basetype)
+                                   || TYPE_HAS_COMPLEX_DFLT (basetype));
+
+      /*  A standard-layout class is a class that:
+         ...
+         * has no non-standard-layout base classes,  */
+      CLASSTYPE_NON_STD_LAYOUT (t) |= CLASSTYPE_NON_STD_LAYOUT (basetype);
+      if (!CLASSTYPE_NON_STD_LAYOUT (t))
+       {
+         tree basefield;
+         /* ...has no base classes of the same type as the first non-static
+            data member...  */
+         if (field && DECL_CONTEXT (field) == t
+             && (same_type_ignoring_top_level_qualifiers_p
+                 (TREE_TYPE (field), basetype)))
+           CLASSTYPE_NON_STD_LAYOUT (t) = 1;
+         else
+           /* ...either has no non-static data members in the most-derived
+              class and at most one base class with non-static data
+              members, or has no base classes with non-static data
+              members */
+           for (basefield = TYPE_FIELDS (basetype); basefield;
+                basefield = DECL_CHAIN (basefield))
+             if (TREE_CODE (basefield) == FIELD_DECL)
+               {
+                 if (field)
+                   CLASSTYPE_NON_STD_LAYOUT (t) = 1;
+                 else
+                   field = basefield;
+                 break;
+               }
+       }
     }
 }
 
@@ -1320,7 +1415,8 @@ determine_primary_bases (tree t)
              /* A virtual binfo might have been copied from within
                 another hierarchy. As we're about to use it as a
                 primary base, make sure the offsets match.  */
-             delta = size_diffop (convert (ssizetype,
+             delta = size_diffop_loc (input_location,
+                                  convert (ssizetype,
                                            BINFO_OFFSET (base_binfo)),
                                   convert (ssizetype,
                                            BINFO_OFFSET (this_primary)));
@@ -1383,7 +1479,7 @@ determine_primary_bases (tree t)
          /* A virtual binfo might have been copied from within
             another hierarchy. As we're about to use it as a primary
             base, make sure the offsets match.  */
-         delta = size_diffop (ssize_int (0),
+         delta = size_diffop_loc (input_location, ssize_int (0),
                               convert (ssizetype, BINFO_OFFSET (primary)));
 
          propagate_binfo_offsets (primary, delta);
@@ -1396,23 +1492,24 @@ determine_primary_bases (tree t)
       BINFO_VIRTUALS (type_binfo) = BINFO_VIRTUALS (primary);
     }
 }
-\f
-/* Set memoizing fields and bits of T (and its variants) for later
-   use.  */
 
-static void
-finish_struct_bits (tree t)
+/* Update the variant types of T.  */
+
+void
+fixup_type_variants (tree t)
 {
   tree variants;
 
-  /* Fix up variants (if any).  */
+  if (!t)
+    return;
+
   for (variants = TYPE_NEXT_VARIANT (t);
        variants;
        variants = TYPE_NEXT_VARIANT (variants))
     {
       /* These fields are in the _TYPE part of the node, not in
         the TYPE_LANG_SPECIFIC component, so they are not shared.  */
-      TYPE_HAS_CONSTRUCTOR (variants) = TYPE_HAS_CONSTRUCTOR (t);
+      TYPE_HAS_USER_CONSTRUCTOR (variants) = TYPE_HAS_USER_CONSTRUCTOR (t);
       TYPE_NEEDS_CONSTRUCTING (variants) = TYPE_NEEDS_CONSTRUCTING (t);
       TYPE_HAS_NONTRIVIAL_DESTRUCTOR (variants)
        = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t);
@@ -1425,9 +1522,40 @@ 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);
     }
+}
+
+/* Early variant fixups: we apply attributes at the beginning of the class
+   definition, and we need to fix up any variants that have already been
+   made via elaborated-type-specifier so that check_qualified_type works.  */
+
+void
+fixup_attribute_variants (tree t)
+{
+  tree variants;
+
+  if (!t)
+    return;
+
+  for (variants = TYPE_NEXT_VARIANT (t);
+       variants;
+       variants = TYPE_NEXT_VARIANT (variants))
+    {
+      /* These are the two fields that check_qualified_type looks at and
+        are affected by attributes.  */
+      TYPE_ATTRIBUTES (variants) = TYPE_ATTRIBUTES (t);
+      TYPE_ALIGN (variants) = TYPE_ALIGN (t);
+    }
+}
+\f
+/* Set memoizing fields and bits of T (and its variants) for later
+   use.  */
+
+static void
+finish_struct_bits (tree t)
+{
+  /* Fix up variants (if any).  */
+  fixup_type_variants (t);
 
   if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) && TYPE_POLYMORPHIC_P (t))
     /* For a class w/o baseclasses, 'finish_struct' has set
@@ -1444,13 +1572,14 @@ finish_struct_bits (tree t)
      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))
+  if (type_has_nontrivial_copy_init (t)
+      || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
     {
       tree variants;
       DECL_MODE (TYPE_MAIN_DECL (t)) = BLKmode;
       for (variants = t; variants; variants = TYPE_NEXT_VARIANT (variants))
        {
-         TYPE_MODE (variants) = BLKmode;
+         SET_TYPE_MODE (variants, BLKmode);
          TREE_ADDRESSABLE (variants) = 1;
        }
     }
@@ -1498,7 +1627,7 @@ maybe_warn_about_overly_private_class (tree t)
      functions are private.  (Since there are no friends or
      non-private statics, we can't ever call any of the private member
      functions.)  */
-  for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
+  for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
     /* We're not interested in compiler-generated methods; they don't
        provide any way to call private members.  */
     if (!DECL_ARTIFICIAL (fn))
@@ -1538,7 +1667,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;
        }
     }
@@ -1549,12 +1679,14 @@ 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)
+  /* Warn about classes that have private constructors and no friends.  */
+  if (TYPE_HAS_USER_CONSTRUCTOR (t)
       /* Implicitly generated constructors are always public.  */
       && (!CLASSTYPE_LAZY_DEFAULT_CTOR (t)
          || !CLASSTYPE_LAZY_COPY_CTOR (t)))
@@ -1568,10 +1700,10 @@ maybe_warn_about_overly_private_class (tree t)
 
           template <class T> class C { private: C(); };
 
-        To avoid this asymmetry, we check TYPE_HAS_INIT_REF.  All
+        To avoid this asymmetry, we check TYPE_HAS_COPY_CTOR.  All
         complete non-template or fully instantiated classes have this
         flag set.  */
-      if (!TYPE_HAS_INIT_REF (t))
+      if (!TYPE_HAS_COPY_CTOR (t))
        nonprivate_ctor = 1;
       else
        for (fn = CLASSTYPE_CONSTRUCTORS (t); fn; fn = OVL_NEXT (fn))
@@ -1592,7 +1724,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;
        }
@@ -1609,8 +1742,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;
@@ -1629,8 +1762,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)
@@ -1699,7 +1832,7 @@ finish_struct_methods (tree t)
 
   /* Clear DECL_IN_AGGR_P for all functions.  */
   for (fn_fields = TYPE_METHODS (t); fn_fields;
-       fn_fields = TREE_CHAIN (fn_fields))
+       fn_fields = DECL_CHAIN (fn_fields))
     DECL_IN_AGGR_P (fn_fields) = 0;
 
   /* Issue warnings about private constructors and such.  If there are
@@ -1719,7 +1852,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,8 +1861,7 @@ layout_vtable_decl (tree binfo, int n)
   tree atype;
   tree vtable;
 
-  atype = build_cplus_array_type (vtable_entry_type,
-                                 build_index_type (size_int (n - 1)));
+  atype = build_array_of_n_type (vtable_entry_type, n);
   layout_type (atype);
 
   /* We may have to grow the vtable.  */
@@ -1746,7 +1878,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.  */
@@ -1769,8 +1901,8 @@ same_signature_p (tree fndecl, tree base_fndecl)
       tree types, base_types;
       types = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
       base_types = TYPE_ARG_TYPES (TREE_TYPE (base_fndecl));
-      if ((TYPE_QUALS (TREE_TYPE (TREE_VALUE (base_types)))
-          == TYPE_QUALS (TREE_TYPE (TREE_VALUE (types))))
+      if ((cp_type_quals (TREE_TYPE (TREE_VALUE (base_types)))
+          == cp_type_quals (TREE_TYPE (TREE_VALUE (types))))
          && compparms (TREE_CHAIN (base_types), TREE_CHAIN (types)))
        return 1;
     }
@@ -1939,7 +2071,7 @@ get_vcall_index (tree fn, tree type)
   tree_pair_p p;
   unsigned ix;
 
-  for (ix = 0; VEC_iterate (tree_pair_s, indices, ix, p); ix++)
+  FOR_EACH_VEC_ELT (tree_pair_s, indices, ix, p)
     if ((DECL_DESTRUCTOR_P (fn) && DECL_DESTRUCTOR_P (p->purpose))
        || same_signature_p (fn, p->purpose))
       return p->value;
@@ -1949,8 +2081,9 @@ get_vcall_index (tree fn, tree type)
 }
 
 /* Update an entry in the vtable for BINFO, which is in the hierarchy
-   dominated by T.  FN has been overridden in BINFO; VIRTUALS points to the
-   corresponding position in the BINFO_VIRTUALS list.  */
+   dominated by T.  FN is the old function; VIRTUALS points to the
+   corresponding position in the new BINFO_VIRTUALS list.  IX is the index
+   of that entry in the list.  */
 
 static void
 update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
@@ -2069,9 +2202,10 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
                {
                  /* We convert via virtual base.  Adjust the fixed
                     offset to be from there.  */
-                 offset = size_diffop
-                   (offset, convert
-                    (ssizetype, BINFO_OFFSET (virtual_offset)));
+                 offset = 
+                   size_diffop (offset,
+                                convert (ssizetype,
+                                         BINFO_OFFSET (virtual_offset)));
                }
              if (fixed_offset)
                /* There was an existing fixed offset, this must be
@@ -2091,7 +2225,42 @@ 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));
+
+  /* If we need a covariant thunk, then we may need to adjust first_defn.
+     The ABI specifies that the thunks emitted with a function are
+     determined by which bases the function overrides, so we need to be
+     sure that we're using a thunk for some overridden base; even if we
+     know that the necessary this adjustment is zero, there may not be an
+     appropriate zero-this-adjusment thunk for us to use since thunks for
+     overriding virtual bases always use the vcall offset.
+
+     Furthermore, just choosing any base that overrides this function isn't
+     quite right, as this slot won't be used for calls through a type that
+     puts a covariant thunk here.  Calling the function through such a type
+     will use a different slot, and that slot is the one that determines
+     the thunk emitted for that base.
+
+     So, keep looking until we find the base that we're really overriding
+     in this slot: the nearest primary base that doesn't use a covariant
+     thunk in this slot.  */
+  if (overrider_target != overrider_fn)
+    {
+      if (BINFO_TYPE (b) == DECL_CONTEXT (overrider_target))
+       /* We already know that the overrider needs a covariant thunk.  */
+       b = get_primary_binfo (b);
+      for (; ; b = get_primary_binfo (b))
+       {
+         tree main_binfo = TYPE_BINFO (BINFO_TYPE (b));
+         tree bv = chain_index (ix, BINFO_VIRTUALS (main_binfo));
+         if (!DECL_THUNK_P (TREE_VALUE (bv)))
+           break;
+         if (BINFO_LOST_PRIMARY_P (b))
+           lost = true;
+       }
+      first_defn = b;
+    }
 
   /* Assume that we will produce a thunk that convert all the way to
      the final overrider, and not to an intermediate virtual base.  */
@@ -2117,43 +2286,14 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
        }
     }
 
-  if (overrider_fn != overrider_target && !virtual_base)
-    {
-      /* The ABI specifies that a covariant thunk includes a mangling
-        for a this pointer adjustment.  This-adjusting thunks that
-        override a function from a virtual base have a vcall
-        adjustment.  When the virtual base in question is a primary
-        virtual base, we know the adjustments are zero, (and in the
-        non-covariant case, we would not use the thunk).
-        Unfortunately we didn't notice this could happen, when
-        designing the ABI and so never mandated that such a covariant
-        thunk should be emitted.  Because we must use the ABI mandated
-        name, we must continue searching from the binfo where we
-        found the most recent definition of the function, towards the
-        primary binfo which first introduced the function into the
-        vtable.  If that enters a virtual base, we must use a vcall
-        this-adjusting thunk.  Bleah! */
-      tree probe = first_defn;
-
-      while ((probe = get_primary_binfo (probe))
-            && (unsigned) list_length (BINFO_VIRTUALS (probe)) > ix)
-       if (BINFO_VIRTUAL_P (probe))
-         virtual_base = probe;
-
-      if (virtual_base)
-       /* Even if we find a virtual base, the correct delta is
-          between the overrider and the binfo we're building a vtable
-          for.  */
-       goto virtual_covariant;
-    }
-
   /* Compute the constant adjustment to the `this' pointer.  The
      `this' pointer, when this function is called, will point at BINFO
      (or one of its primary bases, which are at the same offset).  */
   if (virtual_base)
     /* The `this' pointer needs to be adjusted from the declaration to
        the nearest virtual base.  */
-    delta = size_diffop (convert (ssizetype, BINFO_OFFSET (virtual_base)),
+    delta = size_diffop_loc (input_location,
+                        convert (ssizetype, BINFO_OFFSET (virtual_base)),
                         convert (ssizetype, BINFO_OFFSET (first_defn)));
   else if (lost)
     /* If the nearest definition is in a lost primary, we don't need an
@@ -2165,8 +2305,8 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
     /* The `this' pointer needs to be adjusted from pointing to
        BINFO to pointing at the base where the final overrider
        appears.  */
-    virtual_covariant:
-    delta = size_diffop (convert (ssizetype,
+    delta = size_diffop_loc (input_location,
+                        convert (ssizetype,
                                  BINFO_OFFSET (TREE_VALUE (overrider))),
                         convert (ssizetype, BINFO_OFFSET (binfo)));
 
@@ -2177,6 +2317,9 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
       = get_vcall_index (overrider_target, BINFO_TYPE (virtual_base));
   else
     BV_VCALL_INDEX (*virtuals) = NULL_TREE;
+
+  if (lost)
+    BV_LOST_PRIMARY (*virtuals) = true;
 }
 
 /* Called from modify_all_vtables via dfs_walk.  */
@@ -2314,6 +2457,7 @@ get_basefndecls (tree name, tree t)
 void
 check_for_override (tree decl, tree ctype)
 {
+  bool overrides_found = false;
   if (TREE_CODE (decl) == TEMPLATE_DECL)
     /* In [temp.mem] we have:
 
@@ -2328,20 +2472,29 @@ check_for_override (tree decl, tree ctype)
     /* 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;
+    {
+      DECL_VINDEX (decl) = decl;
+      overrides_found = true;
+    }
 
   if (DECL_VIRTUAL_P (decl))
     {
       if (!DECL_VINDEX (decl))
        DECL_VINDEX (decl) = error_mark_node;
       IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
+      if (DECL_DESTRUCTOR_P (decl))
+       TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true;
     }
+  else if (DECL_FINAL_P (decl))
+    error ("%q+#D marked final, but is not virtual", decl);
+  if (DECL_OVERRIDE_P (decl) && !overrides_found)
+    error ("%q+#D marked override, but does not override", decl);
 }
 
 /* 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);
@@ -2404,8 +2557,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);
        }
     }
@@ -2419,7 +2572,7 @@ finish_struct_anon (tree t)
 {
   tree field;
 
-  for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
+  for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
     {
       if (TREE_STATIC (field))
        continue;
@@ -2429,8 +2582,9 @@ 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))
+         for (; elt; elt = DECL_CHAIN (elt))
            {
              /* We're generally only interested in entities the user
                 declared, but we also find nested classes by noticing
@@ -2446,15 +2600,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)
+                   permerror (input_location, "%q+#D invalid; an anonymous union can "
+                              "only have non-static data members", elt);
+                 else
+                   permerror (input_location, "%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)
+                   permerror (input_location, "private member %q+#D in anonymous union", elt);
+                 else
+                   permerror (input_location, "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)
+                   permerror (input_location, "protected member %q+#D in anonymous union", elt);
+                 else
+                   permerror (input_location, "protected member %q+#D in anonymous struct", elt);
+               }
 
              TREE_PRIVATE (elt) = TREE_PRIVATE (field);
              TREE_PROTECTED (elt) = TREE_PROTECTED (field);
@@ -2483,6 +2651,70 @@ maybe_add_class_template_decl_list (tree type, tree t, int friend_p)
                   t, CLASSTYPE_DECL_LIST (type));
 }
 
+/* This function is called from declare_virt_assop_and_dtor via
+   dfs_walk_all.
+
+   DATA is a type that direcly or indirectly inherits the base
+   represented by BINFO.  If BINFO contains a virtual assignment [copy
+   assignment or move assigment] operator or a virtual constructor,
+   declare that function in DATA if it hasn't been already declared.  */
+
+static tree
+dfs_declare_virt_assop_and_dtor (tree binfo, void *data)
+{
+  tree bv, fn, t = (tree)data;
+  tree opname = ansi_assopname (NOP_EXPR);
+
+  gcc_assert (t && CLASS_TYPE_P (t));
+  gcc_assert (binfo && TREE_CODE (binfo) == TREE_BINFO);
+
+  if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
+    /* A base without a vtable needs no modification, and its bases
+       are uninteresting.  */
+    return dfs_skip_bases;
+
+  if (BINFO_PRIMARY_P (binfo))
+    /* If this is a primary base, then we have already looked at the
+       virtual functions of its vtable.  */
+    return NULL_TREE;
+
+  for (bv = BINFO_VIRTUALS (binfo); bv; bv = TREE_CHAIN (bv))
+    {
+      fn = BV_FN (bv);
+
+      if (DECL_NAME (fn) == opname)
+       {
+         if (CLASSTYPE_LAZY_COPY_ASSIGN (t))
+           lazily_declare_fn (sfk_copy_assignment, t);
+         if (CLASSTYPE_LAZY_MOVE_ASSIGN (t))
+           lazily_declare_fn (sfk_move_assignment, t);
+       }
+      else if (DECL_DESTRUCTOR_P (fn)
+              && CLASSTYPE_LAZY_DESTRUCTOR (t))
+       lazily_declare_fn (sfk_destructor, t);
+    }
+
+  return NULL_TREE;
+}
+
+/* If the class type T has a direct or indirect base that contains a
+   virtual assignment operator or a virtual destructor, declare that
+   function in T if it hasn't been already declared.  */
+
+static void
+declare_virt_assop_and_dtor (tree t)
+{
+  if (!(TYPE_POLYMORPHIC_P (t)
+       && (CLASSTYPE_LAZY_COPY_ASSIGN (t)
+           || CLASSTYPE_LAZY_MOVE_ASSIGN (t)
+           || CLASSTYPE_LAZY_DESTRUCTOR (t))))
+    return;
+
+  dfs_walk_all (TYPE_BINFO (t),
+               dfs_declare_virt_assop_and_dtor,
+               NULL, t);
+}
+
 /* Create default constructors, assignment operators, and so forth for
    the type indicated by T, if they are needed.  CANT_HAVE_CONST_CTOR,
    and CANT_HAVE_CONST_ASSIGNMENT are nonzero if, for whatever reason,
@@ -2500,75 +2732,59 @@ add_implicitly_declared_members (tree t,
     {
       /* In general, we create destructors lazily.  */
       CLASSTYPE_LAZY_DESTRUCTOR (t) = 1;
-      /* However, if the implicit destructor is non-trivial
-        destructor, we sometimes have to create it at this point.  */
-      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
-       {
-         bool lazy_p = true;
-
-         if (TYPE_FOR_JAVA (t))
-           /* If this a Java class, any non-trivial destructor is
-              invalid, even if compiler-generated.  Therefore, if the
-              destructor is non-trivial we create it now.  */
-           lazy_p = false;
-         else
-           {
-             tree binfo;
-             tree base_binfo;
-             int ix;
-
-             /* If the implicit destructor will be virtual, then we must
-                generate it now because (unfortunately) we do not
-                generate virtual tables lazily.  */
-             binfo = TYPE_BINFO (t);
-             for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
-               {
-                 tree base_type;
-                 tree dtor;
-
-                 base_type = BINFO_TYPE (base_binfo);
-                 dtor = CLASSTYPE_DESTRUCTORS (base_type);
-                 if (dtor && DECL_VIRTUAL_P (dtor))
-                   {
-                     lazy_p = false;
-                     break;
-                   }
-               }
-           }
 
-         /* If we can't get away with being lazy, generate the destructor
-            now.  */
-         if (!lazy_p)
-           lazily_declare_fn (sfk_destructor, t);
-       }
+      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
+         && TYPE_FOR_JAVA (t))
+       /* But if this is a Java class, any non-trivial destructor is
+          invalid, even if compiler-generated.  Therefore, if the
+          destructor is non-trivial we create it now.  */
+       lazily_declare_fn (sfk_destructor, t);
     }
 
-  /* Default constructor.  */
-  if (! TYPE_HAS_CONSTRUCTOR (t))
+  /* [class.ctor]
+
+     If there is no user-declared constructor for a class, a default
+     constructor is implicitly declared.  */
+  if (! TYPE_HAS_USER_CONSTRUCTOR (t))
     {
       TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1;
       CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1;
+      if (cxx_dialect >= cxx0x)
+       TYPE_HAS_CONSTEXPR_CTOR (t)
+         = synthesized_default_constructor_is_constexpr (t);
     }
 
-  /* Copy constructor.  */
-  if (! TYPE_HAS_INIT_REF (t) && ! TYPE_FOR_JAVA (t))
+  /* [class.ctor]
+
+     If a class definition does not explicitly declare a copy
+     constructor, one is declared implicitly.  */
+  if (! TYPE_HAS_COPY_CTOR (t) && ! TYPE_FOR_JAVA (t)
+      && !type_has_move_constructor (t))
     {
-      TYPE_HAS_INIT_REF (t) = 1;
-      TYPE_HAS_CONST_INIT_REF (t) = !cant_have_const_cctor;
+      TYPE_HAS_COPY_CTOR (t) = 1;
+      TYPE_HAS_CONST_COPY_CTOR (t) = !cant_have_const_cctor;
       CLASSTYPE_LAZY_COPY_CTOR (t) = 1;
-      TYPE_HAS_CONSTRUCTOR (t) = 1;
+      if (cxx_dialect >= cxx0x)
+       CLASSTYPE_LAZY_MOVE_CTOR (t) = 1;
     }
 
   /* If there is no assignment operator, one will be created if and
      when it is needed.  For now, just record whether or not the type
      of the parameter to the assignment operator will be a const or
      non-const reference.  */
-  if (!TYPE_HAS_ASSIGN_REF (t) && !TYPE_FOR_JAVA (t))
+  if (!TYPE_HAS_COPY_ASSIGN (t) && !TYPE_FOR_JAVA (t)
+      && !type_has_move_assign (t))
     {
-      TYPE_HAS_ASSIGN_REF (t) = 1;
-      TYPE_HAS_CONST_ASSIGN_REF (t) = !cant_have_const_assignment;
-      CLASSTYPE_LAZY_ASSIGNMENT_OP (t) = 1;
+      TYPE_HAS_COPY_ASSIGN (t) = 1;
+      TYPE_HAS_CONST_COPY_ASSIGN (t) = !cant_have_const_assignment;
+      CLASSTYPE_LAZY_COPY_ASSIGN (t) = 1;
+      if (cxx_dialect >= cxx0x)
+       CLASSTYPE_LAZY_MOVE_ASSIGN (t) = 1;
     }
+
+  /* We can't be lazy about declaring functions that might override
+     a virtual function from a base class.  */
+  declare_virt_assop_and_dtor (t);
 }
 
 /* Subroutine of finish_struct_1.  Recursively count the number of fields
@@ -2579,7 +2795,7 @@ count_fields (tree fields)
 {
   tree x;
   int n_fields = 0;
-  for (x = fields; x; x = TREE_CHAIN (x))
+  for (x = fields; x; x = DECL_CHAIN (x))
     {
       if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x)))
        n_fields += count_fields (TYPE_FIELDS (TREE_TYPE (x)));
@@ -2596,7 +2812,7 @@ static int
 add_fields_to_record_type (tree fields, struct sorted_fields_type *field_vec, int idx)
 {
   tree x;
-  for (x = fields; x; x = TREE_CHAIN (x))
+  for (x = fields; x; x = DECL_CHAIN (x))
     {
       if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x)))
        idx = add_fields_to_record_type (TYPE_FIELDS (TREE_TYPE (x)), field_vec, idx);
@@ -2608,32 +2824,38 @@ 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_OR_ENUMERATION_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);
-
+      location_t loc = input_location;
       /* Avoid the non_lvalue wrapper added by fold for PLUS_EXPRs.  */
       STRIP_NOPS (w);
 
       /* detect invalid field size.  */
-      w = integral_constant_value (w);
+      input_location = DECL_SOURCE_LOCATION (field);
+      w = cxx_constant_value (w);
+      input_location = loc;
 
       if (TREE_CODE (w) != INTEGER_CST)
        {
@@ -2655,30 +2877,23 @@ check_bitfield_decl (tree field)
               && TREE_CODE (type) != BOOLEAN_TYPE)
        warning (0, "width of %q+D exceeds its type", field);
       else if (TREE_CODE (type) == ENUMERAL_TYPE
-              && (0 > compare_tree_int (w,
-                                        min_precision (TYPE_MIN_VALUE (type),
-                                                       TYPE_UNSIGNED (type)))
-                  ||  0 > compare_tree_int (w,
-                                            min_precision
-                                            (TYPE_MAX_VALUE (type),
-                                             TYPE_UNSIGNED (type)))))
+              && (0 > (compare_tree_int
+                       (w, TYPE_PRECISION (ENUM_UNDERLYING_TYPE (type))))))
        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;
     }
 }
 
@@ -2695,17 +2910,17 @@ check_field_decl (tree field,
 {
   tree type = strip_array_types (TREE_TYPE (field));
 
-  /* An anonymous union cannot contain any fields which would change
+  /* In C++98 an anonymous union cannot contain any fields which would change
      the settings of CANT_HAVE_CONST_CTOR and friends.  */
-  if (ANON_UNION_TYPE_P (type))
+  if (ANON_UNION_TYPE_P (type) && cxx_dialect < cxx0x)
     ;
-  /* And, we don't set TYPE_HAS_CONST_INIT_REF, etc., for anonymous
+  /* And, we don't set TYPE_HAS_CONST_COPY_CTOR, etc., for anonymous
      structs.  So, we recurse through their fields here.  */
   else if (ANON_AGGR_TYPE_P (type))
     {
       tree fields;
 
-      for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
+      for (fields = TYPE_FIELDS (type); fields; fields = DECL_CHAIN (fields))
        if (TREE_CODE (fields) == FIELD_DECL && !DECL_C_BIT_FIELD (field))
          check_field_decl (fields, t, cant_have_const_ctor,
                            no_const_asn_ref, any_default_members);
@@ -2718,30 +2933,47 @@ check_field_decl (tree field,
         make it through without complaint.  */
       abstract_virtuals_error (field, type);
 
-      if (TREE_CODE (t) == UNION_TYPE)
+      if (TREE_CODE (t) == UNION_TYPE && cxx_dialect < cxx0x)
        {
+         static bool warned;
+         int oldcount = errorcount;
          if (TYPE_NEEDS_CONSTRUCTING (type))
            error ("member %q+#D with constructor not allowed in union",
                   field);
          if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
            error ("member %q+#D with destructor not allowed in union", field);
-         if (TYPE_HAS_COMPLEX_ASSIGN_REF (type))
+         if (TYPE_HAS_COMPLEX_COPY_ASSIGN (type))
            error ("member %q+#D with copy assignment operator not allowed in union",
                   field);
+         if (!warned && errorcount > oldcount)
+           {
+             inform (DECL_SOURCE_LOCATION (field), "unrestricted unions "
+                     "only available with -std=c++0x or -std=gnu++0x");
+             warned = true;
+           }
        }
       else
        {
          TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (type);
          TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
            |= 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_COPY_ASSIGN (t)
+           |= (TYPE_HAS_COMPLEX_COPY_ASSIGN (type)
+               || !TYPE_HAS_COPY_ASSIGN (type));
+         TYPE_HAS_COMPLEX_COPY_CTOR (t) |= (TYPE_HAS_COMPLEX_COPY_CTOR (type)
+                                            || !TYPE_HAS_COPY_CTOR (type));
+         TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) |= TYPE_HAS_COMPLEX_MOVE_ASSIGN (type);
+         TYPE_HAS_COMPLEX_MOVE_CTOR (t) |= TYPE_HAS_COMPLEX_MOVE_CTOR (type);
+         TYPE_HAS_COMPLEX_DFLT (t) |= (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type)
+                                       || TYPE_HAS_COMPLEX_DFLT (type));
        }
 
-      if (!TYPE_HAS_CONST_INIT_REF (type))
+      if (TYPE_HAS_COPY_CTOR (type)
+         && !TYPE_HAS_CONST_COPY_CTOR (type))
        *cant_have_const_ctor = 1;
 
-      if (!TYPE_HAS_CONST_ASSIGN_REF (type))
+      if (TYPE_HAS_COPY_ASSIGN (type)
+         && !TYPE_HAS_CONST_COPY_ASSIGN (type))
        *no_const_asn_ref = 1;
     }
   if (DECL_INITIAL (field) != NULL_TREE)
@@ -2788,6 +3020,8 @@ check_field_decls (tree t, tree *access_decls,
   tree *next;
   bool has_pointers;
   int any_default_members;
+  int cant_pack = 0;
+  int field_access = -1;
 
   /* Assume there are no access declarations.  */
   *access_decls = NULL_TREE;
@@ -2801,47 +3035,14 @@ check_field_decls (tree t, tree *access_decls,
     {
       tree x = *field;
       tree type = TREE_TYPE (x);
+      int this_field_access;
 
-      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 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
-           {
-             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;
-           }
-       }
+      next = &DECL_CHAIN (x);
 
       if (TREE_CODE (x) == USING_DECL)
        {
          /* Prune the access declaration from the list of fields.  */
-         *field = TREE_CHAIN (x);
+         *field = DECL_CHAIN (x);
 
          /* Save the access declarations for our caller.  */
          *access_decls = tree_cons (NULL_TREE, x, *access_decls);
@@ -2883,10 +3084,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)
@@ -2913,11 +3110,26 @@ check_field_decls (tree t, tree *access_decls,
       if (TREE_PRIVATE (x) || TREE_PROTECTED (x))
        CLASSTYPE_NON_AGGREGATE (t) = 1;
 
-      /* If this is of reference type, check if it needs an init.
-        Also do a little ANSI jig if necessary.  */
+      /* If at least one non-static data member is non-literal, the whole
+         class becomes non-literal.  */
+      if (!literal_type_p (type))
+        CLASSTYPE_LITERAL_P (t) = false;
+
+      /* A standard-layout class is a class that:
+        ...
+        has the same access control (Clause 11) for all non-static data members,
+         ...  */
+      this_field_access = TREE_PROTECTED (x) ? 1 : TREE_PRIVATE (x) ? 2 : 0;
+      if (field_access == -1)
+       field_access = this_field_access;
+      else if (this_field_access != field_access)
+       CLASSTYPE_NON_STD_LAYOUT (t) = 1;
+
+      /* If this is of reference type, check if it needs an init.  */
       if (TREE_CODE (type) == REFERENCE_TYPE)
        {
-         CLASSTYPE_NON_POD_P (t) = 1;
+         CLASSTYPE_NON_LAYOUT_POD_P (t) = 1;
+         CLASSTYPE_NON_STD_LAYOUT (t) = 1;
          if (DECL_INITIAL (x) == NULL_TREE)
            SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1);
 
@@ -2925,15 +3137,44 @@ check_field_decls (tree t, tree *access_decls,
             aggregate, initialization by a brace-enclosed list) is the
             only way to initialize nonstatic const and reference
             members.  */
-         TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;
-
-         if (! TYPE_HAS_CONSTRUCTOR (t) && CLASSTYPE_NON_AGGREGATE (t)
-             && extra_warnings)
-           warning (0, "non-static reference %q+#D in class without a constructor", x);
+         TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1;
+         TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) = 1;
        }
 
       type = strip_array_types (type);
 
+      if (TYPE_PACKED (t))
+       {
+         if (!layout_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 (DECL_C_BIT_FIELD (x)
+                  || 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.  */
@@ -2953,14 +3194,25 @@ check_field_decls (tree t, tree *access_decls,
       if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (type))
        CLASSTYPE_HAS_MUTABLE (t) = 1;
 
-      if (! pod_type_p (type))
+      if (! layout_pod_type_p (type))
        /* DR 148 now allows pointers to members (which are POD themselves),
           to be allowed in POD structs.  */
-       CLASSTYPE_NON_POD_P (t) = 1;
+       CLASSTYPE_NON_LAYOUT_POD_P (t) = 1;
+
+      if (!std_layout_type_p (type))
+       CLASSTYPE_NON_STD_LAYOUT (t) = 1;
 
       if (! zero_init_p (type))
        CLASSTYPE_NON_ZERO_INIT_P (t) = 1;
 
+      /* 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))
+       check_field_decl (x, t,
+                         cant_have_const_ctor_p,
+                         no_const_asn_ref_p,
+                         &any_default_members);
+
       /* If any field is const, the structure type is pseudo-const.  */
       if (CP_TYPE_CONST_P (type))
        {
@@ -2972,11 +3224,8 @@ check_field_decls (tree t, tree *access_decls,
             aggregate, initialization by a brace-enclosed list) is the
             only way to initialize nonstatic const and reference
             members.  */
-         TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;
-
-         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);
+         TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1;
+         TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) = 1;
        }
       /* A field that is pseudo-const makes the structure likewise.  */
       else if (CLASS_TYPE_P (type))
@@ -2989,19 +3238,10 @@ check_field_decls (tree t, tree *access_decls,
 
       /* Core issue 80: A nonstatic data member is required to have a
         different name from the class iff the class has a
-        user-defined constructor.  */
-      if (constructor_name_p (DECL_NAME (x), t) && TYPE_HAS_CONSTRUCTOR (t))
-       pedwarn ("field %q+#D with same name as class", x);
-
-      /* 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
-       check_field_decl (x, t,
-                         cant_have_const_ctor_p,
-                         no_const_asn_ref_p,
-                         &any_default_members);
+        user-declared constructor.  */
+      if (constructor_name_p (DECL_NAME (x), t)
+         && TYPE_HAS_USER_CONSTRUCTOR (t))
+       permerror (input_location, "field %q+#D with same name as class", x);
     }
 
   /* Effective C++ rule 11: if a class has dynamic memory held by pointers,
@@ -3018,24 +3258,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_USER_CONSTRUCTOR (t)
+      && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
+      && !(TYPE_HAS_COPY_CTOR (t) && TYPE_HAS_COPY_ASSIGN (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))
+      if (! TYPE_HAS_COPY_CTOR (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_COPY_ASSIGN (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);
+      else if (! TYPE_HAS_COPY_ASSIGN (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);
@@ -3123,7 +3368,7 @@ walk_subobject_offsets (tree type,
 
   if (type == error_mark_node)
     return 0;
-  
+
   if (!TYPE_P (type))
     {
       if (abi_version_at_least (2))
@@ -3235,7 +3480,7 @@ walk_subobject_offsets (tree type,
        }
 
       /* Iterate through the fields of TYPE.  */
-      for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+      for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
        if (TREE_CODE (field) == FIELD_DECL && !DECL_ARTIFICIAL (field))
          {
            tree field_offset;
@@ -3323,7 +3568,7 @@ record_subobject_offsets (tree type,
      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 
+  if (is_data_member
       || !is_empty_class (BINFO_TYPE (type)))
     max_offset = sizeof_biggest_empty_class;
   else
@@ -3451,7 +3696,8 @@ layout_nonempty_base_or_field (record_layout_info rli,
        hierarchy.  Therefore, we may not need to add the entire
        OFFSET.  */
     propagate_binfo_offsets (binfo,
-                            size_diffop (convert (ssizetype, offset),
+                            size_diffop_loc (input_location,
+                                         convert (ssizetype, offset),
                                          convert (ssizetype,
                                                   BINFO_OFFSET (binfo))));
 }
@@ -3473,7 +3719,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);
@@ -3487,9 +3734,11 @@ 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"
+         (binfo, size_diffop_loc (input_location,
+                              size_zero_node, BINFO_OFFSET (binfo)));
+      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));
     }
@@ -3518,6 +3767,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;
 }
 
@@ -3552,25 +3810,29 @@ build_base_field (record_layout_info rli, tree binfo,
       CLASSTYPE_EMPTY_P (t) = 0;
 
       /* Create the FIELD_DECL.  */
-      decl = build_decl (FIELD_DECL, NULL_TREE, CLASSTYPE_AS_BASE (basetype));
+      decl = build_decl (input_location,
+                        FIELD_DECL, NULL_TREE, CLASSTYPE_AS_BASE (basetype));
       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.  */
+         DECL_CHAIN (decl) = *next_field;
+         *next_field = decl;
+         next_field = &DECL_CHAIN (decl);
+       }
     }
   else
     {
@@ -3579,9 +3841,10 @@ build_base_field (record_layout_info rli, tree binfo,
 
       /* On some platforms (ARM), even empty classes will not be
         byte-aligned.  */
-      eoc = round_up (rli_size_unit_so_far (rli),
+      eoc = round_up_loc (input_location,
+                     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))
@@ -3600,8 +3863,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);
            }
        }
@@ -3679,7 +3943,7 @@ check_methods (tree t)
 {
   tree x;
 
-  for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x))
+  for (x = TYPE_METHODS (t); x; x = DECL_CHAIN (x))
     {
       check_for_override (x, t);
       if (DECL_PURE_VIRTUAL_P (x) && ! DECL_VINDEX (x))
@@ -3692,8 +3956,10 @@ check_methods (tree t)
          if (DECL_PURE_VIRTUAL_P (x))
            VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (t), x);
        }
-      /* All user-declared destructors are non-trivial.  */
-      if (DECL_DESTRUCTOR_P (x))
+      /* All user-provided destructors are non-trivial.
+         Constructors and assignment ops are handled in
+        grok_special_member_properties.  */
+      if (DECL_DESTRUCTOR_P (x) && user_provided_p (x))
        TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 1;
     }
 }
@@ -3710,17 +3976,30 @@ build_clone (tree fn, tree name)
 
   /* Copy the function.  */
   clone = copy_decl (fn);
-  /* Remember where this function came from.  */
-  DECL_CLONED_FUNCTION (clone) = fn;
-  DECL_ABSTRACT_ORIGIN (clone) = fn;
   /* Reset the function name.  */
   DECL_NAME (clone) = name;
   SET_DECL_ASSEMBLER_NAME (clone, NULL_TREE);
+  /* Remember where this function came from.  */
+  DECL_ABSTRACT_ORIGIN (clone) = fn;
+  /* Make it easy to find the CLONE given the FN.  */
+  DECL_CHAIN (clone) = DECL_CHAIN (fn);
+  DECL_CHAIN (fn) = clone;
+
+  /* If this is a template, do the rest on the DECL_TEMPLATE_RESULT.  */
+  if (TREE_CODE (clone) == TEMPLATE_DECL)
+    {
+      tree result = build_clone (DECL_TEMPLATE_RESULT (clone), name);
+      DECL_TEMPLATE_RESULT (clone) = result;
+      DECL_TEMPLATE_INFO (result) = copy_node (DECL_TEMPLATE_INFO (result));
+      DECL_TI_TEMPLATE (result) = clone;
+      TREE_TYPE (clone) = TREE_TYPE (result);
+      return clone;
+    }
+
+  DECL_CLONED_FUNCTION (clone) = fn;
   /* There's no pending inline data for this function.  */
   DECL_PENDING_INLINE_INFO (clone) = NULL;
   DECL_PENDING_INLINE_P (clone) = 0;
-  /* And it hasn't yet been deferred.  */
-  DECL_DEFERRED_FN (clone) = 0;
 
   /* The base-class destructor is not virtual.  */
   if (name == base_dtor_identifier)
@@ -3763,63 +4042,81 @@ build_clone (tree fn, tree name)
                                           TYPE_ATTRIBUTES (TREE_TYPE (fn)));
     }
 
-  /* Copy the function parameters.  But, DECL_ARGUMENTS on a TEMPLATE_DECL
-     aren't function parameters; those are the template parameters.  */
-  if (TREE_CODE (clone) != TEMPLATE_DECL)
+  /* Copy the function parameters.  */
+  DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone));
+  /* Remove the in-charge parameter.  */
+  if (DECL_HAS_IN_CHARGE_PARM_P (clone))
     {
-      DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone));
-      /* Remove the in-charge parameter.  */
-      if (DECL_HAS_IN_CHARGE_PARM_P (clone))
-       {
-         TREE_CHAIN (DECL_ARGUMENTS (clone))
-           = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
-         DECL_HAS_IN_CHARGE_PARM_P (clone) = 0;
-       }
-      /* And the VTT parm, in a complete [cd]tor.  */
-      if (DECL_HAS_VTT_PARM_P (fn))
+      DECL_CHAIN (DECL_ARGUMENTS (clone))
+       = DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone)));
+      DECL_HAS_IN_CHARGE_PARM_P (clone) = 0;
+    }
+  /* And the VTT parm, in a complete [cd]tor.  */
+  if (DECL_HAS_VTT_PARM_P (fn))
+    {
+      if (DECL_NEEDS_VTT_PARM_P (clone))
+       DECL_HAS_VTT_PARM_P (clone) = 1;
+      else
        {
-         if (DECL_NEEDS_VTT_PARM_P (clone))
-           DECL_HAS_VTT_PARM_P (clone) = 1;
-         else
-           {
-             TREE_CHAIN (DECL_ARGUMENTS (clone))
-               = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
-             DECL_HAS_VTT_PARM_P (clone) = 0;
-           }
+         DECL_CHAIN (DECL_ARGUMENTS (clone))
+           = DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone)));
+         DECL_HAS_VTT_PARM_P (clone) = 0;
        }
+    }
 
-      for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms))
-       {
-         DECL_CONTEXT (parms) = clone;
-         cxx_dup_lang_specific_decl (parms);
-       }
+  for (parms = DECL_ARGUMENTS (clone); parms; parms = DECL_CHAIN (parms))
+    {
+      DECL_CONTEXT (parms) = clone;
+      cxx_dup_lang_specific_decl (parms);
     }
 
   /* Create the RTL for this function.  */
-  SET_DECL_RTL (clone, NULL_RTX);
+  SET_DECL_RTL (clone, NULL);
   rest_of_decl_compilation (clone, /*top_level=*/1, at_eof);
 
-  /* Make it easy to find the CLONE given the FN.  */
-  TREE_CHAIN (clone) = TREE_CHAIN (fn);
-  TREE_CHAIN (fn) = clone;
-
-  /* If this is a template, handle the DECL_TEMPLATE_RESULT as well.  */
-  if (TREE_CODE (clone) == TEMPLATE_DECL)
-    {
-      tree result;
-
-      DECL_TEMPLATE_RESULT (clone)
-       = build_clone (DECL_TEMPLATE_RESULT (clone), name);
-      result = DECL_TEMPLATE_RESULT (clone);
-      DECL_TEMPLATE_INFO (result) = copy_node (DECL_TEMPLATE_INFO (result));
-      DECL_TI_TEMPLATE (result) = clone;
-    }
-  else if (pch_file)
+  if (pch_file)
     note_decl_for_pch (clone);
 
   return clone;
 }
 
+/* Implementation of DECL_CLONED_FUNCTION and DECL_CLONED_FUNCTION_P, do
+   not invoke this function directly.
+
+   For a non-thunk function, returns the address of the slot for storing
+   the function it is a clone of.  Otherwise returns NULL_TREE.
+
+   If JUST_TESTING, looks through TEMPLATE_DECL and returns NULL if
+   cloned_function is unset.  This is to support the separate
+   DECL_CLONED_FUNCTION and DECL_CLONED_FUNCTION_P modes; using the latter
+   on a template makes sense, but not the former.  */
+
+tree *
+decl_cloned_function_p (const_tree decl, bool just_testing)
+{
+  tree *ptr;
+  if (just_testing)
+    decl = STRIP_TEMPLATE (decl);
+
+  if (TREE_CODE (decl) != FUNCTION_DECL
+      || !DECL_LANG_SPECIFIC (decl)
+      || DECL_LANG_SPECIFIC (decl)->u.fn.thunk_p)
+    {
+#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
+      if (!just_testing)
+       lang_check_failed (__FILE__, __LINE__, __FUNCTION__);
+      else
+#endif
+       return NULL;
+    }
+
+  ptr = &DECL_LANG_SPECIFIC (decl)->u.fn.u5.cloned_function;
+  if (just_testing && *ptr == NULL_TREE)
+    return NULL;
+  else
+    return ptr;
+}
+
 /* Produce declarations for all appropriate clones of FN.  If
    UPDATE_METHOD_VEC_P is nonzero, the clones are added to the
    CLASTYPE_METHOD_VEC as well.  */
@@ -3830,8 +4127,8 @@ clone_function_decl (tree fn, int update_method_vec_p)
   tree clone;
 
   /* Avoid inappropriate cloning.  */
-  if (TREE_CHAIN (fn)
-      && DECL_CLONED_FUNCTION (TREE_CHAIN (fn)))
+  if (DECL_CHAIN (fn)
+      && DECL_CLONED_FUNCTION_P (DECL_CHAIN (fn)))
     return;
 
   if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn))
@@ -3888,8 +4185,8 @@ adjust_clone_args (tree decl)
 {
   tree clone;
 
-  for (clone = TREE_CHAIN (decl); clone && DECL_CLONED_FUNCTION (clone);
-       clone = TREE_CHAIN (clone))
+  for (clone = DECL_CHAIN (decl); clone && DECL_CLONED_FUNCTION_P (clone);
+       clone = DECL_CHAIN (clone))
     {
       tree orig_clone_parms = TYPE_ARG_TYPES (TREE_TYPE (clone));
       tree orig_decl_parms = TYPE_ARG_TYPES (TREE_TYPE (decl));
@@ -3922,6 +4219,7 @@ adjust_clone_args (tree decl)
              /* A default parameter has been added. Adjust the
                 clone's parameters.  */
              tree exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (clone));
+             tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (clone));
              tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (clone));
              tree type;
 
@@ -3939,6 +4237,8 @@ adjust_clone_args (tree decl)
                                                 clone_parms);
              if (exceptions)
                type = build_exception_variant (type, exceptions);
+             if (attrs)
+               type = cp_build_type_attribute_variant (type, attrs);
              TREE_TYPE (clone) = type;
 
              clone_parms = NULL_TREE;
@@ -3968,6 +4268,229 @@ clone_constructors_and_destructors (tree t)
     clone_function_decl (OVL_CURRENT (fns), /*update_method_vec_p=*/1);
 }
 
+/* Returns true iff class T has a user-defined constructor other than
+   the default constructor.  */
+
+bool
+type_has_user_nondefault_constructor (tree t)
+{
+  tree fns;
+
+  if (!TYPE_HAS_USER_CONSTRUCTOR (t))
+    return false;
+
+  for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+    {
+      tree fn = OVL_CURRENT (fns);
+      if (!DECL_ARTIFICIAL (fn)
+         && (TREE_CODE (fn) == TEMPLATE_DECL
+             || (skip_artificial_parms_for (fn, DECL_ARGUMENTS (fn))
+                 != NULL_TREE)))
+       return true;
+    }
+
+  return false;
+}
+
+/* Returns the defaulted constructor if T has one. Otherwise, returns
+   NULL_TREE.  */
+
+tree
+in_class_defaulted_default_constructor (tree t)
+{
+  tree fns, args;
+
+  if (!TYPE_HAS_USER_CONSTRUCTOR (t))
+    return NULL_TREE;
+
+  for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+    {
+      tree fn = OVL_CURRENT (fns);
+
+      if (DECL_DEFAULTED_IN_CLASS_P (fn))
+       {
+         args = FUNCTION_FIRST_USER_PARMTYPE (fn);
+         while (args && TREE_PURPOSE (args))
+           args = TREE_CHAIN (args);
+         if (!args || args == void_list_node)
+           return fn;
+       }
+    }
+
+  return NULL_TREE;
+}
+
+/* Returns true iff FN is a user-provided function, i.e. user-declared
+   and not defaulted at its first declaration; or explicit, private,
+   protected, or non-const.  */
+
+bool
+user_provided_p (tree fn)
+{
+  if (TREE_CODE (fn) == TEMPLATE_DECL)
+    return true;
+  else
+    return (!DECL_ARTIFICIAL (fn)
+           && !DECL_DEFAULTED_IN_CLASS_P (fn));
+}
+
+/* Returns true iff class T has a user-provided constructor.  */
+
+bool
+type_has_user_provided_constructor (tree t)
+{
+  tree fns;
+
+  if (!CLASS_TYPE_P (t))
+    return false;
+
+  if (!TYPE_HAS_USER_CONSTRUCTOR (t))
+    return false;
+
+  /* This can happen in error cases; avoid crashing.  */
+  if (!CLASSTYPE_METHOD_VEC (t))
+    return false;
+
+  for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+    if (user_provided_p (OVL_CURRENT (fns)))
+      return true;
+
+  return false;
+}
+
+/* Returns true iff class T has a user-provided default constructor.  */
+
+bool
+type_has_user_provided_default_constructor (tree t)
+{
+  tree fns;
+
+  if (!TYPE_HAS_USER_CONSTRUCTOR (t))
+    return false;
+
+  for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+    {
+      tree fn = OVL_CURRENT (fns);
+      if (TREE_CODE (fn) == FUNCTION_DECL
+         && user_provided_p (fn)
+         && sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (fn)))
+       return true;
+    }
+
+  return false;
+}
+
+/* Returns true iff for class T, a synthesized default constructor
+   would be constexpr.  */
+
+bool
+synthesized_default_constructor_is_constexpr (tree t)
+{
+  /* A defaulted default constructor is constexpr
+     if there is nothing to initialize.  */
+  /* FIXME adjust for non-static data member initializers.  */
+  return is_really_empty_class (t);
+}
+
+/* Returns true iff class T has a constexpr default constructor.  */
+
+bool
+type_has_constexpr_default_constructor (tree t)
+{
+  tree fns;
+
+  if (!CLASS_TYPE_P (t))
+    {
+      /* The caller should have stripped an enclosing array.  */
+      gcc_assert (TREE_CODE (t) != ARRAY_TYPE);
+      return false;
+    }
+  if (CLASSTYPE_LAZY_DEFAULT_CTOR (t))
+    return synthesized_default_constructor_is_constexpr (t);
+  fns = locate_ctor (t);
+  return (fns && DECL_DECLARED_CONSTEXPR_P (fns));
+}
+
+/* Returns true iff class TYPE has a virtual destructor.  */
+
+bool
+type_has_virtual_destructor (tree type)
+{
+  tree dtor;
+
+  if (!CLASS_TYPE_P (type))
+    return false;
+
+  gcc_assert (COMPLETE_TYPE_P (type));
+  dtor = CLASSTYPE_DESTRUCTORS (type);
+  return (dtor && DECL_VIRTUAL_P (dtor));
+}
+
+/* Returns true iff class T has a move constructor.  */
+
+bool
+type_has_move_constructor (tree t)
+{
+  tree fns;
+
+  if (CLASSTYPE_LAZY_MOVE_CTOR (t))
+    {
+      gcc_assert (COMPLETE_TYPE_P (t));
+      lazily_declare_fn (sfk_move_constructor, t);
+    }
+
+  if (!CLASSTYPE_METHOD_VEC (t))
+    return false;
+
+  for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+    if (move_fn_p (OVL_CURRENT (fns)))
+      return true;
+
+  return false;
+}
+
+/* Returns true iff class T has a move assignment operator.  */
+
+bool
+type_has_move_assign (tree t)
+{
+  tree fns;
+
+  if (CLASSTYPE_LAZY_MOVE_ASSIGN (t))
+    {
+      gcc_assert (COMPLETE_TYPE_P (t));
+      lazily_declare_fn (sfk_move_assignment, t);
+    }
+
+  for (fns = lookup_fnfields_slot (t, ansi_assopname (NOP_EXPR));
+       fns; fns = OVL_NEXT (fns))
+    if (move_fn_p (OVL_CURRENT (fns)))
+      return true;
+
+  return false;
+}
+
+/* Nonzero if we need to build up a constructor call when initializing an
+   object of this class, either because it has a user-provided constructor
+   or because it doesn't have a default constructor (so we need to give an
+   error if no initializer is provided).  Use TYPE_NEEDS_CONSTRUCTING when
+   what you care about is whether or not an object can be produced by a
+   constructor (e.g. so we don't set TREE_READONLY on const variables of
+   such type); use this function when what you care about is whether or not
+   to try to call a constructor to create an object.  The latter case is
+   the former plus some cases of constructors that cannot be called.  */
+
+bool
+type_build_ctor_call (tree t)
+{
+  tree inner;
+  if (TYPE_NEEDS_CONSTRUCTING (t))
+    return true;
+  inner = strip_array_types (t);
+  return (CLASS_TYPE_P (inner) && !TYPE_HAS_DEFAULT_CONSTRUCTOR (inner)
+         && !ANON_AGGR_TYPE_P (inner));
+}
+
 /* Remove all zero-width bit-fields from T.  */
 
 static void
@@ -3980,10 +4503,15 @@ remove_zero_width_bit_fields (tree t)
     {
       if (TREE_CODE (*fieldsp) == FIELD_DECL
          && DECL_C_BIT_FIELD (*fieldsp)
-         && DECL_INITIAL (*fieldsp))
-       *fieldsp = TREE_CHAIN (*fieldsp);
+          /* We should not be confused by the fact that grokbitfield
+            temporarily sets the width of the bit field into
+            DECL_INITIAL (*fieldsp).
+            check_bitfield_decl eventually sets DECL_SIZE (*fieldsp)
+            to that width.  */
+         && integer_zerop (DECL_SIZE (*fieldsp)))
+       *fieldsp = DECL_CHAIN (*fieldsp);
       else
-       fieldsp = &TREE_CHAIN (*fieldsp);
+       fieldsp = &DECL_CHAIN (*fieldsp);
     }
 }
 
@@ -4028,21 +4556,61 @@ type_requires_array_cookie (tree type)
       second_parm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
       if (second_parm == void_list_node)
        return false;
+      /* Do not consider this function if its second argument is an
+        ellipsis.  */
+      if (!second_parm)
+       continue;
       /* Otherwise, if we have a two-argument function and the second
         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;
     }
 
   return has_two_argument_delete_p;
 }
 
+/* Finish computing the `literal type' property of class type T.
+
+   At this point, we have already processed base classes and
+   non-static data members.  We need to check whether the copy
+   constructor is trivial, the destructor is trivial, and there
+   is a trivial default constructor or at least one constexpr
+   constructor other than the copy constructor.  */
+
+static void
+finalize_literal_type_property (tree t)
+{
+  tree fn;
+
+  if (cxx_dialect < cxx0x
+      || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
+      /* FIXME These constraints seem unnecessary; remove from standard.
+        || !TYPE_HAS_TRIVIAL_COPY_CTOR (t)
+        || TYPE_HAS_COMPLEX_MOVE_CTOR (t)*/ )
+    CLASSTYPE_LITERAL_P (t) = false;
+  else if (CLASSTYPE_LITERAL_P (t) && !TYPE_HAS_TRIVIAL_DFLT (t)
+          && !TYPE_HAS_CONSTEXPR_CTOR (t))
+    CLASSTYPE_LITERAL_P (t) = false;
+
+  if (!CLASSTYPE_LITERAL_P (t))
+    for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
+      if (DECL_DECLARED_CONSTEXPR_P (fn)
+         && TREE_CODE (fn) != TEMPLATE_DECL
+         && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+         && !DECL_CONSTRUCTOR_P (fn))
+       {
+         DECL_DECLARED_CONSTEXPR_P (fn) = false;
+         if (!DECL_TEMPLATE_INFO (fn))
+           error ("enclosing class of %q+#D is not a literal type", fn);
+       }
+}
+
 /* Check the validity of the bases and members declared in T.  Add any
    implicitly-generated functions (like copy-constructors and
    assignment operators).  Compute various flag bits (like
-   CLASSTYPE_NON_POD_T) for T.  This routine works purely at the C++
+   CLASSTYPE_NON_LAYOUT_POD_T) for T.  This routine works purely at the C++
    level: i.e., independently of the ABI in use.  */
 
 static void
@@ -4055,6 +4623,9 @@ check_bases_and_members (tree t)
      should take a non-const reference argument.  */
   int no_const_asn_ref;
   tree access_decls;
+  bool saved_complex_asn_ref;
+  bool saved_nontrivial_dtor;
+  tree fn;
 
   /* By default, we use const reference arguments and generate default
      constructors.  */
@@ -4068,6 +4639,12 @@ check_bases_and_members (tree t)
   /* Check all the method declarations.  */
   check_methods (t);
 
+  /* Save the initial values of these flags which only indicate whether
+     or not the class has user-provided functions.  As we analyze the
+     bases and members we can set these flags for other reasons.  */
+  saved_complex_asn_ref = TYPE_HAS_COMPLEX_COPY_ASSIGN (t);
+  saved_nontrivial_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t);
+
   /* Check all the data member declarations.  We cannot call
      check_field_decls until we have called check_bases check_methods,
      as check_field_decls depends on TYPE_HAS_NONTRIVIAL_DESTRUCTOR
@@ -4083,24 +4660,113 @@ check_bases_and_members (tree t)
 
   /* Do some bookkeeping that will guide the generation of implicitly
      declared member functions.  */
-  TYPE_HAS_COMPLEX_INIT_REF (t)
-    |= (TYPE_HAS_INIT_REF (t) || TYPE_CONTAINS_VPTR_P (t));
+  TYPE_HAS_COMPLEX_COPY_CTOR (t) |= TYPE_CONTAINS_VPTR_P (t);
+  TYPE_HAS_COMPLEX_MOVE_CTOR (t) |= TYPE_CONTAINS_VPTR_P (t);
+  /* We need to call a constructor for this class if it has a
+     user-provided constructor, or if the default constructor is going
+     to initialize the vptr.  (This is not an if-and-only-if;
+     TYPE_NEEDS_CONSTRUCTING is set elsewhere if bases or members
+     themselves need constructing.)  */
   TYPE_NEEDS_CONSTRUCTING (t)
-    |= (TYPE_HAS_CONSTRUCTOR (t) || TYPE_CONTAINS_VPTR_P (t));
+    |= (type_has_user_provided_constructor (t) || TYPE_CONTAINS_VPTR_P (t));
+  /* [dcl.init.aggr]
+
+     An aggregate is an array or a class with no user-provided
+     constructors ... and no virtual functions.  
+
+     Again, other conditions for being an aggregate are checked
+     elsewhere.  */
   CLASSTYPE_NON_AGGREGATE (t)
-    |= (TYPE_HAS_CONSTRUCTOR (t) || TYPE_POLYMORPHIC_P (t));
-  CLASSTYPE_NON_POD_P (t)
+    |= (type_has_user_provided_constructor (t) || TYPE_POLYMORPHIC_P (t));
+  /* This is the C++98/03 definition of POD; it changed in C++0x, but we
+     retain the old definition internally for ABI reasons.  */
+  CLASSTYPE_NON_LAYOUT_POD_P (t)
     |= (CLASSTYPE_NON_AGGREGATE (t)
-       || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
-       || TYPE_HAS_ASSIGN_REF (t));
-  TYPE_HAS_COMPLEX_ASSIGN_REF (t)
-    |= TYPE_HAS_ASSIGN_REF (t) || TYPE_CONTAINS_VPTR_P (t);
+       || saved_nontrivial_dtor || saved_complex_asn_ref);
+  CLASSTYPE_NON_STD_LAYOUT (t) |= TYPE_CONTAINS_VPTR_P (t);
+  TYPE_HAS_COMPLEX_COPY_ASSIGN (t) |= TYPE_CONTAINS_VPTR_P (t);
+  TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) |= TYPE_CONTAINS_VPTR_P (t);
+  TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_CONTAINS_VPTR_P (t);
+
+  /* If the class has no user-declared constructor, but does have
+     non-static const or reference data members that can never be
+     initialized, issue a warning.  */
+  if (warn_uninitialized
+      /* Classes with user-declared constructors are presumed to
+        initialize these members.  */
+      && !TYPE_HAS_USER_CONSTRUCTOR (t)
+      /* Aggregates can be initialized with brace-enclosed
+        initializers.  */
+      && CLASSTYPE_NON_AGGREGATE (t))
+    {
+      tree field;
+
+      for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
+       {
+         tree type;
+
+         if (TREE_CODE (field) != FIELD_DECL)
+           continue;
+
+         type = TREE_TYPE (field);
+         if (TREE_CODE (type) == REFERENCE_TYPE)
+           warning (OPT_Wuninitialized, "non-static reference %q+#D "
+                    "in class without a constructor", field);
+         else if (CP_TYPE_CONST_P (type)
+                  && (!CLASS_TYPE_P (type)
+                      || !TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
+           warning (OPT_Wuninitialized, "non-static const member %q+#D "
+                    "in class without a constructor", field);
+       }
+    }
 
   /* Synthesize any needed methods.  */
   add_implicitly_declared_members (t,
                                   cant_have_const_ctor,
                                   no_const_asn_ref);
 
+  /* Check defaulted declarations here so we have cant_have_const_ctor
+     and don't need to worry about clones.  */
+  for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
+    if (DECL_DEFAULTED_IN_CLASS_P (fn))
+      {
+       int copy = copy_fn_p (fn);
+       if (copy > 0)
+         {
+           bool imp_const_p
+             = (DECL_CONSTRUCTOR_P (fn) ? !cant_have_const_ctor
+                : !no_const_asn_ref);
+           bool fn_const_p = (copy == 2);
+
+           if (fn_const_p && !imp_const_p)
+             /* If the function is defaulted outside the class, we just
+                give the synthesis error.  */
+             error ("%q+D declared to take const reference, but implicit "
+                    "declaration would take non-const", fn);
+           else if (imp_const_p && !fn_const_p)
+             error ("%q+D declared to take non-const reference cannot be "
+                    "defaulted in the class body", fn);
+         }
+       defaulted_late_check (fn);
+      }
+
+  if (LAMBDA_TYPE_P (t))
+    {
+      /* "The closure type associated with a lambda-expression has a deleted
+        default constructor and a deleted copy assignment operator."  */
+      TYPE_NEEDS_CONSTRUCTING (t) = 1;
+      TYPE_HAS_COMPLEX_DFLT (t) = 1;
+      TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1;
+      CLASSTYPE_LAZY_MOVE_ASSIGN (t) = 0;
+
+      /* "This class type is not an aggregate."  */
+      CLASSTYPE_NON_AGGREGATE (t) = 1;
+    }
+
+  /* Compute the 'literal type' property before we
+     do anything with non-static member functions.  */
+  finalize_literal_type_property (t);
+
   /* Create the in-charge and not-in-charge variants of constructors
      and destructors.  */
   clone_constructors_and_destructors (t);
@@ -4131,7 +4797,7 @@ create_vtable_ptr (tree t, tree* virtuals_p)
   tree fn;
 
   /* Collect the virtual functions declared in T.  */
-  for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
+  for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
     if (DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)
        && TREE_CODE (DECL_VINDEX (fn)) != INTEGER_CST)
       {
@@ -4172,11 +4838,14 @@ create_vtable_ptr (tree t, tree* virtuals_p)
         stores cannot alias stores to void*!  */
       tree field;
 
-      field = build_decl (FIELD_DECL, get_vfield_name (t), vtbl_ptr_type_node);
+      field = build_decl (input_location, 
+                         FIELD_DECL, get_vfield_name (t), vtbl_ptr_type_node);
       DECL_VIRTUAL_P (field) = 1;
       DECL_ARTIFICIAL (field) = 1;
       DECL_FIELD_CONTEXT (field) = t;
       DECL_FCONTEXT (field) = t;
+      if (TYPE_PACKED (t))
+       DECL_PACKED (field) = 1;
 
       TYPE_VFIELD (t) = field;
 
@@ -4189,54 +4858,6 @@ create_vtable_ptr (tree t, tree* virtuals_p)
   return NULL_TREE;
 }
 
-/* Fixup the inline function given by INFO now that the class is
-   complete.  */
-
-static void
-fixup_pending_inline (tree fn)
-{
-  if (DECL_PENDING_INLINE_INFO (fn))
-    {
-      tree args = DECL_ARGUMENTS (fn);
-      while (args)
-       {
-         DECL_CONTEXT (args) = fn;
-         args = TREE_CHAIN (args);
-       }
-    }
-}
-
-/* Fixup the inline methods and friends in TYPE now that TYPE is
-   complete.  */
-
-static void
-fixup_inline_methods (tree type)
-{
-  tree method = TYPE_METHODS (type);
-  VEC(tree,gc) *friends;
-  unsigned ix;
-
-  if (method && TREE_CODE (method) == TREE_VEC)
-    {
-      if (TREE_VEC_ELT (method, 1))
-       method = TREE_VEC_ELT (method, 1);
-      else if (TREE_VEC_ELT (method, 0))
-       method = TREE_VEC_ELT (method, 0);
-      else
-       method = TREE_VEC_ELT (method, 2);
-    }
-
-  /* Do inline member functions.  */
-  for (; method; method = TREE_CHAIN (method))
-    fixup_pending_inline (method);
-
-  /* Do friends.  */
-  for (friends = CLASSTYPE_INLINE_FRIENDS (type), ix = 0;
-       VEC_iterate (tree, friends, ix, method); ix++)
-    fixup_pending_inline (method);
-  CLASSTYPE_INLINE_FRIENDS (type) = NULL;
-}
-
 /* Add OFFSET to all base types of BINFO which is a base in the
    hierarchy dominated by T.
 
@@ -4311,7 +4932,7 @@ layout_virtual_bases (record_layout_info rli, splay_tree offsets)
      bases will go after the last extant field to date.  */
   next_field = &TYPE_FIELDS (t);
   while (*next_field)
-    next_field = &TREE_CHAIN (*next_field);
+    next_field = &DECL_CHAIN (*next_field);
 
   /* Go through the virtual bases, allocating space for each virtual
      base that is not already a primary base class.  These are
@@ -4341,11 +4962,13 @@ layout_virtual_bases (record_layout_info rli, splay_tree offsets)
              && first_vbase
              && (tree_int_cst_lt
                  (size_binop (CEIL_DIV_EXPR,
-                              round_up (CLASSTYPE_SIZE (t),
+                              round_up_loc (input_location,
+                                        CLASSTYPE_SIZE (t),
                                         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);
 
@@ -4362,7 +4985,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.  */
@@ -4456,7 +5081,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);
       }
 }
@@ -4548,9 +5173,9 @@ layout_class_type (tree t, tree *virtuals_p)
   /* The vptr is always the first thing in the class.  */
   if (vptr)
     {
-      TREE_CHAIN (vptr) = TYPE_FIELDS (t);
+      DECL_CHAIN (vptr) = TYPE_FIELDS (t);
       TYPE_FIELDS (t) = vptr;
-      next_field = &TREE_CHAIN (vptr);
+      next_field = &DECL_CHAIN (vptr);
       place_field (rli, vptr);
     }
   else
@@ -4562,13 +5187,13 @@ layout_class_type (tree t, tree *virtuals_p)
   build_base_fields (rli, empty_base_offsets, next_field);
 
   /* Layout the non-static data members.  */
-  for (field = non_static_data_members; field; field = TREE_CHAIN (field))
+  for (field = non_static_data_members; field; field = DECL_CHAIN (field))
     {
       tree type;
       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);
@@ -4594,6 +5219,8 @@ layout_class_type (tree t, tree *virtuals_p)
        }
 
       type = TREE_TYPE (field);
+      if (type == error_mark_node)
+       continue;
 
       padding = NULL_TREE;
 
@@ -4603,7 +5230,7 @@ layout_class_type (tree t, tree *virtuals_p)
       if (DECL_C_BIT_FIELD (field)
          && INT_CST_LT (TYPE_SIZE (type), DECL_SIZE (field)))
        {
-         integer_type_kind itk;
+         unsigned int itk;
          tree integer_type;
          bool was_unnamed_p = false;
          /* We must allocate the bits as if suitably aligned for the
@@ -4611,14 +5238,21 @@ layout_class_type (tree t, tree *virtuals_p)
             of the field.  Then, we are supposed to use the left over
             bits as additional padding.  */
          for (itk = itk_char; itk != itk_none; ++itk)
-           if (INT_CST_LT (DECL_SIZE (field),
-                           TYPE_SIZE (integer_types[itk])))
+           if (integer_types[itk] != NULL_TREE
+               && (INT_CST_LT (size_int (MAX_FIXED_MODE_SIZE),
+                               TYPE_SIZE (integer_types[itk]))
+                   || INT_CST_LT (DECL_SIZE (field),
+                                  TYPE_SIZE (integer_types[itk]))))
              break;
 
          /* ITK now indicates a type that is too large for the
             field.  We have to back up by one to find the largest
             type that fits.  */
-         integer_type = integer_types[itk - 1];
+         do
+         {
+            --itk;
+           integer_type = integer_types[itk];
+         } while (itk > 0 && integer_type == NULL_TREE);
 
          /* Figure out how much additional padding is required.  GCC
             3.2 always created a padding field, even if it had zero
@@ -4632,8 +5266,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);
@@ -4672,7 +5306,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
@@ -4700,26 +5335,55 @@ 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
         offset of the field.  */
       if (warn_abi
+         && !abi_version_at_least (2)
          && !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))
+       {
+         unsigned HOST_WIDE_INT width;
+         tree 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));
+             TREE_TYPE (field)
+               = cp_build_qualified_type (TREE_TYPE (field),
+                                          cp_type_quals (ftype));
+           }
+       }
+
       /* If we needed additional padding after this field, add it
         now.  */
       if (padding)
        {
          tree padding_field;
 
-         padding_field = build_decl (FIELD_DECL,
+         padding_field = build_decl (input_location,
+                                     FIELD_DECL,
                                      NULL_TREE,
                                      char_type_node);
          DECL_BIT_FIELD (padding_field) = 1;
@@ -4740,7 +5404,7 @@ layout_class_type (tree t, tree *virtuals_p)
       /* Make sure that we are on a byte boundary so that the size of
         the class without virtual bases will always be a round number
         of bytes.  */
-      rli->bitpos = round_up (rli->bitpos, BITS_PER_UNIT);
+      rli->bitpos = round_up_loc (input_location, rli->bitpos, BITS_PER_UNIT);
       normalize_rli (rli);
     }
 
@@ -4754,9 +5418,9 @@ layout_class_type (tree t, tree *virtuals_p)
   remove_zero_width_bit_fields (t);
 
   /* Create the version of T used for virtual bases.  We do not use
-     make_aggr_type for this version; this is an artificial type.  For
+     make_class_type for this version; this is an artificial type.  For
      a POD type, we just reuse T.  */
-  if (CLASSTYPE_NON_POD_P (t) || CLASSTYPE_EMPTY_P (t))
+  if (CLASSTYPE_NON_LAYOUT_POD_P (t) || CLASSTYPE_EMPTY_P (t))
     {
       base_t = make_node (TREE_CODE (t));
 
@@ -4768,7 +5432,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);
        }
@@ -4803,10 +5468,11 @@ layout_class_type (tree t, tree *virtuals_p)
 
       /* Copy the fields from T.  */
       next_field = &TYPE_FIELDS (base_t);
-      for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
+      for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
        if (TREE_CODE (field) == FIELD_DECL)
          {
-           *next_field = build_decl (FIELD_DECL,
+           *next_field = build_decl (input_location,
+                                     FIELD_DECL,
                                      DECL_NAME (field),
                                      TREE_TYPE (field));
            DECL_CONTEXT (*next_field) = base_t;
@@ -4815,7 +5481,7 @@ layout_class_type (tree t, tree *virtuals_p)
              = DECL_FIELD_BIT_OFFSET (field);
            DECL_SIZE (*next_field) = DECL_SIZE (field);
            DECL_MODE (*next_field) = DECL_MODE (field);
-           next_field = &TREE_CHAIN (*next_field);
+           next_field = &DECL_CHAIN (*next_field);
          }
 
       /* Record the base version of the type.  */
@@ -4847,16 +5513,22 @@ layout_class_type (tree t, tree *virtuals_p)
   /* Make sure not to create any structures with zero size.  */
   if (integer_zerop (rli_size_unit_so_far (rli)) && CLASSTYPE_EMPTY_P (t))
     place_field (rli,
-                build_decl (FIELD_DECL, NULL_TREE, char_type_node));
+                build_decl (input_location,
+                            FIELD_DECL, NULL_TREE, char_type_node));
 
-  /* Let the back-end lay out the type.  */
+  /* If this is a non-POD, declaring it packed makes a difference to how it
+     can be used as a field; don't let finalize_record_size undo it.  */
+  if (TYPE_PACKED (t) && !layout_pod_type_p (t))
+    rli->packed_maybe_necessary = true;
+
+  /* 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.  */
   warn_about_ambiguous_bases (t);
 
   /* Now that we're done with layout, give the base fields the real types.  */
-  for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
+  for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
     if (DECL_ARTIFICIAL (field) && IS_FAKE_BASE_TYPE (TREE_TYPE (field)))
       TREE_TYPE (field) = TYPE_CONTEXT (TREE_TYPE (field));
 
@@ -4864,7 +5536,7 @@ layout_class_type (tree t, tree *virtuals_p)
   splay_tree_delete (empty_base_offsets);
 
   if (CLASSTYPE_EMPTY_P (t)
-      && tree_int_cst_lt (sizeof_biggest_empty_class, 
+      && tree_int_cst_lt (sizeof_biggest_empty_class,
                          TYPE_SIZE_UNIT (t)))
     sizeof_biggest_empty_class = TYPE_SIZE_UNIT (t);
 }
@@ -4888,7 +5560,7 @@ determine_key_method (tree type)
      key function may not be inline; those targets should not call
      this function until the end of the translation unit.  */
   for (method = TYPE_METHODS (type); method != NULL_TREE;
-       method = TREE_CHAIN (method))
+       method = DECL_CHAIN (method))
     if (DECL_VINDEX (method) != NULL_TREE
        && ! DECL_DECLARED_INLINE_P (method)
        && ! DECL_PURE_VIRTUAL_P (method))
@@ -4913,7 +5585,7 @@ finish_struct_1 (tree t)
 
   if (COMPLETE_TYPE_P (t))
     {
-      gcc_assert (IS_AGGR_TYPE (t));
+      gcc_assert (MAYBE_CLASS_TYPE_P (t));
       error ("redefinition of %q#T", t);
       popclass ();
       return;
@@ -4924,13 +5596,12 @@ finish_struct_1 (tree t)
   TYPE_SIZE (t) = NULL_TREE;
   CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE;
 
-  fixup_inline_methods (t);
-
   /* Make assumptions about the class; we'll reset the flags if
      necessary.  */
   CLASSTYPE_EMPTY_P (t) = 1;
   CLASSTYPE_NEARLY_EMPTY_P (t) = 1;
   CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 0;
+  CLASSTYPE_LITERAL_P (t) = true;
 
   /* Do end-of-class semantic processing: checking the validity of the
      bases and members and add implicitly generated methods.  */
@@ -5014,8 +5685,9 @@ finish_struct_1 (tree t)
 
   /* Complete the rtl for any static member objects of the type we're
      working on.  */
-  for (x = TYPE_FIELDS (t); x; x = TREE_CHAIN (x))
+  for (x = TYPE_FIELDS (t); x; x = DECL_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);
 
@@ -5029,18 +5701,18 @@ finish_struct_1 (tree t)
   n_fields = count_fields (TYPE_FIELDS (t));
   if (n_fields > 7)
     {
-      struct sorted_fields_type *field_vec = GGC_NEWVAR
-        (struct sorted_fields_type,
-         sizeof (struct sorted_fields_type) + n_fields * sizeof (tree));
+      struct sorted_fields_type *field_vec = ggc_alloc_sorted_fields_type
+        (sizeof (struct sorted_fields_type) + n_fields * sizeof (tree));
       field_vec->len = n_fields;
       add_fields_to_record_type (TYPE_FIELDS (t), field_vec, 0);
       qsort (field_vec->elts, n_fields, sizeof (tree),
             field_decl_cmp);
-      if (! DECL_LANG_SPECIFIC (TYPE_MAIN_DECL (t)))
-       retrofit_lang_decl (TYPE_MAIN_DECL (t));
-      DECL_SORTED_FIELDS (TYPE_MAIN_DECL (t)) = field_vec;
+      CLASSTYPE_SORTED_FIELDS (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);
@@ -5055,17 +5727,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);
@@ -5108,13 +5782,13 @@ unreverse_member_declarations (tree t)
        x && TREE_CODE (x) != TYPE_DECL;
        x = next)
     {
-      next = TREE_CHAIN (x);
-      TREE_CHAIN (x) = prev;
+      next = DECL_CHAIN (x);
+      DECL_CHAIN (x) = prev;
       prev = x;
     }
   if (prev)
     {
-      TREE_CHAIN (TYPE_FIELDS (t)) = x;
+      DECL_CHAIN (TYPE_FIELDS (t)) = x;
       if (prev)
        TYPE_FIELDS (t) = prev;
     }
@@ -5151,10 +5825,13 @@ finish_struct (tree t, tree attributes)
         CLASSTYPE_PURE_VIRTUALS contains the list of the inline friends
         (see CLASSTYPE_INLINE_FRIENDS) so we need to clear it.  */
       CLASSTYPE_PURE_VIRTUALS (t) = NULL;
-      for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x))
+      for (x = TYPE_METHODS (t); x; x = DECL_CHAIN (x))
        if (DECL_PURE_VIRTUAL_P (x))
          VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (t), x);
       complete_vars (t);
+
+      /* Remember current #pragma pack value.  */
+      TYPE_PRECISION (t) = maximum_field_alignment;
     }
   else
     finish_struct_1 (t);
@@ -5183,16 +5860,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.  */
@@ -5212,20 +5890,21 @@ 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);
+    CASE_CONVERT:
+      return RECUR (TREE_OPERAND (instance, 0));
 
     case ADDR_EXPR:
       instance = TREE_OPERAND (instance, 0);
@@ -5238,19 +5917,19 @@ 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:
       if (TREE_CODE (TREE_TYPE (instance)) == ARRAY_TYPE
-         && IS_AGGR_TYPE (TREE_TYPE (TREE_TYPE (instance))))
+         && MAYBE_CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (instance))))
        {
          if (nonnull)
            *nonnull = 1;
@@ -5260,7 +5939,7 @@ fixed_type_or_null (tree instance, int* nonnull, int* cdtorp)
     case TARGET_EXPR:
     case PARM_DECL:
     case RESULT_DECL:
-      if (IS_AGGR_TYPE (TREE_TYPE (instance)))
+      if (MAYBE_CLASS_TYPE_P (TREE_TYPE (instance)))
        {
          if (nonnull)
            *nonnull = 1;
@@ -5283,22 +5962,34 @@ 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))
+             && !type_dependent_expression_p_push (DECL_INITIAL (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;
            }
        }
@@ -5307,6 +5998,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
@@ -5328,8 +6020,17 @@ resolves_to_fixed_type_p (tree instance, int* nonnull)
 {
   tree t = TREE_TYPE (instance);
   int cdtorp = 0;
+  tree fixed;
+
+  if (processing_template_decl)
+    {
+      /* In a template we only care about the type of the result.  */
+      if (nonnull)
+       *nonnull = true;
+      return true;
+    }
 
-  tree fixed = fixed_type_or_null (instance, nonnull, &cdtorp);
+  fixed = fixed_type_or_null (instance, nonnull, &cdtorp);
   if (fixed == NULL_TREE)
     return 0;
   if (POINTER_TYPE_P (t))
@@ -5387,6 +6088,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.  */
@@ -5395,14 +6098,16 @@ pushclass (tree type)
       current_class_stack_size *= 2;
       current_class_stack
        = XRESIZEVEC (struct class_stack_node, current_class_stack,
-                      current_class_stack_size);
+                     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.  */
@@ -5459,21 +6164,56 @@ 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;
+
+  if (!CLASS_TYPE_P (t))
+    return false;
+
+  t = TYPE_MAIN_VARIANT (t);
+
+  /* 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
@@ -5496,9 +6236,41 @@ 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;
+}
+
+/* Returns the innermost class type which is not a lambda closure type.  */
+
+tree
+current_nonlambda_class_type (void)
+{
+  int i;
 
+  /* 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 (!LAMBDA_TYPE_P (c))
+       return c;
+    }
   return NULL_TREE;
 }
 
@@ -5511,21 +6283,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);
 }
 
@@ -5597,18 +6361,25 @@ 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.  If
+   TF_NO_ACCESS_CONTROL is not set in FLAGS, and the address is
+   resolved to a member function, access checks will be performed and
+   errors issued if appropriate.  */
 
 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:
 
@@ -5637,12 +6408,12 @@ resolve_address_of_overloaded_function (tree target_type,
        selected function.  */
 
   int is_ptrmem = 0;
-  int is_reference = 0;
   /* We store the matches in a TREE_LIST rooted here.  The functions
      are the TREE_PURPOSE, not the TREE_VALUE, in this list, for easy
      interoperability with most_specialized_instantiation.  */
   tree matches = NULL_TREE;
   tree fn;
+  tree target_fn_type;
 
   /* By the time we get here, we should be seeing only real
      pointer-to-member types, not the internal POINTER_TYPE to
@@ -5659,12 +6430,9 @@ resolve_address_of_overloaded_function (tree target_type,
     /* This is OK, too.  */
     is_ptrmem = 1;
   else if (TREE_CODE (target_type) == FUNCTION_TYPE)
-    {
-      /* This is OK, too.  This comes from a conversion to reference
-        type.  */
-      target_type = build_reference_type (target_type);
-      is_reference = 1;
-    }
+    /* This is OK, too.  This comes from a conversion to reference
+       type.  */
+    target_type = build_reference_type (target_type);
   else
     {
       if (flags & tf_error)
@@ -5674,6 +6442,15 @@ resolve_address_of_overloaded_function (tree target_type,
       return error_mark_node;
     }
 
+  /* Non-member functions and static member functions match targets of type
+     "pointer-to-function" or "reference-to-function."  Nonstatic member
+     functions match targets of type "pointer-to-member-function;" the
+     function type of the pointer to member is used to select the member
+     function from the set of overloaded member functions.
+
+     So figure out the FUNCTION_TYPE that we want to match against.  */
+  target_fn_type = static_fn_type (target_type);
+
   /* If we can find a non-template function that matches, we can just
      use it.  There's no point in generating template instantiations
      if we're just going to throw them out anyhow.  But, of course, we
@@ -5685,7 +6462,6 @@ resolve_address_of_overloaded_function (tree target_type,
       for (fns = overload; fns; fns = OVL_NEXT (fns))
        {
          tree fn = OVL_CURRENT (fns);
-         tree fntype;
 
          if (TREE_CODE (fn) == TEMPLATE_DECL)
            /* We're not looking for templates just yet.  */
@@ -5703,13 +6479,7 @@ resolve_address_of_overloaded_function (tree target_type,
            continue;
 
          /* See if there's a match.  */
-         fntype = TREE_TYPE (fn);
-         if (is_ptrmem)
-           fntype = build_ptrmemfunc_type (build_pointer_type (fntype));
-         else if (!is_reference)
-           fntype = build_pointer_type (fntype);
-
-         if (can_convert_arg (target_type, fntype, fn, LOOKUP_NORMAL))
+         if (same_type_p (target_fn_type, static_fn_type (fn)))
            matches = tree_cons (fn, NULL_TREE, matches);
        }
     }
@@ -5719,28 +6489,28 @@ resolve_address_of_overloaded_function (tree target_type,
      match we need to look at them, too.  */
   if (!matches)
     {
-      tree target_fn_type;
       tree target_arg_types;
       tree target_ret_type;
       tree fns;
+      tree *args;
+      unsigned int nargs, ia;
+      tree arg;
 
-      if (is_ptrmem)
-       target_fn_type
-         = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (target_type));
-      else
-       target_fn_type = TREE_TYPE (target_type);
       target_arg_types = TYPE_ARG_TYPES (target_fn_type);
       target_ret_type = TREE_TYPE (target_fn_type);
 
-      /* Never do unification on the 'this' parameter.  */
-      if (TREE_CODE (target_fn_type) == METHOD_TYPE)
-       target_arg_types = TREE_CHAIN (target_arg_types);
+      nargs = list_length (target_arg_types);
+      args = XALLOCAVEC (tree, nargs);
+      for (arg = target_arg_types, ia = 0;
+          arg != NULL_TREE && arg != void_list_node;
+          arg = TREE_CHAIN (arg), ++ia)
+       args[ia] = TREE_VALUE (arg);
+      nargs = ia;
 
       for (fns = overload; fns; fns = OVL_NEXT (fns))
        {
          tree fn = OVL_CURRENT (fns);
          tree instantiation;
-         tree instantiation_type;
          tree targs;
 
          if (TREE_CODE (fn) != TEMPLATE_DECL)
@@ -5755,9 +6525,9 @@ resolve_address_of_overloaded_function (tree target_type,
 
          /* Try to do argument deduction.  */
          targs = make_tree_vec (DECL_NTPARMS (fn));
-         if (fn_type_unification (fn, explicit_targs, targs,
-                                  target_arg_types, target_ret_type,
-                                  DEDUCE_EXACT, LOOKUP_NORMAL))
+         if (fn_type_unification (fn, explicit_targs, targs, args, nargs,
+                                  target_ret_type, DEDUCE_EXACT,
+                                  LOOKUP_NORMAL))
            /* Argument deduction failed.  */
            continue;
 
@@ -5768,14 +6538,7 @@ resolve_address_of_overloaded_function (tree target_type,
            continue;
 
          /* See if there's a match.  */
-         instantiation_type = TREE_TYPE (instantiation);
-         if (is_ptrmem)
-           instantiation_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, 
-                              LOOKUP_NORMAL))
+         if (same_type_p (target_fn_type, static_fn_type (instantiation)))
            matches = tree_cons (instantiation, fn, matches);
        }
 
@@ -5785,7 +6548,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);
        }
     }
 
@@ -5796,41 +6561,42 @@ resolve_address_of_overloaded_function (tree target_type,
       if (flags & tf_error)
        {
          error ("no matches converting function %qD to type %q#T",
-                DECL_NAME (OVL_FUNCTION (overload)),
+                DECL_NAME (OVL_CURRENT (overload)),
                 target_type);
 
-         /* print_candidates expects a chain with the functions in
-            TREE_VALUE slots, so we cons one up here (we're losing anyway,
-            so why be clever?).  */
-         for (; overload; overload = OVL_NEXT (overload))
-           matches = tree_cons (NULL_TREE, OVL_CURRENT (overload),
-                                matches);
-
-         print_candidates (matches);
+         print_candidates (overload);
        }
       return error_mark_node;
     }
   else if (TREE_CHAIN (matches))
     {
-      /* There were too many matches.  */
+      /* There were too many matches.  First check if they're all
+        the same function.  */
+      tree match;
 
-      if (flags & tf_error)
+      fn = TREE_PURPOSE (matches);
+      for (match = TREE_CHAIN (matches); match; match = TREE_CHAIN (match))
+       if (!decls_match (fn, TREE_PURPOSE (match)))
+         break;
+
+      if (match)
        {
-         tree match;
+         if (flags & tf_error)
+           {
+             error ("converting overloaded function %qD to type %q#T is ambiguous",
+                    DECL_NAME (OVL_FUNCTION (overload)),
+                    target_type);
 
-         error ("converting overloaded function %qD to type %q#T is ambiguous",
-                   DECL_NAME (OVL_FUNCTION (overload)),
-                   target_type);
+             /* Since print_candidates expects the functions in the
+                TREE_VALUE slot, we flip them here.  */
+             for (match = matches; match; match = TREE_CHAIN (match))
+               TREE_VALUE (match) = TREE_PURPOSE (match);
 
-         /* Since print_candidates expects the functions in the
-            TREE_VALUE slot, we flip them here.  */
-         for (match = matches; match; match = TREE_CHAIN (match))
-           TREE_VALUE (match) = TREE_PURPOSE (match);
+             print_candidates (matches);
+           }
 
-         print_candidates (matches);
+         return error_mark_node;
        }
-
-      return error_mark_node;
     }
 
   /* Good, exactly one match.  Now, convert it to the correct type.  */
@@ -5844,10 +6610,10 @@ resolve_address_of_overloaded_function (tree target_type,
       if (!(flags & tf_error))
        return error_mark_node;
 
-      pedwarn ("assuming pointer to member %qD", fn);
+      permerror (input_location, "assuming pointer to member %qD", fn);
       if (!explained)
        {
-         pedwarn ("(a pointer to member can only be formed with %<&%E%>)", fn);
+         inform (input_location, "(a pointer to member can only be formed with %<&%E%>)", fn);
          explained = 1;
        }
     }
@@ -5857,13 +6623,29 @@ 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);
+    {
+      /* Make =delete work with SFINAE.  */
+      if (DECL_DELETED_FN (fn) && !(flags & tf_error))
+       return error_mark_node;
+      
+      mark_used (fn);
+    }
+
+  /* We could not check access to member functions when this
+     expression was originally created since we did not know at that
+     time to which function the expression referred.  */
+  if (!(flags & tf_no_access_control) 
+      && 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);
+    return cp_build_addr_expr (fn, flags);
   else
     {
-      /* The target must be a REFERENCE_TYPE.  Above, build_unary_op
+      /* The target must be a REFERENCE_TYPE.  Above, cp_build_unary_op
         will mark the function as addressed, but here we must do it
         explicitly.  */
       cxx_mark_addressable (fn);
@@ -5886,10 +6668,11 @@ 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;
 
-  if (TREE_CODE (lhstype) == UNKNOWN_TYPE)
+  if (lhstype == unknown_type_node)
     {
       if (flags & tf_error)
        error ("not enough type information");
@@ -5916,7 +6699,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.  */
@@ -5927,10 +6713,12 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
       return error_mark_node;
     }
 
-  /* We don't overwrite rhs if it is an overloaded function.
-     Copying it would destroy the tree link.  */
-  if (TREE_CODE (rhs) != OVERLOAD)
-    rhs = copy_node (rhs);
+  /* 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
+             || really_overloaded_fn (rhs)
+             || (flag_ms_extensions && TREE_CODE (rhs) == FUNCTION_DECL));
 
   /* This should really only be used when attempting to distinguish
      what sort of a pointer to function we have.  For now, any
@@ -5939,32 +6727,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);
@@ -5981,7 +6743,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.  */
@@ -5997,7 +6759,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:
@@ -6005,106 +6767,8 @@ 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 ();
-
-    case PLUS_EXPR:
-    case MINUS_EXPR:
-    case COMPOUND_EXPR:
-      TREE_OPERAND (rhs, 0)
-       = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
-      if (TREE_OPERAND (rhs, 0) == error_mark_node)
-       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_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;
+                                               /*explicit_targs=*/NULL_TREE,
+                                               access_path);
 
     case ADDR_EXPR:
     {
@@ -6147,7 +6811,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);
@@ -6186,6 +6851,7 @@ build_self_reference (void)
   DECL_CONTEXT (value) = current_class_type;
   DECL_ARTIFICIAL (value) = 1;
   SET_DECL_SELF_REFERENCE_P (value);
+  set_underlying_type (value);
 
   if (processing_template_decl)
     value = push_template_decl (value);
@@ -6204,7 +6870,7 @@ is_empty_class (tree type)
   if (type == error_mark_node)
     return 0;
 
-  if (! IS_AGGR_TYPE (type))
+  if (! CLASS_TYPE_P (type))
     return 0;
 
   /* In G++ 3.2, whether or not a class was empty was determined by
@@ -6244,6 +6910,40 @@ contains_empty_class_p (tree type)
   return false;
 }
 
+/* Returns true if TYPE contains no actual data, just various
+   possible combinations of empty classes and possibly a vptr.  */
+
+bool
+is_really_empty_class (tree type)
+{
+  if (CLASS_TYPE_P (type))
+    {
+      tree field;
+      tree binfo;
+      tree base_binfo;
+      int i;
+
+      /* CLASSTYPE_EMPTY_P isn't set properly until the class is actually laid
+        out, but we'd like to be able to check this before then.  */
+      if (COMPLETE_TYPE_P (type) && is_empty_class (type))
+       return true;
+
+      for (binfo = TYPE_BINFO (type), i = 0;
+          BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
+       if (!is_really_empty_class (BINFO_TYPE (base_binfo)))
+         return false;
+      for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+       if (TREE_CODE (field) == FIELD_DECL
+           && !DECL_ARTIFICIAL (field)
+           && !is_really_empty_class (TREE_TYPE (field)))
+         return false;
+      return true;
+    }
+  else if (TREE_CODE (type) == ARRAY_TYPE)
+    return is_really_empty_class (TREE_TYPE (type));
+  return false;
+}
+
 /* Note that NAME was looked up while the current class was being
    defined and that the result of that lookup was DECL.  */
 
@@ -6254,7 +6954,8 @@ maybe_note_name_used_in_class (tree name, tree decl)
 
   /* If we're not defining a class, there's nothing to do.  */
   if (!(innermost_scope_kind() == sk_class
-       && TYPE_BEING_DEFINED (current_class_type)))
+       && TYPE_BEING_DEFINED (current_class_type)
+       && !LAMBDA_TYPE_P (current_class_type)))
     return;
 
   /* If there's already a binding for this NAME, then we don't have
@@ -6287,7 +6988,13 @@ note_name_declared_in_class (tree name, tree decl)
     = current_class_stack[current_class_depth - 1].names_used;
   if (!names_used)
     return;
-
+  /* The C language allows members to be declared with a type of the same
+     name, and the C++ standard says this diagnostic is not required.  So
+     allow it in extern "C" blocks unless predantic is specified.
+     Allow it in all cases if -ms-extensions is specified.  */
+  if ((!pedantic && current_lang_name == lang_name_c)
+      || flag_ms_extensions)
+    return;
   n = splay_tree_lookup (names_used, (splay_tree_key) name);
   if (n)
     {
@@ -6296,9 +7003,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);
+      permerror (input_location, "declaration of %q#D", decl);
+      permerror (input_location, "changes meaning of %qD from %q+#D",
+              DECL_NAME (OVL_CURRENT (decl)), (tree) n->value);
     }
 }
 
@@ -6312,7 +7019,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);
@@ -6329,18 +7036,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.  */
@@ -6470,7 +7175,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);
@@ -6600,7 +7305,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);
@@ -6613,36 +7318,36 @@ debug_thunks (tree fn)
 static void
 finish_vtbls (tree t)
 {
-  tree list;
   tree vbase;
+  VEC(constructor_elt,gc) *v = NULL;
+  tree vtable = BINFO_VTABLE (TYPE_BINFO (t));
 
   /* We lay out the primary and secondary vtables in one contiguous
      vtable.  The primary vtable is first, followed by the non-virtual
      secondary vtables in inheritance graph order.  */
-  list = build_tree_list (BINFO_VTABLE (TYPE_BINFO (t)), NULL_TREE);
-  accumulate_vtbl_inits (TYPE_BINFO (t), TYPE_BINFO (t),
-                        TYPE_BINFO (t), t, list);
+  accumulate_vtbl_inits (TYPE_BINFO (t), TYPE_BINFO (t), TYPE_BINFO (t),
+                        vtable, t, &v);
 
   /* Then come the virtual bases, also in inheritance graph order.  */
   for (vbase = TYPE_BINFO (t); vbase; vbase = TREE_CHAIN (vbase))
     {
       if (!BINFO_VIRTUAL_P (vbase))
        continue;
-      accumulate_vtbl_inits (vbase, vbase, TYPE_BINFO (t), t, list);
+      accumulate_vtbl_inits (vbase, vbase, TYPE_BINFO (t), vtable, t, &v);
     }
 
   if (BINFO_VTABLE (TYPE_BINFO (t)))
-    initialize_vtable (TYPE_BINFO (t), TREE_VALUE (list));
+    initialize_vtable (TYPE_BINFO (t), v);
 }
 
 /* Initialize the vtable for BINFO with the INITS.  */
 
 static void
-initialize_vtable (tree binfo, tree inits)
+initialize_vtable (tree binfo, VEC(constructor_elt,gc) *inits)
 {
   tree decl;
 
-  layout_vtable_decl (binfo, list_length (inits));
+  layout_vtable_decl (binfo, VEC_length (constructor_elt, inits));
   decl = get_vtbl_decl_for_binfo (binfo);
   initialize_artificial_var (decl, inits);
   dump_vtable (BINFO_TYPE (binfo), binfo, decl);
@@ -6664,13 +7369,13 @@ initialize_vtable (tree binfo, tree inits)
 static void
 build_vtt (tree t)
 {
-  tree inits;
   tree type;
   tree vtt;
   tree index;
+  VEC(constructor_elt,gc) *inits;
 
   /* Build up the initializers for the VTT.  */
-  inits = NULL_TREE;
+  inits = NULL;
   index = size_zero_node;
   build_vtt_inits (TYPE_BINFO (t), t, &inits, &index);
 
@@ -6679,15 +7384,15 @@ build_vtt (tree t)
     return;
 
   /* Figure out the type of the VTT.  */
-  type = build_index_type (size_int (list_length (inits) - 1));
-  type = build_cplus_array_type (const_ptr_type_node, type);
+  type = build_array_of_n_type (const_ptr_type_node,
+                               VEC_length (constructor_elt, inits));
 
   /* 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));
-  TREE_CHAIN (CLASSTYPE_VTABLES (t)) = vtt;
+  DECL_CHAIN (vtt) = DECL_CHAIN (CLASSTYPE_VTABLES (t));
+  DECL_CHAIN (CLASSTYPE_VTABLES (t)) = vtt;
 
   dump_vtt (t, vtt);
 }
@@ -6725,8 +7430,8 @@ typedef struct secondary_vptr_vtt_init_data_s
   /* Current index into the VTT.  */
   tree index;
 
-  /* TREE_LIST of initializers built up.  */
-  tree inits;
+  /* Vector of initializers built up.  */
+  VEC(constructor_elt,gc) *inits;
 
   /* The type being constructed by this secondary VTT.  */
   tree type_being_constructed;
@@ -6740,19 +7445,18 @@ typedef struct secondary_vptr_vtt_init_data_s
    for virtual bases of T. When it is not so, we build the constructor
    vtables for the BINFO-in-T variant.  */
 
-static tree *
-build_vtt_inits (tree binfo, tree t, tree *inits, tree *index)
+static void
+build_vtt_inits (tree binfo, tree t, VEC(constructor_elt,gc) **inits, tree *index)
 {
   int i;
   tree b;
   tree init;
-  tree secondary_vptrs;
   secondary_vptr_vtt_init_data data;
   int top_level_p = SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t);
 
   /* We only need VTTs for subobjects with virtual bases.  */
   if (!CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)))
-    return inits;
+    return;
 
   /* We need to use a construction vtable if this is not the primary
      VTT.  */
@@ -6766,8 +7470,7 @@ build_vtt_inits (tree binfo, tree t, tree *inits, tree *index)
 
   /* Add the address of the primary vtable for the complete object.  */
   init = binfo_ctor_vtable (binfo);
-  *inits = build_tree_list (NULL_TREE, init);
-  inits = &TREE_CHAIN (*inits);
+  CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init);
   if (top_level_p)
     {
       gcc_assert (!BINFO_VPTR_INDEX (binfo));
@@ -6778,30 +7481,23 @@ build_vtt_inits (tree binfo, tree t, tree *inits, tree *index)
   /* Recursively add the secondary VTTs for non-virtual bases.  */
   for (i = 0; BINFO_BASE_ITERATE (binfo, i, b); ++i)
     if (!BINFO_VIRTUAL_P (b))
-      inits = build_vtt_inits (b, t, inits, index);
+      build_vtt_inits (b, t, inits, index);
 
   /* Add secondary virtual pointers for all subobjects of BINFO with
      either virtual bases or reachable along a virtual path, except
      subobjects that are non-virtual primary bases.  */
   data.top_level_p = top_level_p;
   data.index = *index;
-  data.inits = NULL;
+  data.inits = *inits;
   data.type_being_constructed = BINFO_TYPE (binfo);
 
   dfs_walk_once (binfo, dfs_build_secondary_vptr_vtt_inits, NULL, &data);
 
   *index = data.index;
 
-  /* The secondary vptrs come back in reverse order.  After we reverse
-     them, and add the INITS, the last init will be the first element
-     of the chain.  */
-  secondary_vptrs = data.inits;
-  if (secondary_vptrs)
-    {
-      *inits = nreverse (secondary_vptrs);
-      inits = &TREE_CHAIN (secondary_vptrs);
-      gcc_assert (*inits == NULL_TREE);
-    }
+  /* data.inits might have grown as we added secondary virtual pointers.
+     Make sure our caller knows about the new vector.  */
+  *inits = data.inits;
 
   if (top_level_p)
     /* Add the secondary VTTs for virtual bases in inheritance graph
@@ -6811,13 +7507,11 @@ build_vtt_inits (tree binfo, tree t, tree *inits, tree *index)
        if (!BINFO_VIRTUAL_P (b))
          continue;
 
-       inits = build_vtt_inits (b, t, inits, index);
+       build_vtt_inits (b, t, inits, index);
       }
   else
     /* Remove the ctor vtables we created.  */
     dfs_walk_all (binfo, dfs_fixup_binfo_vtbls, NULL, binfo);
-
-  return inits;
 }
 
 /* Called from build_vtt_inits via dfs_walk.  BINFO is the binfo for the base
@@ -6865,7 +7559,7 @@ dfs_build_secondary_vptr_vtt_inits (tree binfo, void *data_)
     }
 
   /* Add the initializer for the secondary vptr itself.  */
-  data->inits = tree_cons (NULL_TREE, binfo_ctor_vtable (binfo), data->inits);
+  CONSTRUCTOR_APPEND_ELT (data->inits, NULL_TREE, binfo_ctor_vtable (binfo));
 
   /* Advance the vtt index.  */
   data->index = size_binop (PLUS_EXPR, data->index,
@@ -6908,12 +7602,11 @@ dfs_fixup_binfo_vtbls (tree binfo, void* data)
 static void
 build_ctor_vtbl_group (tree binfo, tree t)
 {
-  tree list;
   tree type;
   tree vtbl;
-  tree inits;
   tree id;
   tree vbase;
+  VEC(constructor_elt,gc) *v;
 
   /* See if we've already created this construction vtable group.  */
   id = mangle_ctor_vtbl_for_type (t, binfo);
@@ -6926,9 +7619,10 @@ build_ctor_vtbl_group (tree binfo, tree t)
      construction vtable group.  */
   vtbl = build_vtable (t, id, ptr_type_node);
   DECL_CONSTRUCTION_VTABLE_P (vtbl) = 1;
-  list = build_tree_list (vtbl, NULL_TREE);
+
+  v = NULL;
   accumulate_vtbl_inits (binfo, TYPE_BINFO (TREE_TYPE (binfo)),
-                        binfo, t, list);
+                        binfo, vtbl, t, &v);
 
   /* Add the vtables for each of our virtual bases using the vbase in T
      binfo.  */
@@ -6942,18 +7636,20 @@ build_ctor_vtbl_group (tree binfo, tree t)
        continue;
       b = copied_binfo (vbase, binfo);
 
-      accumulate_vtbl_inits (b, vbase, binfo, t, list);
+      accumulate_vtbl_inits (b, vbase, binfo, vtbl, t, &v);
     }
-  inits = TREE_VALUE (list);
 
   /* 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);
+  type = build_array_of_n_type (vtable_entry_type,
+                               VEC_length (constructor_elt, v));
+  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);
-  initialize_artificial_var (vtbl, inits);
+  initialize_artificial_var (vtbl, v);
   dump_vtable (t, binfo, vtbl);
 }
 
@@ -6971,8 +7667,9 @@ static void
 accumulate_vtbl_inits (tree binfo,
                       tree orig_binfo,
                       tree rtti_binfo,
+                      tree vtbl,
                       tree t,
-                      tree inits)
+                      VEC(constructor_elt,gc) **inits)
 {
   int i;
   tree base_binfo;
@@ -6992,10 +7689,7 @@ accumulate_vtbl_inits (tree binfo,
     return;
 
   /* Build the initializers for the BINFO-in-T vtable.  */
-  TREE_VALUE (inits)
-    = chainon (TREE_VALUE (inits),
-              dfs_accumulate_vtbl_inits (binfo, orig_binfo,
-                                         rtti_binfo, t, inits));
+  dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, vtbl, t, inits);
 
   /* Walk the BINFO and its bases.  We walk in preorder so that as we
      initialize each vtable we can figure out at what offset the
@@ -7009,24 +7703,25 @@ accumulate_vtbl_inits (tree binfo,
        continue;
       accumulate_vtbl_inits (base_binfo,
                             BINFO_BASE_BINFO (orig_binfo, i),
-                            rtti_binfo, t,
+                            rtti_binfo, vtbl, t,
                             inits);
     }
 }
 
-/* Called from accumulate_vtbl_inits.  Returns the initializers for
-   the BINFO vtable.  */
+/* Called from accumulate_vtbl_inits.  Adds the initializers for the
+   BINFO vtable to L.  */
 
-static tree
+static void
 dfs_accumulate_vtbl_inits (tree binfo,
                           tree orig_binfo,
                           tree rtti_binfo,
+                          tree orig_vtbl,
                           tree t,
-                          tree l)
+                          VEC(constructor_elt,gc) **l)
 {
-  tree inits = NULL_TREE;
   tree vtbl = NULL_TREE;
   int ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t);
+  int n_inits;
 
   if (ctor_vtbl_p
       && BINFO_VIRTUAL_P (orig_binfo) && BINFO_PRIMARY_P (orig_binfo))
@@ -7080,27 +7775,28 @@ dfs_accumulate_vtbl_inits (tree binfo,
       /* Otherwise, this is case 3 and we get our own.  */
     }
   else if (!BINFO_NEW_VTABLE_MARKED (orig_binfo))
-    return inits;
+    return;
+
+  n_inits = VEC_length (constructor_elt, *l);
 
   if (!vtbl)
     {
       tree index;
       int non_fn_entries;
 
-      /* Compute the initializer for this vtable.  */
-      inits = build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo,
-                                     &non_fn_entries);
+      /* Add the initializer for this vtable.  */
+      build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo,
+                              &non_fn_entries, l);
 
       /* Figure out the position to which the VPTR should point.  */
-      vtbl = TREE_PURPOSE (l);
-      vtbl = build1 (ADDR_EXPR, vtbl_ptr_type_node, vtbl);
+      vtbl = build1 (ADDR_EXPR, vtbl_ptr_type_node, orig_vtbl);
       index = size_binop (PLUS_EXPR,
                          size_int (non_fn_entries),
-                         size_int (list_length (TREE_VALUE (l))));
+                         size_int (n_inits));
       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)
@@ -7109,12 +7805,11 @@ dfs_accumulate_vtbl_inits (tree binfo,
        straighten this out.  */
     BINFO_VTABLE (binfo) = tree_cons (rtti_binfo, vtbl, BINFO_VTABLE (binfo));
   else if (BINFO_PRIMARY_P (binfo) && BINFO_VIRTUAL_P (binfo))
-    inits = NULL_TREE;
+    /* Throw away any unneeded intializers.  */
+    VEC_truncate (constructor_elt, *l, n_inits);
   else
      /* For an ordinary vtable, set BINFO_VTABLE.  */
     BINFO_VTABLE (binfo) = vtbl;
-
-  return inits;
 }
 
 static GTY(()) tree abort_fndecl_addr;
@@ -7142,26 +7837,26 @@ static GTY(()) tree abort_fndecl_addr;
    primary bases; we need these while the primary base is being
    constructed.  */
 
-static tree
+static void
 build_vtbl_initializer (tree binfo,
                        tree orig_binfo,
                        tree t,
                        tree rtti_binfo,
-                       int* non_fn_entries_p)
+                       int* non_fn_entries_p,
+                       VEC(constructor_elt,gc) **inits)
 {
-  tree v, b;
-  tree vfun_inits;
+  tree v;
   vtbl_init_data vid;
-  unsigned ix;
+  unsigned ix, jx;
   tree vbinfo;
   VEC(tree,gc) *vbases;
+  constructor_elt *e;
 
   /* Initialize VID.  */
   memset (&vid, 0, sizeof (vid));
   vid.binfo = binfo;
   vid.derived = t;
   vid.rtti_binfo = rtti_binfo;
-  vid.last_init = &vid.inits;
   vid.primary_vtbl_p = SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t);
   vid.ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t);
   vid.generate_vcall_entries = true;
@@ -7187,28 +7882,52 @@ build_vtbl_initializer (tree binfo,
   /* If the target requires padding between data entries, add that now.  */
   if (TARGET_VTABLE_DATA_ENTRY_DISTANCE > 1)
     {
-      tree cur, *prev;
+      int n_entries = VEC_length (constructor_elt, vid.inits);
 
-      for (prev = &vid.inits; (cur = *prev); prev = &TREE_CHAIN (cur))
+      VEC_safe_grow (constructor_elt, gc, vid.inits,
+                    TARGET_VTABLE_DATA_ENTRY_DISTANCE * n_entries);
+
+      /* Move data entries into their new positions and add padding
+        after the new positions.  Iterate backwards so we don't
+        overwrite entries that we would need to process later.  */
+      for (ix = n_entries - 1;
+          VEC_iterate (constructor_elt, vid.inits, ix, e);
+          ix--)
        {
-         tree add = cur;
-         int i;
+         int j;
+         int new_position = (TARGET_VTABLE_DATA_ENTRY_DISTANCE * ix
+                             + (TARGET_VTABLE_DATA_ENTRY_DISTANCE - 1));
 
-         for (i = 1; i < TARGET_VTABLE_DATA_ENTRY_DISTANCE; ++i)
-           add = tree_cons (NULL_TREE,
-                            build1 (NOP_EXPR, vtable_entry_type,
-                                    null_pointer_node),
-                            add);
-         *prev = add;
+         VEC_replace (constructor_elt, vid.inits, new_position, e);
+
+         for (j = 1; j < TARGET_VTABLE_DATA_ENTRY_DISTANCE; ++j)
+           {
+             constructor_elt *f = VEC_index (constructor_elt, vid.inits,
+                                             new_position - j);
+             f->index = NULL_TREE;
+             f->value = build1 (NOP_EXPR, vtable_entry_type,
+                                null_pointer_node);
+           }
        }
     }
 
   if (non_fn_entries_p)
-    *non_fn_entries_p = list_length (vid.inits);
+    *non_fn_entries_p = VEC_length (constructor_elt, vid.inits);
+
+  /* The initializers for virtual functions were built up in reverse
+     order.  Straighten them out and add them to the running list in one
+     step.  */
+  jx = VEC_length (constructor_elt, *inits);
+  VEC_safe_grow (constructor_elt, gc, *inits,
+                (jx + VEC_length (constructor_elt, vid.inits)));
+
+  for (ix = VEC_length (constructor_elt, vid.inits) - 1;
+       VEC_iterate (constructor_elt, vid.inits, ix, e);
+       ix--, jx++)
+    VEC_replace (constructor_elt, *inits, jx, e);
 
   /* Go through all the ordinary virtual functions, building up
      initializers.  */
-  vfun_inits = NULL_TREE;
   for (v = BINFO_VIRTUALS (orig_binfo); v; v = TREE_CHAIN (v))
     {
       tree delta;
@@ -7237,23 +7956,11 @@ build_vtbl_initializer (tree binfo,
 
         We first check this in update_vtable_entry_for_fn, so we handle
         restored primary bases properly; we also need to do it here so we
-        zero out unused slots in ctor vtables, rather than filling themff
+        zero out unused slots in ctor vtables, rather than filling them
         with erroneous values (though harmless, apart from relocation
         costs).  */
-      for (b = binfo; ; b = get_primary_binfo (b))
-       {
-         /* We found a defn before a lost primary; go ahead as normal.  */
-         if (look_for_overrides_here (BINFO_TYPE (b), fn_original))
-           break;
-
-         /* The nearest definition is from a lost primary; clear the
-            slot.  */
-         if (BINFO_LOST_PRIMARY_P (b))
-           {
-             init = size_zero_node;
-             break;
-           }
-       }
+      if (BV_LOST_PRIMARY (v))
+       init = size_zero_node;
 
       if (! init)
        {
@@ -7270,9 +7977,14 @@ build_vtbl_initializer (tree binfo,
          if (DECL_PURE_VIRTUAL_P (fn_original))
            {
              fn = abort_fndecl;
-             if (abort_fndecl_addr == NULL)
-               abort_fndecl_addr = build1 (ADDR_EXPR, vfunc_ptr_type_node, fn);
-             init = abort_fndecl_addr;
+             if (!TARGET_VTABLE_USES_DESCRIPTORS)
+               {
+                 if (abort_fndecl_addr == NULL)
+                   abort_fndecl_addr
+                     = fold_convert (vfunc_ptr_type_node,
+                                     build_fold_addr_expr (fn));
+                 init = abort_fndecl_addr;
+               }
            }
          else
            {
@@ -7284,7 +7996,9 @@ build_vtbl_initializer (tree binfo,
                }
              /* Take the address of the function, considering it to be of an
                 appropriate generic type.  */
-             init = build1 (ADDR_EXPR, vfunc_ptr_type_node, fn);
+             if (!TARGET_VTABLE_USES_DESCRIPTORS)
+               init = fold_convert (vfunc_ptr_type_node,
+                                    build_fold_addr_expr (fn));
            }
        }
 
@@ -7294,32 +8008,20 @@ build_vtbl_initializer (tree binfo,
          int i;
          if (init == size_zero_node)
            for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i)
-             vfun_inits = tree_cons (NULL_TREE, init, vfun_inits);
+             CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init);
          else
            for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i)
              {
                tree fdesc = build2 (FDESC_EXPR, vfunc_ptr_type_node,
-                                    TREE_OPERAND (init, 0),
-                                    build_int_cst (NULL_TREE, i));
+                                    fn, build_int_cst (NULL_TREE, i));
                TREE_CONSTANT (fdesc) = 1;
-               TREE_INVARIANT (fdesc) = 1;
 
-               vfun_inits = tree_cons (NULL_TREE, fdesc, vfun_inits);
+               CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, fdesc);
              }
        }
       else
-       vfun_inits = tree_cons (NULL_TREE, init, vfun_inits);
+       CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init);
     }
-
-  /* The initializers for virtual functions were built up in reverse
-     order; straighten them out now.  */
-  vfun_inits = nreverse (vfun_inits);
-
-  /* The negative offset initializers are also in reverse order.  */
-  vid.inits = nreverse (vid.inits);
-
-  /* Chain the two together.  */
-  return chainon (vid.inits, vfun_inits);
 }
 
 /* Adds to vid->inits the initializers for the vbase and vcall
@@ -7426,14 +8128,12 @@ build_vbase_offset_vtbl_entries (tree binfo, vtbl_init_data* vid)
         The vbase offsets go in reverse inheritance-graph order, and
         we are walking in inheritance graph order so these end up in
         the right order.  */
-      delta = size_diffop (BINFO_OFFSET (b), BINFO_OFFSET (non_primary_binfo));
+      delta = size_diffop_loc (input_location,
+                          BINFO_OFFSET (b), BINFO_OFFSET (non_primary_binfo));
 
-      *vid->last_init
-       = build_tree_list (NULL_TREE,
-                          fold_build1 (NOP_EXPR,
-                                       vtable_entry_type,
-                                       delta));
-      vid->last_init = &TREE_CHAIN (*vid->last_init);
+      CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE,
+                             fold_build1_loc (input_location, NOP_EXPR,
+                                              vtable_entry_type, delta));
     }
 }
 
@@ -7447,7 +8147,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:
@@ -7521,7 +8228,7 @@ add_vcall_offset_vtbl_entries_1 (tree binfo, vtbl_init_data* vid)
         order.  G++ 3.2 used the order in the vtable.  */
       for (orig_fn = TYPE_METHODS (BINFO_TYPE (binfo));
           orig_fn;
-          orig_fn = TREE_CHAIN (orig_fn))
+          orig_fn = DECL_CHAIN (orig_fn))
        if (DECL_VINDEX (orig_fn))
          add_vcall_offset (orig_fn, binfo, vid);
     }
@@ -7605,7 +8312,7 @@ add_vcall_offset (tree orig_fn, tree binfo, vtbl_init_data *vid)
      signature as FN, then we do not need a second vcall offset.
      Check the list of functions already present in the derived
      class vtable.  */
-  for (i = 0; VEC_iterate (tree, vid->fns, i, derived_entry); ++i)
+  FOR_EACH_VEC_ELT (tree, vid->fns, i, derived_entry)
     {
       if (same_signature_p (derived_entry, orig_fn)
          /* We only use one vcall offset for virtual destructors,
@@ -7643,8 +8350,7 @@ add_vcall_offset (tree orig_fn, tree binfo, vtbl_init_data *vid)
       /* Find the overriding function.  */
       fn = find_final_overrider (vid->rtti_binfo, binfo, orig_fn);
       if (fn == error_mark_node)
-       vcall_offset = build1 (NOP_EXPR, vtable_entry_type,
-                              integer_zero_node);
+       vcall_offset = build_zero_cst (vtable_entry_type);
       else
        {
          base = TREE_VALUE (fn);
@@ -7653,14 +8359,15 @@ add_vcall_offset (tree orig_fn, tree binfo, vtbl_init_data *vid)
             vid->binfo.  But it might be a lost primary, so its
             BINFO_OFFSET might be wrong, so we just use the
             BINFO_OFFSET from vid->binfo.  */
-         vcall_offset = size_diffop (BINFO_OFFSET (base),
+         vcall_offset = size_diffop_loc (input_location,
+                                     BINFO_OFFSET (base),
                                      BINFO_OFFSET (vid->binfo));
-         vcall_offset = fold_build1 (NOP_EXPR, vtable_entry_type,
+         vcall_offset = fold_build1_loc (input_location,
+                                     NOP_EXPR, vtable_entry_type,
                                      vcall_offset);
        }
       /* Add the initializer to the vtable.  */
-      *vid->last_init = build_tree_list (NULL_TREE, vcall_offset);
-      vid->last_init = &TREE_CHAIN (*vid->last_init);
+      CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, vcall_offset);
     }
 }
 
@@ -7673,12 +8380,10 @@ build_rtti_vtbl_entries (tree binfo, vtbl_init_data* vid)
 {
   tree b;
   tree t;
-  tree basetype;
   tree offset;
   tree decl;
   tree init;
 
-  basetype = BINFO_TYPE (binfo);
   t = BINFO_TYPE (vid->rtti_binfo);
 
   /* To find the complete object, we will first convert to our most
@@ -7694,7 +8399,8 @@ build_rtti_vtbl_entries (tree binfo, vtbl_init_data* vid)
                  && BINFO_INHERITANCE_CHAIN (primary_base) == b);
       b = primary_base;
     }
-  offset = size_diffop (BINFO_OFFSET (vid->rtti_binfo), BINFO_OFFSET (b));
+  offset = size_diffop_loc (input_location,
+                       BINFO_OFFSET (vid->rtti_binfo), BINFO_OFFSET (b));
 
   /* The second entry is the address of the typeinfo object.  */
   if (flag_rtti)
@@ -7705,45 +8411,13 @@ build_rtti_vtbl_entries (tree binfo, vtbl_init_data* vid)
   /* Convert the declaration to a type that can be stored in the
      vtable.  */
   init = build_nop (vfunc_ptr_type_node, decl);
-  *vid->last_init = build_tree_list (NULL_TREE, init);
-  vid->last_init = &TREE_CHAIN (*vid->last_init);
+  CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, init);
 
   /* Add the offset-to-top entry.  It comes earlier in the vtable than
      the typeinfo entry.  Convert the offset to look like a
      function pointer, so that we can put it in the vtable.  */
   init = build_nop (vfunc_ptr_type_node, offset);
-  *vid->last_init = build_tree_list (NULL_TREE, init);
-  vid->last_init = &TREE_CHAIN (*vid->last_init);
-}
-
-/* Fold a OBJ_TYPE_REF expression to the address of a function.
-   KNOWN_TYPE carries the true type of OBJ_TYPE_REF_OBJECT(REF).  */
-
-tree
-cp_fold_obj_type_ref (tree ref, tree known_type)
-{
-  HOST_WIDE_INT index = tree_low_cst (OBJ_TYPE_REF_TOKEN (ref), 1);
-  HOST_WIDE_INT i = 0;
-  tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
-  tree fndecl;
-
-  while (i != index)
-    {
-      i += (TARGET_VTABLE_USES_DESCRIPTORS
-           ? TARGET_VTABLE_USES_DESCRIPTORS : 1);
-      v = TREE_CHAIN (v);
-    }
-
-  fndecl = BV_FN (v);
-
-#ifdef ENABLE_CHECKING
-  gcc_assert (tree_int_cst_equal (OBJ_TYPE_REF_TOKEN (ref),
-                                 DECL_VINDEX (fndecl)));
-#endif
-
-  cgraph_node (fndecl)->local.vtable_method = true;
-
-  return build_address (fndecl);
+  CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, init);
 }
 
 #include "gt-cp-class.h"