aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-07-17 07:31:08 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2004-07-17 07:31:08 +0000
commit508a1c9c6d5d84df1207ff6d1e849e104b41694b (patch)
tree2d69e1c139bcf0ee4f483089d38a6c6ff542bbce /gcc
parent165b54c3f3249b748d8e7ac186d9ad93dab86d86 (diff)
downloadgcc-508a1c9c6d5d84df1207ff6d1e849e104b41694b.zip
gcc-508a1c9c6d5d84df1207ff6d1e849e104b41694b.tar.gz
gcc-508a1c9c6d5d84df1207ff6d1e849e104b41694b.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog22
-rw-r--r--gcc/cp/class.c30
-rw-r--r--gcc/cp/cp-tree.h15
-rw-r--r--gcc/cp/decl2.c3
-rw-r--r--gcc/cp/method.c75
-rw-r--r--gcc/cp/name-lookup.c7
-rw-r--r--gcc/cp/search.c42
7 files changed, 134 insertions, 60 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 472b101..a67bfc3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,25 @@
+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>
* cp-tree.h (struct lang_type): Don't have three GTY options on a
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index c916d5f..cc1dc76 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1714,18 +1714,10 @@ finish_struct_methods (tree t)
VEC(tree) *method_vec;
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);
- my_friendly_assert (method_vec, 19991215);
+ if (!method_vec)
+ return;
+
len = VEC_length (tree, method_vec);
/* First fill in entry 0 with the constructors, entry 1 with destructors,
@@ -2554,21 +2546,17 @@ add_implicitly_declared_members (tree t,
/* Default constructor. */
if (! TYPE_HAS_CONSTRUCTOR (t) && ! cant_have_default_ctor)
{
- default_fn = implicitly_declare_fn (sfk_constructor, t, /*const_p=*/0);
- TREE_CHAIN (default_fn) = implicit_fns;
- implicit_fns = default_fn;
+ TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1;
+ CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1;
}
/* Copy constructor. */
if (! TYPE_HAS_INIT_REF (t) && ! TYPE_FOR_JAVA (t))
{
- /* ARM 12.18: You get either X(X&) or X(const X&), but
- not both. --Chip */
- default_fn
- = implicitly_declare_fn (sfk_copy_constructor, t,
- /*const_p=*/!cant_have_const_cctor);
- TREE_CHAIN (default_fn) = implicit_fns;
- implicit_fns = default_fn;
+ TYPE_HAS_INIT_REF (t) = 1;
+ TYPE_HAS_CONST_INIT_REF (t) = !cant_have_const_cctor;
+ CLASSTYPE_LAZY_COPY_CTOR (t) = 1;
+ TYPE_HAS_CONSTRUCTOR (t) = 1;
}
/* If there is no assignment operator, one will be created if and
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index e7069ba..a7d35d4 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -991,6 +991,8 @@ struct lang_type_class GTY(())
unsigned ptrmemfunc_flag : 1;
unsigned was_anonymous : 1;
+ unsigned lazy_default_ctor : 1;
+ unsigned lazy_copy_ctor : 1;
unsigned has_const_init_ref : 1;
unsigned has_complex_init_ref : 1;
unsigned has_complex_assign_ref : 1;
@@ -1004,7 +1006,7 @@ struct lang_type_class GTY(())
/* 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
remove a flag. */
- unsigned dummy : 11;
+ unsigned dummy : 9;
tree primary_base;
tree vfields;
@@ -1089,6 +1091,16 @@ struct lang_type GTY(())
#define TYPE_HAS_CONVERSION(NODE) \
(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&). */
#define TYPE_HAS_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_assign_ref)
@@ -3884,6 +3896,7 @@ extern void finish_thunk (tree);
extern void use_thunk (tree, bool);
extern void synthesize_method (tree);
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);
/* In optimize.c */
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 8467ad6..7257f69 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -693,9 +693,8 @@ check_classfn (tree ctype, tree function, tree template_parms)
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);
if (!DECL_CONV_FN_P (OVL_CURRENT (fndecls)))
{
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 1a9ecad..984e0e9 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -825,7 +825,9 @@ synthesize_exception_spec (tree type, tree (*extractor) (tree, void*),
static tree
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. */
@@ -838,6 +840,11 @@ locate_ctor (tree type, void *client ATTRIBUTE_UNUSED)
if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
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))
{
tree fn = OVL_CURRENT (fns);
@@ -864,21 +871,27 @@ locate_copy (tree type, void *client_)
{
struct copy_data *client = (struct copy_data *)client_;
tree fns;
- int ix = -1;
tree best = NULL_TREE;
bool excess_p = false;
if (client->name)
{
- if (TYPE_HAS_ASSIGN_REF (type))
- ix = lookup_fnfields_1 (type, client->name);
+ int ix;
+ 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))
- 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;
- fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix);
-
for (; fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
@@ -927,6 +940,8 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
tree rhs_parm_type = NULL_TREE;
tree name;
+ type = TYPE_MAIN_VARIANT (type);
+
switch (kind)
{
case sfk_destructor:
@@ -939,12 +954,9 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
/* Default constructor. */
name = constructor_name (type);
raises = synthesize_exception_spec (type, &locate_ctor, 0);
- TYPE_HAS_CONSTRUCTOR (type) = 1;
break;
case sfk_copy_constructor:
- TYPE_HAS_CONSTRUCTOR (type) = 1;
- /* Fall through. */
case sfk_assignment_operator:
{
struct copy_data data;
@@ -1019,6 +1031,47 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
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
as there are artificial parms in FN. */
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index fd3776f..3a2f71c 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -1794,12 +1794,7 @@ set_identifier_type_value (tree id, tree decl)
tree
constructor_name_full (tree type)
{
- type = 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 TYPE_IDENTIFIER (TYPE_MAIN_VARIANT (type));
}
/* Return the name for the constructor (or destructor) for the
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 97b9789..ceefa3c 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -1368,8 +1368,24 @@ lookup_fnfields_1 (tree type, tree name)
if (!CLASS_TYPE_P (type))
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)
return -1;
@@ -1405,24 +1421,6 @@ lookup_fnfields_1 (tree type, tree name)
int lo;
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;
hi = VEC_length (tree, method_vec);
while (lo < hi)
@@ -1789,6 +1787,12 @@ look_for_overrides_here (tree type, tree fndecl)
{
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))
ix = CLASSTYPE_DESTRUCTOR_SLOT;
else