This is the biggest chunk, in the C++ FE.

The only quirk is a hopefully short-lived additional check when looking up a non-function member in an incomplete type. We iterate over TYPE_FIELDS, and should now ignore things that are functions -- because we'll find them as overloads when looking at the method-vector. That's a subsequent cleanup.

nathan
--
Nathan Sidwell
2017-07-14  Nathan Sidwell  <nat...@acm.org>

        gcc/cp/
        * class.c (maybe_warn_about_overly_private_class,
        finish_struct_methods, one_inheriting_sig, count_fields,
        add_fields_to_record_type, check_field_decls, check_methods,
        clone_function_decl, set_method_tm_attributes,
        finalize_literal_type_property, check_bases_and_members,
        create_vtable_ptr, determine_key_method,
        unreverse_member_declarations, finish_struct,
        add_vcall_offset_vtbl_entries_1): Member fns are on TYPE_FIELDS.
        * decl.c (fixup_anonymous_aggr): Likewise.
        * decl2.c (reset_type_linkage_2): Likewise.
        * method.c (after_nsdmi_defaulted_late_checks,
        lazily_declare_fn): Likewise.
        * optimize.c (maybe_thunk_body, maybe_clone_body): Likewise.
        * pt.c (instantiate_class_template_1, tsubst_expr,
        do_type_instantiation, instantiate_pending_templates): Likewise.
        * search.c (lookup_field_1): Likewise.
        * semantics.c (finish_member_declaration,
        finish_omp_declare_simd_methods): Likewise.

        gcc/testsuite/
        * g++.dg/ext/anon-struct6.C: Adjust diag.
        * g++.old-deja/g++.other/anon4.C: Adjust diag.

Index: gcc/cp/class.c
===================================================================
--- gcc/cp/class.c      (revision 250160)
+++ gcc/cp/class.c      (working copy)
@@ -2149,7 +2149,6 @@ maybe_warn_about_overly_private_class (t
 {
   int has_member_fn = 0;
   int has_nonprivate_method = 0;
-  tree fn;
 
   if (!warn_ctor_dtor_privacy
       /* If the class has friends, those entities might create and
@@ -2179,26 +2178,26 @@ maybe_warn_about_overly_private_class (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 = 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))
+  for (tree fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
+    if (!DECL_DECLARES_FUNCTION_P (fn))
+      /* Not a function.  */;
+    else if (DECL_ARTIFICIAL (fn))
+      /* We're not interested in compiler-generated methods; they don't
+        provide any way to call private members.  */;
+    else if (!TREE_PRIVATE (fn))
       {
-       if (!TREE_PRIVATE (fn))
-         {
-           if (DECL_STATIC_FUNCTION_P (fn))
-             /* A non-private static member function is just like a
-                friend; it can create and invoke private member
-                functions, and be accessed without a class
-                instance.  */
-             return;
+       if (DECL_STATIC_FUNCTION_P (fn))
+         /* A non-private static member function is just like a
+            friend; it can create and invoke private member
+            functions, and be accessed without a class
+            instance.  */
+         return;
 
-           has_nonprivate_method = 1;
-           /* Keep searching for a static member function.  */
-         }
-       else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn))
-         has_member_fn = 1;
+       has_nonprivate_method = 1;
+       /* Keep searching for a static member function.  */
       }
+    else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn))
+      has_member_fn = 1;
 
   if (!has_nonprivate_method && has_member_fn)
     {
@@ -2228,14 +2227,14 @@ maybe_warn_about_overly_private_class (t
   /* Even if some of the member functions are non-private, the class
      won't be useful for much if all the constructors or destructors
      are private: such an object can never be created or destroyed.  */
-  fn = CLASSTYPE_DESTRUCTOR (t);
-  if (fn && TREE_PRIVATE (fn))
-    {
-      warning (OPT_Wctor_dtor_privacy,
-              "%q#T only defines a private destructor and has no friends",
-              t);
-      return;
-    }
+  if (tree dtor = CLASSTYPE_DESTRUCTOR (t))
+    if (TREE_PRIVATE (dtor))
+      {
+       warning (OPT_Wctor_dtor_privacy,
+                "%q#T only defines a private destructor and has no friends",
+                t);
+       return;
+      }
 
   /* Warn about classes that have private constructors and no friends.  */
   if (TYPE_HAS_USER_CONSTRUCTOR (t)
@@ -2367,7 +2366,6 @@ resort_type_method_vec (void* obj,
 static void
 finish_struct_methods (tree t)
 {
-  tree fn_fields;
   vec<tree, va_gc> *method_vec;
   int slot, len;
 
@@ -2378,9 +2376,9 @@ finish_struct_methods (tree t)
   len = method_vec->length ();
 
   /* Clear DECL_IN_AGGR_P for all functions.  */
-  for (fn_fields = TYPE_METHODS (t); fn_fields;
-       fn_fields = DECL_CHAIN (fn_fields))
-    DECL_IN_AGGR_P (fn_fields) = 0;
+  for (tree fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
+    if (DECL_DECLARES_FUNCTION_P (fn))
+      DECL_IN_AGGR_P (fn) = false;
 
   /* Issue warnings about private constructors and such.  If there are
      no methods, then some public defaults are generated.  */
@@ -2388,6 +2386,7 @@ finish_struct_methods (tree t)
 
   /* The type conversion ops have to live at the front of the vec, so we
      can't sort them.  */
+  tree fn_fields;
   for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
        method_vec->iterate (slot, &fn_fields);
        ++slot)
@@ -3299,6 +3298,8 @@ declare_virt_assop_and_dtor (tree t)
 static void
 one_inheriting_sig (tree t, tree ctor, tree *parms, int nparms)
 {
+  gcc_assert (TYPE_MAIN_VARIANT (t) == t);
+
   /* We don't declare an inheriting ctor that would be a default,
      copy or move ctor for derived or base.  */
   if (nparms == 0)
@@ -3316,11 +3317,11 @@ one_inheriting_sig (tree t, tree ctor, t
     parmlist = tree_cons (NULL_TREE, parms[i], parmlist);
   tree fn = implicitly_declare_fn (sfk_inheriting_constructor,
                                   t, false, ctor, parmlist);
-  gcc_assert (TYPE_MAIN_VARIANT (t) == t);
+
   if (add_method (t, fn, false))
     {
-      DECL_CHAIN (fn) = TYPE_METHODS (t);
-      TYPE_METHODS (t) = fn;
+      DECL_CHAIN (fn) = TYPE_FIELDS (t);
+      TYPE_FIELDS (t) = fn;
     }
 }
 
@@ -3459,7 +3460,9 @@ count_fields (tree fields)
   int n_fields = 0;
   for (x = fields; x; x = DECL_CHAIN (x))
     {
-      if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x)))
+      if (DECL_DECLARES_FUNCTION_P (x))
+       /* Functions are dealt with separately.  */;
+      else if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x)))
        n_fields += count_fields (TYPE_FIELDS (TREE_TYPE (x)));
       else
        n_fields += 1;
@@ -3477,7 +3480,9 @@ add_fields_to_record_type (tree fields,
   tree x;
   for (x = fields; x; x = DECL_CHAIN (x))
     {
-      if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x)))
+      if (DECL_DECLARES_FUNCTION_P (x))
+       /* Functions are handled separately.  */;
+      else 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);
       else
        field_vec->elts[idx++] = x;
@@ -3734,6 +3739,10 @@ check_field_decls (tree t, tree *access_
          || TREE_CODE (x) == TEMPLATE_DECL)
        continue;
 
+      if (TREE_CODE (x) == FUNCTION_DECL)
+       /* FIXME: We should fold in the checking from check_methods.  */
+       continue;
+
       /* If we've gotten this far, it's a data member, possibly static,
         or an enumerator.  */
       if (TREE_CODE (x) != CONST_DECL)
@@ -4658,39 +4667,42 @@ build_base_fields (record_layout_info rl
     }
 }
 
-/* Go through the TYPE_METHODS of T issuing any appropriate
+/* Go through the TYPE_FIELDS of T issuing any appropriate
    diagnostics, figuring out which methods override which other
    methods, and so forth.  */
 
 static void
 check_methods (tree t)
 {
-  tree x;
+  for (tree x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
+    if (DECL_DECLARES_FUNCTION_P (x))
+      {
+       check_for_override (x, t);
 
-  for (x = TYPE_METHODS (t); x; x = DECL_CHAIN (x))
-    {
-      check_for_override (x, t);
-      if (DECL_PURE_VIRTUAL_P (x) && (TREE_CODE (x) != FUNCTION_DECL || ! 
DECL_VINDEX (x)))
-       error ("initializer specified for non-virtual method %q+D", x);
-      /* The name of the field is the original field name
-        Save this in auxiliary field for later overloading.  */
-      if (TREE_CODE (x) == FUNCTION_DECL && DECL_VINDEX (x))
-       {
-         TYPE_POLYMORPHIC_P (t) = 1;
-         if (DECL_PURE_VIRTUAL_P (x))
-           vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), 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;
-      if (!DECL_VIRTUAL_P (x)
-         && lookup_attribute ("transaction_safe_dynamic", DECL_ATTRIBUTES (x)))
-       error_at (DECL_SOURCE_LOCATION (x),
-                 "%<transaction_safe_dynamic%> may only be specified for "
-                 "a virtual function");
-    }
+       if (DECL_PURE_VIRTUAL_P (x)
+           && (TREE_CODE (x) != FUNCTION_DECL || ! DECL_VINDEX (x)))
+         error ("initializer specified for non-virtual method %q+D", x);
+       /* The name of the field is the original field name
+          Save this in auxiliary field for later overloading.  */
+       if (TREE_CODE (x) == FUNCTION_DECL && DECL_VINDEX (x))
+         {
+           TYPE_POLYMORPHIC_P (t) = 1;
+           if (DECL_PURE_VIRTUAL_P (x))
+             vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), 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;
+       if (!DECL_VIRTUAL_P (x)
+           && lookup_attribute ("transaction_safe_dynamic",
+                                DECL_ATTRIBUTES (x)))
+         error_at (DECL_SOURCE_LOCATION (x),
+                   "%<transaction_safe_dynamic%> may only be specified for "
+                   "a virtual function");
+      }
 }
 
 /* FN is a constructor or destructor.  Clone the declaration to create
@@ -4896,7 +4908,7 @@ clone_function_decl (tree fn, bool updat
       /* For each destructor, we need three variants: an in-charge
         version, a not-in-charge version, and an in-charge deleting
         version.  We clone the deleting version first because that
-        means it will go second on the TYPE_METHODS list -- and that
+        means it will go second on the TYPE_FIELDS list -- and that
         corresponds to the correct layout order in the virtual
         function table.
 
@@ -5168,11 +5180,10 @@ set_method_tm_attributes (tree t)
 
   /* 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);
-    }
+  for (fndecl = TYPE_FIELDS (t); fndecl; fndecl = DECL_CHAIN (fndecl))
+    if (DECL_DECLARES_FUNCTION_P (fndecl)
+       && !find_tm_attribute (TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
+      apply_tm_attr (fndecl, class_tm_attr);
 }
 
 /* Returns true if FN is a default constructor.  */
@@ -5705,9 +5716,9 @@ finalize_literal_type_property (tree t)
   /* C++14 DR 1684 removed this restriction.  */
   if (cxx_dialect < cxx14
       && !CLASSTYPE_LITERAL_P (t) && !LAMBDA_TYPE_P (t))
-    for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
-      if (DECL_DECLARED_CONSTEXPR_P (fn)
-         && TREE_CODE (fn) != TEMPLATE_DECL
+    for (fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
+      if (TREE_CODE (fn) == FUNCTION_DECL
+         && DECL_DECLARED_CONSTEXPR_P (fn)
          && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
          && !DECL_CONSTRUCTOR_P (fn))
        {
@@ -5969,8 +5980,10 @@ 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 = DECL_CHAIN (fn))
-    if (!DECL_ARTIFICIAL (fn) && DECL_DEFAULTED_IN_CLASS_P (fn))
+  for (fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
+    if (DECL_DECLARES_FUNCTION_P (fn)
+       && !DECL_ARTIFICIAL (fn)
+       && DECL_DEFAULTED_IN_CLASS_P (fn))
       {
        int copy = copy_fn_p (fn);
        if (copy > 0)
@@ -6029,7 +6042,7 @@ create_vtable_ptr (tree t, tree* virtual
   tree fn;
 
   /* Collect the virtual functions declared in T.  */
-  for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
+  for (fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
     if (TREE_CODE (fn) == FUNCTION_DECL
        && DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)
        && TREE_CODE (DECL_VINDEX (fn)) != INTEGER_CST)
@@ -6688,8 +6701,7 @@ determine_key_method (tree type)
      inline at the point of class definition.  On some targets the
      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 = DECL_CHAIN (method))
+  for (method = TYPE_FIELDS (type); method; method = DECL_CHAIN (method))
     if (TREE_CODE (method) == FUNCTION_DECL
        && DECL_VINDEX (method) != NULL_TREE
        && ! DECL_DECLARED_INLINE_P (method)
@@ -7381,11 +7393,11 @@ unreverse_member_declarations (tree t)
 
   /* The following lists are all in reverse order.  Put them in
      declaration order now.  */
-  TYPE_METHODS (t) = nreverse (TYPE_METHODS (t));
   CLASSTYPE_DECL_LIST (t) = nreverse (CLASSTYPE_DECL_LIST (t));
 
-  /* Actually, for the TYPE_FIELDS, only the non TYPE_DECLs are in
-     reverse order, so we can't just use nreverse.  */
+  /* For the TYPE_FIELDS, only the non TYPE_DECLs are in reverse
+     order, so we can't just use nreverse.  Due to stat_hack
+     chicanery in finish_member_declarations.  */
   prev = NULL_TREE;
   for (x = TYPE_FIELDS (t);
        x && TREE_CODE (x) != TYPE_DECL;
@@ -7395,6 +7407,7 @@ unreverse_member_declarations (tree t)
       DECL_CHAIN (x) = prev;
       prev = x;
     }
+
   if (prev)
     {
       DECL_CHAIN (TYPE_FIELDS (t)) = x;
@@ -7435,8 +7448,8 @@ 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 = DECL_CHAIN (x))
-       if (DECL_PURE_VIRTUAL_P (x))
+      for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
+       if (TREE_CODE (x) == FUNCTION_DECL && DECL_PURE_VIRTUAL_P (x))
          vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), x);
       complete_vars (t);
       /* We need to add the target functions to the CLASSTYPE_METHOD_VEC if
@@ -7461,7 +7474,6 @@ finish_struct (tree t, tree attributes)
          TYPE_SIZE (x) = TYPE_SIZE (t);
          TYPE_SIZE_UNIT (x) = TYPE_SIZE_UNIT (t);
          TYPE_FIELDS (x) = TYPE_FIELDS (t);
-         TYPE_METHODS (x) = TYPE_METHODS (t);
        }
     }
   else
@@ -9967,7 +9979,7 @@ add_vcall_offset_vtbl_entries_1 (tree bi
 
   /* The ABI requires that the methods be processed in declaration
      order.  */
-  for (orig_fn = TYPE_METHODS (BINFO_TYPE (binfo));
+  for (orig_fn = TYPE_FIELDS (BINFO_TYPE (binfo));
        orig_fn;
        orig_fn = DECL_CHAIN (orig_fn))
     if (TREE_CODE (orig_fn) == FUNCTION_DECL && DECL_VINDEX (orig_fn))
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c       (revision 250160)
+++ gcc/cp/decl.c       (working copy)
@@ -4549,8 +4549,6 @@ push_throw_library_fn (tree name, tree t
 void
 fixup_anonymous_aggr (tree t)
 {
-  tree *q;
-
   /* Wipe out memory of synthesized methods.  */
   TYPE_HAS_USER_CONSTRUCTOR (t) = 0;
   TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 0;
@@ -4559,29 +4557,12 @@ fixup_anonymous_aggr (tree t)
   TYPE_HAS_COPY_ASSIGN (t) = 0;
   TYPE_HAS_CONST_COPY_ASSIGN (t) = 0;
 
-  /* Splice the implicitly generated functions out of the TYPE_METHODS
-     list.  */
-  q = &TYPE_METHODS (t);
-  while (*q)
-    {
-      if (DECL_ARTIFICIAL (*q))
-       *q = TREE_CHAIN (*q);
-      else
-       q = &DECL_CHAIN (*q);
-    }
-
-  /* ISO C++ 9.5.3.  Anonymous unions may not have function members.  */
-  if (TYPE_METHODS (t))
-    {
-      tree decl = TYPE_MAIN_DECL (t);
-
-      if (TREE_CODE (t) != UNION_TYPE)
-       error_at (DECL_SOURCE_LOCATION (decl), 
-                 "an anonymous struct cannot have function members");
-      else
-       error_at (DECL_SOURCE_LOCATION (decl),
-                 "an anonymous union cannot have function members");
-    }
+  /* Splice the implicitly generated functions out of TYPE_FIELDS.  */
+  for (tree probe, *prev_p = &TYPE_FIELDS (t); (probe = *prev_p);)
+    if (TREE_CODE (probe) == FUNCTION_DECL && DECL_ARTIFICIAL (probe))
+      *prev_p = DECL_CHAIN (probe);
+    else
+      prev_p = &DECL_CHAIN (probe);
 
   /* Anonymous aggregates cannot have fields with ctors, dtors or complex
      assignment operators (because they cannot have these methods themselves).
Index: gcc/cp/decl2.c
===================================================================
--- gcc/cp/decl2.c      (revision 250160)
+++ gcc/cp/decl2.c      (working copy)
@@ -2592,6 +2592,7 @@ reset_decl_linkage (tree decl)
   determine_visibility (decl);
   tentative_decl_linkage (decl);
 }
+
 static void
 reset_type_linkage_2 (tree type)
 {
@@ -2615,18 +2616,14 @@ reset_type_linkage_2 (tree type)
       for (tree m = TYPE_FIELDS (type); m; m = DECL_CHAIN (m))
        {
          tree mem = STRIP_TEMPLATE (m);
-         if (VAR_P (mem))
+         if (TREE_CODE (mem) == VAR_DECL || TREE_CODE (mem) == FUNCTION_DECL)
            reset_decl_linkage (mem);
        }
-      for (tree m = TYPE_METHODS (type); m; m = DECL_CHAIN (m))
-       {
-         tree mem = STRIP_TEMPLATE (m);
-         reset_decl_linkage (mem);
-       }
       binding_table_foreach (CLASSTYPE_NESTED_UTDS (type),
                             bt_reset_linkage_2, NULL);
     }
 }
+
 static void
 bt_reset_linkage_2 (binding_entry b, void */*data*/)
 {
@@ -4997,19 +4994,13 @@ mark_used (tree decl, tsubst_flags_t com
   if (TREE_CODE (decl) == FUNCTION_DECL
       && DECL_DELETED_FN (decl))
     {
-      if (DECL_ARTIFICIAL (decl))
-       {
-         if (DECL_OVERLOADED_OPERATOR_P (decl) == TYPE_EXPR
-             && LAMBDA_TYPE_P (DECL_CONTEXT (decl)))
-           {
-             /* We mark a lambda conversion op as deleted if we can't
-                generate it properly; see maybe_add_lambda_conv_op.  */
-             sorry ("converting lambda which uses %<...%> to "
-                    "function pointer");
-             return false;
-           }
-       }
-      if (complain & tf_error)
+      if (DECL_ARTIFICIAL (decl)
+         && DECL_OVERLOADED_OPERATOR_P (decl) == TYPE_EXPR
+         && LAMBDA_TYPE_P (DECL_CONTEXT (decl)))
+       /* We mark a lambda conversion op as deleted if we can't
+          generate it properly; see maybe_add_lambda_conv_op.  */
+       sorry ("converting lambda which uses %<...%> to function pointer");
+      else if (complain & tf_error)
        {
          error ("use of deleted function %qD", decl);
          if (!maybe_explain_implicit_delete (decl))
Index: gcc/cp/method.c
===================================================================
--- gcc/cp/method.c     (revision 250160)
+++ gcc/cp/method.c     (working copy)
@@ -2248,8 +2248,10 @@ after_nsdmi_defaulted_late_checks (tree
     return;
   if (t == error_mark_node)
     return;
-  for (tree fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
-    if (!DECL_ARTIFICIAL (fn) && DECL_DEFAULTED_IN_CLASS_P (fn))
+  for (tree fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
+    if (!DECL_ARTIFICIAL (fn)
+       && DECL_DECLARES_FUNCTION_P (fn)
+       && DECL_DEFAULTED_IN_CLASS_P (fn))
       {
        tree fn_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
        if (UNEVALUATED_NOEXCEPT_SPEC_P (fn_spec))
@@ -2383,20 +2385,25 @@ lazily_declare_fn (special_function_kind
       || sfk == sfk_move_assignment
       || sfk == sfk_copy_assignment)
     check_for_override (fn, type);
+
   /* Add it to CLASSTYPE_METHOD_VEC.  */
   bool added = add_method (type, fn, false);
   gcc_assert (added);
-  /* Add it to TYPE_METHODS.  */
+
+  /* Add it to TYPE_FIELDS.  */
   if (sfk == sfk_destructor
       && DECL_VIRTUAL_P (fn))
     /* The ABI requires that a virtual destructor go at the end of the
        vtable.  */
-    TYPE_METHODS (type) = chainon (TYPE_METHODS (type), fn);
+    TYPE_FIELDS (type) = chainon (TYPE_FIELDS (type), fn);
   else
     {
-      DECL_CHAIN (fn) = TYPE_METHODS (type);
-      TYPE_METHODS (type) = fn;
+      DECL_CHAIN (fn) = TYPE_FIELDS (type);
+      TYPE_FIELDS (type) = fn;
     }
+  /* Propagate TYPE_FIELDS.  */
+  fixup_type_variants (type);
+
   maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0);
   if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
       || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
Index: gcc/cp/optimize.c
===================================================================
--- gcc/cp/optimize.c   (revision 250160)
+++ gcc/cp/optimize.c   (working copy)
@@ -326,7 +326,7 @@ maybe_thunk_body (tree fn, bool force)
     }
   args = XALLOCAVEC (tree, max_parms);
 
-  /* We know that any clones immediately follow FN in TYPE_METHODS.  */
+  /* We know that any clones immediately follow FN in TYPE_FIELDS.  */
   FOR_EACH_CLONE (clone, fn)
     {
       tree clone_parm;
@@ -447,7 +447,7 @@ maybe_clone_body (tree fn)
   if (!tree_versionable_function_p (fn))
     need_alias = true;
 
-  /* We know that any clones immediately follow FN in the TYPE_METHODS
+  /* We know that any clones immediately follow FN in the TYPE_FIELDS
      list.  */
   push_to_top_level ();
   for (idx = 0; idx < 3; idx++)
@@ -516,7 +516,7 @@ maybe_clone_body (tree fn)
   /* Emit the DWARF1 abstract instance.  */
   (*debug_hooks->deferred_inline_function) (fn);
 
-  /* We know that any clones immediately follow FN in the TYPE_METHODS list. */
+  /* We know that any clones immediately follow FN in the TYPE_FIELDS. */
   for (idx = 0; idx < 3; idx++)
     {
       tree parm;
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c (revision 250160)
+++ gcc/cp/pt.c (working copy)
@@ -10550,7 +10550,6 @@ instantiate_class_template_1 (tree type)
            }
          else if (DECL_DECLARES_FUNCTION_P (t))
            {
-             /* Build new TYPE_METHODS.  */
              tree r;
 
              if (TREE_CODE (t) == TEMPLATE_DECL)
@@ -16136,13 +16135,15 @@ tsubst_expr (tree t, tree args, tsubst_f
             instantiated along with their containing function.  And this
             way we don't have to deal with pushing out of one local class
             to instantiate a member of another local class.  */
-         tree fn;
          /* Closures are handled by the LAMBDA_EXPR.  */
          gcc_assert (!LAMBDA_TYPE_P (TREE_TYPE (t)));
          complete_type (tmp);
-         for (fn = TYPE_METHODS (tmp); fn; fn = DECL_CHAIN (fn))
-           if (!DECL_ARTIFICIAL (fn))
-             instantiate_decl (fn, /*defer_ok=*/false,
+         for (tree fld = TYPE_FIELDS (tmp); fld; fld = DECL_CHAIN (fld))
+           if ((VAR_P (fld)
+                || (TREE_CODE (fld) == FUNCTION_DECL
+                    && !DECL_ARTIFICIAL (fld)))
+               && DECL_TEMPLATE_INSTANTIATION (fld))
+             instantiate_decl (fld, /*defer_ok=*/false,
                                /*expl_inst_class=*/false);
        }
       break;
@@ -22132,18 +22133,6 @@ bt_instantiate_type_proc (binding_entry
     do_type_instantiation (TYPE_MAIN_DECL (entry->type), storage, 0);
 }
 
-/* Called from do_type_instantiation to instantiate a member
-   (a member function or a static member variable) of an
-   explicitly instantiated class template.  */
-static void
-instantiate_class_member (tree decl, int extern_p)
-{
-  mark_decl_instantiated (decl, extern_p);
-  if (! extern_p)
-    instantiate_decl (decl, /*defer_ok=*/true,
-                     /*expl_inst_class_mem_p=*/true);
-}
-
 /* Perform an explicit instantiation of template class T.  STORAGE, if
    non-null, is the RID for extern, inline or static.  COMPLAIN is
    nonzero if this is called from the parser, zero if called recursively,
@@ -22253,12 +22242,9 @@ do_type_instantiation (tree t, tree stor
   if (nomem_p)
     return;
 
-  {
-    tree tmp;
-
-    /* In contrast to implicit instantiation, where only the
-       declarations, and not the definitions, of members are
-       instantiated, we have here:
+  /* In contrast to implicit instantiation, where only the
+     declarations, and not the definitions, of members are
+     instantiated, we have here:
 
         [temp.explicit]
 
@@ -22267,27 +22253,28 @@ do_type_instantiation (tree t, tree stor
         previously explicitly specialized in the translation unit
         containing the explicit instantiation.
 
-       Of course, we can't instantiate member template classes, since
-       we don't have any arguments for them.  Note that the standard
-       is unclear on whether the instantiation of the members are
-       *explicit* instantiations or not.  However, the most natural
-       interpretation is that it should be an explicit instantiation.  */
-
-    if (! static_p)
-      for (tmp = TYPE_METHODS (t); tmp; tmp = DECL_CHAIN (tmp))
-       if (TREE_CODE (tmp) == FUNCTION_DECL
-           && DECL_TEMPLATE_INSTANTIATION (tmp)
-           && user_provided_p (tmp))
-         instantiate_class_member (tmp, extern_p);
-
-    for (tmp = TYPE_FIELDS (t); tmp; tmp = DECL_CHAIN (tmp))
-      if (VAR_P (tmp) && DECL_TEMPLATE_INSTANTIATION (tmp))
-       instantiate_class_member (tmp, extern_p);
-
-    if (CLASSTYPE_NESTED_UTDS (t))
-      binding_table_foreach (CLASSTYPE_NESTED_UTDS (t),
-                            bt_instantiate_type_proc, &storage);
-  }
+     Of course, we can't instantiate member template classes, since we
+     don't have any arguments for them.  Note that the standard is
+     unclear on whether the instantiation of the members are
+     *explicit* instantiations or not.  However, the most natural
+     interpretation is that it should be an explicit
+     instantiation.  */
+  for (tree fld = TYPE_FIELDS (t); fld; fld = DECL_CHAIN (fld))
+    if ((VAR_P (fld)
+        || (TREE_CODE (fld) == FUNCTION_DECL
+            && !static_p
+            && user_provided_p (fld)))
+       && DECL_TEMPLATE_INSTANTIATION (fld))
+      {
+       mark_decl_instantiated (fld, extern_p);
+       if (! extern_p)
+         instantiate_decl (fld, /*defer_ok=*/true,
+                           /*expl_inst_class_mem_p=*/true);
+      }
+
+  if (CLASSTYPE_NESTED_UTDS (t))
+    binding_table_foreach (CLASSTYPE_NESTED_UTDS (t),
+                          bt_instantiate_type_proc, &storage);
 }
 
 /* Given a function DECL, which is a specialization of TMPL, modify
@@ -23079,19 +23066,20 @@ instantiate_pending_templates (int retri
 
          if (TYPE_P (instantiation))
            {
-             tree fn;
-
              if (!COMPLETE_TYPE_P (instantiation))
                {
                  instantiate_class_template (instantiation);
                  if (CLASSTYPE_TEMPLATE_INSTANTIATION (instantiation))
-                   for (fn = TYPE_METHODS (instantiation);
-                        fn;
-                        fn = TREE_CHAIN (fn))
-                     if (! DECL_ARTIFICIAL (fn))
-                       instantiate_decl (fn,
+                   for (tree fld = TYPE_FIELDS (instantiation);
+                        fld; fld = TREE_CHAIN (fld))
+                     if ((VAR_P (fld)
+                          || (TREE_CODE (fld) == FUNCTION_DECL
+                              && !DECL_ARTIFICIAL (fld)))
+                         && DECL_TEMPLATE_INSTANTIATION (fld))
+                       instantiate_decl (fld,
                                          /*defer_ok=*/false,
                                          /*expl_inst_class_mem_p=*/false);
+
                  if (COMPLETE_TYPE_P (instantiation))
                    reconsider = 1;
                }
Index: gcc/cp/search.c
===================================================================
--- gcc/cp/search.c     (revision 250160)
+++ gcc/cp/search.c     (working copy)
@@ -444,6 +444,10 @@ lookup_field_1 (tree type, tree name, bo
     {
       tree decl = field;
 
+      if (DECL_DECLARES_FUNCTION_P (decl))
+       /* Functions are kep separately, at the moment.  */
+       continue;
+
       if (GATHER_STATISTICS)
        n_fields_searched++;
 
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c  (revision 250160)
+++ gcc/cp/semantics.c  (working copy)
@@ -3037,9 +3037,9 @@ finish_member_declaration (tree decl)
   if (DECL_LANG_SPECIFIC (decl) && DECL_LANGUAGE (decl) == lang_c)
     SET_DECL_LANGUAGE (decl, lang_cplusplus);
 
-  /* Put functions on the TYPE_METHODS list and everything else on the
-     TYPE_FIELDS list.  Note that these are built up in reverse order.
-     We reverse them (to obtain declaration order) in finish_struct.  */
+  /* Put the decl on the TYPE_FIELDS list.  Note that this is built up
+     in reverse order.  We reverse it (to obtain declaration order) in
+     finish_struct.  */
   if (DECL_DECLARES_FUNCTION_P (decl))
     {
       /* We also need to add this function to the
@@ -3047,8 +3047,8 @@ finish_member_declaration (tree decl)
       if (add_method (current_class_type, decl, false))
        {
          gcc_assert (TYPE_MAIN_VARIANT (current_class_type) == 
current_class_type);
-         DECL_CHAIN (decl) = TYPE_METHODS (current_class_type);
-         TYPE_METHODS (current_class_type) = decl;
+         DECL_CHAIN (decl) = TYPE_FIELDS (current_class_type);
+         TYPE_FIELDS (current_class_type) = decl;
 
          maybe_add_class_template_decl_list (current_class_type, decl,
                                              /*friend_p=*/0);
@@ -5794,7 +5794,7 @@ finish_omp_declare_simd_methods (tree t)
   if (processing_template_decl)
     return;
 
-  for (tree x = TYPE_METHODS (t); x; x = DECL_CHAIN (x))
+  for (tree x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
     {
       if (TREE_CODE (TREE_TYPE (x)) != METHOD_TYPE)
        continue;
Index: gcc/testsuite/g++.dg/ext/anon-struct6.C
===================================================================
--- gcc/testsuite/g++.dg/ext/anon-struct6.C     (revision 250160)
+++ gcc/testsuite/g++.dg/ext/anon-struct6.C     (working copy)
@@ -3,8 +3,8 @@
 struct A
 {
   struct
-  {  // { dg-error "anonymous struct cannot have function members" }
+  {
     struct { static int i; }; // { dg-error "prohibits anonymous 
structs|non-static data members|unnamed class" }
-    void foo() { i; }
+    void foo() { i; } // { dg-error "can only have non-static data" }
   }; // { dg-error "prohibits anonymous structs" }
 };
Index: gcc/testsuite/g++.old-deja/g++.other/anon4.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.other/anon4.C        (revision 250160)
+++ gcc/testsuite/g++.old-deja/g++.other/anon4.C        (working copy)
@@ -10,7 +10,7 @@
 struct A
 {
   union
-  {  // { dg-error "" } anon union cannot have member fns
-    void bad();
+  {
+    void bad(); // { dg-error "can only have non-static data" }
   };
 };

Reply via email to