diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7f515d9f7b57..64a2b8a56167 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,31 @@ +2000-03-21 Nathan Sidwell + + * 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 Jason Merrill diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 745e033b1e70..fb8ce9f8b84d 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -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 \ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3e6f1c98066f..abf072ceadd2 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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] diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 5a4a5121c788..e1d317830d73 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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"); diff --git a/gcc/cp/inc/cxxabi.h b/gcc/cp/inc/cxxabi.h new file mode 100644 index 000000000000..b140a15f648b --- /dev/null +++ b/gcc/cp/inc/cxxabi.h @@ -0,0 +1,399 @@ +/* new abi support -*- C++ -*- + Copyright (C) 2000 + Free Software Foundation, Inc. + Written by Nathan Sidwell, Codesourcery LLC, + + 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 +#include + +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 */ diff --git a/gcc/cp/inc/typeinfo b/gcc/cp/inc/typeinfo index 5e475041bc9f..02fa73d334fa 100644 --- a/gcc/cp/inc/typeinfo +++ b/gcc/cp/inc/typeinfo @@ -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 }; diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index f06174c4ded5..bc9746c97528 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -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); diff --git a/gcc/cp/tinfo.cc b/gcc/cp/tinfo.cc index 20e6c9eee11b..90c3058abaa8 100644 --- a/gcc/cp/tinfo.cc +++ b/gcc/cp/tinfo.cc @@ -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 (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 (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 diff --git a/gcc/cp/tinfo.h b/gcc/cp/tinfo.h index b392227a3ac1..4173ca6eec0e 100644 --- a/gcc/cp/tinfo.h +++ b/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 #endif diff --git a/gcc/cp/tinfo2.cc b/gcc/cp/tinfo2.cc index c66f8a3eeabb..1eb3502880e0 100644 --- a/gcc/cp/tinfo2.cc +++ b/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 #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::