aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2000-05-04 14:54:18 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2000-05-04 14:54:18 +0000
commit872f37f91215eb7e737c4e7662aa829e6032be60 (patch)
treeafa1bd1d9dfc8d268635e08179700f055b9f48cb
parent72b9c7fb371a69f8430e70beb466911694de669b (diff)
downloadgcc-872f37f91215eb7e737c4e7662aa829e6032be60.zip
gcc-872f37f91215eb7e737c4e7662aa829e6032be60.tar.gz
gcc-872f37f91215eb7e737c4e7662aa829e6032be60.tar.bz2
cp-tree.h (special_function_kind): Add various kinds of destructors.
* cp-tree.h (special_function_kind): Add various kinds of destructors. (special_function_p): New function. * class.c (overrides): Don't let one kind of destructor override another. * decl2.c (mark_used): Use DECL_NON_THUNK_FUNCTION_P when deciding whether or not to instantiate a template. * tree.c (special_function_p): Define. From-SVN: r33668
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/class.c15
-rw-r--r--gcc/cp/cp-tree.h14
-rw-r--r--gcc/cp/decl2.c2
-rw-r--r--gcc/cp/tree.c31
5 files changed, 64 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b2b62a3..9ae429e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,14 @@
+2000-05-04 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (special_function_kind): Add various kinds of
+ destructors.
+ (special_function_p): New function.
+ * class.c (overrides): Don't let one kind of destructor override
+ another.
+ * decl2.c (mark_used): Use DECL_NON_THUNK_FUNCTION_P when deciding
+ whether or not to instantiate a template.
+ * tree.c (special_function_p): Define.
+
2000-05-03 Mark Mitchell <mark@codesourcery.com>
* cp-tree.def (THUNK_DECL): Remove.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 7198e54..f0136b2 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -2284,18 +2284,21 @@ static int
overrides (fndecl, base_fndecl)
tree fndecl, base_fndecl;
{
- /* Destructors have special names. */
- if (DECL_DESTRUCTOR_P (base_fndecl) && DECL_DESTRUCTOR_P (fndecl))
+ /* One destructor overrides another if they are the same kind of
+ destructor. */
+ if (DECL_DESTRUCTOR_P (base_fndecl) && DECL_DESTRUCTOR_P (fndecl)
+ && special_function_p (base_fndecl) == special_function_p (fndecl))
return 1;
+ /* But a non-destructor never overrides a destructor, nor vice
+ versa, nor do different kinds of destructors override
+ one-another. For example, a complete object destructor does not
+ override a deleting destructor. */
if (DECL_DESTRUCTOR_P (base_fndecl) || DECL_DESTRUCTOR_P (fndecl))
return 0;
+
if (DECL_NAME (fndecl) == DECL_NAME (base_fndecl))
{
tree types, base_types;
-#if 0
- retypes = TREE_TYPE (TREE_TYPE (fndecl));
- base_retypes = TREE_TYPE (TREE_TYPE (base_fndecl));
-#endif
types = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
base_types = TYPE_ARG_TYPES (TREE_TYPE (base_fndecl));
if ((TYPE_QUALS (TREE_TYPE (TREE_VALUE (base_types)))
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 3a4e6b3..5e2b433 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1988,7 +1988,7 @@ struct lang_decl
&& DECL_NAME (NODE) == base_dtor_identifier)
/* Nonzero if NODE (a FUNCTION_DECL) is a destructor for a complete
- object. */
+ object that deletes the object after it has been destroyed. */
#define DECL_DELETING_DESTRUCTOR_P(NODE) \
(DECL_DESTRUCTOR_P (NODE) \
&& DECL_NAME (NODE) == deleting_dtor_identifier)
@@ -3218,12 +3218,21 @@ typedef enum access_kind {
ak_private = 3 /* Accessible, as a `private' thing. */
} access_kind;
+/* The various kinds of special functions. If you add to this list,
+ you should update special_function_p as well. */
typedef enum special_function_kind {
- sfk_none, /* Not a special function. */
+ sfk_none = 0, /* Not a special function. This enumeral
+ must have value zero; see
+ special_function_p. */
sfk_constructor, /* A constructor. */
sfk_copy_constructor, /* A copy constructor. */
sfk_assignment_operator, /* An assignment operator. */
sfk_destructor, /* A destructor. */
+ sfk_complete_destructor, /* A destructor for complete objects. */
+ sfk_base_destructor, /* A destructor for base subobjects. */
+ sfk_deleting_destructor, /* A destructor for complete objects that
+ deletes the object after it has been
+ destroyed. */
sfk_conversion /* A conversion operator. */
} special_function_kind;
@@ -4527,6 +4536,7 @@ extern void remap_save_expr PARAMS ((tree *, splay_tree, tre
#define cp_build_qualified_type(TYPE, QUALS) \
cp_build_qualified_type_real ((TYPE), (QUALS), /*complain=*/1)
extern tree build_shared_int_cst PARAMS ((int));
+extern special_function_kind special_function_p PARAMS ((tree));
/* in typeck.c */
extern int string_conv_p PARAMS ((tree, tree, int));
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index fe22c3b..85bc908 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -5243,7 +5243,7 @@ mark_used (decl)
template, we now know that we will need to actually do the
instantiation. We check that DECL is not an explicit
instantiation because that is not checked in instantiate_decl. */
- if ((TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == VAR_DECL)
+ if ((DECL_NON_THUNK_FUNCTION_P (decl) || TREE_CODE (decl) == VAR_DECL)
&& DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
&& (!DECL_EXPLICIT_INSTANTIATION (decl)
|| (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))))
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index c3bdb1d..712e40d 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2413,3 +2413,34 @@ cp_unsave (tp)
/* Clean up. */
splay_tree_delete (st);
}
+
+/* Returns the kind of special function that DECL (a FUNCTION_DECL)
+ is. Note that this sfk_none is zero, so this function can be used
+ as a predicate to test whether or not DECL is a special function. */
+
+special_function_kind
+special_function_p (decl)
+ tree decl;
+{
+ /* Rather than doing all this stuff with magic names, we should
+ probably have a field of type `special_function_kind' in
+ DECL_LANG_SPECIFIC. */
+ if (DECL_COPY_CONSTRUCTOR_P (decl))
+ return sfk_copy_constructor;
+ if (DECL_CONSTRUCTOR_P (decl))
+ return sfk_constructor;
+ if (DECL_NAME (decl) == ansi_opname[(int) MODIFY_EXPR])
+ return sfk_assignment_operator;
+ if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl))
+ return sfk_destructor;
+ if (DECL_COMPLETE_DESTRUCTOR_P (decl))
+ return sfk_complete_destructor;
+ if (DECL_BASE_DESTRUCTOR_P (decl))
+ return sfk_base_destructor;
+ if (DECL_DELETING_DESTRUCTOR_P (decl))
+ return sfk_deleting_destructor;
+ if (DECL_CONV_FN_P (decl))
+ return sfk_conversion;
+
+ return sfk_none;
+}