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> 2000-01-30 Mark Mitchell <mark@codesourcery.com>
* cp/class.c (build_vtable): Rename to build_primary_vtable. * cp/class.c (build_vtable): Rename to build_primary_vtable.
......
...@@ -244,7 +244,7 @@ extern int flag_rtti; ...@@ -244,7 +244,7 @@ extern int flag_rtti;
/* Nonzero if we use access type_info objects directly, and use the /* Nonzero if we use access type_info objects directly, and use the
cross-vendor layout for them. Zero if we use an accessor function cross-vendor layout for them. Zero if we use an accessor function
to get the type_info object address. */ 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. */ /* Language-dependent contents of an identifier. */
......
...@@ -184,7 +184,11 @@ __cplus_type_matcher (__eh_info *info_, void *match_info, ...@@ -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! */ /* 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, if (__throw_type_match_rtti_2 (match_type, info->type,
info->original_value, &info->value)) info->original_value, &info->value))
......
// RTTI support for -*- C++ -*- // 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__ #ifndef __TYPEINFO__
#define __TYPEINFO__ #define __TYPEINFO__
...@@ -12,33 +17,74 @@ extern "C++" { ...@@ -12,33 +17,74 @@ extern "C++" {
namespace std { namespace std {
#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
class __class_type_info;
#endif
class type_info { 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: 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& operator= (const type_info&);
type_info (const type_info&); type_info (const type_info&);
protected: protected:
explicit type_info (const char *n): _name (n) { }
const char *_name; const char *_name;
protected:
explicit type_info (const char *n): _name (n) { }
public: public:
// destructor // the public interface
virtual ~type_info (); #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; bool before (const type_info& arg) const;
const char* name () const const char* name () const
{ return _name; } { return _name; }
bool operator== (const type_info& arg) const; 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:: // the internal interface
operator!= (const type_info& arg) const #if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
{ public:
return !operator== (arg); // 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 { class bad_cast : public exception {
public: public:
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
using std::type_info; using std::type_info;
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
bool bool
type_info::before (const type_info &arg) const type_info::before (const type_info &arg) const
{ {
...@@ -88,6 +89,248 @@ struct __array_type_info : public type_info { ...@@ -88,6 +89,248 @@ struct __array_type_info : public type_info {
__array_type_info (const char *n): type_info (n) {} __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. // Entry points for the compiler.
/* Low level match routine used by compiler to match types of catch /* 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, ...@@ -102,6 +345,8 @@ __throw_type_match_rtti_2 (const void *catch_type_r, const void *throw_type_r,
*valp = objptr; *valp = objptr;
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
// old abi
if (catch_type == throw_type) if (catch_type == throw_type)
return 1; return 1;
...@@ -213,10 +458,15 @@ __throw_type_match_rtti_2 (const void *catch_type_r, const void *throw_type_r, ...@@ -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; return 0;
} }
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
/* Backward compatibility wrapper. */ /* Backward compatibility wrapper. */
extern "C" void* extern "C" void*
...@@ -228,6 +478,7 @@ __throw_type_match_rtti (const void *catch_type_r, const void *throw_type_r, ...@@ -228,6 +478,7 @@ __throw_type_match_rtti (const void *catch_type_r, const void *throw_type_r,
return ret; return ret;
return NULL; return NULL;
} }
#endif
/* Called from __cp_pop_exception. Is P the type_info node for a pointer /* Called from __cp_pop_exception. Is P the type_info node for a pointer
of some kind? */ of some kind? */
...@@ -236,11 +487,20 @@ bool ...@@ -236,11 +487,20 @@ bool
__is_pointer (void *p) __is_pointer (void *p)
{ {
const type_info *t = reinterpret_cast <const type_info *>(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 = const __pointer_type_info *pt =
dynamic_cast <const __pointer_type_info *> (t); dynamic_cast <const __pointer_type_info *> (t);
return pt != 0; 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 extern "C" void
__rtti_ptr (void *addr, const char *n, const type_info *ti) __rtti_ptr (void *addr, const char *n, const type_info *ti)
{ new (addr) __pointer_type_info (n, *ti); } { new (addr) __pointer_type_info (n, *ti); }
...@@ -302,3 +562,10 @@ BUILTIN (v); BUILTIN (x); BUILTIN (l); BUILTIN (i); BUILTIN (s); BUILTIN (b); ...@@ -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 (c); BUILTIN (w); BUILTIN (r); BUILTIN (d); BUILTIN (f);
BUILTIN (Ui); BUILTIN (Ul); BUILTIN (Ux); BUILTIN (Us); BUILTIN (Uc); BUILTIN (Ui); BUILTIN (Ul); BUILTIN (Ux); BUILTIN (Us); BUILTIN (Uc);
BUILTIN (Sc); 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