* cp-tree.h (struct lang_type): Add com_interface.
(CLASSTYPE_COM_INTERFACE): New macro.
* class.c (set_rtti_entry): COM interface classes have no RTTI
entries in their vtables; adjust.
(add_virtual_function, finish_base_struct, skip_rtti_stuff,
modify_one_vtable, fixup_vtable_deltas1, override_one_vtable,
finish_struct_1): Likewise.
* decl2.c (mark_vtable_entries): Likewise.
* rtti.c (build_headof, get_tinfo_fn_dynamic): Likewise.
* search.c (get_abstract_virtuals_1, get_abstract_virtuals,
expand_upcast_fixups): Likewise.
* tree.c (debug_binfo): Likewise.
From-SVN: r26394
1999-04-12 Jason Merrill <jason@yorick.cygnus.com>
+ * cp-tree.h (struct lang_type): Add com_interface.
+ (CLASSTYPE_COM_INTERFACE): New macro.
+ * class.c (set_rtti_entry): COM interface classes have no RTTI
+ entries in their vtables; adjust.
+ (add_virtual_function, finish_base_struct, skip_rtti_stuff,
+ modify_one_vtable, fixup_vtable_deltas1, override_one_vtable,
+ finish_struct_1): Likewise.
+ * decl2.c (mark_vtable_entries): Likewise.
+ * rtti.c (build_headof, get_tinfo_fn_dynamic): Likewise.
+ * search.c (get_abstract_virtuals_1, get_abstract_virtuals,
+ expand_upcast_fixups): Likewise.
+ * tree.c (debug_binfo): Likewise.
+
* cp-tree.h (COMPARE_NO_ATTRIBUTES): New macro.
* typeck.c (comptypes): If we get it, ignore attributes.
* class.c (instantiate_type): Use BASELINK_P. Change complain
{
tree vfn;
+ if (CLASSTYPE_COM_INTERFACE (type))
+ return;
+
if (flag_rtti)
vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, get_tinfo_fn (type));
else
CLASSTYPE_RTTI (t) = t;
/* If we are using thunks, use two slots at the front, one
- for the offset pointer, one for the tdesc pointer. */
- if (*has_virtual == 0 && flag_vtable_thunks)
+ for the offset pointer, one for the tdesc pointer.
+ For ARM-style vtables, use the same slot for both. */
+ if (*has_virtual == 0 && ! CLASSTYPE_COM_INTERFACE (t))
{
- *has_virtual = 1;
+ if (flag_vtable_thunks)
+ *has_virtual = 2;
+ else
+ *has_virtual = 1;
}
/* Build a new INT_CST for this DECL_VINDEX. */
static tree index_table[256];
tree idx;
/* We skip a slot for the offset/tdesc entry. */
- int i = ++(*has_virtual);
+ int i = (*has_virtual)++;
if (i >= 256 || index_table[i] == 0)
{
TYPE_OVERLOADS_ARRAY_REF (t) |= TYPE_OVERLOADS_ARRAY_REF (basetype);
TYPE_OVERLOADS_ARROW (t) |= TYPE_OVERLOADS_ARROW (basetype);
+ if (CLASSTYPE_COM_INTERFACE (basetype))
+ {
+ CLASSTYPE_COM_INTERFACE (t) = 1;
+ if (i > 0)
+ cp_error
+ ("COM interface type `%T' must be the leftmost base class",
+ basetype);
+ }
+ else if (CLASSTYPE_COM_INTERFACE (t))
+ {
+ cp_error ("COM interface type `%T' with non-COM base class `%T'",
+ t, basetype);
+ CLASSTYPE_COM_INTERFACE (t) = 0;
+ }
+
if (TYPE_VIRTUAL_P (basetype))
{
/* Ensure that this is set from at least a virtual base
/* Skip RTTI information at the front of the virtual list. */
unsigned HOST_WIDE_INT
-skip_rtti_stuff (virtuals)
- tree *virtuals;
+skip_rtti_stuff (virtuals, t)
+ tree *virtuals, t;
{
int n;
+ if (CLASSTYPE_COM_INTERFACE (t))
+ return 0;
+
n = 0;
if (*virtuals)
{
if (fndecl == NULL_TREE)
return;
- n = skip_rtti_stuff (&virtuals);
+ n = skip_rtti_stuff (&virtuals, t);
while (virtuals)
{
tree virtuals = BINFO_VIRTUALS (binfo);
unsigned HOST_WIDE_INT n;
- n = skip_rtti_stuff (&virtuals);
+ n = skip_rtti_stuff (&virtuals, t);
while (virtuals)
{
if (BINFO_NEW_VTABLE_MARKED (binfo))
choose = NEITHER;
- skip_rtti_stuff (&virtuals);
- skip_rtti_stuff (&old_virtuals);
+ skip_rtti_stuff (&virtuals, t);
+ skip_rtti_stuff (&old_virtuals, t);
while (virtuals)
{
/* We must enter these virtuals into the table. */
if (first_vfn_base_index < 0)
{
- /* The second slot is for the tdesc pointer when thunks are used. */
- if (flag_vtable_thunks)
- pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals);
+ if (! CLASSTYPE_COM_INTERFACE (t))
+ {
+ /* The second slot is for the tdesc pointer when thunks are used. */
+ if (flag_vtable_thunks)
+ pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals);
- /* The first slot is for the rtti offset. */
- pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals);
+ /* The first slot is for the rtti offset. */
+ pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals);
- set_rtti_entry (pending_virtuals,
- convert (ssizetype, integer_zero_node), t);
+ set_rtti_entry (pending_virtuals,
+ convert (ssizetype, integer_zero_node), t);
+ }
build_vtable (NULL_TREE, t);
}
else
unsigned non_aggregate : 1;
unsigned is_partial_instantiation : 1;
unsigned has_mutable : 1;
+ unsigned com_interface : 1;
/* The MIPS compiler gets it wrong if this struct also
does not fill out to a multiple of 4 bytes. Add a
member `dummy' with new bits if you go over the edge. */
- unsigned dummy : 11;
+ unsigned dummy : 10;
} type_flags;
int vsize;
#define CLASSTYPE_HAS_MUTABLE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_mutable)
#define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE))
+/* Nonzero means that this type is meant for communication via COM. */
+#define CLASSTYPE_COM_INTERFACE(NODE) \
+ (TYPE_LANG_SPECIFIC(NODE)->type_flags.com_interface)
+
/* A list of class types of which this type is a friend. The
TREE_VALUE is normally a TYPE, but will be a TEMPLATE_DECL in the
case of a template friend. */
extern tree instantiate_type PROTO((tree, tree, int));
extern void print_class_statistics PROTO((void));
extern void maybe_push_cache_obstack PROTO((void));
-extern unsigned HOST_WIDE_INT skip_rtti_stuff PROTO((tree *));
+extern unsigned HOST_WIDE_INT skip_rtti_stuff PROTO((tree *, tree));
extern void build_self_reference PROTO((void));
extern void warn_hidden PROTO((tree));
extern tree get_enclosing_class PROTO((tree));
{
tree entries = CONSTRUCTOR_ELTS (DECL_INITIAL (decl));
- if (flag_rtti)
- {
- tree fnaddr = (flag_vtable_thunks ? TREE_VALUE (TREE_CHAIN (entries))
- : FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries)));
- tree fn = TREE_OPERAND (fnaddr, 0);
- TREE_ADDRESSABLE (fn) = 1;
- mark_used (fn);
- }
- skip_rtti_stuff (&entries);
-
for (; entries; entries = TREE_CHAIN (entries))
{
- tree fnaddr = (flag_vtable_thunks ? TREE_VALUE (entries)
- : FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries)));
- tree fn = TREE_OPERAND (fnaddr, 0);
+ tree fnaddr;
+ tree fn;
+
+ if (TREE_CODE (TREE_VALUE (entries)) == NOP_EXPR)
+ /* RTTI offset. */
+ continue;
+
+ fnaddr = (flag_vtable_thunks ? TREE_VALUE (entries)
+ : FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries)));
+ fn = TREE_OPERAND (fnaddr, 0);
TREE_ADDRESSABLE (fn) = 1;
if (DECL_LANG_SPECIFIC (fn) && DECL_ABSTRACT_VIRTUAL_P (fn))
{
if (!TYPE_VIRTUAL_P (type))
return exp;
+ if (CLASSTYPE_COM_INTERFACE (type))
+ {
+ cp_error ("RTTI not supported for COM interface type `%T'", type);
+ return error_mark_node;
+ }
/* If we don't have rtti stuff, get to a sub-object that does. */
if (!CLASSTYPE_VFIELDS (TREE_TYPE (TREE_TYPE (exp))))
if (! flag_rtti)
error ("taking dynamic typeid of object with -fno-rtti");
+ if (CLASSTYPE_COM_INTERFACE (type))
+ {
+ cp_error ("RTTI not supported for COM interface type `%T'", type);
+ return error_mark_node;
+ }
/* If we don't have rtti stuff, get to a sub-object that does. */
if (! CLASSTYPE_VFIELDS (type))
{
tree virtuals = BINFO_VIRTUALS (binfo);
- skip_rtti_stuff (&virtuals);
+ skip_rtti_stuff (&virtuals, BINFO_TYPE (binfo));
while (virtuals)
{
{
tree virtuals = BINFO_VIRTUALS (vbases);
- skip_rtti_stuff (&virtuals);
+ skip_rtti_stuff (&virtuals, type);
while (virtuals)
{
*vbase_offsets = delta;
}
- n = skip_rtti_stuff (&virtuals);
+ n = skip_rtti_stuff (&virtuals, t);
while (virtuals)
{
fprintf (stderr, "virtuals:\n");
virtuals = BINFO_VIRTUALS (elem);
- n = skip_rtti_stuff (&virtuals);
+ n = skip_rtti_stuff (&virtuals, BINFO_TYPE (elem));
while (virtuals)
{