2017-07-14 Nathan Sidwell 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 *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), - "% 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), + "% 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" } }; };