Commit 508a1c9c by Mark Mitchell Committed by Mark Mitchell

class.c (finish_struct_methods): Remove unncessary code.

	* class.c (finish_struct_methods): Remove unncessary code.
	(add_implicitly_declared_members): Create declarations for default
	constructors and copy constructors lazily.
	* cp-tree.h (lang_type_class): Remove lazy_default_ctor and
	lazy_copy_ctor.
	(CLASSTYPE_LAZY_DEFAULT_CTOR): New macro.
	(CLASSTYPE_LAZY_COPY_CTOR): Likewise.
	* decl2.c (check_classfn): Robustify.
	(locate_dtor): Handle empty CLASSTYPE_METHOD_VEC.
	(locate_ctor): Handle lazy default constructors.
	(locate_copy): Handle lazy copy constructors.
	(implicitly_declare_fn): Make sure we're looking at the
	TYPE_MAIN_VARIANT for a class before creating functions.  Don't
	set TYPE_HAS_CONSTRUCTOR.
	(lazily_declare_fn): New function.
	* name-lookup.c (constructor_name_full): Simplify.
	* search.c (lookup_fnfields_1): Lazily create methods, as
	necessary.
	(lookup_for_overrides): Handle empty CLASSTYPE_METHOD_VEC.

From-SVN: r84851
parent 165b54c3
2004-07-16 Mark Mitchell <mark@codesourcery.com>
* class.c (finish_struct_methods): Remove unncessary code.
(add_implicitly_declared_members): Create declarations for default
constructors and copy constructors lazily.
* cp-tree.h (lang_type_class): Remove lazy_default_ctor and
lazy_copy_ctor.
(CLASSTYPE_LAZY_DEFAULT_CTOR): New macro.
(CLASSTYPE_LAZY_COPY_CTOR): Likewise.
* decl2.c (check_classfn): Robustify.
(locate_dtor): Handle empty CLASSTYPE_METHOD_VEC.
(locate_ctor): Handle lazy default constructors.
(locate_copy): Handle lazy copy constructors.
(implicitly_declare_fn): Make sure we're looking at the
TYPE_MAIN_VARIANT for a class before creating functions. Don't
set TYPE_HAS_CONSTRUCTOR.
(lazily_declare_fn): New function.
* name-lookup.c (constructor_name_full): Simplify.
* search.c (lookup_fnfields_1): Lazily create methods, as
necessary.
(lookup_for_overrides): Handle empty CLASSTYPE_METHOD_VEC.
2004-07-16 Steven Bosscher <stevenb@suse.de> 2004-07-16 Steven Bosscher <stevenb@suse.de>
* cp-tree.h (struct lang_type): Don't have three GTY options on a * cp-tree.h (struct lang_type): Don't have three GTY options on a
......
...@@ -1714,18 +1714,10 @@ finish_struct_methods (tree t) ...@@ -1714,18 +1714,10 @@ finish_struct_methods (tree t)
VEC(tree) *method_vec; VEC(tree) *method_vec;
int slot, len; int slot, len;
if (!TYPE_METHODS (t))
{
/* Clear these for safety; perhaps some parsing error could set
these incorrectly. */
TYPE_HAS_CONSTRUCTOR (t) = 0;
TYPE_HAS_DESTRUCTOR (t) = 0;
CLASSTYPE_METHOD_VEC (t) = NULL;
return;
}
method_vec = CLASSTYPE_METHOD_VEC (t); method_vec = CLASSTYPE_METHOD_VEC (t);
my_friendly_assert (method_vec, 19991215); if (!method_vec)
return;
len = VEC_length (tree, method_vec); len = VEC_length (tree, method_vec);
/* First fill in entry 0 with the constructors, entry 1 with destructors, /* First fill in entry 0 with the constructors, entry 1 with destructors,
...@@ -2554,21 +2546,17 @@ add_implicitly_declared_members (tree t, ...@@ -2554,21 +2546,17 @@ add_implicitly_declared_members (tree t,
/* Default constructor. */ /* Default constructor. */
if (! TYPE_HAS_CONSTRUCTOR (t) && ! cant_have_default_ctor) if (! TYPE_HAS_CONSTRUCTOR (t) && ! cant_have_default_ctor)
{ {
default_fn = implicitly_declare_fn (sfk_constructor, t, /*const_p=*/0); TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1;
TREE_CHAIN (default_fn) = implicit_fns; CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1;
implicit_fns = default_fn;
} }
/* Copy constructor. */ /* Copy constructor. */
if (! TYPE_HAS_INIT_REF (t) && ! TYPE_FOR_JAVA (t)) if (! TYPE_HAS_INIT_REF (t) && ! TYPE_FOR_JAVA (t))
{ {
/* ARM 12.18: You get either X(X&) or X(const X&), but TYPE_HAS_INIT_REF (t) = 1;
not both. --Chip */ TYPE_HAS_CONST_INIT_REF (t) = !cant_have_const_cctor;
default_fn CLASSTYPE_LAZY_COPY_CTOR (t) = 1;
= implicitly_declare_fn (sfk_copy_constructor, t, TYPE_HAS_CONSTRUCTOR (t) = 1;
/*const_p=*/!cant_have_const_cctor);
TREE_CHAIN (default_fn) = implicit_fns;
implicit_fns = default_fn;
} }
/* If there is no assignment operator, one will be created if and /* If there is no assignment operator, one will be created if and
......
...@@ -991,6 +991,8 @@ struct lang_type_class GTY(()) ...@@ -991,6 +991,8 @@ struct lang_type_class GTY(())
unsigned ptrmemfunc_flag : 1; unsigned ptrmemfunc_flag : 1;
unsigned was_anonymous : 1; unsigned was_anonymous : 1;
unsigned lazy_default_ctor : 1;
unsigned lazy_copy_ctor : 1;
unsigned has_const_init_ref : 1; unsigned has_const_init_ref : 1;
unsigned has_complex_init_ref : 1; unsigned has_complex_init_ref : 1;
unsigned has_complex_assign_ref : 1; unsigned has_complex_assign_ref : 1;
...@@ -1004,7 +1006,7 @@ struct lang_type_class GTY(()) ...@@ -1004,7 +1006,7 @@ struct lang_type_class GTY(())
/* There are some bits left to fill out a 32-bit word. Keep track /* There are some bits left to fill out a 32-bit word. Keep track
of this by updating the size of this bitfield whenever you add or of this by updating the size of this bitfield whenever you add or
remove a flag. */ remove a flag. */
unsigned dummy : 11; unsigned dummy : 9;
tree primary_base; tree primary_base;
tree vfields; tree vfields;
...@@ -1089,6 +1091,16 @@ struct lang_type GTY(()) ...@@ -1089,6 +1091,16 @@ struct lang_type GTY(())
#define TYPE_HAS_CONVERSION(NODE) \ #define TYPE_HAS_CONVERSION(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->h.has_type_conversion) (LANG_TYPE_CLASS_CHECK (NODE)->h.has_type_conversion)
/* Nonzero means that NODE (a class type) has a default constructor --
but that it has not yet been declared. */
#define CLASSTYPE_LAZY_DEFAULT_CTOR(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->lazy_default_ctor)
/* Nonzero means that NODE (a class type) has a copy constructor --
but that it has not yet been declared. */
#define CLASSTYPE_LAZY_COPY_CTOR(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->lazy_copy_ctor)
/* Nonzero means that this _CLASSTYPE node overloads operator=(X&). */ /* Nonzero means that this _CLASSTYPE node overloads operator=(X&). */
#define TYPE_HAS_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_assign_ref) #define TYPE_HAS_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_assign_ref)
...@@ -3884,6 +3896,7 @@ extern void finish_thunk (tree); ...@@ -3884,6 +3896,7 @@ extern void finish_thunk (tree);
extern void use_thunk (tree, bool); extern void use_thunk (tree, bool);
extern void synthesize_method (tree); extern void synthesize_method (tree);
extern tree implicitly_declare_fn (special_function_kind, tree, bool); extern tree implicitly_declare_fn (special_function_kind, tree, bool);
extern tree lazily_declare_fn (special_function_kind, tree);
extern tree skip_artificial_parms_for (tree, tree); extern tree skip_artificial_parms_for (tree, tree);
/* In optimize.c */ /* In optimize.c */
......
...@@ -693,9 +693,8 @@ check_classfn (tree ctype, tree function, tree template_parms) ...@@ -693,9 +693,8 @@ check_classfn (tree ctype, tree function, tree template_parms)
if (!fndecls && is_conv_op) if (!fndecls && is_conv_op)
{ {
if (VEC_length (tree, methods) > (size_t) ix) if (VEC_length (tree, methods) > (size_t) ++ix)
{ {
ix++;
fndecls = VEC_index (tree, methods, ix); fndecls = VEC_index (tree, methods, ix);
if (!DECL_CONV_FN_P (OVL_CURRENT (fndecls))) if (!DECL_CONV_FN_P (OVL_CURRENT (fndecls)))
{ {
......
...@@ -825,7 +825,9 @@ synthesize_exception_spec (tree type, tree (*extractor) (tree, void*), ...@@ -825,7 +825,9 @@ synthesize_exception_spec (tree type, tree (*extractor) (tree, void*),
static tree static tree
locate_dtor (tree type, void *client ATTRIBUTE_UNUSED) locate_dtor (tree type, void *client ATTRIBUTE_UNUSED)
{ {
return CLASSTYPE_DESTRUCTORS (type); return (CLASSTYPE_METHOD_VEC (type)
? CLASSTYPE_DESTRUCTORS (type)
: NULL_TREE);
} }
/* Locate the default ctor of TYPE. */ /* Locate the default ctor of TYPE. */
...@@ -838,6 +840,11 @@ locate_ctor (tree type, void *client ATTRIBUTE_UNUSED) ...@@ -838,6 +840,11 @@ locate_ctor (tree type, void *client ATTRIBUTE_UNUSED)
if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type)) if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
return NULL_TREE; return NULL_TREE;
/* Call lookup_fnfields_1 to create the constructor declarations, if
necessary. */
if (CLASSTYPE_LAZY_DEFAULT_CTOR (type))
return lazily_declare_fn (sfk_constructor, type);
for (fns = CLASSTYPE_CONSTRUCTORS (type); fns; fns = OVL_NEXT (fns)) for (fns = CLASSTYPE_CONSTRUCTORS (type); fns; fns = OVL_NEXT (fns))
{ {
tree fn = OVL_CURRENT (fns); tree fn = OVL_CURRENT (fns);
...@@ -864,21 +871,27 @@ locate_copy (tree type, void *client_) ...@@ -864,21 +871,27 @@ locate_copy (tree type, void *client_)
{ {
struct copy_data *client = (struct copy_data *)client_; struct copy_data *client = (struct copy_data *)client_;
tree fns; tree fns;
int ix = -1;
tree best = NULL_TREE; tree best = NULL_TREE;
bool excess_p = false; bool excess_p = false;
if (client->name) if (client->name)
{ {
if (TYPE_HAS_ASSIGN_REF (type)) int ix;
ix = lookup_fnfields_1 (type, client->name); ix = lookup_fnfields_1 (type, client->name);
if (ix < 0)
return NULL_TREE;
fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix);
} }
else if (TYPE_HAS_INIT_REF (type)) else if (TYPE_HAS_INIT_REF (type))
ix = CLASSTYPE_CONSTRUCTOR_SLOT; {
if (ix < 0) /* If construction of the copy constructor was postponed, create
it now. */
if (CLASSTYPE_LAZY_COPY_CTOR (type))
lazily_declare_fn (sfk_copy_constructor, type);
fns = CLASSTYPE_CONSTRUCTORS (type);
}
else
return NULL_TREE; return NULL_TREE;
fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix);
for (; fns; fns = OVL_NEXT (fns)) for (; fns; fns = OVL_NEXT (fns))
{ {
tree fn = OVL_CURRENT (fns); tree fn = OVL_CURRENT (fns);
...@@ -927,6 +940,8 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p) ...@@ -927,6 +940,8 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
tree rhs_parm_type = NULL_TREE; tree rhs_parm_type = NULL_TREE;
tree name; tree name;
type = TYPE_MAIN_VARIANT (type);
switch (kind) switch (kind)
{ {
case sfk_destructor: case sfk_destructor:
...@@ -939,12 +954,9 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p) ...@@ -939,12 +954,9 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
/* Default constructor. */ /* Default constructor. */
name = constructor_name (type); name = constructor_name (type);
raises = synthesize_exception_spec (type, &locate_ctor, 0); raises = synthesize_exception_spec (type, &locate_ctor, 0);
TYPE_HAS_CONSTRUCTOR (type) = 1;
break; break;
case sfk_copy_constructor: case sfk_copy_constructor:
TYPE_HAS_CONSTRUCTOR (type) = 1;
/* Fall through. */
case sfk_assignment_operator: case sfk_assignment_operator:
{ {
struct copy_data data; struct copy_data data;
...@@ -1019,6 +1031,47 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p) ...@@ -1019,6 +1031,47 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
return fn; return fn;
} }
/* Add an implicit declaration to TYPE for the kind of function
indicated by SFK. Return the FUNCTION_DECL for the new implicit
declaration. */
tree
lazily_declare_fn (special_function_kind sfk, tree type)
{
tree fn;
bool const_p;
/* Figure out whether or not the argument has a const reference
type. */
if (sfk == sfk_copy_constructor)
const_p = TYPE_HAS_CONST_INIT_REF (type);
else if (sfk == sfk_assignment_operator)
const_p = TYPE_HAS_CONST_ASSIGN_REF (type);
else
/* In this case, CONST_P will be ignored. */
const_p = false;
/* Declare the function. */
fn = implicitly_declare_fn (sfk, type, const_p);
/* Add it to CLASSTYPE_METHOD_VEC. */
add_method (type, fn);
/* Add it to TYPE_METHODS. */
TREE_CHAIN (fn) = TYPE_METHODS (type);
TYPE_METHODS (type) = fn;
maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0);
if (sfk == sfk_constructor || sfk == sfk_copy_constructor)
{
/* Remember that the function has been created. */
if (sfk == sfk_constructor)
CLASSTYPE_LAZY_DEFAULT_CTOR (type) = 0;
else
CLASSTYPE_LAZY_COPY_CTOR (type) = 0;
/* Create appropriate clones. */
clone_function_decl (fn, /*update_method_vec=*/true);
}
return fn;
}
/* Given a FUNCTION_DECL FN and a chain LIST, skip as many elements of LIST /* Given a FUNCTION_DECL FN and a chain LIST, skip as many elements of LIST
as there are artificial parms in FN. */ as there are artificial parms in FN. */
......
...@@ -1794,12 +1794,7 @@ set_identifier_type_value (tree id, tree decl) ...@@ -1794,12 +1794,7 @@ set_identifier_type_value (tree id, tree decl)
tree tree
constructor_name_full (tree type) constructor_name_full (tree type)
{ {
type = TYPE_MAIN_VARIANT (type); return TYPE_IDENTIFIER (TYPE_MAIN_VARIANT (type));
if (CLASS_TYPE_P (type) && TYPE_WAS_ANONYMOUS (type)
&& TYPE_HAS_CONSTRUCTOR (type))
return DECL_NAME (OVL_CURRENT (CLASSTYPE_CONSTRUCTORS (type)));
else
return TYPE_IDENTIFIER (type);
} }
/* Return the name for the constructor (or destructor) for the /* Return the name for the constructor (or destructor) for the
......
...@@ -1368,8 +1368,24 @@ lookup_fnfields_1 (tree type, tree name) ...@@ -1368,8 +1368,24 @@ lookup_fnfields_1 (tree type, tree name)
if (!CLASS_TYPE_P (type)) if (!CLASS_TYPE_P (type))
return -1; return -1;
method_vec = CLASSTYPE_METHOD_VEC (type); if (COMPLETE_TYPE_P (type))
{
if ((name == ctor_identifier
|| name == base_ctor_identifier
|| name == complete_ctor_identifier))
{
if (CLASSTYPE_LAZY_DEFAULT_CTOR (type))
lazily_declare_fn (sfk_constructor, type);
if (CLASSTYPE_LAZY_COPY_CTOR (type))
lazily_declare_fn (sfk_copy_constructor, type);
}
else if (name == ansi_assopname(NOP_EXPR)
&& !TYPE_HAS_ASSIGN_REF (type)
&& !TYPE_FOR_JAVA (type))
lazily_declare_fn (sfk_assignment_operator, type);
}
method_vec = CLASSTYPE_METHOD_VEC (type);
if (!method_vec) if (!method_vec)
return -1; return -1;
...@@ -1405,24 +1421,6 @@ lookup_fnfields_1 (tree type, tree name) ...@@ -1405,24 +1421,6 @@ lookup_fnfields_1 (tree type, tree name)
int lo; int lo;
int hi; int hi;
/* All non-Java classes have "operator=" -- but we do not
actually create the declaration until it is needed. */
if (name == ansi_assopname(NOP_EXPR)
&& !TYPE_HAS_ASSIGN_REF (type)
&& !TYPE_FOR_JAVA (type))
{
tree fn;
/* Declare the function. */
fn = implicitly_declare_fn (sfk_assignment_operator, type,
TYPE_HAS_CONST_ASSIGN_REF (type));
add_method (type, fn);
TREE_CHAIN (fn) = TYPE_METHODS (type);
TYPE_METHODS (type) = fn;
maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0);
method_vec = CLASSTYPE_METHOD_VEC (type);
}
lo = i; lo = i;
hi = VEC_length (tree, method_vec); hi = VEC_length (tree, method_vec);
while (lo < hi) while (lo < hi)
...@@ -1789,6 +1787,12 @@ look_for_overrides_here (tree type, tree fndecl) ...@@ -1789,6 +1787,12 @@ look_for_overrides_here (tree type, tree fndecl)
{ {
int ix; int ix;
/* If there are no methods in TYPE (meaning that only implicitly
declared methods will ever be provided for TYPE), then there are
no virtual functions. */
if (!CLASSTYPE_METHOD_VEC (type))
return NULL_TREE;
if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fndecl)) if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fndecl))
ix = CLASSTYPE_DESTRUCTOR_SLOT; ix = CLASSTYPE_DESTRUCTOR_SLOT;
else else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment