mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-18 12:41:25 +08:00
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:
parent
61612fa5da
commit
5aaa8fb406
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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))
|
||||
for (tree fld = TYPE_FIELDS (TREE_TYPE (t));
|
||||
fld; fld = TREE_CHAIN (fld))
|
||||
{
|
||||
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))
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
176
gcc/cp/class.c
176
gcc/cp/class.c
@ -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);
|
||||
|
||||
for (x = TYPE_METHODS (t); x; x = DECL_CHAIN (x))
|
||||
{
|
||||
check_for_override (x, t);
|
||||
if (DECL_PURE_VIRTUAL_P (x) && (TREE_CODE (x) != FUNCTION_DECL || ! DECL_VINDEX (x)))
|
||||
error ("initializer specified for non-virtual method %q+D", x);
|
||||
/* The name of the field is the original field name
|
||||
Save this in auxiliary field for later overloading. */
|
||||
if (TREE_CODE (x) == FUNCTION_DECL && DECL_VINDEX (x))
|
||||
{
|
||||
TYPE_POLYMORPHIC_P (t) = 1;
|
||||
if (DECL_PURE_VIRTUAL_P (x))
|
||||
vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), x);
|
||||
}
|
||||
/* All user-provided destructors are non-trivial.
|
||||
Constructors and assignment ops are handled in
|
||||
grok_special_member_properties. */
|
||||
if (DECL_DESTRUCTOR_P (x) && user_provided_p (x))
|
||||
TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 1;
|
||||
if (!DECL_VIRTUAL_P (x)
|
||||
&& lookup_attribute ("transaction_safe_dynamic", DECL_ATTRIBUTES (x)))
|
||||
error_at (DECL_SOURCE_LOCATION (x),
|
||||
"%<transaction_safe_dynamic%> may only be specified for "
|
||||
"a virtual function");
|
||||
}
|
||||
if (DECL_PURE_VIRTUAL_P (x)
|
||||
&& (TREE_CODE (x) != FUNCTION_DECL || ! DECL_VINDEX (x)))
|
||||
error ("initializer specified for non-virtual method %q+D", x);
|
||||
/* The name of the field is the original field name
|
||||
Save this in auxiliary field for later overloading. */
|
||||
if (TREE_CODE (x) == FUNCTION_DECL && DECL_VINDEX (x))
|
||||
{
|
||||
TYPE_POLYMORPHIC_P (t) = 1;
|
||||
if (DECL_PURE_VIRTUAL_P (x))
|
||||
vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), x);
|
||||
}
|
||||
|
||||
/* All user-provided destructors are non-trivial.
|
||||
Constructors and assignment ops are handled in
|
||||
grok_special_member_properties. */
|
||||
if (DECL_DESTRUCTOR_P (x) && user_provided_p (x))
|
||||
TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 1;
|
||||
if (!DECL_VIRTUAL_P (x)
|
||||
&& lookup_attribute ("transaction_safe_dynamic",
|
||||
DECL_ATTRIBUTES (x)))
|
||||
error_at (DECL_SOURCE_LOCATION (x),
|
||||
"%<transaction_safe_dynamic%> may only be specified for "
|
||||
"a virtual function");
|
||||
}
|
||||
}
|
||||
|
||||
/* FN is a constructor or destructor. Clone the declaration to create
|
||||
@ -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))
|
||||
|
@ -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).
|
||||
|
@ -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))
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
|
88
gcc/cp/pt.c
88
gcc/cp/pt.c
@ -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. */
|
||||
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 (! 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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -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++;
|
||||
|
||||
|
@ -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;
|
||||
|
43
gcc/dbxout.c
43
gcc/dbxout.c
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 (';');
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
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 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 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);
|
||||
/* 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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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" }
|
||||
};
|
||||
|
@ -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" }
|
||||
};
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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>");
|
||||
|
47
gcc/tree.c
47
gcc/tree.c
@ -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");
|
||||
|
@ -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) \
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user