aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2002-05-13 04:00:48 -0400
committerJason Merrill <jason@gcc.gnu.org>2002-05-13 04:00:48 -0400
commitf63ab951732ba679174976e269fe8697742ebbcd (patch)
tree8cecf23aef6e66bf41d420e5722b052aef5792fc
parenta1cb2d640d085630bc7356b0b991c0c478b67a33 (diff)
downloadgcc-f63ab951732ba679174976e269fe8697742ebbcd.zip
gcc-f63ab951732ba679174976e269fe8697742ebbcd.tar.gz
gcc-f63ab951732ba679174976e269fe8697742ebbcd.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/class.c88
-rw-r--r--gcc/cp/decl2.c7
-rw-r--r--gcc/cp/rtti.c6
-rw-r--r--gcc/cp/typeck.c1
5 files changed, 48 insertions, 65 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b1eda61..da89625e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index b06828f..98f32dc 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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;
-
- 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;
- }
- }
- }
+ tree binfo = lookup_base (fixed_type, basetype,
+ ba_ignore|ba_quiet, NULL);
+ if (binfo)
+ vtbl = BINFO_VTABLE (binfo);
+ }
- 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;
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 2054a37..2fd67ae 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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);
}
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 16df801..63ffcb7 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -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;
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 329bc33..3b92a64 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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. */