Commit 068feaa9 by Nathan Sidwell Committed by Nathan Sidwell

rtti.c (class_hint_flags): Rename flags.

	* 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.

From-SVN: r32828
parent 19caa751
2000-03-30 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.
2000-03-29 Nathan Sidwell <nathan@codesourcery.com> 2000-03-29 Nathan Sidwell <nathan@codesourcery.com>
* rtti.c (get_tinfo_decl): Mark used. * rtti.c (get_tinfo_decl): Mark used.
......
...@@ -160,52 +160,41 @@ class __base_class_info ...@@ -160,52 +160,41 @@ class __base_class_info
/* abi defined member variables */ /* abi defined member variables */
public: public:
const __class_type_info *base; /* base class type */ const __class_type_info *base; /* base class type */
std::ptrdiff_t offset; /* offset to the sub object */ long vmi_offset_flags; /* offset and info */
int vmi_flags; /* about the base */
/* implementation defined types */ /* implementation defined types */
public: public:
enum vmi_masks { enum vmi_masks {
virtual_mask = 0x1, virtual_mask = 0x1,
public_mask = 0x2, public_mask = 0x2,
hwm_bit = 2 hwm_bit = 2,
offset_shift = 8 /* bits to shift offset by */
}; };
/* implementation defined member functions */ /* implementation defined member functions */
public: public:
bool is_virtual_p () const bool is_virtual_p () const
{ return vmi_flags & virtual_mask; } { return vmi_offset_flags & virtual_mask; }
bool is_public_p () const bool is_public_p () const
{ return vmi_flags & public_mask; } { 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 */ /* type information for a class */
class __class_type_info class __class_type_info
: public std::type_info : public std::type_info
{ {
/* abi defined member variables */
public:
int details; /* details about the class heirarchy */
/* abi defined member functions */ /* abi defined member functions */
public: public:
virtual ~__class_type_info (); virtual ~__class_type_info ();
public: public:
explicit __class_type_info (const char *n_, explicit __class_type_info (const char *n_)
int details_) : type_info (n_)
: type_info (n_), details (details_)
{ } { }
/* implementation defined types */ /* implementation defined types */
public: 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 /* 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 object. We often do this lazily, hence the UNKNOWN value. At other times
we may use NOT_CONTAINED to mean not publicly contained. */ we may use NOT_CONTAINED to mean not publicly contained. */
...@@ -230,7 +219,7 @@ public: ...@@ -230,7 +219,7 @@ public:
{ {
const void *dst_ptr; /* pointer to caught object */ const void *dst_ptr; /* pointer to caught object */
sub_kind whole2dst; /* path from most derived object to target */ sub_kind whole2dst; /* path from most derived object to target */
int src_details; /* hints about the source type */ int src_details; /* hints about the source type heirarchy */
const __class_type_info *base_type; /* where we found the target, */ const __class_type_info *base_type; /* where we found the target, */
/* if in vbase the __class_type_info of vbase */ /* if in vbase the __class_type_info of vbase */
/* if a non-virtual base then 1 */ /* if a non-virtual base then 1 */
...@@ -320,9 +309,8 @@ public: ...@@ -320,9 +309,8 @@ public:
virtual ~__si_class_type_info (); virtual ~__si_class_type_info ();
public: public:
explicit __si_class_type_info (const char *n_, explicit __si_class_type_info (const char *n_,
int details_,
const __class_type_info *base_) const __class_type_info *base_)
: __class_type_info (n_, details_), base (base_) : __class_type_info (n_), base (base_)
{ } { }
/* implementation defined member functions */ /* implementation defined member functions */
...@@ -342,7 +330,8 @@ protected: ...@@ -342,7 +330,8 @@ protected:
/* type information for a class with multiple and/or virtual bases */ /* type information for a class with multiple and/or virtual bases */
class __vmi_class_type_info : public __class_type_info { class __vmi_class_type_info : public __class_type_info {
/* abi defined member variables */ /* abi defined member variables */
protected: public:
int details; /* details about the class heirarchy */
int n_bases; /* number of direct bases */ int n_bases; /* number of direct bases */
__base_class_info base_list[1]; /* array of bases */ __base_class_info base_list[1]; /* array of bases */
/* The array of bases uses the trailing array struct hack /* The array of bases uses the trailing array struct hack
...@@ -355,9 +344,20 @@ public: ...@@ -355,9 +344,20 @@ public:
public: public:
explicit __vmi_class_type_info (const char *n_, explicit __vmi_class_type_info (const char *n_,
int details_) int details_)
: __class_type_info (n_, details_), n_bases (0) : __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 */ /* implementation defined member functions */
protected: protected:
virtual bool do_dyncast (std::ptrdiff_t src2dst, sub_kind access_path, virtual bool do_dyncast (std::ptrdiff_t src2dst, sub_kind access_path,
......
...@@ -1392,12 +1392,12 @@ class_hint_flags (type) ...@@ -1392,12 +1392,12 @@ class_hint_flags (type)
tree type; tree type;
{ {
int hint_flags = 0; 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;
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; return hint_flags;
} }
...@@ -1412,9 +1412,7 @@ class_initializer (desc, target, trail) ...@@ -1412,9 +1412,7 @@ class_initializer (desc, target, trail)
tree trail; tree trail;
{ {
tree init = tinfo_base_init (desc, target); 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; TREE_CHAIN (init) = trail;
init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, init); init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, init);
TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1; TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
...@@ -1520,8 +1518,11 @@ synthesize_tinfo_var (target_type, real_name) ...@@ -1520,8 +1518,11 @@ synthesize_tinfo_var (target_type, real_name)
} }
is_simple = 0; is_simple = 0;
base_init = tree_cons /* combine offset and flags into one field */
(NULL_TREE, build_int_2 (flags, 0), base_init); 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, offset, base_init);
base_init = tree_cons (NULL_TREE, tinfo, base_init); base_init = tree_cons (NULL_TREE, tinfo, base_init);
base_init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_init); base_init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_init);
...@@ -1532,12 +1533,16 @@ synthesize_tinfo_var (target_type, real_name) ...@@ -1532,12 +1533,16 @@ synthesize_tinfo_var (target_type, real_name)
var_type = si_class_desc_type_node; var_type = si_class_desc_type_node;
else else
{ {
/* Prepend the number of bases. */ int hint = class_hint_flags (target_type);
base_inits = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_inits); 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, base_inits, NULL_TREE);
/* Prepend the number of bases. */
base_inits = tree_cons (NULL_TREE, base_inits = tree_cons (NULL_TREE,
build_int_2 (nbases, 0), base_inits); 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_type = get_vmi_pseudo_type_info (nbases);
} }
var_init = class_initializer (var_type, target_type, base_inits); var_init = class_initializer (var_type, target_type, base_inits);
...@@ -1761,27 +1766,24 @@ create_tinfo_types () ...@@ -1761,27 +1766,24 @@ create_tinfo_types ()
/* Class type_info. Add a flags field. */ /* Class type_info. Add a flags field. */
class_desc_type_node = create_pseudo_type_info class_desc_type_node = create_pseudo_type_info
("__class_type_info", 0, ("__class_type_info", 0,
build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
NULL); NULL);
/* Single public non-virtual base class. Add pointer to base class. */ /* Single public non-virtual base class. Add pointer to base class. */
si_class_desc_type_node = create_pseudo_type_info si_class_desc_type_node = create_pseudo_type_info
("__si_class_type_info", 0, ("__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), build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
NULL); NULL);
/* Base class internal helper. Pointer to base type, offset to base, /* Base class internal helper. Pointer to base type, offset to base,
flags. */ flags. */
{ {
tree fields[3]; tree fields[2];
fields[0] = build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info), 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[1] = build_lang_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]);
fields[2] = build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
base_desc_type_node = make_aggr_type (RECORD_TYPE); base_desc_type_node = make_aggr_type (RECORD_TYPE);
finish_builtin_type (base_desc_type_node, "__base_class_type_info_pseudo", finish_builtin_type (base_desc_type_node, "__base_class_type_info_pseudo",
fields, 2, ptr_type_node); fields, 1, ptr_type_node);
TYPE_HAS_CONSTRUCTOR (base_desc_type_node) = 1; TYPE_HAS_CONSTRUCTOR (base_desc_type_node) = 1;
} }
......
...@@ -652,7 +652,7 @@ do_catch (const type_info *thr_type, void **thr_obj, ...@@ -652,7 +652,7 @@ do_catch (const type_info *thr_type, void **thr_obj,
bool __class_type_info:: bool __class_type_info::
do_upcast (const __class_type_info *dst_type, void **obj_ptr) const do_upcast (const __class_type_info *dst_type, void **obj_ptr) const
{ {
upcast_result result (details); upcast_result result (__vmi_class_type_info::details_unknown_mask);
if (do_upcast (contained_public, dst_type, *obj_ptr, result)) if (do_upcast (contained_public, dst_type, *obj_ptr, result))
return false; return false;
...@@ -712,7 +712,7 @@ do_find_public_src (ptrdiff_t src2dst, ...@@ -712,7 +712,7 @@ do_find_public_src (ptrdiff_t src2dst,
continue; // Not public, can't be here. continue; // Not public, can't be here.
const void *base = obj_ptr; const void *base = obj_ptr;
ptrdiff_t offset = base_list[i].offset; ptrdiff_t offset = base_list[i].offset ();
if (base_list[i].is_virtual_p ()) if (base_list[i].is_virtual_p ())
{ {
...@@ -836,7 +836,7 @@ do_dyncast (ptrdiff_t src2dst, ...@@ -836,7 +836,7 @@ do_dyncast (ptrdiff_t src2dst,
dyncast_result result2; dyncast_result result2;
void const *base = obj_ptr; void const *base = obj_ptr;
sub_kind base_access = access_path; sub_kind base_access = access_path;
ptrdiff_t offset = base_list[i].offset; ptrdiff_t offset = base_list[i].offset ();
if (base_list[i].is_virtual_p ()) if (base_list[i].is_virtual_p ())
{ {
...@@ -1018,16 +1018,20 @@ do_upcast (sub_kind access_path, ...@@ -1018,16 +1018,20 @@ do_upcast (sub_kind access_path,
return contained_nonpublic_p (access_path); 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--;) for (size_t i = n_bases; i--;)
{ {
upcast_result result2 (result.src_details); upcast_result result2 (src_details);
const void *base = obj_ptr; const void *base = obj_ptr;
sub_kind sub_access = access_path; sub_kind sub_access = access_path;
ptrdiff_t offset = base_list[i].offset; ptrdiff_t offset = base_list[i].offset ();
if (!base_list[i].is_public_p ()) if (!base_list[i].is_public_p ())
{ {
if (!(result.src_details & multiple_base_mask)) if (!(src_details & non_diamond_repeat_mask))
// original cannot have an ambiguous base // original cannot have an ambiguous base
continue; continue;
sub_access = sub_kind (sub_access & ~contained_public_mask); sub_access = sub_kind (sub_access & ~contained_public_mask);
...@@ -1055,7 +1059,7 @@ do_upcast (sub_kind access_path, ...@@ -1055,7 +1059,7 @@ do_upcast (sub_kind access_path,
if (!result.base_type) if (!result.base_type)
{ {
result = result2; result = result2;
if (!(details & multiple_base_mask)) if (!(details & non_diamond_repeat_mask))
// cannot have an ambiguous other base // cannot have an ambiguous other base
return false; return false;
} }
...@@ -1119,9 +1123,11 @@ __dynamic_cast (const void *src_ptr, // object started from ...@@ -1119,9 +1123,11 @@ __dynamic_cast (const void *src_ptr, // object started from
if (contained_nonvirtual_p (result.whole2src)) if (contained_nonvirtual_p (result.whole2src))
// Found an invalid cross cast, which cannot also be a down cast // Found an invalid cross cast, which cannot also be a down cast
return NULL; return NULL;
#if 0 // FIXME: we need to discover this lazily
if (!(whole_type->details & __class_type_info::private_base_mask)) if (!(whole_type->details & __class_type_info::private_base_mask))
// whole type has no private bases // whole type has no private bases
return const_cast <void *> (result.dst_ptr); return const_cast <void *> (result.dst_ptr);
#endif
if (result.dst2src == __class_type_info::unknown) if (result.dst2src == __class_type_info::unknown)
result.dst2src = dst_type->find_public_src (src2dst, result.dst_ptr, result.dst2src = dst_type->find_public_src (src2dst, result.dst_ptr,
src_type, src_ptr); src_type, src_ptr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment