From c83788c9a91bd06f2b9a6c344f817e1326878ce8 Mon Sep 17 00:00:00 2001 From: mmitchel Date: Sat, 26 Oct 2002 00:44:44 +0000 Subject: [PATCH] * call.c (build_over_call): Use DECL_CONTEXT, not DECL_VIRTUAL_CONTEXT. * class.c (modify_vtable_entry): Don't mess with DECL_VIRTUAL_CONTEXT. (set_vindex): Remove. (set_primary_base): Remove vfuns_p parameter. (determine_primary_base): Likewise. (modify_all_vtables): Likewise. (layout_class_type): Likewise. Adjust calls to other functions accordingly. (finish_struct_1): Adjust calls to modified functions. Set DECL_VINDEX here. * cp-tree.h (lang_type_class): Remove vsize. (CLASSTYPE_VSIZE): Remove. (lang_decl): Remove thunks. (DECL_THUNKS): Adjust. (DECL_VIRTUAL_CONTEXT): Remove. (duplicate_decls): Don't copy it. * pt.c (build_template_decl): Don't set it. (tsubst_decl): Likewise. * typeck.c (expand_ptrmemfunc_cst): Don't use it. * g++.dg/lookup/ptrmem1.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@58548 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 22 ++++++++++ gcc/cp/call.c | 2 +- gcc/cp/class.c | 82 +++++++++++------------------------ gcc/cp/cp-tree.h | 22 ++-------- gcc/cp/decl.c | 11 ++--- gcc/cp/pt.c | 10 ----- gcc/cp/typeck.c | 2 +- gcc/testsuite/ChangeLog | 2 + gcc/testsuite/g++.dg/lookup/ptrmem1.C | 15 +++++++ 9 files changed, 74 insertions(+), 94 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lookup/ptrmem1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 03a13c1..d9e212a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -6,6 +6,28 @@ 2002-10-25 Mark Mitchell + * call.c (build_over_call): Use DECL_CONTEXT, not + DECL_VIRTUAL_CONTEXT. + * class.c (modify_vtable_entry): Don't mess with + DECL_VIRTUAL_CONTEXT. + (set_vindex): Remove. + (set_primary_base): Remove vfuns_p parameter. + (determine_primary_base): Likewise. + (modify_all_vtables): Likewise. + (layout_class_type): Likewise. Adjust calls to other functions + accordingly. + (finish_struct_1): Adjust calls to modified functions. Set + DECL_VINDEX here. + * cp-tree.h (lang_type_class): Remove vsize. + (CLASSTYPE_VSIZE): Remove. + (lang_decl): Remove thunks. + (DECL_THUNKS): Adjust. + (DECL_VIRTUAL_CONTEXT): Remove. + (duplicate_decls): Don't copy it. + * pt.c (build_template_decl): Don't set it. + (tsubst_decl): Likewise. + * typeck.c (expand_ptrmemfunc_cst): Don't use it. + * class.c (build_vtbl_initializer): Don't use build_vtable_entry. (build_vtable_entry): Remove. * cp-tree.h (BINFO_VIRTUALS): Expand documentation. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 1b79ac4..4ec8d5e 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4507,7 +4507,7 @@ build_over_call (cand, args, flags) { tree t, *p = &TREE_VALUE (converted_args); tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (*p)), - DECL_VIRTUAL_CONTEXT (fn), + DECL_CONTEXT (fn), ba_any, NULL); my_friendly_assert (binfo && binfo != error_mark_node, 20010730); diff --git a/gcc/cp/class.c b/gcc/cp/class.c index a11ad7b..8263161 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -116,8 +116,8 @@ static int alter_access PARAMS ((tree, tree, tree)); static void handle_using_decl PARAMS ((tree, tree)); static void check_for_override PARAMS ((tree, tree)); static tree dfs_modify_vtables PARAMS ((tree, void *)); -static tree modify_all_vtables PARAMS ((tree, int *, tree)); -static void determine_primary_base PARAMS ((tree, int *)); +static tree modify_all_vtables PARAMS ((tree, tree)); +static void determine_primary_base PARAMS ((tree)); static void finish_struct_methods PARAMS ((tree)); static void maybe_warn_about_overly_private_class PARAMS ((tree)); static int field_decl_cmp PARAMS ((const tree *, const tree *)); @@ -142,10 +142,10 @@ static void check_bases PARAMS ((tree, int *, int *, int *)); static void check_bases_and_members (tree); static tree create_vtable_ptr (tree, tree *); static void include_empty_classes (record_layout_info); -static void layout_class_type (tree, int *, tree *); +static void layout_class_type (tree, tree *); static void fixup_pending_inline PARAMS ((tree)); static void fixup_inline_methods PARAMS ((tree)); -static void set_primary_base PARAMS ((tree, tree, int *)); +static void set_primary_base PARAMS ((tree, tree)); static void propagate_binfo_offsets PARAMS ((tree, tree, tree)); static void layout_virtual_bases (record_layout_info, splay_tree); static tree dfs_set_offset_for_unshared_vbases PARAMS ((tree, void *)); @@ -173,7 +173,6 @@ static bool layout_empty_base PARAMS ((tree, tree, splay_tree, tree)); static void accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree, tree)); static tree dfs_accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree, tree)); -static void set_vindex PARAMS ((tree, int *)); static void build_rtti_vtbl_entries PARAMS ((tree, vtbl_init_data *)); static void build_vcall_and_vbase_vtbl_entries PARAMS ((tree, vtbl_init_data *)); @@ -738,37 +737,9 @@ modify_vtable_entry (t, binfo, fndecl, delta, virtuals) BV_DELTA (v) = delta; BV_VCALL_INDEX (v) = NULL_TREE; BV_FN (v) = fndecl; - - /* Now assign virtual dispatch information, if unset. We can - dispatch this through any overridden base function. - - FIXME this can choose a secondary vtable if the primary is not - also lexically first, leading to useless conversions. - In the V3 ABI, there's no reason for DECL_VIRTUAL_CONTEXT to - ever be different from DECL_CONTEXT. */ - if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST) - { - DECL_VINDEX (fndecl) = DECL_VINDEX (base_fndecl); - DECL_VIRTUAL_CONTEXT (fndecl) = DECL_VIRTUAL_CONTEXT (base_fndecl); - } } } -/* Set DECL_VINDEX for DECL. VINDEX_P is the number of virtual - functions present in the vtable so far. */ - -static void -set_vindex (decl, vfuns_p) - tree decl; - int *vfuns_p; -{ - int vindex; - - vindex = *vfuns_p; - *vfuns_p += (TARGET_VTABLE_USES_DESCRIPTORS - ? TARGET_VTABLE_USES_DESCRIPTORS : 1); - DECL_VINDEX (decl) = build_shared_int_cst (vindex); -} /* Add method METHOD to class TYPE. If ERROR_P is true, we are adding the method after the class has already been defined because a @@ -1577,10 +1548,9 @@ mark_primary_bases (type) /* Make the BINFO the primary base of T. */ static void -set_primary_base (t, binfo, vfuns_p) +set_primary_base (t, binfo) tree t; tree binfo; - int *vfuns_p; { tree basetype; @@ -1590,15 +1560,13 @@ set_primary_base (t, binfo, vfuns_p) TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype); TYPE_VFIELD (t) = TYPE_VFIELD (basetype); CLASSTYPE_RTTI (t) = CLASSTYPE_RTTI (basetype); - *vfuns_p = CLASSTYPE_VSIZE (basetype); } /* Determine the primary class for T. */ static void -determine_primary_base (t, vfuns_p) +determine_primary_base (t) tree t; - int *vfuns_p; { int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t); tree vbases; @@ -1630,7 +1598,7 @@ determine_primary_base (t, vfuns_p) if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t)) { - set_primary_base (t, base_binfo, vfuns_p); + set_primary_base (t, base_binfo); CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (basetype)); } else @@ -1732,7 +1700,7 @@ determine_primary_base (t, vfuns_p) /* If we've got a primary base, use it. */ if (candidate) { - set_primary_base (t, candidate, vfuns_p); + set_primary_base (t, candidate); CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (BINFO_TYPE (candidate))); } @@ -2544,9 +2512,8 @@ dfs_modify_vtables (binfo, data) should therefore be appended to the end of the vtable for T. */ static tree -modify_all_vtables (t, vfuns_p, virtuals) +modify_all_vtables (t, virtuals) tree t; - int *vfuns_p; tree virtuals; { tree binfo = TYPE_BINFO (t); @@ -2570,12 +2537,6 @@ modify_all_vtables (t, vfuns_p, virtuals) if (!value_member (fn, BINFO_VIRTUALS (binfo)) || DECL_VINDEX (fn) == error_mark_node) { - /* Set the vtable index. */ - set_vindex (fn, vfuns_p); - /* We don't need to convert to a base class when calling - this function. */ - DECL_VIRTUAL_CONTEXT (fn) = t; - /* We don't need to adjust the `this' pointer when calling this function. */ BV_DELTA (*fnsp) = integer_zero_node; @@ -2588,7 +2549,7 @@ modify_all_vtables (t, vfuns_p, virtuals) /* We've already got an entry for this function. Skip it. */ *fnsp = TREE_CHAIN (*fnsp); } - + return virtuals; } @@ -4850,7 +4811,7 @@ include_empty_classes (record_layout_info rli) pointer. Accumulate declared virtual functions on VIRTUALS_P. */ static void -layout_class_type (tree t, int *vfuns_p, tree *virtuals_p) +layout_class_type (tree t, tree *virtuals_p) { tree non_static_data_members; tree field; @@ -4874,7 +4835,7 @@ layout_class_type (tree t, int *vfuns_p, tree *virtuals_p) /* If possible, we reuse the virtual function table pointer from one of our base classes. */ - determine_primary_base (t, vfuns_p); + determine_primary_base (t); /* Create a pointer to our virtual function table. */ vptr = create_vtable_ptr (t, virtuals_p); @@ -5145,7 +5106,6 @@ finish_struct_1 (t) tree t; { tree x; - int vfuns; /* A TREE_LIST. The TREE_VALUE of each node is a FUNCTION_DECL. */ tree virtuals = NULL_TREE; int n_fields = 0; @@ -5166,7 +5126,6 @@ finish_struct_1 (t) TYPE_SIZE (t) = NULL_TREE; CLASSTYPE_GOT_SEMICOLON (t) = 0; CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE; - vfuns = 0; CLASSTYPE_RTTI (t) = NULL_TREE; fixup_inline_methods (t); @@ -5182,7 +5141,7 @@ finish_struct_1 (t) check_bases_and_members (t); /* Layout the class itself. */ - layout_class_type (t, &vfuns, &virtuals); + layout_class_type (t, &virtuals); /* Make sure that we get our own copy of the vfield FIELD_DECL. */ vfield = TYPE_VFIELD (t); @@ -5206,7 +5165,7 @@ finish_struct_1 (t) else my_friendly_assert (!vfield || DECL_FIELD_CONTEXT (vfield) == t, 20010726); - virtuals = modify_all_vtables (t, &vfuns, nreverse (virtuals)); + virtuals = modify_all_vtables (t, nreverse (virtuals)); /* If we created a new vtbl pointer for this class, add it to the list. */ @@ -5246,6 +5205,9 @@ finish_struct_1 (t) if (TYPE_CONTAINS_VPTR_P (t)) { + int vindex; + tree fn; + if (TYPE_BINFO_VTABLE (t)) my_friendly_assert (DECL_VIRTUAL_P (TYPE_BINFO_VTABLE (t)), 20000116); @@ -5253,9 +5215,17 @@ finish_struct_1 (t) my_friendly_assert (TYPE_BINFO_VIRTUALS (t) == NULL_TREE, 20000116); - CLASSTYPE_VSIZE (t) = vfuns; /* Add entries for virtual functions introduced by this class. */ TYPE_BINFO_VIRTUALS (t) = chainon (TYPE_BINFO_VIRTUALS (t), virtuals); + + /* Set DECL_VINDEX for all functions declared in this class. */ + for (vindex = 0, fn = BINFO_VIRTUALS (TYPE_BINFO (t)); + fn; + fn = TREE_CHAIN (fn), + vindex += (TARGET_VTABLE_USES_DESCRIPTORS + ? TARGET_VTABLE_USES_DESCRIPTORS : 1)) + if (TREE_CODE (DECL_VINDEX (BV_FN (fn))) != INTEGER_CST) + DECL_VINDEX (BV_FN (fn)) = build_shared_int_cst (vindex); } finish_struct_bits (t); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 5b30d39..e1544fd 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1150,8 +1150,6 @@ struct lang_type_class GTY(()) remove a flag. */ unsigned dummy : 4; - int vsize; - tree primary_base; tree vfields; tree vbases; @@ -1375,10 +1373,6 @@ struct lang_type GTY(()) #define CLASSTYPE_PRIMARY_BINFO(NODE) \ (LANG_TYPE_CLASS_CHECK (NODE)->primary_base) -/* The number of virtual functions present in this class' virtual - function table. */ -#define CLASSTYPE_VSIZE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->vsize) - /* A chain of BINFOs for the direct and indirect virtual base classes that this type uses in a post-order depth-first left-to-right order. (In other words, these bases appear in the order that they @@ -1766,13 +1760,10 @@ struct lang_decl GTY(()) { tree befriending_classes; - /* For a virtual FUNCTION_DECL, this is DECL_VIRTUAL_CONTEXT. For a - non-virtual FUNCTION_DECL, this is DECL_FRIEND_CONTEXT. */ + /* For a non-virtual FUNCTION_DECL, this is + DECL_FRIEND_CONTEXT. For a virtual FUNCTION_DECL for which + DECL_THUNK_P does not hold, this is DECL_THUNKS. */ tree context; - - /* In a FUNCTION_DECL for which DECL_THUNK_P does not hold, this - is DECL_THUNKS. */ - tree thunks; /* In a FUNCTION_DECL, this is DECL_CLONED_FUNCTION. */ tree cloned_function; @@ -2060,7 +2051,7 @@ struct lang_decl GTY(()) /* The thunks associated with NODE, a FUNCTION_DECL that is not itself a thunk. */ #define DECL_THUNKS(NODE) \ - (DECL_LANG_SPECIFIC (NODE)->u.f.thunks) + (DECL_LANG_SPECIFIC (NODE)->u.f.context) /* Nonzero if NODE is a thunk, rather than an ordinary function. */ #define DECL_THUNK_P(NODE) \ @@ -2114,11 +2105,6 @@ struct lang_decl GTY(()) (DECL_CONTEXT (NODE) ? DECL_CONTEXT (NODE) : global_namespace) #define FROB_CONTEXT(NODE) ((NODE) == global_namespace ? NULL_TREE : (NODE)) -/* For a virtual function, the base where we find its vtable entry. - For a non-virtual function, the base where it is defined. */ -#define DECL_VIRTUAL_CONTEXT(NODE) \ - (DECL_LANG_SPECIFIC (NODE)->u.f.context) - /* 1 iff NODE has namespace scope, including the global namespace. */ #define DECL_NAMESPACE_SCOPE_P(NODE) \ (!DECL_TEMPLATE_PARM_P (NODE) \ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 3e1c215..e3b7b5b 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3374,8 +3374,6 @@ duplicate_decls (newdecl, olddecl) definition. */ if (DECL_VINDEX (olddecl)) DECL_VINDEX (newdecl) = DECL_VINDEX (olddecl); - if (DECL_VIRTUAL_CONTEXT (olddecl)) - DECL_VIRTUAL_CONTEXT (newdecl) = DECL_VIRTUAL_CONTEXT (olddecl); if (DECL_CONTEXT (olddecl)) DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl); DECL_STATIC_CONSTRUCTOR (newdecl) |= DECL_STATIC_CONSTRUCTOR (olddecl); @@ -3412,12 +3410,9 @@ duplicate_decls (newdecl, olddecl) if (newtype != error_mark_node && oldtype != error_mark_node && TYPE_LANG_SPECIFIC (newtype) && TYPE_LANG_SPECIFIC (oldtype)) - { - CLASSTYPE_VSIZE (newtype) = CLASSTYPE_VSIZE (oldtype); - CLASSTYPE_FRIEND_CLASSES (newtype) - = CLASSTYPE_FRIEND_CLASSES (oldtype); - } - + CLASSTYPE_FRIEND_CLASSES (newtype) + = CLASSTYPE_FRIEND_CLASSES (oldtype); +\ DECL_ORIGINAL_TYPE (newdecl) = DECL_ORIGINAL_TYPE (olddecl); } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index ceff84f..183a360 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2106,8 +2106,6 @@ build_template_decl (decl, parms) DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl); if (DECL_LANG_SPECIFIC (decl)) { - if (CAN_HAVE_FULL_LANG_DECL_P (decl)) - DECL_VIRTUAL_CONTEXT (tmpl) = DECL_VIRTUAL_CONTEXT (decl); DECL_STATIC_FUNCTION_P (tmpl) = DECL_STATIC_FUNCTION_P (decl); DECL_CONSTRUCTOR_P (tmpl) = DECL_CONSTRUCTOR_P (decl); DECL_DESTRUCTOR_P (tmpl) = DECL_DESTRUCTOR_P (decl); @@ -5777,10 +5775,6 @@ tsubst_decl (t, args, type, complain) = tsubst_aggr_type (DECL_CONTEXT (t), args, complain, in_decl, /*entering_scope=*/1); - DECL_VIRTUAL_CONTEXT (r) - = tsubst_aggr_type (DECL_VIRTUAL_CONTEXT (t), args, - complain, in_decl, - /*entering_scope=*/1); DECL_TEMPLATE_INFO (r) = build_tree_list (t, args); if (TREE_CODE (decl) == TYPE_DECL) @@ -5951,10 +5945,6 @@ tsubst_decl (t, args, type, complain) SET_DECL_RTL (r, NULL_RTX); DECL_CONTEXT (r) = ctx; - DECL_VIRTUAL_CONTEXT (r) - = tsubst_aggr_type (DECL_VIRTUAL_CONTEXT (t), args, - complain, t, - /*entering_scope=*/1); if (member && DECL_CONV_FN_P (r)) /* Type-conversion operator. Reconstruct the name, in diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index ae78dbf..9b4fbf6 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5695,7 +5695,7 @@ expand_ptrmemfunc_cst (cst, delta, pfn) /* If we're dealing with a virtual function, we have to adjust 'this' again, to point to the base which provides the vtable entry for fn; the call will do the opposite adjustment. */ - tree orig_class = DECL_VIRTUAL_CONTEXT (fn); + tree orig_class = DECL_CONTEXT (fn); tree binfo = binfo_or_else (orig_class, fn_class); *delta = fold (build (PLUS_EXPR, TREE_TYPE (*delta), *delta, BINFO_OFFSET (binfo))); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e6874ec..adb6613 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -4,6 +4,8 @@ 2002-10-25 Mark Mitchell + * g++.dg/lookup/ptrmem1.C: New test. + * g++.dg/abi/vthunk2.C: New test. 2002-10-25 Zack Weinberg diff --git a/gcc/testsuite/g++.dg/lookup/ptrmem1.C b/gcc/testsuite/g++.dg/lookup/ptrmem1.C new file mode 100644 index 0000000..5bdef26 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/ptrmem1.C @@ -0,0 +1,15 @@ +struct A { + virtual void f (); +}; + +struct B : public A { +}; + +struct C : public A { +}; + +struct D : public B, C { + virtual void f (); +}; + +void (D::*p)() = &D::f; -- 2.7.4