* 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
+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>
* rtti.c (get_tinfo_decl): Mark used.
/* 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 */
+ long vmi_offset_flags; /* offset and info */
/* implementation defined types */
public:
enum vmi_masks {
virtual_mask = 0x1,
public_mask = 0x2,
- hwm_bit = 2
+ hwm_bit = 2,
+ offset_shift = 8 /* bits to shift offset by */
};
/* implementation defined member functions */
public:
bool is_virtual_p () const
- { return vmi_flags & virtual_mask; }
+ { return vmi_offset_flags & virtual_mask; }
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 */
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_)
+ explicit __class_type_info (const char *n_)
+ : type_info (n_)
{ }
/* 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
{
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 */
+ 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 */
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_)
+ : __class_type_info (n_), base (base_)
{ }
/* implementation defined member functions */
/* 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:
+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:
explicit __vmi_class_type_info (const char *n_,
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 */
protected:
virtual bool do_dyncast (std::ptrdiff_t src2dst, sub_kind access_path,
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;
+ 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;
}
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;
}
is_simple = 0;
- base_init = tree_cons
- (NULL_TREE, build_int_2 (flags, 0), base_init);
+ /* 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);
var_type = si_class_desc_type_node;
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 = 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);
/* 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];
+ tree fields[2];
- 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),
+ 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, 2, ptr_type_node);
+ fields, 1, ptr_type_node);
TYPE_HAS_CONSTRUCTOR (base_desc_type_node) = 1;
}
bool __class_type_info::
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))
return false;
continue; // Not public, can't be here.
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 ())
{
dyncast_result result2;
void const *base = obj_ptr;
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 ())
{
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 (result.src_details);
+ upcast_result result2 (src_details);
const void *base = obj_ptr;
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 (!(result.src_details & multiple_base_mask))
+ if (!(src_details & non_diamond_repeat_mask))
// original cannot have an ambiguous base
continue;
sub_access = sub_kind (sub_access & ~contained_public_mask);
if (!result.base_type)
{
result = result2;
- if (!(details & multiple_base_mask))
+ if (!(details & non_diamond_repeat_mask))
// cannot have an ambiguous other base
return false;
}
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);