This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] more new abi rtti
- To: gcc-patches at gcc dot gnu dot org
- Subject: [C++ PATCH] more new abi rtti
- From: Nathan Sidwell <nathan at codesourcery dot com>
- Date: Thu, 30 Mar 2000 13:06:14 +0100
- Organization: CodeSourcery, LLC
Hi,
I've installed the attached with brings in more of the updated
new abi spec. Primarily moving fields around the type_info
structures.
booted and tested on i686-pc-linux-gnu
nathan
--
Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2000-03-28 Nathan Sidwell <nathan@codesourcery.com>
* rtti.c (class_hint_flags): Rename flags.
(class_initializer): Remove flags.
(synthesize_tinfo_var): Combine offset and flags. Add flags
for __vmi_class_type_info.
(create_tinfo_types): Remove flags from __class_type_info and
__si_class_type_info. Merge flags and offset from
base_class_type_info.
* inc/cxxabi.h (__base_class_info): Merge offset and vmi_flags.
(__base_class_info::is_virtual_p): Adjust.
(__base_class_info::is_public_p): Adjust.
(__base_class_info::offset): New accessor.
(__class_type_info::details): Remove member.
(__class_type_info::__class_type_info): Lose details.
(__class_type_info::detail_masks): Remove.
(__si_class_type_info::__si_class_type_info): Lose details.
(__vmi_class_type_info::details): New member.
(__vmi_class_type_info::__vmi_class_type_info): Adjust.
(__vmi_class_type_info::detail_masks): New member.
* tinfo.cc (__class_type_info::do_upcast): Initialize result
with unknown_details_mask.
(__vmi_class_type_info::do_find_public_src): Adjust
(__vmi_class_type_info::do_dyncast): Adjust.
(__vmi_class_type_info::do_upcast): Set result details, if
needed. Adjust.
(__dynamic_cast): Temporarily #if out optimization.
Index: cp/rtti.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/rtti.c,v
retrieving revision 1.74
diff -c -3 -p -r1.74 rtti.c
*** rtti.c 2000/03/24 16:36:06 1.74
--- rtti.c 2000/03/25 10:33:39
*************** class_hint_flags (type)
*** 1384,1395 ****
tree type;
{
int hint_flags = 0;
- hint_flags |= 0x1; /* contains multiply inherited sub object */
- hint_flags |= 0x4; /* has virtual bases */
- hint_flags |= 0x8; /* has private base */
- if (TYPE_POLYMORPHIC_P (type))
- hint_flags |= 0x2;
return hint_flags;
}
--- 1385,1396 ----
tree type;
{
int hint_flags = 0;
+ hint_flags |= 0x1; /* non-diamond shaped repeated base */
+ hint_flags |= 0x2; /* diamond shaped */
+ hint_flags |= 0x4; /* non-public base */
+ hint_flags |= 0x8; /* public base */
+ type = 0; /* FIXME: Use it! */
return hint_flags;
}
*************** class_initializer (desc, target, trail)
*** 1404,1412 ****
tree trail;
{
tree init = tinfo_base_init (desc, target);
- int flags = class_hint_flags (target);
- trail = tree_cons (NULL_TREE, build_int_2 (flags, 0), trail);
TREE_CHAIN (init) = trail;
init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, init);
TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
--- 1405,1411 ----
*************** synthesize_tinfo_var (target_type, real_
*** 1512,1519 ****
}
is_simple = 0;
! base_init = tree_cons
! (NULL_TREE, build_int_2 (flags, 0), base_init);
base_init = tree_cons (NULL_TREE, offset, base_init);
base_init = tree_cons (NULL_TREE, tinfo, base_init);
base_init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_init);
--- 1511,1521 ----
}
is_simple = 0;
! /* combine offset and flags into one field */
! offset = build_binary_op (LSHIFT_EXPR, offset,
! build_int_2 (8, 0));
! offset = build_binary_op (BIT_IOR_EXPR, offset,
! build_int_2 (flags, 0));
base_init = tree_cons (NULL_TREE, offset, base_init);
base_init = tree_cons (NULL_TREE, tinfo, base_init);
base_init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_init);
*************** synthesize_tinfo_var (target_type, real_
*** 1524,1535 ****
var_type = si_class_desc_type_node;
else
{
! /* Prepend the number of bases. */
base_inits = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_inits);
base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
base_inits = tree_cons (NULL_TREE,
build_int_2 (nbases, 0), base_inits);
!
var_type = get_vmi_pseudo_type_info (nbases);
}
var_init = class_initializer (var_type, target_type, base_inits);
--- 1526,1541 ----
var_type = si_class_desc_type_node;
else
{
! int hint = class_hint_flags (target_type);
!
base_inits = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_inits);
base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
+ /* Prepend the number of bases. */
base_inits = tree_cons (NULL_TREE,
build_int_2 (nbases, 0), base_inits);
! /* Prepend the hint flags. */
! base_inits = tree_cons (NULL_TREE,
! build_int_2 (hint, 0), base_inits);
var_type = get_vmi_pseudo_type_info (nbases);
}
var_init = class_initializer (var_type, target_type, base_inits);
*************** create_tinfo_types ()
*** 1742,1768 ****
/* Class type_info. Add a flags field. */
class_desc_type_node = create_pseudo_type_info
("__class_type_info", 0,
- build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
NULL);
/* Single public non-virtual base class. Add pointer to base class. */
si_class_desc_type_node = create_pseudo_type_info
("__si_class_type_info", 0,
- build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
NULL);
/* Base class internal helper. Pointer to base type, offset to base,
flags. */
{
! tree fields[3];
! fields[0] = build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
! fields[1] = build_lang_decl (FIELD_DECL, NULL_TREE, ptrdiff_type_node),
! fields[2] = build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
base_desc_type_node = make_aggr_type (RECORD_TYPE);
finish_builtin_type (base_desc_type_node, "__base_class_type_info_pseudo",
! fields, 2, ptr_type_node);
TYPE_HAS_CONSTRUCTOR (base_desc_type_node) = 1;
}
--- 1748,1771 ----
/* Class type_info. Add a flags field. */
class_desc_type_node = create_pseudo_type_info
("__class_type_info", 0,
NULL);
/* Single public non-virtual base class. Add pointer to base class. */
si_class_desc_type_node = create_pseudo_type_info
("__si_class_type_info", 0,
build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
NULL);
/* Base class internal helper. Pointer to base type, offset to base,
flags. */
{
! tree fields[2];
! fields[0] = build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info);
! fields[1] = build_lang_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]);
base_desc_type_node = make_aggr_type (RECORD_TYPE);
finish_builtin_type (base_desc_type_node, "__base_class_type_info_pseudo",
! fields, 1, ptr_type_node);
TYPE_HAS_CONSTRUCTOR (base_desc_type_node) = 1;
}
Index: cp/inc/cxxabi.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/inc/cxxabi.h,v
retrieving revision 1.1
diff -c -3 -p -r1.1 cxxabi.h
*** cxxabi.h 2000/03/21 16:12:25 1.1
--- cxxabi.h 2000/03/25 10:33:39
*************** class __base_class_info
*** 160,211 ****
/* abi defined member variables */
public:
const __class_type_info *base; /* base class type */
! std::ptrdiff_t offset; /* offset to the sub object */
! int vmi_flags; /* about the base */
/* implementation defined types */
public:
enum vmi_masks {
virtual_mask = 0x1,
public_mask = 0x2,
! hwm_bit = 2
};
/* implementation defined member functions */
public:
bool is_virtual_p () const
! { return vmi_flags & virtual_mask; }
bool is_public_p () const
! { return vmi_flags & public_mask; }
};
/* type information for a class */
class __class_type_info
: public std::type_info
{
- /* abi defined member variables */
- public:
- int details; /* details about the class heirarchy */
-
/* abi defined member functions */
public:
virtual ~__class_type_info ();
public:
! explicit __class_type_info (const char *n_,
! int details_)
! : type_info (n_), details (details_)
{ }
/* implementation defined types */
public:
- enum detail_masks {
- multiple_base_mask = 0x1, /* multiple inheritance of the same base type */
- polymorphic_mask = 0x2, /* is a polymorphic type */
- virtual_base_mask = 0x4, /* has virtual bases (direct or indirect) */
- private_base_mask = 0x8 /* has private bases (direct or indirect) */
- };
-
- public:
/* sub_kind tells us about how a base object is contained within a derived
object. We often do this lazily, hence the UNKNOWN value. At other times
we may use NOT_CONTAINED to mean not publicly contained. */
--- 160,200 ----
/* abi defined member variables */
public:
const __class_type_info *base; /* base class type */
! long vmi_offset_flags; /* offset and info */
/* implementation defined types */
public:
enum vmi_masks {
virtual_mask = 0x1,
public_mask = 0x2,
! hwm_bit = 2,
! offset_shift = 8 /* bits to shift offset by */
};
/* implementation defined member functions */
public:
bool is_virtual_p () const
! { return vmi_offset_flags & virtual_mask; }
bool is_public_p () const
! { return vmi_offset_flags & public_mask; }
! std::ptrdiff_t offset () const
! { return std::ptrdiff_t (vmi_offset_flags) >> offset_shift; }
};
/* type information for a class */
class __class_type_info
: public std::type_info
{
/* abi defined member functions */
public:
virtual ~__class_type_info ();
public:
! explicit __class_type_info (const char *n_)
! : type_info (n_)
{ }
/* implementation defined types */
public:
/* sub_kind tells us about how a base object is contained within a derived
object. We often do this lazily, hence the UNKNOWN value. At other times
we may use NOT_CONTAINED to mean not publicly contained. */
*************** public:
*** 230,236 ****
{
const void *dst_ptr; /* pointer to caught object */
sub_kind whole2dst; /* path from most derived object to target */
! int src_details; /* hints about the source type */
const __class_type_info *base_type; /* where we found the target, */
/* if in vbase the __class_type_info of vbase */
/* if a non-virtual base then 1 */
--- 219,225 ----
{
const void *dst_ptr; /* pointer to caught object */
sub_kind whole2dst; /* path from most derived object to target */
! int src_details; /* hints about the source type heirarchy */
const __class_type_info *base_type; /* where we found the target, */
/* if in vbase the __class_type_info of vbase */
/* if a non-virtual base then 1 */
*************** public:
*** 320,328 ****
virtual ~__si_class_type_info ();
public:
explicit __si_class_type_info (const char *n_,
- int details_,
const __class_type_info *base_)
! : __class_type_info (n_, details_), base (base_)
{ }
/* implementation defined member functions */
--- 309,316 ----
virtual ~__si_class_type_info ();
public:
explicit __si_class_type_info (const char *n_,
const __class_type_info *base_)
! : __class_type_info (n_), base (base_)
{ }
/* implementation defined member functions */
*************** protected:
*** 342,348 ****
/* type information for a class with multiple and/or virtual bases */
class __vmi_class_type_info : public __class_type_info {
/* abi defined member variables */
! protected:
int n_bases; /* number of direct bases */
__base_class_info base_list[1]; /* array of bases */
/* The array of bases uses the trailing array struct hack
--- 330,337 ----
/* type information for a class with multiple and/or virtual bases */
class __vmi_class_type_info : public __class_type_info {
/* abi defined member variables */
! public:
! int details; /* details about the class heirarchy */
int n_bases; /* number of direct bases */
__base_class_info base_list[1]; /* array of bases */
/* The array of bases uses the trailing array struct hack
*************** public:
*** 355,362 ****
public:
explicit __vmi_class_type_info (const char *n_,
int details_)
! : __class_type_info (n_, details_), n_bases (0)
{ }
/* implementation defined member functions */
protected:
--- 344,362 ----
public:
explicit __vmi_class_type_info (const char *n_,
int details_)
! : __class_type_info (n_), details (details_), n_bases (0)
{ }
+
+ /* implementation defined types */
+ public:
+ enum detail_masks {
+ non_diamond_repeat_mask = 0x1, /* distinct instance of repeated base */
+ diamond_shaped_mask = 0x2, /* diamond shaped multiple inheritance */
+ non_public_base_mask = 0x4, /* has non-public direct or indirect base */
+ public_base_mask = 0x8, /* has public base (direct) */
+
+ details_unknown_mask = 0x10
+ };
/* implementation defined member functions */
protected:
Index: cp/tinfo.cc
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/tinfo.cc,v
retrieving revision 1.18
diff -c -3 -p -r1.18 tinfo.cc
*** tinfo.cc 2000/03/21 16:12:24 1.18
--- tinfo.cc 2000/03/25 10:33:39
*************** do_catch (const type_info *thr_type, voi
*** 652,658 ****
bool __class_type_info::
do_upcast (const __class_type_info *dst_type, void **obj_ptr) const
{
! upcast_result result (details);
if (do_upcast (contained_public, dst_type, *obj_ptr, result))
return false;
--- 652,658 ----
bool __class_type_info::
do_upcast (const __class_type_info *dst_type, void **obj_ptr) const
{
! upcast_result result (__vmi_class_type_info::details_unknown_mask);
if (do_upcast (contained_public, dst_type, *obj_ptr, result))
return false;
*************** do_find_public_src (ptrdiff_t src2dst,
*** 712,718 ****
continue; // Not public, can't be here.
const void *base = obj_ptr;
! ptrdiff_t offset = base_list[i].offset;
if (base_list[i].is_virtual_p ())
{
--- 712,718 ----
continue; // Not public, can't be here.
const void *base = obj_ptr;
! ptrdiff_t offset = base_list[i].offset ();
if (base_list[i].is_virtual_p ())
{
*************** do_dyncast (ptrdiff_t src2dst,
*** 836,842 ****
dyncast_result result2;
void const *base = obj_ptr;
sub_kind base_access = access_path;
! ptrdiff_t offset = base_list[i].offset;
if (base_list[i].is_virtual_p ())
{
--- 836,842 ----
dyncast_result result2;
void const *base = obj_ptr;
sub_kind base_access = access_path;
! ptrdiff_t offset = base_list[i].offset ();
if (base_list[i].is_virtual_p ())
{
*************** do_upcast (sub_kind access_path,
*** 1018,1033 ****
return contained_nonpublic_p (access_path);
}
for (size_t i = n_bases; i--;)
{
! upcast_result result2 (result.src_details);
const void *base = obj_ptr;
sub_kind sub_access = access_path;
! ptrdiff_t offset = base_list[i].offset;
if (!base_list[i].is_public_p ())
{
! if (!(result.src_details & multiple_base_mask))
// original cannot have an ambiguous base
continue;
sub_access = sub_kind (sub_access & ~contained_public_mask);
--- 1018,1037 ----
return contained_nonpublic_p (access_path);
}
+ int src_details = result.src_details;
+ if (src_details & details_unknown_mask)
+ src_details = details;
+
for (size_t i = n_bases; i--;)
{
! upcast_result result2 (src_details);
const void *base = obj_ptr;
sub_kind sub_access = access_path;
! ptrdiff_t offset = base_list[i].offset ();
if (!base_list[i].is_public_p ())
{
! if (!(src_details & non_diamond_repeat_mask))
// original cannot have an ambiguous base
continue;
sub_access = sub_kind (sub_access & ~contained_public_mask);
*************** do_upcast (sub_kind access_path,
*** 1055,1061 ****
if (!result.base_type)
{
result = result2;
! if (!(details & multiple_base_mask))
// cannot have an ambiguous other base
return false;
}
--- 1059,1065 ----
if (!result.base_type)
{
result = result2;
! if (!(details & non_diamond_repeat_mask))
// cannot have an ambiguous other base
return false;
}
*************** __dynamic_cast (const void *src_ptr,
*** 1120,1128 ****
--- 1124,1134 ----
if (contained_nonvirtual_p (result.whole2src))
// Found an invalid cross cast, which cannot also be a down cast
return NULL;
+ #if 0 // FIXME: we need to discover this lazily
if (!(whole_type->details & __class_type_info::private_base_mask))
// whole type has no private bases
return const_cast <void *> (result.dst_ptr);
+ #endif
if (result.dst2src == __class_type_info::unknown)
result.dst2src = dst_type->find_public_src (src2dst, result.dst_ptr,
src_type, src_ptr);