diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 304a1229860..179cd0c7c42 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,18 @@ 1999-04-12 Jason Merrill + * 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 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index a577441aba3..9d3d52532fb 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -671,6 +671,9 @@ set_rtti_entry (virtuals, offset, type) { tree vfn; + if (CLASSTYPE_COM_INTERFACE (type)) + return; + if (flag_rtti) vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, get_tinfo_fn (type)); else @@ -1035,10 +1038,14 @@ add_virtual_function (pv, phv, has_virtual, fndecl, t) 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. */ @@ -1046,7 +1053,7 @@ add_virtual_function (pv, phv, has_virtual, fndecl, t) 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) { @@ -1634,6 +1641,21 @@ finish_base_struct (t, b) 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 @@ -2285,11 +2307,14 @@ get_class_offset (context, t, binfo, fndecl) /* 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) { @@ -2331,7 +2356,7 @@ modify_one_vtable (binfo, t, fndecl, pfn) if (fndecl == NULL_TREE) return; - n = skip_rtti_stuff (&virtuals); + n = skip_rtti_stuff (&virtuals, t); while (virtuals) { @@ -2425,7 +2450,7 @@ fixup_vtable_deltas1 (binfo, t) tree virtuals = BINFO_VIRTUALS (binfo); unsigned HOST_WIDE_INT n; - n = skip_rtti_stuff (&virtuals); + n = skip_rtti_stuff (&virtuals, t); while (virtuals) { @@ -2598,8 +2623,8 @@ override_one_vtable (binfo, old, t) 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) { @@ -3874,15 +3899,18 @@ finish_struct_1 (t, warn_anon) /* 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 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a88156d4461..ab364454902 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -736,11 +736,12 @@ struct lang_type 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; @@ -1010,6 +1011,10 @@ struct lang_type #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. */ @@ -2724,7 +2729,7 @@ extern void pop_lang_context PROTO((void)); 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)); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 180de3d6824..04114f74417 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2339,21 +2339,18 @@ mark_vtable_entries (decl) { 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)) { diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index d98435e54f3..6ff3c60410d 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -108,6 +108,11 @@ build_headof (exp) 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)))) @@ -216,6 +221,11 @@ get_tinfo_fn_dynamic (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)) diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 4b90e7ebc76..a756acde93e 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -2034,7 +2034,7 @@ get_abstract_virtuals_1 (binfo, do_self, abstract_virtuals) { tree virtuals = BINFO_VIRTUALS (binfo); - skip_rtti_stuff (&virtuals); + skip_rtti_stuff (&virtuals, BINFO_TYPE (binfo)); while (virtuals) { @@ -2067,7 +2067,7 @@ get_abstract_virtuals (type) { tree virtuals = BINFO_VIRTUALS (vbases); - skip_rtti_stuff (&virtuals); + skip_rtti_stuff (&virtuals, type); while (virtuals) { @@ -2528,7 +2528,7 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t, *vbase_offsets = delta; } - n = skip_rtti_stuff (&virtuals); + n = skip_rtti_stuff (&virtuals, t); while (virtuals) { diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 44e958f064d..d870a6be691 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1169,7 +1169,7 @@ debug_binfo (elem) fprintf (stderr, "virtuals:\n"); virtuals = BINFO_VIRTUALS (elem); - n = skip_rtti_stuff (&virtuals); + n = skip_rtti_stuff (&virtuals, BINFO_TYPE (elem)); while (virtuals) {