class.c (build_vtbl_ref_1): Use fixed_type_or_null.
* class.c (build_vtbl_ref_1): Use fixed_type_or_null. (fixed_type_or_null): See through reference vars. (build_base_path): Vtable contents are constant. * typeck.c (get_member_function_from_ptrfunc): Likewise. * rtti.c (emit_tinfo_decl): Call import_export_decl. * decl2.c (import_export_decl): Set DECL_NOT_REALLY_EXTERN on tinfo decls by default. Don't mess with the builtins. From-SVN: r53416
This commit is contained in:
parent
a1cb2d640d
commit
f63ab95173
@ -1,3 +1,14 @@
|
||||
2002-05-13 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* class.c (build_vtbl_ref_1): Use fixed_type_or_null.
|
||||
(fixed_type_or_null): See through reference vars.
|
||||
(build_base_path): Vtable contents are constant.
|
||||
* typeck.c (get_member_function_from_ptrfunc): Likewise.
|
||||
|
||||
* rtti.c (emit_tinfo_decl): Call import_export_decl.
|
||||
* decl2.c (import_export_decl): Set DECL_NOT_REALLY_EXTERN on
|
||||
tinfo decls by default. Don't mess with the builtins.
|
||||
|
||||
2002-05-12 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* cp-lang.c (ok_to_generate_alias_set_for_type): Backend-created
|
||||
|
@ -316,7 +316,8 @@ build_base_path (code, expr, binfo, nonnull)
|
||||
build_pointer_type (ptrdiff_type_node),
|
||||
v_offset);
|
||||
v_offset = build_indirect_ref (v_offset, NULL);
|
||||
|
||||
TREE_CONSTANT (v_offset) = 1;
|
||||
|
||||
offset = cp_convert (ptrdiff_type_node,
|
||||
size_diffop (offset, BINFO_OFFSET (v_binfo)));
|
||||
|
||||
@ -401,75 +402,36 @@ static tree
|
||||
build_vtbl_ref_1 (instance, idx)
|
||||
tree instance, idx;
|
||||
{
|
||||
tree vtbl, aref;
|
||||
tree basetype = TREE_TYPE (instance);
|
||||
tree aref;
|
||||
tree vtbl = NULL_TREE;
|
||||
|
||||
/* Try to figure out what a reference refers to, and
|
||||
access its virtual function table directly. */
|
||||
|
||||
int cdtorp = 0;
|
||||
tree fixed_type = fixed_type_or_null (instance, NULL, &cdtorp);
|
||||
|
||||
tree basetype = TREE_TYPE (instance);
|
||||
if (TREE_CODE (basetype) == REFERENCE_TYPE)
|
||||
basetype = TREE_TYPE (basetype);
|
||||
|
||||
if (instance == current_class_ref)
|
||||
vtbl = build_vfield_ref (instance, basetype);
|
||||
else
|
||||
if (fixed_type && !cdtorp)
|
||||
{
|
||||
if (optimize)
|
||||
{
|
||||
/* Try to figure out what a reference refers to, and
|
||||
access its virtual function table directly. */
|
||||
tree ref = NULL_TREE;
|
||||
tree binfo = lookup_base (fixed_type, basetype,
|
||||
ba_ignore|ba_quiet, NULL);
|
||||
if (binfo)
|
||||
vtbl = BINFO_VTABLE (binfo);
|
||||
}
|
||||
|
||||
if (TREE_CODE (instance) == INDIRECT_REF
|
||||
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (instance, 0))) == REFERENCE_TYPE)
|
||||
ref = TREE_OPERAND (instance, 0);
|
||||
else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
|
||||
ref = instance;
|
||||
|
||||
if (ref && TREE_CODE (ref) == VAR_DECL
|
||||
&& DECL_INITIAL (ref))
|
||||
{
|
||||
tree init = DECL_INITIAL (ref);
|
||||
|
||||
while (TREE_CODE (init) == NOP_EXPR
|
||||
|| TREE_CODE (init) == NON_LVALUE_EXPR)
|
||||
init = TREE_OPERAND (init, 0);
|
||||
if (TREE_CODE (init) == ADDR_EXPR)
|
||||
{
|
||||
init = TREE_OPERAND (init, 0);
|
||||
if (IS_AGGR_TYPE (TREE_TYPE (init))
|
||||
&& (TREE_CODE (init) == PARM_DECL
|
||||
|| TREE_CODE (init) == VAR_DECL))
|
||||
instance = init;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_AGGR_TYPE (TREE_TYPE (instance))
|
||||
&& (TREE_CODE (instance) == RESULT_DECL
|
||||
|| TREE_CODE (instance) == PARM_DECL
|
||||
|| TREE_CODE (instance) == VAR_DECL))
|
||||
{
|
||||
vtbl = TYPE_BINFO_VTABLE (basetype);
|
||||
/* Knowing the dynamic type of INSTANCE we can easily obtain
|
||||
the correct vtable entry. We resolve this back to be in
|
||||
terms of the primary vtable. */
|
||||
if (TREE_CODE (vtbl) == PLUS_EXPR)
|
||||
{
|
||||
idx = fold (build (PLUS_EXPR,
|
||||
TREE_TYPE (idx),
|
||||
idx,
|
||||
build (EXACT_DIV_EXPR,
|
||||
TREE_TYPE (idx),
|
||||
TREE_OPERAND (vtbl, 1),
|
||||
TYPE_SIZE_UNIT (vtable_entry_type))));
|
||||
vtbl = get_vtbl_decl_for_binfo (TYPE_BINFO (basetype));
|
||||
}
|
||||
}
|
||||
else
|
||||
vtbl = build_vfield_ref (instance, basetype);
|
||||
if (!vtbl)
|
||||
{
|
||||
vtbl = build_vfield_ref (instance, basetype);
|
||||
}
|
||||
|
||||
assemble_external (vtbl);
|
||||
|
||||
aref = build_array_ref (vtbl, idx);
|
||||
TREE_CONSTANT (aref) = 1;
|
||||
|
||||
return aref;
|
||||
}
|
||||
@ -5396,7 +5358,7 @@ fixed_type_or_null (instance, nonnull, cdtorp)
|
||||
return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
|
||||
if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST)
|
||||
/* Propagate nonnull. */
|
||||
fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
|
||||
return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
|
||||
return NULL_TREE;
|
||||
|
||||
case NOP_EXPR:
|
||||
@ -5423,6 +5385,7 @@ fixed_type_or_null (instance, nonnull, cdtorp)
|
||||
/* fall through... */
|
||||
case TARGET_EXPR:
|
||||
case PARM_DECL:
|
||||
case RESULT_DECL:
|
||||
if (IS_AGGR_TYPE (TREE_TYPE (instance)))
|
||||
{
|
||||
if (nonnull)
|
||||
@ -5449,6 +5412,11 @@ fixed_type_or_null (instance, nonnull, cdtorp)
|
||||
/* Reference variables should be references to objects. */
|
||||
if (nonnull)
|
||||
*nonnull = 1;
|
||||
|
||||
if (TREE_CODE (instance) == VAR_DECL
|
||||
&& DECL_INITIAL (instance))
|
||||
return fixed_type_or_null (DECL_INITIAL (instance),
|
||||
nonnull, cdtorp);
|
||||
}
|
||||
return NULL_TREE;
|
||||
|
||||
|
@ -2514,6 +2514,7 @@ import_export_decl (decl)
|
||||
if (IS_AGGR_TYPE (ctype))
|
||||
import_export_class (ctype);
|
||||
|
||||
DECL_NOT_REALLY_EXTERN (decl) = 1;
|
||||
if (IS_AGGR_TYPE (ctype) && CLASSTYPE_INTERFACE_KNOWN (ctype)
|
||||
&& TYPE_POLYMORPHIC_P (ctype)
|
||||
/* If -fno-rtti, we're not necessarily emitting this stuff with
|
||||
@ -2537,9 +2538,9 @@ import_export_decl (decl)
|
||||
if (flag_weak)
|
||||
comdat_linkage (decl);
|
||||
}
|
||||
else if (TYPE_BUILT_IN (ctype)
|
||||
&& same_type_p (ctype, TYPE_MAIN_VARIANT (ctype)))
|
||||
DECL_NOT_REALLY_EXTERN (decl) = 0;
|
||||
/* We used to exclude the builtin types here, but that broke
|
||||
emit_support_tinfos. Let rtti.c choose whether or not to emit
|
||||
them. */
|
||||
else
|
||||
comdat_linkage (decl);
|
||||
}
|
||||
|
@ -1462,9 +1462,11 @@ emit_tinfo_decl (decl_ptr, data)
|
||||
my_friendly_assert (TREE_TYPE (tinfo_decl) == tinfo_decl_type, 20000121);
|
||||
tinfo_type = TREE_TYPE (DECL_NAME (tinfo_decl));
|
||||
my_friendly_assert (tinfo_type != NULL_TREE, 20000120);
|
||||
|
||||
if (!DECL_NEEDED_P (tinfo_decl))
|
||||
|
||||
import_export_decl (tinfo_decl);
|
||||
if (DECL_REALLY_EXTERN (tinfo_decl) || !DECL_NEEDED_P (tinfo_decl))
|
||||
return 0;
|
||||
|
||||
/* Say we've dealt with it. */
|
||||
TREE_TYPE (DECL_NAME (tinfo_decl)) = NULL_TREE;
|
||||
|
||||
|
@ -2911,6 +2911,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
|
||||
/* Finally, extract the function pointer from the vtable. */
|
||||
e2 = fold (build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, idx));
|
||||
e2 = build_indirect_ref (e2, NULL);
|
||||
TREE_CONSTANT (e2) = 1;
|
||||
|
||||
/* When using function descriptors, the address of the
|
||||
vtable entry is treated as a function pointer. */
|
||||
|
Loading…
Reference in New Issue
Block a user