Commit 2854d3c6 by Nathan Sidwell Committed by Nathan Sidwell

cxxabi.h: New header file.

	* inc/cxxabi.h: New header file. Define new-abi entry points.
	(__pointer_type_info::target): Rename member to ...
	(__pointer_type_info::type): ... here.
	(__base_class_info::type): Rename member to ...
	(__base_class_info::base): ... here.
	* Make-lang.in (CXX_EXTRA_HEADERS): Add cxxabi.h
	* cp-tree.h (CPTI_ABI): New global tree enumeration.
	(abi_node): New global tree node.
	* decl.c (abi_node): Document.
	(init_decl_processing): Initialize abi_node.
	* rtti.c (build_dynamic_cast_1): Use abi_node for new-abi.
	(get_vmi_pseudo_type_info): Likewise.
	(create_tinfo_types): Likewise.
	(emit_support_tinfos): Likewise.
	* tinfo.h (cxxabi.h): Include for new-abi.
	Move rtti class definitions to new header file.
	* tinfo.cc (abi): Use the namespace.
	(std): Move new abi rtti classes from here ...
	(__cxxabiv1): ... to here.
	* tinfo2.cc (cxxabi.h): Include for new-abi.
	Move rtti class definitions to new header file.
	(std): Move new abi rtti classes from here ...
	(__cxxabiv1): ... to here.
	* inc/typeinfo (__class_type_info): Move into __cxxabiv1
	namespace.

From-SVN: r32669
parent b8731430
2000-03-21 Nathan Sidwell <nathan@codesourcery.com>
* inc/cxxabi.h: New header file. Define new-abi entry points.
(__pointer_type_info::target): Rename member to ...
(__pointer_type_info::type): ... here.
(__base_class_info::type): Rename member to ...
(__base_class_info::base): ... here.
* Make-lang.in (CXX_EXTRA_HEADERS): Add cxxabi.h
* cp-tree.h (CPTI_ABI): New global tree enumeration.
(abi_node): New global tree node.
* decl.c (abi_node): Document.
(init_decl_processing): Initialize abi_node.
* rtti.c (build_dynamic_cast_1): Use abi_node for new-abi.
(get_vmi_pseudo_type_info): Likewise.
(create_tinfo_types): Likewise.
(emit_support_tinfos): Likewise.
* tinfo.h (cxxabi.h): Include for new-abi.
Move rtti class definitions to new header file.
* tinfo.cc (abi): Use the namespace.
(std): Move new abi rtti classes from here ...
(__cxxabiv1): ... to here.
* tinfo2.cc (cxxabi.h): Include for new-abi.
Move rtti class definitions to new header file.
(std): Move new abi rtti classes from here ...
(__cxxabiv1): ... to here.
* inc/typeinfo (__class_type_info): Move into __cxxabiv1
namespace.
2000-03-20 Jed Wing <jedwin@zloty.ugcs.caltech.edu>
Jason Merrill <jason@casey.cygnus.com>
......
......@@ -58,7 +58,7 @@ DEMANGLER_PROG = c++filt$(exeext)
# Extra headers to install.
CXX_EXTRA_HEADERS = $(srcdir)/cp/inc/typeinfo $(srcdir)/cp/inc/exception \
$(srcdir)/cp/inc/new $(srcdir)/cp/inc/new.h
$(srcdir)/cp/inc/new $(srcdir)/cp/inc/new.h $(srcdir)/cp/inc/cxxabi.h
# Extra code to include in libgcc2.
CXX_LIB2FUNCS = tinfo.o tinfo2.o new.o opnew.o opnewnt.o opvnew.o opvnewnt.o \
......
......@@ -537,6 +537,7 @@ enum cp_tree_index
CPTI_VTBL_TYPE,
CPTI_VTBL_PTR_TYPE,
CPTI_STD,
CPTI_ABI,
CPTI_TYPE_INFO_TYPE,
CPTI_TINFO_DECL_ID,
CPTI_TINFO_DECL_TYPE,
......@@ -622,6 +623,7 @@ extern tree cp_global_trees[CPTI_MAX];
#define vtbl_type_node cp_global_trees[CPTI_VTBL_TYPE]
#define vtbl_ptr_type_node cp_global_trees[CPTI_VTBL_PTR_TYPE]
#define std_node cp_global_trees[CPTI_STD]
#define abi_node cp_global_trees[CPTI_ABI]
#define type_info_type_node cp_global_trees[CPTI_TYPE_INFO_TYPE]
#define tinfo_decl_id cp_global_trees[CPTI_TINFO_DECL_ID]
#define tinfo_decl_type cp_global_trees[CPTI_TINFO_DECL_TYPE]
......
......@@ -231,9 +231,10 @@ tree error_mark_list;
tree vtbl_type_node;
tree vtbl_ptr_type_node;
Nnamespace std
Namespaces,
tree std_node;
tree abi_node;
A FUNCTION_DECL which can call `abort'. Not necessarily the
one that the user will declare, but sufficient to be called
......@@ -6385,6 +6386,13 @@ init_decl_processing ()
get_identifier (flag_honor_std ? "fake std":"std"),
void_type_node);
pushdecl (std_node);
if (flag_new_abi)
{
push_namespace (get_identifier ("__cxxabiv1"));
abi_node = current_namespace;
pop_namespace ();
}
global_type_node = make_node (LANG_TYPE);
record_unknown_type (global_type_node, "global type");
......
......@@ -15,12 +15,15 @@
extern "C++" {
namespace std {
#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
class __class_type_info;
namespace __cxxabiv1
{
class __class_type_info;
} // namespace __cxxabiv1
#endif
namespace std {
class type_info {
public:
// Destructor. Being the first non-inline virtual function, this controls in
......@@ -82,7 +85,7 @@ public:
unsigned outer) const;
// internally used during catch matching
virtual bool do_upcast (const __class_type_info *target, void **obj_ptr) const;
virtual bool do_upcast (const __cxxabiv1::__class_type_info *target, void **obj_ptr) const;
#endif
};
......
......@@ -769,10 +769,10 @@ build_dynamic_cast_1 (type, expr)
{
tree tmp;
tree tinfo_ptr;
tree ns = global_namespace;
tree ns = new_abi_rtti_p () ? abi_node : global_namespace;
const char *name;
push_nested_namespace (ns);
push_nested_namespace (ns);
if (!new_abi_rtti_p ())
{
tinfo_ptr = build_pointer_type (tinfo_decl_type);
......@@ -787,11 +787,6 @@ build_dynamic_cast_1 (type, expr)
}
else
{
if (flag_honor_std)
{
push_namespace (get_identifier ("std"));
ns = current_namespace;
}
tinfo_ptr = xref_tag (class_type_node,
get_identifier ("__class_type_info"),
1);
......@@ -1675,8 +1670,7 @@ get_vmi_pseudo_type_info (num_bases)
array_domain = build_index_type (build_int_2 (num_bases, 0));
base_array = build_array_type (base_desc_type_node, array_domain);
if (flag_honor_std)
push_namespace (get_identifier ("std"));
push_nested_namespace (abi_node);
desc = create_pseudo_type_info
("__vmi_class_type_info", num_bases,
......@@ -1685,8 +1679,7 @@ get_vmi_pseudo_type_info (num_bases)
build_lang_decl (FIELD_DECL, NULL_TREE, base_array),
NULL);
if (flag_honor_std)
pop_namespace ();
pop_nested_namespace (abi_node);
TREE_VEC_ELT (vmi_class_desc_type_node, num_bases) = desc;
return desc;
......@@ -1702,8 +1695,7 @@ create_tinfo_types ()
if (bltn_desc_type_node)
return;
if (flag_honor_std)
push_namespace (get_identifier ("std"));
push_nested_namespace (abi_node);
ptr_type_info = build_pointer_type
(build_qualified_type
......@@ -1785,8 +1777,7 @@ create_tinfo_types ()
build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
NULL);
if (flag_honor_std)
pop_namespace ();
pop_nested_namespace (abi_node);
}
/* Emit the type_info descriptors which are guaranteed to be in the runtime
......@@ -1825,12 +1816,10 @@ emit_support_tinfos ()
int ix;
tree bltn_type, dtor;
if (flag_honor_std)
push_namespace (get_identifier ("std"));
push_nested_namespace (abi_node);
bltn_type = xref_tag (class_type_node,
get_identifier ("__fundamental_type_info"), 1);
if (flag_honor_std)
pop_namespace ();
pop_nested_namespace (abi_node);
if (!TYPE_SIZE (bltn_type))
return;
dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (bltn_type), 1);
......
......@@ -562,7 +562,7 @@ do_catch (const type_info *thr_type, void **, unsigned) const
// upcast from this type to the target. __class_type_info will override
bool type_info::
do_upcast (const __class_type_info *, void **) const
do_upcast (const abi::__class_type_info *, void **) const
{
return false;
}
......@@ -572,6 +572,7 @@ do_upcast (const __class_type_info *, void **) const
namespace {
using namespace std;
using namespace abi;
// initial part of a vtable, this structure is used with offsetof, so we don't
// have to keep alignments consistent manually.
......@@ -621,7 +622,8 @@ static const __class_type_info *const nonvirtual_base_type =
}; // namespace
namespace std {
namespace __cxxabiv1
{
__class_type_info::
~__class_type_info ()
......@@ -722,7 +724,7 @@ do_find_public_src (ptrdiff_t src2dst,
}
base = adjust_pointer <void> (base, offset);
sub_kind base_kind = base_list[i].type->do_find_public_src
sub_kind base_kind = base_list[i].base->do_find_public_src
(src2dst, base, src_type, src_ptr);
if (contained_p (base_kind))
{
......@@ -849,7 +851,7 @@ do_dyncast (ptrdiff_t src2dst,
base_access = sub_kind (base_access & ~contained_public_mask);
bool result2_ambig
= base_list[i].type->do_dyncast (src2dst, base_access,
= base_list[i].base->do_dyncast (src2dst, base_access,
dst_type, base,
src_type, src_ptr, result2);
result.whole2src = sub_kind (result.whole2src | result2.whole2src);
......@@ -1043,13 +1045,13 @@ do_upcast (sub_kind access_path,
if (base)
base = adjust_pointer <void> (base, offset);
if (base_list[i].type->do_upcast (sub_access, dst, base, result2))
if (base_list[i].base->do_upcast (sub_access, dst, base, result2))
return true; // must fail
if (result2.base_type)
{
if (result2.base_type == nonvirtual_base_type
&& base_list[i].is_virtual_p ())
result2.base_type = base_list[i].type;
result2.base_type = base_list[i].base;
if (!result.base_type)
{
result = result2;
......@@ -1131,5 +1133,5 @@ __dynamic_cast (const void *src_ptr, // object started from
return NULL;
}
}; // namespace std
}; // namespace __cxxabiv1
#endif
......@@ -210,226 +210,6 @@ struct __class_type_info : public __user_type_info {
};
#else
// new abi
#include "stddef.h"
namespace std {
class __class_type_info;
// helper class for __vmi_class_type
struct __base_class_info {
const __class_type_info *type; // base class type
ptrdiff_t offset; // offset to the sub object
int vmi_flags; // about the base
// implementation specific parts
enum vmi_masks {
virtual_mask = 0x1,
public_mask = 0x2,
hwm_bit = 2
};
public:
bool is_virtual_p () const
{ return vmi_flags & virtual_mask; }
bool is_public_p () const
{ return vmi_flags & public_mask; }
};
// type information for a class
class __class_type_info : public type_info {
protected:
virtual ~__class_type_info ();
public:
int details; // details about the class heirarchy
// implementation specific parts
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.
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_virtual_mask = __base_class_info::virtual_mask, // via a virtual path
contained_public_mask = __base_class_info::public_mask, // via a public path
contained_mask = 1 << __base_class_info::hwm_bit, // contained within us
contained_private = contained_mask,
contained_public = contained_mask | contained_public_mask
};
public:
struct upcast_result
{
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
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
// else NULL
public:
upcast_result (int d)
:dst_ptr (NULL), whole2dst (unknown), src_details (d), base_type (NULL)
{}
};
public:
// dyncast_result is used to hold information during traversal of a class
// heirarchy when dynamic casting.
struct dyncast_result
{
const void *dst_ptr; // pointer to target object or NULL
sub_kind whole2dst; // path from most derived object to target
sub_kind whole2src; // path from most derived object to sub object
sub_kind dst2src; // path from target to sub object
public:
dyncast_result ()
:dst_ptr (NULL), whole2dst (unknown),
whole2src (unknown), dst2src (unknown)
{}
};
public:
explicit __class_type_info (const char *n,
int details_)
: type_info (n), details (details_)
{ }
protected:
virtual bool do_upcast (const __class_type_info *dst_type, void **obj_ptr) const;
protected:
virtual bool do_catch (const type_info *thr_type, void **thr_obj,
unsigned outer) const;
public:
// Helper for upcast. See if DST is us, or one of our bases. ACCESS_PATH
// gives the access from the start object. Return TRUE if we know the upcast
// fails.
virtual bool do_upcast (sub_kind access_path,
const __class_type_info *dst, const void *obj,
upcast_result &__restrict result) const;
public:
// Indicate whether SRC_PTR of type SRC_TYPE is contained publicly within
// OBJ_PTR. OBJ_PTR points to a base object of our type, which is the
// destination type. SRC2DST indicates how SRC objects might be contained
// within this type. If SRC_PTR is one of our SRC_TYPE bases, indicate the
// virtuality. Returns not_contained for non containment or private
// containment.
inline sub_kind find_public_src (ptrdiff_t src2dst, const void *obj_ptr,
const __class_type_info *src_type,
const void *src_ptr) const;
public:
// dynamic cast helper. ACCESS_PATH gives the access from the most derived
// object to this base. DST_TYPE indicates the desired type we want. OBJ_PTR
// points to a base of our type within the complete object. SRC_TYPE
// indicates the static type started from and SRC_PTR 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.
virtual bool do_dyncast (ptrdiff_t src2dst, sub_kind access_path,
const __class_type_info *dst_type, const void *obj_ptr,
const __class_type_info *src_type, const void *src_ptr,
dyncast_result &result) const;
public:
// Helper for find_public_subobj. SRC2DST indicates how SRC_TYPE bases are
// inherited by the type started from -- which is not necessarily the
// current type. The current type will be a base of the destination type.
// OBJ_PTR points to the current base.
virtual sub_kind do_find_public_src (ptrdiff_t src2dst, const void *obj_ptr,
const __class_type_info *src_type,
const void *src_ptr) const;
};
// type information for a class with a single non-virtual base
class __si_class_type_info : public __class_type_info {
protected:
virtual ~__si_class_type_info ();
protected:
const __class_type_info *base; // base type
public:
explicit __si_class_type_info (const char *n,
int details_,
const __class_type_info *base_)
: __class_type_info (n, details_), base (base_)
{ }
// implementation specific parts
protected:
virtual bool do_dyncast (ptrdiff_t src2dst, sub_kind access_path,
const __class_type_info *dst_type, const void *obj_ptr,
const __class_type_info *src_type, const void *src_ptr,
dyncast_result &result) const;
virtual sub_kind do_find_public_src (ptrdiff_t src2dst, const void *obj_ptr,
const __class_type_info *src_type,
const void *sub_ptr) const;
virtual bool do_upcast (sub_kind access_path,
const __class_type_info *dst, const void *obj,
upcast_result &__restrict result) const;
};
// type information for a class with multiple and/or virtual bases
class __vmi_class_type_info : public __class_type_info {
protected:
virtual ~__vmi_class_type_info ();
protected:
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
// so this class is not constructable with a normal constructor. It is
// internally generated by the compiler.
public:
explicit __vmi_class_type_info (const char *n,
int details_)
: __class_type_info (n, details_), n_bases (0)
{ }
// implementation specific parts
protected:
virtual bool do_dyncast (ptrdiff_t src2dst, sub_kind access_path,
const __class_type_info *dst_type, const void *obj_ptr,
const __class_type_info *src_type, const void *src_ptr,
dyncast_result &result) const;
virtual sub_kind do_find_public_src (ptrdiff_t src2dst, const void *obj_ptr,
const __class_type_info *src_type,
const void *src_ptr) const;
virtual bool do_upcast (sub_kind access_path,
const __class_type_info *dst, const void *obj,
upcast_result &__restrict result) const;
};
// dynamic cast runtime
void *__dynamic_cast (const void *src_ptr, // object started from
const __class_type_info *src_type, // static type of object
const __class_type_info *dst_type, // desired target type
ptrdiff_t src2dst); // how src and dst are related
// src2dst has the following possible values
// >= 0: src_type is a unique public non-virtual base of dst_type
// dst_ptr + src2dst == src_ptr
// -1: unspecified relationship
// -2: src_type is not a public base of dst_type
// -3: src_type is a multiple public non-virtual base of dst_type
} // namespace std
#include <cxxabi.h>
#endif
......@@ -91,111 +91,13 @@ struct __array_type_info : public type_info {
#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 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 __pointer_to_member_type_info : public type_info {
public:
virtual ~__pointer_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 __pointer_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
#include <cxxabi.h>
#endif
#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
namespace std {
namespace __cxxabiv1 {
using 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
......@@ -262,13 +164,13 @@ do_catch (const type_info *thr_type,
if (!(quals & const_mask))
outer &= ~1;
if (outer < 2 && *target == typeid (void))
if (outer < 2 && *type == typeid (void))
{
// conversion to void
return !thrown_type->is_function_p ();
}
return target->do_catch (thrown_type->target, thr_obj, outer + 2);
return type->do_catch (thrown_type->type, thr_obj, outer + 2);
}
bool __pointer_to_member_type_info::
......
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