This is a patch series that changes the way vtables are constructed in
the C++ frontend (the first two are small preliminary patches, the meat
will be in 3/3). The problem I was trying to solve was that on the port
I was working on, function pointers are smaller than data pointers, and
size_t is smaller than a data pointer too. All three kinds of types are
used in vtables.

The C++ frontend assumes all three sizes are identical and constructs
references to them by just multiplying an index with a (constant) size.
(There is a target macro to add extra padding to the data members, but
it's unsuitable for the situation I described, and in any case wastes
too much space to be useful.) This patch series changes that so that
along with a vtable and its initializers, we build up a list of
structure fields and create a vtable type from these. We can then access
the various elements by using COMPONENT_REFs without having to know
exactly what the offsets are. Incidentally, libsupc++ already uses a
"struct vtable_prefix" to describe the layout.

I think this is a cleanup, but since the port won't be contributed I
could understand if the C++ maintainers don't want to risk this patch
set. If it doesn't go in, maybe it will be useful as a reference for
others when porting to a similar target.

There is one assumption here that needs to be pointed out, and one
little piece of ugliness. The assumption is that on current targets,
size_type_node is always the same size as const_ptr_type_node (i.e.
sizeof (void *) == sizeof (size_t)), and also that they have the same
alignment. This is required because the data fields of the vtable are
now created using a size_type_node. If someone knows of a target where
this isn't true, it would be helpful to know. Given the size_t/uintptr_t
testsuite patch I just submitted I'm thinking they don't exist, but I'm
kind of wondering about m32c, so Cc'ing DJ.

The small ugliness is that we must allow empty arrays in the middle of
structures since we must be able to take the address of such an array
field to get an object's vtable pointer. GCC seems to have no problems
with this concept in general, but since 4.5 (which I was working on) one
little problem has crept in: we crash in varasm.c when finding such an
array while initializing the vtable. This is addressed by the following
small preliminary patch which essentially just restores the previous code.

Bootstrapped and tested on x86_64-linux, ok?


Bernd
commit 618d06f7d414842a934fb360fa98972478e13483
Author: Bernd Schmidt <ber...@codesourcery.com>
Date:   Tue Apr 23 15:19:07 2013 +0200

    Allow empty arrays to be initialized
    
    This undoes an earlier change in output_constructor_regular_field so that
    we no longer crash when a zero-size array is initialized.  This is in
    preparation for changes to the way C++ vtables are laid out.
    
    	* varasm.c (output_constructor_regular_field): Don't crash for
    	arrays with empty DECL_SIZE_UNIT.

diff --git a/gcc/varasm.c b/gcc/varasm.c
index 2532d80..830fdd0 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -4833,7 +4833,7 @@ output_constructor_regular_field (oc_local_state *local)
 	     better be last.  */
 	  gcc_assert (!fieldsize || !DECL_CHAIN (local->field));
 	}
-      else
+      else if (DECL_SIZE_UNIT (local->field))
 	fieldsize = tree_low_cst (DECL_SIZE_UNIT (local->field), 1);
     }
   else

Reply via email to