aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2000-03-30 12:08:26 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2000-03-30 12:08:26 +0000
commit068feaa95538472dfdb0244ef4899a86e73db86e (patch)
tree215e7cef70275acfb861ad0b6003848dbc7a54ea /gcc
parent19caa751a84a1ff3a90a5dc64e3f4c5cac6ce97f (diff)
downloadgcc-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/ChangeLog28
-rw-r--r--gcc/cp/inc/cxxabi.h50
-rw-r--r--gcc/cp/rtti.c38
-rw-r--r--gcc/cp/tinfo.cc20
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);