aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog41
-rw-r--r--gcc/cp/call.c2
-rw-r--r--gcc/cp/class.c101
-rw-r--r--gcc/cp/cp-tree.h47
-rw-r--r--gcc/cp/decl.c71
-rw-r--r--gcc/cp/decl2.c12
-rw-r--r--gcc/cp/error.c20
-rw-r--r--gcc/cp/init.c8
-rw-r--r--gcc/cp/rtti.c10
-rw-r--r--gcc/cp/search.c300
-rw-r--r--gcc/cp/typeck.c22
11 files changed, 97 insertions, 537 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 10da3ae..ed073c1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,44 @@
+2001-07-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ Remove flag_vtable_thunk. It is always on for the 3.0 ABI.
+ * cp-tree.h (CPTI_DELTA2_IDENTIFIER): Remove.
+ (CPTI_INDEX_IDENTIFIER): Remove.
+ (CPT_PFN_OR_DELTA2_IDENTIFIER): Remove.
+ (delta2_identifier): Remove.
+ (index_identifier): Remove.
+ (pfn_or_delta2_identifier): Remove.
+ (flag_vtable_thunks): Remove.
+ (VTABLE_DELTA2_NAME): Remove.
+ (VTABLE_INDEX_NAME): Remove.
+ (FNADDR_FROM_VTABLE_ENTRY): Adjust.
+ (vfunc_ptr_type_node): Adjust.
+ (VTABLE_NAME_PREFIX): Adjust.
+ (build_vfn_ref): Lose first parameter.
+ (fixup_all_virtual_upcast_offsets): Remove.
+ * decl.c (initialize_predefined_identifiers): Remove
+ delta2_identifier, index_identifier, pfn_or_delta2_identifier.
+ (init_decl_processing): Remove no-vtable-thunk code.
+ * decl2.c (flag_vtable_thunks): Remove.
+ (mark_vtable_entries): Remove no-vtable-thunk code.
+ * error.c (dump_decl): Remove no-vtable-thunk code.
+ (dump_expr): Adjust ptr to member function code.
+ * init.c (initialize_vtable_ptrs): Remove no-vtable-thunk
+ code.
+ * rtti.c (build_headof): Remove no-vtable-thunk code.
+ (get_tinfo_decl_dynamic): Adjust build_vfn_ref call.
+ * search.c (get_base_distance): Remove expand_upcast_fixups case.
+ (virtual_context) Remove.
+ (expand_upcast_fixups): Remove.
+ (fixup_virtual_upcast_offsets): Remove.
+ (fixup_all_virtual_upcast_offsets): Remove.
+ * typeck.c (get_member_function_from_ptrfunc): Remove
+ no-vtable-thunk code.
+ * call.c (build_over_call): Adjust call to build_vfn_ref.
+ * class.c (build_vfn_ref): Lose first parameter. Remove
+ no-vtable-thunk code.
+ (build_rtti_vtbl_entries): Remove no-vtable-thunk code.
+ (build_vtable_entry): Remove no-vtable-thunk code.
+
2001-07-20 Nathan Sidwell <nathan@codesourcery.com>
Remove old-abi remnants. Remove comments about old abi
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 7cfbd96..c8c5246 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -4307,7 +4307,7 @@ build_over_call (cand, args, flags)
if (DECL_CONTEXT (fn) && TYPE_JAVA_INTERFACE (DECL_CONTEXT (fn)))
fn = build_java_interface_fn_ref (fn, *p);
else
- fn = build_vfn_ref (p, build_indirect_ref (*p, 0), DECL_VINDEX (fn));
+ fn = build_vfn_ref (build_indirect_ref (*p, 0), DECL_VINDEX (fn));
TREE_TYPE (fn) = t;
}
else if (DECL_INLINE (fn))
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 99c8638..1667758 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -543,37 +543,16 @@ build_vtbl_ref (instance, idx)
}
/* Given an object INSTANCE, return an expression which yields the
- virtual function corresponding to INDEX. There are many special
- cases for INSTANCE which we take care of here, mainly to avoid
- creating extra tree nodes when we don't have to. */
+ virtual function corresponding to IDX. */
tree
-build_vfn_ref (ptr_to_instptr, instance, idx)
- tree *ptr_to_instptr, instance;
+build_vfn_ref (instance, idx)
+ tree instance;
tree idx;
{
tree aref = build_vtbl_ref (instance, idx);
- /* When using thunks, there is no extra delta, and we get the pfn
- directly. */
- if (flag_vtable_thunks)
- return aref;
-
- if (ptr_to_instptr)
- {
- /* Save the intermediate result in a SAVE_EXPR so we don't have to
- compute each component of the virtual function pointer twice. */
- if (TREE_CODE (aref) == INDIRECT_REF)
- TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0));
-
- *ptr_to_instptr
- = build (PLUS_EXPR, TREE_TYPE (*ptr_to_instptr),
- *ptr_to_instptr,
- cp_convert (ptrdiff_type_node,
- build_component_ref (aref, delta_identifier, NULL_TREE, 0)));
- }
-
- return build_component_ref (aref, pfn_identifier, NULL_TREE, 0);
+ return aref;
}
/* Return the name of the virtual function table (as an IDENTIFIER_NODE)
@@ -8019,16 +7998,12 @@ build_rtti_vtbl_entries (binfo, vid)
vid->last_init = &TREE_CHAIN (*vid->last_init);
/* Add the offset-to-top entry. It comes earlier in the vtable that
- the the typeinfo entry. */
- if (flag_vtable_thunks)
- {
- /* Convert the offset to look like a function pointer, so that
- we can put it in the vtable. */
- init = build1 (NOP_EXPR, vfunc_ptr_type_node, offset);
- TREE_CONSTANT (init) = 1;
- *vid->last_init = build_tree_list (NULL_TREE, init);
- vid->last_init = &TREE_CHAIN (*vid->last_init);
- }
+ the the typeinfo entry. Convert the offset to look like a
+ function pointer, so that we can put it in the vtable. */
+ init = build1 (NOP_EXPR, vfunc_ptr_type_node, offset);
+ TREE_CONSTANT (init) = 1;
+ *vid->last_init = build_tree_list (NULL_TREE, init);
+ vid->last_init = &TREE_CHAIN (*vid->last_init);
}
/* Build an entry in the virtual function table. DELTA is the offset
@@ -8045,54 +8020,18 @@ build_vtable_entry (delta, vcall_index, entry)
tree vcall_index;
tree entry;
{
- if (flag_vtable_thunks)
- {
- tree fn;
-
- fn = TREE_OPERAND (entry, 0);
- if ((!integer_zerop (delta) || vcall_index != NULL_TREE)
- && fn != abort_fndecl)
- {
- entry = make_thunk (entry, delta, vcall_index);
- entry = build1 (ADDR_EXPR, vtable_entry_type, entry);
- TREE_READONLY (entry) = 1;
- TREE_CONSTANT (entry) = 1;
- }
-#ifdef GATHER_STATISTICS
- n_vtable_entries += 1;
-#endif
- return entry;
- }
- else
+ tree fn = TREE_OPERAND (entry, 0);
+
+ if ((!integer_zerop (delta) || vcall_index != NULL_TREE)
+ && fn != abort_fndecl)
{
- tree elems = tree_cons (NULL_TREE, delta,
- tree_cons (NULL_TREE, integer_zero_node,
- build_tree_list (NULL_TREE, entry)));
- tree entry = build (CONSTRUCTOR, vtable_entry_type, NULL_TREE, elems);
-
- /* We don't use vcall offsets when not using vtable thunks. */
- my_friendly_assert (vcall_index == NULL_TREE, 20000125);
-
- /* DELTA used to be constructed by `size_int' and/or size_binop,
- which caused overflow problems when it was negative. That should
- be fixed now. */
-
- if (! int_fits_type_p (delta, delta_type_node))
- {
- if (flag_huge_objects)
- sorry ("object size exceeds built-in limit for virtual function table implementation");
- else
- sorry ("object size exceeds normal limit for virtual function table implementation, recompile all source and use -fhuge-objects");
- }
-
- TREE_CONSTANT (entry) = 1;
- TREE_STATIC (entry) = 1;
+ entry = make_thunk (entry, delta, vcall_index);
+ entry = build1 (ADDR_EXPR, vtable_entry_type, entry);
TREE_READONLY (entry) = 1;
-
+ TREE_CONSTANT (entry) = 1;
+ }
#ifdef GATHER_STATISTICS
- n_vtable_entries += 1;
+ n_vtable_entries += 1;
#endif
-
- return entry;
- }
+ return entry;
}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 465ba51..e7005c7 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -552,15 +552,12 @@ enum cp_tree_index
CPTI_COMPLETE_DTOR_IDENTIFIER,
CPTI_BASE_DTOR_IDENTIFIER,
CPTI_DELETING_DTOR_IDENTIFIER,
- CPTI_DELTA2_IDENTIFIER,
CPTI_DELTA_IDENTIFIER,
CPTI_IN_CHARGE_IDENTIFIER,
CPTI_VTT_PARM_IDENTIFIER,
- CPTI_INDEX_IDENTIFIER,
CPTI_NELTS_IDENTIFIER,
CPTI_THIS_IDENTIFIER,
CPTI_PFN_IDENTIFIER,
- CPTI_PFN_OR_DELTA2_IDENTIFIER,
CPTI_VPTR_IDENTIFIER,
CPTI_STD_IDENTIFIER,
@@ -594,8 +591,7 @@ extern tree cp_global_trees[CPTI_MAX];
#define wchar_decl_node cp_global_trees[CPTI_WCHAR_DECL]
#define vtable_entry_type cp_global_trees[CPTI_VTABLE_ENTRY_TYPE]
/* The type used to represent an offset by which to adjust the `this'
- pointer in pointer-to-member types and, when not using vtable
- thunks, in vtables. */
+ pointer in pointer-to-member types. */
#define delta_type_node cp_global_trees[CPTI_DELTA_TYPE]
/* The type used to represent an index into the vtable. */
#define vtable_index_type cp_global_trees[CPTI_VTABLE_INDEX_TYPE]
@@ -671,20 +667,14 @@ extern tree cp_global_trees[CPTI_MAX];
/* The name of a destructor that destroys virtual base classes, and
then deletes the entire object. */
#define deleting_dtor_identifier cp_global_trees[CPTI_DELETING_DTOR_IDENTIFIER]
-
-#define delta2_identifier cp_global_trees[CPTI_DELTA2_IDENTIFIER]
#define delta_identifier cp_global_trees[CPTI_DELTA_IDENTIFIER]
#define in_charge_identifier cp_global_trees[CPTI_IN_CHARGE_IDENTIFIER]
-
/* The name of the parameter that contains a pointer to the VTT to use
for this subobject constructor or destructor. */
#define vtt_parm_identifier cp_global_trees[CPTI_VTT_PARM_IDENTIFIER]
-
-#define index_identifier cp_global_trees[CPTI_INDEX_IDENTIFIER]
#define nelts_identifier cp_global_trees[CPTI_NELTS_IDENTIFIER]
#define this_identifier cp_global_trees[CPTI_THIS_IDENTIFIER]
#define pfn_identifier cp_global_trees[CPTI_PFN_IDENTIFIER]
-#define pfn_or_delta2_identifier cp_global_trees[CPTI_PFN_OR_DELTA2_IDENTIFIER]
#define vptr_identifier cp_global_trees[CPTI_VPTR_IDENTIFIER]
/* The name of the std namespace. */
#define std_identifier cp_global_trees[CPTI_STD_IDENTIFIER]
@@ -1031,11 +1021,6 @@ extern int warn_reorder;
extern int flag_signed_bitfields;
-/* True for more efficient but incompatible (not fully tested)
- vtable implementation (using thunks).
- 0 is old behavior; 1 is new behavior. */
-extern int flag_vtable_thunks;
-
/* INTERFACE_ONLY nonzero means that we are in an "interface"
section of the compiler. INTERFACE_UNKNOWN nonzero means
we cannot trust the value of INTERFACE_ONLY. If INTERFACE_UNKNOWN
@@ -1180,11 +1165,9 @@ enum languages { lang_c, lang_cplusplus, lang_java };
/* Virtual function addresses can be gotten from a virtual function
table entry using this macro. */
#define FNADDR_FROM_VTABLE_ENTRY(ENTRY) \
- (!flag_vtable_thunks ? \
- TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (ENTRY)))) \
- : !DECL_THUNK_P (TREE_OPERAND ((ENTRY), 0)) \
- ? (ENTRY) \
- : DECL_INITIAL (TREE_OPERAND ((ENTRY), 0)))
+ (DECL_THUNK_P (TREE_OPERAND ((ENTRY), 0)) \
+ : DECL_INITIAL (TREE_OPERAND ((ENTRY), 0)) \
+ ? (ENTRY))
#define FUNCTION_ARG_CHAIN(NODE) \
(TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (NODE))))
@@ -2555,9 +2538,11 @@ extern int flag_new_for_scope;
ptrdiff_t __delta;
};
- (As the vtable is always the first thing in the object, we don't
- need an offset to it.) If the function is virtual, then PFN is one
- plus twice the index into the vtable; otherwise, it is just a
+ If __pfn is NULL, it is a NULL pointer-to-member-function.
+
+ (Because the vtable is always the first thing in the object, we
+ don't need its offset.) If the function is virtual, then PFN is
+ one plus twice the index into the vtable; otherwise, it is just a
pointer to the function.
Unfortunately, using the lowest bit of PFN doesn't work in
@@ -3087,8 +3072,7 @@ extern tree error_mark_list;
/* Node for "pointer to (virtual) function".
This may be distinct from ptr_type_node so gdb can distinguish them. */
-#define vfunc_ptr_type_node \
- (flag_vtable_thunks ? vtable_entry_type : ptr_type_node)
+#define vfunc_ptr_type_node vtable_entry_type
/* For building calls to `delete'. */
@@ -3156,7 +3140,7 @@ extern varray_type local_classes;
#define AUTO_TEMP_NAME "_$tmp_"
#define AUTO_TEMP_FORMAT "_$tmp_%d"
#define VTABLE_BASE "$vb"
-#define VTABLE_NAME_PREFIX (flag_vtable_thunks ? "__vt_" : "_vt$")
+#define VTABLE_NAME_PREFIX "__vt_"
#define VFIELD_BASE "$vf"
#define VFIELD_NAME "_vptr$"
#define VFIELD_NAME_FORMAT "_vptr$%s"
@@ -3178,7 +3162,7 @@ extern varray_type local_classes;
#define AUTO_TEMP_NAME "_.tmp_"
#define AUTO_TEMP_FORMAT "_.tmp_%d"
#define VTABLE_BASE ".vb"
-#define VTABLE_NAME_PREFIX (flag_vtable_thunks ? "__vt_" : "_vt.")
+#define VTABLE_NAME_PREFIX "__vt_"
#define VFIELD_BASE ".vf"
#define VFIELD_NAME "_vptr."
#define VFIELD_NAME_FORMAT "_vptr.%s"
@@ -3207,7 +3191,7 @@ extern varray_type local_classes;
#define AUTO_TEMP_FORMAT "__tmp_%d"
#define VTABLE_BASE "__vtb"
#define VTABLE_NAME "__vt_"
-#define VTABLE_NAME_PREFIX (flag_vtable_thunks ? "__vt_" : "_vt_")
+#define VTABLE_NAME_PREFIX "__vt_"
#define VTABLE_NAME_P(ID_NODE) \
(!strncmp (IDENTIFIER_POINTER (ID_NODE), VTABLE_NAME, \
sizeof (VTABLE_NAME) - 1))
@@ -3247,9 +3231,7 @@ extern varray_type local_classes;
#define VTBL_PTR_TYPE "__vtbl_ptr_type"
#define VTABLE_DELTA_NAME "__delta"
-#define VTABLE_INDEX_NAME "__index"
#define VTABLE_PFN_NAME "__pfn"
-#define VTABLE_DELTA2_NAME "__delta2"
#define EXCEPTION_CLEANUP_NAME "exception cleanup"
@@ -3592,7 +3574,7 @@ extern tree perform_implicit_conversion PARAMS ((tree, tree));
/* in class.c */
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, tree));
+extern tree build_vfn_ref PARAMS ((tree, tree));
extern tree get_vtable_decl PARAMS ((tree, int));
extern void add_method PARAMS ((tree, tree, int));
extern int currently_open_class PARAMS ((tree));
@@ -4106,7 +4088,6 @@ extern tree convert_pointer_to_vbase PARAMS ((tree, tree));
extern tree find_vbase_instance PARAMS ((tree, tree));
extern tree binfo_for_vbase PARAMS ((tree, tree));
extern tree binfo_via_virtual PARAMS ((tree, tree));
-extern void fixup_all_virtual_upcast_offsets PARAMS ((tree));
/* in semantics.c */
extern void init_cp_semantics PARAMS ((void));
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 2abddd2..c140af4 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -162,28 +162,13 @@ tree error_mark_list;
tree vtable_entry_type;
tree delta_type_node;
-#if 0
- Old rtti stuff.
- tree __baselist_desc_type_node;
- tree __i_desc_type_node, __m_desc_type_node;
- tree __t_desc_array_type, __i_desc_array_type, __m_desc_array_type;
-#endif
tree __t_desc_type_node;
-#if 0
- tree __tp_desc_type_node;
-#endif
tree ti_desc_type_node;
tree bltn_desc_type_node, ptr_desc_type_node;
tree ary_desc_type_node, func_desc_type_node, enum_desc_type_node;
tree class_desc_type_node, si_class_desc_type_node, vmi_class_desc_type_node;
tree ptm_desc_type_node;
tree base_desc_type_node;
-#if 0
- Not needed yet? May be needed one day?
- tree __bltn_desc_array_type, __user_desc_array_type, __class_desc_array_type;
- tree __ptr_desc_array_type, __attr_dec_array_type, __func_desc_array_type;
- tree __ptmf_desc_array_type, __ptmd_desc_array_type;
-#endif
tree class_type_node, record_type_node, union_type_node, enum_type_node;
tree unknown_type_node;
@@ -6304,14 +6289,11 @@ initialize_predefined_identifiers ()
{ "__comp_dtor", &complete_dtor_identifier, 1 },
{ "__base_dtor", &base_dtor_identifier, 1 },
{ "__deleting_dtor", &deleting_dtor_identifier, 1 },
- { VTABLE_DELTA2_NAME, &delta2_identifier, 0 },
- { VTABLE_DELTA_NAME, &delta_identifier, 0 },
{ IN_CHARGE_NAME, &in_charge_identifier, 0 },
- { VTABLE_INDEX_NAME, &index_identifier, 0 },
{ "nelts", &nelts_identifier, 0 },
{ THIS_NAME, &this_identifier, 0 },
+ { VTABLE_DELTA_NAME, &delta_identifier, 0 },
{ VTABLE_PFN_NAME, &pfn_identifier, 0 },
- { "__pfn_or_delta2", &pfn_or_delta2_identifier, 0 },
{ "_vptr", &vptr_identifier, 0 },
{ "__vtt_parm", &vtt_parm_identifier, 0 },
{ "std", &std_identifier, 0 },
@@ -6334,15 +6316,9 @@ initialize_predefined_identifiers ()
void
init_decl_processing ()
{
- tree fields[20];
tree void_ftype;
tree void_ftype_ptr;
- /* Check to see that the user did not specify an invalid combination
- of command-line options. */
- if (!flag_vtable_thunks)
- error ("the ABI requires vtable thunks");
-
/* Create all the identifiers we need. */
initialize_predefined_identifiers ();
@@ -6487,41 +6463,16 @@ init_decl_processing ()
TYPE_POINTER_TO (unknown_type_node) = unknown_type_node;
TYPE_REFERENCE_TO (unknown_type_node) = unknown_type_node;
- if (flag_vtable_thunks)
- {
- /* Make sure we get a unique function type, so we can give
- its pointer type a name. (This wins for gdb.) */
- tree vfunc_type = make_node (FUNCTION_TYPE);
- TREE_TYPE (vfunc_type) = integer_type_node;
- TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
- layout_type (vfunc_type);
-
- vtable_entry_type = build_pointer_type (vfunc_type);
- }
- else
- {
- vtable_entry_type = make_aggr_type (RECORD_TYPE);
- fields[0] = build_decl (FIELD_DECL, delta_identifier,
- delta_type_node);
- fields[1] = build_decl (FIELD_DECL, index_identifier,
- delta_type_node);
- fields[2] = build_decl (FIELD_DECL, pfn_identifier,
- ptr_type_node);
- finish_builtin_type (vtable_entry_type, VTBL_PTR_TYPE, fields, 2,
- double_type_node);
-
- /* Make this part of an invisible union. */
- fields[3] = copy_node (fields[2]);
- TREE_TYPE (fields[3]) = delta_type_node;
- DECL_NAME (fields[3]) = delta2_identifier;
- DECL_MODE (fields[3]) = TYPE_MODE (delta_type_node);
- DECL_SIZE (fields[3]) = TYPE_SIZE (delta_type_node);
- DECL_SIZE_UNIT (fields[3]) = TYPE_SIZE_UNIT (delta_type_node);
- TREE_UNSIGNED (fields[3]) = 0;
- TREE_CHAIN (fields[2]) = fields[3];
- vtable_entry_type = build_qualified_type (vtable_entry_type,
- TYPE_QUAL_CONST);
- }
+ {
+ /* Make sure we get a unique function type, so we can give
+ its pointer type a name. (This wins for gdb.) */
+ tree vfunc_type = make_node (FUNCTION_TYPE);
+ TREE_TYPE (vfunc_type) = integer_type_node;
+ TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
+ layout_type (vfunc_type);
+
+ vtable_entry_type = build_pointer_type (vfunc_type);
+ }
record_builtin_type (RID_MAX, VTBL_PTR_TYPE, vtable_entry_type);
vtbl_type_node
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index d2d8ec5..d0f8c43 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -189,11 +189,6 @@ int warn_long_long = 1;
int warn_ctor_dtor_privacy = 1;
-/* True if we want to implement vtables using "thunks".
- The default is off. */
-
-int flag_vtable_thunks = 1;
-
/* Nonzero means generate separate instantiation control files and juggle
them at link time. */
@@ -2247,12 +2242,9 @@ mark_vtable_entries (decl)
for (; entries; entries = TREE_CHAIN (entries))
{
- tree fnaddr;
+ tree fnaddr = TREE_VALUE (entries);
tree fn;
-
- fnaddr = (flag_vtable_thunks ? TREE_VALUE (entries)
- : FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries)));
-
+
if (TREE_CODE (fnaddr) != ADDR_EXPR)
/* This entry is an offset: a virtual base class offset, a
virtual call offset, an RTTI offset, etc. */
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 3bb043d..05352c2 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -950,13 +950,8 @@ dump_decl (t, flags)
if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t)))
{
output_add_string (scratch_buffer, "vtable for ");
- if (TYPE_P (DECL_CONTEXT (t)))
- dump_type (DECL_CONTEXT (t), flags);
- else
- /* This case can arise with -fno-vtable-thunks. See
- expand_upcast_fixups. It's not clear what to print
- here. */
- print_identifier (scratch_buffer, "<unknown type>");
+ my_friendly_assert (TYPE_P (DECL_CONTEXT (t)), 20010720);
+ dump_type (DECL_CONTEXT (t), flags);
break;
}
/* else fall through */
@@ -1918,16 +1913,9 @@ dump_expr (t, flags)
case CONSTRUCTOR:
if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
{
- tree idx = build_component_ref (t, index_identifier, NULL_TREE, 0);
+ tree idx = build_component_ref (t, pfn_identifier, NULL_TREE, 0);
- if (integer_all_onesp (idx))
- {
- tree pfn = PFN_FROM_PTRMEMFUNC (t);
- dump_unary_op ("&", pfn, flags | TFF_EXPR_IN_PARENS);
- break;
- }
- else if (TREE_CODE (idx) == INTEGER_CST
- && tree_int_cst_equal (idx, integer_zero_node))
+ if (integer_zerop (idx))
{
/* A NULL pointer-to-member constant. */
output_add_string (scratch_buffer, "((");
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 0cf2847..6dbef0b 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -182,14 +182,6 @@ initialize_vtbl_ptrs (addr)
NULL, dfs_unmarked_real_bases_queue_p, list);
dfs_walk (TYPE_BINFO (type), dfs_unmark,
dfs_marked_real_bases_queue_p, type);
-
- /* If we're not using thunks, we may need to adjust the deltas in
- the vtable to handle virtual base classes correctly. When we are
- using thunks, we either use construction vtables (which are
- preloaded with the right answers) or nothing (in which case
- vitual function calls sometimes don't work right.) */
- if (TYPE_USES_VIRTUAL_BASECLASSES (type) && !flag_vtable_thunks)
- fixup_all_virtual_upcast_offsets (addr);
}
/* [dcl.init]:
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 6e32ed3..5638eb6 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -113,7 +113,6 @@ build_headof (exp)
tree exp;
{
tree type = TREE_TYPE (exp);
- tree aref;
tree offset;
tree index;
@@ -133,12 +132,7 @@ build_headof (exp)
/* The offset-to-top field is at index -2 from the vptr. */
index = build_int_2 (-2, -1);
- aref = build_vtbl_ref (build_indirect_ref (exp, NULL), index);
-
- if (flag_vtable_thunks)
- offset = aref;
- else
- offset = build_component_ref (aref, delta_identifier, NULL_TREE, 0);
+ offset = build_vtbl_ref (build_indirect_ref (exp, NULL), index);
type = build_qualified_type (ptr_type_node,
CP_TYPE_QUALS (TREE_TYPE (exp)));
@@ -227,7 +221,7 @@ get_tinfo_decl_dynamic (exp)
/* The RTTI information is at index -1. */
index = integer_minus_one_node;
- t = build_vfn_ref ((tree *) 0, exp, index);
+ t = build_vfn_ref (exp, index);
TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
return t;
}
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 87157ba..4fac30f 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -86,18 +86,12 @@ struct vbase_info
static tree get_vbase_1 PARAMS ((tree, tree, unsigned int *));
static tree lookup_field_1 PARAMS ((tree, tree));
static int is_subobject_of_p PARAMS ((tree, tree, tree));
-static tree virtual_context PARAMS ((tree, tree, tree));
static tree dfs_check_overlap PARAMS ((tree, void *));
static tree dfs_no_overlap_yet PARAMS ((tree, void *));
static int get_base_distance_recursive
PARAMS ((tree, int, int, int, int *, tree *, tree,
int, int *, int, int));
static int dynamic_cast_base_recurse PARAMS ((tree, tree, int, tree *));
-static void expand_upcast_fixups
- PARAMS ((tree, tree, tree, tree, tree, tree, tree *));
-static void fixup_virtual_upcast_offsets
- PARAMS ((tree, tree, int, int, tree, tree, tree, tree,
- tree *));
static tree marked_pushdecls_p PARAMS ((tree, void *));
static tree unmarked_pushdecls_p PARAMS ((tree, void *));
static tree dfs_debug_unmarkedp PARAMS ((tree, void *));
@@ -474,16 +468,6 @@ get_base_distance (parent, binfo, protect, path_ptr)
if (rval && protect && rval_private)
return -3;
- /* If they gave us the real vbase binfo, which isn't in the main binfo
- tree, deal with it. This happens when we are called from
- expand_upcast_fixups. */
- if (rval == -1 && TREE_CODE (parent) == TREE_VEC
- && parent == binfo_for_vbase (BINFO_TYPE (parent), type))
- {
- new_binfo = parent;
- rval = 1;
- }
-
if (path_ptr)
*path_ptr = new_binfo;
return rval;
@@ -2332,290 +2316,6 @@ dfs_unmark (binfo, data)
return NULL_TREE;
}
-
-/* get the virtual context (the vbase that directly contains the
- DECL_CONTEXT of the FNDECL) that the given FNDECL is declared in,
- or NULL_TREE if there is none.
-
- FNDECL must come from a virtual table from a virtual base to ensure
- that there is only one possible DECL_CONTEXT.
-
- We know that if there is more than one place (binfo) the fndecl that the
- declared, they all refer to the same binfo. See get_class_offset_1 for
- the check that ensures this. */
-
-static tree
-virtual_context (fndecl, t, vbase)
- tree fndecl, t, vbase;
-{
- tree path;
- if (get_base_distance (DECL_CONTEXT (fndecl), t, 0, &path) < 0)
- {
- /* DECL_CONTEXT can be ambiguous in t. */
- if (get_base_distance (DECL_CONTEXT (fndecl), vbase, 0, &path) >= 0)
- {
- while (path)
- {
- /* Not sure if checking path == vbase is necessary here, but just in
- case it is. */
- if (TREE_VIA_VIRTUAL (path) || path == vbase)
- return binfo_for_vbase (BINFO_TYPE (path), t);
- path = BINFO_INHERITANCE_CHAIN (path);
- }
- }
- /* This shouldn't happen, I don't want errors! */
- warning ("recoverable compiler error, fixups for virtual function");
- return vbase;
- }
- while (path)
- {
- if (TREE_VIA_VIRTUAL (path))
- return binfo_for_vbase (BINFO_TYPE (path), t);
- path = BINFO_INHERITANCE_CHAIN (path);
- }
- return 0;
-}
-
-/* Fixups upcast offsets for one vtable.
- Entries may stay within the VBASE given, or
- they may upcast into a direct base, or
- they may upcast into a different vbase.
-
- We only need to do fixups in case 2 and 3. In case 2, we add in
- the virtual base offset to effect an upcast, in case 3, we add in
- the virtual base offset to effect an upcast, then subtract out the
- offset for the other virtual base, to effect a downcast into it.
-
- This routine mirrors fixup_vtable_deltas in functionality, though
- this one is runtime based, and the other is compile time based.
- Conceivably that routine could be removed entirely, and all fixups
- done at runtime.
-
- VBASE_OFFSETS is an association list of virtual bases that contains
- offset information for the virtual bases, so the offsets are only
- calculated once. */
-
-static void
-expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t,
- vbase_offsets)
- tree binfo, addr, orig_addr, vbase, vbase_addr, t, *vbase_offsets;
-{
- tree virtuals;
- tree vc;
- tree delta;
- HOST_WIDE_INT n;
-
- while (BINFO_PRIMARY_P (binfo))
- {
- binfo = BINFO_INHERITANCE_CHAIN (binfo);
- if (TREE_VIA_VIRTUAL (binfo))
- return;
- }
-
- delta = purpose_member (vbase, *vbase_offsets);
- if (! delta)
- {
- delta = build (PLUS_EXPR,
- build_pointer_type (BINFO_TYPE (vbase)),
- orig_addr,
- BINFO_OFFSET (vbase));
- delta = build (MINUS_EXPR, ptrdiff_type_node, delta, vbase_addr);
- delta = save_expr (delta);
- delta = tree_cons (vbase, delta, *vbase_offsets);
- *vbase_offsets = delta;
- }
-
- for (virtuals = BINFO_VIRTUALS (binfo), n = 0;
- virtuals;
- virtuals = TREE_CHAIN (virtuals), ++n)
- {
- tree current_fndecl = TREE_VALUE (virtuals);
-
- if (current_fndecl
- && current_fndecl != abort_fndecl
- && (vc=virtual_context (current_fndecl, t, vbase)) != vbase)
- {
- /* This may in fact need a runtime fixup. */
- tree idx = build_int_2 (n, 0);
- tree vtbl = BINFO_VTABLE (binfo);
- tree nvtbl = lookup_name (DECL_NAME (vtbl), 0);
- tree aref, ref, naref;
- tree old_delta, new_delta;
- tree init;
-
- if (nvtbl == NULL_TREE
- || nvtbl == IDENTIFIER_GLOBAL_VALUE (DECL_NAME (vtbl)))
- {
- /* Dup it if it isn't in local scope yet. */
- nvtbl = build_decl
- (VAR_DECL, DECL_NAME (vtbl),
- TYPE_MAIN_VARIANT (TREE_TYPE (vtbl)));
- DECL_ALIGN (nvtbl) = MAX (TYPE_ALIGN (double_type_node),
- DECL_ALIGN (nvtbl));
- TREE_READONLY (nvtbl) = 0;
- DECL_ARTIFICIAL (nvtbl) = 1;
- nvtbl = pushdecl (nvtbl);
- init = NULL_TREE;
- cp_finish_decl (nvtbl, init, NULL_TREE,
- LOOKUP_ONLYCONVERTING);
-
- /* We don't set DECL_VIRTUAL_P and DECL_CONTEXT on nvtbl
- because they wouldn't be useful; everything that wants to
- look at the vtable will look at the decl for the normal
- vtable. Setting DECL_CONTEXT also screws up
- decl_function_context. */
-
- init = build (MODIFY_EXPR, TREE_TYPE (nvtbl),
- nvtbl, vtbl);
- finish_expr_stmt (init);
- /* Update the vtable pointers as necessary. */
- ref = build_vfield_ref
- (build_indirect_ref (addr, NULL),
- DECL_CONTEXT (TYPE_VFIELD (BINFO_TYPE (binfo))));
- finish_expr_stmt
- (build_modify_expr (ref, NOP_EXPR, nvtbl));
- }
- assemble_external (vtbl);
- aref = build_array_ref (vtbl, idx);
- naref = build_array_ref (nvtbl, idx);
- old_delta = build_component_ref (aref, delta_identifier,
- NULL_TREE, 0);
- new_delta = build_component_ref (naref, delta_identifier,
- NULL_TREE, 0);
-
- /* This is a upcast, so we have to add the offset for the
- virtual base. */
- old_delta = cp_build_binary_op (PLUS_EXPR, old_delta,
- TREE_VALUE (delta));
- if (vc)
- {
- /* If this is set, we need to subtract out the delta
- adjustments for the other virtual base that we
- downcast into. */
- tree vc_delta = purpose_member (vc, *vbase_offsets);
- if (! vc_delta)
- {
- tree vc_addr = convert_pointer_to_real (vc, orig_addr);
- vc_delta = build (PLUS_EXPR,
- build_pointer_type (BINFO_TYPE (vc)),
- orig_addr,
- BINFO_OFFSET (vc));
- vc_delta = build (MINUS_EXPR, ptrdiff_type_node,
- vc_delta, vc_addr);
- vc_delta = save_expr (vc_delta);
- *vbase_offsets = tree_cons (vc, vc_delta, *vbase_offsets);
- }
- else
- vc_delta = TREE_VALUE (vc_delta);
-
- /* This is a downcast, so we have to subtract the offset
- for the virtual base. */
- old_delta = cp_build_binary_op (MINUS_EXPR, old_delta, vc_delta);
- }
-
- TREE_READONLY (new_delta) = 0;
- TREE_TYPE (new_delta) =
- cp_build_qualified_type (TREE_TYPE (new_delta),
- CP_TYPE_QUALS (TREE_TYPE (new_delta))
- & ~TYPE_QUAL_CONST);
- finish_expr_stmt (build_modify_expr (new_delta, NOP_EXPR,
- old_delta));
- }
- }
-}
-
-/* Fixup upcast offsets for all direct vtables. Patterned after
- expand_direct_vtbls_init. */
-
-static void
-fixup_virtual_upcast_offsets (real_binfo, binfo, init_self, can_elide, addr, orig_addr, type, vbase, vbase_offsets)
- tree real_binfo, binfo;
- int init_self, can_elide;
- tree addr, orig_addr, type, vbase, *vbase_offsets;
-{
- tree real_binfos = BINFO_BASETYPES (real_binfo);
- tree binfos = BINFO_BASETYPES (binfo);
- int i, n_baselinks = real_binfos ? TREE_VEC_LENGTH (real_binfos) : 0;
-
- for (i = 0; i < n_baselinks; i++)
- {
- tree real_base_binfo = TREE_VEC_ELT (real_binfos, i);
- tree base_binfo = TREE_VEC_ELT (binfos, i);
- int is_not_base_vtable
- = !BINFO_PRIMARY_P (real_base_binfo);
- if (! TREE_VIA_VIRTUAL (real_base_binfo))
- fixup_virtual_upcast_offsets (real_base_binfo, base_binfo,
- is_not_base_vtable, can_elide, addr,
- orig_addr, type, vbase, vbase_offsets);
- }
-#if 0
- /* Before turning this on, make sure it is correct. */
- if (can_elide && ! BINFO_MODIFIED (binfo))
- return;
-#endif
- /* Should we use something besides CLASSTYPE_VFIELDS? */
- if (init_self && CLASSTYPE_VFIELDS (BINFO_TYPE (real_binfo)))
- {
- tree new_addr = convert_pointer_to_real (binfo, addr);
- expand_upcast_fixups (real_binfo, new_addr, orig_addr, vbase, addr,
- type, vbase_offsets);
- }
-}
-
-/* Fixup all the virtual upcast offsets for TYPE. DECL_PTR is the
- address of the sub-object being initialized. */
-
-void
-fixup_all_virtual_upcast_offsets (decl_ptr)
- tree decl_ptr;
-{
- tree if_stmt;
- tree in_charge_node;
- tree vbases;
- tree type;
-
- /* Only tweak the vtables if we're in charge. */
- in_charge_node = current_in_charge_parm;
- if (!in_charge_node)
- /* There's no need for any fixups in this case. */
- return;
- in_charge_node = cp_build_binary_op (EQ_EXPR,
- in_charge_node, integer_zero_node);
- if_stmt = begin_if_stmt ();
- finish_if_stmt_cond (in_charge_node, if_stmt);
-
- /* Iterate through the virtual bases, fixing up the upcast offset
- for each one. */
- type = TREE_TYPE (TREE_TYPE (decl_ptr));
- for (vbases = CLASSTYPE_VBASECLASSES (type);
- vbases;
- vbases = TREE_CHAIN (vbases))
- {
- if (flag_vtable_thunks)
- /* We don't have dynamic thunks yet! So for now, just fail
- silently. */
- ;
- else
- {
- tree vbase;
- tree vbase_offsets;
- tree addr;
-
- vbase = find_vbase_instance (TREE_PURPOSE (vbases), type);
- vbase_offsets = NULL_TREE;
- addr = convert_pointer_to_vbase (TREE_PURPOSE (vbases), decl_ptr);
- fixup_virtual_upcast_offsets (vbase,
- TYPE_BINFO (TREE_PURPOSE (vbases)),
- 1, 0, addr, decl_ptr,
- type, vbase, &vbase_offsets);
- }
- }
-
- /* Close out the if-statement. */
- finish_then_clause (if_stmt);
- finish_if_stmt ();
-}
-
/* get virtual base class types.
This adds type to the vbase_types list in reverse dfs order.
Ordering is very important, so don't change it. */
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 9db741c..3580373 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2858,7 +2858,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))
{
- tree fntype, idx, e1, delta, delta2, e2, e3, aref, vtbl;
+ tree fntype, idx, e1, delta, delta2, e2, e3, vtbl;
tree instance, basetype;
tree instance_ptr = *instance_ptrptr;
@@ -2940,26 +2940,8 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
build_pointer_type (build_pointer_type (vtable_entry_type)),
vtbl, cp_convert (ptrdiff_type_node, delta2));
vtbl = build_indirect_ref (vtbl, NULL);
- aref = build_array_ref (vtbl, idx);
+ e2 = build_array_ref (vtbl, idx);
- if (! flag_vtable_thunks)
- {
- aref = save_expr (aref);
-
- delta = cp_build_binary_op
- (PLUS_EXPR,
- build_conditional_expr (e1,
- build_component_ref (aref,
- delta_identifier,
- NULL_TREE, 0),
- integer_zero_node),
- delta);
- }
-
- if (flag_vtable_thunks)
- e2 = aref;
- else
- e2 = build_component_ref (aref, pfn_identifier, NULL_TREE, 0);
TREE_TYPE (e2) = TREE_TYPE (e3);
e1 = build_conditional_expr (e1, e2, e3);