diff options
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r-- | gcc/cp/class.c | 176 |
1 files changed, 94 insertions, 82 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 4b9b93a..eac6649 100644 --- a/gcc/cp/class.c +++ b/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); + + if (DECL_PURE_VIRTUAL_P (x) + && (TREE_CODE (x) != FUNCTION_DECL || ! DECL_VINDEX (x))) + error ("initializer specified for non-virtual method %q+D", x); + /* The name of the field is the original field name + Save this in auxiliary field for later overloading. */ + if (TREE_CODE (x) == FUNCTION_DECL && DECL_VINDEX (x)) + { + TYPE_POLYMORPHIC_P (t) = 1; + if (DECL_PURE_VIRTUAL_P (x)) + vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), x); + } - for (x = TYPE_METHODS (t); x; x = DECL_CHAIN (x)) - { - check_for_override (x, t); - if (DECL_PURE_VIRTUAL_P (x) && (TREE_CODE (x) != FUNCTION_DECL || ! DECL_VINDEX (x))) - error ("initializer specified for non-virtual method %q+D", x); - /* The name of the field is the original field name - Save this in auxiliary field for later overloading. */ - if (TREE_CODE (x) == FUNCTION_DECL && DECL_VINDEX (x)) - { - TYPE_POLYMORPHIC_P (t) = 1; - if (DECL_PURE_VIRTUAL_P (x)) - vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), x); - } - /* All user-provided destructors are non-trivial. - Constructors and assignment ops are handled in - grok_special_member_properties. */ - if (DECL_DESTRUCTOR_P (x) && user_provided_p (x)) - TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 1; - if (!DECL_VIRTUAL_P (x) - && lookup_attribute ("transaction_safe_dynamic", DECL_ATTRIBUTES (x))) - error_at (DECL_SOURCE_LOCATION (x), - "%<transaction_safe_dynamic%> may only be specified for " - "a virtual function"); - } + /* All user-provided destructors are non-trivial. + Constructors and assignment ops are handled in + grok_special_member_properties. */ + if (DECL_DESTRUCTOR_P (x) && user_provided_p (x)) + TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 1; + if (!DECL_VIRTUAL_P (x) + && lookup_attribute ("transaction_safe_dynamic", + DECL_ATTRIBUTES (x))) + error_at (DECL_SOURCE_LOCATION (x), + "%<transaction_safe_dynamic%> may only be specified for " + "a virtual function"); + } } /* FN is a constructor or destructor. Clone the declaration to create @@ -4902,7 +4914,7 @@ clone_function_decl (tree fn, bool update_methods) /* For each destructor, we need three variants: an in-charge version, a not-in-charge version, and an in-charge deleting version. We clone the deleting version first because that - means it will go second on the TYPE_METHODS list -- and that + means it will go second on the TYPE_FIELDS list -- and that corresponds to the correct layout order in the virtual function table. @@ -5174,11 +5186,10 @@ set_method_tm_attributes (tree t) /* Any method that does not yet have a tm attribute inherits the one from the class. */ - for (fndecl = TYPE_METHODS (t); fndecl; fndecl = TREE_CHAIN (fndecl)) - { - if (!find_tm_attribute (TYPE_ATTRIBUTES (TREE_TYPE (fndecl)))) - apply_tm_attr (fndecl, class_tm_attr); - } + for (fndecl = TYPE_FIELDS (t); fndecl; fndecl = DECL_CHAIN (fndecl)) + if (DECL_DECLARES_FUNCTION_P (fndecl) + && !find_tm_attribute (TYPE_ATTRIBUTES (TREE_TYPE (fndecl)))) + apply_tm_attr (fndecl, class_tm_attr); } /* Returns true if FN is a default constructor. */ @@ -5660,9 +5671,9 @@ finalize_literal_type_property (tree t) /* C++14 DR 1684 removed this restriction. */ if (cxx_dialect < cxx14 && !CLASSTYPE_LITERAL_P (t) && !LAMBDA_TYPE_P (t)) - for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn)) - if (DECL_DECLARED_CONSTEXPR_P (fn) - && TREE_CODE (fn) != TEMPLATE_DECL + for (fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn)) + if (TREE_CODE (fn) == FUNCTION_DECL + && DECL_DECLARED_CONSTEXPR_P (fn) && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn) && !DECL_CONSTRUCTOR_P (fn)) { @@ -5924,8 +5935,10 @@ check_bases_and_members (tree t) /* Check defaulted declarations here so we have cant_have_const_ctor and don't need to worry about clones. */ - for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn)) - if (!DECL_ARTIFICIAL (fn) && DECL_DEFAULTED_IN_CLASS_P (fn)) + for (fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn)) + if (DECL_DECLARES_FUNCTION_P (fn) + && !DECL_ARTIFICIAL (fn) + && DECL_DEFAULTED_IN_CLASS_P (fn)) { int copy = copy_fn_p (fn); if (copy > 0) @@ -5984,7 +5997,7 @@ create_vtable_ptr (tree t, tree* virtuals_p) tree fn; /* Collect the virtual functions declared in T. */ - for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn)) + for (fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn)) if (TREE_CODE (fn) == FUNCTION_DECL && DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn) && TREE_CODE (DECL_VINDEX (fn)) != INTEGER_CST) @@ -6643,8 +6656,7 @@ determine_key_method (tree type) inline at the point of class definition. On some targets the key function may not be inline; those targets should not call this function until the end of the translation unit. */ - for (method = TYPE_METHODS (type); method != NULL_TREE; - method = DECL_CHAIN (method)) + for (method = TYPE_FIELDS (type); method; method = DECL_CHAIN (method)) if (TREE_CODE (method) == FUNCTION_DECL && DECL_VINDEX (method) != NULL_TREE && ! DECL_DECLARED_INLINE_P (method) @@ -7336,11 +7348,11 @@ unreverse_member_declarations (tree t) /* The following lists are all in reverse order. Put them in declaration order now. */ - TYPE_METHODS (t) = nreverse (TYPE_METHODS (t)); CLASSTYPE_DECL_LIST (t) = nreverse (CLASSTYPE_DECL_LIST (t)); - /* Actually, for the TYPE_FIELDS, only the non TYPE_DECLs are in - reverse order, so we can't just use nreverse. */ + /* For the TYPE_FIELDS, only the non TYPE_DECLs are in reverse + order, so we can't just use nreverse. Due to stat_hack + chicanery in finish_member_declarations. */ prev = NULL_TREE; for (x = TYPE_FIELDS (t); x && TREE_CODE (x) != TYPE_DECL; @@ -7350,6 +7362,7 @@ unreverse_member_declarations (tree t) DECL_CHAIN (x) = prev; prev = x; } + if (prev) { DECL_CHAIN (TYPE_FIELDS (t)) = x; @@ -7390,8 +7403,8 @@ finish_struct (tree t, tree attributes) CLASSTYPE_PURE_VIRTUALS contains the list of the inline friends (see CLASSTYPE_INLINE_FRIENDS) so we need to clear it. */ CLASSTYPE_PURE_VIRTUALS (t) = NULL; - for (x = TYPE_METHODS (t); x; x = DECL_CHAIN (x)) - if (DECL_PURE_VIRTUAL_P (x)) + for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x)) + if (TREE_CODE (x) == FUNCTION_DECL && DECL_PURE_VIRTUAL_P (x)) vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), x); complete_vars (t); /* We need to add the target functions to the CLASSTYPE_METHOD_VEC if @@ -7416,7 +7429,6 @@ finish_struct (tree t, tree attributes) TYPE_SIZE (x) = TYPE_SIZE (t); TYPE_SIZE_UNIT (x) = TYPE_SIZE_UNIT (t); TYPE_FIELDS (x) = TYPE_FIELDS (t); - TYPE_METHODS (x) = TYPE_METHODS (t); } } else @@ -9922,7 +9934,7 @@ add_vcall_offset_vtbl_entries_1 (tree binfo, vtbl_init_data* vid) /* The ABI requires that the methods be processed in declaration order. */ - for (orig_fn = TYPE_METHODS (BINFO_TYPE (binfo)); + for (orig_fn = TYPE_FIELDS (BINFO_TYPE (binfo)); orig_fn; orig_fn = DECL_CHAIN (orig_fn)) if (TREE_CODE (orig_fn) == FUNCTION_DECL && DECL_VINDEX (orig_fn)) |