aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r--gcc/cp/class.c176
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))