parent
11662aaaa5
commit
1f84ec231e
|
@ -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.
|
||||
|
|
|
@ -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,23 +4413,10 @@ 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
|
||||
if ((name == base_ctor_identifier
|
||||
|| name == base_dtor_identifier)
|
||||
&& TYPE_USES_VIRTUAL_BASECLASSES (basetype))
|
||||
{
|
||||
|
|
158
gcc/cp/class.c
158
gcc/cp/class.c
|
@ -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 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 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,8 +2715,6 @@ 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)
|
||||
{
|
||||
/* If we find BINFO, then the final overrider is in a class
|
||||
|
@ -2772,9 +2741,6 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
|
|||
|
||||
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,7 +2788,6 @@ 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);
|
||||
|
||||
/* Now, go through each of the virtual functions in the virtual
|
||||
|
@ -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,7 +3919,7 @@ 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),
|
||||
if (layout_conflict_p (TREE_TYPE (decl),
|
||||
offset,
|
||||
offsets,
|
||||
field_p))
|
||||
|
@ -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,15 +4145,10 @@ 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
|
||||
if (!seen_one_arg_array_delete_p
|
||||
&& second_parm
|
||||
&& TREE_CHAIN (second_parm) == void_list_node
|
||||
&& same_type_p (TREE_VALUE (second_parm), sizetype))
|
||||
|
@ -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 (!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);
|
||||
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)))))
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if (IDENTIFIER_GLOBAL_VALUE (id))
|
||||
return;
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
112
gcc/cp/decl.c
112
gcc/cp/decl.c
|
@ -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));
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
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 ();
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
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 = 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,9 +3666,6 @@ 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);
|
||||
pop_from_top_level ();
|
||||
reconsider = 1;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,7 +2216,6 @@ 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))
|
||||
|
@ -2236,8 +2227,6 @@ build_java_class_ref (type)
|
|||
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,8 +2253,6 @@ 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;
|
||||
|
@ -2277,14 +2264,6 @@ get_cookie_size (type)
|
|||
cookie_size = sizetype_size;
|
||||
else
|
||||
cookie_size = type_align;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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. */
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
cookie_expr = build (MODIFY_EXPR, void_type_node, cookie, nelts);
|
||||
TREE_SIDE_EFFECTS (cookie_expr) = 1;
|
||||
}
|
||||
|
@ -3412,25 +3381,12 @@ 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);
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
{
|
||||
/* get the total number of things in the array, maxindex is a bad name */
|
||||
|
|
|
@ -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
|
||||
|
|
1836
gcc/cp/method.c
1836
gcc/cp/method.c
File diff suppressed because it is too large
Load Diff
|
@ -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))
|
||||
|
|
96
gcc/cp/pt.c
96
gcc/cp/pt.c
|
@ -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));
|
||||
|
||||
/* 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));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
/* Return truthvalue if we're processing a template different from
|
||||
|
|
|
@ -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;
|
||||
|
|
457
gcc/cp/rtti.c
457
gcc/cp/rtti.c
|
@ -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_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);
|
||||
|
||||
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_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);
|
||||
DECL_INITIAL (name_decl) = name_string;
|
||||
cp_finish_decl (name_decl, name_string, NULL_TREE, 0);
|
||||
pushdecl_top_level (name_decl);
|
||||
|
@ -1809,8 +1359,6 @@ 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,
|
||||
|
@ -1818,7 +1366,6 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
|
|||
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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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))
|
||||
|
|
198
gcc/cp/typeck.c
198
gcc/cp/typeck.c
|
@ -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);
|
||||
}
|
||||
|
||||
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);
|
||||
vtbl = build
|
||||
(PLUS_EXPR,
|
||||
build_pointer_type (build_pointer_type (vtable_entry_type)),
|
||||
|
@ -3629,17 +3614,9 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
|
|||
error ("ISO C++ forbids comparison between pointer and integer");
|
||||
}
|
||||
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;
|
||||
}
|
||||
result_type = TREE_TYPE (op0);
|
||||
}
|
||||
else if (TYPE_PTRMEMFUNC_P (type1) && null_ptr_cst_p (op0))
|
||||
|
@ -3652,14 +3629,16 @@ 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:
|
||||
|
||||
(op0.pfn == op1.pfn
|
||||
|
@ -3668,11 +3647,6 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
|
|||
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,
|
||||
|
@ -3687,45 +3661,6 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
|
|||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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));
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 = 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);
|
||||
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,9 +6122,6 @@ 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;
|
||||
*pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type), build_addr_func (fn));
|
||||
*delta2 = NULL_TREE;
|
||||
|
@ -6290,15 +6136,6 @@ 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;
|
||||
|
@ -6309,7 +6146,6 @@ expand_ptrmemfunc_cst (cst, delta, idx, pfn, delta2)
|
|||
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));
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
|
Loading…
Reference in New Issue