Remove TYPE_METHODS.
authorNathan Sidwell <nathan@acm.org>
Fri, 21 Jul 2017 00:27:51 +0000 (00:27 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Fri, 21 Jul 2017 00:27:51 +0000 (00:27 +0000)
gcc/
Remove TYPE_METHODS.
* tree.h (TYPE_METHODS): Delete.
* dwarf2out.c (gen_member_die): Member fns are on TYPE_FIELDS.
* dbxout.c (dbxout_type_fields): Ignore FUNCTION_DECLs.
(dbxout_type_methods): Scan TYPE_FIELDS.
(dbxout_type): Don't check TYPE_METHODS here.
* function.c (use_register_for_decl): Always ignore register for
class types when not optimizing.
* ipa-devirt.c (odr_types_equivalent_p): Delete TYPE_METHODS scan.
* tree.c (free_lang_data_in_type): Stitch out member functions and
templates from TYPE_FIELDS.
(build_distinct_type_copy, verify_type_variant,
verify_type): Member fns are on TYPE_FIELDS.
* tree-dump.c (dequeue_and_dump): No TYPE_METHODS.
* tree-pretty-print.c (dump_generic_node): Likewise.

gcc/cp/
Remove TYPE_METHODS.
* 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/c-family/
Remove TYPE_METHODS.
* c-ada-spec.c (is_tagged_type, has_nontrivial_methods,
dump_ada_template, print_ada_methods,
print_ada_declaration): Member fns are on TYPE_FIELDS.

gcc/objc/
Remove TYPE_METHODS.
* objc-runtime-shared-support.c (build_ivar_list_initializer):
Don't presume first item is a FIELD_DECL.

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

libcc1/
Remove TYPE_METHODS.
* libcp1plugin.cc (plugin_build_decl): Member fns are on TYPE_FIELDS.

From-SVN: r250413

27 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-ada-spec.c
gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/method.c
gcc/cp/optimize.c
gcc/cp/pt.c
gcc/cp/search.c
gcc/cp/semantics.c
gcc/dbxout.c
gcc/dwarf2out.c
gcc/function.c
gcc/ipa-devirt.c
gcc/objc/ChangeLog
gcc/objc/objc-runtime-shared-support.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/anon-struct6.C
gcc/testsuite/g++.old-deja/g++.other/anon4.C
gcc/tree-dump.c
gcc/tree-pretty-print.c
gcc/tree.c
gcc/tree.h
libcc1/ChangeLog
libcc1/libcp1plugin.cc

index 9bc43b4dc882902155fc1bb16efa53d3fc5dcdb9..713788c77c692f5997819265ec268f690b8c225c 100644 (file)
@@ -1,3 +1,21 @@
+2017-07-20  Nathan Sidwell  <nathan@acm.org>
+
+       Remove TYPE_METHODS.
+       * tree.h (TYPE_METHODS): Delete.
+       * dwarf2out.c (gen_member_die): Member fns are on TYPE_FIELDS.
+       * dbxout.c (dbxout_type_fields): Ignore FUNCTION_DECLs.
+       (dbxout_type_methods): Scan TYPE_FIELDS.
+       (dbxout_type): Don't check TYPE_METHODS here.
+       * function.c (use_register_for_decl): Always ignore register for
+       class types when not optimizing.
+       * ipa-devirt.c (odr_types_equivalent_p): Delete TYPE_METHODS scan.
+       * tree.c (free_lang_data_in_type): Stitch out member functions and
+       templates from TYPE_FIELDS.
+       (build_distinct_type_copy, verify_type_variant,
+       verify_type): Member fns are on TYPE_FIELDS.
+       * tree-dump.c (dequeue_and_dump): No TYPE_METHODS.
+       * tree-pretty-print.c (dump_generic_node): Likewise.
+
 2017-07-20  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/80846
index e79a57141f11692fa6d1b476ff5dcba83facf910..bd00b252f09c3d9d7f6b270f64a658445b43cac9 100644 (file)
@@ -1,3 +1,10 @@
+2017-07-20  Nathan Sidwell  <nathan@acm.org>
+
+       Remove TYPE_METHODS.
+       * c-ada-spec.c (is_tagged_type, has_nontrivial_methods,
+       dump_ada_template, print_ada_methods,
+       print_ada_declaration): Member fns are on TYPE_FIELDS.
+
 2017-07-18  Nathan Sidwell  <nathan@acm.org>
 
        * c-warn.c (warn_for_memset): Use TYPE_{MIN,MAX}_VALUE.
index 6cf298a126afc91af909de8dfde3ef3c10846dfa..d39501c7b914d539ec4c6f1b274b7b73c6d234c7 100644 (file)
@@ -1070,16 +1070,11 @@ has_static_fields (const_tree type)
 static bool
 is_tagged_type (const_tree type)
 {
-  tree tmp;
-
   if (!type || !RECORD_OR_UNION_TYPE_P (type))
     return false;
 
-  /* TYPE_METHODS is only set on the main variant.  */
-  type = TYPE_MAIN_VARIANT (type);
-
-  for (tmp = TYPE_METHODS (type); tmp; tmp = TREE_CHAIN (tmp))
-    if (TREE_CODE (tmp) == FUNCTION_DECL && DECL_VINDEX (tmp))
+  for (tree fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
+    if (TREE_CODE (fld) == FUNCTION_DECL && DECL_VINDEX (fld))
       return true;
 
   return false;
@@ -1093,8 +1088,6 @@ is_tagged_type (const_tree type)
 static bool
 has_nontrivial_methods (tree type)
 {
-  tree tmp;
-
   if (!type || !RECORD_OR_UNION_TYPE_P (type))
     return false;
 
@@ -1106,12 +1099,9 @@ has_nontrivial_methods (tree type)
   if (!cpp_check (type, IS_TRIVIAL))
     return true;
 
-  /* TYPE_METHODS is only set on the main variant.  */
-  type = TYPE_MAIN_VARIANT (type);
-
   /* If there are user-defined methods, they are deemed non-trivial.  */
-  for (tmp = TYPE_METHODS (type); tmp; tmp = TREE_CHAIN (tmp))
-    if (!DECL_ARTIFICIAL (tmp))
+  for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
+    if (TREE_CODE (TREE_TYPE (fld)) == METHOD_TYPE && !DECL_ARTIFICIAL (fld))
       return true;
 
   return false;
@@ -1896,7 +1886,7 @@ dump_ada_template (pretty_printer *buffer, tree t, int spc)
       if (TREE_VEC_LENGTH (types) == 0)
        break;
 
-      if (!RECORD_OR_UNION_TYPE_P (instance) || !TYPE_METHODS (instance))
+      if (!RECORD_OR_UNION_TYPE_P (instance))
        break;
 
       /* We are interested in concrete template instantiations only: skip
@@ -2442,25 +2432,23 @@ dump_generic_ada_node (pretty_printer *buffer, tree node, tree type, int spc,
 static int
 print_ada_methods (pretty_printer *buffer, tree node, int spc)
 {
-  tree t;
-  int res;
-
   if (!has_nontrivial_methods (node))
     return 0;
 
   pp_semicolon (buffer);
 
-  res = 1;
-  for (t = TYPE_METHODS (node); t; t = TREE_CHAIN (t))
-    {
-      if (res)
-       {
-         pp_newline (buffer);
-         pp_newline (buffer);
-       }
-
-      res = print_ada_declaration (buffer, t, node, spc);
-    }
+  int res = 1;
+  for (tree fld = TYPE_FIELDS (node); fld; fld = DECL_CHAIN (fld))
+    if (TREE_CODE (TREE_TYPE (fld)) == METHOD_TYPE)
+      {
+       if (res)
+         {
+           pp_newline (buffer);
+           pp_newline (buffer);
+         }
+       
+       res = print_ada_declaration (buffer, fld, node, spc);
+      }
 
   return 1;
 }
@@ -2961,19 +2949,13 @@ print_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
          dump_generic_ada_node (buffer, ret_type, type, spc, false, true);
        }
 
-      if (is_constructor
-         && RECORD_OR_UNION_TYPE_P (type)
-         && TYPE_METHODS (type))
-       {
-         tree tmp;
-
-         for (tmp = TYPE_METHODS (type); tmp; tmp = TREE_CHAIN (tmp))
-           if (cpp_check (tmp, IS_ABSTRACT))
-             {
-               is_abstract_class = true;
-               break;
-             }
-       }
+      if (is_constructor && RECORD_OR_UNION_TYPE_P (type))
+       for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
+         if (cpp_check (fld, IS_ABSTRACT))
+           {
+             is_abstract_class = true;
+             break;
+           }
 
       if (is_abstract || is_abstract_class)
        pp_string (buffer, " is abstract");
@@ -3028,35 +3010,33 @@ print_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
 
       pp_string (buffer, " is ");
 
-      /* Check whether we have an Ada interface compatible class.  */
+      /* Check whether we have an Ada interface compatible class.
+        That is only have a vtable non-static data member and no
+        non-abstract methods.  */
       if (cpp_check
-         && RECORD_OR_UNION_TYPE_P (TREE_TYPE (t))
-         && TYPE_METHODS (TREE_TYPE (t)))
+         && RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)))
        {
-         int num_fields = 0;
-         tree tmp;
+         is_interface = -1;
 
          /* Check that there are no fields other than the virtual table.  */
-         for (tmp = TYPE_FIELDS (TREE_TYPE (t)); tmp; tmp = TREE_CHAIN (tmp))
-           {
-             if (TREE_CODE (tmp) == TYPE_DECL)
-               continue;
-             num_fields++;
-           }
-
-         if (num_fields == 1)
-           is_interface = 1;
-
-         /* Also check that there are only pure virtual methods.  Since the
-            class is empty, we can skip implicit constructors/destructors.  */
-         for (tmp = TYPE_METHODS (TREE_TYPE (t)); tmp; tmp = TREE_CHAIN (tmp))
+         for (tree fld = TYPE_FIELDS (TREE_TYPE (t));
+              fld; fld = TREE_CHAIN (fld))
            {
-             if (DECL_ARTIFICIAL (tmp))
-               continue;
-             if (cpp_check (tmp, IS_ABSTRACT))
-               is_abstract_record = 1;
-             else
-               is_interface = 0;
+             if (TREE_CODE (fld) == FIELD_DECL)
+               {
+                 if (is_interface < 0 && DECL_VIRTUAL_P (fld))
+                   is_interface = 1;
+                 else
+                   is_interface = 0;
+               }
+             else if (TREE_CODE (TREE_TYPE (fld)) == METHOD_TYPE
+                      && !DECL_ARTIFICIAL (fld))
+               {
+                 if (cpp_check (fld, IS_ABSTRACT))
+                   is_abstract_record = 1;
+                 else
+                   is_interface = 0;
+               }
            }
        }
 
index 597c6b3f6c8bc48824766e71aba30000921aabb3..234d0425839e1e9b3006d9cac4a9328b154a0b65 100644 (file)
@@ -1,3 +1,25 @@
+2017-07-20  Nathan Sidwell  <nathan@acm.org>
+
+       Remove TYPE_METHODS.
+       * 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.
+
 2017-07-19  Nathan Sidwell  <nathan@acm.org>
 
        * class.c (add_implicitly_declared_members): Use
index 4b9b93a77a778131bbb4870848142d87170f316e..eac664929f81dcabb3364d27621d1cff0af4472d 100644 (file)
@@ -2149,7 +2149,6 @@ maybe_warn_about_overly_private_class (tree 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 (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 = 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 (tree 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)
@@ -2373,7 +2372,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;
 
@@ -2384,9 +2382,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.  */
@@ -2394,6 +2392,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)
@@ -3305,6 +3304,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)
@@ -3322,11 +3323,11 @@ one_inheriting_sig (tree t, tree ctor, tree *parms, int nparms)
     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;
     }
 }
 
@@ -3465,7 +3466,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;
@@ -3483,7 +3486,9 @@ add_fields_to_record_type (tree fields, struct sorted_fields_type *field_vec, in
   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;
@@ -3740,6 +3745,10 @@ check_field_decls (tree t, tree *access_decls,
          || 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)
@@ -4664,39 +4673,42 @@ build_base_fields (record_layout_info rli,
     }
 }
 
-/* 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);
+
+       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);
+         }
 
-  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");
-    }
+       /* 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
@@ -4902,7 +4914,7 @@ clone_function_decl (tree fn, bool update_methods)
       /* 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.
 
@@ -5174,11 +5186,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.  */
@@ -5660,9 +5671,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))
        {
@@ -5924,8 +5935,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)
@@ -5984,7 +5997,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 = 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)
@@ -6643,8 +6656,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)
@@ -7336,11 +7348,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;
@@ -7350,6 +7362,7 @@ unreverse_member_declarations (tree t)
       DECL_CHAIN (x) = prev;
       prev = x;
     }
+
   if (prev)
     {
       DECL_CHAIN (TYPE_FIELDS (t)) = x;
@@ -7390,8 +7403,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
@@ -7416,7 +7429,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
@@ -9922,7 +9934,7 @@ add_vcall_offset_vtbl_entries_1 (tree binfo, vtbl_init_data* vid)
 
   /* 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 5b8e6a22b01ce00cac5e3a79829b3aa66d457e02..d98fab370d716001bc1d9b3a41a7e314df904c14 100644 (file)
@@ -4549,8 +4549,6 @@ push_throw_library_fn (tree name, tree type)
 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 4fa4ad9740f89206840dd5af58bb133677d3293e..2a52f8ca3e206fd74f927569c59a7c4fa2d518dc 100644 (file)
@@ -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 complain)
   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 3c57b41c8d9977b35eb86b3972c42708061a6a27..cca1b14691720fc6b3e64a79cb944bc982fd49d0 100644 (file)
@@ -2246,8 +2246,10 @@ after_nsdmi_defaulted_late_checks (tree t)
     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))
@@ -2379,20 +2381,25 @@ lazily_declare_fn (special_function_kind sfk, tree type)
       || 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 d646ef73803fdf4b33b20329aea5287c91c48547..a1c387092d4b49bfec4229f690eb0c9dae0da938 100644 (file)
@@ -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 da133bd186346f0ea5bc4ffce87733368b5c3334..bb323534ec05e9691a46f74feb1a039b5740b1e6 100644 (file)
@@ -10551,7 +10551,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)
@@ -16137,13 +16136,15 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
             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;
@@ -22133,18 +22134,6 @@ bt_instantiate_type_proc (binding_entry entry, void *data)
     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,
@@ -22254,12 +22243,9 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
   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]
 
@@ -22268,27 +22254,28 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
         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
@@ -23080,19 +23067,20 @@ instantiate_pending_templates (int retries)
 
          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 cd06e529fb94d79864f3c59e74d9c13fce0d9fac..40caf70a0012971a5def9a5450685c398ed023c5 100644 (file)
@@ -444,6 +444,10 @@ lookup_field_1 (tree type, tree name, bool want_type)
     {
       tree decl = field;
 
+      if (DECL_DECLARES_FUNCTION_P (decl))
+       /* Functions are kep separately, at the moment.  */
+       continue;
+
       if (GATHER_STATISTICS)
        n_fields_searched++;
 
index cf19e5fd96a79f0283190c4afe171f6d07e1d0e1..ddb84f29080057f4d39f9bf4b3e36c6fbe275454 100644 (file)
@@ -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 783a70bec4f200e17515b28f5b9fd41f6c12115f..b278c6da1d4405ee8dcc4c718bdc7884b29ebe15 100644 (file)
@@ -1481,6 +1481,8 @@ dbxout_type_fields (tree type)
       /* Omit here local type decls until we know how to support them.  */
       if (TREE_CODE (tem) == TYPE_DECL
          || TREE_CODE (tem) == TEMPLATE_DECL
+         /* Member functions emitted after fields.  */
+         || TREE_CODE (tem) == FUNCTION_DECL
          /* Omit here the nameless fields that are used to skip bits.  */
          || DECL_IGNORED_P (tem)
          /* Omit fields whose position or size are variable or too large to
@@ -1586,55 +1588,38 @@ dbxout_type_method_1 (tree decl)
     }
 }
 \f
-/* Subroutine of `dbxout_type'.  Output debug info about the methods defined
-   in TYPE.  */
+/* Subroutine of `dbxout_type'.  Output debug info about the member
+   functions defined in TYPE.  */
 
 static void
 dbxout_type_methods (tree type)
 {
-  /* C++: put out the method names and their parameter lists */
-  tree methods = TYPE_METHODS (type);
-  tree fndecl;
-  tree last;
-
-  if (methods == NULL_TREE)
-    return;
-
-  if (TREE_CODE (methods) != TREE_VEC)
-    fndecl = methods;
-  else if (TREE_VEC_ELT (methods, 0) != NULL_TREE)
-    fndecl = TREE_VEC_ELT (methods, 0);
-  else
-    fndecl = TREE_VEC_ELT (methods, 1);
-
-  while (fndecl)
+  for (tree fndecl = TYPE_FIELDS (type); fndecl;)
     {
       int need_prefix = 1;
 
       /* Group together all the methods for the same operation.
         These differ in the types of the arguments.  */
-      for (last = NULL_TREE;
+      for (tree last = NULL_TREE;
           fndecl && (last == NULL_TREE || DECL_NAME (fndecl) == DECL_NAME (last));
           fndecl = DECL_CHAIN (fndecl))
        /* Output the name of the field (after overloading), as
           well as the name of the field before overloading, along
           with its parameter list */
        {
-         /* Skip methods that aren't FUNCTION_DECLs.  (In C++, these
-            include TEMPLATE_DECLs.)  The debugger doesn't know what
-            to do with such entities anyhow.  */
+         /* Skip non-functions.  */
          if (TREE_CODE (fndecl) != FUNCTION_DECL)
            continue;
 
-         CONTIN;
-
-         last = fndecl;
-
          /* Also ignore abstract methods; those are only interesting to
             the DWARF backends.  */
          if (DECL_IGNORED_P (fndecl) || DECL_ABSTRACT_P (fndecl))
            continue;
 
+         CONTIN;
+
+         last = fndecl;
+
          /* Redundantly output the plain name, since that's what gdb
             expects.  */
          if (need_prefix)
@@ -2209,10 +2194,8 @@ dbxout_type (tree type, int full)
 
       /* Write out the field declarations.  */
       dbxout_type_fields (type);
-      if (use_gnu_debug_info_extensions && TYPE_METHODS (type) != NULL_TREE)
-       {
-         dbxout_type_methods (type);
-       }
+      if (use_gnu_debug_info_extensions)
+       dbxout_type_methods (type);
 
       stabstr_C (';');
 
index 72d2c588c86294aaea47d13f773a6d4bfc69b797..66103d76188608686dfcea729be916a7648460e1 100644 (file)
@@ -24032,7 +24032,8 @@ gen_member_die (tree type, dw_die_ref context_die)
 {
   tree member;
   tree binfo = TYPE_BINFO (type);
-  dw_die_ref child;
+
+  gcc_assert (TYPE_MAIN_VARIANT (type) == type);
 
   /* If this is not an incomplete type, output descriptions of each of its
      members. Note that as we output the DIEs necessary to represent the
@@ -24069,13 +24070,16 @@ gen_member_die (tree type, dw_die_ref context_die)
           && (lang_hooks.decls.decl_dwarf_attribute (member, DW_AT_inline)
               != -1));
 
+      /* Ignore clones.  */
+      if (DECL_ABSTRACT_ORIGIN (member))
+       continue;
+
       /* If we thought we were generating minimal debug info for TYPE
         and then changed our minds, some of the member declarations
         may have already been defined.  Don't define them again, but
         do put them in the right order.  */
 
-      child = lookup_decl_die (member);
-      if (child)
+      if (dw_die_ref child = lookup_decl_die (member))
        {
          /* Handle inline static data members, which only have in-class
             declarations.  */
@@ -24103,6 +24107,7 @@ gen_member_die (tree type, dw_die_ref context_die)
                  static_inline_p = false;
                }
            }
+
          if (child->die_tag == DW_TAG_variable
              && child->die_parent == comp_unit_die ()
              && ref == NULL)
@@ -24141,23 +24146,6 @@ gen_member_die (tree type, dw_die_ref context_die)
          DECL_EXTERNAL (member) = old_extern;
        }
     }
-
-  /* We do not keep type methods in type variants.  */
-  gcc_assert (TYPE_MAIN_VARIANT (type) == type);
-  /* Now output info about the function members (if any).  */
-  if (TYPE_METHODS (type) != error_mark_node)
-    for (member = TYPE_METHODS (type); member; member = DECL_CHAIN (member))
-      {
-       /* Don't include clones in the member list.  */
-       if (DECL_ABSTRACT_ORIGIN (member))
-         continue;
-
-       child = lookup_decl_die (member);
-       if (child)
-         splice_child_die (context_die, child);
-       else
-         gen_decl_die (member, NULL, NULL, context_die);
-      }
 }
 
 /* Generate a DIE for a structure or union type.  If TYPE_DECL_SUPPRESS_DEBUG
index f625489205be3f31c17b39e102dd94d6a29cda59..986f43f07048649c0a48ad7f1deff088e789ff90 100644 (file)
@@ -2218,20 +2218,11 @@ use_register_for_decl (const_tree decl)
   if (!DECL_REGISTER (decl))
     return false;
 
-  switch (TREE_CODE (TREE_TYPE (decl)))
-    {
-    case RECORD_TYPE:
-    case UNION_TYPE:
-    case QUAL_UNION_TYPE:
-      /* When not optimizing, disregard register keyword for variables with
-        types containing methods, otherwise the methods won't be callable
-        from the debugger.  */
-      if (TYPE_METHODS (TYPE_MAIN_VARIANT (TREE_TYPE (decl))))
-       return false;
-      break;
-    default:
-      break;
-    }
+  /* When not optimizing, disregard register keyword for types that
+     could have methods, otherwise the methods won't be callable from
+     the debugger.  */
+  if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)))
+    return false;
 
   return true;
 }
index f0bc2501c273b6c3828456e568bcf310215ed3ab..9781acd0766334a644a133c2f94b09b48fbe7f9d 100644 (file)
@@ -1602,62 +1602,6 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
                
                return false;
              }
-           if ((TYPE_MAIN_VARIANT (t1) == t1 || TYPE_MAIN_VARIANT (t2) == t2)
-               && COMPLETE_TYPE_P (TYPE_MAIN_VARIANT (t1))
-               && COMPLETE_TYPE_P (TYPE_MAIN_VARIANT (t2))
-               && odr_type_p (TYPE_MAIN_VARIANT (t1))
-               && odr_type_p (TYPE_MAIN_VARIANT (t2))
-               && (TYPE_METHODS (TYPE_MAIN_VARIANT (t1))
-                   != TYPE_METHODS (TYPE_MAIN_VARIANT (t2))))
-             {
-               /* Currently free_lang_data sets TYPE_METHODS to error_mark_node
-                  if it is non-NULL so this loop will never realy execute.  */
-               if (TYPE_METHODS (TYPE_MAIN_VARIANT (t1)) != error_mark_node
-                   && TYPE_METHODS (TYPE_MAIN_VARIANT (t2)) != error_mark_node)
-                 for (f1 = TYPE_METHODS (TYPE_MAIN_VARIANT (t1)),
-                      f2 = TYPE_METHODS (TYPE_MAIN_VARIANT (t2));
-                      f1 && f2 ; f1 = DECL_CHAIN (f1), f2 = DECL_CHAIN (f2))
-                   {
-                     if (DECL_ASSEMBLER_NAME (f1) != DECL_ASSEMBLER_NAME (f2))
-                       {
-                         warn_odr (t1, t2, f1, f2, warn, warned,
-                                   G_("a different method of same type "
-                                      "is defined in another "
-                                      "translation unit"));
-                         return false;
-                       }
-                     if (DECL_VIRTUAL_P (f1) != DECL_VIRTUAL_P (f2))
-                       {
-                         warn_odr (t1, t2, f1, f2, warn, warned,
-                                   G_("a definition that differs by virtual "
-                                      "keyword in another translation unit"));
-                         return false;
-                       }
-                     if (DECL_VINDEX (f1) != DECL_VINDEX (f2))
-                       {
-                         warn_odr (t1, t2, f1, f2, warn, warned,
-                                   G_("virtual table layout differs "
-                                      "in another translation unit"));
-                         return false;
-                       }
-                     if (odr_subtypes_equivalent_p (TREE_TYPE (f1),
-                                                    TREE_TYPE (f2), visited,
-                                                    loc1, loc2))
-                       {
-                         warn_odr (t1, t2, f1, f2, warn, warned,
-                                   G_("method with incompatible type is "
-                                      "defined in another translation unit"));
-                         return false;
-                       }
-                   }
-               if ((f1 == NULL) != (f2 == NULL))
-                 {
-                   warn_odr (t1, t2, NULL, NULL, warn, warned,
-                             G_("a type with different number of methods "
-                                "is defined in another translation unit"));
-                   return false;
-                 }
-             }
          }
        break;
       }
index 053e4d4a543a58bffb8d719636dd527302334266..27bb0600626cafb3a209b02d6b5ebb62fea6357f 100644 (file)
@@ -1,3 +1,9 @@
+2017-07-20  Nathan Sidwell  <nathan@acm.org>
+
+       Remove TYPE_METHODS.
+       * objc-runtime-shared-support.c (build_ivar_list_initializer):
+       Don't presume first item is a FIELD_DECL.
+
 2017-07-19  Nathan Sidwell  <nathan@acm.org>
 
        * objc-act.h (CLASS_NST_METHODS, CLASS_CLS_METHODS): Use
index 5ead87078c6206f6a660901532ad9d6412389f59..53303e47d201c9b5aca36bb44f644dfde19d192f 100644 (file)
@@ -528,34 +528,32 @@ build_ivar_list_initializer (tree type, tree field_decl)
 {
   vec<constructor_elt, va_gc> *inits = NULL;
 
-  do
-    {
-      vec<constructor_elt, va_gc> *ivar = NULL;
-      tree id;
-
-      /* Set name.  */
-      if (DECL_NAME (field_decl))
-       CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
-                               add_objc_string (DECL_NAME (field_decl),
-                                                meth_var_names));
-      else
-       /* Unnamed bit-field ivar (yuck).  */
-       CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0));
-
-      /* Set type.  */
-      id = add_objc_string (encode_field_decl (field_decl),
-                            meth_var_types);
-      CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
-
-      /* Set offset.  */
-      CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
-      CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
-                             objc_build_constructor (type, ivar));
-      do
-       field_decl = DECL_CHAIN (field_decl);
-      while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
+  for (; field_decl; field_decl = DECL_CHAIN (field_decl))
+    if (TREE_CODE (field_decl) == FIELD_DECL)
+      {
+       vec<constructor_elt, va_gc> *ivar = NULL;
+       tree id;
+
+       /* Set name.  */
+       if (DECL_NAME (field_decl))
+         CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
+                                 add_objc_string (DECL_NAME (field_decl),
+                                                  meth_var_names));
+       else
+         /* Unnamed bit-field ivar (yuck).  */
+         CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
+                                 build_int_cst (NULL_TREE, 0));
+
+       /* Set type.  */
+       id = add_objc_string (encode_field_decl (field_decl),
+                             meth_var_types);
+       CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
+
+       /* Set offset.  */
+       CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
+       CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
+                               objc_build_constructor (type, ivar));
     }
-  while (field_decl);
 
   return objc_build_constructor (build_array_type (type, 0), inits);
 }
index bafcb2c6382e0291439ad73b49de3f0da39a0b30..482b8dd2c9a12dacb3c19eb09973e4279ece1ebd 100644 (file)
@@ -1,3 +1,8 @@
+2017-07-20  Nathan Sidwell  <nathan@acm.org>
+
+       * g++.dg/ext/anon-struct6.C: Adjust diag.
+       * g++.old-deja/g++.other/anon4.C: Adjust diag.
+
 2017-07-20  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/80846
index 66d4b32719621c37067b7c85e0f8ed0268e238be..9b59085f67099fd77ba0f594056650690f4f1cd3 100644 (file)
@@ -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 2a01be3d0aa2f8974090862c47fcbda318afe331..b6cb3006d713cf980b3d398a061b7dd41eeece26 100644 (file)
@@ -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" }
   };
 };
index 0eab7ac590ad09639afd41a15a3d4021a99943a1..da36031da3090db925943b5c6357adb578f9b342 100644 (file)
@@ -490,7 +490,6 @@ dequeue_and_dump (dump_info_p di)
        dump_string_field (di, "tag", "union");
 
       dump_child ("flds", TYPE_FIELDS (t));
-      dump_child ("fncs", TYPE_METHODS (t));
       queue_and_dump_index (di, "binf", TYPE_BINFO (t),
                            DUMP_BINFO);
       break;
index b70e32573eecfb993839985ef3c89698c394faaa..4d8177c4a6240e80e78cdecc110bda1c7e2bd53f 100644 (file)
@@ -1860,22 +1860,9 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
        dump_decl_name (pp, node, flags);
       else if (TYPE_NAME (TREE_TYPE (node)) != node)
        {
-         if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
-              || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
-             && TYPE_METHODS (TREE_TYPE (node)))
-           {
-             /* The type is a c++ class: all structures have at least
-                4 methods.  */
-             pp_string (pp, "class ");
-             dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
-           }
-         else
-           {
-             pp_string (pp,
-                        (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
+         pp_string (pp, (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
                          ? "union" : "struct "));
-             dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
-           }
+         dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
        }
       else
        pp_string (pp, "<anon>");
index 70da8d2ee2dcae582cb8226302d3cfe0ce354eee..b7de2840ac63c79d1be29ab136f4ae9162f4c158 100644 (file)
@@ -5217,13 +5217,15 @@ free_lang_data_in_type (tree type)
       if (TYPE_VFIELD (type) && TREE_CODE (TYPE_VFIELD (type)) != FIELD_DECL)
         TYPE_VFIELD (type) = NULL_TREE;
 
-      /* Remove TYPE_METHODS list.  While it would be nice to keep it
-        to enable ODR warnings about different method lists, doing so
-        seems to impractically increase size of LTO data streamed.
-        Keep the information if TYPE_METHODS was non-NULL. This is used
-        by function.c and pretty printers.  */
-      if (TYPE_METHODS (type))
-        TYPE_METHODS (type) = error_mark_node;
+      /* Splice out FUNCTION_DECLS and TEMPLATE_DECLS from
+        TYPE_FIELDS.  So LTO doesn't grow.  */
+      for (tree probe, *prev= &TYPE_FIELDS (type); (probe = *prev); )
+       if (TREE_CODE (probe) == FUNCTION_DECL
+           || TREE_CODE (probe) == TEMPLATE_DECL)
+         *prev = probe;
+       else
+         prev = &DECL_CHAIN (probe);
+
       if (TYPE_BINFO (type))
        {
          free_lang_data_in_binfo (TYPE_BINFO (type));
@@ -5418,9 +5420,10 @@ free_lang_data_in_decl (tree decl)
         At this point, it is not needed anymore.  */
       DECL_SAVED_TREE (decl) = NULL_TREE;
 
-      /* Clear the abstract origin if it refers to a method.  Otherwise
-         dwarf2out.c will ICE as we clear TYPE_METHODS and thus the
-        origin will not be output correctly.  */
+      /* Clear the abstract origin if it refers to a method.
+         Otherwise dwarf2out.c will ICE as we splice functions out of
+         TYPE_FIELDS and thus the origin will not be output
+         correctly.  */
       if (DECL_ABSTRACT_ORIGIN (decl)
          && DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl))
          && RECORD_OR_UNION_TYPE_P
@@ -6679,12 +6682,6 @@ build_distinct_type_copy (tree type MEM_STAT_DECL)
   TYPE_MAIN_VARIANT (t) = t;
   TYPE_NEXT_VARIANT (t) = 0;
 
-  /* We do not record methods in type copies nor variants
-     so we do not need to keep them up to date when new method
-     is inserted.  */
-  if (RECORD_OR_UNION_TYPE_P (t))
-    TYPE_METHODS (t) = NULL_TREE;
-
   /* Note that it is now possible for TYPE_MIN_VALUE to be a value
      whose TREE_TYPE is not t.  This can also happen in the Ada
      frontend when using subtypes.  */
@@ -13410,8 +13407,6 @@ verify_type_variant (const_tree t, tree tv)
      - aggregates may have new TYPE_FIELDS list that list variants of
        the main variant TYPE_FIELDS.
      - vector types may differ by TYPE_VECTOR_OPAQUE
-     - TYPE_METHODS is always NULL for variant types and maintained for
-       main variant only.
    */
 
   /* Convenience macro for matching individual fields.  */
@@ -13512,12 +13507,6 @@ verify_type_variant (const_tree t, tree tv)
     }
   if (TREE_CODE (t) == METHOD_TYPE)
     verify_variant_match (TYPE_METHOD_BASETYPE);
-  if (RECORD_OR_UNION_TYPE_P (t) && TYPE_METHODS (t))
-    {
-      error ("type variant has TYPE_METHODS");
-      debug_tree (tv);
-      return false;
-    }
   if (TREE_CODE (t) == OFFSET_TYPE)
     verify_variant_match (TYPE_OFFSET_BASETYPE);
   if (TREE_CODE (t) == ARRAY_TYPE)
@@ -14020,14 +14009,6 @@ verify_type (const_tree t)
   /* Check various uses of TYPE_MAXVAL.  */
   if (RECORD_OR_UNION_TYPE_P (t))
     {
-      if (TYPE_METHODS (t) && TREE_CODE (TYPE_METHODS (t)) != FUNCTION_DECL
-         && TREE_CODE (TYPE_METHODS (t)) != TEMPLATE_DECL
-         && TYPE_METHODS (t) != error_mark_node)
-       {
-         error ("TYPE_METHODS is not FUNCTION_DECL, TEMPLATE_DECL nor error_mark_node");
-         debug_tree (TYPE_METHODS (t));
-         error_found = true;
-       }
     }
   else if (TREE_CODE (t) == FUNCTION_TYPE || TREE_CODE (t) == METHOD_TYPE)
     {
@@ -14158,6 +14139,8 @@ verify_type (const_tree t)
            ;
          else if (TREE_CODE (fld) == USING_DECL)
            ;
+         else if (TREE_CODE (fld) == FUNCTION_DECL)
+           ;
          else
            {
              error ("Wrong tree in TYPE_FIELDS list");
index 6ab42244df5d0a98154a5f4eea35a9db2356d9ae..819938c4458192cac026a907668789f0a088f188 100644 (file)
@@ -2122,8 +2122,6 @@ extern machine_mode element_mode (const_tree t);
 
 #define TYPE_MAX_VALUE(NODE) \
   (NUMERICAL_TYPE_CHECK (NODE)->type_non_common.maxval)
-#define TYPE_METHODS(NODE)                             \
-  (RECORD_OR_UNION_CHECK (NODE)->type_non_common.maxval)
 #define TYPE_METHOD_BASETYPE(NODE)                     \
   (FUNC_OR_METHOD_CHECK (NODE)->type_non_common.maxval)
 #define TYPE_OFFSET_BASETYPE(NODE)                     \
index a5acf0df000ed94647bb1d862f35d2c4fa37e84f..4d8f40c83123522fa8f6f54566438e19241a5ae9 100644 (file)
@@ -1,3 +1,8 @@
+2017-07-20  Nathan Sidwell  <nathan@acm.org>
+
+       Remove TYPE_METHODS.
+       * libcp1plugin.cc (plugin_build_decl): Member fns are on TYPE_FIELDS.
+
 2017-07-12  Nathan Sidwell  <nathan@acm.org>
 
        * libcp1plugin.cc (plugin_build_decl): Use
index 8dd5e673838728537b1fa408150ac5d63e531df0..d7bf5a29d6d0019a3a87aeb6979814aebf6721d3 100644 (file)
@@ -1556,7 +1556,7 @@ plugin_build_decl (cc1_plugin::connection *self,
 
   if ((ctor || dtor)
       /* Don't crash after a duplicate declaration of a cdtor.  */
-      && TYPE_METHODS (current_class_type) == decl)
+      && TYPE_FIELDS (current_class_type) == decl)
     {
       /* ctors and dtors clones are chained after DECL.
         However, we create the clones before TYPE_METHODS is
@@ -1568,9 +1568,9 @@ plugin_build_decl (cc1_plugin::connection *self,
       tree save = DECL_CHAIN (decl);
       DECL_CHAIN (decl) = NULL_TREE;
       clone_function_decl (decl, /*update_methods=*/true);
-      gcc_assert (TYPE_METHODS (current_class_type) == decl);
-      TYPE_METHODS (current_class_type)
-       = nreverse (TYPE_METHODS (current_class_type));
+      gcc_assert (TYPE_FIELDS (current_class_type) == decl);
+      TYPE_FIELDS (current_class_type)
+       = nreverse (TYPE_FIELDS (current_class_type));
       DECL_CHAIN (decl) = save;
     }