cp-tree.h (struct lang_decl_flags): Add needs_final_overrider.
d * 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. From-SVN: r18588
This commit is contained in:
parent
cdcb673e6e
commit
4a67c9e985
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
cp_error ("\t%#D", TREE_VALUE (u));
|
||||
u = TREE_CHAIN (u);
|
||||
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)
|
||||
{
|
||||
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.
|
||||
|
|
Loading…
Reference in New Issue