This is another preliminary piece. It teaches some folding code that vtable references could contain COMPONENT_REFs and how to deal with that.
Bootstrapped and tested on x86_64-linux, both with and without the final vtables patch. Ok? Bernd
commit d1b84c0bbdb1816b7173dca29486bc88124e4641 Author: Bernd Schmidt <ber...@codesourcery.com> Date: Tue Apr 23 15:17:34 2013 +0200 Allow virtual table refs to be COMPONENT_REFs This is a preparation patch for changing the C++ vtable layout. It makes gimple-fold aware of how to fold a vtable reference that is a COMPONENT_REF. * gimple-fold.c (gimple_get_virt_method_for_binfo): Allow COMPONENT_REFs. diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index b9211a9..e2364bf 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -3118,16 +3118,25 @@ gimple_get_virt_method_for_binfo (HOST_WIDE_INT token, tree known_binfo) if (TREE_CODE (v) != ADDR_EXPR) return NULL_TREE; v = TREE_OPERAND (v, 0); + tree v_outer = v; + if (TREE_CODE (v_outer) == COMPONENT_REF) + { + tree field = TREE_OPERAND (v_outer, 1); + offset += tree_low_cst (DECL_FIELD_OFFSET (field), 1) * BITS_PER_UNIT; + offset += tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1); + v_outer = TREE_OPERAND (v_outer, 0); + } - if (TREE_CODE (v) != VAR_DECL - || !DECL_VIRTUAL_P (v) - || !DECL_INITIAL (v) - || DECL_INITIAL (v) == error_mark_node) + if (TREE_CODE (v_outer) != VAR_DECL + || !DECL_VIRTUAL_P (v_outer) + || !DECL_INITIAL (v_outer) + || DECL_INITIAL (v_outer) == error_mark_node) return NULL_TREE; gcc_checking_assert (TREE_CODE (TREE_TYPE (v)) == ARRAY_TYPE); size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (v))), 1); offset += token * size; - fn = fold_ctor_reference (TREE_TYPE (TREE_TYPE (v)), DECL_INITIAL (v), + fn = fold_ctor_reference (TREE_TYPE (TREE_TYPE (v)), + DECL_INITIAL (v_outer), offset, size, vtable); if (!fn || integer_zerop (fn)) return NULL_TREE;