From 8bfe5753492bfe542555904ce7d0a6021ab42427 Mon Sep 17 00:00:00 2001 From: jason Date: Mon, 13 May 2002 08:00:48 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@53416 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 11 +++++++ gcc/cp/class.c | 88 ++++++++++++++++++-------------------------------------- gcc/cp/decl2.c | 7 +++-- gcc/cp/rtti.c | 6 ++-- gcc/cp/typeck.c | 1 + 5 files changed, 48 insertions(+), 65 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b1eda61..da89625 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2002-05-13 Jason Merrill + + * 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 * 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. */ -- 2.7.4