Commit 548502d3 by Mark Mitchell Committed by Mark Mitchell

call.c (build_special_member_call): Do not try to lookup VTTs by name.

	* call.c (build_special_member_call): Do not try to lookup VTTs by
	name.
	* class.c (vtbl_init_data): Add generate_vcall_entries.
	(get_vtable_decl): Do not look up virtual tables by name.
	(copy_virtuals): Do not use BV_USE_VCALL_INDEX_P.
	(set_primary_base): Do not set CLASSTYPE_RTTI.
	(determine_primary_base): Likewise.
	(get_matching_virtual): Remove.
	(get_vcall_index): New function.
	(update_vtable_entry_for_fn): Do not try to use virtual thunks
	when they are not required.  Assign vcall indices at this point.
	(finish_struct_1): Do not set CLASSTYPE_NEEDS_VIRTUAL_REINIT.
	Do update dynamic_classes.
	(build_vtt): Do not add VTTs to the symbol table.
	(build_ctor_vtbl_group): Likewise.
	(build_vtbl_initializer): Simplify handling of vcall indices.
	(build_vcall_offset_vtbl_entries): Pretend to build vcall offsets
	for the most derived class.
	(add_vcall_offset_vtbl_entries_1): But do not actually add them to
	the vtable.
	* cp-tree.h (dynamic_classes): New macro.
	(lang_type_class): Remove rtti.  Add vtables.  Add vcall_indices.
	(CLASSTYPE_RTTI): Remove.
	(CLASSTYPE_NEEDS_VIRTUAL_REINIT): Remove.
	(CLASSTYPE_VCALL_INDICES): New macro.
	(CLASSTYPE_VTABLES): Likewise.
	(BV_USE_VCALL_INDEX_P): Remove.
	(build_vtable_path): Remove.
	* decl2.c (finish_vtable_vardecl): Remove.
	(key_method): Remove #if 0'd code.
	(finish_vtable_vardecl): Rename to ...
	(maybe_emit_vtables): ... this.
	(finish_file): Use it.
	* search.c (look_for_overrides_here): Update comment.

	* g++.dg/abi/thunk1.C: New test.
	* g++.dg/abi/thunk2.C: Likewise.
	* g++.dg/abi/vtt1.C: Likewise.

From-SVN: r58779
parent 55376e41
2002-11-03 Mark Mitchell <mark@codesourcery.com>
* call.c (build_special_member_call): Do not try to lookup VTTs by
name.
* class.c (vtbl_init_data): Add generate_vcall_entries.
(get_vtable_decl): Do not look up virtual tables by name.
(copy_virtuals): Do not use BV_USE_VCALL_INDEX_P.
(set_primary_base): Do not set CLASSTYPE_RTTI.
(determine_primary_base): Likewise.
(get_matching_virtual): Remove.
(get_vcall_index): New function.
(update_vtable_entry_for_fn): Do not try to use virtual thunks
when they are not required. Assign vcall indices at this point.
(finish_struct_1): Do not set CLASSTYPE_NEEDS_VIRTUAL_REINIT.
Do update dynamic_classes.
(build_vtt): Do not add VTTs to the symbol table.
(build_ctor_vtbl_group): Likewise.
(build_vtbl_initializer): Simplify handling of vcall indices.
(build_vcall_offset_vtbl_entries): Pretend to build vcall offsets
for the most derived class.
(add_vcall_offset_vtbl_entries_1): But do not actually add them to
the vtable.
* cp-tree.h (dynamic_classes): New macro.
(lang_type_class): Remove rtti. Add vtables. Add vcall_indices.
(CLASSTYPE_RTTI): Remove.
(CLASSTYPE_NEEDS_VIRTUAL_REINIT): Remove.
(CLASSTYPE_VCALL_INDICES): New macro.
(CLASSTYPE_VTABLES): Likewise.
(BV_USE_VCALL_INDEX_P): Remove.
(build_vtable_path): Remove.
* decl2.c (finish_vtable_vardecl): Remove.
(key_method): Remove #if 0'd code.
(finish_vtable_vardecl): Rename to ...
(maybe_emit_vtables): ... this.
(finish_file): Use it.
* search.c (look_for_overrides_here): Update comment.
2002-11-01 Zack Weinberg <zack@codesourcery.com>
PR c/7353 redux
......
......@@ -4712,7 +4712,7 @@ build_special_member_call (tree instance, tree name, tree args,
/* If the current function is a complete object constructor
or destructor, then we fetch the VTT directly.
Otherwise, we look it up using the VTT we were given. */
vtt = IDENTIFIER_GLOBAL_VALUE (get_vtt_name (current_class_type));
vtt = TREE_CHAIN (CLASSTYPE_VTABLES (current_class_type));
vtt = decay_conversion (vtt);
vtt = build (COND_EXPR, TREE_TYPE (vtt),
build (EQ_EXPR, boolean_type_node,
......
......@@ -47,7 +47,6 @@ struct diagnostic_context;
ICS_USER_FLAG (in _CONV)
CLEANUP_P (in TRY_BLOCK)
AGGR_INIT_VIA_CTOR_P (in AGGR_INIT_EXPR)
BV_USE_VCALL_INDEX_P (in the BINFO_VIRTUALS TREE_LIST)
PTRMEM_OK_P (in ADDR_EXPR, OFFSET_REF)
PARMLIST_ELLIPSIS_P (in PARMLIST)
1: IDENTIFIER_VIRTUAL_P.
......@@ -133,9 +132,7 @@ struct diagnostic_context;
of the base class.
The BV_VCALL_INDEX of each node, if non-NULL, gives the vtable
index of the vcall offset for this entry. If
BV_USE_VCALL_INDEX_P then the corresponding vtable entry should
use a virtual thunk, as opposed to an ordinary thunk.
index of the vcall offset for this entry.
The BV_FN is the declaration for the virtual function itself.
......@@ -615,6 +612,8 @@ enum cp_tree_index
CPTI_DSO_HANDLE,
CPTI_DCAST,
CPTI_DYNAMIC_CLASSES,
CPTI_MAX
};
......@@ -745,6 +744,10 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
destructors. */
#define vtt_parm_type cp_global_trees[CPTI_VTT_PARM_TYPE]
/* A TREE_LIST of all of the dynamic classes in the program. */
#define dynamic_classes cp_global_trees[CPTI_DYNAMIC_CLASSES]
/* Global state. */
struct saved_scope GTY(())
......@@ -1153,12 +1156,13 @@ struct lang_type_class GTY(())
tree primary_base;
tree vfields;
tree vcall_indices;
tree vtables;
tree vbases;
tree tags;
tree as_base;
tree pure_virtuals;
tree friend_classes;
tree rtti;
tree methods;
tree decl_list;
tree template_info;
......@@ -1257,9 +1261,6 @@ struct lang_type GTY(())
convenient, don't reprocess any methods that appear in its redefinition. */
#define TYPE_REDEFINED(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->redefined)
/* The is the basetype that contains NODE's rtti. */
#define CLASSTYPE_RTTI(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->rtti)
/* Nonzero means that this _CLASSTYPE node overloads operator(). */
#define TYPE_OVERLOADS_CALL_EXPR(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->has_call_overloaded)
......@@ -1431,13 +1432,6 @@ struct lang_type GTY(())
/* Nonzero means that this aggr type has been `closed' by a semicolon. */
#define CLASSTYPE_GOT_SEMICOLON(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->got_semicolon)
/* Nonzero means that the main virtual function table pointer needs to be
set because base constructors have placed the wrong value there.
If this is zero, it means that they placed the right value there,
and there is no need to change it. */
#define CLASSTYPE_NEEDS_VIRTUAL_REINIT(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->needs_virtual_reinit)
/* Nonzero means that this type has an X() constructor. */
#define TYPE_HAS_DEFAULT_CONSTRUCTOR(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->h.has_default_ctor)
......@@ -1629,6 +1623,19 @@ struct lang_type GTY(())
/* Used by various search routines. */
#define IDENTIFIER_MARKED(NODE) TREE_LANG_FLAG_0 (NODE)
/* A TREE_LIST of the vcall indices associated with the class NODE.
The TREE_PURPOSE of each node is a FUNCTION_DECL for a virtual
function. The TREE_VALUE is the index into the virtual table where
the vcall offset for that function is stored, when NODE is a
virtual base. */
#define CLASSTYPE_VCALL_INDICES(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->vcall_indices)
/* The various vtables for the class NODE. The primary vtable will be
first, followed by the construction vtables and VTT, if any. */
#define CLASSTYPE_VTABLES(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->vtables)
/* Accessor macros for the vfield slots in structures. */
/* List of virtual table fields that this type contains (both the primary
......@@ -1664,8 +1671,6 @@ struct lang_type GTY(())
/* The function to call. */
#define BV_FN(NODE) (TREE_VALUE (NODE))
/* Nonzero if we should use a virtual thunk for this entry. */
#define BV_USE_VCALL_INDEX_P(NODE) (TREE_LANG_FLAG_0 (NODE))
/* Nonzero for TREE_LIST node means that this list of things
is a list of parameters, as opposed to a list of expressions. */
......@@ -3546,7 +3551,6 @@ extern tree perform_implicit_conversion PARAMS ((tree, tree));
/* in class.c */
extern tree build_base_path PARAMS ((enum tree_code, tree, tree, int));
extern tree convert_to_base (tree, tree, bool);
extern tree build_vbase_path PARAMS ((enum tree_code, tree, tree, tree, int));
extern tree build_vtbl_ref PARAMS ((tree, tree));
extern tree build_vfn_ref PARAMS ((tree, tree));
extern tree get_vtable_decl PARAMS ((tree, int));
......
......@@ -60,7 +60,7 @@ typedef struct priority_info_s {
static void mark_vtable_entries PARAMS ((tree));
static void grok_function_init PARAMS ((tree, tree));
static int finish_vtable_vardecl PARAMS ((tree *, void *));
static int maybe_emit_vtables (tree);
static int is_namespace_ancestor PARAMS ((tree, tree));
static void add_using_namespace PARAMS ((tree, tree, int));
static tree ambiguous_decl PARAMS ((tree, tree, tree,int));
......@@ -1658,12 +1658,7 @@ key_method (type)
method = TREE_CHAIN (method))
if (DECL_VINDEX (method) != NULL_TREE
&& ! DECL_DECLARED_INLINE_P (method)
&& (! DECL_PURE_VIRTUAL_P (method)
#if 0
/* This would be nice, but we didn't think of it in time. */
|| DECL_DESTRUCTOR_P (method)
#endif
))
&& ! DECL_PURE_VIRTUAL_P (method))
return method;
return NULL_TREE;
......@@ -1805,28 +1800,52 @@ output_vtable_inherit (vars)
assemble_vtable_inherit (child_rtx, parent_rtx);
}
/* If necessary, write out the vtables for the dynamic class CTYPE.
Returns non-zero if any vtables were emitted. */
static int
finish_vtable_vardecl (t, data)
tree *t;
void *data ATTRIBUTE_UNUSED;
maybe_emit_vtables (tree ctype)
{
tree vars = *t;
tree ctype = DECL_CONTEXT (vars);
tree vtbl;
tree primary_vtbl;
/* If the vtables for this class have already been emitted there is
nothing more to do. */
primary_vtbl = CLASSTYPE_VTABLES (ctype);
if (TREE_ASM_WRITTEN (primary_vtbl))
return 0;
/* Ignore dummy vtables made by get_vtable_decl. */
if (TREE_TYPE (primary_vtbl) == void_type_node)
return 0;
import_export_class (ctype);
import_export_vtable (vars, ctype, 1);
import_export_vtable (primary_vtbl, ctype, 1);
if (! DECL_EXTERNAL (vars)
&& DECL_NEEDED_P (vars)
&& ! TREE_ASM_WRITTEN (vars))
/* See if any of the vtables are needed. */
for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = TREE_CHAIN (vtbl))
if (!DECL_EXTERNAL (vtbl) && DECL_NEEDED_P (vtbl))
break;
if (!vtbl)
{
/* If the references to this class' vtables are optimized away,
still emit the appropriate debugging information. See
dfs_debug_mark. */
if (DECL_COMDAT (primary_vtbl)
&& CLASSTYPE_DEBUG_REQUESTED (ctype))
note_debug_info_needed (ctype);
return 0;
}
/* The ABI requires that we emit all of the vtables if we emit any
of them. */
for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = TREE_CHAIN (vtbl))
{
if (TREE_TYPE (vars) == void_type_node)
/* It is a dummy vtable made by get_vtable_decl. Ignore it. */
return 0;
/* Write it out. */
mark_vtable_entries (vars);
if (TREE_TYPE (DECL_INITIAL (vars)) == 0)
store_init_value (vars, DECL_INITIAL (vars));
import_export_vtable (vtbl, ctype, 1);
mark_vtable_entries (vtbl);
if (TREE_TYPE (DECL_INITIAL (vtbl)) == 0)
store_init_value (vtbl, DECL_INITIAL (vtbl));
if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG)
{
......@@ -1851,37 +1870,29 @@ finish_vtable_vardecl (t, data)
`S' get written (which would solve the problem) but that would
require more intrusive changes to the g++ front end. */
DECL_IGNORED_P (vars) = 1;
DECL_IGNORED_P (vtbl) = 1;
}
/* Always make vtables weak. */
if (flag_weak)
comdat_linkage (vars);
comdat_linkage (vtbl);
rest_of_decl_compilation (vars, NULL, 1, 1);
rest_of_decl_compilation (vtbl, NULL, 1, 1);
if (flag_vtable_gc)
output_vtable_inherit (vars);
output_vtable_inherit (vtbl);
/* Because we're only doing syntax-checking, we'll never end up
actually marking the variable as written. */
if (flag_syntax_only)
TREE_ASM_WRITTEN (vars) = 1;
/* Since we're writing out the vtable here, also write the debug
info. */
note_debug_info_needed (ctype);
return 1;
TREE_ASM_WRITTEN (vtbl) = 1;
}
/* If the references to this class' vtables were optimized away, still
emit the appropriate debugging information. See dfs_debug_mark. */
if (DECL_COMDAT (vars)
&& CLASSTYPE_DEBUG_REQUESTED (ctype))
note_debug_info_needed (ctype);
/* Since we're writing out the vtable here, also write the debug
info. */
note_debug_info_needed (ctype);
return 0;
return 1;
}
/* Determines the proper settings of TREE_PUBLIC and DECL_EXTERNAL for an
......@@ -2755,6 +2766,8 @@ finish_file ()
do
{
tree t;
reconsider = 0;
/* If there are templates that we've put off instantiating, do
......@@ -2764,10 +2777,9 @@ finish_file ()
/* Write out virtual tables as required. Note that writing out
the virtual table for a template class may cause the
instantiation of members of that class. */
if (walk_vtables (vtable_decl_p,
finish_vtable_vardecl,
/*data=*/0))
reconsider = 1;
for (t = dynamic_classes; t; t = TREE_CHAIN (t))
if (maybe_emit_vtables (TREE_VALUE (t)))
reconsider = 1;
/* Write out needed type info variables. Writing out one variable
might cause others to be needed. */
......
......@@ -1955,9 +1955,8 @@ look_for_overrides (type, fndecl)
return found;
}
/* Look in TYPE for virtual functions with the same signature as FNDECL.
This differs from get_matching_virtual in that it will only return
a function from TYPE. */
/* Look in TYPE for virtual functions with the same signature as
FNDECL. */
tree
look_for_overrides_here (type, fndecl)
......
2002-11-03 Mark Mitchell <mark@codesourcery.com>
* g++.dg/abi/thunk1.C: New test.
* g++.dg/abi/thunk2.C: Likewise.
* g++.dg/abi/vtt1.C: Likewise.
2002-11-02 Diego Novillo <dnovillo@redhat.com>
PR optimization/8423
......
// { dg-do compile { target i?86-*-* } }
struct A {
virtual void f ();
};
struct B : public virtual A {
virtual void f ();
};
struct C {
virtual void g ();
};
struct D : public C, public B {
virtual void f ();
};
void D::f () {}
// { dg-final { scan-assembler _ZThn4_N1D1fEv } }
// { dg-final { scan-assembler _ZTv0_n12_N1D1fEv } }
// { dg-do compile { target i?86-*-* } }
// { dg-options -w }
struct A {
virtual void f2 ();
virtual void f3 ();
};
struct B : virtual public A {
virtual void f3 ();
};
struct C : public A, public B {
virtual void f4 ();
};
struct D : virtual public B, virtual public C, virtual public A
{
virtual void f5 ();
virtual void f6 ();
virtual void f3 ();
};
void D::f3 () {}
// { dg-final { scan-assembler _ZTvn4_n20_N1D2f3Ev } }
// { dg-do compile }
struct A {
};
struct B : virtual public A {
};
B b;
// { dg-final { scan-assembler _ZTT1B } }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment