+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.
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)))
&& 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)
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;
#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));
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))))
/* 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;
+}