+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.
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))
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;
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 *));
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 *));
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
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. */
}
}
-/* 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);
}
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. */
= 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);
}
}
}
/* 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. */
/* 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
/* 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
|| !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;
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
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);
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
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)
/* 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
&& !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);
}
}
[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. */
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))
{
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))
/* 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);
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
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))
{
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
/* 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);
/* 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);
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;
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;
}
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
/* 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);
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
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;
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;
\f
/* 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. */
/* 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,
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
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)
\f
/* Language-dependent contents of an identifier. */
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) \
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));
/* 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));
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 *));
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));
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);
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));
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));
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)
{
/* 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 ();
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;
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");
}
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 ();
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);
/* 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
{
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)
{
tree fields[4];
tree t;
- tree u;
tree unqualified_variant = NULL_TREE;
if (type == error_mark_node)
/* ... 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. */
/* 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)
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:
if (sfk != sfk_none)
type = check_special_function_return_type (sfk, type,
- ctor_return_type,
ctor_return_type);
else if (type == NULL_TREE)
{
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. */
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);
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. */
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
/* 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);
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
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)
{
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);
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,
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)
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)
{
/* 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. */
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,
/* 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;
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;
}
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. */
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)));
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);
{
/* 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
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;
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));
}
/* 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)
{
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;
}
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;
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;
}
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)
{
: &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
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-/* Obstack where we build text strings for overloading, etc. */
-static struct obstack scratch_obstack;
-static char *scratch_firstobj;
-
-static void icat PARAMS ((HOST_WIDE_INT));
-static void dicat PARAMS ((HOST_WIDE_INT, HOST_WIDE_INT));
-static int old_backref_index PARAMS ((tree));
-static int flush_repeats PARAMS ((int, tree));
-static void build_overload_identifier PARAMS ((tree));
-static void build_overload_nested_name PARAMS ((tree));
-static void mangle_expression PARAMS ((tree));
-static void build_overload_int PARAMS ((tree, mangling_flags));
-static void build_overload_identifier PARAMS ((tree));
-static void build_qualified_name PARAMS ((tree));
-static void build_overload_value PARAMS ((tree, tree, mangling_flags));
-static void issue_nrepeats PARAMS ((int, tree));
-static char *build_mangled_name PARAMS ((tree,int,int));
-static void process_modifiers PARAMS ((tree));
-static void process_overload_item PARAMS ((tree,int));
static void do_build_assign_ref PARAMS ((tree));
static void do_build_copy_constructor PARAMS ((tree));
-static void build_template_template_parm_names PARAMS ((tree));
-static void build_template_parm_names PARAMS ((tree, tree));
-static void build_underscore_int PARAMS ((int));
-static void start_squangling PARAMS ((void));
-static void end_squangling PARAMS ((void));
-static int check_ktype PARAMS ((tree, int));
-static int issue_ktype PARAMS ((tree));
-static void build_overload_scope_ref PARAMS ((tree));
-static void build_mangled_template_parm_index PARAMS ((const char *, tree));
#if HOST_BITS_PER_WIDE_INT >= 64
static void build_mangled_C99_name PARAMS ((int));
#endif
-static int is_back_referenceable_type PARAMS ((tree));
-static int check_btype PARAMS ((tree));
-static void build_mangled_name_for_type PARAMS ((tree));
-static void build_mangled_name_for_type_with_Gcode PARAMS ((tree, int));
static tree synthesize_exception_spec PARAMS ((tree, tree (*) (tree, void *), void *));
static tree locate_dtor PARAMS ((tree, void *));
static tree locate_ctor PARAMS ((tree, void *));
static tree locate_copy PARAMS ((tree, void *));
-# define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0)
-# define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C)))
-# define OB_PUTC2(C1,C2) \
- (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2)))
-# define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1))
-# define OB_PUTID(ID) \
- (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID), \
- IDENTIFIER_LENGTH (ID)))
-# define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S)))
-# define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0'))
-# define OB_LAST() (obstack_next_free (&scratch_obstack)[-1])
-
-/* type tables for K and B type compression */
-static varray_type btypelist;
-static varray_type ktypelist;
-
-/* number of each type seen */
-static size_t maxbtype;
-static size_t maxktype;
-
-/* Array of types seen so far in top-level call to `build_mangled_name'.
- Allocated and deallocated by caller. */
-static varray_type typevec;
-
-/* Number of types interned by `build_mangled_name' so far. */
-static size_t maxtype;
-
-/* Called once to initialize method.c. */
-
-void
-init_method ()
-{
- gcc_obstack_init (&scratch_obstack);
- scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0);
- ggc_add_tree_varray_root (&btypelist, 1);
- ggc_add_tree_varray_root (&ktypelist, 1);
- ggc_add_tree_varray_root (&typevec, 1);
- if (flag_new_abi)
- init_mangle ();
-}
-
-/* This must be large enough to hold any printed integer or floating-point
- value. */
-static char digit_buffer[128];
-
-\f
-/* Here is where overload code starts. */
-
-/* Nonzero if we should not try folding parameter types. */
-static int nofold;
-
-/* Nonzero if an underscore is required before adding a digit to the
- mangled name currently being built. */
-static int numeric_output_need_bar;
-
-static inline void
-start_squangling ()
-{
- /* This function is obsoleted by the new ABI. */
- my_friendly_assert (!flag_new_abi, 200005222);
-
- if (flag_do_squangling)
- {
- nofold = 0;
- maxbtype = 0;
- maxktype = 0;
- VARRAY_TREE_INIT (btypelist, 50, "btypelist");
- VARRAY_TREE_INIT (ktypelist, 50, "ktypelist");
- }
-}
-
-static inline void
-end_squangling ()
-{
- if (flag_do_squangling)
- {
- VARRAY_FREE (ktypelist);
- VARRAY_FREE (btypelist);
- maxbtype = 0;
- maxktype = 0;
- }
-}
-
-/* Code to concatenate an asciified integer to a string. */
-
-static inline void
-icat (i)
- HOST_WIDE_INT i;
-{
- unsigned HOST_WIDE_INT ui;
-
- /* Handle this case first, to go really quickly. For many common values,
- the result of ui/10 below is 1. */
- if (i == 1)
- {
- OB_PUTC ('1');
- return;
- }
-
- if (i >= 0)
- ui = i;
- else
- {
- OB_PUTC ('m');
- ui = -i;
- }
-
- if (ui >= 10)
- icat (ui / 10);
-
- OB_PUTC ('0' + (ui % 10));
-}
-
-static void
-dicat (lo, hi)
- HOST_WIDE_INT lo, hi;
-{
- unsigned HOST_WIDE_INT ulo, uhi, qlo, qhi;
-
- if (hi >= 0)
- {
- uhi = hi;
- ulo = lo;
- }
- else
- {
- uhi = (lo == 0 ? -hi : -hi-1);
- ulo = -lo;
- }
- if (uhi == 0
- && ulo < ((unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT - 1)))
- {
- icat (ulo);
- return;
- }
- /* Divide 2^HOST_WIDE_INT*uhi+ulo by 10. */
- qhi = uhi / 10;
- uhi = uhi % 10;
- qlo = uhi * (((unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT - 1)) / 5);
- qlo += ulo / 10;
- ulo = ulo % 10;
- ulo += uhi * (((unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT - 1)) % 5)
- * 2;
- qlo += ulo / 10;
- ulo = ulo % 10;
- /* Quotient is 2^HOST_WIDE_INT*qhi+qlo, remainder is ulo. */
- dicat (qlo, qhi);
- OB_PUTC ('0' + ulo);
-}
-
-/* Returns the index of TYPE in the typevec, or -1 if it's not there. */
-
-static inline int
-old_backref_index (type)
- tree type;
-{
- size_t tindex;
-
- if (! is_back_referenceable_type (type))
- return -1;
-
- /* The entry for this parm is at maxtype-1, so don't look there for
- something to repeat. */
- for (tindex = 0; tindex < maxtype - 1; ++tindex)
- if (same_type_p (VARRAY_TREE (typevec, tindex), type))
- break;
-
- if (tindex == maxtype - 1)
- return -1;
-
- return tindex;
-}
-
-/* Old mangling style: If TYPE has already been used in the parameter list,
- emit a backward reference and return non-zero; otherwise, return 0.
-
- NREPEATS is the number of repeats we've recorded of this type, or 0 if
- this is the first time we've seen it and we're just looking to see if
- it had been used before. */
-
-static inline int
-flush_repeats (nrepeats, type)
- int nrepeats;
- tree type;
-{
- int tindex = old_backref_index (type);
-
- if (tindex == -1)
- {
- my_friendly_assert (nrepeats == 0, 990316);
- return 0;
- }
-
- if (nrepeats > 1)
- {
- OB_PUTC ('N');
- icat (nrepeats);
- if (nrepeats > 9)
- OB_PUTC ('_');
- }
- else
- OB_PUTC ('T');
- icat (tindex);
- if (tindex > 9)
- OB_PUTC ('_');
-
- return 1;
-}
-
-/* Returns nonzero iff this is a type to which we will want to make
- back-references (using the `B' code). */
-
-static int
-is_back_referenceable_type (type)
- tree type;
-{
- /* For some reason, the Java folks don't want back refs on these. */
- if (TYPE_FOR_JAVA (type))
- return 0;
-
- switch (TREE_CODE (type))
- {
- case BOOLEAN_TYPE:
- if (!flag_do_squangling)
- /* Even though the mangling of this is just `b', we did
- historically generate back-references for it. */
- return 1;
- /* Fall through. */
-
- case INTEGER_TYPE:
- case REAL_TYPE:
- case VOID_TYPE:
- /* These types have single-character manglings, so there's no
- point in generating back-references. */
- return 0;
-
- case TEMPLATE_TYPE_PARM:
- /* It would be a bit complex to demangle signatures correctly if
- we generated back-references to these, and the manglings of
- type parameters are short. */
- return 0;
-
- default:
- return 1;
- }
-}
-
-/* Issue the squangling code indicating NREPEATS repetitions of TYPE,
- which was the last parameter type output. */
-
-static void
-issue_nrepeats (nrepeats, type)
- int nrepeats;
- tree type;
-{
- if (nrepeats == 1 && !is_back_referenceable_type (type))
- /* For types whose manglings are short, don't bother using the
- repetition code if there's only one repetition, since the
- repetition code will be about as long as the ordinary mangling. */
- build_mangled_name_for_type (type);
- else
- {
- OB_PUTC ('n');
- icat (nrepeats);
- if (nrepeats > 9)
- OB_PUTC ('_');
- }
-}
-
-/* Check to see if a tree node has been entered into the Kcode typelist.
- If not, add it. Returns -1 if it isn't found, otherwise returns the
- index. */
-
-static int
-check_ktype (node, add)
- tree node;
- int add;
-{
- size_t x;
- tree localnode = node;
-
- if (ktypelist == NULL)
- return -1;
-
- if (TREE_CODE (node) == TYPE_DECL)
- localnode = TREE_TYPE (node);
-
- for (x = 0; x < maxktype; x++)
- {
- if (same_type_p (localnode, VARRAY_TREE (ktypelist, x)))
- return x;
- }
- /* Didn't find it, so add it here. */
- if (add)
- {
- if (VARRAY_SIZE (ktypelist) <= maxktype)
- VARRAY_GROW (ktypelist,
- VARRAY_SIZE (ktypelist) * 3 / 2);
- VARRAY_TREE (ktypelist, maxktype) = localnode;
- maxktype++;
- }
- return -1;
-}
-
-
-static inline int
-issue_ktype (decl)
- tree decl;
-{
- int kindex;
- kindex = check_ktype (decl, FALSE);
- if (kindex != -1)
- {
- OB_PUTC ('K');
- icat (kindex);
- if (kindex > 9)
- OB_PUTC ('_');
- return TRUE;
- }
- return FALSE;
-}
-
-/* Build a representation for DECL, which may be an entity not at
- global scope. If so, a marker indicating that the name is
- qualified has already been output, but the qualifying context has
- not. */
-
-static void
-build_overload_nested_name (decl)
- tree decl;
-{
- tree context;
-
- if (ktypelist && issue_ktype (decl))
- return;
-
- if (decl == global_namespace)
- return;
-
- context = CP_DECL_CONTEXT (decl);
-
- /* try to issue a K type, and if we can't continue the normal path */
- if (!(ktypelist && issue_ktype (context)))
- {
- /* For a template type parameter, we want to output an 'Xn'
- rather than 'T' or some such. */
- if (TREE_CODE (context) == TEMPLATE_TYPE_PARM
- || TREE_CODE (context) == TEMPLATE_TEMPLATE_PARM
- || TREE_CODE (context) == BOUND_TEMPLATE_TEMPLATE_PARM)
- build_mangled_name_for_type (context);
- else
- {
- if (TYPE_P (context))
- context = TYPE_NAME (context);
- build_overload_nested_name (context);
- }
- }
-
- if (TREE_CODE (decl) == FUNCTION_DECL)
- {
- static int static_labelno;
-
- tree name = DECL_ASSEMBLER_NAME (decl);
- char *label;
-
- ASM_FORMAT_PRIVATE_NAME (label, IDENTIFIER_POINTER (name), static_labelno);
- static_labelno++;
-
- if (numeric_output_need_bar)
- OB_PUTC ('_');
- icat (strlen (label));
- OB_PUTCP (label);
- numeric_output_need_bar = 1;
- }
- else if (TREE_CODE (decl) == NAMESPACE_DECL)
- build_overload_identifier (DECL_NAME (decl));
- else /* TYPE_DECL */
- build_overload_identifier (decl);
-}
-
-/* Output the decimal representation of I. If I > 9, the decimal
- representation is preceeded and followed by an underscore. */
-
-static void
-build_underscore_int (i)
- int i;
-{
- if (i > 9)
- OB_PUTC ('_');
- icat (i);
- if (i > 9)
- OB_PUTC ('_');
-}
-
-static void
-build_overload_scope_ref (value)
- tree value;
-{
- OB_PUTC2 ('Q', '2');
- numeric_output_need_bar = 0;
- build_mangled_name_for_type (TREE_OPERAND (value, 0));
- build_overload_identifier (TREE_OPERAND (value, 1));
-}
-
-/* VALUE is a complex expression. Produce an appropriate mangling.
- (We are forced to mangle complex expressions when dealing with
- templates, and an expression involving template parameters appears
- in the type of a function parameter.) */
-
-static void
-mangle_expression (value)
- tree value;
-{
- if (TREE_CODE (value) == SCOPE_REF)
- {
- build_overload_scope_ref (value);
- return;
- }
-
- OB_PUTC ('E');
- numeric_output_need_bar = 0;
-
- if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (value))))
- {
- int i;
- int operands = TREE_CODE_LENGTH (TREE_CODE (value));
- const char *name;
-
- name = operator_name_info[TREE_CODE (value)].mangled_name;
- if (name == NULL)
- /* On some erroneous inputs, we can get here with VALUE a
- LOOKUP_EXPR. We must survive this routine in order to issue
- a sensible error message, so we fall through to the case
- below. */
- goto bad_value;
-
- for (i = 0; i < operands; ++i)
- {
- tree operand;
- enum tree_code tc;
-
- /* We just outputted either the `E' or the name of the
- operator. */
- numeric_output_need_bar = 0;
-
- if (i != 0)
- /* Skip the leading underscores. */
- OB_PUTCP (name + 2);
-
- operand = TREE_OPERAND (value, i);
- tc = TREE_CODE (operand);
-
- if (TREE_CODE_CLASS (tc) == 't')
- /* We can get here with sizeof, e.g.:
-
- template <class T> void f(A<sizeof(T)>); */
- build_mangled_name_for_type (operand);
- else
- build_overload_value (TREE_TYPE (operand),
- operand,
- mf_maybe_uninstantiated);
- }
- }
- else
- {
- /* We don't ever want this output, but it's
- inconvenient not to be able to build the string.
- This should cause assembler errors we'll notice. */
-
- static int n;
- bad_value:
- sprintf (digit_buffer, " *%d", n++);
- OB_PUTCP (digit_buffer);
- }
-
- OB_PUTC ('W');
- numeric_output_need_bar = 0;
-}
-
-/* Encoding for an INTEGER_CST value. */
-
-static void
-build_overload_int (value, flags)
- tree value;
- mangling_flags flags;
-{
- int multiple_words_p = 0;
- int multiple_digits_p = 0;
-
- if ((flags & mf_maybe_uninstantiated) && TREE_CODE (value) != INTEGER_CST)
- {
- mangle_expression (value);
- return;
- }
-
- /* Unless we were looking at an uninstantiated template, integers
- should always be represented by constants. */
- my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243);
-
- /* If value doesn't fit in a single HOST_WIDE_INT, we must use a
- special output routine that can deal with this. */
- if (! host_integerp (value, 0))
- {
- multiple_words_p = 1;
- /* And there is certainly going to be more than one digit. */
- multiple_digits_p = 1;
- }
- else
- multiple_digits_p = ((HOST_WIDE_INT) TREE_INT_CST_LOW (value) > 9
- || (HOST_WIDE_INT) TREE_INT_CST_LOW (value) < -9);
-
- /* If necessary, add a leading underscore. */
- if (multiple_digits_p && (flags & mf_use_underscores_around_value))
- OB_PUTC ('_');
-
- /* Output the number itself. */
- if (multiple_words_p)
- dicat (TREE_INT_CST_LOW (value), TREE_INT_CST_HIGH (value));
- else
- icat (TREE_INT_CST_LOW (value));
-
- if (flags & mf_use_underscores_around_value)
- {
- if (multiple_digits_p)
- OB_PUTC ('_');
- /* Whether or not there were multiple digits, we don't need an
- underscore. We've either terminated the number with an
- underscore, or else it only had one digit. */
- numeric_output_need_bar = 0;
- }
- else
- /* We just output a numeric value. */
- numeric_output_need_bar = 1;
-}
-
-
-/* Output S followed by a representation of the TEMPLATE_PARM_INDEX
- supplied in INDEX. */
-
-static void
-build_mangled_template_parm_index (s, index)
- const char *s;
- tree index;
-{
- OB_PUTCP (s);
- build_underscore_int (TEMPLATE_PARM_IDX (index));
- /* We use the LEVEL, not the ORIG_LEVEL, because the mangling is a
- representation of the function from the point of view of its
- type. */
- build_underscore_int (TEMPLATE_PARM_LEVEL (index));
-}
-
-
-/* Mangling for C99 integer types (and Cygnus extensions for 128-bit
- and other types) is based on the letter "I" followed by the hex
- representations of the bitsize for the type in question. For
- encodings that result in larger than two digits, a leading and
- trailing underscore is added.
-
- Thus:
- int1_t = 001 = I01
- int8_t = 008 = I08
- int16_t = 010 = I10
- int24_t = 018 = I18
- int32_t = 020 = I20
- int64_t = 040 = I40
- int80_t = 050 = I50
- int128_t = 080 = I80
- int256_t = 100 = I_100_
- int512_t = 200 = I_200_
-
- Given an integer in decimal format, mangle according to this scheme. */
-
-#if HOST_BITS_PER_WIDE_INT >= 64
-static void
-build_mangled_C99_name (bits)
- int bits;
-{
- char mangled[10] = "";
-
- if (bits > 255)
- sprintf (mangled, "I_%x_", bits);
- else
- sprintf (mangled, "I%.2x", bits);
-
- OB_PUTCP (mangled);
-}
-#endif
-
-static void
-build_overload_value (type, value, flags)
- tree type, value;
- mangling_flags flags;
-{
- my_friendly_assert (TYPE_P (type), 0);
-
- while (TREE_CODE (value) == NON_LVALUE_EXPR
- || TREE_CODE (value) == NOP_EXPR)
- value = TREE_OPERAND (value, 0);
-
- if (numeric_output_need_bar)
- {
- OB_PUTC ('_');
- numeric_output_need_bar = 0;
- }
-
- if (TREE_CODE (value) == TEMPLATE_PARM_INDEX)
- {
- build_mangled_template_parm_index ("Y", value);
- return;
- }
-
- if (TYPE_PTRMEM_P (type))
- {
- if (TREE_CODE (value) != PTRMEM_CST)
- /* We should have already rejected this pointer to member,
- since it is not a constant. */
- my_friendly_abort (0);
-
- /* Get the actual FIELD_DECL. */
- value = PTRMEM_CST_MEMBER (value);
- my_friendly_assert (TREE_CODE (value) == FIELD_DECL, 0);
-
- /* Output the name of the field. */
- build_overload_identifier (DECL_NAME (value));
- return;
- }
- else if (INTEGRAL_TYPE_P (type))
- {
- build_overload_int (value, flags);
- return;
- }
-
- /* The only case where we use the extra underscores here is when
- forming the mangling for an integral non-type template argument.
- If that didn't happen, stop now. */
- flags &= ~mf_use_underscores_around_value;
-
- switch (TREE_CODE (type))
- {
- case REAL_TYPE:
- {
- REAL_VALUE_TYPE val;
- char *bufp = digit_buffer;
-
- /* We must handle non-constants in templates. */
- if (TREE_CODE (value) != REAL_CST)
- {
- mangle_expression (value);
- break;
- }
-
- val = TREE_REAL_CST (value);
- if (REAL_VALUE_ISNAN (val))
- {
- sprintf (bufp, "NaN");
- }
- else
- {
- if (REAL_VALUE_NEGATIVE (val))
- {
- val = REAL_VALUE_NEGATE (val);
- *bufp++ = 'm';
- }
- if (REAL_VALUE_ISINF (val))
- {
- sprintf (bufp, "Infinity");
- }
- else
- {
- REAL_VALUE_TO_DECIMAL (val, "%.20e", bufp);
- bufp = (char *) strchr (bufp, 'e');
- if (!bufp)
- strcat (digit_buffer, "e0");
- else
- {
- char *p;
- bufp++;
- if (*bufp == '-')
- {
- *bufp++ = 'm';
- }
- p = bufp;
- if (*p == '+')
- p++;
- while (*p == '0')
- p++;
- if (*p == 0)
- {
- *bufp++ = '0';
- *bufp = 0;
- }
- else if (p != bufp)
- {
- while (*p)
- *bufp++ = *p++;
- *bufp = 0;
- }
- }
-#ifdef NO_DOT_IN_LABEL
- bufp = (char *) strchr (bufp, '.');
- if (bufp)
- *bufp = '_';
-#endif
- }
- }
- OB_PUTCP (digit_buffer);
- numeric_output_need_bar = 1;
- return;
- }
- case POINTER_TYPE:
- if (TREE_CODE (value) == INTEGER_CST)
- {
- build_overload_int (value, flags);
- return;
- }
- else if (TREE_CODE (value) == TEMPLATE_PARM_INDEX)
- {
- build_mangled_template_parm_index ("", value);
- numeric_output_need_bar = 1;
- return;
- }
-
- value = TREE_OPERAND (value, 0);
-
- /* Fall through. */
-
- case REFERENCE_TYPE:
- if (TREE_CODE (value) == ADDR_EXPR)
- value = TREE_OPERAND (value, 0);
-
- if (TREE_CODE (value) == VAR_DECL)
- {
- my_friendly_assert (DECL_NAME (value) != 0, 245);
- build_overload_identifier (DECL_ASSEMBLER_NAME (value));
- return;
- }
- else if (TREE_CODE (value) == FUNCTION_DECL)
- {
- my_friendly_assert (DECL_NAME (value) != 0, 246);
- build_overload_identifier (DECL_ASSEMBLER_NAME (value));
- return;
- }
- else if (TREE_CODE (value) == SCOPE_REF)
- build_overload_scope_ref (value);
- else
- my_friendly_abort (71);
- break; /* not really needed */
-
- case RECORD_TYPE:
- {
- tree delta;
- tree idx;
- tree pfn;
- tree delta2;
- tree fn;
-
- my_friendly_assert (TYPE_PTRMEMFUNC_P (type), 0);
-
- /* We'll get a ADDR_EXPR of a SCOPE_REF here if we're
- mangling, an instantiation of something like:
-
- template <class T, void (T::*fp)()> class C {};
- template <class T> C<T, &T::f> x();
-
- We mangle the return type of the function, and that
- contains template parameters. */
- if (TREE_CODE (value) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (value, 0)) == SCOPE_REF)
- {
- build_overload_scope_ref (TREE_OPERAND (value, 0));
- break;
- }
-
- my_friendly_assert (TREE_CODE (value) == PTRMEM_CST, 0);
-
- expand_ptrmemfunc_cst (value, &delta, &idx, &pfn, &delta2);
- fn = PTRMEM_CST_MEMBER (value);
- build_overload_int (delta, flags);
- OB_PUTC ('_');
- if (!flag_new_abi)
- {
- build_overload_int (idx, flags);
- OB_PUTC ('_');
- }
- else if (DECL_VIRTUAL_P (fn))
- {
- build_overload_int (DECL_VINDEX (fn), flags);
- OB_PUTC ('_');
- }
-
- if (!DECL_VIRTUAL_P (fn))
- {
- numeric_output_need_bar = 0;
- build_overload_identifier (DECL_ASSEMBLER_NAME (fn));
- }
- else if (!flag_new_abi)
- {
- OB_PUTC ('i');
- build_overload_int (delta2, flags);
- }
- }
- break;
-
- default:
- sorry ("conversion of %s as template parameter",
- tree_code_name [(int) TREE_CODE (type)]);
- my_friendly_abort (72);
- }
-}
-
-
-/* Add encodings for the declaration of template template parameters.
- PARMLIST must be a TREE_VEC. */
-
-static void
-build_template_template_parm_names (parmlist)
- tree parmlist;
-{
- int i, nparms;
-
- my_friendly_assert (TREE_CODE (parmlist) == TREE_VEC, 990228);
- nparms = TREE_VEC_LENGTH (parmlist);
- icat (nparms);
- for (i = 0; i < nparms; i++)
- {
- tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i));
- if (TREE_CODE (parm) == TYPE_DECL)
- {
- /* This parameter is a type. */
- OB_PUTC ('Z');
- }
- else if (TREE_CODE (parm) == TEMPLATE_DECL)
- {
- /* This parameter is a template. */
- OB_PUTC ('z');
- build_template_template_parm_names (DECL_INNERMOST_TEMPLATE_PARMS (parm));
- }
- else
- /* It's a PARM_DECL. */
- build_mangled_name_for_type (TREE_TYPE (parm));
- }
-}
-
-
-/* Add encodings for the vector of template parameters in PARMLIST,
- given the vector of arguments to be substituted in ARGLIST. */
-
-static void
-build_template_parm_names (parmlist, arglist)
- tree parmlist;
- tree arglist;
-{
- int i, nparms;
- tree inner_args = INNERMOST_TEMPLATE_ARGS (arglist);
-
- nparms = TREE_VEC_LENGTH (parmlist);
- icat (nparms);
- for (i = 0; i < nparms; i++)
- {
- tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i));
- tree arg = TREE_VEC_ELT (inner_args, i);
- if (TREE_CODE (parm) == TYPE_DECL)
- {
- /* This parameter is a type. */
- OB_PUTC ('Z');
- build_mangled_name_for_type (arg);
- }
- else if (TREE_CODE (parm) == TEMPLATE_DECL)
- {
- /* This parameter is a template. */
- if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
- /* Output parameter declaration, argument index and level. */
- build_mangled_name_for_type (arg);
- else
- {
- /* A TEMPLATE_DECL node, output the parameter declaration
- and template name */
-
- OB_PUTC ('z');
- build_template_template_parm_names
- (DECL_INNERMOST_TEMPLATE_PARMS (parm));
- icat (IDENTIFIER_LENGTH (DECL_NAME (arg)));
- OB_PUTID (DECL_NAME (arg));
- }
- }
- else
- {
- parm = tsubst (parm, inner_args, /*complain=*/1, NULL_TREE);
- /* It's a PARM_DECL. */
- build_mangled_name_for_type (TREE_TYPE (parm));
- build_overload_value (TREE_TYPE (parm), arg,
- ((mf_maybe_uninstantiated
- * uses_template_parms (arglist))
- | mf_use_underscores_around_value));
- }
- }
- }
-
-/* Output the representation for NAME, which is either a TYPE_DECL or
- an IDENTIFIER. */
-
-static void
-build_overload_identifier (name)
- tree name;
-{
- if (TREE_CODE (name) == TYPE_DECL
- && CLASS_TYPE_P (TREE_TYPE (name))
- && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name))
- && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name)))
- || (TREE_CODE (CP_DECL_CONTEXT (CLASSTYPE_TI_TEMPLATE
- (TREE_TYPE (name))))
- == FUNCTION_DECL)))
- {
- /* NAME is the TYPE_DECL for a template specialization. */
- tree template, parmlist, arglist, tname;
- template = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name));
- arglist = CLASSTYPE_TI_ARGS (TREE_TYPE (name));
- tname = DECL_NAME (template);
- parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
- OB_PUTC ('t');
- icat (IDENTIFIER_LENGTH (tname));
- OB_PUTID (tname);
- build_template_parm_names (parmlist, arglist);
- }
- else
- {
- if (TREE_CODE (name) == TYPE_DECL)
- name = DECL_NAME (name);
- if (numeric_output_need_bar)
- {
- OB_PUTC ('_');
- numeric_output_need_bar = 0;
- }
- icat (IDENTIFIER_LENGTH (name));
- OB_PUTID (name);
- }
-}
-
-/* Given DECL, either a class TYPE, TYPE_DECL or FUNCTION_DECL, produce
- the mangling for it. Used by build_mangled_name and build_static_name. */
-
-static void
-build_qualified_name (decl)
- tree decl;
-{
- tree context;
- int i = 1;
-
- if (TYPE_P (decl))
- decl = TYPE_NAME (decl);
-
- /* If DECL_ASSEMBLER_NAME has been set properly, use it. */
- if (TREE_CODE (decl) == TYPE_DECL
- && DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl) && !flag_do_squangling)
- {
- tree id = DECL_ASSEMBLER_NAME (decl);
- OB_PUTID (id);
- if (ISDIGIT (IDENTIFIER_POINTER (id) [IDENTIFIER_LENGTH (id) - 1]))
- numeric_output_need_bar = 1;
- return;
- }
-
- context = decl;
- /* If we can't find a Ktype, do it the hard way. */
- if (check_ktype (context, FALSE) == -1)
- {
- /* Count type and namespace scopes. */
- while (1)
- {
- context = CP_DECL_CONTEXT (context);
- if (context == global_namespace)
- break;
- i += 1;
- if (check_ktype (context, FALSE) != -1)
- /* Found one! */
- break;
- if (TYPE_P (context))
- context = TYPE_NAME (context);
- }
- }
-
- if (i > 1)
- {
- OB_PUTC ('Q');
- build_underscore_int (i);
- numeric_output_need_bar = 0;
- }
- build_overload_nested_name (decl);
-}
-
-/* Output the mangled representation for TYPE. If EXTRA_GCODE is
- non-zero, mangled names for structure/union types are intentionally
- mangled differently from the method described in the ARM. */
-
-static void
-build_mangled_name_for_type_with_Gcode (type, extra_Gcode)
- tree type;
- int extra_Gcode;
-{
- if (TYPE_PTRMEMFUNC_P (type))
- type = TYPE_PTRMEMFUNC_FN_TYPE (type);
- process_modifiers (type);
- process_overload_item (type, extra_Gcode);
-}
-
-/* Like build_mangled_name_for_type_with_Gcode, but never outputs the
- `G'. */
-
-static void
-build_mangled_name_for_type (type)
- tree type;
-{
- build_mangled_name_for_type_with_Gcode (type, 0);
-}
-
-/* Given a list of parameters in PARMTYPES, create an unambiguous
- overload string. Should distinguish any type that C (or C++) can
- distinguish. I.e., pointers to functions are treated correctly.
-
- Caller must deal with whether a final `e' goes on the end or not.
-
- Any default conversions must take place before this function
- is called.
-
- BEGIN and END control initialization and finalization of the
- obstack where we build the string. */
-
-char *
-build_overload_name (parmtypes, begin, end)
- tree parmtypes;
- int begin, end;
-{
- char *ret;
-
- /* This function is obsoleted by the new ABI. */
- my_friendly_assert (!flag_new_abi, 200005221);
-
- start_squangling ();
- ret = build_mangled_name (parmtypes, begin, end);
- end_squangling ();
- return ret ;
-}
-
-/* Output the mangled representation for PARMTYPES. If PARMTYPES is a
- TREE_LIST, then it is a list of parameter types. Otherwise,
- PARMTYPES must be a single type. */
-
-static char *
-build_mangled_name (parmtypes, begin, end)
- tree parmtypes;
- int begin, end;
-{
- /* This function is obsoleted by the new ABI. */
- my_friendly_assert (!flag_new_abi, 200004105);
-
- if (begin)
- OB_INIT ();
-
- if (TREE_CODE (parmtypes) != TREE_LIST)
- /* There is only one type. */
- build_mangled_name_for_type (parmtypes);
- else
- {
- /* There are several types in a parameter list. */
- int nrepeats = 0;
- int old_style_repeats = !flag_do_squangling && !nofold && typevec;
- tree last_type = NULL_TREE;
-
- for (; parmtypes && parmtypes != void_list_node;
- parmtypes = TREE_CHAIN (parmtypes))
- {
- /* We used to call canonical_type_variant here, but that isn't
- good enough; it doesn't handle pointers to typedef types. So
- we can't just set TREE_USED to say we've seen a type already;
- we have to check each of the earlier types with same_type_p. */
- tree parmtype = TREE_VALUE (parmtypes);
-
- if (old_style_repeats)
- {
- /* Every argument gets counted. */
- my_friendly_assert (maxtype < VARRAY_SIZE (typevec), 387);
- VARRAY_TREE (typevec, maxtype) = parmtype;
- maxtype++;
- }
-
- if (last_type && same_type_p (parmtype, last_type))
- {
- if (flag_do_squangling
- || (old_style_repeats
- && is_back_referenceable_type (parmtype)))
- {
- /* The next type is the same as this one. Keep
- track of the repetition, and output the repeat
- count later. */
- nrepeats++;
- continue;
- }
- }
- else if (nrepeats != 0)
- {
- /* Indicate how many times the previous parameter was
- repeated. */
- if (old_style_repeats)
- flush_repeats (nrepeats, last_type);
- else
- issue_nrepeats (nrepeats, last_type);
- nrepeats = 0;
- }
-
- /* Insead of protecting flush_repeats() against
- error_mark_node, we can do it here. Since we wouldn't
- add anything for an ERROR_MARK anyway, it's ok to skip
- the mangling for this type. */
- if (old_style_repeats && parmtype == error_mark_node)
- {
- last_type = NULL_TREE;
- continue;
- }
-
- last_type = parmtype;
-
- /* Note that for bug-compatibility with 2.7.2, we can't build up
- repeats of types other than the most recent one. So we call
- flush_repeats every round, if we get this far. */
- if (old_style_repeats && flush_repeats (0, parmtype))
- continue;
-
- /* Output the PARMTYPE. */
- build_mangled_name_for_type_with_Gcode (parmtype, 1);
- }
-
- /* Output the repeat count for the last parameter, if
- necessary. */
- if (nrepeats != 0)
- {
- if (old_style_repeats)
- flush_repeats (nrepeats, last_type);
- else
- issue_nrepeats (nrepeats, last_type);
- nrepeats = 0;
- }
-
- if (!parmtypes)
- /* The parameter list ends in an ellipsis. */
- OB_PUTC ('e');
- }
-
- if (end)
- OB_FINISH ();
- return (char *) obstack_base (&scratch_obstack);
-}
-
-/* Emit modifiers such as constant, read-only, and volatile. */
-
-static void
-process_modifiers (parmtype)
- tree parmtype;
-{
- /* Note that here we do not use CP_TYPE_CONST_P and friends because
- we describe types recursively; we will get the `const' in
- `const int ()[10]' when processing the `const int' part. */
- if (TYPE_READONLY (parmtype))
- OB_PUTC ('C');
- if (TREE_CODE (parmtype) == INTEGER_TYPE
- && ! same_type_p (parmtype, char_type_node)
- && ! same_type_p (parmtype, wchar_type_node)
- && (TYPE_MAIN_VARIANT (parmtype)
- == unsigned_type (TYPE_MAIN_VARIANT (parmtype)))
- && ! TYPE_FOR_JAVA (parmtype))
- OB_PUTC ('U');
- if (TYPE_VOLATILE (parmtype))
- OB_PUTC ('V');
- /* It would be better to use `R' for `restrict', but that's already
- used for reference types. And `r' is used for `long double'. */
- if (TYPE_RESTRICT (parmtype))
- OB_PUTC ('u');
-}
-
-/* Check to see if TYPE has been entered into the Bcode typelist. If
- so, return 1 and emit a backreference to TYPE. Otherwise, add TYPE
- to the list of back-referenceable types and return 0. */
-
-static int
-check_btype (type)
- tree type;
-{
- size_t x;
-
- if (btypelist == NULL)
- return 0;
-
- if (!is_back_referenceable_type (type))
- return 0;
-
- for (x = 0; x < maxbtype; x++)
- if (same_type_p (type, VARRAY_TREE (btypelist, x)))
- {
- OB_PUTC ('B');
- icat (x);
- if (x > 9)
- OB_PUTC ('_');
- return 1 ;
- }
-
- if (VARRAY_SIZE (btypelist) <= maxbtype)
- /* Enlarge the table. */
- VARRAY_GROW (btypelist,
- VARRAY_SIZE (btypelist) * 3 / 2);
-
- /* Register the TYPE. */
- VARRAY_TREE (btypelist, maxbtype) = type;
- maxbtype++;
-
- return 0;
-}
-
-/* Emit the correct code for various node types. */
+/* Called once to initialize method.c. */
-static void
-process_overload_item (parmtype, extra_Gcode)
- tree parmtype;
- int extra_Gcode;
+void
+init_method ()
{
- tree tmp;
-
- numeric_output_need_bar = 0;
-
- /* Our caller should have already handed any qualifiers, so pull out the
- TYPE_MAIN_VARIANT to avoid typedef confusion. Except we can't do that
- for arrays, because they are transparent to qualifiers. Sigh. */
- if (TREE_CODE (parmtype) == ARRAY_TYPE)
- parmtype = canonical_type_variant (parmtype);
- else
- parmtype = TYPE_MAIN_VARIANT (parmtype);
-
- /* These tree types are considered modifiers for B code squangling,
- and therefore should not get entries in the Btypelist. They are,
- however, repeatable types. */
-
- switch (TREE_CODE (parmtype))
- {
- case REFERENCE_TYPE:
- OB_PUTC ('R');
- goto more;
-
- case ARRAY_TYPE:
- {
- OB_PUTC ('A');
- if (TYPE_DOMAIN (parmtype) == NULL_TREE)
- OB_PUTC ('_');
- else
- {
- tree length = array_type_nelts (parmtype);
- if (TREE_CODE (length) != INTEGER_CST || flag_do_squangling)
- {
- if (TREE_CODE (length) == MINUS_EXPR
- && TREE_OPERAND (length, 1) == integer_one_node)
- length = TREE_OPERAND (length, 0);
- else
- length = fold (build (PLUS_EXPR, TREE_TYPE (length),
- length, integer_one_node));
- STRIP_NOPS (length);
- }
- build_overload_value (sizetype, length, 1);
- }
- if (numeric_output_need_bar && ! flag_do_squangling)
- OB_PUTC ('_');
- goto more;
- }
-
- case POINTER_TYPE:
- OB_PUTC ('P');
- more:
- build_mangled_name_for_type (TREE_TYPE (parmtype));
- return;
- break;
-
- default:
- break;
- }
-
- if (flag_do_squangling && check_btype (parmtype))
- /* If PARMTYPE is already in the list of back-referenceable types,
- then check_btype will output the appropriate reference, and
- there's nothing more to do. */
- return;
-
- switch (TREE_CODE (parmtype))
- {
- case OFFSET_TYPE:
- OB_PUTC ('O');
- build_mangled_name_for_type (TYPE_OFFSET_BASETYPE (parmtype));
- OB_PUTC ('_');
- build_mangled_name_for_type (TREE_TYPE (parmtype));
- break;
-
- case FUNCTION_TYPE:
- case METHOD_TYPE:
- {
- tree parms = TYPE_ARG_TYPES (parmtype);
-
- /* Rather than implementing a reentrant TYPEVEC, we turn off
- repeat codes here, unless we're squangling. Squangling
- doesn't make use of the TYPEVEC, so there's no reentrancy
- problem. */
- int old_nofold = nofold;
- if (!flag_do_squangling)
- nofold = 1;
-
- if (TREE_CODE (parmtype) == METHOD_TYPE)
- {
- /* Mark this as a method. */
- OB_PUTC ('M');
- /* Output the class of which this method is a member. */
- build_mangled_name_for_type (TYPE_METHOD_BASETYPE (parmtype));
- /* Output any qualifiers for the `this' parameter. */
- process_modifiers (TREE_TYPE (TREE_VALUE (parms)));
- }
-
- /* Output the parameter types. */
- OB_PUTC ('F');
- if (parms == NULL_TREE)
- OB_PUTC ('e');
- else if (parms == void_list_node)
- OB_PUTC ('v');
- else
- build_mangled_name (parms, 0, 0);
-
- /* Output the return type. */
- OB_PUTC ('_');
- build_mangled_name_for_type (TREE_TYPE (parmtype));
-
- nofold = old_nofold;
- break;
- }
-
- case INTEGER_TYPE:
- iagain:
- if (parmtype == integer_type_node
- || parmtype == unsigned_type_node
- || parmtype == java_int_type_node)
- OB_PUTC ('i');
- else if (parmtype == long_integer_type_node
- || parmtype == long_unsigned_type_node)
- OB_PUTC ('l');
- else if (parmtype == short_integer_type_node
- || parmtype == short_unsigned_type_node
- || parmtype == java_short_type_node)
- OB_PUTC ('s');
- else if (parmtype == signed_char_type_node)
- {
- OB_PUTC ('S');
- OB_PUTC ('c');
- }
- else if (parmtype == char_type_node
- || parmtype == unsigned_char_type_node
- || parmtype == java_byte_type_node)
- OB_PUTC ('c');
- else if (parmtype == wchar_type_node
- || parmtype == java_char_type_node)
- OB_PUTC ('w');
- else if (parmtype == long_long_integer_type_node
- || parmtype == long_long_unsigned_type_node
- || parmtype == java_long_type_node)
- OB_PUTC ('x');
- else if (parmtype == java_boolean_type_node)
- OB_PUTC ('b');
- /* Handle intSI_type_node and such like their C++ equivalents. */
- else if (tmp = type_for_mode (TYPE_MODE (parmtype),
- TREE_UNSIGNED (parmtype)),
- parmtype != tmp)
- {
- parmtype = tmp;
- goto iagain;
- }
-#if HOST_BITS_PER_WIDE_INT >= 64
- else
- {
- int bits = TREE_INT_CST_LOW (TYPE_SIZE (parmtype));
- build_mangled_C99_name (bits);
- }
-#else
- else
- my_friendly_abort (73);
-#endif
- break;
-
- case BOOLEAN_TYPE:
- OB_PUTC ('b');
- break;
-
- case REAL_TYPE:
- if (parmtype == long_double_type_node)
- OB_PUTC ('r');
- else if (parmtype == double_type_node
- || parmtype == java_double_type_node)
- OB_PUTC ('d');
- else if (parmtype == float_type_node
- || parmtype == java_float_type_node)
- OB_PUTC ('f');
- else my_friendly_abort (74);
- break;
-
- case COMPLEX_TYPE:
- OB_PUTC ('J');
- build_mangled_name_for_type (TREE_TYPE (parmtype));
- break;
-
- case VECTOR_TYPE:
- OB_PUTC ('o');
- build_mangled_name_for_type (TREE_TYPE (parmtype));
- break;
-
- case VOID_TYPE:
- OB_PUTC ('v');
- break;
-
- case ERROR_MARK: /* not right, but nothing is anyway */
- break;
-
- /* have to do these */
- case UNION_TYPE:
- case RECORD_TYPE:
- {
- if (extra_Gcode)
- OB_PUTC ('G'); /* make it look incompatible with AT&T */
- /* drop through into next case */
- }
- case ENUMERAL_TYPE:
- {
- tree name = TYPE_NAME (parmtype);
-
- my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 248);
-
- build_qualified_name (name);
- break;
- }
-
- case UNKNOWN_TYPE:
- /* This will take some work. */
- OB_PUTC ('?');
- break;
-
- case BOUND_TEMPLATE_TEMPLATE_PARM:
- /* Find and output the original template parameter
- declaration. */
- build_mangled_template_parm_index ("tzX",
- TEMPLATE_TYPE_PARM_INDEX
- (parmtype));
- build_template_parm_names
- (DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (parmtype)),
- TYPE_TI_ARGS (parmtype));
- break;
-
- case TEMPLATE_TEMPLATE_PARM:
- build_mangled_template_parm_index ("ZzX",
- TEMPLATE_TYPE_PARM_INDEX
- (parmtype));
- build_template_template_parm_names
- (DECL_INNERMOST_TEMPLATE_PARMS (TYPE_STUB_DECL (parmtype)));
- break;
-
- case TEMPLATE_TYPE_PARM:
- build_mangled_template_parm_index ("X",
- TEMPLATE_TYPE_PARM_INDEX
- (parmtype));
- break;
-
- case TYPENAME_TYPE:
- /* When mangling the type of a function template whose
- declaration looks like:
-
- template <class T> void foo(typename T::U)
-
- we have to mangle these. */
- build_qualified_name (parmtype);
- break;
-
- default:
- my_friendly_abort (75);
- }
-
+ init_mangle ();
}
-/* Produce the mangling for a variable named NAME in CONTEXT, which can
- be either a class TYPE or a FUNCTION_DECL. */
-
-tree
-build_static_name (context, name)
- tree context, name;
-{
- /* This function is obsoleted by the new ABI. */
- my_friendly_assert (!flag_new_abi, 200004106);
-
- OB_INIT ();
- numeric_output_need_bar = 0;
- start_squangling ();
-#ifdef JOINER
- OB_PUTC ('_');
- build_qualified_name (context);
- OB_PUTC (JOINER);
-#else
- OB_PUTS ("__static_");
- build_qualified_name (context);
- OB_PUTC ('_');
-#endif
- OB_PUTID (name);
- OB_FINISH ();
- end_squangling ();
-
- return get_identifier ((char *)obstack_base (&scratch_obstack));
-}
\f
-/* FOR_METHOD should be 1 if the declaration in question is for a member
- of a class (including a static member) and 2 if the declaration is
- for a constructor. */
-tree
-build_decl_overload_real (decl, parms, ret_type, tparms, targs,
- for_method)
- tree decl;
- tree parms;
- tree ret_type;
- tree tparms;
- tree targs;
- int for_method;
-{
- const char *name;
- enum tree_code operator_code;
-
- /* This function is obsoleted by the new ABI. */
- my_friendly_assert (!flag_new_abi, 20000410);
-
- operator_code = DECL_OVERLOADED_OPERATOR_P (decl);
- if (!DECL_CONV_FN_P (decl) && operator_code)
- {
- /* member operators new and delete look like methods at this
- point. */
- if (! for_method && CP_DECL_CONTEXT (decl) == global_namespace
- && parms != NULL_TREE && TREE_CODE (parms) == TREE_LIST
- && TREE_CHAIN (parms) == void_list_node)
- switch (operator_code)
- {
- case DELETE_EXPR:
- return get_identifier ("__builtin_delete");
- case VEC_DELETE_EXPR:
- return get_identifier ("__builtin_vec_delete");
- case NEW_EXPR:
- return get_identifier ("__builtin_new");
- case VEC_NEW_EXPR:
- return get_identifier ("__builtin_vec_new");
- default:
- break;
- }
-
- if (DECL_ASSIGNMENT_OPERATOR_P (decl))
- name = assignment_operator_name_info[(int) operator_code].mangled_name;
- else
- name = operator_name_info[(int) operator_code].mangled_name;
- }
- else
- name = IDENTIFIER_POINTER (DECL_NAME (decl));
-
- start_squangling ();
- OB_INIT ();
- if (for_method != 2)
- OB_PUTCP (name);
- /* Otherwise, we can divine that this is a constructor,
- and figure out its name without any extra encoding. */
-
- OB_PUTC2 ('_', '_');
- numeric_output_need_bar = 0;
-
- if (tparms)
- {
- OB_PUTC ('H');
- build_template_parm_names (tparms, targs);
- OB_PUTC ('_');
- }
- else if (!for_method && CP_DECL_CONTEXT (decl) == global_namespace)
- OB_PUTC ('F');
-
- if (!for_method && CP_DECL_CONTEXT (decl) != global_namespace)
- /* qualify with namespace */
- build_qualified_name (CP_DECL_CONTEXT (decl));
-
- if (parms == NULL_TREE)
- OB_PUTC ('e');
- else if (parms == void_list_node)
- OB_PUTC ('v');
- else
- {
- if (!flag_do_squangling)
- {
- /* Allocate typevec array. */
- size_t typevec_size = list_length (parms);
- maxtype = 0;
- if (!for_method && CP_DECL_CONTEXT (decl) != global_namespace)
- /* The namespace of a global function needs one slot. */
- typevec_size++;
- VARRAY_TREE_INIT (typevec, typevec_size, "typevec");
- }
- nofold = 0;
-
- if (for_method)
- {
- tree this_type = TREE_TYPE (TREE_VALUE (parms));
-
- build_mangled_name_for_type (this_type);
-
- if (!flag_do_squangling)
- {
- my_friendly_assert (maxtype < VARRAY_SIZE (typevec), 387);
- VARRAY_TREE (typevec, maxtype) = this_type;
- maxtype++;
- }
-
- if (TREE_CHAIN (parms))
- build_mangled_name (TREE_CHAIN (parms), 0, 0);
- else
- OB_PUTC ('e');
- }
- else
- {
- /* the namespace qualifier for a global function
- will count as type */
- if (CP_DECL_CONTEXT (decl) != global_namespace
- && !flag_do_squangling)
- {
- my_friendly_assert (maxtype < VARRAY_SIZE (typevec), 387);
- VARRAY_TREE (typevec, maxtype) = CP_DECL_CONTEXT (decl);
- maxtype++;
- }
- build_mangled_name (parms, 0, 0);
- }
-
- if (!flag_do_squangling)
- /* Deallocate typevec array. */
- VARRAY_FREE (typevec);
- }
-
- if (ret_type != NULL_TREE && for_method != 2)
- {
- /* Add the return type. */
- OB_PUTC ('_');
- build_mangled_name_for_type (ret_type);
- }
-
- OB_FINISH ();
- end_squangling ();
- {
- tree n = get_identifier (obstack_base (&scratch_obstack));
- return n;
- }
-}
-
/* Set the mangled name (DECL_ASSEMBLER_NAME) for DECL. */
void
set_mangled_name_for_decl (decl)
tree decl;
{
- tree parm_types;
-
if (processing_template_decl)
/* There's no need to mangle the name of a template function. */
return;
- if (flag_new_abi)
- {
- DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
- return;
- }
-
- if (DECL_EXTERN_C_P (decl))
- {
- /* In extern "C" we have to mangle at least overloaded operators,
- because they contain characters invalid in assembler. */
- enum tree_code code = DECL_OVERLOADED_OPERATOR_P (decl);
- const char *name;
-
- if (code)
- {
- if (DECL_ASSIGNMENT_OPERATOR_P (decl))
- name = assignment_operator_name_info[(int) code].mangled_name;
- else
- name = operator_name_info[(int) code].mangled_name;
- DECL_ASSEMBLER_NAME (decl) = get_identifier (name);
- return;
- }
- }
-
- parm_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
-
- if (DECL_STATIC_FUNCTION_P (decl))
- parm_types =
- hash_tree_chain (build_pointer_type (DECL_CONTEXT (decl)),
- parm_types);
- else
- /* The only member functions whose type is a FUNCTION_TYPE, rather
- than a METHOD_TYPE, should be static members. */
- my_friendly_assert (!DECL_CONTEXT (decl)
- || !IS_AGGR_TYPE_CODE (TREE_CODE (DECL_CONTEXT (decl)))
- || TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE,
- 0);
-
- DECL_ASSEMBLER_NAME (decl)
- = build_decl_overload_real (decl, parm_types, NULL_TREE,
- NULL_TREE, NULL_TREE,
- DECL_FUNCTION_MEMBER_P (decl)
- + DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl));
-}
-
-/* Build an overload name for the type expression TYPE. */
-
-tree
-build_typename_overload (type)
- tree type;
-{
- tree id;
-
- /* This function is obsoleted by the new ABI. */
- my_friendly_assert (!flag_new_abi, 200004108);
-
- OB_INIT ();
- OB_PUTS (OPERATOR_TYPENAME_FORMAT);
- nofold = 1;
- start_squangling ();
- build_mangled_name (type, 0, 1);
- id = get_identifier (obstack_base (&scratch_obstack));
- IDENTIFIER_OPNAME_P (id) = 1;
- IDENTIFIER_TYPENAME_P (id) = 1;
- TREE_TYPE (id) = type;
- end_squangling ();
- return id;
-}
-
-tree
-build_overload_with_type (name, type)
- tree name, type;
-{
- /* This function is obsoleted by the new ABI. */
- my_friendly_assert (!flag_new_abi, 200004109);
-
- OB_INIT ();
- OB_PUTID (name);
- nofold = 1;
-
- start_squangling ();
- build_mangled_name (type, 0, 1);
- end_squangling ();
- return get_identifier (obstack_base (&scratch_obstack));
-}
-
-tree
-get_id_2 (name, name2)
- const char *name;
- tree name2;
-{
- /* This function is obsoleted by the new ABI. */
- my_friendly_assert (!flag_new_abi, 20000411);
-
- OB_INIT ();
- OB_PUTCP (name);
- OB_PUTID (name2);
- OB_FINISH ();
- return get_identifier (obstack_base (&scratch_obstack));
-}
-
-/* Returns the name of a construction vtable group. TYPE is the most
- derived class in the hierarhcy. BINFO is the most derived class in
- the construction vtable group. */
-
-tree
-get_ctor_vtbl_name (type, binfo)
- tree type;
- tree binfo;
-{
- /* This function is obsoleted by the new ABI. */
- my_friendly_assert (!flag_new_abi, 200005220);
-
- start_squangling ();
- OB_INIT ();
- OB_PUTCP (CTOR_VTBL_NAME_PREFIX);
- build_mangled_name (type, 0, 0);
- OB_PUTC ('_');
- build_mangled_name (BINFO_TYPE (binfo), 0, 0);
- OB_PUTC ('_');
- build_overload_int (BINFO_OFFSET (binfo), mf_none);
- OB_FINISH ();
- end_squangling ();
- return get_identifier (obstack_base (&scratch_obstack));
+ DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
}
-/* Returns a DECL_ASSEMBLER_NAME for the destructor of type TYPE. */
-
-tree
-build_destructor_name (type)
- tree type;
-{
- return build_overload_with_type (get_identifier (DESTRUCTOR_DECL_PREFIX),
- type);
-}
\f
/* Given a tree_code CODE, and some arguments (at least one),
attempt to use an overloaded operator on the arguments.
if (TREE_CODE (func_decl) != FUNCTION_DECL)
abort ();
- if (flag_new_abi)
- thunk_id = mangle_thunk (TREE_OPERAND (function, 0),
- delta, vcall_offset);
- else
- {
- OB_INIT ();
- OB_PUTS ("__thunk_");
- if (d > 0)
- {
- OB_PUTC ('n');
- icat (d);
- }
- else
- icat (-d);
- OB_PUTC ('_');
- if (vcall_index)
- {
- icat (tree_low_cst (vcall_index, 0));
- OB_PUTC ('_');
- }
- OB_PUTID (DECL_ASSEMBLER_NAME (func_decl));
- OB_FINISH ();
- thunk_id = get_identifier (obstack_base (&scratch_obstack));
- }
-
+ thunk_id = mangle_thunk (TREE_OPERAND (function, 0),
+ delta, vcall_offset);
thunk = IDENTIFIER_GLOBAL_VALUE (thunk_id);
if (thunk && !DECL_THUNK_P (thunk))
{
/* 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.
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))
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
/*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);
/* 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
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;
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
/* 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.
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;
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));
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
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
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)
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;
}
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
return convert_from_reference (build_dynamic_cast_1 (type, expr));
}
\f
-/* 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
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;
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);
/* 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);
*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)
{
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)
{
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))
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)),
}
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))
/* 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
- && (!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);
- }
+ /* 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. */
+ 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);
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;
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);
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);
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;
/* 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))
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. */
{
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))
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;
}
*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,
delta2_from_ptrmemfunc (t)
tree t;
{
- my_friendly_assert (!flag_new_abi, 20000221);
+ my_friendly_assert (0, 20000221);
if (TREE_CODE (t) == PTRMEM_CST)
{
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
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);