OSDN Git Service

+ PR c++/51928
[pf3gnuchains/gcc-fork.git] / gcc / cp / class.c
index 60908ff..35e0864 100644 (file)
@@ -1,6 +1,6 @@
 /* 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, 2007, 2008, 2009, 2010
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cgraph.h"
 #include "tree-dump.h"
 #include "splay-tree.h"
+#include "pointer-set.h"
 
 /* The number of nested classes being processed.  If we are not in the
    scope of any class, this is zero.  */
@@ -234,7 +235,8 @@ tree
 build_base_path (enum tree_code code,
                 tree expr,
                 tree binfo,
-                int nonnull)
+                int nonnull,
+                tsubst_flags_t complain)
 {
   tree v_binfo = NULL_TREE;
   tree d_binfo = NULL_TREE;
@@ -264,10 +266,25 @@ build_base_path (enum tree_code code,
   if (want_pointer)
     probe = TYPE_MAIN_VARIANT (TREE_TYPE (probe));
 
+  if (code == PLUS_EXPR
+      && !SAME_BINFO_TYPE_P (BINFO_TYPE (d_binfo), probe))
+    {
+      /* This can happen when adjust_result_of_qualified_name_lookup can't
+        find a unique base binfo in a call to a member function.  We
+        couldn't give the diagnostic then since we might have been calling
+        a static member function, so we do it now.  */
+      if (complain & tf_error)
+       {
+         tree base = lookup_base (probe, BINFO_TYPE (d_binfo),
+                                  ba_unique, NULL);
+         gcc_assert (base == error_mark_node);
+       }
+      return error_mark_node;
+    }
+
   gcc_assert ((code == MINUS_EXPR
               && SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), probe))
-             || (code == PLUS_EXPR
-                 && SAME_BINFO_TYPE_P (BINFO_TYPE (d_binfo), probe)));
+             || code == PLUS_EXPR);
 
   if (binfo == d_binfo)
     /* Nothing to do.  */
@@ -275,27 +292,55 @@ build_base_path (enum tree_code code,
 
   if (code == MINUS_EXPR && v_binfo)
     {
-      error ("cannot convert from base %qT to derived type %qT via virtual base %qT",
-            BINFO_TYPE (binfo), BINFO_TYPE (d_binfo), BINFO_TYPE (v_binfo));
+      if (complain & tf_error)
+       error ("cannot convert from base %qT to derived type %qT via "
+              "virtual base %qT", BINFO_TYPE (binfo), BINFO_TYPE (d_binfo),
+              BINFO_TYPE (v_binfo));
       return error_mark_node;
     }
 
   if (!want_pointer)
     /* This must happen before the call to save_expr.  */
-    expr = cp_build_unary_op (ADDR_EXPR, expr, 0, tf_warning_or_error);
+    expr = cp_build_addr_expr (expr, complain);
+  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);
+  /* 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.  */
+  target_type = cp_build_qualified_type
+    (target_type, cp_type_quals (TREE_TYPE (TREE_TYPE (expr))));
+  ptr_target_type = build_pointer_type (target_type);
 
   /* 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)
+     source type is incomplete and the pointer value doesn't matter.  In a
+     template (even in fold_non_dependent_expr), we don't have vtables set
+     up properly yet, and the value doesn't matter there either; we're just
+     interested in the result of overload resolution.  */
+  if (cp_unevaluated_operand != 0
+      || (current_function_decl
+         && uses_template_parms (current_function_decl)))
+    {
+      expr = build_nop (ptr_target_type, expr);
+      if (!want_pointer)
+       expr = build_indirect_ref (EXPR_LOCATION (expr), expr, RO_NULL);
+      return expr;
+    }
+
+  /* If we're in an NSDMI, we don't have the full constructor context yet
+     that we need for converting to a virtual base, so just build a stub
+     CONVERT_EXPR and expand it later in bot_replace.  */
+  if (virtual_access && fixed_type_p < 0
+      && current_scope () != current_function_decl)
     {
-      expr = build_nop (build_pointer_type (target_type), expr);
+      expr = build1 (CONVERT_EXPR, ptr_target_type, expr);
+      CONVERT_EXPR_VBASE_PATH (expr) = true;
       if (!want_pointer)
        expr = build_indirect_ref (EXPR_LOCATION (expr), expr, RO_NULL);
       return expr;
@@ -310,18 +355,7 @@ build_base_path (enum tree_code code,
         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);
-       }
+       return build_nop (ptr_target_type, expr);
       null_test = error_mark_node;
     }
 
@@ -332,7 +366,7 @@ build_base_path (enum tree_code code,
   /* Now that we've saved expr, build the real null test.  */
   if (null_test)
     {
-      tree zero = cp_convert (TREE_TYPE (expr), integer_zero_node);
+      tree zero = cp_convert (TREE_TYPE (expr), nullptr_node);
       null_test = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
                               expr, zero);
     }
@@ -343,7 +377,7 @@ build_base_path (enum tree_code code,
         interesting to the optimizers anyway.  */
       && !has_empty)
     {
-      expr = cp_build_indirect_ref (expr, RO_NULL, tf_warning_or_error);
+      expr = cp_build_indirect_ref (expr, RO_NULL, complain);
       expr = build_simple_base_path (expr, binfo);
       if (want_pointer)
        expr = build_address (expr);
@@ -368,20 +402,18 @@ 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 = cp_build_indirect_ref (v_offset, RO_NULL, 
-                                            tf_warning_or_error);
+         v_offset = cp_build_indirect_ref (v_offset, RO_NULL, complain);
        }
       else
        v_offset = build_vfield_ref (cp_build_indirect_ref (expr, RO_NULL,
-                                                            tf_warning_or_error),
+                                                            complain),
                                     TREE_TYPE (TREE_TYPE (expr)));
 
-      v_offset = build2 (POINTER_PLUS_EXPR, TREE_TYPE (v_offset),
-                        v_offset, fold_convert (sizetype, BINFO_VPTR_FIELD (v_binfo)));
+      v_offset = fold_build_pointer_plus (v_offset, BINFO_VPTR_FIELD (v_binfo));
       v_offset = build1 (NOP_EXPR,
                         build_pointer_type (ptrdiff_type_node),
                         v_offset);
-      v_offset = cp_build_indirect_ref (v_offset, RO_NULL, tf_warning_or_error);
+      v_offset = cp_build_indirect_ref (v_offset, RO_NULL, complain);
       TREE_CONSTANT (v_offset) = 1;
 
       offset = convert_to_integer (ptrdiff_type_node,
@@ -405,9 +437,6 @@ build_base_path (enum tree_code code,
        offset = v_offset;
     }
 
-  target_type = cp_build_qualified_type
-    (target_type, cp_type_quals (TREE_TYPE (TREE_TYPE (expr))));
-  ptr_target_type = build_pointer_type (target_type);
   if (want_pointer)
     target_type = ptr_target_type;
 
@@ -418,19 +447,18 @@ build_base_path (enum tree_code code,
       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);
+      expr = fold_build_pointer_plus (expr, offset);
     }
   else
     null_test = NULL;
 
   if (!want_pointer)
-    expr = cp_build_indirect_ref (expr, RO_NULL, tf_warning_or_error);
+    expr = cp_build_indirect_ref (expr, RO_NULL, complain);
 
  out:
   if (null_test)
     expr = fold_build3_loc (input_location, COND_EXPR, target_type, null_test, expr,
-                       fold_build1_loc (input_location, NOP_EXPR, target_type,
-                                    integer_zero_node));
+                           build_zero_cst (target_type));
 
   return expr;
 }
@@ -467,11 +495,18 @@ 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)
-       && TREE_TYPE (field) == type)
+       && TREE_TYPE (field) == type
+       /* If we're looking for a field in the most-derived class,
+          also check the field offset; we can have two base fields
+          of the same type if one is an indirect virtual base and one
+          is a direct non-virtual base.  */
+       && (BINFO_INHERITANCE_CHAIN (d_binfo)
+           || tree_int_cst_equal (byte_position (field),
+                                  BINFO_OFFSET (binfo))))
       {
        /* We don't use build_class_member_access_expr here, as that
           has unnecessary checks, and more importantly results in
@@ -530,7 +565,7 @@ convert_to_base (tree object, tree type, bool check_access, bool nonnull,
   if (!binfo || binfo == error_mark_node)
     return error_mark_node;
 
-  return build_base_path (PLUS_EXPR, object, binfo, nonnull);
+  return build_base_path (PLUS_EXPR, object, binfo, nonnull, complain);
 }
 
 /* EXPR is an expression with unqualified class type.  BASE is a base
@@ -546,21 +581,19 @@ convert_to_base_statically (tree expr, tree base)
   expr_type = TREE_TYPE (expr);
   if (!SAME_BINFO_TYPE_P (BINFO_TYPE (base), expr_type))
     {
-      tree pointer_type;
-
-      pointer_type = build_pointer_type (expr_type);
+      /* If this is a non-empty base, use a COMPONENT_REF.  */
+      if (!is_empty_class (BINFO_TYPE (base)))
+       return build_simple_base_path (expr, base);
 
       /* 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_unary_op (ADDR_EXPR, expr, /*noconvert=*/1, 
-                             tf_warning_or_error);
+      expr = cp_build_addr_expr (expr, tf_warning_or_error);
       if (!integer_zerop (BINFO_OFFSET (base)))
-        expr = fold_build2_loc (input_location,
-                           POINTER_PLUS_EXPR, pointer_type, expr,
-                           fold_convert (sizetype, BINFO_OFFSET (base)));
+        expr = fold_build_pointer_plus_loc (input_location,
+                                           expr, BINFO_OFFSET (base));
       expr = fold_convert (build_pointer_type (BINFO_TYPE (base)), expr);
       expr = build_fold_indirect_ref_loc (input_location, expr);
     }
@@ -659,8 +692,7 @@ build_vfn_ref (tree instance_ptr, tree idx)
      vtable entry is treated as a function pointer.  */
   if (TARGET_VTABLE_USES_DESCRIPTORS)
     aref = build1 (NOP_EXPR, TREE_TYPE (aref),
-                  cp_build_unary_op (ADDR_EXPR, aref, /*noconvert=*/1,
-                                   tf_warning_or_error));
+                  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);
@@ -686,21 +718,10 @@ get_vtable_name (tree type)
    the abstract.  */
 
 void
-set_linkage_according_to_type (tree type, tree decl)
+set_linkage_according_to_type (tree type ATTRIBUTE_UNUSED, tree decl)
 {
-  /* If TYPE involves a local class in a function with internal
-     linkage, then DECL should have internal linkage too.  Other local
-     classes have no linkage -- but if their containing functions
-     have external linkage, it makes sense for DECL to have external
-     linkage too.  That will allow template definitions to be merged,
-     for example.  */
-  if (no_linkage_check (type, /*relaxed_p=*/true))
-    {
-      TREE_PUBLIC (decl) = 0;
-      DECL_INTERFACE_KNOWN (decl) = 1;
-    }
-  else
-    TREE_PUBLIC (decl) = 1;
+  TREE_PUBLIC (decl) = 1;
+  determine_visibility (decl);
 }
 
 /* Create a VAR_DECL for a primary or secondary vtable for CLASS_TYPE.
@@ -1076,11 +1097,6 @@ add_method (tree type, tree method, tree 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);
            }
          else
            {
@@ -1102,6 +1118,8 @@ add_method (tree type, tree method, tree using_decl)
 
   /* Add the new binding.  */
   overload = build_overload (method, current_fns);
+  if (using_decl && TREE_CODE (overload) == OVERLOAD)
+    OVL_USED (overload) = true;
 
   if (conv_p)
     TYPE_HAS_CONVERSION (type) = 1;
@@ -1190,7 +1208,8 @@ handle_using_decl (tree using_decl, tree t)
 
   gcc_assert (!processing_template_decl && decl);
 
-  old_value = lookup_member (t, name, /*protect=*/0, /*want_type=*/false);
+  old_value = lookup_member (t, name, /*protect=*/0, /*want_type=*/false,
+                            tf_warning_or_error);
   if (old_value)
     {
       if (is_overloaded_fn (old_value))
@@ -1250,15 +1269,14 @@ check_bases (tree t,
             int* no_const_asn_ref_p)
 {
   int i;
-  int seen_non_virtual_nearly_empty_base_p;
+  bool seen_non_virtual_nearly_empty_base_p = 0;
+  int seen_tm_mask = 0;
   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 = TREE_CHAIN (field))
+    for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
       if (TREE_CODE (field) == FIELD_DECL)
        break;
 
@@ -1269,6 +1287,14 @@ 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.  */
@@ -1280,10 +1306,11 @@ check_bases (tree t,
         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))
@@ -1309,13 +1336,19 @@ 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_COMPLEX_DFLT (basetype);      
+      TYPE_HAS_COMPLEX_DFLT (t) |= (!TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype)
+                                   || TYPE_HAS_COMPLEX_DFLT (basetype));
 
       /*  A standard-layout class is a class that:
          ...
@@ -1336,7 +1369,7 @@ check_bases (tree t,
               members, or has no base classes with non-static data
               members */
            for (basefield = TYPE_FIELDS (basetype); basefield;
-                basefield = TREE_CHAIN (basefield))
+                basefield = DECL_CHAIN (basefield))
              if (TREE_CODE (basefield) == FIELD_DECL)
                {
                  if (field)
@@ -1346,6 +1379,23 @@ check_bases (tree t,
                  break;
                }
        }
+
+      /* Don't bother collecting tm attributes if transactional memory
+        support is not enabled.  */
+      if (flag_tm)
+       {
+         tree tm_attr = find_tm_attribute (TYPE_ATTRIBUTES (basetype));
+         if (tm_attr)
+           seen_tm_mask |= tm_attr_to_mask (tm_attr);
+       }
+    }
+
+  /* If one of the base classes had TM attributes, and the current class
+     doesn't define its own, then the current class inherits one.  */
+  if (seen_tm_mask && !find_tm_attribute (TYPE_ATTRIBUTES (t)))
+    {
+      tree tm_attr = tm_mask_to_attr (seen_tm_mask & -seen_tm_mask);
+      TYPE_ATTRIBUTES (t) = tree_cons (tm_attr, NULL, TYPE_ATTRIBUTES (t));
     }
 }
 
@@ -1508,12 +1558,31 @@ fixup_type_variants (tree t)
       TYPE_VFIELD (variants) = TYPE_VFIELD (t);
       TYPE_METHODS (variants) = TYPE_METHODS (t);
       TYPE_FIELDS (variants) = TYPE_FIELDS (t);
+    }
+}
 
-      /* All variants of a class have the same attributes.  */
+/* 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.  */
@@ -1539,7 +1608,8 @@ 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;
@@ -1593,7 +1663,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))
@@ -1666,10 +1736,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))
@@ -1798,7 +1868,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
@@ -1827,8 +1897,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.  */
@@ -2038,7 +2107,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;
@@ -2048,8 +2117,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,
@@ -2194,6 +2264,40 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
     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.  */
   virtual_base = NULL_TREE;
@@ -2218,36 +2322,6 @@ 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).  */
@@ -2267,7 +2341,6 @@ 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_loc (input_location,
                         convert (ssizetype,
                                  BINFO_OFFSET (TREE_VALUE (overrider))),
@@ -2280,6 +2353,8 @@ 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;
+
+  BV_LOST_PRIMARY (*virtuals) = lost;
 }
 
 /* Called from modify_all_vtables via dfs_walk.  */
@@ -2417,6 +2492,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:
 
@@ -2431,14 +2507,23 @@ 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.
@@ -2522,7 +2607,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;
@@ -2534,7 +2619,7 @@ finish_struct_anon (tree t)
        {
          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
@@ -2601,6 +2686,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,
@@ -2613,6 +2762,13 @@ add_implicitly_declared_members (tree t,
                                 int cant_have_const_cctor,
                                 int cant_have_const_assignment)
 {
+  bool move_ok = false;
+
+  if (cxx_dialect >= cxx0x && !CLASSTYPE_DESTRUCTORS (t)
+      && !TYPE_HAS_COPY_CTOR (t) && !TYPE_HAS_COPY_ASSIGN (t)
+      && !type_has_move_constructor (t) && !type_has_move_assign (t))
+    move_ok = true;
+
   /* Destructor.  */
   if (!CLASSTYPE_DESTRUCTORS (t))
     {
@@ -2635,62 +2791,41 @@ add_implicitly_declared_members (tree t,
     {
       TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1;
       CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1;
+      if (cxx_dialect >= cxx0x)
+       TYPE_HAS_CONSTEXPR_CTOR (t)
+         /* This might force the declaration.  */
+         = type_has_constexpr_default_constructor (t);
     }
 
   /* [class.ctor]
 
      If a class definition does not explicitly declare a copy
      constructor, one is declared implicitly.  */
-  if (! TYPE_HAS_INIT_REF (t) && ! TYPE_FOR_JAVA (t))
+  if (! TYPE_HAS_COPY_CTOR (t) && ! TYPE_FOR_JAVA (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;
+      if (move_ok)
+       CLASSTYPE_LAZY_MOVE_CTOR (t) = 1;
     }
 
-  /* Currently only lambdas get a lazy move ctor, but N2987 adds them for
-     other classes.  */
-  if (LAMBDA_TYPE_P (t))
-    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_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 (move_ok)
+       CLASSTYPE_LAZY_MOVE_ASSIGN (t) = 1;
     }
 
   /* We can't be lazy about declaring functions that might override
      a virtual function from a base class.  */
-  if (TYPE_POLYMORPHIC_P (t)
-      && (CLASSTYPE_LAZY_ASSIGNMENT_OP (t)
-         || CLASSTYPE_LAZY_DESTRUCTOR (t)))
-    {
-      tree binfo = TYPE_BINFO (t);
-      tree base_binfo;
-      int ix;
-      tree opname = ansi_assopname (NOP_EXPR);
-      for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ++ix)
-       {
-         tree bv;
-         for (bv = BINFO_VIRTUALS (base_binfo); bv; bv = TREE_CHAIN (bv))
-           {
-             tree fn = BV_FN (bv);
-             if (DECL_NAME (fn) == opname)
-               {
-                 if (CLASSTYPE_LAZY_ASSIGNMENT_OP (t))
-                   lazily_declare_fn (sfk_assignment_operator, t);
-               }
-             else if (DECL_DESTRUCTOR_P (fn)
-                      && CLASSTYPE_LAZY_DESTRUCTOR (t))
-               lazily_declare_fn (sfk_destructor, t);
-           }
-       }
-    }
+  declare_virt_assop_and_dtor (t);
 }
 
 /* Subroutine of finish_struct_1.  Recursively count the number of fields
@@ -2701,7 +2836,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)));
@@ -2718,7 +2853,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);
@@ -2754,11 +2889,14 @@ check_bitfield_decl (tree field)
     }
   else
     {
+      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)
        {
@@ -2813,17 +2951,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);
@@ -2836,38 +2974,54 @@ 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++11 or -std=gnu++11");
+             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_DFLT (t) |= TYPE_HAS_COMPLEX_DFLT (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)
     {
       /* `build_class_init_list' does not recognize
         non-FIELD_DECLs.  */
-      if (TREE_CODE (t) == UNION_TYPE && any_default_members != 0)
+      if (TREE_CODE (t) == UNION_TYPE && *any_default_members != 0)
        error ("multiple fields in union %qT initialized", t);
       *any_default_members = 1;
     }
@@ -2924,19 +3078,12 @@ check_field_decls (tree t, tree *access_decls,
       tree type = TREE_TYPE (x);
       int this_field_access;
 
-      next = &TREE_CHAIN (x);
+      next = &DECL_CHAIN (x);
 
       if (TREE_CODE (x) == USING_DECL)
        {
-         /* Prune the access declaration from the list of fields.  */
-         *field = TREE_CHAIN (x);
-
          /* Save the access declarations for our caller.  */
          *access_decls = tree_cons (NULL_TREE, x, *access_decls);
-
-         /* Since we've reset *FIELD there's no reason to skip to the
-            next field.  */
-         next = field;
          continue;
        }
 
@@ -2997,6 +3144,11 @@ check_field_decls (tree t, tree *access_decls,
       if (TREE_PRIVATE (x) || TREE_PROTECTED (x))
        CLASSTYPE_NON_AGGREGATE (t) = 1;
 
+      /* 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,
@@ -3019,7 +3171,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;
+         TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1;
+         TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) = 1;
        }
 
       type = strip_array_types (type);
@@ -3094,6 +3247,12 @@ check_field_decls (tree t, tree *access_decls,
                          no_const_asn_ref_p,
                          &any_default_members);
 
+      /* Now that we've removed bit-field widths from DECL_INITIAL,
+        anything left in DECL_INITIAL is an NSDMI that makes the class
+        non-aggregate.  */
+      if (DECL_INITIAL (x))
+       CLASSTYPE_NON_AGGREGATE (t) = true;
+
       /* If any field is const, the structure type is pseudo-const.  */
       if (CP_TYPE_CONST_P (type))
        {
@@ -3105,7 +3264,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;
+         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))
@@ -3142,22 +3302,30 @@ check_field_decls (tree t, tree *access_decls,
       && has_pointers
       && TYPE_HAS_USER_CONSTRUCTOR (t)
       && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
-      && !(TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t)))
+      && !(TYPE_HAS_COPY_CTOR (t) && TYPE_HAS_COPY_ASSIGN (t)))
     {
       warning (OPT_Weffc__, "%q#T has pointer data members", t);
 
-      if (! TYPE_HAS_INIT_REF (t))
+      if (! TYPE_HAS_COPY_CTOR (t))
        {
          warning (OPT_Weffc__,
                   "  but does not override %<%T(const %T&)%>", t, t);
-         if (!TYPE_HAS_ASSIGN_REF (t))
+         if (!TYPE_HAS_COPY_ASSIGN (t))
            warning (OPT_Weffc__, "  or %<operator=(const %T&)%>", t);
        }
-      else if (! TYPE_HAS_ASSIGN_REF (t))
+      else if (! TYPE_HAS_COPY_ASSIGN (t))
        warning (OPT_Weffc__,
                 "  but does not override %<operator=(const %T&)%>", t);
     }
 
+  /* Non-static data member initializers make the default constructor
+     non-trivial.  */
+  if (any_default_members)
+    {
+      TYPE_NEEDS_CONSTRUCTING (t) = true;
+      TYPE_HAS_COMPLEX_DFLT (t) = true;
+    }
+
   /* If any of the fields couldn't be packed, unset TYPE_PACKED.  */
   if (cant_pack)
     TYPE_PACKED (t) = 0;
@@ -3360,7 +3528,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;
@@ -3709,9 +3877,9 @@ build_base_field (record_layout_info rli, tree binfo,
             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;
+         DECL_CHAIN (decl) = *next_field;
          *next_field = decl;
-         next_field = &TREE_CHAIN (decl);
+         next_field = &DECL_CHAIN (decl);
        }
     }
   else
@@ -3823,7 +3991,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))
@@ -3836,7 +4004,9 @@ check_methods (tree t)
          if (DECL_PURE_VIRTUAL_P (x))
            VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (t), x);
        }
-      /* All user-provided destructors are non-trivial.  */
+      /* 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;
     }
@@ -3860,8 +4030,8 @@ build_clone (tree fn, tree name)
   /* Remember where this function came from.  */
   DECL_ABSTRACT_ORIGIN (clone) = fn;
   /* Make it easy to find the CLONE given the FN.  */
-  TREE_CHAIN (clone) = TREE_CHAIN (fn);
-  TREE_CHAIN (fn) = clone;
+  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)
@@ -3925,8 +4095,8 @@ build_clone (tree fn, tree name)
   /* 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_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.  */
@@ -3936,13 +4106,13 @@ build_clone (tree fn, tree name)
        DECL_HAS_VTT_PARM_P (clone) = 1;
       else
        {
-         TREE_CHAIN (DECL_ARGUMENTS (clone))
-           = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
+         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))
+  for (parms = DECL_ARGUMENTS (clone); parms; parms = DECL_CHAIN (parms))
     {
       DECL_CONTEXT (parms) = clone;
       cxx_dup_lang_specific_decl (parms);
@@ -4005,8 +4175,8 @@ clone_function_decl (tree fn, int update_method_vec_p)
   tree clone;
 
   /* Avoid inappropriate cloning.  */
-  if (TREE_CHAIN (fn)
-      && DECL_CLONED_FUNCTION_P (TREE_CHAIN (fn)))
+  if (DECL_CHAIN (fn)
+      && DECL_CLONED_FUNCTION_P (DECL_CHAIN (fn)))
     return;
 
   if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn))
@@ -4063,8 +4233,8 @@ adjust_clone_args (tree decl)
 {
   tree clone;
 
-  for (clone = TREE_CHAIN (decl); clone && DECL_CLONED_FUNCTION_P (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));
@@ -4146,6 +4316,142 @@ clone_constructors_and_destructors (tree t)
     clone_function_decl (OVL_CURRENT (fns), /*update_method_vec_p=*/1);
 }
 
+/* Subroutine of set_one_vmethod_tm_attributes.  Search base classes
+   of TYPE for virtual functions which FNDECL overrides.  Return a
+   mask of the tm attributes found therein.  */
+
+static int
+look_for_tm_attr_overrides (tree type, tree fndecl)
+{
+  tree binfo = TYPE_BINFO (type);
+  tree base_binfo;
+  int ix, found = 0;
+
+  for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ++ix)
+    {
+      tree o, basetype = BINFO_TYPE (base_binfo);
+
+      if (!TYPE_POLYMORPHIC_P (basetype))
+       continue;
+
+      o = look_for_overrides_here (basetype, fndecl);
+      if (o)
+       found |= tm_attr_to_mask (find_tm_attribute
+                                 (TYPE_ATTRIBUTES (TREE_TYPE (o))));
+      else
+       found |= look_for_tm_attr_overrides (basetype, fndecl);
+    }
+
+  return found;
+}
+
+/* Subroutine of set_method_tm_attributes.  Handle the checks and
+   inheritance for one virtual method FNDECL.  */
+
+static void
+set_one_vmethod_tm_attributes (tree type, tree fndecl)
+{
+  tree tm_attr;
+  int found, have;
+
+  found = look_for_tm_attr_overrides (type, fndecl);
+
+  /* If FNDECL doesn't actually override anything (i.e. T is the
+     class that first declares FNDECL virtual), then we're done.  */
+  if (found == 0)
+    return;
+
+  tm_attr = find_tm_attribute (TYPE_ATTRIBUTES (TREE_TYPE (fndecl)));
+  have = tm_attr_to_mask (tm_attr);
+
+  /* Intel STM Language Extension 3.0, Section 4.2 table 4:
+     tm_pure must match exactly, otherwise no weakening of
+     tm_safe > tm_callable > nothing.  */
+  /* ??? The tm_pure attribute didn't make the transition to the
+     multivendor language spec.  */
+  if (have == TM_ATTR_PURE)
+    {
+      if (found != TM_ATTR_PURE)
+       {
+         found &= -found;
+         goto err_override;
+       }
+    }
+  /* If the overridden function is tm_pure, then FNDECL must be.  */
+  else if (found == TM_ATTR_PURE && tm_attr)
+    goto err_override;
+  /* Look for base class combinations that cannot be satisfied.  */
+  else if (found != TM_ATTR_PURE && (found & TM_ATTR_PURE))
+    {
+      found &= ~TM_ATTR_PURE;
+      found &= -found;
+      error_at (DECL_SOURCE_LOCATION (fndecl),
+               "method overrides both %<transaction_pure%> and %qE methods",
+               tm_mask_to_attr (found));
+    }
+  /* If FNDECL did not declare an attribute, then inherit the most
+     restrictive one.  */
+  else if (tm_attr == NULL)
+    {
+      apply_tm_attr (fndecl, tm_mask_to_attr (found & -found));
+    }
+  /* Otherwise validate that we're not weaker than a function
+     that is being overridden.  */
+  else
+    {
+      found &= -found;
+      if (found <= TM_ATTR_CALLABLE && have > found)
+       goto err_override;
+    }
+  return;
+
+ err_override:
+  error_at (DECL_SOURCE_LOCATION (fndecl),
+           "method declared %qE overriding %qE method",
+           tm_attr, tm_mask_to_attr (found));
+}
+
+/* For each of the methods in T, propagate a class-level tm attribute.  */
+
+static void
+set_method_tm_attributes (tree t)
+{
+  tree class_tm_attr, fndecl;
+
+  /* Don't bother collecting tm attributes if transactional memory
+     support is not enabled.  */
+  if (!flag_tm)
+    return;
+
+  /* Process virtual methods first, as they inherit directly from the
+     base virtual function and also require validation of new attributes.  */
+  if (TYPE_CONTAINS_VPTR_P (t))
+    {
+      tree vchain;
+      for (vchain = BINFO_VIRTUALS (TYPE_BINFO (t)); vchain;
+          vchain = TREE_CHAIN (vchain))
+       {
+         fndecl = BV_FN (vchain);
+         if (DECL_THUNK_P (fndecl))
+           fndecl = THUNK_TARGET (fndecl);
+         set_one_vmethod_tm_attributes (t, fndecl);
+       }
+    }
+
+  /* If the class doesn't have an attribute, nothing more to do.  */
+  class_tm_attr = find_tm_attribute (TYPE_ATTRIBUTES (t));
+  if (class_tm_attr == NULL)
+    return;
+
+  /* Any method that does not yet have a tm attribute inherits
+     the one from the class.  */
+  for (fndecl = TYPE_METHODS (t); fndecl; fndecl = TREE_CHAIN (fndecl))
+    {
+      if (!find_tm_attribute (TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
+       apply_tm_attr (fndecl, class_tm_attr);
+    }
+}
+
 /* Returns true iff class T has a user-defined constructor other than
    the default constructor.  */
 
@@ -4258,6 +4564,204 @@ type_has_user_provided_default_constructor (tree t)
   return false;
 }
 
+/* If default-initialization leaves part of TYPE uninitialized, returns
+   a DECL for the field or TYPE itself (DR 253).  */
+
+tree
+default_init_uninitialized_part (tree type)
+{
+  tree t, r, binfo;
+  int i;
+
+  type = strip_array_types (type);
+  if (!CLASS_TYPE_P (type))
+    return type;
+  if (type_has_user_provided_default_constructor (type))
+    return NULL_TREE;
+  for (binfo = TYPE_BINFO (type), i = 0;
+       BINFO_BASE_ITERATE (binfo, i, t); ++i)
+    {
+      r = default_init_uninitialized_part (BINFO_TYPE (t));
+      if (r)
+       return r;
+    }
+  for (t = TYPE_FIELDS (type); t; t = DECL_CHAIN (t))
+    if (TREE_CODE (t) == FIELD_DECL
+       && !DECL_ARTIFICIAL (t)
+       && !DECL_INITIAL (t))
+      {
+       r = default_init_uninitialized_part (TREE_TYPE (t));
+       if (r)
+         return DECL_P (r) ? r : t;
+      }
+
+  return NULL_TREE;
+}
+
+/* Returns true iff for class T, a trivial synthesized default constructor
+   would be constexpr.  */
+
+bool
+trivial_default_constructor_is_constexpr (tree t)
+{
+  /* A defaulted trivial default constructor is constexpr
+     if there is nothing to initialize.  */
+  gcc_assert (!TYPE_HAS_COMPLEX_DFLT (t));
+  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))
+    {
+      if (!TYPE_HAS_COMPLEX_DFLT (t))
+       return trivial_default_constructor_is_constexpr (t);
+      /* Non-trivial, we need to check subobject constructors.  */
+      lazily_declare_fn (sfk_constructor, 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_nolazy (t, ansi_assopname (NOP_EXPR));
+       fns; fns = OVL_NEXT (fns))
+    if (move_fn_p (OVL_CURRENT (fns)))
+      return true;
+
+  return false;
+}
+
+/* Returns true iff class T has a move constructor that was explicitly
+   declared in the class body.  Note that this is different from
+   "user-provided", which doesn't include functions that are defaulted in
+   the class.  */
+
+bool
+type_has_user_declared_move_constructor (tree t)
+{
+  tree fns;
+
+  if (CLASSTYPE_LAZY_MOVE_CTOR (t))
+    return false;
+
+  if (!CLASSTYPE_METHOD_VEC (t))
+    return false;
+
+  for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+    {
+      tree fn = OVL_CURRENT (fns);
+      if (move_fn_p (fn) && !DECL_ARTIFICIAL (fn))
+       return true;
+    }
+
+  return false;
+}
+
+/* Returns true iff class T has a move assignment operator that was
+   explicitly declared in the class body.  */
+
+bool
+type_has_user_declared_move_assign (tree t)
+{
+  tree fns;
+
+  if (CLASSTYPE_LAZY_MOVE_ASSIGN (t))
+    return false;
+
+  for (fns = lookup_fnfields_slot_nolazy (t, ansi_assopname (NOP_EXPR));
+       fns; fns = OVL_NEXT (fns))
+    {
+      tree fn = OVL_CURRENT (fns);
+      if (move_fn_p (fn) && !DECL_ARTIFICIAL (fn))
+       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
@@ -4276,9 +4780,9 @@ remove_zero_width_bit_fields (tree t)
             check_bitfield_decl eventually sets DECL_SIZE (*fieldsp)
             to that width.  */
          && integer_zerop (DECL_SIZE (*fieldsp)))
-       *fieldsp = TREE_CHAIN (*fieldsp);
+       *fieldsp = DECL_CHAIN (*fieldsp);
       else
-       fieldsp = &TREE_CHAIN (*fieldsp);
+       fieldsp = &DECL_CHAIN (*fieldsp);
     }
 }
 
@@ -4338,6 +4842,108 @@ type_requires_array_cookie (tree type)
   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))
+    CLASSTYPE_LITERAL_P (t) = false;
+  else if (CLASSTYPE_LITERAL_P (t) && !TYPE_HAS_TRIVIAL_DFLT (t)
+          && CLASSTYPE_NON_AGGREGATE (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_GENERATED_P (fn))
+           {
+             error ("enclosing class of constexpr non-static member "
+                    "function %q+#D is not a literal type", fn);
+             explain_non_literal_class (t);
+           }
+       }
+}
+
+/* T is a non-literal type used in a context which requires a constant
+   expression.  Explain why it isn't literal.  */
+
+void
+explain_non_literal_class (tree t)
+{
+  static struct pointer_set_t *diagnosed;
+
+  if (!CLASS_TYPE_P (t))
+    return;
+  t = TYPE_MAIN_VARIANT (t);
+
+  if (diagnosed == NULL)
+    diagnosed = pointer_set_create ();
+  if (pointer_set_insert (diagnosed, t) != 0)
+    /* Already explained.  */
+    return;
+
+  inform (0, "%q+T is not literal because:", t);
+  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
+    inform (0, "  %q+T has a non-trivial destructor", t);
+  else if (CLASSTYPE_NON_AGGREGATE (t)
+          && !TYPE_HAS_TRIVIAL_DFLT (t)
+          && !TYPE_HAS_CONSTEXPR_CTOR (t))
+    {
+      inform (0, "  %q+T is not an aggregate, does not have a trivial "
+             "default constructor, and has no constexpr constructor that "
+             "is not a copy or move constructor", t);
+      if (TYPE_HAS_DEFAULT_CONSTRUCTOR (t)
+         && !type_has_user_provided_default_constructor (t))
+       explain_invalid_constexpr_fn (locate_ctor (t));
+    }
+  else
+    {
+      tree binfo, base_binfo, field; int i;
+      for (binfo = TYPE_BINFO (t), i = 0;
+          BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+       {
+         tree basetype = TREE_TYPE (base_binfo);
+         if (!CLASSTYPE_LITERAL_P (basetype))
+           {
+             inform (0, "  base class %qT of %q+T is non-literal",
+                     basetype, t);
+             explain_non_literal_class (basetype);
+             return;
+           }
+       }
+      for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
+       {
+         tree ftype;
+         if (TREE_CODE (field) != FIELD_DECL)
+           continue;
+         ftype = TREE_TYPE (field);
+         if (!literal_type_p (ftype))
+           {
+             inform (0, "  non-static data member %q+D has "
+                     "non-literal type", field);
+             if (CLASS_TYPE_P (ftype))
+               explain_non_literal_class (ftype);
+           }
+       }
+    }
+}
+
 /* 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
@@ -4373,7 +4979,7 @@ check_bases_and_members (tree 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_ASSIGN_REF (t);
+  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
@@ -4391,7 +4997,8 @@ 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_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;
@@ -4414,7 +5021,8 @@ check_bases_and_members (tree t)
     |= (CLASSTYPE_NON_AGGREGATE (t)
        || saved_nontrivial_dtor || saved_complex_asn_ref);
   CLASSTYPE_NON_STD_LAYOUT (t) |= TYPE_CONTAINS_VPTR_P (t);
-  TYPE_HAS_COMPLEX_ASSIGN_REF (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
@@ -4430,7 +5038,7 @@ check_bases_and_members (tree t)
     {
       tree field;
 
-      for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
+      for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
        {
          tree type;
 
@@ -4456,7 +5064,7 @@ check_bases_and_members (tree t)
 
   /* 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 = TREE_CHAIN (fn))
+  for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
     if (DECL_DEFAULTED_IN_CLASS_P (fn))
       {
        int copy = copy_fn_p (fn);
@@ -4484,15 +5092,18 @@ check_bases_and_members (tree 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_DEFAULT_CONSTRUCTOR (t) = 0;
-      CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 0;
-      TYPE_HAS_ASSIGN_REF (t) = 0;
-      CLASSTYPE_LAZY_ASSIGNMENT_OP (t) = 0;
+      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);
@@ -4523,7 +5134,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)
       {
@@ -4658,7 +5269,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
@@ -4899,9 +5510,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
@@ -4913,7 +5524,7 @@ 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;
@@ -5194,7 +5805,7 @@ 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 (input_location,
@@ -5207,7 +5818,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.  */
@@ -5254,7 +5865,7 @@ layout_class_type (tree t, tree *virtuals_p)
   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));
 
@@ -5286,7 +5897,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))
@@ -5298,6 +5909,22 @@ determine_key_method (tree type)
   return;
 }
 
+
+/* Allocate and return an instance of struct sorted_fields_type with
+   N fields.  */
+
+static struct sorted_fields_type *
+sorted_fields_type_new (int n)
+{
+  struct sorted_fields_type *sft;
+  sft = ggc_alloc_sorted_fields_type (sizeof (struct sorted_fields_type)
+                                     + n * sizeof (tree));
+  sft->len = n;
+
+  return sft;
+}
+
+
 /* Perform processing required when the definition of T (a class type)
    is complete.  */
 
@@ -5327,6 +5954,7 @@ finish_struct_1 (tree t)
   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.  */
@@ -5407,10 +6035,11 @@ finish_struct_1 (tree t)
     }
 
   finish_struct_bits (t);
+  set_method_tm_attributes (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))
@@ -5426,9 +6055,7 @@ finish_struct_1 (tree t)
   n_fields = count_fields (TYPE_FIELDS (t));
   if (n_fields > 7)
     {
-      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;
+      struct sorted_fields_type *field_vec = sorted_fields_type_new (n_fields);
       add_fields_to_record_type (TYPE_FIELDS (t), field_vec, 0);
       qsort (field_vec->elts, n_fields, sizeof (tree),
             field_decl_cmp);
@@ -5483,6 +6110,27 @@ finish_struct_1 (tree t)
 
   /* Finish debugging output for this type.  */
   rest_of_type_compilation (t, ! LOCAL_CLASS_P (t));
+
+  if (TYPE_TRANSPARENT_AGGR (t))
+    {
+      tree field = first_field (t);
+      if (field == NULL_TREE || error_operand_p (field))
+       {
+         error ("type transparent class %qT does not have any fields", t);
+         TYPE_TRANSPARENT_AGGR (t) = 0;
+       }
+      else if (DECL_ARTIFICIAL (field))
+       {
+         if (DECL_FIELD_IS_BASE (field))
+           error ("type transparent class %qT has base classes", t);
+         else
+           {
+             gcc_checking_assert (DECL_VIRTUAL_P (field));
+             error ("type transparent class %qT has virtual functions", t);
+           }
+         TYPE_TRANSPARENT_AGGR (t) = 0;
+       }
+    }
 }
 
 /* When T was built up, the member declarations were added in reverse
@@ -5507,13 +6155,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;
     }
@@ -5550,10 +6198,22 @@ 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);
+      /* We need to add the target functions to the CLASSTYPE_METHOD_VEC if
+        an enclosing scope is a template class, so that this function be
+        found by lookup_fnfields_1 when the using declaration is not
+        instantiated yet.  */
+      for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
+       if (TREE_CODE (x) == USING_DECL)
+         {
+           tree fn = strip_using_decl (x);
+           if (is_overloaded_fn (fn))
+             for (; fn; fn = OVL_NEXT (fn))
+               add_method (t, OVL_CURRENT (fn), x);
+         }
 
       /* Remember current #pragma pack value.  */
       TYPE_PRECISION (t) = maximum_field_alignment;
@@ -5675,10 +6335,13 @@ fixed_type_or_null (tree instance, int *nonnull, int *cdtorp)
          if (nonnull)
            *nonnull = 1;
 
-         /* if we're in a ctor or dtor, we know our type.  */
-         if (DECL_LANG_SPECIFIC (current_function_decl)
-             && (DECL_CONSTRUCTOR_P (current_function_decl)
-                 || DECL_DESTRUCTOR_P (current_function_decl)))
+         /* if we're in a ctor or dtor, we know our type.  If
+            current_class_ptr is set but we aren't in a function, we're in
+            an NSDMI (and therefore a constructor).  */
+         if (current_scope () != current_function_decl
+             || (DECL_LANG_SPECIFIC (current_function_decl)
+                 && (DECL_CONSTRUCTOR_P (current_function_decl)
+                     || DECL_DESTRUCTOR_P (current_function_decl))))
            {
              if (cdtorp)
                *cdtorp = 1;
@@ -5704,6 +6367,7 @@ fixed_type_or_null (tree instance, int *nonnull, int *cdtorp)
             itself.  */
          if (TREE_CODE (instance) == VAR_DECL
              && DECL_INITIAL (instance)
+             && !type_dependent_expression_p_push (DECL_INITIAL (instance))
              && !htab_find (ht, instance))
            {
              tree type;
@@ -5744,7 +6408,17 @@ resolves_to_fixed_type_p (tree instance, int* nonnull)
 {
   tree t = TREE_TYPE (instance);
   int cdtorp = 0;
-  tree fixed = fixed_type_or_null (instance, nonnull, &cdtorp);
+  tree fixed;
+
+  if (processing_template_decl)
+    {
+      /* In a template we only care about the type of the result.  */
+      if (nonnull)
+       *nonnull = true;
+      return true;
+    }
+
+  fixed = fixed_type_or_null (instance, nonnull, &cdtorp);
   if (fixed == NULL_TREE)
     return 0;
   if (POINTER_TYPE_P (t))
@@ -6241,7 +6915,7 @@ resolve_address_of_overloaded_function (tree target_type,
          targs = make_tree_vec (DECL_NTPARMS (fn));
          if (fn_type_unification (fn, explicit_targs, targs, args, nargs,
                                   target_ret_type, DEDUCE_EXACT,
-                                  LOOKUP_NORMAL))
+                                  LOOKUP_NORMAL, false))
            /* Argument deduction failed.  */
            continue;
 
@@ -6278,14 +6952,7 @@ resolve_address_of_overloaded_function (tree target_type,
                 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;
     }
@@ -6363,7 +7030,7 @@ resolve_address_of_overloaded_function (tree target_type,
     }
 
   if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
-    return cp_build_unary_op (ADDR_EXPR, fn, 0, flags);
+    return cp_build_addr_expr (fn, flags);
   else
     {
       /* The target must be a REFERENCE_TYPE.  Above, cp_build_unary_op
@@ -6413,13 +7080,13 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
       else
        {
          if (flags & tf_error)
-           error ("argument of type %qT does not match %qT",
-                  TREE_TYPE (rhs), lhstype);
+           error ("cannot convert %qE from type %qT to type %qT",
+                  rhs, TREE_TYPE (rhs), lhstype);
          return error_mark_node;
        }
     }
 
-  if (TREE_CODE (rhs) == BASELINK)
+  if (BASELINK_P (rhs))
     {
       access_path = BASELINK_ACCESS_BINFO (rhs);
       rhs = BASELINK_FUNCTIONS (rhs);
@@ -6572,7 +7239,7 @@ build_self_reference (void)
   DECL_CONTEXT (value) = current_class_type;
   DECL_ARTIFICIAL (value) = 1;
   SET_DECL_SELF_REFERENCE_P (value);
-  cp_set_underlying_type (value);
+  set_underlying_type (value);
 
   if (processing_template_decl)
     value = push_template_decl (value);
@@ -6632,13 +7299,11 @@ contains_empty_class_p (tree type)
 }
 
 /* Returns true if TYPE contains no actual data, just various
-   possible combinations of empty classes.  */
+   possible combinations of empty classes and possibly a vptr.  */
 
 bool
 is_really_empty_class (tree type)
 {
-  if (is_empty_class (type))
-    return true;
   if (CLASS_TYPE_P (type))
     {
       tree field;
@@ -6646,11 +7311,16 @@ is_really_empty_class (tree type)
       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 = TREE_CHAIN (field))
+      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)))
@@ -6679,7 +7349,7 @@ maybe_note_name_used_in_class (tree name, tree decl)
   /* If there's already a binding for this NAME, then we don't have
      anything to worry about.  */
   if (lookup_member (current_class_type, name,
-                    /*protect=*/0, /*want_type=*/false))
+                    /*protect=*/0, /*want_type=*/false, tf_warning_or_error))
     return;
 
   if (!current_class_stack[current_class_depth - 1].names_used)
@@ -6706,7 +7376,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)
     {
@@ -7096,15 +7772,15 @@ build_vtt (tree t)
     return;
 
   /* Figure out the type of the VTT.  */
-  type = build_index_type (size_int (VEC_length (constructor_elt, 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, 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);
 }
@@ -7352,8 +8028,8 @@ build_ctor_vtbl_group (tree binfo, tree t)
     }
 
   /* Figure out the type of the construction vtable.  */
-  type = build_index_type (size_int (VEC_length (constructor_elt, v) - 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;
@@ -7502,13 +8178,10 @@ dfs_accumulate_vtbl_inits (tree binfo,
 
       /* Figure out the position to which the VPTR should point.  */
       vtbl = build1 (ADDR_EXPR, vtbl_ptr_type_node, orig_vtbl);
-      index = size_binop (PLUS_EXPR,
-                         size_int (non_fn_entries),
-                         size_int (n_inits));
       index = size_binop (MULT_EXPR,
                          TYPE_SIZE_UNIT (vtable_entry_type),
-                         index);
-      vtbl = build2 (POINTER_PLUS_EXPR, TREE_TYPE (vtbl), vtbl, index);
+                         size_int (non_fn_entries + n_inits));
+      vtbl = fold_build_pointer_plus (vtbl, index);
     }
 
   if (ctor_vtbl_p)
@@ -7557,7 +8230,7 @@ build_vtbl_initializer (tree binfo,
                        int* non_fn_entries_p,
                        VEC(constructor_elt,gc) **inits)
 {
-  tree v, b;
+  tree v;
   vtbl_init_data vid;
   unsigned ix, jx;
   tree vbinfo;
@@ -7607,14 +8280,15 @@ build_vtbl_initializer (tree binfo,
           ix--)
        {
          int j;
-         int new_position = TARGET_VTABLE_DATA_ENTRY_DISTANCE * ix;
+         int new_position = (TARGET_VTABLE_DATA_ENTRY_DISTANCE * ix
+                             + (TARGET_VTABLE_DATA_ENTRY_DISTANCE - 1));
 
          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, *inits,
-                                             new_position + 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);
@@ -7670,20 +8344,8 @@ build_vtbl_initializer (tree binfo,
         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)
        {
@@ -7700,9 +8362,26 @@ 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;
+               }
+           }
+         /* Likewise for deleted virtuals.  */
+         else if (DECL_DELETED_FN (fn_original))
+           {
+             fn = get_identifier ("__cxa_deleted_virtual");
+             if (!get_global_value_if_present (fn, &fn))
+               fn = push_library_fn (fn, (build_function_type_list
+                                          (void_type_node, NULL_TREE)),
+                                     NULL_TREE);
+             if (!TARGET_VTABLE_USES_DESCRIPTORS)
+               init = fold_convert (vfunc_ptr_type_node,
+                                    build_fold_addr_expr (fn));
            }
          else
            {
@@ -7714,7 +8393,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));
            }
        }
 
@@ -7729,8 +8410,7 @@ build_vtbl_initializer (tree binfo,
            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;
 
                CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, fdesc);
@@ -7945,7 +8625,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);
     }
@@ -8029,7 +8709,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,
@@ -8067,8 +8747,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);
@@ -8138,34 +8817,4 @@ build_rtti_vtbl_entries (tree binfo, vtbl_init_data* vid)
   CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, 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);
-}
-
 #include "gt-cp-class.h"