Remove old ABI support.

From-SVN: r39599
This commit is contained in:
Mark Mitchell 2001-02-12 09:58:18 +00:00 committed by Mark Mitchell
parent 11662aaaa5
commit 1f84ec231e
20 changed files with 243 additions and 3190 deletions

View File

@ -1,3 +1,7 @@
2001-02-12 Mark Mitchell <mark@codesourcery.com>
Remove old ABI support.
2001-02-11 Mark Mitchell <mark@codesourcery.com>
* decl2.c (flag_vtable_thunks): Always set it to 1.

View File

@ -2355,9 +2355,7 @@ build_user_type_conversion_1 (totype, expr, flags)
if (IS_AGGR_TYPE (totype))
ctors = lookup_fnfields (TYPE_BINFO (totype),
(flag_new_abi
? complete_ctor_identifier
: ctor_identifier),
complete_ctor_identifier,
0);
if (IS_AGGR_TYPE (fromtype))
@ -4415,25 +4413,12 @@ build_new_method_call (instance, name, args, basetype_path, flags)
pretty_name = (constructor_p
? constructor_name (basetype) : dtor_identifier);
if (!flag_new_abi)
{
/* Add the in-charge parameter as an implicit first argument. */
if (!constructor_p
|| TYPE_USES_VIRTUAL_BASECLASSES (basetype))
args = tree_cons (NULL_TREE,
in_charge_arg_for_name (name),
args);
/* We want to call the normal constructor function under the
old ABI. */
name = constructor_p ? ctor_identifier : dtor_identifier;
}
/* If we're a call to a constructor or destructor for a
subobject that uses virtual base classes, then we need to
pass down a pointer to a VTT for the subobject. */
else if ((name == base_ctor_identifier
|| name == base_dtor_identifier)
&& TYPE_USES_VIRTUAL_BASECLASSES (basetype))
if ((name == base_ctor_identifier
|| name == base_dtor_identifier)
&& TYPE_USES_VIRTUAL_BASECLASSES (basetype))
{
tree vtt;
tree sub_vtt;

View File

@ -143,7 +143,7 @@ static void check_field_decl PARAMS ((tree, tree, int *, int *, int *, int *));
static void check_field_decls PARAMS ((tree, tree *, int *, int *, int *,
int *));
static void build_base_field PARAMS ((record_layout_info, tree, int *,
unsigned int *, splay_tree));
splay_tree));
static void build_base_fields PARAMS ((record_layout_info, int *,
splay_tree));
static tree build_vbase_pointer_fields PARAMS ((record_layout_info, int *));
@ -182,7 +182,7 @@ static void layout_empty_base PARAMS ((tree, tree, splay_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, tree, int *));
static void set_vindex PARAMS ((tree, int *));
static void build_rtti_vtbl_entries PARAMS ((tree, tree, vtbl_init_data *));
static void build_vcall_and_vbase_vtbl_entries PARAMS ((tree,
vtbl_init_data *));
@ -663,11 +663,7 @@ static tree
get_vtable_name (type)
tree type;
{
if (flag_new_abi)
return mangle_vtbl_for_type (type);
else
return build_overload_with_type (get_identifier (VTABLE_NAME_PREFIX),
type);
return mangle_vtbl_for_type (type);
}
/* Return an IDENTIFIER_NODE for the name of the virtual table table
@ -677,11 +673,7 @@ tree
get_vtt_name (type)
tree type;
{
if (flag_new_abi)
return mangle_vtt_for_type (type);
else
return build_overload_with_type (get_identifier (VTT_NAME_PREFIX),
type);
return mangle_vtt_for_type (type);
}
/* Return the offset to the main vtable for a given base BINFO. */
@ -1086,35 +1078,17 @@ modify_vtable_entry (t, binfo, fndecl, delta, virtuals)
}
}
/* Return the index (in the virtual function table) of the first
virtual function. */
int
first_vfun_index (t)
tree t;
{
/* Under the old ABI, the offset-to-top and RTTI entries are at
indices zero and one; under the new ABI, the first virtual
function is at index zero. */
if (!CLASSTYPE_COM_INTERFACE (t) && !flag_new_abi)
return flag_vtable_thunks ? 2 : 1;
return 0;
}
/* Set DECL_VINDEX for DECL. VINDEX_P is the number of virtual
functions present in the vtable so far. */
static void
set_vindex (t, decl, vfuns_p)
tree t;
set_vindex (decl, vfuns_p)
tree decl;
int *vfuns_p;
{
int vindex;
vindex = (*vfuns_p)++;
vindex += first_vfun_index (t);
DECL_VINDEX (decl) = build_shared_int_cst (vindex);
}
@ -1158,7 +1132,7 @@ add_virtual_function (new_virtuals_p, overridden_virtuals_p,
CLASSTYPE_RTTI (t) = t;
/* Now assign virtual dispatch information. */
set_vindex (t, fndecl, vfuns_p);
set_vindex (fndecl, vfuns_p);
DECL_VIRTUAL_CONTEXT (fndecl) = t;
/* Save the state we've computed on the NEW_VIRTUALS list. */
@ -1942,9 +1916,6 @@ determine_primary_base (t, vfuns_p)
= tree_cons (base_binfo,
VF_BASETYPE_VALUE (vfields),
CLASSTYPE_VFIELDS (t));
if (!flag_new_abi && *vfuns_p == 0)
set_primary_base (t, base_binfo, vfuns_p);
}
}
}
@ -1994,7 +1965,7 @@ determine_primary_base (t, vfuns_p)
/* The new ABI allows for the use of a "nearly-empty" virtual base
class as the primary base class if no non-virtual polymorphic
base can be found. */
if (flag_new_abi && !CLASSTYPE_HAS_PRIMARY_BASE_P (t))
if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
{
/* If not NULL, this is the best primary base candidate we have
found so far. */
@ -2744,37 +2715,32 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
/* Under the new ABI, we will convert to an intermediate virtual
base first, and then use the vcall offset located there to finish
the conversion. */
if (flag_new_abi)
while (b)
{
while (b)
{
/* If we find BINFO, then the final overrider is in a class
derived from BINFO, so the thunks can be generated with
the final overrider. */
if (!virtual_base
&& same_type_p (BINFO_TYPE (b), BINFO_TYPE (binfo)))
generate_thunk_with_vtable_p = 0;
/* If we find BINFO, then the final overrider is in a class
derived from BINFO, so the thunks can be generated with
the final overrider. */
if (!virtual_base
&& same_type_p (BINFO_TYPE (b), BINFO_TYPE (binfo)))
generate_thunk_with_vtable_p = 0;
/* If we find the final overrider, then we can stop
walking. */
if (same_type_p (BINFO_TYPE (b),
BINFO_TYPE (TREE_VALUE (overrider))))
break;
if (same_type_p (BINFO_TYPE (b),
BINFO_TYPE (TREE_VALUE (overrider))))
break;
/* If we find a virtual base, and we haven't yet found the
overrider, then there is a virtual base between the
declaring base and the final overrider. */
if (!virtual_base && TREE_VIA_VIRTUAL (b))
{
generate_thunk_with_vtable_p = 1;
virtual_base = b;
}
b = BINFO_INHERITANCE_CHAIN (b);
if (!virtual_base && TREE_VIA_VIRTUAL (b))
{
generate_thunk_with_vtable_p = 1;
virtual_base = b;
}
b = BINFO_INHERITANCE_CHAIN (b);
}
else
virtual_base = NULL_TREE;
if (virtual_base)
/* The `this' pointer needs to be adjusted to the nearest virtual
@ -2822,8 +2788,7 @@ dfs_modify_vtables (binfo, data)
/* If we're supporting RTTI then we always need a new vtable to
point to the RTTI information. Under the new ABI we may need
a new vtable to contain vcall and vbase offsets. */
if (flag_rtti || flag_new_abi)
make_new_vtable (t, binfo);
make_new_vtable (t, binfo);
/* Now, go through each of the virtual functions in the virtual
function table for BINFO. Find the final overrider, and
@ -2884,7 +2849,7 @@ modify_all_vtables (t, vfuns_p, overridden_virtuals)
|| !value_member (fn, BINFO_VIRTUALS (binfo)))
{
/* Set the vtable index. */
set_vindex (t, fn, vfuns_p);
set_vindex (fn, vfuns_p);
/* We don't need to convert to a base class when calling
this function. */
DECL_VIRTUAL_CONTEXT (fn) = t;
@ -3954,10 +3919,10 @@ layout_nonempty_base_or_field (rli, decl, binfo, offsets)
empty class, have non-zero size, any overlap can happen only
with a direct or indirect base-class -- it can't happen with
a data member. */
if (flag_new_abi && layout_conflict_p (TREE_TYPE (decl),
offset,
offsets,
field_p))
if (layout_conflict_p (TREE_TYPE (decl),
offset,
offsets,
field_p))
{
/* Strip off the size allocated to this field. That puts us
at the first place we could have put the field with
@ -4033,11 +3998,10 @@ layout_empty_base (binfo, eoc, offsets)
class. OFFSETS gives the location of empty base subobjects. */
static void
build_base_field (rli, binfo, empty_p, base_align, offsets)
build_base_field (rli, binfo, empty_p, offsets)
record_layout_info rli;
tree binfo;
int *empty_p;
unsigned int *base_align;
splay_tree offsets;
{
tree basetype = BINFO_TYPE (binfo);
@ -4056,20 +4020,6 @@ build_base_field (rli, binfo, empty_p, base_align, offsets)
DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype);
DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);
if (! flag_new_abi)
{
/* Brain damage for backwards compatibility. For no good
reason, the old basetype layout made every base have at least
as large as the alignment for the bases up to that point,
gratuitously wasting space. So we do the same thing here. */
*base_align = MAX (*base_align, DECL_ALIGN (decl));
DECL_SIZE (decl)
= size_binop (MAX_EXPR, DECL_SIZE (decl), bitsize_int (*base_align));
DECL_SIZE_UNIT (decl)
= size_binop (MAX_EXPR, DECL_SIZE_UNIT (decl),
size_int (*base_align / BITS_PER_UNIT));
}
if (!integer_zerop (DECL_SIZE (decl)))
{
/* The containing class is non-empty because it has a non-empty
@ -4120,13 +4070,12 @@ build_base_fields (rli, empty_p, offsets)
tree rec = rli->t;
int n_baseclasses = CLASSTYPE_N_BASECLASSES (rec);
int i;
unsigned int base_align = 0;
/* Under the new ABI, the primary base class is always allocated
first. */
if (flag_new_abi && CLASSTYPE_HAS_PRIMARY_BASE_P (rec))
if (CLASSTYPE_HAS_PRIMARY_BASE_P (rec))
build_base_field (rli, CLASSTYPE_PRIMARY_BINFO (rec),
empty_p, &base_align, offsets);
empty_p, offsets);
/* Now allocate the rest of the bases. */
for (i = 0; i < n_baseclasses; ++i)
@ -4137,7 +4086,7 @@ build_base_fields (rli, empty_p, offsets)
/* Under the new ABI, the primary base was already allocated
above, so we don't need to allocate it again here. */
if (flag_new_abi && base_binfo == CLASSTYPE_PRIMARY_BINFO (rec))
if (base_binfo == CLASSTYPE_PRIMARY_BINFO (rec))
continue;
/* A primary virtual base class is allocated just like any other
@ -4147,7 +4096,7 @@ build_base_fields (rli, empty_p, offsets)
&& !BINFO_PRIMARY_P (base_binfo))
continue;
build_base_field (rli, base_binfo, empty_p, &base_align, offsets);
build_base_field (rli, base_binfo, empty_p, offsets);
}
}
@ -4196,18 +4145,13 @@ check_methods (t)
[class.free]) requires that the second argument be set
correctly. */
second_parm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (x)));
/* This is overly conservative, but we must maintain this
behavior for backwards compatibility. */
if (!flag_new_abi && second_parm != void_list_node)
TYPE_VEC_DELETE_TAKES_SIZE (t) = 1;
/* Under the new ABI, we choose only those function that are
explicitly declared as `operator delete[] (void *,
size_t)'. */
else if (flag_new_abi
&& !seen_one_arg_array_delete_p
&& second_parm
&& TREE_CHAIN (second_parm) == void_list_node
&& same_type_p (TREE_VALUE (second_parm), sizetype))
if (!seen_one_arg_array_delete_p
&& second_parm
&& TREE_CHAIN (second_parm) == void_list_node
&& same_type_p (TREE_VALUE (second_parm), sizetype))
TYPE_VEC_DELETE_TAKES_SIZE (t) = 1;
/* If there's no second parameter, then this is the usual
deallocation function. */
@ -4351,9 +4295,8 @@ clone_function_decl (fn, update_method_vec_p)
tree clone;
/* Avoid inappropriate cloning. */
if (! flag_new_abi
|| (TREE_CHAIN (fn)
&& DECL_CLONED_FUNCTION (TREE_CHAIN (fn))))
if (TREE_CHAIN (fn)
&& DECL_CLONED_FUNCTION (TREE_CHAIN (fn)))
return;
if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn))
@ -4398,10 +4341,6 @@ clone_constructors_and_destructors (t)
{
tree fns;
/* We only clone constructors and destructors under the new ABI. */
if (!flag_new_abi)
return;
/* If for some reason we don't have a CLASSTYPE_METHOD_VEC, we bail
out now. */
if (!CLASSTYPE_METHOD_VEC (t))
@ -4540,8 +4479,7 @@ create_vtable_ptr (t, empty_p, vfuns_p,
/* Loop over the virtual functions, adding them to our various
vtables. */
for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
if (DECL_VINDEX (fn)
&& !(flag_new_abi && DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)))
if (DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
add_virtual_function (new_virtuals_p, overridden_virtuals_p,
vfuns_p, fn, t);
@ -4580,7 +4518,7 @@ create_vtable_ptr (t, empty_p, vfuns_p,
t,
empty_p);
if (flag_new_abi && CLASSTYPE_N_BASECLASSES (t))
if (CLASSTYPE_N_BASECLASSES (t))
/* If there were any baseclasses, they can't possibly be at
offset zero any more, because that's where the vtable
pointer is. So, converting to a base class is going to
@ -4755,22 +4693,15 @@ layout_virtual_bases (t, offsets)
ABI, these are allocated according to a depth-first left-to-right
postorder traversal; in the new ABI, inheritance graph order is
used instead. */
for (vbases = (flag_new_abi
? TYPE_BINFO (t)
: CLASSTYPE_VBASECLASSES (t));
for (vbases = TYPE_BINFO (t);
vbases;
vbases = TREE_CHAIN (vbases))
{
tree vbase;
if (flag_new_abi)
{
if (!TREE_VIA_VIRTUAL (vbases))
continue;
vbase = binfo_for_vbase (BINFO_TYPE (vbases), t);
}
else
vbase = TREE_VALUE (vbases);
if (!TREE_VIA_VIRTUAL (vbases))
continue;
vbase = binfo_for_vbase (BINFO_TYPE (vbases), t);
if (!BINFO_PRIMARY_P (vbase))
{
@ -4781,13 +4712,7 @@ layout_virtual_bases (t, offsets)
basetype = BINFO_TYPE (vbase);
if (flag_new_abi)
desired_align = CLASSTYPE_ALIGN (basetype);
else
/* Under the old ABI, virtual bases were aligned as for the
entire base object (including its virtual bases). That's
wasteful, in general. */
desired_align = TYPE_ALIGN (basetype);
desired_align = CLASSTYPE_ALIGN (basetype);
TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), desired_align);
/* Add padding so that we can put the virtual base class at an
@ -4796,7 +4721,7 @@ layout_virtual_bases (t, offsets)
/* Under the new ABI, we try to squish empty virtual bases in
just like ordinary empty bases. */
if (flag_new_abi && is_empty_class (basetype))
if (is_empty_class (basetype))
layout_empty_base (vbase,
size_int (CEIL (dsize, BITS_PER_UNIT)),
offsets);
@ -4945,7 +4870,7 @@ layout_class_type (t, empty_p, vfuns_p,
/* Under the new ABI, the vptr is always the first thing in the
class. */
if (flag_new_abi && vptr)
if (vptr)
{
TYPE_FIELDS (t) = chainon (vptr, TYPE_FIELDS (t));
place_field (rli, vptr);
@ -4986,12 +4911,7 @@ layout_class_type (t, empty_p, vfuns_p,
rules, but the back-end can't handle bitfields longer than a
`long long', so we use the same mechanism. */
if (DECL_C_BIT_FIELD (field)
&& ((flag_new_abi
&& INT_CST_LT (TYPE_SIZE (type), DECL_SIZE (field)))
|| (!flag_new_abi
&& 0 < compare_tree_int (DECL_SIZE (field),
TYPE_PRECISION
(long_long_unsigned_type_node)))))
&& INT_CST_LT (TYPE_SIZE (type), DECL_SIZE (field)))
{
integer_type_kind itk;
tree integer_type;
@ -5049,10 +4969,6 @@ layout_class_type (t, empty_p, vfuns_p,
if (TREE_CODE (rli_size_unit_so_far (rli)) == INTEGER_CST
&& compare_tree_int (rli_size_unit_so_far (rli), eoc) < 0)
{
/* We don't handle zero-sized base classes specially under the
old ABI, so if we get here, we had better be operating under
the new ABI rules. */
my_friendly_assert (flag_new_abi, 20000321);
rli->offset = size_binop (MAX_EXPR, rli->offset, size_int (eoc + 1));
rli->bitpos = bitsize_zero_node;
}
@ -5073,14 +4989,6 @@ layout_class_type (t, empty_p, vfuns_p,
TREE_STATIC (TYPE_NONCOPIED_PARTS (t)) = 1;
}
/* Under the old ABI, the vptr comes at the very end of the
class. */
if (!flag_new_abi && vptr)
{
place_field (rli, vptr);
TYPE_FIELDS (t) = chainon (TYPE_FIELDS (t), vptr);
}
/* Let the back-end lay out the type. Note that at this point we
have only included non-virtual base-classes; we will lay out the
virtual base classes later. So, the TYPE_SIZE/TYPE_ALIGN after
@ -5094,21 +5002,16 @@ layout_class_type (t, empty_p, vfuns_p,
/* Remember the size and alignment of the class before adding
the virtual bases. */
if (*empty_p && flag_new_abi)
if (*empty_p)
{
CLASSTYPE_SIZE (t) = bitsize_zero_node;
CLASSTYPE_SIZE_UNIT (t) = size_zero_node;
}
else if (flag_new_abi)
else
{
CLASSTYPE_SIZE (t) = TYPE_BINFO_SIZE (t);
CLASSTYPE_SIZE_UNIT (t) = TYPE_BINFO_SIZE_UNIT (t);
}
else
{
CLASSTYPE_SIZE (t) = TYPE_SIZE (t);
CLASSTYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (t);
}
CLASSTYPE_ALIGN (t) = TYPE_ALIGN (t);
CLASSTYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (t);
@ -6493,23 +6396,13 @@ int
is_empty_class (type)
tree type;
{
tree t;
if (type == error_mark_node)
return 0;
if (! IS_AGGR_TYPE (type))
return 0;
if (flag_new_abi)
return integer_zerop (CLASSTYPE_SIZE (type));
if (TYPE_BINFO_BASETYPES (type))
return 0;
t = TYPE_FIELDS (type);
while (t && TREE_CODE (t) != FIELD_DECL)
t = TREE_CHAIN (t);
return (t == NULL_TREE);
return integer_zerop (CLASSTYPE_SIZE (type));
}
/* Find the enclosing class of the given NODE. NODE can be a *_DECL or
@ -6894,10 +6787,6 @@ build_vtt (t)
tree vtt;
tree index;
/* Under the old ABI, we don't use VTTs. */
if (!flag_new_abi)
return;
/* Build up the initializers for the VTT. */
inits = NULL_TREE;
index = size_zero_node;
@ -7194,10 +7083,7 @@ build_ctor_vtbl_group (binfo, t)
tree vbase;
/* See if we've already create this construction vtable group. */
if (flag_new_abi)
id = mangle_ctor_vtbl_for_type (t, binfo);
else
id = get_ctor_vtbl_name (t, binfo);
id = mangle_ctor_vtbl_for_type (t, binfo);
if (IDENTIFIER_GLOBAL_VALUE (id))
return;

View File

@ -213,10 +213,6 @@ Boston, MA 02111-1307, USA. */
/* ABI control. */
/* Nonzero to enable experimental ABI changes. */
extern int flag_new_abi;
/* Nonzero to use __cxa_atexit, rather than atexit, to register
destructors for local statics and global objects. */
@ -238,12 +234,12 @@ extern int flag_huge_objects;
/* Nonzero if virtual base class offsets are stored in the virtual
function table. Zero if, instead, a pointer to the virtual base is
stored in the object itself. */
#define vbase_offsets_in_vtable_p() (flag_new_abi)
#define vbase_offsets_in_vtable_p() (1)
/* Nonzero if displacements to the `this' pointer to use when calling
virtual functions in a virtual base class are present in the
vtable. */
#define vcall_offsets_in_vtable_p() (flag_new_abi)
#define vcall_offsets_in_vtable_p() (1)
/* Nonzero if a derived class that needs a vptr should always get one,
even if a non-primary base class already has one. For example,
@ -255,7 +251,7 @@ extern int flag_huge_objects;
one could either reuse the vptr in `S' for `T', or create a new
vptr for `T'. If this flag is nonzero we choose the latter
alternative; otherwise, we choose the former. */
#define vptrs_present_everywhere_p() (flag_new_abi)
#define vptrs_present_everywhere_p() (1)
/* Nonzero if the vtable for a derived class should contain the
virtual functions from the primary base and all virtual functions
@ -263,16 +259,16 @@ extern int flag_huge_objects;
only those virtual functions from the primary base together with
the functions declared in the derived class (but not in any base
class). */
#define all_overridden_vfuns_in_vtables_p() (flag_new_abi)
#define all_overridden_vfuns_in_vtables_p() (1)
/* Nonzero if we use access type_info objects directly, and use the
cross-vendor layout for them. Zero if we use an accessor function
to get the type_info object address. */
#define new_abi_rtti_p() (flag_new_abi)
#define new_abi_rtti_p() (1)
/* Nonzero if primary and secondary vtables are combined into a single
vtable. */
#define merge_primary_and_secondary_vtables_p() (flag_new_abi)
#define merge_primary_and_secondary_vtables_p() (1)
/* Language-dependent contents of an identifier. */
@ -2681,9 +2677,7 @@ extern int flag_new_for_scope;
pointer to member function. TYPE_PTRMEMFUNC_P _must_ be true,
before using this macro. */
#define TYPE_PTRMEMFUNC_FN_TYPE(NODE) \
(flag_new_abi \
? (TREE_TYPE (TYPE_FIELDS (NODE))) \
: (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (NODE))))))))
(TREE_TYPE (TYPE_FIELDS (NODE)))
/* Returns `A' for a type like `int (A::*)(double)' */
#define TYPE_PTRMEMFUNC_OBJECT_TYPE(NODE) \
@ -3739,7 +3733,6 @@ extern void push_lang_context PARAMS ((tree));
extern void pop_lang_context PARAMS ((void));
extern tree instantiate_type PARAMS ((tree, tree, enum instantiate_type_flags));
extern void print_class_statistics PARAMS ((void));
extern int first_vfun_index PARAMS ((tree));
extern void build_self_reference PARAMS ((void));
extern void warn_hidden PARAMS ((tree));
extern tree get_enclosing_class PARAMS ((tree));
@ -4097,22 +4090,13 @@ extern int cp_type_qual_from_rid PARAMS ((tree));
/* in method.c */
extern void init_method PARAMS ((void));
extern char *build_overload_name PARAMS ((tree, int, int));
extern tree build_static_name PARAMS ((tree, tree));
extern tree build_decl_overload_real PARAMS ((tree, tree, tree, tree,
tree, int));
extern void set_mangled_name_for_decl PARAMS ((tree));
extern tree build_typename_overload PARAMS ((tree));
extern tree build_overload_with_type PARAMS ((tree, tree));
extern tree build_destructor_name PARAMS ((tree));
extern tree build_opfncall PARAMS ((enum tree_code, int, tree, tree, tree));
extern tree hack_identifier PARAMS ((tree, tree));
extern tree make_thunk PARAMS ((tree, tree, tree, int));
extern void use_thunk PARAMS ((tree, int));
extern void synthesize_method PARAMS ((tree));
extern tree get_id_2 PARAMS ((const char *, tree));
extern tree implicitly_declare_fn PARAMS ((special_function_kind, tree, int));
extern tree get_ctor_vtbl_name PARAMS ((tree, tree));
/* In optimize.c */
extern void optimize_function PARAMS ((tree));
@ -4191,7 +4175,6 @@ extern tree get_tinfo_decl PARAMS((tree));
extern tree get_typeid PARAMS((tree));
extern tree get_typeid_1 PARAMS((tree));
extern tree build_dynamic_cast PARAMS((tree, tree));
extern void synthesize_tinfo_fn PARAMS((tree));
extern void emit_support_tinfos PARAMS((void));
extern int tinfo_decl_p PARAMS((tree, void *));
extern int emit_tinfo_decl PARAMS((tree *, void *));
@ -4500,7 +4483,7 @@ extern int cp_type_quals PARAMS ((tree));
extern int cp_has_mutable_p PARAMS ((tree));
extern int at_least_as_qualified_p PARAMS ((tree, tree));
extern int more_qualified_p PARAMS ((tree, tree));
extern tree build_ptrmemfunc1 PARAMS ((tree, tree, tree, tree, tree));
extern tree build_ptrmemfunc1 PARAMS ((tree, tree, tree));
extern void expand_ptrmemfunc_cst PARAMS ((tree, tree *, tree *, tree *, tree *));
extern tree delta2_from_ptrmemfunc PARAMS ((tree));
extern tree pfn_from_ptrmemfunc PARAMS ((tree));

View File

@ -258,7 +258,7 @@ cp_convert_to_pointer (type, expr, force)
if (TYPE_PTRMEMFUNC_P (type))
return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0);
if (flag_new_abi && TYPE_PTRMEM_P (type))
if (TYPE_PTRMEM_P (type))
/* Under the new ABI, a NULL pointer-to-member is represented
by -1, not by zero. */
expr = build_int_2 (-1, -1);

View File

@ -51,15 +51,10 @@ extern tree global_namespace;
extern int (*valid_lang_attribute) PARAMS ((tree, tree, tree, tree));
#ifndef BOOL_TYPE_SIZE
#ifdef SLOW_BYTE_ACCESS
/* In the new ABI, `bool' has size and alignment `1', on all
platforms. */
#define BOOL_TYPE_SIZE \
((SLOW_BYTE_ACCESS && !flag_new_abi) ? (POINTER_SIZE) : (CHAR_TYPE_SIZE))
#else
#define BOOL_TYPE_SIZE CHAR_TYPE_SIZE
#endif
#endif
static tree grokparms PARAMS ((tree));
static const char *redeclaration_error_message PARAMS ((tree, tree));
@ -149,7 +144,7 @@ static void end_cleanup_fn PARAMS ((void));
static tree cp_make_fname_decl PARAMS ((tree, const char *, int));
static void initialize_predefined_identifiers PARAMS ((void));
static tree check_special_function_return_type
PARAMS ((special_function_kind, tree, tree, tree));
PARAMS ((special_function_kind, tree, tree));
static tree push_cp_library_fn PARAMS ((enum tree_code, tree));
static tree build_cp_library_fn PARAMS ((tree, enum tree_code, tree));
static void store_parm_decls PARAMS ((tree));
@ -2844,13 +2839,7 @@ pushtag (name, type, globalize)
VARRAY_PUSH_TREE (local_classes, type);
if (!uses_template_parms (type))
{
if (flag_new_abi)
DECL_ASSEMBLER_NAME (d) = mangle_type (type);
else
DECL_ASSEMBLER_NAME (d)
= get_identifier (build_overload_name (type, 1, 1));
}
DECL_ASSEMBLER_NAME (d) = mangle_type (type);
}
if (b->parm_flag == 2)
{
@ -6307,8 +6296,8 @@ init_decl_processing ()
/* Check to see that the user did not specify an invalid combination
of command-line options. */
if (flag_new_abi && !flag_vtable_thunks)
error ("the new ABI requires vtable thunks");
if (!flag_vtable_thunks)
error ("the ABI requires vtable thunks");
/* Create all the identifiers we need. */
initialize_predefined_identifiers ();
@ -6411,17 +6400,8 @@ init_decl_processing ()
record_builtin_type (RID_MAX, NULL_PTR, string_type_node);
#endif
if (flag_new_abi)
delta_type_node = ptrdiff_type_node;
else if (flag_huge_objects)
delta_type_node = long_integer_type_node;
else
delta_type_node = short_integer_type_node;
if (flag_new_abi)
vtable_index_type = ptrdiff_type_node;
else
vtable_index_type = delta_type_node;
delta_type_node = ptrdiff_type_node;
vtable_index_type = ptrdiff_type_node;
vtt_parm_type = build_pointer_type (const_ptr_type_node);
lang_type_promotes_to = convert_type_from_ellipsis;
@ -6490,12 +6470,9 @@ init_decl_processing ()
layout_type (vtbl_ptr_type_node);
record_builtin_type (RID_MAX, NULL_PTR, vtbl_ptr_type_node);
if (flag_new_abi)
{
push_namespace (get_identifier ("__cxxabiv1"));
abi_node = current_namespace;
pop_namespace ();
}
push_namespace (get_identifier ("__cxxabiv1"));
abi_node = current_namespace;
pop_namespace ();
global_type_node = make_node (LANG_TYPE);
record_unknown_type (global_type_node, "global type");
@ -6521,10 +6498,7 @@ init_decl_processing ()
}
abort_fndecl
= build_library_fn_ptr ((flag_new_abi
? "__cxa_pure_virtual"
: "__pure_virtual"),
void_ftype);
= build_library_fn_ptr ("__cxa_pure_virtual", void_ftype);
/* Perform other language dependent initializations. */
init_class_processing ();
@ -7534,13 +7508,7 @@ maybe_commonize_var (decl)
which we can't if it has been initialized. */
if (TREE_PUBLIC (decl))
{
if (flag_new_abi)
DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
else
DECL_ASSEMBLER_NAME (decl)
= build_static_name (current_function_decl, DECL_NAME (decl));
}
DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
else
{
cp_warning_at ("sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)", decl);
@ -8977,13 +8945,7 @@ grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace)
/* DECL_ASSEMBLER_NAME is needed only for full-instantiated
templates. */
if (!uses_template_parms (decl))
{
if (flag_new_abi)
DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
else
DECL_ASSEMBLER_NAME (decl) = build_static_name (basetype,
declarator);
}
DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
}
else
{
@ -9008,13 +8970,7 @@ grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace)
context = DECL_CONTEXT (decl);
if (declarator && context && current_lang_name != lang_name_c)
{
if (flag_new_abi)
DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
else
DECL_ASSEMBLER_NAME (decl)
= build_static_name (context, declarator);
}
DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
}
if (in_namespace)
@ -9079,7 +9035,6 @@ build_ptrmemfunc_type (type)
{
tree fields[4];
tree t;
tree u;
tree unqualified_variant = NULL_TREE;
if (type == error_mark_node)
@ -9104,30 +9059,10 @@ build_ptrmemfunc_type (type)
/* ... and not really an aggregate. */
SET_IS_AGGR_TYPE (t, 0);
if (!flag_new_abi)
{
u = make_aggr_type (UNION_TYPE);
SET_IS_AGGR_TYPE (u, 0);
fields[0] = build_decl (FIELD_DECL, pfn_identifier, type);
fields[1] = build_decl (FIELD_DECL, delta2_identifier,
delta_type_node);
finish_builtin_type (u, "__ptrmemfunc_type", fields, 1, ptr_type_node);
TYPE_NAME (u) = NULL_TREE;
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_or_delta2_identifier, u);
finish_builtin_type (t, "__ptrmemfunc_type", fields, 2, ptr_type_node);
}
else
{
fields[0] = build_decl (FIELD_DECL, pfn_identifier, type);
fields[1] = build_decl (FIELD_DECL, delta_identifier,
delta_type_node);
finish_builtin_type (t, "__ptrmemfunc_type", fields, 1, ptr_type_node);
}
fields[0] = build_decl (FIELD_DECL, pfn_identifier, type);
fields[1] = build_decl (FIELD_DECL, delta_identifier,
delta_type_node);
finish_builtin_type (t, "__ptrmemfunc_type", fields, 1, ptr_type_node);
/* Zap out the name so that the back-end will give us the debugging
information for this anonymous RECORD_TYPE. */
@ -9399,17 +9334,15 @@ create_array_type_for_decl (name, type, size)
/* Check that it's OK to declare a function with the indicated TYPE.
SFK indicates the kind of special function (if any) that this
function is. CTYPE is the class of which this function is a
member. OPTYPE is the type given in a conversion operator
function is. OPTYPE is the type given in a conversion operator
declaration. Returns the actual return type of the function; that
may be different than TYPE if an error occurs, or for certain
special functions. */
static tree
check_special_function_return_type (sfk, type, ctype, optype)
check_special_function_return_type (sfk, type, optype)
special_function_kind sfk;
tree type;
tree ctype;
tree optype;
{
switch (sfk)
@ -9418,9 +9351,8 @@ check_special_function_return_type (sfk, type, ctype, optype)
if (type)
cp_error ("return type specification for constructor invalid");
/* In the old ABI, we return `this'; in the new ABI we don't
bother. */
type = flag_new_abi ? void_type_node : build_pointer_type (ctype);
/* In the new ABI constructors do not return a value. */
type = void_type_node;
break;
case sfk_destructor:
@ -10030,7 +9962,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (sfk != sfk_none)
type = check_special_function_return_type (sfk, type,
ctor_return_type,
ctor_return_type);
else if (type == NULL_TREE)
{
@ -11048,24 +10979,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))
= TYPE_IDENTIFIER (type);
if (flag_new_abi)
DECL_ASSEMBLER_NAME (decl) = mangle_type (type);
else
{
/* XXX Temporarily set the scope.
When returning, start_decl expects it as NULL_TREE,
and will then then set it using pushdecl. */
my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 980404);
if (current_class_type)
DECL_CONTEXT (decl) = current_class_type;
else
DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
DECL_ASSEMBLER_NAME (decl) = DECL_NAME (decl);
DECL_ASSEMBLER_NAME (decl)
= get_identifier (build_overload_name (type, 1, 1));
DECL_CONTEXT (decl) = NULL_TREE;
}
DECL_ASSEMBLER_NAME (decl) = mangle_type (type);
/* FIXME remangle member functions; member functions of a
type with external linkage have external linkage. */
@ -13637,16 +13551,6 @@ start_function (declspecs, declarator, attrs, flags)
dtor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
DECL_CONTEXT (dtor_label) = current_function_decl;
}
/* Under the old ABI we return `this' from constructors, so we make
ordinary `return' statements in constructors jump to CTOR_LABEL;
from there we return `this'. Under the new ABI, we don't bother
with any of this. By not setting CTOR_LABEL the remainder of the
machinery is automatically disabled. */
else if (!flag_new_abi && DECL_CONSTRUCTOR_P (decl1))
{
ctor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
DECL_CONTEXT (ctor_label) = current_function_decl;
}
store_parm_decls (current_function_parms);

View File

@ -415,10 +415,6 @@ int flag_new_for_scope = 1;
int flag_weak = 1;
/* Nonzero to enable experimental ABI changes. */
int flag_new_abi = 1;
/* Nonzero to use __cxa_atexit, rather than atexit, to register
destructors for local statics and global objects. */
@ -620,17 +616,6 @@ cxx_decode_option (argc, argv)
flag_external_templates = 1;
cp_deprecated ("-fexternal-templates");
}
else if (!strcmp (p, "new-abi"))
{
flag_new_abi = 1;
flag_do_squangling = 1;
flag_vtable_thunks = 1;
}
else if (!strcmp (p, "no-new-abi"))
{
flag_new_abi = 0;
flag_do_squangling = 0;
}
else if ((option_value
= skip_leading_substring (p, "template-depth-")))
max_tinst_depth
@ -995,7 +980,7 @@ maybe_retrofit_in_chrg (fn)
/* If this is a subobject constructor or destructor, our caller will
pass us a pointer to our VTT. */
if (flag_new_abi && TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
{
DECL_VTT_PARM (fn) = build_artificial_parm (vtt_parm_identifier,
vtt_parm_type);
@ -1081,12 +1066,7 @@ grokclassfn (ctype, function, flags, quals)
if (flags == DTOR_FLAG)
{
DECL_DESTRUCTOR_P (function) = 1;
if (flag_new_abi)
set_mangled_name_for_decl (function);
else
DECL_ASSEMBLER_NAME (function) = build_destructor_name (ctype);
set_mangled_name_for_decl (function);
TYPE_HAS_DESTRUCTOR (ctype) = 1;
}
else
@ -1560,11 +1540,7 @@ finish_static_data_member_decl (decl, init, asmspec_tree, flags)
if (!asmspec && current_class_type)
{
DECL_INITIAL (decl) = error_mark_node;
if (flag_new_abi)
DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
else
DECL_ASSEMBLER_NAME (decl)
= build_static_name (current_class_type, DECL_NAME (decl));
DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
}
if (! processing_template_decl)
{
@ -1699,13 +1675,7 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
name for this TYPE_DECL. */
DECL_ASSEMBLER_NAME (value) = DECL_NAME (value);
if (!uses_template_parms (value))
{
if (flag_new_abi)
DECL_ASSEMBLER_NAME (value) = mangle_type (TREE_TYPE (value));
else
DECL_ASSEMBLER_NAME (value) =
get_identifier (build_overload_name (TREE_TYPE (value), 1, 1));
}
DECL_ASSEMBLER_NAME (value) = mangle_type (TREE_TYPE (value));
if (processing_template_decl)
value = push_template_decl (value);
@ -1886,10 +1856,7 @@ grokoptypename (declspecs, declarator)
tree declspecs, declarator;
{
tree t = grokdeclarator (declarator, declspecs, TYPENAME, 0, NULL_TREE);
if (flag_new_abi)
return mangle_conv_op_name_for_type (t);
else
return build_typename_overload (t);
return mangle_conv_op_name_for_type (t);
}
/* When a function is declared with an initializer,
@ -2757,9 +2724,7 @@ import_export_decl (decl)
tree ctype = DECL_CONTEXT (decl);
import_export_class (ctype);
if (CLASSTYPE_INTERFACE_KNOWN (ctype)
&& (flag_new_abi
? (! DECL_THIS_INLINE (decl))
: (! DECL_ARTIFICIAL (decl) || DECL_VINDEX (decl))))
&& ! DECL_THIS_INLINE (decl))
{
DECL_NOT_REALLY_EXTERN (decl)
= ! (CLASSTYPE_INTERFACE_ONLY (ctype)
@ -2846,23 +2811,7 @@ get_guard (decl)
tree sname;
tree guard;
/* For a local variable, under the old ABI, we do not try to get a
unique mangled name for the DECL. */
if (!flag_new_abi && DECL_FUNCTION_SCOPE_P (decl))
{
guard = get_temp_name (integer_type_node);
cp_finish_decl (guard, NULL_TREE, NULL_TREE, 0);
return guard;
}
if (!flag_new_abi)
/* For struct X foo __attribute__((weak)), there is a counter
__snfoo. Since base is already an assembler name, sname should
be globally unique */
sname = get_id_2 ("__sn", DECL_ASSEMBLER_NAME (decl));
else
sname = mangle_guard_variable (decl);
sname = mangle_guard_variable (decl);
guard = IDENTIFIER_GLOBAL_VALUE (sname);
if (! guard)
{
@ -2870,11 +2819,7 @@ get_guard (decl)
/* Under the new ABI, we use a type that is big enough to
contain a mutex as well as an integer counter. */
if (flag_new_abi)
guard_type = long_long_integer_type_node;
else
guard_type = integer_type_node;
guard_type = long_long_integer_type_node;
guard = build_decl (VAR_DECL, sname, guard_type);
/* The guard should have the same linkage as what it guards. */
@ -2900,9 +2845,6 @@ static tree
get_guard_bits (guard)
tree guard;
{
if (!flag_new_abi)
return guard;
/* Under the new ABI, we only set the first byte of the guard,
in order to leave room for a mutex in the high-order bits. */
guard = build1 (ADDR_EXPR,
@ -3358,7 +3300,7 @@ start_static_initialization_or_destruction (decl, initp)
/* Under the new ABI, we have not already set the GUARD, so we must
do so now. */
if (guard && initp && flag_new_abi)
if (guard && initp)
finish_expr_stmt (set_guard (guard));
return guard_if_stmt;
@ -3724,10 +3666,7 @@ finish_file ()
finish_function doesn't clean things up, and we end
up with CURRENT_FUNCTION_DECL set. */
push_to_top_level ();
if (DECL_TINFO_FN_P (decl))
synthesize_tinfo_fn (decl);
else
synthesize_method (decl);
synthesize_method (decl);
pop_from_top_level ();
reconsider = 1;
}

View File

@ -1963,7 +1963,7 @@ dump_expr (t, flags)
t = TYPE_METHOD_BASETYPE (t);
virtuals = TYPE_BINFO_VIRTUALS (TYPE_MAIN_VARIANT (t));
n = tree_low_cst (idx, 0) - first_vfun_index (t);
n = tree_low_cst (idx, 0);
/* Map vtable index back one, to allow for the null pointer to
member. */

View File

@ -867,8 +867,6 @@ expand_throw (exp)
tree arg_types;
arg_types = void_list_node;
if (!flag_new_abi)
arg_types = tree_cons (NULL_TREE, integer_type_node, arg_types);
arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
cleanup_type = (build_pointer_type
(build_function_type (void_type_node, arg_types)));
@ -927,9 +925,7 @@ expand_throw (exp)
if (TYPE_HAS_DESTRUCTOR (TREE_TYPE (object)))
{
cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
(flag_new_abi
? complete_dtor_identifier
: dtor_identifier),
complete_dtor_identifier,
0);
cleanup = TREE_VALUE (cleanup);
mark_used (cleanup);

View File

@ -56,18 +56,6 @@ cplus_expand_constant (cst)
{
/* Find the offset for the field. */
tree offset = byte_position (member);
if (flag_new_abi)
/* Under the new ABI, we use -1 to represent the NULL
pointer; non-NULL values simply contain the offset of
the data member. */
;
else
/* We offset all pointer to data members by 1 so that we
can distinguish between a null pointer to data member
and the first data member of a structure. */
offset = size_binop (PLUS_EXPR, offset, size_one_node);
cst = fold (build1 (NOP_EXPR, type, offset));
}
else
@ -75,7 +63,7 @@ cplus_expand_constant (cst)
tree delta, idx, pfn, delta2;
expand_ptrmemfunc_cst (cst, &delta, &idx, &pfn, &delta2);
cst = build_ptrmemfunc1 (type, delta, idx, pfn, delta2);
cst = build_ptrmemfunc1 (type, delta, pfn);
}
}
break;

View File

@ -1954,14 +1954,6 @@ resolve_offset_ref (exp)
addr = convert_pointer_to (basetype, addr);
member = cp_convert (ptrdiff_type_node, member);
if (!flag_new_abi)
/* Pointer to data members are offset by one, so that a null
pointer with a real value of 0 is distinguishable from an
offset of the first member of a structure. */
member = cp_build_binary_op (MINUS_EXPR, member,
cp_convert (ptrdiff_type_node,
integer_one_node));
return build1 (INDIRECT_REF, type,
build (PLUS_EXPR, build_pointer_type (type),
addr, member));
@ -2224,20 +2216,17 @@ build_java_class_ref (type)
}
/* Mangle the class$ field, new and old ABI */
if (flag_new_abi)
{
tree field;
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
if (DECL_NAME (field) == CL_suffix)
{
name = mangle_decl (field);
break;
}
if (!field)
internal_error ("Can't find class$");
{
tree field;
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
if (DECL_NAME (field) == CL_suffix)
{
name = mangle_decl (field);
break;
}
if (!field)
internal_error ("Can't find class$");
}
else
name = build_static_name (type, CL_suffix);
class_decl = IDENTIFIER_GLOBAL_VALUE (name);
if (class_decl == NULL_TREE)
@ -2264,27 +2253,17 @@ get_cookie_size (type)
{
tree cookie_size;
if (flag_new_abi)
{
/* Under the new ABI, we need to allocate an additional max
(sizeof (size_t), alignof (true_type)) bytes. */
tree sizetype_size;
tree type_align;
sizetype_size = size_in_bytes (sizetype);
type_align = size_int (TYPE_ALIGN_UNIT (type));
if (INT_CST_LT_UNSIGNED (type_align, sizetype_size))
cookie_size = sizetype_size;
else
cookie_size = type_align;
}
/* Under the new ABI, we need to allocate an additional max
(sizeof (size_t), alignof (true_type)) bytes. */
tree sizetype_size;
tree type_align;
sizetype_size = size_in_bytes (sizetype);
type_align = size_int (TYPE_ALIGN_UNIT (type));
if (INT_CST_LT_UNSIGNED (type_align, sizetype_size))
cookie_size = sizetype_size;
else
{
if (TYPE_ALIGN (type) > TYPE_ALIGN (BI_header_type))
return size_int (TYPE_ALIGN_UNIT (type));
else
return size_in_bytes (BI_header_type);
}
cookie_size = type_align;
return cookie_size;
}
@ -2386,7 +2365,7 @@ build_new_1 (exp)
else if (placement && !TREE_CHAIN (placement)
&& same_type_p (TREE_TYPE (TREE_VALUE (placement)),
ptr_type_node))
use_cookie = (!flag_new_abi || !use_global_new);
use_cookie = !use_global_new;
/* Otherwise, we need the cookie. */
else
use_cookie = 1;
@ -2481,23 +2460,13 @@ build_new_1 (exp)
tree cookie;
/* Store the number of bytes allocated so that we can know how
many elements to destroy later. */
if (flag_new_abi)
{
/* Under the new ABI, we use the last sizeof (size_t) bytes
to store the number of elements. */
cookie = build (MINUS_EXPR, build_pointer_type (sizetype),
alloc_node, size_in_bytes (sizetype));
cookie = build_indirect_ref (cookie, NULL_PTR);
}
else
{
cookie = build (MINUS_EXPR, build_pointer_type (BI_header_type),
alloc_node, cookie_size);
cookie = build_indirect_ref (cookie, NULL_PTR);
cookie = build_component_ref (cookie, nelts_identifier,
NULL_TREE, 0);
}
many elements to destroy later. Under the new ABI, we use
the last sizeof (size_t) bytes to store the number of
elements. */
cookie = build (MINUS_EXPR, build_pointer_type (sizetype),
alloc_node, size_in_bytes (sizetype));
cookie = build_indirect_ref (cookie, NULL_PTR);
cookie_expr = build (MODIFY_EXPR, void_type_node, cookie, nelts);
TREE_SIDE_EFFECTS (cookie_expr) = 1;
}
@ -3412,24 +3381,11 @@ build_vec_delete (base, maxindex, auto_delete_vec, use_global_delete)
tree cookie_addr;
type = strip_array_types (TREE_TYPE (type));
if (flag_new_abi)
{
cookie_addr = build (MINUS_EXPR,
build_pointer_type (sizetype),
base,
TYPE_SIZE_UNIT (sizetype));
maxindex = build_indirect_ref (cookie_addr, NULL_PTR);
}
else
{
tree cookie;
cookie_addr = build (MINUS_EXPR, build_pointer_type (BI_header_type),
base, get_cookie_size (type));
cookie = build_indirect_ref (cookie_addr, NULL_PTR);
maxindex = build_component_ref (cookie, nelts_identifier,
NULL_TREE, 0);
}
cookie_addr = build (MINUS_EXPR,
build_pointer_type (sizetype),
base,
TYPE_SIZE_UNIT (sizetype));
maxindex = build_indirect_ref (cookie_addr, NULL_PTR);
}
else if (TREE_CODE (type) == ARRAY_TYPE)
{

View File

@ -339,7 +339,7 @@ init_operators ()
: &operator_name_info[(int) CODE]); \
oni->identifier = identifier; \
oni->name = NAME; \
oni->mangled_name = flag_new_abi ? NEW_MANGLING : OLD_MANGLING;
oni->mangled_name = NEW_MANGLING;
#include "operators.def"
#undef DEF_OPERATOR

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* Perform optimizations on tree structure.
Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
Written by Mark Michell (mark@codesourcery.com).
This file is part of GNU CC.
@ -914,10 +914,6 @@ maybe_clone_body (fn)
inline_data id;
tree clone;
/* We don't clone constructors and destructors under the old ABI. */
if (!flag_new_abi)
return 0;
/* We only clone constructors and destructors. */
if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
&& !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))

View File

@ -4222,11 +4222,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
DECL_ASSEMBLER_NAME (type_decl) = DECL_NAME (type_decl);
if (!is_partial_instantiation)
{
if (flag_new_abi)
DECL_ASSEMBLER_NAME (type_decl) = mangle_decl (type_decl);
else
DECL_ASSEMBLER_NAME (type_decl)
= get_identifier (build_overload_name (t, 1, 1));
DECL_ASSEMBLER_NAME (type_decl) = mangle_decl (type_decl);
/* For backwards compatibility; code that uses
-fexternal-templates expects looking up a template to
@ -5817,14 +5813,9 @@ tsubst_decl (t, args, type)
/*entering_scope=*/1);
if (member && DECL_CONV_FN_P (r))
{
/* Type-conversion operator. Reconstruct the name, in
case it's the name of one of the template's parameters. */
if (flag_new_abi)
DECL_NAME (r) = mangle_conv_op_name_for_type (TREE_TYPE (type));
else
DECL_NAME (r) = build_typename_overload (TREE_TYPE (type));
}
/* Type-conversion operator. Reconstruct the name, in
case it's the name of one of the template's parameters. */
DECL_NAME (r) = mangle_conv_op_name_for_type (TREE_TYPE (type));
DECL_ARGUMENTS (r) = tsubst (DECL_ARGUMENTS (t), args,
/*complain=*/1, t);
@ -5860,12 +5851,7 @@ tsubst_decl (t, args, type)
/* Set the mangled name for R. */
if (DECL_DESTRUCTOR_P (t))
{
if (flag_new_abi)
set_mangled_name_for_decl (r);
else
DECL_ASSEMBLER_NAME (r) = build_destructor_name (ctx);
}
set_mangled_name_for_decl (r);
else
{
/* Instantiations of template functions must be mangled
@ -7223,10 +7209,7 @@ tsubst_copy (t, args, complain, in_decl)
if (IDENTIFIER_TYPENAME_P (t))
{
tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
if (flag_new_abi)
return mangle_conv_op_name_for_type (new_type);
else
return (build_typename_overload (new_type));
return mangle_conv_op_name_for_type (new_type);
}
else
return t;
@ -10321,90 +10304,11 @@ static void
set_mangled_name_for_template_decl (decl)
tree decl;
{
tree context = NULL_TREE;
tree fn_type;
tree ret_type;
tree parm_types;
tree tparms;
tree targs;
my_friendly_assert (TREE_CODE (decl) == FUNCTION_DECL, 0);
my_friendly_assert (DECL_TEMPLATE_INFO (decl) != NULL_TREE, 0);
/* Under the new ABI, we don't need special machinery. */
if (flag_new_abi)
{
set_mangled_name_for_decl (decl);
return;
}
/* The names of template functions must be mangled so as to indicate
what template is being specialized with what template arguments.
For example, each of the following three functions must get
different mangled names:
void f(int);
template <> void f<7>(int);
template <> void f<8>(int); */
targs = DECL_TI_ARGS (decl);
if (uses_template_parms (targs))
/* This DECL is for a partial instantiation. There's no need to
mangle the name of such an entity. */
return;
/* We now compute the PARMS and RET_TYPE to give to
build_decl_overload_real. The PARMS and RET_TYPE are the
parameter and return types of the template, after all but the
innermost template arguments have been substituted, not the
parameter and return types of the function DECL. For example,
given:
template <class T> T f(T);
both PARMS and RET_TYPE should be `T' even if DECL is `int f(int)'.
A more subtle example is:
template <class T> struct S { template <class U> void f(T, U); }
Here, if DECL is `void S<int>::f(int, double)', PARMS should be
{int, U}. Thus, the args that we want to subsitute into the
return and parameter type for the function are those in TARGS,
with the innermost level omitted. */
fn_type = get_mostly_instantiated_function_type (decl, &context, &tparms);
/* Now, get the innermost parameters and arguments, and figure out
the parameter and return types. */
tparms = INNERMOST_TEMPLATE_PARMS (tparms);
targs = INNERMOST_TEMPLATE_ARGS (targs);
ret_type = TREE_TYPE (fn_type);
parm_types = TYPE_ARG_TYPES (fn_type);
/* For a static member function, we generate a fake `this' pointer,
for the purposes of mangling. This indicates of which class the
function is a member. Because of:
[class.static]
There shall not be a static and a nonstatic member function
with the same name and the same parameter types
we don't have to worry that this will result in a clash with a
non-static member function. */
if (DECL_STATIC_FUNCTION_P (decl))
parm_types = hash_tree_chain (build_pointer_type (context), parm_types);
/* There should be the same number of template parameters as
template arguments. */
my_friendly_assert (TREE_VEC_LENGTH (tparms) == TREE_VEC_LENGTH (targs),
0);
/* Actually set the DECL_ASSEMBLER_NAME. */
DECL_ASSEMBLER_NAME (decl)
= build_decl_overload_real (decl, parm_types, ret_type,
tparms, targs,
DECL_FUNCTION_MEMBER_P (decl)
+ DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl));
set_mangled_name_for_decl (decl);
}
/* Return truthvalue if we're processing a template different from

View File

@ -1,5 +1,5 @@
/* Code to maintain a C++ template repository.
Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
Contributed by Jason Merrill (jason@cygnus.com)
This file is part of GNU CC.
@ -107,25 +107,6 @@ repo_get_id (t)
vtable = get_vtbl_decl_for_binfo (TYPE_BINFO (t));
/* If we don't have a primary vtable, try looking for a secondary
vtable. */
if (vtable == NULL_TREE && !flag_new_abi
&& TYPE_USES_VIRTUAL_BASECLASSES (t))
{
tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
for (i = 0; i < n_baselinks; ++i)
{
tree base_binfo = TREE_VEC_ELT (binfos, i);
if (TREE_VIA_VIRTUAL (base_binfo))
{
vtable = get_vtbl_decl_for_binfo (base_binfo);
if (vtable)
break;
}
}
}
t = vtable;
if (t == NULL_TREE)
return t;

View File

@ -43,16 +43,10 @@ extern struct obstack permanent_obstack;
static tree build_headof_sub PARAMS((tree));
static tree build_headof PARAMS((tree));
static tree get_tinfo_var PARAMS((tree));
static tree ifnonnull PARAMS((tree, tree));
static tree tinfo_name PARAMS((tree));
static tree get_base_offset PARAMS((tree, tree));
static tree build_dynamic_cast_1 PARAMS((tree, tree));
static void expand_si_desc PARAMS((tree, tree));
static void expand_class_desc PARAMS((tree, tree));
static void expand_attr_desc PARAMS((tree, tree));
static void expand_ptr_desc PARAMS((tree, tree));
static void expand_generic_desc PARAMS((tree, tree, const char *));
static tree throw_bad_cast PARAMS((void));
static tree throw_bad_typeid PARAMS((void));
static tree get_tinfo_decl_dynamic PARAMS((tree));
@ -182,9 +176,7 @@ build_headof (exp)
static tree
throw_bad_cast ()
{
tree fn = get_identifier (flag_new_abi
? "__cxa_bad_cast" :
"__throw_bad_cast");
tree fn = get_identifier ("__cxa_bad_cast");
if (IDENTIFIER_GLOBAL_VALUE (fn))
fn = IDENTIFIER_GLOBAL_VALUE (fn);
else
@ -197,9 +189,7 @@ throw_bad_cast ()
static tree
throw_bad_typeid ()
{
tree fn = get_identifier (flag_new_abi
? "__cxa_bad_typeid"
: "__throw_bad_typeid");
tree fn = get_identifier ("__cxa_bad_typeid");
if (IDENTIFIER_GLOBAL_VALUE (fn))
fn = IDENTIFIER_GLOBAL_VALUE (fn);
else
@ -330,49 +320,6 @@ build_typeid (exp)
return convert_from_reference (exp);
}
static tree
get_tinfo_var (type)
tree type;
{
tree tname = build_overload_with_type (tinfo_var_id, type);
tree arrtype;
int size;
my_friendly_assert (!new_abi_rtti_p (), 20000118);
if (IDENTIFIER_GLOBAL_VALUE (tname))
return IDENTIFIER_GLOBAL_VALUE (tname);
/* Figure out how much space we need to allocate for the type_info object.
If our struct layout or the type_info classes are changed, this will
need to be modified. */
if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)
size = 3 * POINTER_SIZE + INT_TYPE_SIZE;
else if (TREE_CODE (type) == POINTER_TYPE
&& ! (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE
|| TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE))
size = 3 * POINTER_SIZE;
else if (IS_AGGR_TYPE (type))
{
if (CLASSTYPE_N_BASECLASSES (type) == 0)
size = 2 * POINTER_SIZE;
else if (! TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type)
&& (TREE_VIA_PUBLIC
(TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
size = 3 * POINTER_SIZE;
else
size = 3 * POINTER_SIZE + TYPE_PRECISION (sizetype);
}
else
size = 2 * POINTER_SIZE;
/* The type for a character array of the appropriate size. */
arrtype = build_cplus_array_type
(unsigned_char_type_node,
build_index_type (size_int (size / BITS_PER_UNIT - 1)));
return declare_global_var (tname, arrtype);
}
/* Generate the NTBS name of a type. */
static tree
tinfo_name (type)
@ -381,10 +328,7 @@ tinfo_name (type)
const char *name;
tree name_string;
if (flag_new_abi)
name = mangle_type_string (type);
else
name = build_overload_name (type, 1, 1);
name = mangle_type_string (type);
name_string = combine_strings (build_string (strlen (name) + 1, name));
return name_string;
}
@ -410,24 +354,11 @@ get_tinfo_decl (type)
type = build_function_type (TREE_TYPE (type),
TREE_CHAIN (TYPE_ARG_TYPES (type)));
if (flag_new_abi)
name = mangle_typeinfo_for_type (type);
else
name = build_overload_with_type (tinfo_decl_id, type);
name = mangle_typeinfo_for_type (type);
d = IDENTIFIER_GLOBAL_VALUE (name);
if (d)
/* OK */;
else if (!new_abi_rtti_p ())
{
/* The tinfo decl is a function returning a reference to the
type_info object. */
d = push_library_fn (name, tinfo_decl_type);
DECL_NOT_REALLY_EXTERN (d) = 1;
SET_DECL_TINFO_FN_P (d);
TREE_TYPE (name) = type;
defer_fn (d);
}
else
{
/* The tinfo decl is the type_info object itself. We make all
@ -889,381 +820,6 @@ build_dynamic_cast (type, expr)
return convert_from_reference (build_dynamic_cast_1 (type, expr));
}
/* Build and initialize various sorts of descriptors. Every descriptor
node has a name associated with it (the name created by mangling).
For this reason, we use the identifier as our access to the __*_desc
nodes, instead of sticking them directly in the types. Otherwise we
would burden all built-in types (and pointer types) with slots that
we don't necessarily want to use.
For each descriptor we build, we build a variable that contains
the descriptor's information. When we need this info at runtime,
all we need is access to these variables.
Note: these constructors always return the address of the descriptor
info, since that is simplest for their mutual interaction. */
/* Build an initializer for a __si_type_info node. */
static void
expand_si_desc (tdecl, type)
tree tdecl;
tree type;
{
tree t, elems, fn;
tree name_string = tinfo_name (type);
type = BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0));
finish_expr_stmt (get_typeid_1 (type));
t = decay_conversion (get_tinfo_var (type));
elems = tree_cons
(NULL_TREE, decay_conversion (tdecl), tree_cons
(NULL_TREE, decay_conversion (name_string), tree_cons
(NULL_TREE, t, NULL_TREE)));
fn = get_identifier ("__rtti_si");
if (IDENTIFIER_GLOBAL_VALUE (fn))
fn = IDENTIFIER_GLOBAL_VALUE (fn);
else
{
tree tmp;
tmp = tree_cons
(NULL_TREE, ptr_type_node, tree_cons
(NULL_TREE, const_string_type_node, tree_cons
(NULL_TREE, build_pointer_type (type_info_type_node),
void_list_node)));
fn = push_void_library_fn (fn, tmp);
}
fn = build_call (fn, elems);
finish_expr_stmt (fn);
}
/* Build an initializer for a __class_type_info node. */
static void
expand_class_desc (tdecl, type)
tree tdecl;
tree type;
{
tree name_string;
tree fn, tmp;
int i = CLASSTYPE_N_BASECLASSES (type);
int base_cnt = 0;
tree binfos = TYPE_BINFO_BASETYPES (type);
tree base, elems, access, offset, isvir;
tree elt, elts = NULL_TREE;
if (base_desc_type_node == NULL_TREE)
{
tree fields [4];
/* A reasonably close approximation of __class_type_info::base_info */
base_desc_type_node = make_aggr_type (RECORD_TYPE);
/* Actually const __user_type_info * */
fields [0] = build_decl
(FIELD_DECL, NULL_TREE,
build_pointer_type (build_qualified_type
(type_info_type_node,
TYPE_QUAL_CONST)));
fields [1] = build_decl
(FIELD_DECL, NULL_TREE,
flag_new_abi ? intSI_type_node : unsigned_intSI_type_node);
DECL_BIT_FIELD (fields[1]) = 1;
DECL_SIZE (fields[1]) = bitsize_int (29);
fields [2] = build_decl (FIELD_DECL, NULL_TREE, boolean_type_node);
DECL_BIT_FIELD (fields[2]) = 1;
DECL_SIZE (fields[2]) = bitsize_one_node;
/* Actually enum access */
fields [3] = build_decl (FIELD_DECL, NULL_TREE, integer_type_node);
DECL_BIT_FIELD (fields[3]) = 1;
DECL_SIZE (fields[3]) = bitsize_int (2);
finish_builtin_type (base_desc_type_node, "__base_info", fields,
3, ptr_type_node);
}
while (--i >= 0)
{
tree binfo = TREE_VEC_ELT (binfos, i);
finish_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo)));
base = decay_conversion (get_tinfo_var (BINFO_TYPE (binfo)));
offset = get_base_offset (binfo, type);
if (TREE_VIA_PUBLIC (binfo))
access = access_public_node;
else if (TREE_VIA_PROTECTED (binfo))
access = access_protected_node;
else
access = access_private_node;
if (TREE_VIA_VIRTUAL (binfo))
isvir = boolean_true_node;
else
isvir = boolean_false_node;
elt = build
(CONSTRUCTOR, base_desc_type_node, NULL_TREE, tree_cons
(NULL_TREE, base, tree_cons
(NULL_TREE, offset, tree_cons
(NULL_TREE, isvir, tree_cons
(NULL_TREE, access, NULL_TREE)))));
TREE_HAS_CONSTRUCTOR (elt) = TREE_CONSTANT (elt) = TREE_STATIC (elt) = 1;
elts = tree_cons (NULL_TREE, elt, elts);
base_cnt++;
}
name_string = tinfo_name (type);
{
tree arrtype = build_array_type (base_desc_type_node, NULL_TREE);
elts = build (CONSTRUCTOR, arrtype, NULL_TREE, elts);
TREE_HAS_CONSTRUCTOR (elts) = TREE_CONSTANT (elts)
= TREE_STATIC (elts) = 1;
complete_array_type (arrtype, elts, 1);
}
elems = tree_cons
(NULL_TREE, decay_conversion (tdecl), tree_cons
(NULL_TREE, decay_conversion (name_string), tree_cons
(NULL_TREE, decay_conversion (elts), tree_cons
(NULL_TREE, cp_convert (sizetype, build_int_2 (base_cnt, 0)),
NULL_TREE))));
fn = get_identifier ("__rtti_class");
if (IDENTIFIER_GLOBAL_VALUE (fn))
fn = IDENTIFIER_GLOBAL_VALUE (fn);
else
{
tmp = tree_cons
(NULL_TREE, ptr_type_node, tree_cons
(NULL_TREE, const_string_type_node, tree_cons
(NULL_TREE, build_pointer_type (base_desc_type_node), tree_cons
(NULL_TREE, sizetype, void_list_node))));
fn = push_void_library_fn (fn, tmp);
}
fn = build_call (fn, elems);
finish_expr_stmt (fn);
}
/* Build an initializer for a __pointer_type_info node. */
static void
expand_ptr_desc (tdecl, type)
tree tdecl;
tree type;
{
tree t, elems, fn;
tree name_string = tinfo_name (type);
type = TREE_TYPE (type);
finish_expr_stmt (get_typeid_1 (type));
t = decay_conversion (get_tinfo_var (type));
elems = tree_cons
(NULL_TREE, decay_conversion (tdecl), tree_cons
(NULL_TREE, decay_conversion (name_string), tree_cons
(NULL_TREE, t, NULL_TREE)));
fn = get_identifier ("__rtti_ptr");
if (IDENTIFIER_GLOBAL_VALUE (fn))
fn = IDENTIFIER_GLOBAL_VALUE (fn);
else
{
tree tmp;
tmp = tree_cons
(NULL_TREE, ptr_type_node, tree_cons
(NULL_TREE, const_string_type_node, tree_cons
(NULL_TREE, build_pointer_type (type_info_type_node),
void_list_node)));
fn = push_void_library_fn (fn, tmp);
}
fn = build_call (fn, elems);
finish_expr_stmt (fn);
}
/* Build an initializer for a __attr_type_info node. */
static void
expand_attr_desc (tdecl, type)
tree tdecl;
tree type;
{
tree elems, t, fn;
tree name_string = tinfo_name (type);
tree attrval = build_int_2 (TYPE_QUALS (type), 0);
finish_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type)));
t = decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type)));
elems = tree_cons
(NULL_TREE, decay_conversion (tdecl), tree_cons
(NULL_TREE, decay_conversion (name_string), tree_cons
(NULL_TREE, attrval, tree_cons (NULL_TREE, t, NULL_TREE))));
fn = get_identifier ("__rtti_attr");
if (IDENTIFIER_GLOBAL_VALUE (fn))
fn = IDENTIFIER_GLOBAL_VALUE (fn);
else
{
tree tmp;
tmp = tree_cons
(NULL_TREE, ptr_type_node, tree_cons
(NULL_TREE, const_string_type_node, tree_cons
(NULL_TREE, integer_type_node, tree_cons
(NULL_TREE, build_pointer_type (type_info_type_node),
void_list_node))));
fn = push_void_library_fn (fn, tmp);
}
fn = build_call (fn, elems);
finish_expr_stmt (fn);
}
/* Build an initializer for a type_info node that just has a name. */
static void
expand_generic_desc (tdecl, type, fnname)
tree tdecl;
tree type;
const char *fnname;
{
tree name_string = tinfo_name (type);
tree elems = tree_cons
(NULL_TREE, decay_conversion (tdecl), tree_cons
(NULL_TREE, decay_conversion (name_string), NULL_TREE));
tree fn = get_identifier (fnname);
if (IDENTIFIER_GLOBAL_VALUE (fn))
fn = IDENTIFIER_GLOBAL_VALUE (fn);
else
{
tree tmp;
tmp = tree_cons
(NULL_TREE, ptr_type_node, tree_cons
(NULL_TREE, const_string_type_node, void_list_node));
fn = push_void_library_fn (fn, tmp);
}
fn = build_call (fn, elems);
finish_expr_stmt (fn);
}
/* Generate the code for a type_info initialization function.
Note that we take advantage of the passage
5.2.7 Type identification [expr.typeid]
Whether or not the destructor is called for the type_info object at the
end of the program is unspecified.
and don't bother to arrange for these objects to be destroyed. It
doesn't matter, anyway, since the destructors don't do anything.
This must only be called from toplevel (i.e. from finish_file)! */
void
synthesize_tinfo_fn (fndecl)
tree fndecl;
{
tree type = TREE_TYPE (DECL_NAME (fndecl));
tree tmp, addr, tdecl;
tree compound_stmt;
tree if_stmt;
tree then_clause;
my_friendly_assert (!new_abi_rtti_p (), 20000118);
if (at_eof)
{
import_export_decl (fndecl);
if (DECL_REALLY_EXTERN (fndecl))
return;
}
/* Declare the static typeinfo variable. */
tdecl = get_tinfo_var (type);
DECL_EXTERNAL (tdecl) = 0;
TREE_STATIC (tdecl) = 1;
DECL_COMMON (tdecl) = 1;
TREE_USED (tdecl) = 1;
DECL_ALIGN (tdecl) = TYPE_ALIGN (ptr_type_node);
DECL_USER_ALIGN (tdecl) = 0;
cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0);
/* Begin processing the function. */
start_function (NULL_TREE, fndecl, NULL_TREE,
SF_DEFAULT | SF_PRE_PARSED);
DECL_DEFER_OUTPUT (fndecl) = 1;
clear_last_expr ();
/* Begin the body of the function. */
compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
/* For convenience, we save away the address of the static
variable. */
addr = decay_conversion (tdecl);
/* If the first word of the array (the vtable) is non-zero, we've already
initialized the object, so don't do it again. */
if_stmt = begin_if_stmt ();
tmp = cp_convert (build_pointer_type (ptr_type_node), addr);
tmp = build_indirect_ref (tmp, 0);
tmp = cp_build_binary_op (EQ_EXPR, tmp, integer_zero_node);
finish_if_stmt_cond (tmp, if_stmt);
then_clause = begin_compound_stmt (/*has_no_scope=*/0);
if (TREE_CODE (type) == FUNCTION_TYPE)
expand_generic_desc (tdecl, type, "__rtti_func");
else if (TREE_CODE (type) == ARRAY_TYPE)
expand_generic_desc (tdecl, type, "__rtti_array");
else if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)
expand_attr_desc (tdecl, type);
else if (TREE_CODE (type) == POINTER_TYPE)
{
if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE)
expand_generic_desc (tdecl, type, "__rtti_ptmd");
else if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
expand_generic_desc (tdecl, type, "__rtti_ptmf");
else
expand_ptr_desc (tdecl, type);
}
else if (TYPE_PTRMEMFUNC_P (type))
expand_generic_desc (tdecl, type, "__rtti_ptmf");
else if (IS_AGGR_TYPE (type))
{
if (CLASSTYPE_N_BASECLASSES (type) == 0)
expand_generic_desc (tdecl, type, "__rtti_user");
else if (! TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type)
&& (TREE_VIA_PUBLIC
(TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
expand_si_desc (tdecl, type);
else
expand_class_desc (tdecl, type);
}
else if (TREE_CODE (type) == ENUMERAL_TYPE)
expand_generic_desc (tdecl, type, "__rtti_user");
else
my_friendly_abort (252);
finish_compound_stmt (/*has_no_scope=*/0, then_clause);
finish_then_clause (if_stmt);
finish_if_stmt ();
/* OK, now return the type_info object. */
tmp = cp_convert (build_pointer_type (type_info_type_node), addr);
tmp = build_indirect_ref (tmp, 0);
finish_return_stmt (tmp);
/* Finish the function body. */
finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
expand_body (finish_function (0));
}
/* Return the runtime bit mask encoding the qualifiers of TYPE. */
static int
@ -1328,10 +884,7 @@ tinfo_base_init (desc, target)
NULL_TREE);
tree name_string = tinfo_name (target);
if (flag_new_abi)
name_name = mangle_typeinfo_string_for_type (target);
else
name_name = build_overload_with_type (tinfo_var_id, target);
name_name = mangle_typeinfo_string_for_type (target);
name_decl = build_lang_decl (VAR_DECL, name_name, name_type);
DECL_ARTIFICIAL (name_decl) = 1;
@ -1340,13 +893,10 @@ tinfo_base_init (desc, target)
DECL_EXTERNAL (name_decl) = 0;
TREE_PUBLIC (name_decl) = 1;
comdat_linkage (name_decl);
if (flag_new_abi)
/* The new ABI specifies the external name of the string
containing the type's name. */
DECL_ASSEMBLER_NAME (name_decl)
= mangle_typeinfo_string_for_type (target);
else
DECL_ASSEMBLER_NAME (name_decl) = DECL_NAME (name_decl);
/* The new ABI specifies the external name of the string
containing the type's name. */
DECL_ASSEMBLER_NAME (name_decl)
= mangle_typeinfo_string_for_type (target);
DECL_INITIAL (name_decl) = name_string;
cp_finish_decl (name_decl, name_string, NULL_TREE, 0);
pushdecl_top_level (name_decl);
@ -1809,16 +1359,13 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
/* Under the new ABI, we need to point into the middle of the
vtable. */
if (flag_new_abi)
{
vtable_decl = build (PLUS_EXPR,
TREE_TYPE (vtable_decl),
vtable_decl,
size_binop (MULT_EXPR,
size_int (2),
TYPE_SIZE_UNIT (vtable_entry_type)));
TREE_CONSTANT (vtable_decl) = 1;
}
vtable_decl = build (PLUS_EXPR,
TREE_TYPE (vtable_decl),
vtable_decl,
size_binop (MULT_EXPR,
size_int (2),
TYPE_SIZE_UNIT (vtable_entry_type)));
TREE_CONSTANT (vtable_decl) = 1;
/* First field is the pseudo type_info base class. */
fields[0] = build_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);

View File

@ -2507,8 +2507,7 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t,
*vbase_offsets = delta;
}
for (virtuals = BINFO_VIRTUALS (binfo),
n = first_vfun_index (BINFO_TYPE (binfo));
for (virtuals = BINFO_VIRTUALS (binfo), n = 0;
virtuals;
virtuals = TREE_CHAIN (virtuals), ++n)
{

View File

@ -883,7 +883,7 @@ debug_binfo (elem)
fprintf (stderr, "no vtable decl yet\n");
fprintf (stderr, "virtuals:\n");
virtuals = BINFO_VIRTUALS (elem);
n = first_vfun_index (BINFO_TYPE (elem));
n = 0;
while (virtuals)
{
@ -2229,9 +2229,6 @@ cp_valid_lang_attribute (attr_name, attr_args, decl, type)
return 0;
}
if (!flag_new_abi)
/* The v3 ABI is already COM compliant; don't set this flag. */
CLASSTYPE_COM_INTERFACE (type) = 1;
return 1;
}
else if (is_attribute_p ("init_priority", attr_name))

View File

@ -2884,35 +2884,20 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
load-with-sign-extend, while the second used normal load then
shift to sign-extend. An optimizer flaw, perhaps, but it's
easier to make this change. */
if (flag_new_abi)
{
idx = cp_build_binary_op (TRUNC_DIV_EXPR,
build1 (NOP_EXPR, vtable_index_type, e3),
TYPE_SIZE_UNIT (vtable_entry_type));
e1 = cp_build_binary_op (BIT_AND_EXPR,
build1 (NOP_EXPR, vtable_index_type, e3),
integer_one_node);
}
else
{
idx = save_expr (default_conversion
(build_component_ref (function,
index_identifier,
NULL_TREE, 0)));
e1 = cp_build_binary_op (GE_EXPR, idx, integer_zero_node);
idx = cp_build_binary_op (MINUS_EXPR, idx, integer_one_node);
}
idx = cp_build_binary_op (TRUNC_DIV_EXPR,
build1 (NOP_EXPR, vtable_index_type, e3),
TYPE_SIZE_UNIT (vtable_entry_type));
e1 = cp_build_binary_op (BIT_AND_EXPR,
build1 (NOP_EXPR, vtable_index_type, e3),
integer_one_node);
vtbl = convert_pointer_to (ptr_type_node, instance);
delta = cp_convert (ptrdiff_type_node,
build_component_ref (function, delta_identifier,
NULL_TREE, 0));
if (flag_new_abi)
/* DELTA2 is the amount by which to adjust the `this' pointer
to find the vtbl. */
delta2 = delta;
else
delta2 = DELTA2_FROM_PTRMEMFUNC (function);
/* DELTA2 is the amount by which to adjust the `this' pointer
to find the vtbl. */
delta2 = delta;
vtbl = build
(PLUS_EXPR,
build_pointer_type (build_pointer_type (vtable_entry_type)),
@ -3630,16 +3615,8 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
}
else if (TYPE_PTRMEMFUNC_P (type0) && null_ptr_cst_p (op1))
{
if (flag_new_abi)
{
op0 = build_component_ref (op0, pfn_identifier, NULL_TREE, 0);
op1 = cp_convert (TREE_TYPE (op0), integer_zero_node);
}
else
{
op0 = build_component_ref (op0, index_identifier, NULL_TREE, 0);
op1 = integer_zero_node;
}
op0 = build_component_ref (op0, pfn_identifier, NULL_TREE, 0);
op1 = cp_convert (TREE_TYPE (op0), integer_zero_node);
result_type = TREE_TYPE (op0);
}
else if (TYPE_PTRMEMFUNC_P (type1) && null_ptr_cst_p (op0))
@ -3652,80 +3629,38 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
/* E1 and E2 are for scratch. */
tree e1;
tree e2;
tree pfn0;
tree pfn1;
tree delta0;
tree delta1;
if (TREE_SIDE_EFFECTS (op0))
op0 = save_expr (op0);
if (TREE_SIDE_EFFECTS (op1))
op1 = save_expr (op1);
if (flag_new_abi)
{
/* We generate:
/* We generate:
(op0.pfn == op1.pfn
&& (!op0.pfn || op0.delta == op1.delta))
The reason for the `!op0.pfn' bit is that a NULL
pointer-to-member is any member with a zero PFN; the
DELTA field is unspecified. */
tree pfn0;
tree pfn1;
tree delta0;
tree delta1;
pfn0 = pfn_from_ptrmemfunc (op0);
pfn1 = pfn_from_ptrmemfunc (op1);
delta0 = build_component_ref (op0, delta_identifier,
NULL_TREE, 0);
delta1 = build_component_ref (op1, delta_identifier,
NULL_TREE, 0);
e1 = cp_build_binary_op (EQ_EXPR, delta0, delta1);
e2 = cp_build_binary_op (EQ_EXPR,
pfn0,
cp_convert (TREE_TYPE (pfn0),
integer_zero_node));
e1 = cp_build_binary_op (TRUTH_ORIF_EXPR, e1, e2);
e2 = build (EQ_EXPR, boolean_type_node, pfn0, pfn1);
e = cp_build_binary_op (TRUTH_ANDIF_EXPR, e2, e1);
}
else
{
/* The code we generate for the test is:
(op0.index == op1.index
&& op0.delta == op1.delta
&& (op1.index == -1 ? op0.pfn == op1.pfn
: op0.delta2 == op1.delta2)) */
tree index0 = build_component_ref (op0, index_identifier,
NULL_TREE, 0);
tree index1
= save_expr (build_component_ref (op1, index_identifier,
NULL_TREE, 0));
tree delta0 = build_component_ref (op0, delta_identifier,
NULL_TREE, 0);
tree delta1 = build_component_ref (op1, delta_identifier,
NULL_TREE, 0);
tree pfn0 = PFN_FROM_PTRMEMFUNC (op0);
tree pfn1 = PFN_FROM_PTRMEMFUNC (op1);
tree delta20 = DELTA2_FROM_PTRMEMFUNC (op0);
tree delta21 = DELTA2_FROM_PTRMEMFUNC (op1);
tree e3;
tree integer_neg_one_node
= cp_build_binary_op (MINUS_EXPR, integer_zero_node,
integer_one_node);
e1 = cp_build_binary_op (EQ_EXPR, index1, integer_neg_one_node);
/* We can't use build_binary_op for this cmp because it
would get confused by the ptr to method types and
think we want pmfs. */
e2 = build (EQ_EXPR, boolean_type_node, pfn0, pfn1);
e3 = cp_build_binary_op (EQ_EXPR, delta20, delta21);
e = build_conditional_expr (e1, e2, e3);
e1 = cp_build_binary_op (EQ_EXPR, index0, index1);
e = cp_build_binary_op (TRUTH_ANDIF_EXPR, e1, e);
e1 = cp_build_binary_op (EQ_EXPR, delta0, delta1);
e = cp_build_binary_op (TRUTH_ANDIF_EXPR, e1, e);
}
(op0.pfn == op1.pfn
&& (!op0.pfn || op0.delta == op1.delta))
The reason for the `!op0.pfn' bit is that a NULL
pointer-to-member is any member with a zero PFN; the
DELTA field is unspecified. */
pfn0 = pfn_from_ptrmemfunc (op0);
pfn1 = pfn_from_ptrmemfunc (op1);
delta0 = build_component_ref (op0, delta_identifier,
NULL_TREE, 0);
delta1 = build_component_ref (op1, delta_identifier,
NULL_TREE, 0);
e1 = cp_build_binary_op (EQ_EXPR, delta0, delta1);
e2 = cp_build_binary_op (EQ_EXPR,
pfn0,
cp_convert (TREE_TYPE (pfn0),
integer_zero_node));
e1 = cp_build_binary_op (TRUTH_ORIF_EXPR, e1, e2);
e2 = build (EQ_EXPR, boolean_type_node, pfn0, pfn1);
e = cp_build_binary_op (TRUTH_ANDIF_EXPR, e2, e1);
if (code == EQ_EXPR)
return e;
return cp_build_binary_op (EQ_EXPR, e, integer_zero_node);
@ -6025,8 +5960,8 @@ get_delta_difference (from, to, force)
the other components as specified. */
tree
build_ptrmemfunc1 (type, delta, idx, pfn, delta2)
tree type, delta, idx, pfn, delta2;
build_ptrmemfunc1 (type, delta, pfn)
tree type, delta, pfn;
{
tree u = NULL_TREE;
tree delta_field;
@ -6038,24 +5973,12 @@ build_ptrmemfunc1 (type, delta, idx, pfn, delta2)
int allconstant, allsimple;
/* Pull the FIELD_DECLs out of the type. */
if (flag_new_abi)
{
pfn_field = TYPE_FIELDS (type);
delta_field = TREE_CHAIN (pfn_field);
idx_field = NULL_TREE;
pfn_or_delta2_field = NULL_TREE;
delta2_field = NULL_TREE;
subtype = NULL_TREE;
}
else
{
delta_field = TYPE_FIELDS (type);
idx_field = TREE_CHAIN (delta_field);
pfn_or_delta2_field = TREE_CHAIN (idx_field);
subtype = TREE_TYPE (pfn_or_delta2_field);
pfn_field = TYPE_FIELDS (subtype);
delta2_field = TREE_CHAIN (pfn_field);
}
pfn_field = TYPE_FIELDS (type);
delta_field = TREE_CHAIN (pfn_field);
idx_field = NULL_TREE;
pfn_or_delta2_field = NULL_TREE;
delta2_field = NULL_TREE;
subtype = NULL_TREE;
/* Make sure DELTA has the type we want. */
delta = convert_and_check (delta_type_node, delta);
@ -6069,9 +5992,6 @@ build_ptrmemfunc1 (type, delta, idx, pfn, delta2)
if (pfn)
{
/* A non-virtual function. */
if (!flag_new_abi)
u = build_tree_list (pfn_field, pfn);
allconstant &= TREE_CONSTANT (pfn);
allsimple &= (initializer_constant_valid_p (pfn, TREE_TYPE (pfn))
!= NULL_TREE);
@ -6079,39 +5999,14 @@ build_ptrmemfunc1 (type, delta, idx, pfn, delta2)
else
{
/* A virtual function. */
if (flag_new_abi)
{
allconstant &= TREE_CONSTANT (pfn);
allsimple &= (initializer_constant_valid_p (pfn, TREE_TYPE (pfn))
!= NULL_TREE);
}
else
{
idx = convert_and_check (delta_type_node, idx);
u = build_tree_list (delta2_field, delta2);
allconstant &= TREE_CONSTANT (idx) && TREE_CONSTANT (delta2);
allsimple &= ((initializer_constant_valid_p (idx, TREE_TYPE (idx))
!= NULL_TREE)
&& (initializer_constant_valid_p (delta2,
TREE_TYPE (delta2))
!= NULL_TREE));
}
allconstant &= TREE_CONSTANT (pfn);
allsimple &= (initializer_constant_valid_p (pfn, TREE_TYPE (pfn))
!= NULL_TREE);
}
/* Finish creating the initializer. */
if (flag_new_abi)
u = tree_cons (pfn_field, pfn,
build_tree_list (delta_field, delta));
else
{
u = build (CONSTRUCTOR, subtype, NULL_TREE, u);
u = tree_cons (delta_field, delta,
tree_cons (idx_field,
idx,
build_tree_list (pfn_or_delta2_field,
u)));
}
u = tree_cons (pfn_field, pfn,
build_tree_list (delta_field, delta));
u = build (CONSTRUCTOR, type, NULL_TREE, u);
TREE_CONSTANT (u) = allconstant;
TREE_STATIC (u) = allconstant && allsimple;
@ -6141,12 +6036,9 @@ build_ptrmemfunc (type, pfn, force)
/* Handle multiple conversions of pointer to member functions. */
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (pfn)))
{
tree idx = integer_zero_node;
tree delta = integer_zero_node;
tree delta2 = integer_zero_node;
tree npfn = NULL_TREE;
tree ndelta, ndelta2;
tree e1, e2, e3, n;
tree n;
if (!force
&& !can_convert_arg (to_type, TREE_TYPE (pfn), pfn))
@ -6172,56 +6064,13 @@ build_ptrmemfunc (type, pfn, force)
if (TREE_SIDE_EFFECTS (pfn))
pfn = save_expr (pfn);
if (flag_new_abi)
{
/* Under the new ABI, the conversion is easy. Just adjust
the DELTA field. */
npfn = build_component_ref (pfn, pfn_identifier, NULL_TREE, 0);
delta = build_component_ref (pfn, delta_identifier, NULL_TREE, 0);
delta = cp_convert (ptrdiff_type_node, delta);
delta = cp_build_binary_op (PLUS_EXPR, delta, n);
return build_ptrmemfunc1 (to_type, delta, NULL_TREE, npfn,
NULL_TREE);
}
if (TREE_CODE (pfn) == PTRMEM_CST)
{
/* We could just build the resulting CONSTRUCTOR now, but we
don't, relying on the general machinery below, together
with constant-folding, to do the right thing. */
expand_ptrmemfunc_cst (pfn, &ndelta, &idx, &npfn, &ndelta2);
if (npfn)
/* This constant points to a non-virtual function.
NDELTA2 will be NULL, but it's value doesn't really
matter since we won't use it anyhow. */
ndelta2 = integer_zero_node;
}
else
{
ndelta = cp_convert (ptrdiff_type_node,
build_component_ref (pfn,
delta_identifier,
NULL_TREE, 0));
ndelta2 = cp_convert (ptrdiff_type_node,
DELTA2_FROM_PTRMEMFUNC (pfn));
idx = build_component_ref (pfn, index_identifier, NULL_TREE, 0);
}
delta = cp_build_binary_op (PLUS_EXPR, ndelta, n);
delta2 = cp_build_binary_op (PLUS_EXPR, ndelta2, n);
e1 = fold (build (GT_EXPR, boolean_type_node, idx, integer_zero_node));
/* If it's a virtual function, this is what we want. */
e2 = build_ptrmemfunc1 (to_type, delta, idx, NULL_TREE, delta2);
pfn = PFN_FROM_PTRMEMFUNC (pfn);
npfn = build1 (NOP_EXPR, type, pfn);
TREE_CONSTANT (npfn) = TREE_CONSTANT (pfn);
/* But if it's a non-virtual function, or NULL, we use this
instead. */
e3 = build_ptrmemfunc1 (to_type, delta, idx, npfn, NULL_TREE);
return build_conditional_expr (e1, e2, e3);
/* Under the new ABI, the conversion is easy. Just adjust
the DELTA field. */
npfn = build_component_ref (pfn, pfn_identifier, NULL_TREE, 0);
delta = build_component_ref (pfn, delta_identifier, NULL_TREE, 0);
delta = cp_convert (ptrdiff_type_node, delta);
delta = cp_build_binary_op (PLUS_EXPR, delta, n);
return build_ptrmemfunc1 (to_type, delta, npfn);
}
/* Handle null pointer to member function conversions. */
@ -6229,8 +6078,8 @@ build_ptrmemfunc (type, pfn, force)
{
pfn = build_c_cast (type, integer_zero_node);
return build_ptrmemfunc1 (to_type,
integer_zero_node, integer_zero_node,
pfn, NULL_TREE);
integer_zero_node,
pfn);
}
if (type_unknown_p (pfn))
@ -6273,10 +6122,7 @@ expand_ptrmemfunc_cst (cst, delta, idx, pfn, delta2)
if (!DECL_VIRTUAL_P (fn))
{
if (!flag_new_abi)
*idx = build_int_2 (-1, -1);
else
*idx = NULL_TREE;
*idx = NULL_TREE;
*pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type), build_addr_func (fn));
*delta2 = NULL_TREE;
}
@ -6290,26 +6136,16 @@ expand_ptrmemfunc_cst (cst, delta, idx, pfn, delta2)
*delta = fold (build (PLUS_EXPR, TREE_TYPE (*delta),
*delta, BINFO_OFFSET (binfo)));
if (!flag_new_abi)
{
/* Map everything down one to make room for the null PMF. */
*idx = fold (build (PLUS_EXPR, integer_type_node,
DECL_VINDEX (fn), integer_one_node));
*pfn = NULL_TREE;
}
else
{
/* Under the new ABI, we set PFN to the vtable offset, plus
one, at which the function can be found. */
*idx = NULL_TREE;
*pfn = fold (build (MULT_EXPR, integer_type_node,
DECL_VINDEX (fn),
TYPE_SIZE_UNIT (vtable_entry_type)));
*pfn = fold (build (PLUS_EXPR, integer_type_node, *pfn,
integer_one_node));
*pfn = fold (build1 (NOP_EXPR, TYPE_PTRMEMFUNC_FN_TYPE (type),
*pfn));
}
/* Under the new ABI, we set PFN to the vtable offset, plus
one, at which the function can be found. */
*idx = NULL_TREE;
*pfn = fold (build (MULT_EXPR, integer_type_node,
DECL_VINDEX (fn),
TYPE_SIZE_UNIT (vtable_entry_type)));
*pfn = fold (build (PLUS_EXPR, integer_type_node, *pfn,
integer_one_node));
*pfn = fold (build1 (NOP_EXPR, TYPE_PTRMEMFUNC_FN_TYPE (type),
*pfn));
/* Offset from an object of PTR_CLASS to the vptr for ORIG_CLASS. */
*delta2 = fold (build (PLUS_EXPR, integer_type_node, *delta,
@ -6324,7 +6160,7 @@ tree
delta2_from_ptrmemfunc (t)
tree t;
{
my_friendly_assert (!flag_new_abi, 20000221);
my_friendly_assert (0, 20000221);
if (TREE_CODE (t) == PTRMEM_CST)
{
@ -6364,14 +6200,7 @@ pfn_from_ptrmemfunc (t)
return pfn;
}
if (flag_new_abi)
return build_component_ref (t, pfn_identifier, NULL_TREE, 0);
else
return (build_component_ref
(build_component_ref (t,
pfn_or_delta2_identifier, NULL_TREE,
0),
pfn_identifier, NULL_TREE, 0));
return build_component_ref (t, pfn_identifier, NULL_TREE, 0);
}
/* Expression EXPR is about to be implicitly converted to TYPE. Warn
@ -6778,11 +6607,6 @@ check_return_expr (retval)
return NULL_TREE;
}
/* Under the old ABI, constructors actually always return `this',
even though in C++ you can't return a value from a constructor. */
if (!flag_new_abi && DECL_CONSTRUCTOR_P (current_function_decl))
retval = current_class_ptr;
/* When no explicit return-value is given in a function with a named
return value, the named return value is used. */
result = DECL_RESULT (current_function_decl);