aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/error.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/error.c')
-rw-r--r--gcc/cp/error.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 674e407..be0ee59 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1278,6 +1278,23 @@ dump_expr_init_vec (VEC(constructor_elt,gc) *v, int flags)
}
+/* We've gotten an indirect REFERENCE (an OBJ_TYPE_REF) to a virtual
+ function. Resolve it to a close relative -- in the sense of static
+ type -- variant being overridden. That is close to what was written in
+ the source code. Subroutine of dump_expr. */
+
+static tree
+resolve_virtual_fun_from_obj_type_ref (tree ref)
+{
+ tree obj_type = TREE_TYPE (OBJ_TYPE_REF_OBJECT (ref));
+ int index = tree_low_cst (OBJ_TYPE_REF_TOKEN (ref), 1);
+ tree fun = BINFO_VIRTUALS (TYPE_BINFO (TREE_TYPE (obj_type)));
+ while (index--)
+ fun = TREE_CHAIN (fun);
+
+ return BV_FN (fun);
+}
+
/* Print out an expression E under control of FLAGS. */
static void
@@ -1386,6 +1403,10 @@ dump_expr (tree t, int flags)
if (TREE_CODE (fn) == ADDR_EXPR)
fn = TREE_OPERAND (fn, 0);
+ /* Nobody is interested in seeing the guts of vcalls. */
+ if (TREE_CODE (fn) == OBJ_TYPE_REF)
+ fn = resolve_virtual_fun_from_obj_type_ref (fn);
+
if (TREE_TYPE (fn) != NULL_TREE && NEXT_CODE (fn) == METHOD_TYPE)
{
tree ob = TREE_VALUE (args);