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