OSDN Git Service

* cp-tree.h (special_function_kind): Add various kinds of
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 4 May 2000 14:54:18 +0000 (14:54 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 4 May 2000 14:54:18 +0000 (14:54 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@33668 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cp/tree.c

index b2b62a3..9ae429e 100644 (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.
index 7198e54..f0136b2 100644 (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)))
index 3a4e6b3..5e2b433 100644 (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));
index fe22c3b..85bc908 100644 (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))))
index c3bdb1d..712e40d 100644 (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;
+}