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);
|
fndecl = copy_node (fndecl);
|
||||||
copy_lang_decl (fndecl);
|
copy_lang_decl (fndecl);
|
||||||
DECL_ABSTRACT_VIRTUAL_P (fndecl) = 1;
|
DECL_ABSTRACT_VIRTUAL_P (fndecl) = 1;
|
||||||
|
DECL_NEEDS_FINAL_OVERRIDER_P (fndecl) = 1;
|
||||||
/* Make sure we search for it later. */
|
/* Make sure we search for it later. */
|
||||||
if (! CLASSTYPE_ABSTRACT_VIRTUALS (t))
|
if (! CLASSTYPE_ABSTRACT_VIRTUALS (t))
|
||||||
CLASSTYPE_ABSTRACT_VIRTUALS (t) = error_mark_node;
|
CLASSTYPE_ABSTRACT_VIRTUALS (t) = error_mark_node;
|
||||||
|
|
|
@ -2740,6 +2740,7 @@ duplicate_decls (newdecl, olddecl)
|
||||||
DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
|
DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
|
||||||
DECL_ABSTRACT_VIRTUAL_P (newdecl) |= DECL_ABSTRACT_VIRTUAL_P (olddecl);
|
DECL_ABSTRACT_VIRTUAL_P (newdecl) |= DECL_ABSTRACT_VIRTUAL_P (olddecl);
|
||||||
DECL_VIRTUAL_P (newdecl) |= DECL_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. */
|
/* Deal with C++: must preserve virtual function table size. */
|
||||||
|
|
|
@ -130,6 +130,29 @@ abstract_virtuals_error (decl, type)
|
||||||
tree type;
|
tree type;
|
||||||
{
|
{
|
||||||
tree u = CLASSTYPE_ABSTRACT_VIRTUALS (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)
|
if (decl)
|
||||||
{
|
{
|
||||||
|
@ -151,19 +174,52 @@ abstract_virtuals_error (decl, type)
|
||||||
else if (TREE_CODE (decl) == FUNCTION_DECL)
|
else if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||||
cp_error ("invalid return type for function `%#D'", 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. */
|
/* Only go through this once. */
|
||||||
if (TREE_PURPOSE (u) == NULL_TREE)
|
if (TREE_PURPOSE (u) == NULL_TREE)
|
||||||
{
|
{
|
||||||
error (" since the following virtual functions are abstract:");
|
|
||||||
TREE_PURPOSE (u) = error_mark_node;
|
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));
|
if (DECL_ABSTRACT_VIRTUAL_P (TREE_VALUE (tu))
|
||||||
u = TREE_CHAIN (u);
|
&& ! 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.
|
/* Print an error message for invalid use of a signature type.
|
||||||
|
|
Loading…
Reference in New Issue