OSDN Git Service

d
authormanfred <manfred@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 15 Mar 1998 03:28:07 +0000 (03:28 +0000)
committermanfred <manfred@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 15 Mar 1998 03:28:07 +0000 (03:28 +0000)
* cp-tree.h (struct lang_decl_flags): Add needs_final_overrider.
(DECL_NEEDS_FINAL_OVERRIDER_P): New macro.
* class.c (override_one_vtable): Set DECL_NEEDS_FINAL_OVERRIDER_P.
* decl.c (duplicate_decls): Propagate it.
* typeck2.c (abstract_virtuals_error): Use two loops to emit
abstract virtual functions and virtual functions which need a
final overrider separately.

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

gcc/cp/class.c
gcc/cp/decl.c
gcc/cp/typeck2.c

index f13180f..cb32461 100644 (file)
@@ -2725,6 +2725,7 @@ override_one_vtable (binfo, old, t)
            fndecl = copy_node (fndecl);
            copy_lang_decl (fndecl);
            DECL_ABSTRACT_VIRTUAL_P (fndecl) = 1;
+           DECL_NEEDS_FINAL_OVERRIDER_P (fndecl) = 1;
            /* Make sure we search for it later.  */
            if (! CLASSTYPE_ABSTRACT_VIRTUALS (t))
              CLASSTYPE_ABSTRACT_VIRTUALS (t) = error_mark_node;
index fdf704c..43a1660 100644 (file)
@@ -2740,6 +2740,7 @@ duplicate_decls (newdecl, olddecl)
       DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
       DECL_ABSTRACT_VIRTUAL_P (newdecl) |= DECL_ABSTRACT_VIRTUAL_P (olddecl);
       DECL_VIRTUAL_P (newdecl) |= DECL_VIRTUAL_P (olddecl);
+      DECL_NEEDS_FINAL_OVERRIDER_P (newdecl) |= DECL_NEEDS_FINAL_OVERRIDER_P (olddecl);
     }
 
   /* Deal with C++: must preserve virtual function table size.  */
index f462e79..2a208af 100644 (file)
@@ -130,6 +130,29 @@ abstract_virtuals_error (decl, type)
      tree type;
 {
   tree u = CLASSTYPE_ABSTRACT_VIRTUALS (type);
+  int has_abstract_virtuals, needs_final_overriders;
+  tree tu;
+
+  /* Count how many abstract methods need to be defined.  */
+  for (has_abstract_virtuals = 0, tu = u; tu; tu = TREE_CHAIN (tu))
+    {
+      if (DECL_ABSTRACT_VIRTUAL_P (TREE_VALUE (tu))
+         && ! DECL_NEEDS_FINAL_OVERRIDER_P (TREE_VALUE (tu)))
+       {
+         has_abstract_virtuals = 1;
+         break;
+       }
+    }
+
+  /* Count how many virtual methods need a final overrider.  */
+  for (needs_final_overriders = 0, tu = u; tu; tu = TREE_CHAIN (tu))
+    {
+      if (DECL_NEEDS_FINAL_OVERRIDER_P (TREE_VALUE (tu)))
+       {
+         needs_final_overriders = 1;
+         break;
+       }
+    }
 
   if (decl)
     {
@@ -151,19 +174,52 @@ abstract_virtuals_error (decl, type)
       else if (TREE_CODE (decl) == FUNCTION_DECL)
        cp_error ("invalid return type for function `%#D'", decl);
     }
-  else cp_error ("cannot allocate an object of type `%T'", type);
+  else
+    cp_error ("cannot allocate an object of type `%T'", type);
+
   /* Only go through this once.  */
   if (TREE_PURPOSE (u) == NULL_TREE)
     {
-      error ("  since the following virtual functions are abstract:");
       TREE_PURPOSE (u) = error_mark_node;
-      while (u)
+
+      if (has_abstract_virtuals)
+       error ("  since the following virtual functions are abstract:");
+      tu = u;
+      while (tu)
+       {
+         if (DECL_ABSTRACT_VIRTUAL_P (TREE_VALUE (tu))
+             && ! DECL_NEEDS_FINAL_OVERRIDER_P (TREE_VALUE (tu)))
+           cp_error ("\t%#D", TREE_VALUE (tu));
+         tu = TREE_CHAIN (tu);
+       }
+
+      if (needs_final_overriders)
+       {
+         if (has_abstract_virtuals)
+           error ("  and the following virtual functions need a final overrider:");
+         else
+           error ("  since the following virtual functions need a final overrider:");
+       }
+      tu = u;
+      while (tu)
        {
-         cp_error ("\t%#D", TREE_VALUE (u));
-         u = TREE_CHAIN (u);
+         if (DECL_NEEDS_FINAL_OVERRIDER_P (TREE_VALUE (tu)))
+           cp_error ("\t%#D", TREE_VALUE (tu));
+         tu = TREE_CHAIN (tu);
        }
     }
-  else cp_error ("  since type `%T' has abstract virtual functions", type);
+  else
+    {
+      if (has_abstract_virtuals)
+       {
+         if (needs_final_overriders)
+           cp_error ("  since type `%T' has abstract virtual functions and must override virtual functions", type);
+         else
+           cp_error ("  since type `%T' has abstract virtual functions", type);
+       }
+      else
+       cp_error ("  since type `%T' must override virtual functions", type);
+    }
 }
 
 /* Print an error message for invalid use of a signature type.