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
This commit is contained in:
parent
b8731430ae
commit
2854d3c65e
@ -1,3 +1,31 @@
|
||||
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");
|
||||
|
399
gcc/cp/inc/cxxabi.h
Normal file
399
gcc/cp/inc/cxxabi.h
Normal file
@ -0,0 +1,399 @@
|
||||
/* new abi support -*- C++ -*-
|
||||
Copyright (C) 2000
|
||||
Free Software Foundation, Inc.
|
||||
Written by Nathan Sidwell, Codesourcery LLC, <nathan@codesourcery.com>
|
||||
|
||||
This file declares the new abi entry points into the runtime. It is not
|
||||
normally necessary for user programs to include this header, or use the
|
||||
entry points directly. However, this header is available should that be
|
||||
needed.
|
||||
|
||||
Some of the entry points are intended for both C and C++, thus this header
|
||||
is includable from both C and C++. Though the C++ specific parts are not
|
||||
available in C, naturally enough. */
|
||||
|
||||
#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
|
||||
|
||||
#include <typeinfo>
|
||||
#include <stddef.h>
|
||||
|
||||
namespace __cxxabiv1
|
||||
{
|
||||
|
||||
/* type information for int, float etc */
|
||||
class __fundamental_type_info
|
||||
: public std::type_info
|
||||
{
|
||||
public:
|
||||
virtual ~__fundamental_type_info ();
|
||||
public:
|
||||
explicit __fundamental_type_info (const char *n_)
|
||||
: std::type_info (n_)
|
||||
{ }
|
||||
};
|
||||
|
||||
/* type information for pointer to data or function, but not pointer to member */
|
||||
class __pointer_type_info
|
||||
: public std::type_info
|
||||
{
|
||||
/* abi defined member variables */
|
||||
public:
|
||||
int quals; /* qualification of the target object */
|
||||
const std::type_info *type; /* type of pointed to object */
|
||||
|
||||
/* abi defined member functions */
|
||||
public:
|
||||
virtual ~__pointer_type_info ();
|
||||
public:
|
||||
explicit __pointer_type_info (const char *n_,
|
||||
int quals_,
|
||||
const std::type_info *type_)
|
||||
: std::type_info (n_), quals (quals_), type (type_)
|
||||
{ }
|
||||
|
||||
/* implementation defined types */
|
||||
public:
|
||||
enum quals_masks {
|
||||
const_mask = 0x1,
|
||||
volatile_mask = 0x2
|
||||
};
|
||||
|
||||
/* implementation defined member functions */
|
||||
protected:
|
||||
virtual bool is_pointer_p () const;
|
||||
protected:
|
||||
virtual bool do_catch (const std::type_info *thr_type, void **thr_obj,
|
||||
unsigned outer) const;
|
||||
};
|
||||
|
||||
/* type information for array objects */
|
||||
class __array_type_info
|
||||
: public std::type_info
|
||||
{
|
||||
/* abi defined member functions */
|
||||
protected:
|
||||
virtual ~__array_type_info ();
|
||||
public:
|
||||
explicit __array_type_info (const char *n_)
|
||||
: std::type_info (n_)
|
||||
{ }
|
||||
};
|
||||
|
||||
/* type information for functions (both member and non-member) */
|
||||
class __function_type_info
|
||||
: public std::type_info
|
||||
{
|
||||
/* abi defined member functions */
|
||||
public:
|
||||
virtual ~__function_type_info ();
|
||||
public:
|
||||
explicit __function_type_info (const char *n_)
|
||||
: std::type_info (n_)
|
||||
{ }
|
||||
|
||||
/* implementation defined member functions */
|
||||
protected:
|
||||
virtual bool is_function_p () const;
|
||||
};
|
||||
|
||||
/* type information for enumerations */
|
||||
class __enum_type_info
|
||||
: public std::type_info
|
||||
{
|
||||
/* abi defined member functions */
|
||||
public:
|
||||
virtual ~__enum_type_info ();
|
||||
public:
|
||||
explicit __enum_type_info (const char *n_)
|
||||
: std::type_info (n_)
|
||||
{ }
|
||||
};
|
||||
|
||||
/* type information for a pointer to member variable (not function) */
|
||||
class __pointer_to_member_type_info
|
||||
: public std::type_info
|
||||
{
|
||||
/* abi defined member variables */
|
||||
public:
|
||||
const __class_type_info *klass; /* class of the member */
|
||||
const std::type_info *type; /* type of the pointed to member */
|
||||
int quals; /* qualifications of the pointed to type */
|
||||
|
||||
/* abi defined member functions */
|
||||
public:
|
||||
virtual ~__pointer_to_member_type_info ();
|
||||
public:
|
||||
explicit __pointer_to_member_type_info (const char *n_,
|
||||
const __class_type_info *klass_,
|
||||
const std::type_info *type_,
|
||||
int quals_)
|
||||
: std::type_info (n_), klass (klass_), type (type_), quals (quals_)
|
||||
{ }
|
||||
|
||||
/* implementation defined types */
|
||||
public:
|
||||
enum quals_masks {
|
||||
const_mask = 0x1,
|
||||
volatile_mask = 0x2
|
||||
};
|
||||
|
||||
/* implementation defined member functions */
|
||||
protected:
|
||||
virtual bool do_catch (const std::type_info *thr_type, void **thr_obj,
|
||||
unsigned outer) const;
|
||||
};
|
||||
|
||||
class __class_type_info;
|
||||
|
||||
/* helper class for __vmi_class_type */
|
||||
class __base_class_info
|
||||
{
|
||||
/* abi defined member variables */
|
||||
public:
|
||||
const __class_type_info *base; /* base class type */
|
||||
std::ptrdiff_t offset; /* offset to the sub object */
|
||||
int vmi_flags; /* about the base */
|
||||
|
||||
/* implementation defined types */
|
||||
public:
|
||||
enum vmi_masks {
|
||||
virtual_mask = 0x1,
|
||||
public_mask = 0x2,
|
||||
hwm_bit = 2
|
||||
};
|
||||
|
||||
/* implementation defined member functions */
|
||||
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 std::type_info
|
||||
{
|
||||
/* abi defined member variables */
|
||||
public:
|
||||
int details; /* details about the class heirarchy */
|
||||
|
||||
/* abi defined member functions */
|
||||
public:
|
||||
virtual ~__class_type_info ();
|
||||
public:
|
||||
explicit __class_type_info (const char *n_,
|
||||
int details_)
|
||||
: type_info (n_), details (details_)
|
||||
{ }
|
||||
|
||||
/* implementation defined types */
|
||||
public:
|
||||
enum detail_masks {
|
||||
multiple_base_mask = 0x1, /* multiple inheritance of the same base type */
|
||||
polymorphic_mask = 0x2, /* is a polymorphic type */
|
||||
virtual_base_mask = 0x4, /* has virtual bases (direct or indirect) */
|
||||
private_base_mask = 0x8 /* has private bases (direct or indirect) */
|
||||
};
|
||||
|
||||
public:
|
||||
/* sub_kind tells us about how a base object is contained within a derived
|
||||
object. We often do this lazily, hence the UNKNOWN value. At other times
|
||||
we may use NOT_CONTAINED to mean not publicly contained. */
|
||||
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)
|
||||
{}
|
||||
};
|
||||
|
||||
/* implementation defined member functions */
|
||||
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 (std::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 (std::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 (std::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
|
||||
{
|
||||
/* abi defined member variables */
|
||||
protected:
|
||||
const __class_type_info *base; /* base type */
|
||||
|
||||
/* abi defined member functions */
|
||||
public:
|
||||
virtual ~__si_class_type_info ();
|
||||
public:
|
||||
explicit __si_class_type_info (const char *n_,
|
||||
int details_,
|
||||
const __class_type_info *base_)
|
||||
: __class_type_info (n_, details_), base (base_)
|
||||
{ }
|
||||
|
||||
/* implementation defined member functions */
|
||||
protected:
|
||||
virtual bool do_dyncast (std::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 (std::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 {
|
||||
/* abi defined member variables */
|
||||
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. */
|
||||
|
||||
/* abi defined member functions */
|
||||
public:
|
||||
virtual ~__vmi_class_type_info ();
|
||||
public:
|
||||
explicit __vmi_class_type_info (const char *n_,
|
||||
int details_)
|
||||
: __class_type_info (n_, details_), n_bases (0)
|
||||
{ }
|
||||
|
||||
/* implementation defined member functions */
|
||||
protected:
|
||||
virtual bool do_dyncast (std::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 (std::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 */
|
||||
std::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 __cxxabiv1 */
|
||||
|
||||
/* User programs should use the alias `abi'. */
|
||||
namespace abi = __cxxabiv1;
|
||||
|
||||
#else
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
#endif /* __CXXABI_H */
|
@ -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
|
||||
|
222
gcc/cp/tinfo.h
222
gcc/cp/tinfo.h
@ -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
|
||||
|
110
gcc/cp/tinfo2.cc
110
gcc/cp/tinfo2.cc
@ -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::
|
||||
|
Loading…
x
Reference in New Issue
Block a user