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
This commit is contained in:
Mark Mitchell 2000-05-04 14:54:18 +00:00 committed by Mark Mitchell
parent 72b9c7fb37
commit 872f37f912
5 changed files with 64 additions and 9 deletions

View file

@ -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.

View file

@ -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)))

View file

@ -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));

View file

@ -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))))

View file

@ -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;
}