Commit 808c61c8 by Nathan Sidwell Committed by Nathan Sidwell

cp-tree.h (new_abi_rtti_p): Use flag_new_abi.

	* cp-tree.h (new_abi_rtti_p): Use flag_new_abi.

	Runtime support for new-abi rtti.
	* inc/typeinfo (type_info::operator!=): Define in class.
	(type_info::before, type_info::name, type_info::operator==,
	type_info::operator!=): Define new ABI implementations.
	(type_info::is_pointer_p, type_info::is_function_p): Declare
	new virtual functions.
	(type_info::do_catch, type_info::do_upcast): Likewise.

	* tinfo.h (__base_class_info): Define new class.
	(__class_type_info): Likewise.
	(__si_class_type_info): Likewise.
	(__vmi_class_type_info): Likewise.
	(__dynamic_cast): Prototype.

	* tinfo.cc: Conditionalize old and new rtti mechanisms.
	(type_info::is_pointer_p): Define new function.
	(type_info::is_function_p): Likewise.
	(type_info::do_catch): Likewise.
	(type_info::do_upcast): Likewise.
	(vtable_prefix): New structure for vtable access.
	(adjust_pointer): Define new template function.
	(contained_p, public_p, virtual_p, contained_public_p,
	contained_nonpublic_p, contained_nonvirtual_p): Define new
	functions.
	(nonvirtual_base_type): New local variable.
	(__class_type_info::~__class_type_info): Define.
	(__si_class_type_info::~__si_class_type_info): Likewise.
	(__vmi_class_type_info::~__vmi_class_type_info): Likewise.
	(__class_type_info::do_catch): Define new function.
	(__class_type_info::do_upcast): Likewise.
	(__class_type_info::find_public_src): Likewise.
	(__class_type_info::do_find_public_src): Likewise.
	(__si_class_type_info::do_find_public_src): Likewise.
	(__vmi_class_type_info::do_find_public_src): Likewise.
	(__class_type_info::do_dyncast): Likewise.
	(__si_class_type_info::do_dyncast): Likewise.
	(__vmi_class_type_info::do_dyncast): Likewise.
	(__class_type_info::do_upcast): Likewise.
	(__si_class_type_info::do_upcast): Likewise.
	(__vmi_class_type_info::do_upcast): Likewise.
	(__dynamic_cast): Likewise.

	* tinfo2.cc (__fundamental_type_info): Define new class.
	(__pointer_type_info): Likewise.
	(__reference_type_info): Likewise.
	(__array_type_info): Likewise.
	(__function_type_info): Likewise.
	(__enum_type_info): Likewise.
	(__ptr_to_member_type_info): Likewise.
	(__fundamental_type_info::~__fundamental_type_info): Define.
	(__pointer_type_info::~__pointer_type_info): Likewise.
	(__reference_type_info::~__reference_type_info): Likewise.
	(__array_type_info::~__array_type_info): Likewise.
	(__function_type_info::~__function_type_info): Likewise.
	(__enum_type_info::~__enum_type_info): Likewise.
	(__ptr_to_member_type_info::~__ptr_to_member_type_info): Likewise.
	(__pointer_type_info::do_catch): Define new function.
	(__ptr_to_member_type_info::do_catch): Define new function.

	(__throw_type_match_rtti_2): Use new ABI interface, if enabled.
	(__is_pointer): Likewise.

	* exception.cc (__cplus_type_matcher): Deal with new-abi rtti.

From-SVN: r31713
parent ab5cffc5
2000-01-31 Nathan Sidwell <sidwell@codesourcery.com>
* cp-tree.h (new_abi_rtti_p): Use flag_new_abi.
Runtime support for new-abi rtti.
* inc/typeinfo (type_info::operator!=): Define in class.
(type_info::before, type_info::name, type_info::operator==,
type_info::operator!=): Define new ABI implementations.
(type_info::is_pointer_p, type_info::is_function_p): Declare
new virtual functions.
(type_info::do_catch, type_info::do_upcast): Likewise.
* tinfo.h (__base_class_info): Define new class.
(__class_type_info): Likewise.
(__si_class_type_info): Likewise.
(__vmi_class_type_info): Likewise.
(__dynamic_cast): Prototype.
* tinfo.cc: Conditionalize old and new rtti mechanisms.
(type_info::is_pointer_p): Define new function.
(type_info::is_function_p): Likewise.
(type_info::do_catch): Likewise.
(type_info::do_upcast): Likewise.
(vtable_prefix): New structure for vtable access.
(adjust_pointer): Define new template function.
(contained_p, public_p, virtual_p, contained_public_p,
contained_nonpublic_p, contained_nonvirtual_p): Define new
functions.
(nonvirtual_base_type): New local variable.
(__class_type_info::~__class_type_info): Define.
(__si_class_type_info::~__si_class_type_info): Likewise.
(__vmi_class_type_info::~__vmi_class_type_info): Likewise.
(__class_type_info::do_catch): Define new function.
(__class_type_info::do_upcast): Likewise.
(__class_type_info::find_public_src): Likewise.
(__class_type_info::do_find_public_src): Likewise.
(__si_class_type_info::do_find_public_src): Likewise.
(__vmi_class_type_info::do_find_public_src): Likewise.
(__class_type_info::do_dyncast): Likewise.
(__si_class_type_info::do_dyncast): Likewise.
(__vmi_class_type_info::do_dyncast): Likewise.
(__class_type_info::do_upcast): Likewise.
(__si_class_type_info::do_upcast): Likewise.
(__vmi_class_type_info::do_upcast): Likewise.
(__dynamic_cast): Likewise.
* tinfo2.cc (__fundamental_type_info): Define new class.
(__pointer_type_info): Likewise.
(__reference_type_info): Likewise.
(__array_type_info): Likewise.
(__function_type_info): Likewise.
(__enum_type_info): Likewise.
(__ptr_to_member_type_info): Likewise.
(__fundamental_type_info::~__fundamental_type_info): Define.
(__pointer_type_info::~__pointer_type_info): Likewise.
(__reference_type_info::~__reference_type_info): Likewise.
(__array_type_info::~__array_type_info): Likewise.
(__function_type_info::~__function_type_info): Likewise.
(__enum_type_info::~__enum_type_info): Likewise.
(__ptr_to_member_type_info::~__ptr_to_member_type_info): Likewise.
(__pointer_type_info::do_catch): Define new function.
(__ptr_to_member_type_info::do_catch): Define new function.
(__throw_type_match_rtti_2): Use new ABI interface, if enabled.
(__is_pointer): Likewise.
* exception.cc (__cplus_type_matcher): Deal with new-abi rtti.
2000-01-30 Mark Mitchell <mark@codesourcery.com>
* cp/class.c (build_vtable): Rename to build_primary_vtable.
......
......@@ -244,7 +244,7 @@ extern int flag_rtti;
/* Nonzero if we use access type_info objects directly, and use the
cross-vendor layout for them. Zero if we use an accessor function
to get the type_info object address. */
#define new_abi_rtti_p() (0)
#define new_abi_rtti_p() (flag_new_abi)
/* Language-dependent contents of an identifier. */
......
......@@ -184,7 +184,11 @@ __cplus_type_matcher (__eh_info *info_, void *match_info,
/* we don't worry about version info yet, there is only one version! */
void *match_type = ((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))
......
// RTTI support for -*- C++ -*-
// Copyright (C) 1994, 95-97, 1998 Free Software Foundation
// Copyright (C) 1994, 95-97, 1998, 2000 Free Software Foundation
// __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__
......@@ -12,33 +17,74 @@ extern "C++" {
namespace std {
#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
class __class_type_info;
#endif
class type_info {
public:
// Destructor. Being the first non-inline virtual function, this controls in
// which translation unit the vtable is emitted. The compiler makes use of
// that information to know where to emit the runtime-mandated type_info
// structures in the new-abi.
virtual ~type_info ();
private:
// assigning type_info is not supported. made private.
// Assigning type_info is not supported. made private.
type_info& operator= (const type_info&);
type_info (const type_info&);
protected:
explicit type_info (const char *n): _name (n) { }
const char *_name;
public:
// destructor
virtual ~type_info ();
protected:
explicit type_info (const char *n): _name (n) { }
public:
// the public interface
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
// In old abi, there can be multiple instances of a type_info object for one
// type. Uniqueness must use the _name value, not object address.
bool before (const type_info& arg) const;
const char* name () const
{ return _name; }
bool operator== (const type_info& arg) const;
bool operator!= (const type_info& arg) const;
};
bool operator!= (const type_info& arg) const
{ return !operator== (arg); }
#else
// In new abi we can rely on type_info's being unique,
// and therefore address comparisons are sufficient.
bool before (const type_info& arg) const
{ return this < &arg; }
const char* name () const
{ return _name; }
bool operator== (const type_info& arg) const
{ return &arg == this; }
bool operator!= (const type_info& arg) const
{ return !operator== (arg); }
#endif
inline bool type_info::
operator!= (const type_info& arg) const
{
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;
// return true if this is a function type
virtual bool is_function_p () const;
// Try and catch a thrown type. Store an adjusted pointer to the caught type
// in THR_OBJ. If THR_TYPE is not a pointer type, then THR_OBJ points to the
// thrown object. If THR_TYPE is a pointer type, then THR_OBJ is the pointer
// itself. OUTER indicates the number of outer pointers, and whether they
// were const qualified.
virtual bool do_catch (const type_info *thr_type, void **thr_obj,
unsigned outer) const;
// internally used during catch matching
virtual bool do_upcast (const __class_type_info *target, void **obj_ptr) const;
#endif
};
class bad_cast : public exception {
public:
......
......@@ -31,6 +31,7 @@
using std::type_info;
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
bool
type_info::before (const type_info &arg) const
{
......@@ -88,6 +89,248 @@ struct __array_type_info : public type_info {
__array_type_info (const char *n): type_info (n) {}
};
#else
namespace std {
// type information for int, float etc
class __fundamental_type_info : public type_info {
public:
virtual ~__fundamental_type_info ();
public:
explicit __fundamental_type_info (const char *n)
: type_info (n)
{ }
};
// type information for pointer to data or function, but not pointer to member
class __pointer_type_info : public type_info {
public:
virtual ~__pointer_type_info ();
// external parts
int quals; // qualification of the target object
const type_info *target; // type of object being pointed to
// internal parts
enum quals_masks {
const_mask = 0x1,
volatile_mask = 0x2
};
public:
explicit __pointer_type_info (const char *n,
int quals_,
const type_info *target_)
: type_info (n), quals (quals_), target (target_)
{ }
protected:
virtual bool is_pointer_p () const;
virtual bool do_catch (const type_info *thr_type, void **thr_obj,
unsigned outer) const;
};
// type information for reference to data
class __reference_type_info : public type_info {
public:
virtual ~__reference_type_info ();
int quals; // qualification of the target object
const type_info *target; // type of object being referenced
// internal parts
enum quals_masks {
const_mask = 0x1,
volatile_mask = 0x2
};
public:
explicit __reference_type_info (const char *n,
int quals_,
const type_info *target_)
: type_info (n), quals (quals_), target (target_)
{ }
};
// type information for array objects
class __array_type_info : public type_info {
public:
virtual ~__array_type_info ();
public:
explicit __array_type_info (const char *n)
: type_info (n)
{ }
};
// type information for functions (both member and non-member)
class __function_type_info : public type_info {
public:
virtual ~__function_type_info ();
public:
explicit __function_type_info (const char *n)
: type_info (n)
{ }
protected:
virtual bool is_function_p () const;
};
// type information for enumerations
class __enum_type_info : public type_info {
public:
virtual ~__enum_type_info ();
public:
explicit __enum_type_info (const char *n)
: type_info (n)
{ }
};
// type information for a pointer to member variable (not function)
class __ptr_to_member_type_info : public type_info {
public:
virtual ~__ptr_to_member_type_info ();
// external parts
const __class_type_info *klass; // class of the member
const type_info *type; // type of the member
int quals; // qualifications of the pointed to type
// internal parts
enum quals_masks {
const_mask = 0x1,
volatile_mask = 0x2
};
public:
explicit __ptr_to_member_type_info (const char *n,
const __class_type_info *klass_,
const type_info *type_,
int quals_)
: type_info (n), klass (klass_), type (type_), quals (quals_)
{ }
protected:
virtual bool do_catch (const type_info *thr_type, void **thr_obj,
unsigned outer) const;
};
}; // namespace std
#endif
#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
namespace std {
// This has special meaning to the compiler, and will cause it
// to emit the type_info structures for the fundamental types which are
// mandated to exist in the runtime.
__fundamental_type_info::
~__fundamental_type_info ()
{}
__pointer_type_info::
~__pointer_type_info ()
{}
__reference_type_info::
~__reference_type_info ()
{}
__array_type_info::
~__array_type_info ()
{}
__function_type_info::
~__function_type_info ()
{}
__enum_type_info::
~__enum_type_info ()
{}
__ptr_to_member_type_info::
~__ptr_to_member_type_info ()
{}
bool __pointer_type_info::
is_pointer_p () const
{
return true;
}
bool __function_type_info::
is_function_p () const
{
return true;
}
bool __pointer_type_info::
do_catch (const type_info *thr_type,
void **thr_obj,
unsigned outer) const
{
if (*this == *thr_type)
return true; // same type
if (typeid (*this) != typeid (*thr_type))
return false; // not both pointers
if (!(outer & 1))
// We're not the same and our outer pointers are not all const qualified
// Therefore there must at least be a qualification conversion involved
// But for that to be valid, our outer pointers must be const qualified.
return false;
const __pointer_type_info *thrown_type =
static_cast <const __pointer_type_info *> (thr_type);
if (thrown_type->quals & ~quals)
// We're less qualified.
return false;
if (!(quals & const_mask))
outer &= ~1;
if (outer < 2 && *target == typeid (void))
{
// conversion to void
return !thrown_type->is_function_p ();
}
return target->do_catch (thrown_type->target, thr_obj, outer + 2);
}
bool __ptr_to_member_type_info::
do_catch (const type_info *thr_type,
void **thr_obj,
unsigned outer) const
{
if (*this == *thr_type)
return true; // same type
if (typeid (*this) != typeid (*thr_type))
return false; // not both pointers to member
if (!(outer & 1))
// We're not the same and our outer pointers are not all const qualified
// Therefore there must at least be a qualification conversion involved.
// But for that to be valid, our outer pointers must be const qualified.
return false;
const __ptr_to_member_type_info *thrown_type =
static_cast <const __ptr_to_member_type_info *> (thr_type);
if (thrown_type->quals & ~quals)
// We're less qualified.
return false;
if (!(quals & const_mask))
outer &= ~1;
if (*klass != *thrown_type->klass)
return false; // not pointers to member of same class
return type->do_catch (thrown_type->type, thr_obj, outer + 2);
}
} // namespace std
#endif
// Entry points for the compiler.
/* Low level match routine used by compiler to match types of catch
......@@ -102,6 +345,8 @@ __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;
......@@ -213,10 +458,15 @@ __throw_type_match_rtti_2 (const void *catch_type_r, const void *throw_type_r,
}
}
}
#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*
......@@ -228,6 +478,7 @@ __throw_type_match_rtti (const void *catch_type_r, const void *throw_type_r,
return ret;
return NULL;
}
#endif
/* Called from __cp_pop_exception. Is P the type_info node for a pointer
of some kind? */
......@@ -236,11 +487,20 @@ 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); }
......@@ -302,3 +562,10 @@ 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);
#else
// new abi
// we need to define the fundamental type type_info's, but the name mangling is
// not yet defined.
#endif
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