Remove TYPE_METHODS.

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
This commit is contained in:
Nathan Sidwell 2017-07-21 00:27:51 +00:00 committed by Nathan Sidwell
parent 61612fa5da
commit 5aaa8fb406
27 changed files with 356 additions and 459 deletions

View 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> 2017-07-20 Jakub Jelinek <jakub@redhat.com>
PR target/80846 PR target/80846

View 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> 2017-07-18 Nathan Sidwell <nathan@acm.org>
* c-warn.c (warn_for_memset): Use TYPE_{MIN,MAX}_VALUE. * c-warn.c (warn_for_memset): Use TYPE_{MIN,MAX}_VALUE.

View File

@ -1070,16 +1070,11 @@ has_static_fields (const_tree type)
static bool static bool
is_tagged_type (const_tree type) is_tagged_type (const_tree type)
{ {
tree tmp;
if (!type || !RECORD_OR_UNION_TYPE_P (type)) if (!type || !RECORD_OR_UNION_TYPE_P (type))
return false; return false;
/* TYPE_METHODS is only set on the main variant. */ for (tree fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
type = TYPE_MAIN_VARIANT (type); if (TREE_CODE (fld) == FUNCTION_DECL && DECL_VINDEX (fld))
for (tmp = TYPE_METHODS (type); tmp; tmp = TREE_CHAIN (tmp))
if (TREE_CODE (tmp) == FUNCTION_DECL && DECL_VINDEX (tmp))
return true; return true;
return false; return false;
@ -1093,8 +1088,6 @@ is_tagged_type (const_tree type)
static bool static bool
has_nontrivial_methods (tree type) has_nontrivial_methods (tree type)
{ {
tree tmp;
if (!type || !RECORD_OR_UNION_TYPE_P (type)) if (!type || !RECORD_OR_UNION_TYPE_P (type))
return false; return false;
@ -1106,12 +1099,9 @@ has_nontrivial_methods (tree type)
if (!cpp_check (type, IS_TRIVIAL)) if (!cpp_check (type, IS_TRIVIAL))
return true; 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. */ /* If there are user-defined methods, they are deemed non-trivial. */
for (tmp = TYPE_METHODS (type); tmp; tmp = TREE_CHAIN (tmp)) for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
if (!DECL_ARTIFICIAL (tmp)) if (TREE_CODE (TREE_TYPE (fld)) == METHOD_TYPE && !DECL_ARTIFICIAL (fld))
return true; return true;
return false; return false;
@ -1896,7 +1886,7 @@ dump_ada_template (pretty_printer *buffer, tree t, int spc)
if (TREE_VEC_LENGTH (types) == 0) if (TREE_VEC_LENGTH (types) == 0)
break; break;
if (!RECORD_OR_UNION_TYPE_P (instance) || !TYPE_METHODS (instance)) if (!RECORD_OR_UNION_TYPE_P (instance))
break; break;
/* We are interested in concrete template instantiations only: skip /* 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 static int
print_ada_methods (pretty_printer *buffer, tree node, int spc) print_ada_methods (pretty_printer *buffer, tree node, int spc)
{ {
tree t;
int res;
if (!has_nontrivial_methods (node)) if (!has_nontrivial_methods (node))
return 0; return 0;
pp_semicolon (buffer); pp_semicolon (buffer);
res = 1; int res = 1;
for (t = TYPE_METHODS (node); t; t = TREE_CHAIN (t)) for (tree fld = TYPE_FIELDS (node); fld; fld = DECL_CHAIN (fld))
{ if (TREE_CODE (TREE_TYPE (fld)) == METHOD_TYPE)
if (res) {
{ if (res)
pp_newline (buffer); {
pp_newline (buffer); pp_newline (buffer);
} pp_newline (buffer);
}
res = print_ada_declaration (buffer, t, node, spc);
} res = print_ada_declaration (buffer, fld, node, spc);
}
return 1; 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); dump_generic_ada_node (buffer, ret_type, type, spc, false, true);
} }
if (is_constructor if (is_constructor && RECORD_OR_UNION_TYPE_P (type))
&& RECORD_OR_UNION_TYPE_P (type) for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
&& TYPE_METHODS (type)) if (cpp_check (fld, IS_ABSTRACT))
{ {
tree tmp; is_abstract_class = true;
break;
for (tmp = TYPE_METHODS (type); tmp; tmp = TREE_CHAIN (tmp)) }
if (cpp_check (tmp, IS_ABSTRACT))
{
is_abstract_class = true;
break;
}
}
if (is_abstract || is_abstract_class) if (is_abstract || is_abstract_class)
pp_string (buffer, " is abstract"); 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 "); 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 if (cpp_check
&& RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)) && RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)))
&& TYPE_METHODS (TREE_TYPE (t)))
{ {
int num_fields = 0; is_interface = -1;
tree tmp;
/* Check that there are no fields other than the virtual table. */ /* Check that there are no fields other than the virtual table. */
for (tmp = TYPE_FIELDS (TREE_TYPE (t)); tmp; tmp = TREE_CHAIN (tmp)) for (tree fld = TYPE_FIELDS (TREE_TYPE (t));
fld; fld = TREE_CHAIN (fld))
{ {
if (TREE_CODE (tmp) == TYPE_DECL) if (TREE_CODE (fld) == FIELD_DECL)
continue; {
num_fields++; if (is_interface < 0 && DECL_VIRTUAL_P (fld))
} is_interface = 1;
else
if (num_fields == 1) is_interface = 0;
is_interface = 1; }
else if (TREE_CODE (TREE_TYPE (fld)) == METHOD_TYPE
/* Also check that there are only pure virtual methods. Since the && !DECL_ARTIFICIAL (fld))
class is empty, we can skip implicit constructors/destructors. */ {
for (tmp = TYPE_METHODS (TREE_TYPE (t)); tmp; tmp = TREE_CHAIN (tmp)) if (cpp_check (fld, IS_ABSTRACT))
{ is_abstract_record = 1;
if (DECL_ARTIFICIAL (tmp)) else
continue; is_interface = 0;
if (cpp_check (tmp, IS_ABSTRACT)) }
is_abstract_record = 1;
else
is_interface = 0;
} }
} }

View 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> 2017-07-19 Nathan Sidwell <nathan@acm.org>
* class.c (add_implicitly_declared_members): Use * class.c (add_implicitly_declared_members): Use

View File

@ -2149,7 +2149,6 @@ maybe_warn_about_overly_private_class (tree t)
{ {
int has_member_fn = 0; int has_member_fn = 0;
int has_nonprivate_method = 0; int has_nonprivate_method = 0;
tree fn;
if (!warn_ctor_dtor_privacy if (!warn_ctor_dtor_privacy
/* If the class has friends, those entities might create and /* 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 functions are private. (Since there are no friends or
non-private statics, we can't ever call any of the private member non-private statics, we can't ever call any of the private member
functions.) */ functions.) */
for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn)) for (tree fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
/* We're not interested in compiler-generated methods; they don't if (!DECL_DECLARES_FUNCTION_P (fn))
provide any way to call private members. */ /* Not a function. */;
if (!DECL_ARTIFICIAL (fn)) 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
if (DECL_STATIC_FUNCTION_P (fn)) friend; it can create and invoke private member
/* A non-private static member function is just like a functions, and be accessed without a class
friend; it can create and invoke private member instance. */
functions, and be accessed without a class return;
instance. */
return;
has_nonprivate_method = 1; has_nonprivate_method = 1;
/* Keep searching for a static member function. */ /* Keep searching for a static member function. */
}
else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn))
has_member_fn = 1;
} }
else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn))
has_member_fn = 1;
if (!has_nonprivate_method && has_member_fn) 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 /* Even if some of the member functions are non-private, the class
won't be useful for much if all the constructors or destructors won't be useful for much if all the constructors or destructors
are private: such an object can never be created or destroyed. */ are private: such an object can never be created or destroyed. */
fn = CLASSTYPE_DESTRUCTOR (t); if (tree dtor = CLASSTYPE_DESTRUCTOR (t))
if (fn && TREE_PRIVATE (fn)) if (TREE_PRIVATE (dtor))
{ {
warning (OPT_Wctor_dtor_privacy, warning (OPT_Wctor_dtor_privacy,
"%q#T only defines a private destructor and has no friends", "%q#T only defines a private destructor and has no friends",
t); t);
return; return;
} }
/* Warn about classes that have private constructors and no friends. */ /* Warn about classes that have private constructors and no friends. */
if (TYPE_HAS_USER_CONSTRUCTOR (t) if (TYPE_HAS_USER_CONSTRUCTOR (t)
@ -2373,7 +2372,6 @@ resort_type_method_vec (void* obj,
static void static void
finish_struct_methods (tree t) finish_struct_methods (tree t)
{ {
tree fn_fields;
vec<tree, va_gc> *method_vec; vec<tree, va_gc> *method_vec;
int slot, len; int slot, len;
@ -2384,9 +2382,9 @@ finish_struct_methods (tree t)
len = method_vec->length (); len = method_vec->length ();
/* Clear DECL_IN_AGGR_P for all functions. */ /* Clear DECL_IN_AGGR_P for all functions. */
for (fn_fields = TYPE_METHODS (t); fn_fields; for (tree fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
fn_fields = DECL_CHAIN (fn_fields)) if (DECL_DECLARES_FUNCTION_P (fn))
DECL_IN_AGGR_P (fn_fields) = 0; DECL_IN_AGGR_P (fn) = false;
/* Issue warnings about private constructors and such. If there are /* Issue warnings about private constructors and such. If there are
no methods, then some public defaults are generated. */ 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 /* The type conversion ops have to live at the front of the vec, so we
can't sort them. */ can't sort them. */
tree fn_fields;
for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT; for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
method_vec->iterate (slot, &fn_fields); method_vec->iterate (slot, &fn_fields);
++slot) ++slot)
@ -3305,6 +3304,8 @@ declare_virt_assop_and_dtor (tree t)
static void static void
one_inheriting_sig (tree t, tree ctor, tree *parms, int nparms) 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, /* We don't declare an inheriting ctor that would be a default,
copy or move ctor for derived or base. */ copy or move ctor for derived or base. */
if (nparms == 0) 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); parmlist = tree_cons (NULL_TREE, parms[i], parmlist);
tree fn = implicitly_declare_fn (sfk_inheriting_constructor, tree fn = implicitly_declare_fn (sfk_inheriting_constructor,
t, false, ctor, parmlist); t, false, ctor, parmlist);
gcc_assert (TYPE_MAIN_VARIANT (t) == t);
if (add_method (t, fn, false)) if (add_method (t, fn, false))
{ {
DECL_CHAIN (fn) = TYPE_METHODS (t); DECL_CHAIN (fn) = TYPE_FIELDS (t);
TYPE_METHODS (t) = fn; TYPE_FIELDS (t) = fn;
} }
} }
@ -3465,7 +3466,9 @@ count_fields (tree fields)
int n_fields = 0; int n_fields = 0;
for (x = fields; x; x = DECL_CHAIN (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 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))); n_fields += count_fields (TYPE_FIELDS (TREE_TYPE (x)));
else else
n_fields += 1; n_fields += 1;
@ -3483,7 +3486,9 @@ add_fields_to_record_type (tree fields, struct sorted_fields_type *field_vec, in
tree x; tree x;
for (x = fields; x; x = DECL_CHAIN (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); idx = add_fields_to_record_type (TYPE_FIELDS (TREE_TYPE (x)), field_vec, idx);
else else
field_vec->elts[idx++] = x; field_vec->elts[idx++] = x;
@ -3740,6 +3745,10 @@ check_field_decls (tree t, tree *access_decls,
|| TREE_CODE (x) == TEMPLATE_DECL) || TREE_CODE (x) == TEMPLATE_DECL)
continue; 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, /* If we've gotten this far, it's a data member, possibly static,
or an enumerator. */ or an enumerator. */
if (TREE_CODE (x) != CONST_DECL) 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 diagnostics, figuring out which methods override which other
methods, and so forth. */ methods, and so forth. */
static void static void
check_methods (tree t) 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)) if (DECL_PURE_VIRTUAL_P (x)
{ && (TREE_CODE (x) != FUNCTION_DECL || ! DECL_VINDEX (x)))
check_for_override (x, t); error ("initializer specified for non-virtual method %q+D", x);
if (DECL_PURE_VIRTUAL_P (x) && (TREE_CODE (x) != FUNCTION_DECL || ! DECL_VINDEX (x))) /* The name of the field is the original field name
error ("initializer specified for non-virtual method %q+D", x); Save this in auxiliary field for later overloading. */
/* The name of the field is the original field name if (TREE_CODE (x) == FUNCTION_DECL && DECL_VINDEX (x))
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))
TYPE_POLYMORPHIC_P (t) = 1; vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), x);
if (DECL_PURE_VIRTUAL_P (x)) }
vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), x);
} /* All user-provided destructors are non-trivial.
/* All user-provided destructors are non-trivial. Constructors and assignment ops are handled in
Constructors and assignment ops are handled in grok_special_member_properties. */
grok_special_member_properties. */ if (DECL_DESTRUCTOR_P (x) && user_provided_p (x))
if (DECL_DESTRUCTOR_P (x) && user_provided_p (x)) TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 1;
TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 1; if (!DECL_VIRTUAL_P (x)
if (!DECL_VIRTUAL_P (x) && lookup_attribute ("transaction_safe_dynamic",
&& lookup_attribute ("transaction_safe_dynamic", DECL_ATTRIBUTES (x))) DECL_ATTRIBUTES (x)))
error_at (DECL_SOURCE_LOCATION (x), error_at (DECL_SOURCE_LOCATION (x),
"%<transaction_safe_dynamic%> may only be specified for " "%<transaction_safe_dynamic%> may only be specified for "
"a virtual function"); "a virtual function");
} }
} }
/* FN is a constructor or destructor. Clone the declaration to create /* 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 /* For each destructor, we need three variants: an in-charge
version, a not-in-charge version, and an in-charge deleting version, a not-in-charge version, and an in-charge deleting
version. We clone the deleting version first because that 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 corresponds to the correct layout order in the virtual
function table. function table.
@ -5174,11 +5186,10 @@ set_method_tm_attributes (tree t)
/* Any method that does not yet have a tm attribute inherits /* Any method that does not yet have a tm attribute inherits
the one from the class. */ the one from the class. */
for (fndecl = TYPE_METHODS (t); fndecl; fndecl = TREE_CHAIN (fndecl)) for (fndecl = TYPE_FIELDS (t); fndecl; fndecl = DECL_CHAIN (fndecl))
{ if (DECL_DECLARES_FUNCTION_P (fndecl)
if (!find_tm_attribute (TYPE_ATTRIBUTES (TREE_TYPE (fndecl)))) && !find_tm_attribute (TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
apply_tm_attr (fndecl, class_tm_attr); apply_tm_attr (fndecl, class_tm_attr);
}
} }
/* Returns true if FN is a default constructor. */ /* 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. */ /* C++14 DR 1684 removed this restriction. */
if (cxx_dialect < cxx14 if (cxx_dialect < cxx14
&& !CLASSTYPE_LITERAL_P (t) && !LAMBDA_TYPE_P (t)) && !CLASSTYPE_LITERAL_P (t) && !LAMBDA_TYPE_P (t))
for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn)) for (fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
if (DECL_DECLARED_CONSTEXPR_P (fn) if (TREE_CODE (fn) == FUNCTION_DECL
&& TREE_CODE (fn) != TEMPLATE_DECL && DECL_DECLARED_CONSTEXPR_P (fn)
&& DECL_NONSTATIC_MEMBER_FUNCTION_P (fn) && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
&& !DECL_CONSTRUCTOR_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 /* Check defaulted declarations here so we have cant_have_const_ctor
and don't need to worry about clones. */ and don't need to worry about clones. */
for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn)) for (fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
if (!DECL_ARTIFICIAL (fn) && DECL_DEFAULTED_IN_CLASS_P (fn)) if (DECL_DECLARES_FUNCTION_P (fn)
&& !DECL_ARTIFICIAL (fn)
&& DECL_DEFAULTED_IN_CLASS_P (fn))
{ {
int copy = copy_fn_p (fn); int copy = copy_fn_p (fn);
if (copy > 0) if (copy > 0)
@ -5984,7 +5997,7 @@ create_vtable_ptr (tree t, tree* virtuals_p)
tree fn; tree fn;
/* Collect the virtual functions declared in T. */ /* 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 if (TREE_CODE (fn) == FUNCTION_DECL
&& DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn) && DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)
&& TREE_CODE (DECL_VINDEX (fn)) != INTEGER_CST) && 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 inline at the point of class definition. On some targets the
key function may not be inline; those targets should not call key function may not be inline; those targets should not call
this function until the end of the translation unit. */ this function until the end of the translation unit. */
for (method = TYPE_METHODS (type); method != NULL_TREE; for (method = TYPE_FIELDS (type); method; method = DECL_CHAIN (method))
method = DECL_CHAIN (method))
if (TREE_CODE (method) == FUNCTION_DECL if (TREE_CODE (method) == FUNCTION_DECL
&& DECL_VINDEX (method) != NULL_TREE && DECL_VINDEX (method) != NULL_TREE
&& ! DECL_DECLARED_INLINE_P (method) && ! 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 /* The following lists are all in reverse order. Put them in
declaration order now. */ declaration order now. */
TYPE_METHODS (t) = nreverse (TYPE_METHODS (t));
CLASSTYPE_DECL_LIST (t) = nreverse (CLASSTYPE_DECL_LIST (t)); CLASSTYPE_DECL_LIST (t) = nreverse (CLASSTYPE_DECL_LIST (t));
/* Actually, for the TYPE_FIELDS, only the non TYPE_DECLs are in /* For the TYPE_FIELDS, only the non TYPE_DECLs are in reverse
reverse order, so we can't just use nreverse. */ order, so we can't just use nreverse. Due to stat_hack
chicanery in finish_member_declarations. */
prev = NULL_TREE; prev = NULL_TREE;
for (x = TYPE_FIELDS (t); for (x = TYPE_FIELDS (t);
x && TREE_CODE (x) != TYPE_DECL; x && TREE_CODE (x) != TYPE_DECL;
@ -7350,6 +7362,7 @@ unreverse_member_declarations (tree t)
DECL_CHAIN (x) = prev; DECL_CHAIN (x) = prev;
prev = x; prev = x;
} }
if (prev) if (prev)
{ {
DECL_CHAIN (TYPE_FIELDS (t)) = x; 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 CLASSTYPE_PURE_VIRTUALS contains the list of the inline friends
(see CLASSTYPE_INLINE_FRIENDS) so we need to clear it. */ (see CLASSTYPE_INLINE_FRIENDS) so we need to clear it. */
CLASSTYPE_PURE_VIRTUALS (t) = NULL; CLASSTYPE_PURE_VIRTUALS (t) = NULL;
for (x = TYPE_METHODS (t); x; x = DECL_CHAIN (x)) for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
if (DECL_PURE_VIRTUAL_P (x)) if (TREE_CODE (x) == FUNCTION_DECL && DECL_PURE_VIRTUAL_P (x))
vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), x); vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), x);
complete_vars (t); complete_vars (t);
/* We need to add the target functions to the CLASSTYPE_METHOD_VEC if /* 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 (x) = TYPE_SIZE (t);
TYPE_SIZE_UNIT (x) = TYPE_SIZE_UNIT (t); TYPE_SIZE_UNIT (x) = TYPE_SIZE_UNIT (t);
TYPE_FIELDS (x) = TYPE_FIELDS (t); TYPE_FIELDS (x) = TYPE_FIELDS (t);
TYPE_METHODS (x) = TYPE_METHODS (t);
} }
} }
else 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 /* The ABI requires that the methods be processed in declaration
order. */ order. */
for (orig_fn = TYPE_METHODS (BINFO_TYPE (binfo)); for (orig_fn = TYPE_FIELDS (BINFO_TYPE (binfo));
orig_fn; orig_fn;
orig_fn = DECL_CHAIN (orig_fn)) orig_fn = DECL_CHAIN (orig_fn))
if (TREE_CODE (orig_fn) == FUNCTION_DECL && DECL_VINDEX (orig_fn)) if (TREE_CODE (orig_fn) == FUNCTION_DECL && DECL_VINDEX (orig_fn))

View File

@ -4549,8 +4549,6 @@ push_throw_library_fn (tree name, tree type)
void void
fixup_anonymous_aggr (tree t) fixup_anonymous_aggr (tree t)
{ {
tree *q;
/* Wipe out memory of synthesized methods. */ /* Wipe out memory of synthesized methods. */
TYPE_HAS_USER_CONSTRUCTOR (t) = 0; TYPE_HAS_USER_CONSTRUCTOR (t) = 0;
TYPE_HAS_DEFAULT_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_COPY_ASSIGN (t) = 0;
TYPE_HAS_CONST_COPY_ASSIGN (t) = 0; TYPE_HAS_CONST_COPY_ASSIGN (t) = 0;
/* Splice the implicitly generated functions out of the TYPE_METHODS /* Splice the implicitly generated functions out of TYPE_FIELDS. */
list. */ for (tree probe, *prev_p = &TYPE_FIELDS (t); (probe = *prev_p);)
q = &TYPE_METHODS (t); if (TREE_CODE (probe) == FUNCTION_DECL && DECL_ARTIFICIAL (probe))
while (*q) *prev_p = DECL_CHAIN (probe);
{ else
if (DECL_ARTIFICIAL (*q)) prev_p = &DECL_CHAIN (probe);
*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");
}
/* Anonymous aggregates cannot have fields with ctors, dtors or complex /* Anonymous aggregates cannot have fields with ctors, dtors or complex
assignment operators (because they cannot have these methods themselves). assignment operators (because they cannot have these methods themselves).

View File

@ -2592,6 +2592,7 @@ reset_decl_linkage (tree decl)
determine_visibility (decl); determine_visibility (decl);
tentative_decl_linkage (decl); tentative_decl_linkage (decl);
} }
static void static void
reset_type_linkage_2 (tree type) 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)) for (tree m = TYPE_FIELDS (type); m; m = DECL_CHAIN (m))
{ {
tree mem = STRIP_TEMPLATE (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); 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), binding_table_foreach (CLASSTYPE_NESTED_UTDS (type),
bt_reset_linkage_2, NULL); bt_reset_linkage_2, NULL);
} }
} }
static void static void
bt_reset_linkage_2 (binding_entry b, void */*data*/) 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 if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_DELETED_FN (decl)) && DECL_DELETED_FN (decl))
{ {
if (DECL_ARTIFICIAL (decl)) if (DECL_ARTIFICIAL (decl)
{ && DECL_OVERLOADED_OPERATOR_P (decl) == TYPE_EXPR
if (DECL_OVERLOADED_OPERATOR_P (decl) == TYPE_EXPR && LAMBDA_TYPE_P (DECL_CONTEXT (decl)))
&& 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. */
/* We mark a lambda conversion op as deleted if we can't sorry ("converting lambda which uses %<...%> to function pointer");
generate it properly; see maybe_add_lambda_conv_op. */ else if (complain & tf_error)
sorry ("converting lambda which uses %<...%> to "
"function pointer");
return false;
}
}
if (complain & tf_error)
{ {
error ("use of deleted function %qD", decl); error ("use of deleted function %qD", decl);
if (!maybe_explain_implicit_delete (decl)) if (!maybe_explain_implicit_delete (decl))

View File

@ -2246,8 +2246,10 @@ after_nsdmi_defaulted_late_checks (tree t)
return; return;
if (t == error_mark_node) if (t == error_mark_node)
return; return;
for (tree fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn)) for (tree fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
if (!DECL_ARTIFICIAL (fn) && DECL_DEFAULTED_IN_CLASS_P (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)); tree fn_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
if (UNEVALUATED_NOEXCEPT_SPEC_P (fn_spec)) 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_move_assignment
|| sfk == sfk_copy_assignment) || sfk == sfk_copy_assignment)
check_for_override (fn, type); check_for_override (fn, type);
/* Add it to CLASSTYPE_METHOD_VEC. */ /* Add it to CLASSTYPE_METHOD_VEC. */
bool added = add_method (type, fn, false); bool added = add_method (type, fn, false);
gcc_assert (added); gcc_assert (added);
/* Add it to TYPE_METHODS. */
/* Add it to TYPE_FIELDS. */
if (sfk == sfk_destructor if (sfk == sfk_destructor
&& DECL_VIRTUAL_P (fn)) && DECL_VIRTUAL_P (fn))
/* The ABI requires that a virtual destructor go at the end of the /* The ABI requires that a virtual destructor go at the end of the
vtable. */ vtable. */
TYPE_METHODS (type) = chainon (TYPE_METHODS (type), fn); TYPE_FIELDS (type) = chainon (TYPE_FIELDS (type), fn);
else else
{ {
DECL_CHAIN (fn) = TYPE_METHODS (type); DECL_CHAIN (fn) = TYPE_FIELDS (type);
TYPE_METHODS (type) = fn; TYPE_FIELDS (type) = fn;
} }
/* Propagate TYPE_FIELDS. */
fixup_type_variants (type);
maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0); maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0);
if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn) if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
|| DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)) || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))

View File

@ -326,7 +326,7 @@ maybe_thunk_body (tree fn, bool force)
} }
args = XALLOCAVEC (tree, max_parms); 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) FOR_EACH_CLONE (clone, fn)
{ {
tree clone_parm; tree clone_parm;
@ -447,7 +447,7 @@ maybe_clone_body (tree fn)
if (!tree_versionable_function_p (fn)) if (!tree_versionable_function_p (fn))
need_alias = true; 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. */ list. */
push_to_top_level (); push_to_top_level ();
for (idx = 0; idx < 3; idx++) for (idx = 0; idx < 3; idx++)
@ -516,7 +516,7 @@ maybe_clone_body (tree fn)
/* Emit the DWARF1 abstract instance. */ /* Emit the DWARF1 abstract instance. */
(*debug_hooks->deferred_inline_function) (fn); (*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++) for (idx = 0; idx < 3; idx++)
{ {
tree parm; tree parm;

View File

@ -10551,7 +10551,6 @@ instantiate_class_template_1 (tree type)
} }
else if (DECL_DECLARES_FUNCTION_P (t)) else if (DECL_DECLARES_FUNCTION_P (t))
{ {
/* Build new TYPE_METHODS. */
tree r; tree r;
if (TREE_CODE (t) == TEMPLATE_DECL) 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 instantiated along with their containing function. And this
way we don't have to deal with pushing out of one local class way we don't have to deal with pushing out of one local class
to instantiate a member of another local class. */ to instantiate a member of another local class. */
tree fn;
/* Closures are handled by the LAMBDA_EXPR. */ /* Closures are handled by the LAMBDA_EXPR. */
gcc_assert (!LAMBDA_TYPE_P (TREE_TYPE (t))); gcc_assert (!LAMBDA_TYPE_P (TREE_TYPE (t)));
complete_type (tmp); complete_type (tmp);
for (fn = TYPE_METHODS (tmp); fn; fn = DECL_CHAIN (fn)) for (tree fld = TYPE_FIELDS (tmp); fld; fld = DECL_CHAIN (fld))
if (!DECL_ARTIFICIAL (fn)) if ((VAR_P (fld)
instantiate_decl (fn, /*defer_ok=*/false, || (TREE_CODE (fld) == FUNCTION_DECL
&& !DECL_ARTIFICIAL (fld)))
&& DECL_TEMPLATE_INSTANTIATION (fld))
instantiate_decl (fld, /*defer_ok=*/false,
/*expl_inst_class=*/false); /*expl_inst_class=*/false);
} }
break; break;
@ -22133,18 +22134,6 @@ bt_instantiate_type_proc (binding_entry entry, void *data)
do_type_instantiation (TYPE_MAIN_DECL (entry->type), storage, 0); 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 /* Perform an explicit instantiation of template class T. STORAGE, if
non-null, is the RID for extern, inline or static. COMPLAIN is non-null, is the RID for extern, inline or static. COMPLAIN is
nonzero if this is called from the parser, zero if called recursively, 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) if (nomem_p)
return; return;
{ /* In contrast to implicit instantiation, where only the
tree tmp; 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] [temp.explicit]
@ -22268,27 +22254,28 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
previously explicitly specialized in the translation unit previously explicitly specialized in the translation unit
containing the explicit instantiation. containing the explicit instantiation.
Of course, we can't instantiate member template classes, since Of course, we can't instantiate member template classes, since we
we don't have any arguments for them. Note that the standard don't have any arguments for them. Note that the standard is
is unclear on whether the instantiation of the members are unclear on whether the instantiation of the members are
*explicit* instantiations or not. However, the most natural *explicit* instantiations or not. However, the most natural
interpretation is that it should be an explicit instantiation. */ 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 (! static_p) if (CLASSTYPE_NESTED_UTDS (t))
for (tmp = TYPE_METHODS (t); tmp; tmp = DECL_CHAIN (tmp)) binding_table_foreach (CLASSTYPE_NESTED_UTDS (t),
if (TREE_CODE (tmp) == FUNCTION_DECL bt_instantiate_type_proc, &storage);
&& 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);
}
} }
/* Given a function DECL, which is a specialization of TMPL, modify /* Given a function DECL, which is a specialization of TMPL, modify
@ -23080,19 +23067,20 @@ instantiate_pending_templates (int retries)
if (TYPE_P (instantiation)) if (TYPE_P (instantiation))
{ {
tree fn;
if (!COMPLETE_TYPE_P (instantiation)) if (!COMPLETE_TYPE_P (instantiation))
{ {
instantiate_class_template (instantiation); instantiate_class_template (instantiation);
if (CLASSTYPE_TEMPLATE_INSTANTIATION (instantiation)) if (CLASSTYPE_TEMPLATE_INSTANTIATION (instantiation))
for (fn = TYPE_METHODS (instantiation); for (tree fld = TYPE_FIELDS (instantiation);
fn; fld; fld = TREE_CHAIN (fld))
fn = TREE_CHAIN (fn)) if ((VAR_P (fld)
if (! DECL_ARTIFICIAL (fn)) || (TREE_CODE (fld) == FUNCTION_DECL
instantiate_decl (fn, && !DECL_ARTIFICIAL (fld)))
&& DECL_TEMPLATE_INSTANTIATION (fld))
instantiate_decl (fld,
/*defer_ok=*/false, /*defer_ok=*/false,
/*expl_inst_class_mem_p=*/false); /*expl_inst_class_mem_p=*/false);
if (COMPLETE_TYPE_P (instantiation)) if (COMPLETE_TYPE_P (instantiation))
reconsider = 1; reconsider = 1;
} }

View File

@ -444,6 +444,10 @@ lookup_field_1 (tree type, tree name, bool want_type)
{ {
tree decl = field; tree decl = field;
if (DECL_DECLARES_FUNCTION_P (decl))
/* Functions are kep separately, at the moment. */
continue;
if (GATHER_STATISTICS) if (GATHER_STATISTICS)
n_fields_searched++; n_fields_searched++;

View File

@ -3037,9 +3037,9 @@ finish_member_declaration (tree decl)
if (DECL_LANG_SPECIFIC (decl) && DECL_LANGUAGE (decl) == lang_c) if (DECL_LANG_SPECIFIC (decl) && DECL_LANGUAGE (decl) == lang_c)
SET_DECL_LANGUAGE (decl, lang_cplusplus); SET_DECL_LANGUAGE (decl, lang_cplusplus);
/* Put functions on the TYPE_METHODS list and everything else on the /* Put the decl on the TYPE_FIELDS list. Note that this is built up
TYPE_FIELDS list. Note that these are built up in reverse order. in reverse order. We reverse it (to obtain declaration order) in
We reverse them (to obtain declaration order) in finish_struct. */ finish_struct. */
if (DECL_DECLARES_FUNCTION_P (decl)) if (DECL_DECLARES_FUNCTION_P (decl))
{ {
/* We also need to add this function to the /* 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)) if (add_method (current_class_type, decl, false))
{ {
gcc_assert (TYPE_MAIN_VARIANT (current_class_type) == current_class_type); gcc_assert (TYPE_MAIN_VARIANT (current_class_type) == current_class_type);
DECL_CHAIN (decl) = TYPE_METHODS (current_class_type); DECL_CHAIN (decl) = TYPE_FIELDS (current_class_type);
TYPE_METHODS (current_class_type) = decl; TYPE_FIELDS (current_class_type) = decl;
maybe_add_class_template_decl_list (current_class_type, decl, maybe_add_class_template_decl_list (current_class_type, decl,
/*friend_p=*/0); /*friend_p=*/0);
@ -5794,7 +5794,7 @@ finish_omp_declare_simd_methods (tree t)
if (processing_template_decl) if (processing_template_decl)
return; 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) if (TREE_CODE (TREE_TYPE (x)) != METHOD_TYPE)
continue; continue;

View File

@ -1481,6 +1481,8 @@ dbxout_type_fields (tree type)
/* Omit here local type decls until we know how to support them. */ /* Omit here local type decls until we know how to support them. */
if (TREE_CODE (tem) == TYPE_DECL if (TREE_CODE (tem) == TYPE_DECL
|| TREE_CODE (tem) == TEMPLATE_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. */ /* Omit here the nameless fields that are used to skip bits. */
|| DECL_IGNORED_P (tem) || DECL_IGNORED_P (tem)
/* Omit fields whose position or size are variable or too large to /* Omit fields whose position or size are variable or too large to
@ -1586,55 +1588,38 @@ dbxout_type_method_1 (tree decl)
} }
} }
/* Subroutine of `dbxout_type'. Output debug info about the methods defined /* Subroutine of `dbxout_type'. Output debug info about the member
in TYPE. */ functions defined in TYPE. */
static void static void
dbxout_type_methods (tree type) dbxout_type_methods (tree type)
{ {
/* C++: put out the method names and their parameter lists */ for (tree fndecl = TYPE_FIELDS (type); fndecl;)
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)
{ {
int need_prefix = 1; int need_prefix = 1;
/* Group together all the methods for the same operation. /* Group together all the methods for the same operation.
These differ in the types of the arguments. */ 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 && (last == NULL_TREE || DECL_NAME (fndecl) == DECL_NAME (last));
fndecl = DECL_CHAIN (fndecl)) fndecl = DECL_CHAIN (fndecl))
/* Output the name of the field (after overloading), as /* Output the name of the field (after overloading), as
well as the name of the field before overloading, along well as the name of the field before overloading, along
with its parameter list */ with its parameter list */
{ {
/* Skip methods that aren't FUNCTION_DECLs. (In C++, these /* Skip non-functions. */
include TEMPLATE_DECLs.) The debugger doesn't know what
to do with such entities anyhow. */
if (TREE_CODE (fndecl) != FUNCTION_DECL) if (TREE_CODE (fndecl) != FUNCTION_DECL)
continue; continue;
CONTIN;
last = fndecl;
/* Also ignore abstract methods; those are only interesting to /* Also ignore abstract methods; those are only interesting to
the DWARF backends. */ the DWARF backends. */
if (DECL_IGNORED_P (fndecl) || DECL_ABSTRACT_P (fndecl)) if (DECL_IGNORED_P (fndecl) || DECL_ABSTRACT_P (fndecl))
continue; continue;
CONTIN;
last = fndecl;
/* Redundantly output the plain name, since that's what gdb /* Redundantly output the plain name, since that's what gdb
expects. */ expects. */
if (need_prefix) if (need_prefix)
@ -2209,10 +2194,8 @@ dbxout_type (tree type, int full)
/* Write out the field declarations. */ /* Write out the field declarations. */
dbxout_type_fields (type); dbxout_type_fields (type);
if (use_gnu_debug_info_extensions && TYPE_METHODS (type) != NULL_TREE) if (use_gnu_debug_info_extensions)
{ dbxout_type_methods (type);
dbxout_type_methods (type);
}
stabstr_C (';'); stabstr_C (';');

View File

@ -24032,7 +24032,8 @@ gen_member_die (tree type, dw_die_ref context_die)
{ {
tree member; tree member;
tree binfo = TYPE_BINFO (type); 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 /* 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 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) && (lang_hooks.decls.decl_dwarf_attribute (member, DW_AT_inline)
!= -1)); != -1));
/* Ignore clones. */
if (DECL_ABSTRACT_ORIGIN (member))
continue;
/* If we thought we were generating minimal debug info for TYPE /* If we thought we were generating minimal debug info for TYPE
and then changed our minds, some of the member declarations and then changed our minds, some of the member declarations
may have already been defined. Don't define them again, but may have already been defined. Don't define them again, but
do put them in the right order. */ do put them in the right order. */
child = lookup_decl_die (member); if (dw_die_ref child = lookup_decl_die (member))
if (child)
{ {
/* Handle inline static data members, which only have in-class /* Handle inline static data members, which only have in-class
declarations. */ declarations. */
@ -24103,6 +24107,7 @@ gen_member_die (tree type, dw_die_ref context_die)
static_inline_p = false; static_inline_p = false;
} }
} }
if (child->die_tag == DW_TAG_variable if (child->die_tag == DW_TAG_variable
&& child->die_parent == comp_unit_die () && child->die_parent == comp_unit_die ()
&& ref == NULL) && ref == NULL)
@ -24141,23 +24146,6 @@ gen_member_die (tree type, dw_die_ref context_die)
DECL_EXTERNAL (member) = old_extern; 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 /* Generate a DIE for a structure or union type. If TYPE_DECL_SUPPRESS_DEBUG

View File

@ -2218,20 +2218,11 @@ use_register_for_decl (const_tree decl)
if (!DECL_REGISTER (decl)) if (!DECL_REGISTER (decl))
return false; return false;
switch (TREE_CODE (TREE_TYPE (decl))) /* When not optimizing, disregard register keyword for types that
{ could have methods, otherwise the methods won't be callable from
case RECORD_TYPE: the debugger. */
case UNION_TYPE: if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)))
case QUAL_UNION_TYPE: return false;
/* 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;
}
return true; return true;
} }

View File

@ -1602,62 +1602,6 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
return false; 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; break;
} }

View 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> 2017-07-19 Nathan Sidwell <nathan@acm.org>
* objc-act.h (CLASS_NST_METHODS, CLASS_CLS_METHODS): Use * objc-act.h (CLASS_NST_METHODS, CLASS_CLS_METHODS): Use

View File

@ -528,34 +528,32 @@ build_ivar_list_initializer (tree type, tree field_decl)
{ {
vec<constructor_elt, va_gc> *inits = NULL; vec<constructor_elt, va_gc> *inits = NULL;
do 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; vec<constructor_elt, va_gc> *ivar = NULL;
tree id;
/* Set name. */ /* Set name. */
if (DECL_NAME (field_decl)) if (DECL_NAME (field_decl))
CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
add_objc_string (DECL_NAME (field_decl), add_objc_string (DECL_NAME (field_decl),
meth_var_names)); meth_var_names));
else else
/* Unnamed bit-field ivar (yuck). */ /* Unnamed bit-field ivar (yuck). */
CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0)); CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
build_int_cst (NULL_TREE, 0));
/* Set type. */ /* Set type. */
id = add_objc_string (encode_field_decl (field_decl), id = add_objc_string (encode_field_decl (field_decl),
meth_var_types); meth_var_types);
CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id); CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
/* Set offset. */ /* Set offset. */
CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl)); CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
objc_build_constructor (type, ivar)); objc_build_constructor (type, ivar));
do
field_decl = DECL_CHAIN (field_decl);
while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
} }
while (field_decl);
return objc_build_constructor (build_array_type (type, 0), inits); return objc_build_constructor (build_array_type (type, 0), inits);
} }

View 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> 2017-07-20 Jakub Jelinek <jakub@redhat.com>
PR target/80846 PR target/80846

View File

@ -3,8 +3,8 @@
struct A struct A
{ {
struct struct
{ // { dg-error "anonymous struct cannot have function members" } {
struct { static int i; }; // { dg-error "prohibits anonymous structs|non-static data members|unnamed class" } 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" } }; // { dg-error "prohibits anonymous structs" }
}; };

View File

@ -10,7 +10,7 @@
struct A struct A
{ {
union union
{ // { dg-error "" } anon union cannot have member fns {
void bad(); void bad(); // { dg-error "can only have non-static data" }
}; };
}; };

View File

@ -490,7 +490,6 @@ dequeue_and_dump (dump_info_p di)
dump_string_field (di, "tag", "union"); dump_string_field (di, "tag", "union");
dump_child ("flds", TYPE_FIELDS (t)); dump_child ("flds", TYPE_FIELDS (t));
dump_child ("fncs", TYPE_METHODS (t));
queue_and_dump_index (di, "binf", TYPE_BINFO (t), queue_and_dump_index (di, "binf", TYPE_BINFO (t),
DUMP_BINFO); DUMP_BINFO);
break; break;

View 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); dump_decl_name (pp, node, flags);
else if (TYPE_NAME (TREE_TYPE (node)) != node) else if (TYPE_NAME (TREE_TYPE (node)) != node)
{ {
if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE pp_string (pp, (TREE_CODE (TREE_TYPE (node)) == UNION_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
? "union" : "struct ")); ? "union" : "struct "));
dump_generic_node (pp, TREE_TYPE (node), spc, flags, false); dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
}
} }
else else
pp_string (pp, "<anon>"); pp_string (pp, "<anon>");

View File

@ -5217,13 +5217,15 @@ free_lang_data_in_type (tree type)
if (TYPE_VFIELD (type) && TREE_CODE (TYPE_VFIELD (type)) != FIELD_DECL) if (TYPE_VFIELD (type) && TREE_CODE (TYPE_VFIELD (type)) != FIELD_DECL)
TYPE_VFIELD (type) = NULL_TREE; TYPE_VFIELD (type) = NULL_TREE;
/* Remove TYPE_METHODS list. While it would be nice to keep it /* Splice out FUNCTION_DECLS and TEMPLATE_DECLS from
to enable ODR warnings about different method lists, doing so TYPE_FIELDS. So LTO doesn't grow. */
seems to impractically increase size of LTO data streamed. for (tree probe, *prev= &TYPE_FIELDS (type); (probe = *prev); )
Keep the information if TYPE_METHODS was non-NULL. This is used if (TREE_CODE (probe) == FUNCTION_DECL
by function.c and pretty printers. */ || TREE_CODE (probe) == TEMPLATE_DECL)
if (TYPE_METHODS (type)) *prev = probe;
TYPE_METHODS (type) = error_mark_node; else
prev = &DECL_CHAIN (probe);
if (TYPE_BINFO (type)) if (TYPE_BINFO (type))
{ {
free_lang_data_in_binfo (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. */ At this point, it is not needed anymore. */
DECL_SAVED_TREE (decl) = NULL_TREE; DECL_SAVED_TREE (decl) = NULL_TREE;
/* Clear the abstract origin if it refers to a method. Otherwise /* Clear the abstract origin if it refers to a method.
dwarf2out.c will ICE as we clear TYPE_METHODS and thus the Otherwise dwarf2out.c will ICE as we splice functions out of
origin will not be output correctly. */ TYPE_FIELDS and thus the origin will not be output
correctly. */
if (DECL_ABSTRACT_ORIGIN (decl) if (DECL_ABSTRACT_ORIGIN (decl)
&& DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl)) && DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl))
&& RECORD_OR_UNION_TYPE_P && RECORD_OR_UNION_TYPE_P
@ -6679,12 +6682,6 @@ build_distinct_type_copy (tree type MEM_STAT_DECL)
TYPE_MAIN_VARIANT (t) = t; TYPE_MAIN_VARIANT (t) = t;
TYPE_NEXT_VARIANT (t) = 0; 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 /* 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 whose TREE_TYPE is not t. This can also happen in the Ada
frontend when using subtypes. */ 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 - aggregates may have new TYPE_FIELDS list that list variants of
the main variant TYPE_FIELDS. the main variant TYPE_FIELDS.
- vector types may differ by TYPE_VECTOR_OPAQUE - 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. */ /* Convenience macro for matching individual fields. */
@ -13512,12 +13507,6 @@ verify_type_variant (const_tree t, tree tv)
} }
if (TREE_CODE (t) == METHOD_TYPE) if (TREE_CODE (t) == METHOD_TYPE)
verify_variant_match (TYPE_METHOD_BASETYPE); 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) if (TREE_CODE (t) == OFFSET_TYPE)
verify_variant_match (TYPE_OFFSET_BASETYPE); verify_variant_match (TYPE_OFFSET_BASETYPE);
if (TREE_CODE (t) == ARRAY_TYPE) if (TREE_CODE (t) == ARRAY_TYPE)
@ -14020,14 +14009,6 @@ verify_type (const_tree t)
/* Check various uses of TYPE_MAXVAL. */ /* Check various uses of TYPE_MAXVAL. */
if (RECORD_OR_UNION_TYPE_P (t)) 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) 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) == USING_DECL)
; ;
else if (TREE_CODE (fld) == FUNCTION_DECL)
;
else else
{ {
error ("Wrong tree in TYPE_FIELDS list"); error ("Wrong tree in TYPE_FIELDS list");

View File

@ -2122,8 +2122,6 @@ extern machine_mode element_mode (const_tree t);
#define TYPE_MAX_VALUE(NODE) \ #define TYPE_MAX_VALUE(NODE) \
(NUMERICAL_TYPE_CHECK (NODE)->type_non_common.maxval) (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) \ #define TYPE_METHOD_BASETYPE(NODE) \
(FUNC_OR_METHOD_CHECK (NODE)->type_non_common.maxval) (FUNC_OR_METHOD_CHECK (NODE)->type_non_common.maxval)
#define TYPE_OFFSET_BASETYPE(NODE) \ #define TYPE_OFFSET_BASETYPE(NODE) \

View 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> 2017-07-12 Nathan Sidwell <nathan@acm.org>
* libcp1plugin.cc (plugin_build_decl): Use * libcp1plugin.cc (plugin_build_decl): Use

View File

@ -1556,7 +1556,7 @@ plugin_build_decl (cc1_plugin::connection *self,
if ((ctor || dtor) if ((ctor || dtor)
/* Don't crash after a duplicate declaration of a cdtor. */ /* 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. /* ctors and dtors clones are chained after DECL.
However, we create the clones before TYPE_METHODS is 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); tree save = DECL_CHAIN (decl);
DECL_CHAIN (decl) = NULL_TREE; DECL_CHAIN (decl) = NULL_TREE;
clone_function_decl (decl, /*update_methods=*/true); clone_function_decl (decl, /*update_methods=*/true);
gcc_assert (TYPE_METHODS (current_class_type) == decl); gcc_assert (TYPE_FIELDS (current_class_type) == decl);
TYPE_METHODS (current_class_type) TYPE_FIELDS (current_class_type)
= nreverse (TYPE_METHODS (current_class_type)); = nreverse (TYPE_FIELDS (current_class_type));
DECL_CHAIN (decl) = save; DECL_CHAIN (decl) = save;
} }