mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-13 14:01:26 +08:00
Remove old ABI support from libsupc++.
* libsupc++/cxxabi.h: Remove conditionally compiled code. * libsupc++/exception_support.cc: Likewise. * libsupc++/pure.cc: Likewise. * libsupc++/tinfo.cc: Likewise. * libsupc++/tinfo.h: Likewise. * libsupc++/tinfo2.cc: Likewise. * libsupc++/typeinfo: Likewise. * libsupc++/vec.cc: Likewise. From-SVN: r39732
This commit is contained in:
parent
f1a3f197e1
commit
94083e5ddb
@ -1,3 +1,15 @@
|
||||
2001-02-15 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
Remove old ABI support from libsupc++.
|
||||
* libsupc++/cxxabi.h: Remove conditionally compiled code.
|
||||
* libsupc++/exception_support.cc: Likewise.
|
||||
* libsupc++/pure.cc: Likewise.
|
||||
* libsupc++/tinfo.cc: Likewise.
|
||||
* libsupc++/tinfo.h: Likewise.
|
||||
* libsupc++/tinfo2.cc: Likewise.
|
||||
* libsupc++/typeinfo: Likewise.
|
||||
* libsupc++/vec.cc: Likewise.
|
||||
|
||||
2001-02-15 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
Add support for -fno-exceptions.
|
||||
|
@ -42,12 +42,6 @@
|
||||
#ifndef __CXXABI_H
|
||||
#define __CXXABI_H 1
|
||||
|
||||
#if defined(__cplusplus) && (!defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100)
|
||||
/* These structures only make sense when targeting the new abi, catch a
|
||||
bonehead error early rather than let the user get very confused. */
|
||||
#error "Not targetting the new abi, supply -fnew-abi"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
// We use the compiler builtins __SIZE_TYPE__ and __PTRDIFF_TYPE__ instead of
|
||||
|
@ -151,10 +151,6 @@ __cplus_type_matcher (__eh_info *info_, void *match_info,
|
||||
|
||||
void *match_type = match_info;
|
||||
|
||||
#if !defined (__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||
match_type = ((void *(*)())match_type) ();
|
||||
#endif
|
||||
|
||||
if (__throw_type_match_rtti_2 (match_type, info->type,
|
||||
info->original_value, &info->value))
|
||||
// Arbitrary non-null pointer.
|
||||
@ -352,7 +348,7 @@ __check_null_eh_spec (void)
|
||||
// Helpers for rtti. Although these don't return, we give them return types so
|
||||
// that the type system is not broken.
|
||||
extern "C" void *
|
||||
__cxa_bad_cast()
|
||||
__cxa_bad_cast ()
|
||||
{
|
||||
#ifdef __EXCEPTIONS
|
||||
throw std::bad_cast();
|
||||
@ -363,7 +359,7 @@ __cxa_bad_cast()
|
||||
}
|
||||
|
||||
extern "C" std::type_info const &
|
||||
__cxa_bad_typeid()
|
||||
__cxa_bad_typeid ()
|
||||
{
|
||||
#ifdef __EXCEPTIONS
|
||||
throw std::bad_typeid();
|
||||
|
@ -1,6 +1,5 @@
|
||||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2000 Free Software Foundation
|
||||
// Copyright (C) 2000, 2001 Free Software Foundation
|
||||
//
|
||||
// This file is part of GNU CC.
|
||||
//
|
||||
@ -47,16 +46,8 @@ extern "C" {
|
||||
|
||||
extern void __terminate(void) __attribute__ ((__noreturn__));
|
||||
|
||||
// The name of the function to be placed in vtables in place of a pure
|
||||
// virtual function is different in the two ABIs.
|
||||
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||
#define PURE_VIRTUAL_NAME __pure_virtual
|
||||
#else
|
||||
#define PURE_VIRTUAL_NAME __cxa_pure_virtual
|
||||
#endif
|
||||
|
||||
void
|
||||
PURE_VIRTUAL_NAME (void)
|
||||
__cxa_pure_virtual (void)
|
||||
{
|
||||
writestr ("pure virtual method called\n");
|
||||
__terminate ();
|
||||
|
@ -1,6 +1,5 @@
|
||||
// Methods for type_info for -*- C++ -*- Run Time Type Identification.
|
||||
|
||||
// Copyright (C) 1994, 1996, 1998, 1999, 2000 Free Software Foundation
|
||||
// Copyright (C) 1994, 1996, 1998, 1999, 2000, 2001 Free Software Foundation
|
||||
//
|
||||
// This file is part of GNU CC.
|
||||
//
|
||||
@ -53,500 +52,6 @@ operator== (const std::type_info& arg) const
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||
// original (old) abi
|
||||
|
||||
namespace
|
||||
{
|
||||
// ADDR is a pointer to an object. Convert it to a pointer to a base,
|
||||
// using OFFSET.
|
||||
inline void*
|
||||
convert_to_base (void *addr, bool is_virtual, myint32 offset)
|
||||
{
|
||||
if (!addr)
|
||||
return NULL;
|
||||
|
||||
if (!is_virtual)
|
||||
return (char *) addr + offset;
|
||||
|
||||
// Under the old ABI, the offset gives us the address of a pointer
|
||||
// to the virtual base.
|
||||
return *((void **) ((char *) addr + offset));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
__rtti_class (void *addr, const char *name,
|
||||
const __class_type_info::base_info *bl, std::size_t bn)
|
||||
{ new (addr) __class_type_info (name, bl, bn); }
|
||||
|
||||
extern "C" void
|
||||
__rtti_si (void *addr, const char *n, const std::type_info *ti)
|
||||
{
|
||||
new (addr) __si_type_info
|
||||
(n, static_cast <const __user_type_info &> (*ti));
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
__rtti_user (void *addr, const char *name)
|
||||
{ new (addr) __user_type_info (name); }
|
||||
|
||||
// Upcast for catch checking. OBJPTR points to the thrown object and might be
|
||||
// NULL. Return 0 on failure, non-zero on success. Set *ADJPTR to adjusted
|
||||
// object pointer.
|
||||
int __user_type_info::
|
||||
upcast (const type_info &target, void *objptr,
|
||||
void **adjptr) const
|
||||
{
|
||||
upcast_result result;
|
||||
|
||||
if (do_upcast (contained_public, target, objptr, result))
|
||||
return 0;
|
||||
*adjptr = result.target_obj;
|
||||
return contained_public_p (result.whole2target);
|
||||
}
|
||||
|
||||
// Down or cross cast for dynamic_cast. OBJPTR points to the most derrived
|
||||
// object, SUBPTR points to the static base object. Both must not be NULL.
|
||||
// TARGET specifies the desired target type, SUBTYPE specifies the static
|
||||
// type. Both must be defined. Returns adjusted object pointer on success,
|
||||
// NULL on failure. [expr.dynamic.cast]/8 says 'unambiguous public base'. This
|
||||
// itself is an ambiguous statement. We choose it to mean the base must be
|
||||
// separately unambiguous and public, rather than unambiguous considering only
|
||||
// public bases.
|
||||
void *__user_type_info::
|
||||
dyncast (int boff,
|
||||
const type_info &target, void *objptr,
|
||||
const type_info &subtype, void *subptr) const
|
||||
{
|
||||
dyncast_result result;
|
||||
|
||||
do_dyncast (boff, contained_public,
|
||||
target, objptr, subtype, subptr, result);
|
||||
if (!result.target_obj)
|
||||
return NULL;
|
||||
if (contained_public_p (result.target2sub))
|
||||
return result.target_obj;
|
||||
if (contained_public_p (sub_kind (result.whole2sub & result.whole2target)))
|
||||
// Found a valid cross cast
|
||||
return result.target_obj;
|
||||
if (contained_nonvirtual_p (result.whole2sub))
|
||||
// Found an invalid cross cast, which cannot also be a down cast
|
||||
return NULL;
|
||||
if (result.target2sub == unknown)
|
||||
result.target2sub = static_cast <const __user_type_info &> (target)
|
||||
.find_public_subobj (boff, subtype,
|
||||
result.target_obj, subptr);
|
||||
if (contained_public_p (result.target2sub))
|
||||
// Found a valid down cast
|
||||
return result.target_obj;
|
||||
// Must be an invalid down cast, or the cross cast wasn't bettered
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Catch cast helper. ACCESS_PATH is the access from the complete thrown
|
||||
// object to this base. TARGET is the desired type we want to catch. OBJPTR
|
||||
// points to this base within the throw object, it might be NULL. Fill in
|
||||
// RESULT with what we find. Return true, should we determine catch must fail.
|
||||
bool __user_type_info::
|
||||
do_upcast (sub_kind access_path,
|
||||
const type_info &target, void *objptr,
|
||||
upcast_result &__restrict result) const
|
||||
{
|
||||
if (*this == target)
|
||||
{
|
||||
result.target_obj = objptr;
|
||||
result.base_type = nonvirtual_base_type;
|
||||
result.whole2target = access_path;
|
||||
return contained_nonpublic_p (access_path);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// dynamic cast helper. ACCESS_PATH gives the access from the most derived
|
||||
// object to this base. TARGET indicates the desired type we want. OBJPTR
|
||||
// points to this base within the object. SUBTYPE indicates the static type
|
||||
// started from and SUBPTR points to that base within the most derived object.
|
||||
// Fill in RESULT with what we find. Return true if we have located an
|
||||
// ambiguous match.
|
||||
bool __user_type_info::
|
||||
do_dyncast (int, sub_kind access_path,
|
||||
const type_info &target, void *objptr,
|
||||
const type_info &subtype, void *subptr,
|
||||
dyncast_result &__restrict result) const
|
||||
{
|
||||
if (objptr == subptr && *this == subtype)
|
||||
{
|
||||
// The subobject we started from. Indicate how we are accessible from
|
||||
// the most derived object.
|
||||
result.whole2sub = access_path;
|
||||
return false;
|
||||
}
|
||||
if (*this == target)
|
||||
{
|
||||
result.target_obj = objptr;
|
||||
result.whole2target = access_path;
|
||||
result.target2sub = not_contained;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// find_public_subobj helper. Return contained_public if we are the desired
|
||||
// subtype. OBJPTR points to this base type, SUBPTR points to the desired base
|
||||
// object.
|
||||
__user_type_info::sub_kind __user_type_info::
|
||||
do_find_public_subobj (int, const type_info &, void *objptr, void *subptr) const
|
||||
{
|
||||
if (subptr == objptr)
|
||||
// Must be our type, as the pointers match.
|
||||
return contained_public;
|
||||
return not_contained;
|
||||
}
|
||||
|
||||
// catch helper for single public inheritance types. See
|
||||
// __user_type_info::do_upcast for semantics.
|
||||
bool __si_type_info::
|
||||
do_upcast (sub_kind access_path,
|
||||
const type_info &target, void *objptr,
|
||||
upcast_result &__restrict result) const
|
||||
{
|
||||
if (*this == target)
|
||||
{
|
||||
result.target_obj = objptr;
|
||||
result.base_type = nonvirtual_base_type;
|
||||
result.whole2target = access_path;
|
||||
return contained_nonpublic_p (access_path);
|
||||
}
|
||||
return base.do_upcast (access_path, target, objptr, result);
|
||||
}
|
||||
|
||||
// dynamic cast helper for single public inheritance types. See
|
||||
// __user_type_info::do_dyncast for semantics. BOFF indicates how SUBTYPE
|
||||
// types are inherited by TARGET types.
|
||||
bool __si_type_info::
|
||||
do_dyncast (int boff, sub_kind access_path,
|
||||
const type_info &target, void *objptr,
|
||||
const type_info &subtype, void *subptr,
|
||||
dyncast_result &__restrict result) const
|
||||
{
|
||||
if (objptr == subptr && *this == subtype)
|
||||
{
|
||||
// The subobject we started from. Indicate how we are accessible from
|
||||
// the most derived object.
|
||||
result.whole2sub = access_path;
|
||||
return false;
|
||||
}
|
||||
if (*this == target)
|
||||
{
|
||||
result.target_obj = objptr;
|
||||
result.whole2target = access_path;
|
||||
if (boff >= 0)
|
||||
result.target2sub = ((char *)subptr - (char *)objptr) == boff
|
||||
? contained_public : not_contained;
|
||||
else if (boff == -2)
|
||||
result.target2sub = not_contained;
|
||||
return false;
|
||||
}
|
||||
return base.do_dyncast (boff, access_path,
|
||||
target, objptr, subtype, subptr, result);
|
||||
}
|
||||
|
||||
// find_public_subobj helper. See __user_type_info::do_find_public_subobj or
|
||||
// semantics. BOFF indicates how SUBTYPE types are inherited by the original
|
||||
// target object.
|
||||
__user_type_info::sub_kind __si_type_info::
|
||||
do_find_public_subobj (int boff, const type_info &subtype, void *objptr, void *subptr) const
|
||||
{
|
||||
if (subptr == objptr && subtype == *this)
|
||||
return contained_public;
|
||||
return base.do_find_public_subobj (boff, subtype, objptr, subptr);
|
||||
}
|
||||
|
||||
// catch helper for multiple or non-public inheritance types. See
|
||||
// __user_type_info::do_upcast for semantics.
|
||||
bool __class_type_info::
|
||||
do_upcast (sub_kind access_path,
|
||||
const type_info &target, void *objptr,
|
||||
upcast_result &__restrict result) const
|
||||
{
|
||||
if (*this == target)
|
||||
{
|
||||
result.target_obj = objptr;
|
||||
result.base_type = nonvirtual_base_type;
|
||||
result.whole2target = access_path;
|
||||
return contained_nonpublic_p (access_path);
|
||||
}
|
||||
|
||||
for (std::size_t i = n_bases; i--;)
|
||||
{
|
||||
upcast_result result2;
|
||||
void *p = objptr;
|
||||
sub_kind sub_access = access_path;
|
||||
p = convert_to_base (p,
|
||||
base_list[i].is_virtual,
|
||||
base_list[i].offset);
|
||||
if (base_list[i].is_virtual)
|
||||
sub_access = sub_kind (sub_access | contained_virtual_mask);
|
||||
if (base_list[i].access != PUBLIC)
|
||||
sub_access = sub_kind (sub_access & ~contained_public_mask);
|
||||
if (base_list[i].base->do_upcast (sub_access, target, p, result2)
|
||||
&& !contained_virtual_p (result2.whole2target))
|
||||
return true; // must fail
|
||||
if (result2.base_type)
|
||||
{
|
||||
if (result2.base_type == nonvirtual_base_type
|
||||
&& base_list[i].is_virtual)
|
||||
result2.base_type = base_list[i].base;
|
||||
if (!result.base_type)
|
||||
result = result2;
|
||||
else if (result.target_obj != result2.target_obj)
|
||||
{
|
||||
// Found an ambiguity.
|
||||
result.target_obj = NULL;
|
||||
result.whole2target = contained_ambig;
|
||||
return true;
|
||||
}
|
||||
else if (result.target_obj)
|
||||
{
|
||||
// Ok, found real object via a virtual path.
|
||||
result.whole2target
|
||||
= sub_kind (result.whole2target | result2.whole2target);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Dealing with a null pointer, need to check vbase
|
||||
// containing each of the two choices.
|
||||
if (result2.base_type == nonvirtual_base_type
|
||||
|| result.base_type == nonvirtual_base_type
|
||||
|| !(*result2.base_type == *result.base_type))
|
||||
{
|
||||
// Already ambiguous, not virtual or via different virtuals.
|
||||
// Cannot match.
|
||||
result.whole2target = contained_ambig;
|
||||
return true;
|
||||
}
|
||||
result.whole2target
|
||||
= sub_kind (result.whole2target | result2.whole2target);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// dynamic cast helper for non-public or multiple inheritance types. See
|
||||
// __user_type_info::do_dyncast for overall semantics.
|
||||
// This is a big hairy function. Although the run-time behaviour of
|
||||
// dynamic_cast is simple to describe, it gives rise to some non-obvious
|
||||
// behaviour. We also desire to determine as early as possible any definite
|
||||
// answer we can get. Because it is unknown what the run-time ratio of
|
||||
// succeeding to failing dynamic casts is, we do not know in which direction
|
||||
// to bias any optimizations. To that end we make no particular effort towards
|
||||
// early fail answers or early success answers. Instead we try to minimize
|
||||
// work by filling in things lazily (when we know we need the information),
|
||||
// and opportunisticly take early success or failure results.
|
||||
bool __class_type_info::
|
||||
do_dyncast (int boff, sub_kind access_path,
|
||||
const type_info &target, void *objptr,
|
||||
const type_info &subtype, void *subptr,
|
||||
dyncast_result &__restrict result) const
|
||||
{
|
||||
if (objptr == subptr && *this == subtype)
|
||||
{
|
||||
// The subobject we started from. Indicate how we are accessible from
|
||||
// the most derived object.
|
||||
result.whole2sub = access_path;
|
||||
return false;
|
||||
}
|
||||
if (*this == target)
|
||||
{
|
||||
result.target_obj = objptr;
|
||||
result.whole2target = access_path;
|
||||
if (boff >= 0)
|
||||
result.target2sub = ((char *)subptr - (char *)objptr) == boff
|
||||
? contained_public : not_contained;
|
||||
else if (boff == -2)
|
||||
result.target2sub = not_contained;
|
||||
return false;
|
||||
}
|
||||
bool result_ambig = false;
|
||||
for (std::size_t i = n_bases; i--;)
|
||||
{
|
||||
dyncast_result result2;
|
||||
void *p;
|
||||
sub_kind sub_access = access_path;
|
||||
p = convert_to_base (objptr,
|
||||
base_list[i].is_virtual,
|
||||
base_list[i].offset);
|
||||
if (base_list[i].is_virtual)
|
||||
sub_access = sub_kind (sub_access | contained_virtual_mask);
|
||||
if (base_list[i].access != PUBLIC)
|
||||
sub_access = sub_kind (sub_access & ~contained_public_mask);
|
||||
|
||||
bool result2_ambig
|
||||
= base_list[i].base->do_dyncast (boff, sub_access,
|
||||
target, p, subtype, subptr, result2);
|
||||
result.whole2sub = sub_kind (result.whole2sub | result2.whole2sub);
|
||||
if (result2.target2sub == contained_public
|
||||
|| result2.target2sub == contained_ambig)
|
||||
{
|
||||
result.target_obj = result2.target_obj;
|
||||
result.whole2target = result2.whole2target;
|
||||
result.target2sub = result2.target2sub;
|
||||
// Found a downcast which can't be bettered or an ambiguous downcast
|
||||
// which can't be disambiguated
|
||||
return result2_ambig;
|
||||
}
|
||||
|
||||
if (!result_ambig && !result.target_obj)
|
||||
{
|
||||
// Not found anything yet.
|
||||
result.target_obj = result2.target_obj;
|
||||
result.whole2target = result2.whole2target;
|
||||
result_ambig = result2_ambig;
|
||||
}
|
||||
else if (result.target_obj && result.target_obj == result2.target_obj)
|
||||
{
|
||||
// Found at same address, must be via virtual. Pick the most
|
||||
// accessible path.
|
||||
result.whole2target =
|
||||
sub_kind (result.whole2target | result2.whole2target);
|
||||
}
|
||||
else if ((result.target_obj && result2.target_obj)
|
||||
|| (result_ambig && result2.target_obj)
|
||||
|| (result2_ambig && result.target_obj))
|
||||
{
|
||||
// Found two different TARGET bases, or a valid one and a set of
|
||||
// ambiguous ones, must disambiguate. See whether SUBOBJ is
|
||||
// contained publicly within one of the non-ambiguous choices.
|
||||
// If it is in only one, then that's the choice. If it is in
|
||||
// both, then we're ambiguous and fail. If it is in neither,
|
||||
// we're ambiguous, but don't yet fail as we might later find a
|
||||
// third base which does contain SUBPTR.
|
||||
|
||||
sub_kind new_sub_kind = result2.target2sub;
|
||||
sub_kind old_sub_kind = result.target2sub;
|
||||
|
||||
if (contained_nonvirtual_p (result.whole2sub))
|
||||
{
|
||||
// We already found SUBOBJ as a non-virtual base of most
|
||||
// derived. Therefore if it is in either choice, it can only be
|
||||
// in one of them, and we will already know.
|
||||
if (old_sub_kind == unknown)
|
||||
old_sub_kind = not_contained;
|
||||
if (new_sub_kind == unknown)
|
||||
new_sub_kind = not_contained;
|
||||
}
|
||||
else
|
||||
{
|
||||
const __user_type_info &t =
|
||||
static_cast <const __user_type_info &> (target);
|
||||
|
||||
if (old_sub_kind >= not_contained)
|
||||
;// already calculated
|
||||
else if (contained_nonvirtual_p (new_sub_kind))
|
||||
// Already found non-virtually inside the other choice,
|
||||
// cannot be in this.
|
||||
old_sub_kind = not_contained;
|
||||
else
|
||||
old_sub_kind = t.find_public_subobj (boff, subtype,
|
||||
result.target_obj, subptr);
|
||||
|
||||
if (new_sub_kind >= not_contained)
|
||||
;// already calculated
|
||||
else if (contained_nonvirtual_p (old_sub_kind))
|
||||
// Already found non-virtually inside the other choice,
|
||||
// cannot be in this.
|
||||
new_sub_kind = not_contained;
|
||||
else
|
||||
new_sub_kind = t.find_public_subobj (boff, subtype,
|
||||
result2.target_obj, subptr);
|
||||
}
|
||||
|
||||
// Neither sub_kind can be contained_ambig -- we bail out early
|
||||
// when we find those.
|
||||
if (contained_p (sub_kind (new_sub_kind ^ old_sub_kind)))
|
||||
{
|
||||
// Only on one choice, not ambiguous.
|
||||
if (contained_p (new_sub_kind))
|
||||
{
|
||||
// Only in new.
|
||||
result.target_obj = result2.target_obj;
|
||||
result.whole2target = result2.whole2target;
|
||||
result_ambig = false;
|
||||
old_sub_kind = new_sub_kind;
|
||||
}
|
||||
result.target2sub = old_sub_kind;
|
||||
if (result.target2sub == contained_public)
|
||||
return false; // Can't be an ambiguating downcast for later discovery.
|
||||
}
|
||||
else if (contained_p (sub_kind (new_sub_kind & old_sub_kind)))
|
||||
{
|
||||
// In both.
|
||||
result.target_obj = NULL;
|
||||
result.target2sub = contained_ambig;
|
||||
return true; // Fail.
|
||||
}
|
||||
else
|
||||
{
|
||||
// In neither publicly, ambiguous for the moment, but keep
|
||||
// looking. It is possible that it was private in one or
|
||||
// both and therefore we should fail, but that's just tough.
|
||||
result.target_obj = NULL;
|
||||
result.target2sub = not_contained;
|
||||
result_ambig = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (result.whole2sub == contained_private)
|
||||
// We found SUBOBJ as a private non-virtual base, therefore all
|
||||
// cross casts will fail. We have already found a down cast, if
|
||||
// there is one.
|
||||
return result_ambig;
|
||||
}
|
||||
|
||||
return result_ambig;
|
||||
}
|
||||
|
||||
// find_public_subobj helper for non-public or multiple inheritance types. See
|
||||
// __user_type_info::do_find_public_subobj for semantics. We make use of BOFF
|
||||
// to prune the base class walk.
|
||||
__user_type_info::sub_kind __class_type_info::
|
||||
do_find_public_subobj (int boff, const type_info &subtype, void *objptr, void *subptr) const
|
||||
{
|
||||
if (objptr == subptr && subtype == *this)
|
||||
return contained_public;
|
||||
|
||||
for (std::size_t i = n_bases; i--;)
|
||||
{
|
||||
if (base_list[i].access != PUBLIC)
|
||||
continue; // Not public, can't be here.
|
||||
void *p;
|
||||
|
||||
if (base_list[i].is_virtual && boff == -3)
|
||||
// Not a virtual base, so can't be here.
|
||||
continue;
|
||||
|
||||
p = convert_to_base (objptr,
|
||||
base_list[i].is_virtual,
|
||||
base_list[i].offset);
|
||||
|
||||
sub_kind base_kind = base_list[i].base->do_find_public_subobj
|
||||
(boff, subtype, p, subptr);
|
||||
if (contained_p (base_kind))
|
||||
{
|
||||
if (base_list[i].is_virtual)
|
||||
base_kind = sub_kind (base_kind | contained_virtual_mask);
|
||||
return base_kind;
|
||||
}
|
||||
}
|
||||
|
||||
return not_contained;
|
||||
}
|
||||
#else
|
||||
// new abi
|
||||
|
||||
namespace std {
|
||||
|
||||
// return true if this is a type_info for a pointer type
|
||||
@ -1212,4 +717,3 @@ __dynamic_cast (const void *src_ptr, // object started from
|
||||
}
|
||||
|
||||
}; // namespace __cxxabiv1
|
||||
#endif
|
||||
|
@ -1,225 +1,9 @@
|
||||
// RTTI support internals for -*- C++ -*-
|
||||
|
||||
// Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000 Free Software Foundation
|
||||
|
||||
// Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001 Free Software Foundation
|
||||
#include "typeinfo"
|
||||
#include <cstddef>
|
||||
|
||||
// Class declarations shared between the typeinfo implementation files.
|
||||
|
||||
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||
// original (old) abi
|
||||
|
||||
// type_info for a class with no base classes (or an enum).
|
||||
|
||||
struct __user_type_info : public std::type_info {
|
||||
__user_type_info (const char *n) : type_info (n) {}
|
||||
|
||||
// If our type can be upcast to a public and unambiguous base, then return
|
||||
// non-zero and set RES to point to the base object. OBJ points to the throw
|
||||
// object and can be NULL, if there is no object to adjust.
|
||||
int upcast (const type_info &target, void *obj, void **res) const;
|
||||
|
||||
// If our type can be dynamicly cast to the target type, then return
|
||||
// pointer to the target object. OBJ is the pointer to the most derived
|
||||
// type and cannot be NULL. SUBTYPE and SUBOBJ indicate the static type
|
||||
// base object from whence we came, it cannot be NULL. SUBTYPE cannot be
|
||||
// the same as TARGET. TARGET cannot be a base of SUBTYPE.
|
||||
// BOFF indicates how SUBTYPE is related to TARGET.
|
||||
// BOFF >= 0, there is only one public non-virtual SUBTYPE base at offset
|
||||
// BOFF, and there are no public virtual SUBTYPE bases.
|
||||
// Therefore check if SUBOBJ is at offset BOFF when we find a target
|
||||
// BOFF == -1, SUBTYPE occurs as multiple public virtual or non-virtual bases.
|
||||
// Lazily search all the bases of TARGET.
|
||||
// BOFF == -2, SUBTYPE is not a public base.
|
||||
// BOFF == -3, SUBTYPE occurs as multiple public non-virtual bases.
|
||||
// Lazily search the non-virtual bases of TARGET.
|
||||
// For backwards compatibility set BOFF to -1, that is the safe "unknown"
|
||||
// value. We do not care about SUBTYPES as private bases of TARGET, as they
|
||||
// can never succeed as downcasts, only as crosscasts -- and then only if
|
||||
// they are virtual. This is more complicated that it might seem.
|
||||
void *dyncast (int boff,
|
||||
const type_info &target, void *obj,
|
||||
const type_info &subtype, void *subobj) const;
|
||||
|
||||
// non_virtual_base_type is used to indicate that a base class is via a
|
||||
// non-virtual access path.
|
||||
static const type_info *const nonvirtual_base_type
|
||||
= static_cast <const type_info *> (0) + 1;
|
||||
|
||||
// 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.
|
||||
enum sub_kind
|
||||
{
|
||||
unknown = 0, // we have no idea
|
||||
not_contained, // not contained within us (in some
|
||||
// circumstances this might mean not contained
|
||||
// publicly)
|
||||
contained_ambig, // contained ambiguously
|
||||
contained_mask = 4, // contained within us
|
||||
contained_virtual_mask = 1, // via a virtual path
|
||||
contained_public_mask = 2, // via a public path
|
||||
contained_private = contained_mask,
|
||||
contained_public = contained_mask | contained_public_mask
|
||||
};
|
||||
// some predicate functions for sub_kind
|
||||
static inline bool contained_p (sub_kind access_path)
|
||||
{
|
||||
return access_path >= contained_mask;
|
||||
}
|
||||
static inline bool contained_public_p (sub_kind access_path)
|
||||
{
|
||||
return access_path >= contained_public;
|
||||
}
|
||||
static inline bool contained_nonpublic_p (sub_kind access_path)
|
||||
{
|
||||
return (access_path & contained_public) == contained_mask;
|
||||
}
|
||||
static inline bool contained_nonvirtual_p (sub_kind access_path)
|
||||
{
|
||||
return (access_path & (contained_mask | contained_virtual_mask))
|
||||
== contained_mask;
|
||||
}
|
||||
static inline bool contained_virtual_p (sub_kind access_path)
|
||||
{
|
||||
return (access_path & (contained_mask | contained_virtual_mask))
|
||||
== (contained_mask | contained_virtual_mask);
|
||||
}
|
||||
|
||||
struct upcast_result
|
||||
{
|
||||
void *target_obj; // pointer to target object or NULL (init NULL)
|
||||
sub_kind whole2target; // path from most derived object to target
|
||||
const type_info *base_type; // where we found the target, (init NULL)
|
||||
// if in vbase the __user_type_info of vbase)
|
||||
// if a non-virtual base then 1
|
||||
// else NULL
|
||||
public:
|
||||
upcast_result ()
|
||||
:target_obj (NULL), whole2target (unknown), base_type (NULL)
|
||||
{}
|
||||
};
|
||||
struct dyncast_result
|
||||
{
|
||||
void *target_obj; // pointer to target object or NULL (init NULL)
|
||||
sub_kind whole2target; // path from most derived object to target
|
||||
sub_kind whole2sub; // path from most derived object to sub object
|
||||
sub_kind target2sub; // path from target to sub object
|
||||
|
||||
public:
|
||||
dyncast_result ()
|
||||
:target_obj (NULL), whole2target (unknown),
|
||||
whole2sub (unknown), target2sub (unknown)
|
||||
{}
|
||||
};
|
||||
|
||||
public:
|
||||
// Helper for upcast. See if TARGET is us, or one of our bases. ACCESS_PATH
|
||||
// gives the access from the start object. Return TRUE if we know the catch
|
||||
// fails.
|
||||
virtual bool do_upcast (sub_kind access_path,
|
||||
const type_info &target, void *obj,
|
||||
upcast_result &__restrict result) const;
|
||||
// Helper for dyncast. BOFF indicates how the SUBTYPE is related to TARGET.
|
||||
// ACCESS_PATH indicates the access from the most derived object. It is
|
||||
// used to prune the DAG walk. All information about what we find is put
|
||||
// into RESULT. Return true, if the match we have found is ambiguous.
|
||||
virtual bool do_dyncast (int boff, sub_kind access_path,
|
||||
const type_info &target, void *obj,
|
||||
const type_info &subtype, void *subptr,
|
||||
dyncast_result &__restrict result) const;
|
||||
public:
|
||||
// Indicate whether SUBPTR of type SUBTYPE is contained publicly within
|
||||
// OBJPTR. OBJPTR points to this base object. BOFF indicates how SUBTYPE
|
||||
// objects might be contained within this type. If SUBPTR is one of our
|
||||
// SUBTYPE bases, indicate virtuality. Returns not_contained for non
|
||||
// containment or private containment.
|
||||
sub_kind find_public_subobj (int boff, const type_info &subtype,
|
||||
void *objptr, void *subptr) const
|
||||
{
|
||||
if (boff >= 0)
|
||||
return ((char *)subptr - (char *)objptr) == boff
|
||||
? contained_public : not_contained;
|
||||
if (boff == -2)
|
||||
return not_contained;
|
||||
return do_find_public_subobj (boff, subtype, objptr, subptr);
|
||||
}
|
||||
|
||||
public:
|
||||
// Helper for find_subobj. BOFF indicates how SUBTYPE bases are inherited by
|
||||
// the type started from -- which is not necessarily the current type.
|
||||
// OBJPTR points to the current base.
|
||||
virtual sub_kind do_find_public_subobj (int boff, const type_info &subtype,
|
||||
void *objptr, void *subptr) const;
|
||||
};
|
||||
|
||||
// type_info for a class with one public, nonvirtual base class.
|
||||
|
||||
class __si_type_info : public __user_type_info {
|
||||
const __user_type_info &base;
|
||||
|
||||
public:
|
||||
__si_type_info (const char *n, const __user_type_info &b)
|
||||
: __user_type_info (n), base (b) { }
|
||||
|
||||
private:
|
||||
virtual bool do_upcast (sub_kind access_path,
|
||||
const type_info &target, void *obj,
|
||||
upcast_result &__restrict result) const;
|
||||
virtual bool do_dyncast (int boff, sub_kind access_path,
|
||||
const type_info &target, void *obj,
|
||||
const type_info &subtype, void *subptr,
|
||||
dyncast_result &__restrict result) const;
|
||||
virtual sub_kind do_find_public_subobj (int boff, const type_info &subtype,
|
||||
void *objptr, void *subptr) const;
|
||||
};
|
||||
|
||||
// type_info for a general class.
|
||||
|
||||
#include <climits>
|
||||
|
||||
#if INT_MAX == 2147483647
|
||||
typedef int myint32;
|
||||
#elif SHRT_MAX == 2147483647
|
||||
typedef short myint32;
|
||||
#elif SCHAR_MAX == 2147483647
|
||||
typedef signed char myint32;
|
||||
#elif LONG_MAX == 2147483647
|
||||
typedef long myint32;
|
||||
#else
|
||||
# error "No 32-bit data type?"
|
||||
#endif
|
||||
|
||||
struct __class_type_info : public __user_type_info {
|
||||
enum access { PUBLIC = 1, PROTECTED = 2, PRIVATE = 3 };
|
||||
|
||||
struct base_info {
|
||||
const __user_type_info *base;
|
||||
myint32 offset: 29;
|
||||
bool is_virtual: 1;
|
||||
enum access access: 2;
|
||||
};
|
||||
|
||||
const base_info *base_list;
|
||||
std::size_t n_bases;
|
||||
|
||||
__class_type_info (const char *name, const base_info *bl, std::size_t bn)
|
||||
: __user_type_info (name), base_list (bl), n_bases (bn) {}
|
||||
|
||||
public:
|
||||
virtual bool do_upcast (sub_kind access_path,
|
||||
const type_info &target, void *obj,
|
||||
upcast_result &__restrict result) const;
|
||||
virtual bool do_dyncast (int boff, sub_kind access_path,
|
||||
const type_info &target, void *obj,
|
||||
const type_info &subtype, void *subptr,
|
||||
dyncast_result &__restrict result) const;
|
||||
virtual sub_kind do_find_public_subobj (int boff, const type_info &subtype,
|
||||
void *objptr, void *subptr) const;
|
||||
};
|
||||
#else
|
||||
// new abi
|
||||
#include <cxxabi.h>
|
||||
|
||||
#endif
|
||||
|
@ -48,65 +48,8 @@ type_info::before (const type_info &arg) const
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||
|
||||
// type info for pointer type.
|
||||
|
||||
struct __pointer_type_info : public type_info {
|
||||
const type_info& type;
|
||||
|
||||
__pointer_type_info (const char *n, const type_info& ti)
|
||||
: type_info (n), type (ti) {}
|
||||
};
|
||||
|
||||
// type info for attributes
|
||||
|
||||
struct __attr_type_info : public type_info {
|
||||
enum cv { NONE = 0, CONST = 1, VOLATILE = 2, CONSTVOL = 1 | 2 };
|
||||
|
||||
const type_info& type;
|
||||
cv attr;
|
||||
|
||||
__attr_type_info (const char *n, cv a, const type_info& t)
|
||||
: type_info (n), type (t), attr (a) {}
|
||||
};
|
||||
|
||||
// type_info for builtin type
|
||||
|
||||
struct __builtin_type_info : public type_info {
|
||||
__builtin_type_info (const char *n): type_info (n) {}
|
||||
};
|
||||
|
||||
// type info for function.
|
||||
|
||||
struct __func_type_info : public type_info {
|
||||
__func_type_info (const char *n) : type_info (n) {}
|
||||
};
|
||||
|
||||
// type info for pointer to member function.
|
||||
|
||||
struct __ptmf_type_info : public type_info {
|
||||
__ptmf_type_info (const char *n) : type_info (n) {}
|
||||
};
|
||||
|
||||
// type info for pointer to data member.
|
||||
|
||||
struct __ptmd_type_info : public type_info {
|
||||
__ptmd_type_info (const char *n): type_info (n) {}
|
||||
};
|
||||
|
||||
// type info for array.
|
||||
|
||||
struct __array_type_info : public type_info {
|
||||
__array_type_info (const char *n): type_info (n) {}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#include <cxxabi.h>
|
||||
#endif
|
||||
|
||||
#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
|
||||
namespace __cxxabiv1 {
|
||||
|
||||
using namespace std;
|
||||
@ -222,7 +165,6 @@ __pointer_catch (const __pbase_type_info *thr_type,
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
#endif
|
||||
|
||||
// Entry points for the compiler.
|
||||
|
||||
@ -238,141 +180,9 @@ __throw_type_match_rtti_2 (const void *catch_type_r, const void *throw_type_r,
|
||||
|
||||
*valp = objptr;
|
||||
|
||||
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||
// old abi
|
||||
if (catch_type == throw_type)
|
||||
return 1;
|
||||
|
||||
if (const __user_type_info *p
|
||||
= dynamic_cast <const __user_type_info *> (&throw_type))
|
||||
{
|
||||
return p->upcast (catch_type, objptr, valp);
|
||||
}
|
||||
else if (const __pointer_type_info *fr =
|
||||
dynamic_cast <const __pointer_type_info *> (&throw_type))
|
||||
{
|
||||
const __pointer_type_info *to =
|
||||
dynamic_cast <const __pointer_type_info *> (&catch_type);
|
||||
|
||||
if (! to)
|
||||
return 0;
|
||||
|
||||
const type_info *subfr = &fr->type, *subto = &to->type;
|
||||
__attr_type_info::cv cvfrom, cvto;
|
||||
|
||||
if (const __attr_type_info *at
|
||||
= dynamic_cast <const __attr_type_info *> (subfr))
|
||||
{
|
||||
cvfrom = at->attr;
|
||||
subfr = &at->type;
|
||||
}
|
||||
else
|
||||
cvfrom = __attr_type_info::NONE;
|
||||
|
||||
if (const __attr_type_info *at
|
||||
= dynamic_cast <const __attr_type_info *> (subto))
|
||||
{
|
||||
cvto = at->attr;
|
||||
subto = &at->type;
|
||||
}
|
||||
else
|
||||
cvto = __attr_type_info::NONE;
|
||||
|
||||
if (((cvfrom & __attr_type_info::CONST)
|
||||
> (cvto & __attr_type_info::CONST))
|
||||
|| ((cvfrom & __attr_type_info::VOLATILE)
|
||||
> (cvto & __attr_type_info::VOLATILE)))
|
||||
return 0;
|
||||
|
||||
if (*subto == *subfr)
|
||||
return 1;
|
||||
else if (*subto == typeid (void)
|
||||
&& dynamic_cast <const __func_type_info *> (subfr) == 0)
|
||||
return 1;
|
||||
else if (const __user_type_info *p
|
||||
= dynamic_cast <const __user_type_info *> (subfr))
|
||||
return p->upcast (*subto, objptr, valp);
|
||||
else if (const __pointer_type_info *pfr
|
||||
= dynamic_cast <const __pointer_type_info *> (subfr))
|
||||
{
|
||||
// Multi-level pointer conversion.
|
||||
|
||||
const __pointer_type_info *pto
|
||||
= dynamic_cast <const __pointer_type_info *> (subto);
|
||||
|
||||
if (! pto)
|
||||
return 0;
|
||||
|
||||
bool constp = (cvto & __attr_type_info::CONST);
|
||||
for (subto = &pto->type, subfr = &pfr->type; ;
|
||||
subto = &pto->type, subfr = &pfr->type)
|
||||
{
|
||||
if (const __attr_type_info *at
|
||||
= dynamic_cast <const __attr_type_info *> (subfr))
|
||||
{
|
||||
cvfrom = at->attr;
|
||||
subfr = &at->type;
|
||||
}
|
||||
else
|
||||
cvfrom = __attr_type_info::NONE;
|
||||
|
||||
if (const __attr_type_info *at
|
||||
= dynamic_cast <const __attr_type_info *> (subto))
|
||||
{
|
||||
cvto = at->attr;
|
||||
subto = &at->type;
|
||||
}
|
||||
else
|
||||
cvto = __attr_type_info::NONE;
|
||||
|
||||
if (((cvfrom & __attr_type_info::CONST)
|
||||
> (cvto & __attr_type_info::CONST))
|
||||
|| ((cvfrom & __attr_type_info::VOLATILE)
|
||||
> (cvto & __attr_type_info::VOLATILE)))
|
||||
return 0;
|
||||
|
||||
if (! constp
|
||||
&& (((cvfrom & __attr_type_info::CONST)
|
||||
< (cvto & __attr_type_info::CONST))
|
||||
|| ((cvfrom & __attr_type_info::VOLATILE)
|
||||
< (cvto & __attr_type_info::VOLATILE))))
|
||||
return 0;
|
||||
|
||||
if (*subto == *subfr)
|
||||
return 1;
|
||||
|
||||
pto = dynamic_cast <const __pointer_type_info *> (subto);
|
||||
pfr = dynamic_cast <const __pointer_type_info *> (subfr);
|
||||
if (! pto || ! pfr)
|
||||
return 0;
|
||||
|
||||
if (! (cvto & __attr_type_info::CONST))
|
||||
constp = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
// new abi
|
||||
|
||||
return catch_type.__do_catch (&throw_type, valp, 1);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||
/* Backward compatibility wrapper. */
|
||||
|
||||
extern "C" void*
|
||||
__throw_type_match_rtti (const void *catch_type_r, const void *throw_type_r,
|
||||
void *objptr)
|
||||
{
|
||||
void *ret;
|
||||
if (__throw_type_match_rtti_2 (catch_type_r, throw_type_r, objptr, &ret))
|
||||
return ret;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Called from __cp_pop_exception. Is P the type_info node for a pointer
|
||||
of some kind? */
|
||||
|
||||
@ -380,80 +190,6 @@ bool
|
||||
__is_pointer (void *p)
|
||||
{
|
||||
const type_info *t = reinterpret_cast <const type_info *>(p);
|
||||
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||
// old abi
|
||||
const __pointer_type_info *pt =
|
||||
dynamic_cast <const __pointer_type_info *> (t);
|
||||
return pt != 0;
|
||||
#else
|
||||
// new abi
|
||||
return t->__is_pointer_p ();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||
// old abi
|
||||
|
||||
extern "C" void
|
||||
__rtti_ptr (void *addr, const char *n, const type_info *ti)
|
||||
{ new (addr) __pointer_type_info (n, *ti); }
|
||||
|
||||
extern "C" void
|
||||
__rtti_attr (void *addr, const char *n, int attrval, const type_info *ti)
|
||||
{
|
||||
new (addr) __attr_type_info
|
||||
(n, static_cast <__attr_type_info::cv> (attrval), *ti);
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
__rtti_func (void *addr, const char *name)
|
||||
{ new (addr) __func_type_info (name); }
|
||||
|
||||
extern "C" void
|
||||
__rtti_ptmf (void *addr, const char *name)
|
||||
{ new (addr) __ptmf_type_info (name); }
|
||||
|
||||
extern "C" void
|
||||
__rtti_ptmd (void *addr, const char *name)
|
||||
{ new (addr) __ptmd_type_info (name); }
|
||||
|
||||
extern "C" void
|
||||
__rtti_array (void *addr, const char *name)
|
||||
{ new (addr) __array_type_info (name); }
|
||||
|
||||
extern "C" void *
|
||||
__dynamic_cast (const type_info& (*from)(void), const type_info& (*to)(void),
|
||||
int require_public, void *address, const type_info & (*sub)(void), void *subptr)
|
||||
{
|
||||
if (!require_public) abort();
|
||||
return static_cast <__user_type_info const &> (from ()).dyncast
|
||||
(/*boff=*/-1, to (), address, sub (), subptr);
|
||||
}
|
||||
|
||||
extern "C" void *
|
||||
__dynamic_cast_2 (const type_info& (*from)(void), const type_info& (*to)(void),
|
||||
int boff,
|
||||
void *address, const type_info & (*sub)(void), void *subptr)
|
||||
{
|
||||
return static_cast <__user_type_info const &> (from ()).dyncast
|
||||
(boff, to (), address, sub (), subptr);
|
||||
}
|
||||
|
||||
// type_info nodes and functions for the builtin types. The mangling here
|
||||
// must match the mangling in gcc/cp/rtti.c.
|
||||
|
||||
#define BUILTIN(mangled) \
|
||||
unsigned char __ti##mangled [sizeof (__builtin_type_info)] \
|
||||
__attribute__ ((aligned (__alignof__ (void *)))); \
|
||||
extern "C" const type_info &__tf##mangled (void) { \
|
||||
if ((*(void **) __ti##mangled) == 0) \
|
||||
new (__ti##mangled) __builtin_type_info (#mangled); \
|
||||
return *(type_info *)__ti##mangled; \
|
||||
}
|
||||
|
||||
BUILTIN (v); BUILTIN (x); BUILTIN (l); BUILTIN (i); BUILTIN (s); BUILTIN (b);
|
||||
BUILTIN (c); BUILTIN (w); BUILTIN (r); BUILTIN (d); BUILTIN (f);
|
||||
BUILTIN (Ui); BUILTIN (Ul); BUILTIN (Ux); BUILTIN (Us); BUILTIN (Uc);
|
||||
BUILTIN (Sc);
|
||||
|
||||
#endif
|
||||
|
@ -1,6 +1,5 @@
|
||||
// RTTI support for -*- C++ -*-
|
||||
|
||||
// Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000 Free Software Foundation
|
||||
// Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001 Free Software Foundation
|
||||
//
|
||||
// This file is part of GNU CC.
|
||||
//
|
||||
@ -28,11 +27,6 @@
|
||||
// invalidate any other reasons why the executable file might be covered by
|
||||
// the GNU General Public License.
|
||||
|
||||
// __GXX_ABI_VERSION distinguishes the ABI that is being used. Values <100
|
||||
// indicate the `old' abi, which grew as C++ was defined. Values >=100
|
||||
// indicate the `new' abi, which is a cross vendor C++ abi, documented at
|
||||
// `http://reality.sgi.com/dehnert_engr/cxx/'.
|
||||
|
||||
#ifndef __TYPEINFO__
|
||||
#define __TYPEINFO__
|
||||
|
||||
@ -42,23 +36,16 @@
|
||||
|
||||
extern "C++" {
|
||||
|
||||
#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
|
||||
namespace __cxxabiv1
|
||||
{
|
||||
class __class_type_info;
|
||||
} // namespace __cxxabiv1
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||
// In the old ABI, typeinfo name strings were not merged.
|
||||
#define __GXX_MERGED_TYPEINFO_NAMES 0
|
||||
#elif !__GXX_WEAK__
|
||||
// If weak symbols are not supported, they are still not merged.
|
||||
#if !__GXX_WEAK__
|
||||
// If weak symbols are not supported, typeinfo names are not merged.
|
||||
#define __GXX_MERGED_TYPEINFO_NAMES 0
|
||||
#else
|
||||
// In the new ABI, on platforms that support weak symbols, they are
|
||||
// merged.
|
||||
// On platforms that support weak symbols, typeinfo names are merged.
|
||||
#define __GXX_MERGED_TYPEINFO_NAMES 1
|
||||
#endif
|
||||
|
||||
@ -86,13 +73,8 @@ namespace std
|
||||
|
||||
public:
|
||||
// the public interface
|
||||
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||
const char* name() const
|
||||
{ return __name; }
|
||||
#else
|
||||
const char* name() const
|
||||
{ return __name; }
|
||||
#endif
|
||||
|
||||
#if !__GXX_MERGED_TYPEINFO_NAMES
|
||||
bool before(const type_info& arg) const;
|
||||
@ -112,7 +94,6 @@ namespace std
|
||||
{ return !operator==(__arg); }
|
||||
|
||||
// the internal interface
|
||||
#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
|
||||
public:
|
||||
// return true if this is a pointer type of some kind
|
||||
virtual bool __is_pointer_p() const;
|
||||
@ -131,7 +112,6 @@ namespace std
|
||||
// internally used during catch matching
|
||||
virtual bool __do_upcast(const __cxxabiv1::__class_type_info *__target,
|
||||
void **__obj_ptr) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
class bad_cast : public exception
|
||||
|
@ -298,3 +298,4 @@ namespace __cxxabiv1
|
||||
dealloc(base, size);
|
||||
}
|
||||
} // namespace __cxxabiv1
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user