diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2000-03-30 12:08:26 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2000-03-30 12:08:26 +0000 |
commit | 068feaa95538472dfdb0244ef4899a86e73db86e (patch) | |
tree | 215e7cef70275acfb861ad0b6003848dbc7a54ea /gcc | |
parent | 19caa751a84a1ff3a90a5dc64e3f4c5cac6ce97f (diff) | |
download | gcc-068feaa95538472dfdb0244ef4899a86e73db86e.zip gcc-068feaa95538472dfdb0244ef4899a86e73db86e.tar.gz gcc-068feaa95538472dfdb0244ef4899a86e73db86e.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 28 | ||||
-rw-r--r-- | gcc/cp/inc/cxxabi.h | 50 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 38 | ||||
-rw-r--r-- | gcc/cp/tinfo.cc | 20 |
4 files changed, 86 insertions, 50 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2faca96..da0b96f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,31 @@ +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. diff --git a/gcc/cp/inc/cxxabi.h b/gcc/cp/inc/cxxabi.h index b140a15..26cec3f 100644 --- a/gcc/cp/inc/cxxabi.h +++ b/gcc/cp/inc/cxxabi.h @@ -160,52 +160,41 @@ class __base_class_info /* 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 we may use NOT_CONTAINED to mean not publicly contained. */ @@ -230,7 +219,7 @@ public: { 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 */ @@ -320,9 +309,8 @@ public: 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 */ @@ -342,7 +330,8 @@ protected: /* 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 @@ -355,9 +344,20 @@ public: 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, diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 13f5b09..a91bef8 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -1392,12 +1392,12 @@ class_hint_flags (type) 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; } @@ -1412,9 +1412,7 @@ class_initializer (desc, target, trail) 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; @@ -1520,8 +1518,11 @@ synthesize_tinfo_var (target_type, real_name) } 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); @@ -1532,12 +1533,16 @@ synthesize_tinfo_var (target_type, real_name) 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); @@ -1761,27 +1766,24 @@ create_tinfo_types () /* 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; } diff --git a/gcc/cp/tinfo.cc b/gcc/cp/tinfo.cc index 3bf3c90..71e5c28 100644 --- a/gcc/cp/tinfo.cc +++ b/gcc/cp/tinfo.cc @@ -652,7 +652,7 @@ do_catch (const type_info *thr_type, void **thr_obj, 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; @@ -712,7 +712,7 @@ do_find_public_src (ptrdiff_t src2dst, 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 ()) { @@ -836,7 +836,7 @@ do_dyncast (ptrdiff_t src2dst, 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 ()) { @@ -1018,16 +1018,20 @@ do_upcast (sub_kind 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--;) { - 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); @@ -1055,7 +1059,7 @@ do_upcast (sub_kind access_path, 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; } @@ -1119,9 +1123,11 @@ __dynamic_cast (const void *src_ptr, // object started from 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); |