mirror of git://gcc.gnu.org/git/gcc.git
del_op.cc, [...]: New files.
* del_op.cc, del_opnt.cc, del_opv.cc, del_opvnt.cc: New files.
* exception.cc, new_handler.cc, new_op.cc, new_opnt.cc: New files.
* new_opv.cc, new_opvnt.cc, tinfo.cc, tinfo2.cc, vec.cc: New files.
* cxxabi.h, exception, new, new.h, typeinfo, pure.c: New files.
* tinfo.hP: New file.
* Makefile.in (OBJS, HEADERS): Add new files.
* configure.in (XCXXINCLUDES): Add ../include and ../gcc.
From-SVN: r36780
This commit is contained in:
parent
58ad9ee0af
commit
9ab916b8ed
|
|
@ -1,3 +1,14 @@
|
||||||
|
2000-10-07 Richard Henderson <rth@cygnus.com>
|
||||||
|
|
||||||
|
* del_op.cc, del_opnt.cc, del_opv.cc, del_opvnt.cc: New files.
|
||||||
|
* exception.cc, new_handler.cc, new_op.cc, new_opnt.cc: New files.
|
||||||
|
* new_opv.cc, new_opvnt.cc, tinfo.cc, tinfo2.cc, vec.cc: New files.
|
||||||
|
* cxxabi.h, exception, new, new.h, typeinfo, pure.c: New files.
|
||||||
|
* tinfo.hP: New file.
|
||||||
|
|
||||||
|
* Makefile.in (OBJS, HEADERS): Add new files.
|
||||||
|
* configure.in (XCXXINCLUDES): Add ../include and ../gcc.
|
||||||
|
|
||||||
2000-09-19 David Edelsohn <edelsohn@gnu.org>
|
2000-09-19 David Edelsohn <edelsohn@gnu.org>
|
||||||
|
|
||||||
* configure.in: Add AIX multithread support fragment.
|
* configure.in: Add AIX multithread support fragment.
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,11 @@ INTERFACE = 3
|
||||||
|
|
||||||
gxx_include_dir=${includedir}/g++
|
gxx_include_dir=${includedir}/g++
|
||||||
|
|
||||||
OBJS = cstringi.o stdexcepti.o cstdlibi.o cmathi.o stlinst.o valarray.o
|
OBJS = cstringi.o stdexcepti.o cstdlibi.o cmathi.o stlinst.o valarray.o \
|
||||||
|
del_op.o del_opnt.o del_opv.o del_opvnt.o exception.o new_handler.o \
|
||||||
|
new_op.o new_opnt.o new_opv.o new_opvnt.o tinfo.o tinfo2.o vec.o \
|
||||||
|
pure.o
|
||||||
|
|
||||||
SUBLIBS = $(STAMP)-string $(STAMP)-complx
|
SUBLIBS = $(STAMP)-string $(STAMP)-complx
|
||||||
|
|
||||||
# C++ headers with no extension
|
# C++ headers with no extension
|
||||||
|
|
@ -29,7 +33,7 @@ HEADERS= cassert cctype cerrno cfloat ciso646 climits clocale cmath complex \
|
||||||
algorithm deque functional hash_map hash_set iterator list map \
|
algorithm deque functional hash_map hash_set iterator list map \
|
||||||
memory numeric pthread_alloc queue rope set slist stack utility \
|
memory numeric pthread_alloc queue rope set slist stack utility \
|
||||||
vector fstream iomanip iostream strstream iosfwd bitset valarray \
|
vector fstream iomanip iostream strstream iosfwd bitset valarray \
|
||||||
sstream
|
sstream exception new typeinfo
|
||||||
|
|
||||||
ARLIB = libstdc++.a.$(VERSION)
|
ARLIB = libstdc++.a.$(VERSION)
|
||||||
ARLINK = libstdc++.a
|
ARLINK = libstdc++.a
|
||||||
|
|
@ -131,12 +135,29 @@ STRFUNCS = REP MAIN TRAITS ADDSS ADDPS ADDCS ADDSP ADDSC \
|
||||||
STRIO = EXTRACT INSERT GETLINE
|
STRIO = EXTRACT INSERT GETLINE
|
||||||
|
|
||||||
# These are here for SunOS VPATH.
|
# These are here for SunOS VPATH.
|
||||||
cstringi.o: cstringi.cc
|
cinst.o: cinst.cc
|
||||||
cstdlibi.o: cstdlibi.cc
|
|
||||||
cmathi.o: cmathi.cc
|
cmathi.o: cmathi.cc
|
||||||
|
cstdlibi.o: cstdlibi.cc
|
||||||
|
cstringi.o: cstringi.cc
|
||||||
|
del_op.o: del_op.cc new
|
||||||
|
del_opnt.o: del_opnt.cc new
|
||||||
|
del_opv.o: del_opv.cc new
|
||||||
|
del_opvnt.o: del_opvnt.cc new
|
||||||
|
exception.o: exception.cc typeinfo $(srcdir)/../gcc/gansidecl.h \
|
||||||
|
$(srcdir)/../include/ansidecl.h $(srcdir)/../gcc/eh-common.h
|
||||||
|
new_handler.o: new_handler.cc new
|
||||||
|
new_op.o: new_op.cc new
|
||||||
|
new_opnt.o: new_opnt.cc new
|
||||||
|
new_opv.o: new_opv.cc new
|
||||||
|
new_opvnt.o: new_opvnt.cc new
|
||||||
|
sinst.o: sinst.cc
|
||||||
stdexcepti.o: stdexcepti.cc
|
stdexcepti.o: stdexcepti.cc
|
||||||
stlinst.o: stlinst.cc
|
stlinst.o: stlinst.cc
|
||||||
|
tinfo.o: tinfo.cc tinfo.hP typeinfo new
|
||||||
|
tinfo2.o: tinfo2.cc tinfo.hP typeinfo new
|
||||||
valarray.o: valarray.cc
|
valarray.o: valarray.cc
|
||||||
|
vec.o: vec.cc
|
||||||
|
pure.o: pure.c
|
||||||
|
|
||||||
# Later do wide strings, too.
|
# Later do wide strings, too.
|
||||||
stmp-string: ${srcdir}/sinst.cc ${srcdir}/std/bastring.h \
|
stmp-string: ${srcdir}/sinst.cc ${srcdir}/std/bastring.h \
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ ${moveifchange} temp.mt target-mkfrag
|
||||||
LIBDIR=yes
|
LIBDIR=yes
|
||||||
TO_TOPDIR=../
|
TO_TOPDIR=../
|
||||||
ALL='libs'
|
ALL='libs'
|
||||||
XCXXINCLUDES="-I${srcdir} -I${srcdir}/stl -I${TO_TOPDIR}libio -I${srcdir}/${TO_TOPDIR}libio"
|
XCXXINCLUDES="-I${srcdir} -I${srcdir}/stl -I${TO_TOPDIR}libio -I${srcdir}/${TO_TOPDIR}libio -I${srcdir}/${TO_TOPDIR}include -I${srcdir}/${TO_TOPDIR}gcc"
|
||||||
MOSTLYCLEAN='*.o pic stamp-picdir core so_locations $(MOSTLYCLEAN_JUNK)'
|
MOSTLYCLEAN='*.o pic stamp-picdir core so_locations $(MOSTLYCLEAN_JUNK)'
|
||||||
CLEAN='$(CLEAN_JUNK)'
|
CLEAN='$(CLEAN_JUNK)'
|
||||||
EXTRA_DISTCLEAN='target-mkfrag'
|
EXTRA_DISTCLEAN='target-mkfrag'
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,519 @@
|
||||||
|
/* new abi support -*- C++ -*-
|
||||||
|
Copyright (C) 2000
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
Written by Nathan Sidwell, Codesourcery LLC, <nathan@codesourcery.com> */
|
||||||
|
|
||||||
|
// This file is part of GNU CC.
|
||||||
|
//
|
||||||
|
// GNU CC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GNU CC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with GNU CC; see the file COPYING. If not, write to
|
||||||
|
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
// Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
// As a special exception, you may use this file as part of a free software
|
||||||
|
// library without restriction. Specifically, if other files instantiate
|
||||||
|
// templates or use macros or inline functions from this file, or you compile
|
||||||
|
// this file and link it with other files to produce an executable, this
|
||||||
|
// file does not by itself cause the resulting executable to be covered by
|
||||||
|
// the GNU General Public License. This exception does not however
|
||||||
|
// invalidate any other reasons why the executable file might be covered by
|
||||||
|
// the GNU General Public License.
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
// We use the compiler builtins __SIZE_TYPE__ and __PTRDIFF_TYPE__ instead of
|
||||||
|
// std::size_t and std::ptrdiff_t respectively. This makes us independant of
|
||||||
|
// the conformance level of <cstddef> and whether -fhonor-std was supplied.
|
||||||
|
// <cstddef> is not currently available during compiler building anyway.
|
||||||
|
// Including <stddef.h> would be wrong, as that would rudely place size_t in
|
||||||
|
// the global namespace.
|
||||||
|
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
|
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 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)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* common type information for simple pointers and pointers to member */
|
||||||
|
class __pbase_type_info
|
||||||
|
: public std::type_info
|
||||||
|
{
|
||||||
|
/* abi defined member variables */
|
||||||
|
public:
|
||||||
|
unsigned int __qualifier_flags; /* qualification of the target object */
|
||||||
|
const std::type_info *__pointee; /* type of pointed to object */
|
||||||
|
|
||||||
|
/* abi defined member functions */
|
||||||
|
public:
|
||||||
|
virtual ~__pbase_type_info ();
|
||||||
|
public:
|
||||||
|
explicit __pbase_type_info (const char *__n,
|
||||||
|
int __quals,
|
||||||
|
const std::type_info *__type)
|
||||||
|
: std::type_info (__n), __qualifier_flags (__quals), __pointee (__type)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/* implementation defined types */
|
||||||
|
public:
|
||||||
|
enum __qualifier_masks {
|
||||||
|
__const_mask = 0x1,
|
||||||
|
__volatile_mask = 0x2,
|
||||||
|
__restrict_mask = 0x4,
|
||||||
|
__incomplete_mask = 0x8,
|
||||||
|
__incomplete_class_mask = 0x10
|
||||||
|
};
|
||||||
|
|
||||||
|
/* implementation defined member functions */
|
||||||
|
protected:
|
||||||
|
virtual bool __do_catch (const std::type_info *__thr_type,
|
||||||
|
void **__thr_obj,
|
||||||
|
unsigned __outer) const;
|
||||||
|
protected:
|
||||||
|
inline virtual bool __pointer_catch (const __pbase_type_info *__thr_type,
|
||||||
|
void **__thr_obj,
|
||||||
|
unsigned __outer) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* type information for simple pointers */
|
||||||
|
class __pointer_type_info
|
||||||
|
: public __pbase_type_info
|
||||||
|
{
|
||||||
|
/* abi defined member functions */
|
||||||
|
public:
|
||||||
|
virtual ~__pointer_type_info ();
|
||||||
|
public:
|
||||||
|
explicit __pointer_type_info (const char *__n,
|
||||||
|
int __quals,
|
||||||
|
const std::type_info *__type)
|
||||||
|
: __pbase_type_info (__n, __quals, __type)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/* implementation defined member functions */
|
||||||
|
protected:
|
||||||
|
virtual bool __is_pointer_p () const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool __pointer_catch (const __pbase_type_info *__thr_type,
|
||||||
|
void **__thr_obj,
|
||||||
|
unsigned __outer) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* type information for a pointer to member variable */
|
||||||
|
class __pointer_to_member_type_info
|
||||||
|
: public __pbase_type_info
|
||||||
|
{
|
||||||
|
/* abi defined member variables */
|
||||||
|
public:
|
||||||
|
__class_type_info *__context_class; /* class of the member */
|
||||||
|
|
||||||
|
/* abi defined member functions */
|
||||||
|
public:
|
||||||
|
virtual ~__pointer_to_member_type_info ();
|
||||||
|
public:
|
||||||
|
explicit __pointer_to_member_type_info (const char *__n,
|
||||||
|
int __quals,
|
||||||
|
const std::type_info *__type,
|
||||||
|
__class_type_info *__klass)
|
||||||
|
: __pbase_type_info (__n, __quals, __type), __context_class (__klass)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/* implementation defined member functions */
|
||||||
|
protected:
|
||||||
|
virtual bool __pointer_catch (const __pbase_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 */
|
||||||
|
long __offset_flags; /* offset and info */
|
||||||
|
|
||||||
|
/* implementation defined types */
|
||||||
|
public:
|
||||||
|
enum __offset_flags_masks {
|
||||||
|
__virtual_mask = 0x1,
|
||||||
|
__public_mask = 0x2,
|
||||||
|
hwm_bit = 2,
|
||||||
|
offset_shift = 8 /* bits to shift offset by */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* implementation defined member functions */
|
||||||
|
public:
|
||||||
|
bool __is_virtual_p () const
|
||||||
|
{ return __offset_flags & __virtual_mask; }
|
||||||
|
bool __is_public_p () const
|
||||||
|
{ return __offset_flags & __public_mask; }
|
||||||
|
__PTRDIFF_TYPE__ __offset () const
|
||||||
|
{
|
||||||
|
// This shift, being of a signed type, is implementation defined. GCC
|
||||||
|
// implements such shifts as arithmetic, which is what we want.
|
||||||
|
return static_cast<__PTRDIFF_TYPE__> (__offset_flags) >> offset_shift;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* type information for a class */
|
||||||
|
class __class_type_info
|
||||||
|
: public std::type_info
|
||||||
|
{
|
||||||
|
/* abi defined member functions */
|
||||||
|
public:
|
||||||
|
virtual ~__class_type_info ();
|
||||||
|
public:
|
||||||
|
explicit __class_type_info (const char *__n)
|
||||||
|
: type_info (__n)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/* implementation defined types */
|
||||||
|
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;
|
||||||
|
struct __dyncast_result;
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
/* Return false if not found, true if found. */
|
||||||
|
virtual bool __do_upcast (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_TYPE__ __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_TYPE__ __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_TYPE__ __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 */
|
||||||
|
public:
|
||||||
|
const __class_type_info *__base_type;
|
||||||
|
|
||||||
|
/* abi defined member functions */
|
||||||
|
public:
|
||||||
|
virtual ~__si_class_type_info ();
|
||||||
|
public:
|
||||||
|
explicit __si_class_type_info (const char *__n,
|
||||||
|
const __class_type_info *__base)
|
||||||
|
: __class_type_info (__n), __base_type (__base)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/* implementation defined member functions */
|
||||||
|
protected:
|
||||||
|
virtual bool __do_dyncast (__PTRDIFF_TYPE__ __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_TYPE__ __src2dst,
|
||||||
|
const void *__obj_ptr,
|
||||||
|
const __class_type_info *__src_type,
|
||||||
|
const void *__sub_ptr) const;
|
||||||
|
virtual bool __do_upcast (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 */
|
||||||
|
public:
|
||||||
|
unsigned int __flags; /* details about the class heirarchy */
|
||||||
|
unsigned int __base_count; /* number of direct bases */
|
||||||
|
__base_class_info const __base_info[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 ___flags)
|
||||||
|
: __class_type_info (__n), __flags (___flags), __base_count (0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/* implementation defined types */
|
||||||
|
public:
|
||||||
|
enum __flags_masks {
|
||||||
|
__non_diamond_repeat_mask = 0x1, /* distinct instance of repeated base */
|
||||||
|
__diamond_shaped_mask = 0x2, /* diamond shaped multiple inheritance */
|
||||||
|
non_public_base_mask = 0x4, /* has non-public direct or indirect base */
|
||||||
|
public_base_mask = 0x8, /* has public base (direct) */
|
||||||
|
|
||||||
|
__flags_unknown_mask = 0x10
|
||||||
|
};
|
||||||
|
|
||||||
|
/* implementation defined member functions */
|
||||||
|
protected:
|
||||||
|
virtual bool __do_dyncast (__PTRDIFF_TYPE__ __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_TYPE__ __src2dst,
|
||||||
|
const void *__obj_ptr,
|
||||||
|
const __class_type_info *__src_type,
|
||||||
|
const void *__src_ptr) const;
|
||||||
|
virtual bool __do_upcast (const __class_type_info *__dst,
|
||||||
|
const void *__obj,
|
||||||
|
__upcast_result &__restrict __result) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* dynamic cast runtime */
|
||||||
|
extern "C"
|
||||||
|
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_TYPE__ __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 */
|
||||||
|
|
||||||
|
/* array ctor/dtor routines */
|
||||||
|
|
||||||
|
/* allocate and construct array */
|
||||||
|
extern "C"
|
||||||
|
void *__cxa_vec_new (__SIZE_TYPE__ __element_count,
|
||||||
|
__SIZE_TYPE__ __element_size,
|
||||||
|
__SIZE_TYPE__ __padding_size,
|
||||||
|
void (*__constructor) (void *),
|
||||||
|
void (*__destructor) (void *));
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void *__cxa_vec_new2 (__SIZE_TYPE__ __element_count,
|
||||||
|
__SIZE_TYPE__ __element_size,
|
||||||
|
__SIZE_TYPE__ __padding_size,
|
||||||
|
void (*__constructor) (void *),
|
||||||
|
void (*__destructor) (void *),
|
||||||
|
void *(*__alloc) (__SIZE_TYPE__),
|
||||||
|
void (*__dealloc) (void *));
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void *__cxa_vec_new3 (__SIZE_TYPE__ __element_count,
|
||||||
|
__SIZE_TYPE__ __element_size,
|
||||||
|
__SIZE_TYPE__ __padding_size,
|
||||||
|
void (*__constructor) (void *),
|
||||||
|
void (*__destructor) (void *),
|
||||||
|
void *(*__alloc) (__SIZE_TYPE__),
|
||||||
|
void (*__dealloc) (void *, __SIZE_TYPE__));
|
||||||
|
|
||||||
|
/* construct array */
|
||||||
|
extern "C"
|
||||||
|
void __cxa_vec_ctor (void *__array_address,
|
||||||
|
__SIZE_TYPE__ __element_count,
|
||||||
|
__SIZE_TYPE__ __element_size,
|
||||||
|
void (*__constructor) (void *),
|
||||||
|
void (*__destructor) (void *));
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void __cxa_vec_cctor (void *dest_array,
|
||||||
|
void *src_array,
|
||||||
|
__SIZE_TYPE__ element_count,
|
||||||
|
__SIZE_TYPE__ element_size,
|
||||||
|
void (*constructor) (void *, void *),
|
||||||
|
void (*destructor) (void *));
|
||||||
|
|
||||||
|
/* destruct array */
|
||||||
|
extern "C"
|
||||||
|
void __cxa_vec_dtor (void *__array_address,
|
||||||
|
__SIZE_TYPE__ __element_count,
|
||||||
|
__SIZE_TYPE__ __element_size,
|
||||||
|
void (*__destructor) (void *));
|
||||||
|
|
||||||
|
/* destruct and release array */
|
||||||
|
extern "C"
|
||||||
|
void __cxa_vec_delete (void *__array_address,
|
||||||
|
__SIZE_TYPE__ __element_size,
|
||||||
|
__SIZE_TYPE__ __padding_size,
|
||||||
|
void (*__destructor) (void *));
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void __cxa_vec_delete2 (void *__array_address,
|
||||||
|
__SIZE_TYPE__ __element_size,
|
||||||
|
__SIZE_TYPE__ __padding_size,
|
||||||
|
void (*__destructor) (void *),
|
||||||
|
void (*__dealloc) (void *));
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void __cxa_vec_delete3 (void *__array_address,
|
||||||
|
__SIZE_TYPE__ __element_size,
|
||||||
|
__SIZE_TYPE__ __padding_size,
|
||||||
|
void (*__destructor) (void *),
|
||||||
|
void (*__dealloc) (void *, __SIZE_TYPE__));
|
||||||
|
|
||||||
|
/* demangling routines */
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
char *__cxa_demangle (const char *__mangled_name,
|
||||||
|
char *__output_buffer,
|
||||||
|
__SIZE_TYPE__ *__length,
|
||||||
|
int *__status);
|
||||||
|
|
||||||
|
} /* namespace __cxxabiv1 */
|
||||||
|
|
||||||
|
/* User programs should use the alias `abi'. */
|
||||||
|
namespace abi = __cxxabiv1;
|
||||||
|
|
||||||
|
#else
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __CXXABI_H */
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
|
||||||
|
// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GNU CC.
|
||||||
|
//
|
||||||
|
// GNU CC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GNU CC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with GNU CC; see the file COPYING. If not, write to
|
||||||
|
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
// Boston, MA 02111-1307, USA.
|
||||||
|
//
|
||||||
|
// As a special exception, you may use this file as part of a free software
|
||||||
|
// library without restriction. Specifically, if other files instantiate
|
||||||
|
// templates or use macros or inline functions from this file, or you compile
|
||||||
|
// this file and link it with other files to produce an executable, this
|
||||||
|
// file does not by itself cause the resulting executable to be covered by
|
||||||
|
// the GNU General Public License. This exception does not however
|
||||||
|
// invalidate any other reasons why the executable file might be covered by
|
||||||
|
// the GNU General Public License.
|
||||||
|
|
||||||
|
#include "new"
|
||||||
|
|
||||||
|
extern "C" void free (void *);
|
||||||
|
|
||||||
|
void
|
||||||
|
operator delete (void *ptr) throw ()
|
||||||
|
{
|
||||||
|
if (ptr)
|
||||||
|
free (ptr);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
|
||||||
|
// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GNU CC.
|
||||||
|
//
|
||||||
|
// GNU CC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GNU CC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with GNU CC; see the file COPYING. If not, write to
|
||||||
|
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
// Boston, MA 02111-1307, USA.
|
||||||
|
//
|
||||||
|
// As a special exception, you may use this file as part of a free software
|
||||||
|
// library without restriction. Specifically, if other files instantiate
|
||||||
|
// templates or use macros or inline functions from this file, or you compile
|
||||||
|
// this file and link it with other files to produce an executable, this
|
||||||
|
// file does not by itself cause the resulting executable to be covered by
|
||||||
|
// the GNU General Public License. This exception does not however
|
||||||
|
// invalidate any other reasons why the executable file might be covered by
|
||||||
|
// the GNU General Public License.
|
||||||
|
|
||||||
|
#include "new"
|
||||||
|
|
||||||
|
extern "C" void free (void *);
|
||||||
|
|
||||||
|
void
|
||||||
|
operator delete (void *ptr, const std::nothrow_t&) throw ()
|
||||||
|
{
|
||||||
|
if (ptr)
|
||||||
|
free (ptr);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
|
||||||
|
// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GNU CC.
|
||||||
|
//
|
||||||
|
// GNU CC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GNU CC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with GNU CC; see the file COPYING. If not, write to
|
||||||
|
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
// Boston, MA 02111-1307, USA.
|
||||||
|
//
|
||||||
|
// As a special exception, you may use this file as part of a free software
|
||||||
|
// library without restriction. Specifically, if other files instantiate
|
||||||
|
// templates or use macros or inline functions from this file, or you compile
|
||||||
|
// this file and link it with other files to produce an executable, this
|
||||||
|
// file does not by itself cause the resulting executable to be covered by
|
||||||
|
// the GNU General Public License. This exception does not however
|
||||||
|
// invalidate any other reasons why the executable file might be covered by
|
||||||
|
// the GNU General Public License.
|
||||||
|
|
||||||
|
#include "new"
|
||||||
|
|
||||||
|
void
|
||||||
|
operator delete[] (void *ptr) throw ()
|
||||||
|
{
|
||||||
|
::operator delete (ptr);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
|
||||||
|
// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GNU CC.
|
||||||
|
//
|
||||||
|
// GNU CC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GNU CC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with GNU CC; see the file COPYING. If not, write to
|
||||||
|
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
// Boston, MA 02111-1307, USA.
|
||||||
|
//
|
||||||
|
// As a special exception, you may use this file as part of a free software
|
||||||
|
// library without restriction. Specifically, if other files instantiate
|
||||||
|
// templates or use macros or inline functions from this file, or you compile
|
||||||
|
// this file and link it with other files to produce an executable, this
|
||||||
|
// file does not by itself cause the resulting executable to be covered by
|
||||||
|
// the GNU General Public License. This exception does not however
|
||||||
|
// invalidate any other reasons why the executable file might be covered by
|
||||||
|
// the GNU General Public License.
|
||||||
|
|
||||||
|
#include "new"
|
||||||
|
|
||||||
|
void
|
||||||
|
operator delete[] (void *ptr, const std::nothrow_t&) throw ()
|
||||||
|
{
|
||||||
|
::operator delete (ptr);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
// Exception Handling support header for -*- C++ -*-
|
||||||
|
// Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation
|
||||||
|
|
||||||
|
// This file is part of GNU CC.
|
||||||
|
//
|
||||||
|
// GNU CC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GNU CC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with GNU CC; see the file COPYING. If not, write to
|
||||||
|
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
// Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
// As a special exception, you may use this file as part of a free software
|
||||||
|
// library without restriction. Specifically, if other files instantiate
|
||||||
|
// templates or use macros or inline functions from this file, or you compile
|
||||||
|
// this file and link it with other files to produce an executable, this
|
||||||
|
// file does not by itself cause the resulting executable to be covered by
|
||||||
|
// the GNU General Public License. This exception does not however
|
||||||
|
// invalidate any other reasons why the executable file might be covered by
|
||||||
|
// the GNU General Public License.
|
||||||
|
|
||||||
|
#ifndef __EXCEPTION__
|
||||||
|
#define __EXCEPTION__
|
||||||
|
|
||||||
|
#pragma interface "exception"
|
||||||
|
|
||||||
|
extern "C++" {
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
class exception {
|
||||||
|
public:
|
||||||
|
exception () { }
|
||||||
|
virtual ~exception () { }
|
||||||
|
virtual const char* what () const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class bad_exception : public exception {
|
||||||
|
public:
|
||||||
|
bad_exception () { }
|
||||||
|
virtual ~bad_exception () { }
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (*terminate_handler) ();
|
||||||
|
typedef void (*unexpected_handler) ();
|
||||||
|
|
||||||
|
terminate_handler set_terminate (terminate_handler);
|
||||||
|
void terminate () __attribute__ ((__noreturn__));
|
||||||
|
unexpected_handler set_unexpected (unexpected_handler);
|
||||||
|
void unexpected () __attribute__ ((__noreturn__));
|
||||||
|
bool uncaught_exception ();
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
} // extern "C++"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,403 @@
|
||||||
|
// Functions for Exception Support for -*- C++ -*-
|
||||||
|
// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000 Free Software Foundation
|
||||||
|
|
||||||
|
// This file is part of GNU CC.
|
||||||
|
|
||||||
|
// GNU CC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// GNU CC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with GNU CC; see the file COPYING. If not, write to
|
||||||
|
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
// Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
// As a special exception, you may use this file as part of a free software
|
||||||
|
// library without restriction. Specifically, if other files instantiate
|
||||||
|
// templates or use macros or inline functions from this file, or you compile
|
||||||
|
// this file and link it with other files to produce an executable, this
|
||||||
|
// file does not by itself cause the resulting executable to be covered by
|
||||||
|
// the GNU General Public License. This exception does not however
|
||||||
|
// invalidate any other reasons why the executable file might be covered by
|
||||||
|
// the GNU General Public License.
|
||||||
|
|
||||||
|
#pragma implementation "exception"
|
||||||
|
|
||||||
|
#include "typeinfo"
|
||||||
|
#include "exception"
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "gansidecl.h" /* Needed to support macros used in eh-common.h. */
|
||||||
|
#include "eh-common.h"
|
||||||
|
|
||||||
|
/* Define terminate, unexpected, set_terminate, set_unexpected as
|
||||||
|
well as the default terminate func and default unexpected func. */
|
||||||
|
|
||||||
|
extern std::terminate_handler __terminate_func __attribute__((__noreturn__));
|
||||||
|
using std::terminate;
|
||||||
|
|
||||||
|
void
|
||||||
|
std::terminate ()
|
||||||
|
{
|
||||||
|
__terminate_func ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
__default_unexpected ()
|
||||||
|
{
|
||||||
|
terminate ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::unexpected_handler __unexpected_func __attribute__((__noreturn__))
|
||||||
|
= __default_unexpected;
|
||||||
|
|
||||||
|
std::terminate_handler
|
||||||
|
std::set_terminate (std::terminate_handler func)
|
||||||
|
{
|
||||||
|
std::terminate_handler old = __terminate_func;
|
||||||
|
|
||||||
|
__terminate_func = func;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unexpected_handler
|
||||||
|
std::set_unexpected (std::unexpected_handler func)
|
||||||
|
{
|
||||||
|
std::unexpected_handler old = __unexpected_func;
|
||||||
|
|
||||||
|
__unexpected_func = func;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
std::unexpected ()
|
||||||
|
{
|
||||||
|
__unexpected_func ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The type of a function called to clean up an exception object.
|
||||||
|
(These will be destructors.) Under the old ABI, these take a
|
||||||
|
second argument (the `in-charge' argument), that indicates whether
|
||||||
|
or not do delete the object, and whether or not to destroy virtual
|
||||||
|
bases. Under the new ABI, there is no second argument. */
|
||||||
|
#if !defined (__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||||
|
typedef void (*cleanup_fn)(void *, int);
|
||||||
|
/* The `2' is the value for the in-charge parameter that indicates
|
||||||
|
that virtual bases should be destroyed. */
|
||||||
|
#define CALL_CLEANUP(FN, THIS) FN (THIS, 2)
|
||||||
|
#else
|
||||||
|
typedef void (*cleanup_fn)(void *);
|
||||||
|
#define CALL_CLEANUP(FN, THIS) FN (THIS)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* C++-specific state about the current exception.
|
||||||
|
This must match init_exception_processing().
|
||||||
|
|
||||||
|
Note that handlers and caught are not redundant; when rethrown, an
|
||||||
|
exception can have multiple active handlers and still be considered
|
||||||
|
uncaught. */
|
||||||
|
|
||||||
|
struct cp_eh_info
|
||||||
|
{
|
||||||
|
__eh_info eh_info;
|
||||||
|
void *value;
|
||||||
|
void *type;
|
||||||
|
cleanup_fn cleanup;
|
||||||
|
bool caught;
|
||||||
|
cp_eh_info *next;
|
||||||
|
long handlers;
|
||||||
|
void *original_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Language-specific EH info pointer, defined in libgcc2. */
|
||||||
|
|
||||||
|
extern "C" cp_eh_info **__get_eh_info (); // actually void **
|
||||||
|
|
||||||
|
/* Exception allocate and free, defined in libgcc2. */
|
||||||
|
extern "C" void *__eh_alloc(size_t);
|
||||||
|
extern "C" void __eh_free(void *);
|
||||||
|
|
||||||
|
/* Is P the type_info node for a pointer of some kind? */
|
||||||
|
|
||||||
|
extern bool __is_pointer (void *);
|
||||||
|
|
||||||
|
|
||||||
|
/* OLD Compiler hook to return a pointer to the info for the current exception.
|
||||||
|
Used by get_eh_info (). This fudges the actualy returned value to
|
||||||
|
point to the beginning of what USE to be the cp_eh_info structure.
|
||||||
|
THis is so that old code that dereferences this pointer will find
|
||||||
|
things where it expects it to be.*/
|
||||||
|
extern "C" void *
|
||||||
|
__cp_exception_info (void)
|
||||||
|
{
|
||||||
|
return &((*__get_eh_info ())->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CP_EH_INFO ((cp_eh_info *) *__get_eh_info ())
|
||||||
|
|
||||||
|
/* Old Compiler hook to return a pointer to the info for the current exception.
|
||||||
|
Used by get_eh_info (). */
|
||||||
|
|
||||||
|
extern "C" cp_eh_info *
|
||||||
|
__cp_eh_info (void)
|
||||||
|
{
|
||||||
|
cp_eh_info *p = CP_EH_INFO;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compiler hook to return a pointer to the info for the current exception,
|
||||||
|
Set the caught bit, and increment the number of handlers that are
|
||||||
|
looking at this exception. This makes handlers smaller. */
|
||||||
|
|
||||||
|
extern "C" cp_eh_info *
|
||||||
|
__start_cp_handler (void)
|
||||||
|
{
|
||||||
|
cp_eh_info *p = CP_EH_INFO;
|
||||||
|
p->caught = 1;
|
||||||
|
p->handlers++;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int __throw_type_match_rtti_2 (const void *, const void *,
|
||||||
|
void *, void **);
|
||||||
|
|
||||||
|
extern "C" void *
|
||||||
|
__cplus_type_matcher (__eh_info *info_, void *match_info,
|
||||||
|
exception_descriptor *exception_table)
|
||||||
|
{
|
||||||
|
cp_eh_info *info = (cp_eh_info *)info_;
|
||||||
|
|
||||||
|
/* No exception table implies the old style mechanism, so don't check. */
|
||||||
|
if (exception_table != NULL
|
||||||
|
&& exception_table->lang.language != EH_LANG_C_plus_plus)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (match_info == CATCH_ALL_TYPE)
|
||||||
|
return (void *)1;
|
||||||
|
|
||||||
|
/* we don't worry about version info yet, there is only one version! */
|
||||||
|
|
||||||
|
void *match_type = match_info;
|
||||||
|
|
||||||
|
#if !defined (__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||||
|
match_type = ((void *(*)())match_type) ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (__throw_type_match_rtti_2 (match_type, info->type,
|
||||||
|
info->original_value, &info->value))
|
||||||
|
// Arbitrary non-null pointer.
|
||||||
|
return (void *)1;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compiler hook to push a new exception onto the stack.
|
||||||
|
Used by expand_throw(). */
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__cp_push_exception (void *value, void *type, cleanup_fn cleanup)
|
||||||
|
{
|
||||||
|
cp_eh_info *p = (cp_eh_info *) __eh_alloc (sizeof (cp_eh_info));
|
||||||
|
|
||||||
|
p->value = value;
|
||||||
|
p->type = type;
|
||||||
|
p->cleanup = cleanup;
|
||||||
|
p->handlers = 0;
|
||||||
|
p->caught = false;
|
||||||
|
p->original_value = value;
|
||||||
|
|
||||||
|
p->eh_info.match_function = __cplus_type_matcher;
|
||||||
|
p->eh_info.language = EH_LANG_C_plus_plus;
|
||||||
|
p->eh_info.version = 1;
|
||||||
|
|
||||||
|
cp_eh_info **q = __get_eh_info ();
|
||||||
|
|
||||||
|
p->next = *q;
|
||||||
|
*q = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compiler hook to pop an exception that has been finalized. Used by
|
||||||
|
push_eh_cleanup(). P is the info for the exception caught by the
|
||||||
|
current catch block. */
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__cp_pop_exception (cp_eh_info *p)
|
||||||
|
{
|
||||||
|
cp_eh_info **stack = __get_eh_info ();
|
||||||
|
cp_eh_info **q = stack;
|
||||||
|
|
||||||
|
--p->handlers;
|
||||||
|
|
||||||
|
/* Do nothing if our exception is being rethrown (i.e. if the active
|
||||||
|
exception is our exception and it is uncaught). */
|
||||||
|
if (p == *q && !p->caught)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Don't really pop if there are still active handlers for our exception;
|
||||||
|
rather, push it down past any uncaught exceptions. */
|
||||||
|
if (p->handlers != 0)
|
||||||
|
{
|
||||||
|
if (p == *q && p->next && !p->next->caught)
|
||||||
|
{
|
||||||
|
q = &(p->next);
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (*q == 0 || (*q)->caught)
|
||||||
|
break;
|
||||||
|
|
||||||
|
q = &((*q)->next);
|
||||||
|
}
|
||||||
|
*stack = p->next;
|
||||||
|
p->next = *q;
|
||||||
|
*q = p;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; *q; q = &((*q)->next))
|
||||||
|
if (*q == p)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (! *q)
|
||||||
|
terminate ();
|
||||||
|
|
||||||
|
*q = p->next;
|
||||||
|
|
||||||
|
if (p->cleanup)
|
||||||
|
// value may have been adjusted.
|
||||||
|
CALL_CLEANUP (p->cleanup, p->original_value);
|
||||||
|
|
||||||
|
if (! __is_pointer (p->type))
|
||||||
|
__eh_free (p->original_value); // value may have been adjusted.
|
||||||
|
|
||||||
|
__eh_free (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We're doing a rethrow. Find the currently handled exception, mark it
|
||||||
|
uncaught, and move it to the top of the EH stack. */
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__uncatch_exception (void)
|
||||||
|
{
|
||||||
|
cp_eh_info **stack = __get_eh_info ();
|
||||||
|
cp_eh_info **q = stack;
|
||||||
|
cp_eh_info *p;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
p = *q;
|
||||||
|
|
||||||
|
if (p == 0)
|
||||||
|
terminate ();
|
||||||
|
if (p->caught)
|
||||||
|
break;
|
||||||
|
|
||||||
|
q = &(p->next);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (q != stack)
|
||||||
|
{
|
||||||
|
*q = p->next;
|
||||||
|
p->next = *stack;
|
||||||
|
*stack = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->caught = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* As per [except.unexpected]:
|
||||||
|
If an exception is thrown, we check it against the spec. If it doesn't
|
||||||
|
match, we call unexpected (). If unexpected () throws, we check that
|
||||||
|
exception against the spec. If it doesn't match, if the spec allows
|
||||||
|
bad_exception we throw that; otherwise we call terminate ().
|
||||||
|
|
||||||
|
The compiler treats an exception spec as a try block with a generic
|
||||||
|
handler that just calls this function with a list of the allowed
|
||||||
|
exception types, so we have an active exception that can be rethrown.
|
||||||
|
|
||||||
|
This function does not return. */
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__check_eh_spec (int n, const void **spec)
|
||||||
|
{
|
||||||
|
cp_eh_info *p = CP_EH_INFO;
|
||||||
|
void *d;
|
||||||
|
|
||||||
|
for (int i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
if (__throw_type_match_rtti_2 (spec[i], p->type, p->value, &d))
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::unexpected ();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
// __exception_info is an artificial var pushed into each catch block.
|
||||||
|
if (p != __exception_info)
|
||||||
|
{
|
||||||
|
p = __exception_info;
|
||||||
|
for (int i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
if (__throw_type_match_rtti_2 (spec[i], p->type, p->value, &d))
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::type_info &bad_exc = typeid (std::bad_exception);
|
||||||
|
for (int i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
if (__throw_type_match_rtti_2 (spec[i], &bad_exc, p->value, &d))
|
||||||
|
throw std::bad_exception ();
|
||||||
|
}
|
||||||
|
|
||||||
|
terminate ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Special case of the above for throw() specs. */
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__check_null_eh_spec (void)
|
||||||
|
{
|
||||||
|
__check_eh_spec (0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helpers for rtti. Although these don't return, we give them return types so
|
||||||
|
// that the type system is not broken.
|
||||||
|
|
||||||
|
extern "C" void *
|
||||||
|
__throw_bad_cast ()
|
||||||
|
{
|
||||||
|
throw std::bad_cast ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" std::type_info const &
|
||||||
|
__throw_bad_typeid ()
|
||||||
|
{
|
||||||
|
throw std::bad_typeid ();
|
||||||
|
return typeid (void);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Has the current exception been caught? */
|
||||||
|
|
||||||
|
bool
|
||||||
|
std::uncaught_exception ()
|
||||||
|
{
|
||||||
|
cp_eh_info *p = CP_EH_INFO;
|
||||||
|
return p && ! p->caught;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * std::exception::
|
||||||
|
what () const
|
||||||
|
{
|
||||||
|
return typeid (*this).name ();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
// The -*- C++ -*- dynamic memory management header.
|
||||||
|
// Copyright (C) 1994, 1996, 1997, 1998, 2000 Free Software Foundation
|
||||||
|
|
||||||
|
// This file is part of GNU CC.
|
||||||
|
//
|
||||||
|
// GNU CC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GNU CC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with GNU CC; see the file COPYING. If not, write to
|
||||||
|
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
// Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
// As a special exception, you may use this file as part of a free software
|
||||||
|
// library without restriction. Specifically, if other files instantiate
|
||||||
|
// templates or use macros or inline functions from this file, or you compile
|
||||||
|
// this file and link it with other files to produce an executable, this
|
||||||
|
// file does not by itself cause the resulting executable to be covered by
|
||||||
|
// the GNU General Public License. This exception does not however
|
||||||
|
// invalidate any other reasons why the executable file might be covered by
|
||||||
|
// the GNU General Public License.
|
||||||
|
|
||||||
|
#ifndef __NEW__
|
||||||
|
#define __NEW__
|
||||||
|
|
||||||
|
#pragma interface "new"
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
extern "C++" {
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
class bad_alloc : public exception {
|
||||||
|
public:
|
||||||
|
virtual const char* what() const throw() { return "bad_alloc"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nothrow_t {};
|
||||||
|
extern const nothrow_t nothrow;
|
||||||
|
typedef void (*new_handler)();
|
||||||
|
new_handler set_new_handler (new_handler);
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
// replaceable signatures
|
||||||
|
void *operator new (size_t) throw (std::bad_alloc);
|
||||||
|
void *operator new[] (size_t) throw (std::bad_alloc);
|
||||||
|
void operator delete (void *) throw();
|
||||||
|
void operator delete[] (void *) throw();
|
||||||
|
void *operator new (size_t, const std::nothrow_t&) throw();
|
||||||
|
void *operator new[] (size_t, const std::nothrow_t&) throw();
|
||||||
|
void operator delete (void *, const std::nothrow_t&) throw();
|
||||||
|
void operator delete[] (void *, const std::nothrow_t&) throw();
|
||||||
|
|
||||||
|
// default placement versions of operator new
|
||||||
|
inline void *operator new(size_t, void *place) throw() { return place; }
|
||||||
|
inline void *operator new[](size_t, void *place) throw() { return place; }
|
||||||
|
} // extern "C++"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
// -*- C++ -*- forwarding header.
|
||||||
|
// Copyright (C) 2000 Free Software Foundation
|
||||||
|
|
||||||
|
// This file is part of GNU CC.
|
||||||
|
//
|
||||||
|
// GNU CC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GNU CC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with GNU CC; see the file COPYING. If not, write to
|
||||||
|
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
// Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
// As a special exception, you may use this file as part of a free software
|
||||||
|
// library without restriction. Specifically, if other files instantiate
|
||||||
|
// templates or use macros or inline functions from this file, or you compile
|
||||||
|
// this file and link it with other files to produce an executable, this
|
||||||
|
// file does not by itself cause the resulting executable to be covered by
|
||||||
|
// the GNU General Public License. This exception does not however
|
||||||
|
// invalidate any other reasons why the executable file might be covered by
|
||||||
|
// the GNU General Public License.
|
||||||
|
|
||||||
|
#ifndef __NEW_H__
|
||||||
|
#define __NEW_H__
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
using std::new_handler;
|
||||||
|
using std::set_new_handler;
|
||||||
|
|
||||||
|
#endif // __NEW_H__
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Implementation file for the -*- C++ -*- dynamic memory management header.
|
||||||
|
// Copyright (C) 1996, 1997, 1998, 2000 Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GNU CC.
|
||||||
|
//
|
||||||
|
// GNU CC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GNU CC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with GNU CC; see the file COPYING. If not, write to
|
||||||
|
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
// Boston, MA 02111-1307, USA.
|
||||||
|
//
|
||||||
|
// As a special exception, you may use this file as part of a free software
|
||||||
|
// library without restriction. Specifically, if other files instantiate
|
||||||
|
// templates or use macros or inline functions from this file, or you compile
|
||||||
|
// this file and link it with other files to produce an executable, this
|
||||||
|
// file does not by itself cause the resulting executable to be covered by
|
||||||
|
// the GNU General Public License. This exception does not however
|
||||||
|
// invalidate any other reasons why the executable file might be covered by
|
||||||
|
// the GNU General Public License.
|
||||||
|
|
||||||
|
#pragma implementation "new"
|
||||||
|
#include "new"
|
||||||
|
|
||||||
|
const std::nothrow_t std::nothrow = { };
|
||||||
|
|
||||||
|
using std::new_handler;
|
||||||
|
new_handler __new_handler;
|
||||||
|
|
||||||
|
new_handler
|
||||||
|
std::set_new_handler (new_handler handler)
|
||||||
|
{
|
||||||
|
new_handler prev_handler = __new_handler;
|
||||||
|
__new_handler = handler;
|
||||||
|
return prev_handler;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
// Support routines for the -*- C++ -*- dynamic memory management.
|
||||||
|
// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GNU CC.
|
||||||
|
//
|
||||||
|
// GNU CC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GNU CC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with GNU CC; see the file COPYING. If not, write to
|
||||||
|
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
// Boston, MA 02111-1307, USA.
|
||||||
|
//
|
||||||
|
// As a special exception, you may use this file as part of a free software
|
||||||
|
// library without restriction. Specifically, if other files instantiate
|
||||||
|
// templates or use macros or inline functions from this file, or you compile
|
||||||
|
// this file and link it with other files to produce an executable, this
|
||||||
|
// file does not by itself cause the resulting executable to be covered by
|
||||||
|
// the GNU General Public License. This exception does not however
|
||||||
|
// invalidate any other reasons why the executable file might be covered by
|
||||||
|
// the GNU General Public License.
|
||||||
|
|
||||||
|
#include "new"
|
||||||
|
using std::new_handler;
|
||||||
|
using std::bad_alloc;
|
||||||
|
|
||||||
|
extern "C" void *malloc (size_t);
|
||||||
|
extern new_handler __new_handler;
|
||||||
|
|
||||||
|
void *
|
||||||
|
operator new (size_t sz) throw (std::bad_alloc)
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
/* malloc (0) is unpredictable; avoid it. */
|
||||||
|
if (sz == 0)
|
||||||
|
sz = 1;
|
||||||
|
p = (void *) malloc (sz);
|
||||||
|
while (p == 0)
|
||||||
|
{
|
||||||
|
new_handler handler = __new_handler;
|
||||||
|
if (! handler)
|
||||||
|
throw bad_alloc ();
|
||||||
|
handler ();
|
||||||
|
p = (void *) malloc (sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
// Support routines for the -*- C++ -*- dynamic memory management.
|
||||||
|
// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GNU CC.
|
||||||
|
//
|
||||||
|
// GNU CC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GNU CC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with GNU CC; see the file COPYING. If not, write to
|
||||||
|
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
// Boston, MA 02111-1307, USA.
|
||||||
|
//
|
||||||
|
// As a special exception, you may use this file as part of a free software
|
||||||
|
// library without restriction. Specifically, if other files instantiate
|
||||||
|
// templates or use macros or inline functions from this file, or you compile
|
||||||
|
// this file and link it with other files to produce an executable, this
|
||||||
|
// file does not by itself cause the resulting executable to be covered by
|
||||||
|
// the GNU General Public License. This exception does not however
|
||||||
|
// invalidate any other reasons why the executable file might be covered by
|
||||||
|
// the GNU General Public License.
|
||||||
|
|
||||||
|
#include "new"
|
||||||
|
using std::new_handler;
|
||||||
|
using std::bad_alloc;
|
||||||
|
|
||||||
|
extern "C" void *malloc (size_t);
|
||||||
|
extern new_handler __new_handler;
|
||||||
|
|
||||||
|
void *
|
||||||
|
operator new (size_t sz, const std::nothrow_t&) throw()
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
/* malloc (0) is unpredictable; avoid it. */
|
||||||
|
if (sz == 0)
|
||||||
|
sz = 1;
|
||||||
|
p = (void *) malloc (sz);
|
||||||
|
while (p == 0)
|
||||||
|
{
|
||||||
|
new_handler handler = __new_handler;
|
||||||
|
if (! handler)
|
||||||
|
return 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
handler ();
|
||||||
|
}
|
||||||
|
catch (bad_alloc &)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = (void *) malloc (sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
|
||||||
|
// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GNU CC.
|
||||||
|
//
|
||||||
|
// GNU CC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GNU CC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with GNU CC; see the file COPYING. If not, write to
|
||||||
|
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
// Boston, MA 02111-1307, USA.
|
||||||
|
//
|
||||||
|
// As a special exception, you may use this file as part of a free software
|
||||||
|
// library without restriction. Specifically, if other files instantiate
|
||||||
|
// templates or use macros or inline functions from this file, or you compile
|
||||||
|
// this file and link it with other files to produce an executable, this
|
||||||
|
// file does not by itself cause the resulting executable to be covered by
|
||||||
|
// the GNU General Public License. This exception does not however
|
||||||
|
// invalidate any other reasons why the executable file might be covered by
|
||||||
|
// the GNU General Public License.
|
||||||
|
|
||||||
|
#include "new"
|
||||||
|
|
||||||
|
void *
|
||||||
|
operator new[] (size_t sz) throw (std::bad_alloc)
|
||||||
|
{
|
||||||
|
return ::operator new(sz);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
|
||||||
|
// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GNU CC.
|
||||||
|
//
|
||||||
|
// GNU CC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GNU CC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with GNU CC; see the file COPYING. If not, write to
|
||||||
|
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
// Boston, MA 02111-1307, USA.
|
||||||
|
//
|
||||||
|
// As a special exception, you may use this file as part of a free software
|
||||||
|
// library without restriction. Specifically, if other files instantiate
|
||||||
|
// templates or use macros or inline functions from this file, or you compile
|
||||||
|
// this file and link it with other files to produce an executable, this
|
||||||
|
// file does not by itself cause the resulting executable to be covered by
|
||||||
|
// the GNU General Public License. This exception does not however
|
||||||
|
// invalidate any other reasons why the executable file might be covered by
|
||||||
|
// the GNU General Public License.
|
||||||
|
|
||||||
|
#include "new"
|
||||||
|
|
||||||
|
void *
|
||||||
|
operator new[] (size_t sz, const std::nothrow_t& nothrow) throw()
|
||||||
|
{
|
||||||
|
return ::operator new(sz, nothrow);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef __GNU_LIBRARY__
|
||||||
|
/* Avoid forcing the library's meaning of `write' on the user program
|
||||||
|
by using the "internal" name (for use within the library) */
|
||||||
|
#define write(fd, buf, n) __write((fd), (buf), (n))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MESSAGE "pure virtual method called\n"
|
||||||
|
|
||||||
|
void
|
||||||
|
__pure_virtual (void)
|
||||||
|
{
|
||||||
|
write (2, MESSAGE, sizeof (MESSAGE) - 1);
|
||||||
|
__terminate ();
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,223 @@
|
||||||
|
// RTTI support internals for -*- C++ -*-
|
||||||
|
// Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000 Free Software Foundation
|
||||||
|
|
||||||
|
#include "typeinfo"
|
||||||
|
|
||||||
|
// Class declarations shared between the typeinfo implementation files.
|
||||||
|
|
||||||
|
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||||
|
// original (old) abi
|
||||||
|
|
||||||
|
// type_info for a class with no base classes (or an enum).
|
||||||
|
|
||||||
|
struct __user_type_info : public std::type_info {
|
||||||
|
__user_type_info (const char *n) : type_info (n) {}
|
||||||
|
|
||||||
|
// If our type can be upcast to a public and unambiguous base, then return
|
||||||
|
// non-zero and set RES to point to the base object. OBJ points to the throw
|
||||||
|
// object and can be NULL, if there is no object to adjust.
|
||||||
|
int upcast (const type_info &target, void *obj, void **res) const;
|
||||||
|
|
||||||
|
// If our type can be dynamicly cast to the target type, then return
|
||||||
|
// pointer to the target object. OBJ is the pointer to the most derived
|
||||||
|
// type and cannot be NULL. SUBTYPE and SUBOBJ indicate the static type
|
||||||
|
// base object from whence we came, it cannot be NULL. SUBTYPE cannot be
|
||||||
|
// the same as TARGET. TARGET cannot be a base of SUBTYPE.
|
||||||
|
// BOFF indicates how SUBTYPE is related to TARGET.
|
||||||
|
// BOFF >= 0, there is only one public non-virtual SUBTYPE base at offset
|
||||||
|
// BOFF, and there are no public virtual SUBTYPE bases.
|
||||||
|
// Therefore check if SUBOBJ is at offset BOFF when we find a target
|
||||||
|
// BOFF == -1, SUBTYPE occurs as multiple public virtual or non-virtual bases.
|
||||||
|
// Lazily search all the bases of TARGET.
|
||||||
|
// BOFF == -2, SUBTYPE is not a public base.
|
||||||
|
// BOFF == -3, SUBTYPE occurs as multiple public non-virtual bases.
|
||||||
|
// Lazily search the non-virtual bases of TARGET.
|
||||||
|
// For backwards compatibility set BOFF to -1, that is the safe "unknown"
|
||||||
|
// value. We do not care about SUBTYPES as private bases of TARGET, as they
|
||||||
|
// can never succeed as downcasts, only as crosscasts -- and then only if
|
||||||
|
// they are virtual. This is more complicated that it might seem.
|
||||||
|
void *dyncast (int boff,
|
||||||
|
const type_info &target, void *obj,
|
||||||
|
const type_info &subtype, void *subobj) const;
|
||||||
|
|
||||||
|
// non_virtual_base_type is used to indicate that a base class is via a
|
||||||
|
// non-virtual access path.
|
||||||
|
static const type_info *const nonvirtual_base_type
|
||||||
|
= static_cast <const type_info *> (0) + 1;
|
||||||
|
|
||||||
|
// 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_mask = 4, // contained within us
|
||||||
|
contained_virtual_mask = 1, // via a virtual path
|
||||||
|
contained_public_mask = 2, // via a public path
|
||||||
|
contained_private = contained_mask,
|
||||||
|
contained_public = contained_mask | contained_public_mask
|
||||||
|
};
|
||||||
|
// some predicate functions for sub_kind
|
||||||
|
static inline bool contained_p (sub_kind access_path)
|
||||||
|
{
|
||||||
|
return access_path >= contained_mask;
|
||||||
|
}
|
||||||
|
static inline bool contained_public_p (sub_kind access_path)
|
||||||
|
{
|
||||||
|
return access_path >= contained_public;
|
||||||
|
}
|
||||||
|
static inline bool contained_nonpublic_p (sub_kind access_path)
|
||||||
|
{
|
||||||
|
return (access_path & contained_public) == contained_mask;
|
||||||
|
}
|
||||||
|
static inline bool contained_nonvirtual_p (sub_kind access_path)
|
||||||
|
{
|
||||||
|
return (access_path & (contained_mask | contained_virtual_mask))
|
||||||
|
== contained_mask;
|
||||||
|
}
|
||||||
|
static inline bool contained_virtual_p (sub_kind access_path)
|
||||||
|
{
|
||||||
|
return (access_path & (contained_mask | contained_virtual_mask))
|
||||||
|
== (contained_mask | contained_virtual_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct upcast_result
|
||||||
|
{
|
||||||
|
void *target_obj; // pointer to target object or NULL (init NULL)
|
||||||
|
sub_kind whole2target; // path from most derived object to target
|
||||||
|
const type_info *base_type; // where we found the target, (init NULL)
|
||||||
|
// if in vbase the __user_type_info of vbase)
|
||||||
|
// if a non-virtual base then 1
|
||||||
|
// else NULL
|
||||||
|
public:
|
||||||
|
upcast_result ()
|
||||||
|
:target_obj (NULL), whole2target (unknown), base_type (NULL)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
struct dyncast_result
|
||||||
|
{
|
||||||
|
void *target_obj; // pointer to target object or NULL (init NULL)
|
||||||
|
sub_kind whole2target; // path from most derived object to target
|
||||||
|
sub_kind whole2sub; // path from most derived object to sub object
|
||||||
|
sub_kind target2sub; // path from target to sub object
|
||||||
|
|
||||||
|
public:
|
||||||
|
dyncast_result ()
|
||||||
|
:target_obj (NULL), whole2target (unknown),
|
||||||
|
whole2sub (unknown), target2sub (unknown)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Helper for upcast. See if TARGET is us, or one of our bases. ACCESS_PATH
|
||||||
|
// gives the access from the start object. Return TRUE if we know the catch
|
||||||
|
// fails.
|
||||||
|
virtual bool do_upcast (sub_kind access_path,
|
||||||
|
const type_info &target, void *obj,
|
||||||
|
upcast_result &__restrict result) const;
|
||||||
|
// Helper for dyncast. BOFF indicates how the SUBTYPE is related to TARGET.
|
||||||
|
// ACCESS_PATH indicates the access from the most derived object. It is
|
||||||
|
// used to prune the DAG walk. All information about what we find is put
|
||||||
|
// into RESULT. Return true, if the match we have found is ambiguous.
|
||||||
|
virtual bool do_dyncast (int boff, sub_kind access_path,
|
||||||
|
const type_info &target, void *obj,
|
||||||
|
const type_info &subtype, void *subptr,
|
||||||
|
dyncast_result &__restrict result) const;
|
||||||
|
public:
|
||||||
|
// Indicate whether SUBPTR of type SUBTYPE is contained publicly within
|
||||||
|
// OBJPTR. OBJPTR points to this base object. BOFF indicates how SUBTYPE
|
||||||
|
// objects might be contained within this type. If SUBPTR is one of our
|
||||||
|
// SUBTYPE bases, indicate virtuality. Returns not_contained for non
|
||||||
|
// containment or private containment.
|
||||||
|
sub_kind find_public_subobj (int boff, const type_info &subtype,
|
||||||
|
void *objptr, void *subptr) const
|
||||||
|
{
|
||||||
|
if (boff >= 0)
|
||||||
|
return ((char *)subptr - (char *)objptr) == boff
|
||||||
|
? contained_public : not_contained;
|
||||||
|
if (boff == -2)
|
||||||
|
return not_contained;
|
||||||
|
return do_find_public_subobj (boff, subtype, objptr, subptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Helper for find_subobj. BOFF indicates how SUBTYPE bases are inherited by
|
||||||
|
// the type started from -- which is not necessarily the current type.
|
||||||
|
// OBJPTR points to the current base.
|
||||||
|
virtual sub_kind do_find_public_subobj (int boff, const type_info &subtype,
|
||||||
|
void *objptr, void *subptr) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// type_info for a class with one public, nonvirtual base class.
|
||||||
|
|
||||||
|
class __si_type_info : public __user_type_info {
|
||||||
|
const __user_type_info &base;
|
||||||
|
|
||||||
|
public:
|
||||||
|
__si_type_info (const char *n, const __user_type_info &b)
|
||||||
|
: __user_type_info (n), base (b) { }
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual bool do_upcast (sub_kind access_path,
|
||||||
|
const type_info &target, void *obj,
|
||||||
|
upcast_result &__restrict result) const;
|
||||||
|
virtual bool do_dyncast (int boff, sub_kind access_path,
|
||||||
|
const type_info &target, void *obj,
|
||||||
|
const type_info &subtype, void *subptr,
|
||||||
|
dyncast_result &__restrict result) const;
|
||||||
|
virtual sub_kind do_find_public_subobj (int boff, const type_info &subtype,
|
||||||
|
void *objptr, void *subptr) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// type_info for a general class.
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#if INT_MAX == 2147483647
|
||||||
|
typedef int myint32;
|
||||||
|
#elif SHRT_MAX == 2147483647
|
||||||
|
typedef short myint32;
|
||||||
|
#elif SCHAR_MAX == 2147483647
|
||||||
|
typedef signed char myint32;
|
||||||
|
#elif LONG_MAX == 2147483647
|
||||||
|
typedef long myint32;
|
||||||
|
#else
|
||||||
|
# error "No 32-bit data type?"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct __class_type_info : public __user_type_info {
|
||||||
|
enum access { PUBLIC = 1, PROTECTED = 2, PRIVATE = 3 };
|
||||||
|
|
||||||
|
struct base_info {
|
||||||
|
const __user_type_info *base;
|
||||||
|
myint32 offset: 29;
|
||||||
|
bool is_virtual: 1;
|
||||||
|
enum access access: 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
const base_info *base_list;
|
||||||
|
size_t n_bases;
|
||||||
|
|
||||||
|
__class_type_info (const char *name, const base_info *bl, size_t bn)
|
||||||
|
: __user_type_info (name), base_list (bl), n_bases (bn) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual bool do_upcast (sub_kind access_path,
|
||||||
|
const type_info &target, void *obj,
|
||||||
|
upcast_result &__restrict result) const;
|
||||||
|
virtual bool do_dyncast (int boff, sub_kind access_path,
|
||||||
|
const type_info &target, void *obj,
|
||||||
|
const type_info &subtype, void *subptr,
|
||||||
|
dyncast_result &__restrict result) const;
|
||||||
|
virtual sub_kind do_find_public_subobj (int boff, const type_info &subtype,
|
||||||
|
void *objptr, void *subptr) const;
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
// new abi
|
||||||
|
#include <cxxabi.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,452 @@
|
||||||
|
// Methods for type_info for -*- C++ -*- Run Time Type Identification.
|
||||||
|
// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000 Free Software Foundation
|
||||||
|
|
||||||
|
// This file is part of GNU CC.
|
||||||
|
|
||||||
|
// GNU CC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// GNU CC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with GNU CC; see the file COPYING. If not, write to
|
||||||
|
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
// Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
// As a special exception, you may use this file as part of a free software
|
||||||
|
// library without restriction. Specifically, if other files instantiate
|
||||||
|
// templates or use macros or inline functions from this file, or you compile
|
||||||
|
// this file and link it with other files to produce an executable, this
|
||||||
|
// file does not by itself cause the resulting executable to be covered by
|
||||||
|
// the GNU General Public License. This exception does not however
|
||||||
|
// invalidate any other reasons why the executable file might be covered by
|
||||||
|
// the GNU General Public License.
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "tinfo.hP"
|
||||||
|
#include "new" // for placement new
|
||||||
|
|
||||||
|
// We can't rely on having stdlib.h if we're freestanding.
|
||||||
|
extern "C" void abort ();
|
||||||
|
|
||||||
|
using std::type_info;
|
||||||
|
|
||||||
|
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||||
|
bool
|
||||||
|
type_info::before (const type_info &arg) const
|
||||||
|
{
|
||||||
|
return __builtin_strcmp (name (), arg.name ()) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// type info for pointer type.
|
||||||
|
|
||||||
|
struct __pointer_type_info : public type_info {
|
||||||
|
const type_info& type;
|
||||||
|
|
||||||
|
__pointer_type_info (const char *n, const type_info& ti)
|
||||||
|
: type_info (n), type (ti) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// type info for attributes
|
||||||
|
|
||||||
|
struct __attr_type_info : public type_info {
|
||||||
|
enum cv { NONE = 0, CONST = 1, VOLATILE = 2, CONSTVOL = 1 | 2 };
|
||||||
|
|
||||||
|
const type_info& type;
|
||||||
|
cv attr;
|
||||||
|
|
||||||
|
__attr_type_info (const char *n, cv a, const type_info& t)
|
||||||
|
: type_info (n), type (t), attr (a) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// type_info for builtin type
|
||||||
|
|
||||||
|
struct __builtin_type_info : public type_info {
|
||||||
|
__builtin_type_info (const char *n): type_info (n) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// type info for function.
|
||||||
|
|
||||||
|
struct __func_type_info : public type_info {
|
||||||
|
__func_type_info (const char *n) : type_info (n) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// type info for pointer to member function.
|
||||||
|
|
||||||
|
struct __ptmf_type_info : public type_info {
|
||||||
|
__ptmf_type_info (const char *n) : type_info (n) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// type info for pointer to data member.
|
||||||
|
|
||||||
|
struct __ptmd_type_info : public type_info {
|
||||||
|
__ptmd_type_info (const char *n): type_info (n) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// type info for array.
|
||||||
|
|
||||||
|
struct __array_type_info : public type_info {
|
||||||
|
__array_type_info (const char *n): type_info (n) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <cxxabi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
|
||||||
|
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
|
||||||
|
// mandated to exist in the runtime.
|
||||||
|
__fundamental_type_info::
|
||||||
|
~__fundamental_type_info ()
|
||||||
|
{}
|
||||||
|
|
||||||
|
__array_type_info::
|
||||||
|
~__array_type_info ()
|
||||||
|
{}
|
||||||
|
|
||||||
|
__function_type_info::
|
||||||
|
~__function_type_info ()
|
||||||
|
{}
|
||||||
|
|
||||||
|
__enum_type_info::
|
||||||
|
~__enum_type_info ()
|
||||||
|
{}
|
||||||
|
|
||||||
|
__pbase_type_info::
|
||||||
|
~__pbase_type_info ()
|
||||||
|
{}
|
||||||
|
|
||||||
|
__pointer_type_info::
|
||||||
|
~__pointer_type_info ()
|
||||||
|
{}
|
||||||
|
|
||||||
|
__pointer_to_member_type_info::
|
||||||
|
~__pointer_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 __pbase_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 same kind of 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 __pbase_type_info *thrown_type =
|
||||||
|
static_cast <const __pbase_type_info *> (thr_type);
|
||||||
|
|
||||||
|
if (thrown_type->__qualifier_flags & ~__qualifier_flags)
|
||||||
|
// We're less qualified.
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!(__qualifier_flags & __const_mask))
|
||||||
|
outer &= ~1;
|
||||||
|
|
||||||
|
return __pointer_catch (thrown_type, thr_obj, outer);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool __pbase_type_info::
|
||||||
|
__pointer_catch (const __pbase_type_info *thrown_type,
|
||||||
|
void **thr_obj,
|
||||||
|
unsigned outer) const
|
||||||
|
{
|
||||||
|
return __pointee->__do_catch (thrown_type->__pointee, thr_obj, outer + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool __pointer_type_info::
|
||||||
|
__pointer_catch (const __pbase_type_info *thrown_type,
|
||||||
|
void **thr_obj,
|
||||||
|
unsigned outer) const
|
||||||
|
{
|
||||||
|
if (outer < 2 && *__pointee == typeid (void))
|
||||||
|
{
|
||||||
|
// conversion to void
|
||||||
|
return !thrown_type->__pointee->__is_function_p ();
|
||||||
|
}
|
||||||
|
|
||||||
|
return __pbase_type_info::__pointer_catch (thrown_type, thr_obj, outer);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool __pointer_to_member_type_info::
|
||||||
|
__pointer_catch (const __pbase_type_info *thr_type,
|
||||||
|
void **thr_obj,
|
||||||
|
unsigned outer) const
|
||||||
|
{
|
||||||
|
// This static cast is always valid, as our caller will have determined that
|
||||||
|
// thr_type is really a __pointer_to_member_type_info.
|
||||||
|
const __pointer_to_member_type_info *thrown_type =
|
||||||
|
static_cast <const __pointer_to_member_type_info *> (thr_type);
|
||||||
|
|
||||||
|
if (*__context_class != *thrown_type->__context_class)
|
||||||
|
return false; // not pointers to member of same class
|
||||||
|
|
||||||
|
return __pbase_type_info::__pointer_catch (thrown_type, thr_obj, outer);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Entry points for the compiler.
|
||||||
|
|
||||||
|
/* Low level match routine used by compiler to match types of catch
|
||||||
|
variables and thrown objects. */
|
||||||
|
|
||||||
|
extern "C" int
|
||||||
|
__throw_type_match_rtti_2 (const void *catch_type_r, const void *throw_type_r,
|
||||||
|
void *objptr, void **valp)
|
||||||
|
{
|
||||||
|
const type_info &catch_type = *(const type_info *)catch_type_r;
|
||||||
|
const type_info &throw_type = *(const type_info *)throw_type_r;
|
||||||
|
|
||||||
|
*valp = objptr;
|
||||||
|
|
||||||
|
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||||
|
// old abi
|
||||||
|
if (catch_type == throw_type)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (const __user_type_info *p
|
||||||
|
= dynamic_cast <const __user_type_info *> (&throw_type))
|
||||||
|
{
|
||||||
|
return p->upcast (catch_type, objptr, valp);
|
||||||
|
}
|
||||||
|
else if (const __pointer_type_info *fr =
|
||||||
|
dynamic_cast <const __pointer_type_info *> (&throw_type))
|
||||||
|
{
|
||||||
|
const __pointer_type_info *to =
|
||||||
|
dynamic_cast <const __pointer_type_info *> (&catch_type);
|
||||||
|
|
||||||
|
if (! to)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const type_info *subfr = &fr->type, *subto = &to->type;
|
||||||
|
__attr_type_info::cv cvfrom, cvto;
|
||||||
|
|
||||||
|
if (const __attr_type_info *at
|
||||||
|
= dynamic_cast <const __attr_type_info *> (subfr))
|
||||||
|
{
|
||||||
|
cvfrom = at->attr;
|
||||||
|
subfr = &at->type;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cvfrom = __attr_type_info::NONE;
|
||||||
|
|
||||||
|
if (const __attr_type_info *at
|
||||||
|
= dynamic_cast <const __attr_type_info *> (subto))
|
||||||
|
{
|
||||||
|
cvto = at->attr;
|
||||||
|
subto = &at->type;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cvto = __attr_type_info::NONE;
|
||||||
|
|
||||||
|
if (((cvfrom & __attr_type_info::CONST)
|
||||||
|
> (cvto & __attr_type_info::CONST))
|
||||||
|
|| ((cvfrom & __attr_type_info::VOLATILE)
|
||||||
|
> (cvto & __attr_type_info::VOLATILE)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (*subto == *subfr)
|
||||||
|
return 1;
|
||||||
|
else if (*subto == typeid (void)
|
||||||
|
&& dynamic_cast <const __func_type_info *> (subfr) == 0)
|
||||||
|
return 1;
|
||||||
|
else if (const __user_type_info *p
|
||||||
|
= dynamic_cast <const __user_type_info *> (subfr))
|
||||||
|
return p->upcast (*subto, objptr, valp);
|
||||||
|
else if (const __pointer_type_info *pfr
|
||||||
|
= dynamic_cast <const __pointer_type_info *> (subfr))
|
||||||
|
{
|
||||||
|
// Multi-level pointer conversion.
|
||||||
|
|
||||||
|
const __pointer_type_info *pto
|
||||||
|
= dynamic_cast <const __pointer_type_info *> (subto);
|
||||||
|
|
||||||
|
if (! pto)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bool constp = (cvto & __attr_type_info::CONST);
|
||||||
|
for (subto = &pto->type, subfr = &pfr->type; ;
|
||||||
|
subto = &pto->type, subfr = &pfr->type)
|
||||||
|
{
|
||||||
|
if (const __attr_type_info *at
|
||||||
|
= dynamic_cast <const __attr_type_info *> (subfr))
|
||||||
|
{
|
||||||
|
cvfrom = at->attr;
|
||||||
|
subfr = &at->type;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cvfrom = __attr_type_info::NONE;
|
||||||
|
|
||||||
|
if (const __attr_type_info *at
|
||||||
|
= dynamic_cast <const __attr_type_info *> (subto))
|
||||||
|
{
|
||||||
|
cvto = at->attr;
|
||||||
|
subto = &at->type;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cvto = __attr_type_info::NONE;
|
||||||
|
|
||||||
|
if (((cvfrom & __attr_type_info::CONST)
|
||||||
|
> (cvto & __attr_type_info::CONST))
|
||||||
|
|| ((cvfrom & __attr_type_info::VOLATILE)
|
||||||
|
> (cvto & __attr_type_info::VOLATILE)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (! constp
|
||||||
|
&& (((cvfrom & __attr_type_info::CONST)
|
||||||
|
< (cvto & __attr_type_info::CONST))
|
||||||
|
|| ((cvfrom & __attr_type_info::VOLATILE)
|
||||||
|
< (cvto & __attr_type_info::VOLATILE))))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (*subto == *subfr)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
pto = dynamic_cast <const __pointer_type_info *> (subto);
|
||||||
|
pfr = dynamic_cast <const __pointer_type_info *> (subfr);
|
||||||
|
if (! pto || ! pfr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (! (cvto & __attr_type_info::CONST))
|
||||||
|
constp = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// new abi
|
||||||
|
|
||||||
|
return catch_type.__do_catch (&throw_type, valp, 1);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||||
|
/* Backward compatibility wrapper. */
|
||||||
|
|
||||||
|
extern "C" void*
|
||||||
|
__throw_type_match_rtti (const void *catch_type_r, const void *throw_type_r,
|
||||||
|
void *objptr)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
if (__throw_type_match_rtti_2 (catch_type_r, throw_type_r, objptr, &ret))
|
||||||
|
return ret;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Called from __cp_pop_exception. Is P the type_info node for a pointer
|
||||||
|
of some kind? */
|
||||||
|
|
||||||
|
bool
|
||||||
|
__is_pointer (void *p)
|
||||||
|
{
|
||||||
|
const type_info *t = reinterpret_cast <const type_info *>(p);
|
||||||
|
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||||
|
// old abi
|
||||||
|
const __pointer_type_info *pt =
|
||||||
|
dynamic_cast <const __pointer_type_info *> (t);
|
||||||
|
return pt != 0;
|
||||||
|
#else
|
||||||
|
// new abi
|
||||||
|
return t->__is_pointer_p ();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||||
|
// old abi
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__rtti_ptr (void *addr, const char *n, const type_info *ti)
|
||||||
|
{ new (addr) __pointer_type_info (n, *ti); }
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__rtti_attr (void *addr, const char *n, int attrval, const type_info *ti)
|
||||||
|
{
|
||||||
|
new (addr) __attr_type_info
|
||||||
|
(n, static_cast <__attr_type_info::cv> (attrval), *ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__rtti_func (void *addr, const char *name)
|
||||||
|
{ new (addr) __func_type_info (name); }
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__rtti_ptmf (void *addr, const char *name)
|
||||||
|
{ new (addr) __ptmf_type_info (name); }
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__rtti_ptmd (void *addr, const char *name)
|
||||||
|
{ new (addr) __ptmd_type_info (name); }
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__rtti_array (void *addr, const char *name)
|
||||||
|
{ new (addr) __array_type_info (name); }
|
||||||
|
|
||||||
|
extern "C" void *
|
||||||
|
__dynamic_cast (const type_info& (*from)(void), const type_info& (*to)(void),
|
||||||
|
int require_public, void *address, const type_info & (*sub)(void), void *subptr)
|
||||||
|
{
|
||||||
|
if (!require_public) abort();
|
||||||
|
return static_cast <__user_type_info const &> (from ()).dyncast
|
||||||
|
(/*boff=*/-1, to (), address, sub (), subptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void *
|
||||||
|
__dynamic_cast_2 (const type_info& (*from)(void), const type_info& (*to)(void),
|
||||||
|
int boff,
|
||||||
|
void *address, const type_info & (*sub)(void), void *subptr)
|
||||||
|
{
|
||||||
|
return static_cast <__user_type_info const &> (from ()).dyncast
|
||||||
|
(boff, to (), address, sub (), subptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// type_info nodes and functions for the builtin types. The mangling here
|
||||||
|
// must match the mangling in gcc/cp/rtti.c.
|
||||||
|
|
||||||
|
#define BUILTIN(mangled) \
|
||||||
|
unsigned char __ti##mangled [sizeof (__builtin_type_info)] \
|
||||||
|
__attribute__ ((aligned (__alignof__ (void *)))); \
|
||||||
|
extern "C" const type_info &__tf##mangled (void) { \
|
||||||
|
if ((*(void **) __ti##mangled) == 0) \
|
||||||
|
new (__ti##mangled) __builtin_type_info (#mangled); \
|
||||||
|
return *(type_info *)__ti##mangled; \
|
||||||
|
}
|
||||||
|
|
||||||
|
BUILTIN (v); BUILTIN (x); BUILTIN (l); BUILTIN (i); BUILTIN (s); BUILTIN (b);
|
||||||
|
BUILTIN (c); BUILTIN (w); BUILTIN (r); BUILTIN (d); BUILTIN (f);
|
||||||
|
BUILTIN (Ui); BUILTIN (Ul); BUILTIN (Ux); BUILTIN (Us); BUILTIN (Uc);
|
||||||
|
BUILTIN (Sc);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,134 @@
|
||||||
|
// RTTI support for -*- C++ -*-
|
||||||
|
// Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000 Free Software Foundation
|
||||||
|
|
||||||
|
// This file is part of GNU CC.
|
||||||
|
//
|
||||||
|
// GNU CC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GNU CC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with GNU CC; see the file COPYING. If not, write to
|
||||||
|
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
// Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
// As a special exception, you may use this file as part of a free software
|
||||||
|
// library without restriction. Specifically, if other files instantiate
|
||||||
|
// templates or use macros or inline functions from this file, or you compile
|
||||||
|
// this file and link it with other files to produce an executable, this
|
||||||
|
// file does not by itself cause the resulting executable to be covered by
|
||||||
|
// the GNU General Public License. This exception does not however
|
||||||
|
// invalidate any other reasons why the executable file might be covered by
|
||||||
|
// the GNU General Public License.
|
||||||
|
|
||||||
|
// __GXX_ABI_VERSION distinguishes the ABI that is being used. Values <100
|
||||||
|
// indicate the `old' abi, which grew as C++ was defined. Values >=100
|
||||||
|
// indicate the `new' abi, which is a cross vendor C++ abi, documented at
|
||||||
|
// `http://reality.sgi.com/dehnert_engr/cxx/'.
|
||||||
|
|
||||||
|
#ifndef __TYPEINFO__
|
||||||
|
#define __TYPEINFO__
|
||||||
|
|
||||||
|
#pragma interface "typeinfo"
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
extern "C++" {
|
||||||
|
|
||||||
|
#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
|
||||||
|
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
|
||||||
|
// which translation unit the vtable is emitted. The compiler makes use of
|
||||||
|
// that information to know where to emit the runtime-mandated type_info
|
||||||
|
// structures in the new-abi.
|
||||||
|
virtual ~type_info ();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Assigning type_info is not supported. made private.
|
||||||
|
type_info& operator= (const type_info&);
|
||||||
|
type_info (const type_info&);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const char *__name;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit type_info (const char *__n): __name (__n) { }
|
||||||
|
|
||||||
|
public:
|
||||||
|
// the public interface
|
||||||
|
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
|
||||||
|
// In old abi, there can be multiple instances of a type_info object for one
|
||||||
|
// type. Uniqueness must use the _name value, not object address.
|
||||||
|
bool before (const type_info& arg) const;
|
||||||
|
const char* name () const
|
||||||
|
{ return __name; }
|
||||||
|
bool operator== (const type_info& __arg) const;
|
||||||
|
bool operator!= (const type_info& __arg) const
|
||||||
|
{ return !operator== (__arg); }
|
||||||
|
|
||||||
|
#else
|
||||||
|
// In new abi we can rely on type_info's NTBS being unique,
|
||||||
|
// and therefore address comparisons are sufficient.
|
||||||
|
bool before (const type_info& __arg) const
|
||||||
|
{ return __name < __arg.__name; }
|
||||||
|
const char* name () const
|
||||||
|
{ return __name; }
|
||||||
|
bool operator== (const type_info& __arg) const
|
||||||
|
{ return __name == __arg.__name; }
|
||||||
|
bool operator!= (const type_info& __arg) const
|
||||||
|
{ return !operator== (__arg); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// the internal interface
|
||||||
|
#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
|
||||||
|
public:
|
||||||
|
// return true if this is a pointer type of some kind
|
||||||
|
virtual bool __is_pointer_p () const;
|
||||||
|
// return true if this is a function type
|
||||||
|
virtual bool __is_function_p () const;
|
||||||
|
|
||||||
|
// Try and catch a thrown type. Store an adjusted pointer to the caught type
|
||||||
|
// in THR_OBJ. If THR_TYPE is not a pointer type, then THR_OBJ points to the
|
||||||
|
// thrown object. If THR_TYPE is a pointer type, then THR_OBJ is the pointer
|
||||||
|
// itself. OUTER indicates the number of outer pointers, and whether they
|
||||||
|
// were const qualified.
|
||||||
|
virtual bool __do_catch (const type_info *__thr_type, void **__thr_obj,
|
||||||
|
unsigned __outer) const;
|
||||||
|
|
||||||
|
// internally used during catch matching
|
||||||
|
virtual bool __do_upcast (const __cxxabiv1::__class_type_info *__target,
|
||||||
|
void **__obj_ptr) const;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
class bad_cast : public exception {
|
||||||
|
public:
|
||||||
|
bad_cast() { }
|
||||||
|
virtual ~bad_cast() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
class bad_typeid : public exception {
|
||||||
|
public:
|
||||||
|
bad_typeid () { }
|
||||||
|
virtual ~bad_typeid () { }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
} // extern "C++"
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,279 @@
|
||||||
|
// new abi support -*- C++ -*-
|
||||||
|
// Copyright (C) 2000
|
||||||
|
// Free Software Foundation, Inc.
|
||||||
|
// Written by Nathan Sidwell, Codesourcery LLC, <nathan@codesourcery.com>
|
||||||
|
//
|
||||||
|
// GNU CC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// GNU CC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with GNU CC; see the file COPYING. If not, write to
|
||||||
|
// the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
// Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
// As a special exception, you may use this file as part of a free software
|
||||||
|
// library without restriction. Specifically, if other files instantiate
|
||||||
|
// templates or use macros or inline functions from this file, or you compile
|
||||||
|
// this file and link it with other files to produce an executable, this
|
||||||
|
// file does not by itself cause the resulting executable to be covered by
|
||||||
|
// the GNU General Public License. This exception does not however
|
||||||
|
// invalidate any other reasons why the executable file might be covered by
|
||||||
|
// the GNU General Public License.
|
||||||
|
|
||||||
|
#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
|
||||||
|
#include <cxxabi.h>
|
||||||
|
#include <new>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
// Exception handling hook, to mark current exception as not caught --
|
||||||
|
// generally because we're about to rethrow it after some cleanup.
|
||||||
|
extern "C" void __uncatch_exception (void);
|
||||||
|
|
||||||
|
namespace __cxxabiv1
|
||||||
|
{
|
||||||
|
|
||||||
|
/* allocate and construct array */
|
||||||
|
extern "C" void *
|
||||||
|
__cxa_vec_new (size_t element_count,
|
||||||
|
size_t element_size,
|
||||||
|
size_t padding_size,
|
||||||
|
void (*constructor) (void *),
|
||||||
|
void (*destructor) (void *))
|
||||||
|
{
|
||||||
|
return __cxa_vec_new2 (element_count, element_size, padding_size,
|
||||||
|
constructor, destructor,
|
||||||
|
&operator new[], &operator delete []);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void *
|
||||||
|
__cxa_vec_new2 (size_t element_count,
|
||||||
|
size_t element_size,
|
||||||
|
size_t padding_size,
|
||||||
|
void (*constructor) (void *),
|
||||||
|
void (*destructor) (void *),
|
||||||
|
void *(*alloc) (size_t),
|
||||||
|
void (*dealloc) (void *))
|
||||||
|
{
|
||||||
|
size_t size = element_count * element_size + padding_size;
|
||||||
|
char *base = static_cast <char *> (alloc (size));
|
||||||
|
|
||||||
|
if (padding_size)
|
||||||
|
{
|
||||||
|
base += padding_size;
|
||||||
|
reinterpret_cast <size_t *> (base)[-1] = element_count;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
__cxa_vec_ctor (base, element_count, element_size,
|
||||||
|
constructor, destructor);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
__uncatch_exception ();
|
||||||
|
dealloc (base - padding_size);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void *
|
||||||
|
__cxa_vec_new3 (size_t element_count,
|
||||||
|
size_t element_size,
|
||||||
|
size_t padding_size,
|
||||||
|
void (*constructor) (void *),
|
||||||
|
void (*destructor) (void *),
|
||||||
|
void *(*alloc) (size_t),
|
||||||
|
void (*dealloc) (void *, size_t))
|
||||||
|
{
|
||||||
|
size_t size = element_count * element_size + padding_size;
|
||||||
|
char *base = static_cast <char *> (alloc (size));
|
||||||
|
|
||||||
|
if (padding_size)
|
||||||
|
{
|
||||||
|
base += padding_size;
|
||||||
|
reinterpret_cast <size_t *> (base)[-1] = element_count;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
__cxa_vec_ctor (base, element_count, element_size,
|
||||||
|
constructor, destructor);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
__uncatch_exception ();
|
||||||
|
dealloc (base - padding_size, size);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* construct array */
|
||||||
|
extern "C" void
|
||||||
|
__cxa_vec_ctor (void *array_address,
|
||||||
|
size_t element_count,
|
||||||
|
size_t element_size,
|
||||||
|
void (*constructor) (void *),
|
||||||
|
void (*destructor) (void *))
|
||||||
|
{
|
||||||
|
size_t ix = 0;
|
||||||
|
char *ptr = static_cast <char *> (array_address);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (constructor)
|
||||||
|
for (; ix != element_count; ix++, ptr += element_size)
|
||||||
|
constructor (ptr);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
__uncatch_exception ();
|
||||||
|
__cxa_vec_dtor (array_address, ix, element_size, destructor);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* construct an array by copying */
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__cxa_vec_cctor (void *dest_array,
|
||||||
|
void *src_array,
|
||||||
|
size_t element_count,
|
||||||
|
size_t element_size,
|
||||||
|
void (*constructor) (void *, void *),
|
||||||
|
void (*destructor) (void *))
|
||||||
|
{
|
||||||
|
size_t ix = 0;
|
||||||
|
char *dest_ptr = static_cast <char *> (dest_array);
|
||||||
|
char *src_ptr = static_cast <char *> (src_array);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (constructor)
|
||||||
|
for (; ix != element_count;
|
||||||
|
ix++, src_ptr += element_size, dest_ptr += element_size)
|
||||||
|
constructor (dest_ptr, src_ptr);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
__uncatch_exception ();
|
||||||
|
__cxa_vec_dtor (dest_array, ix, element_size, destructor);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* destruct array */
|
||||||
|
extern "C" void
|
||||||
|
__cxa_vec_dtor (void *array_address,
|
||||||
|
size_t element_count,
|
||||||
|
size_t element_size,
|
||||||
|
void (*destructor) (void *))
|
||||||
|
{
|
||||||
|
if (destructor)
|
||||||
|
{
|
||||||
|
char *ptr = static_cast <char *> (array_address);
|
||||||
|
size_t ix = element_count;
|
||||||
|
bool unwinding = std::uncaught_exception ();
|
||||||
|
|
||||||
|
ptr += element_count * element_size;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (ix--)
|
||||||
|
{
|
||||||
|
ptr -= element_size;
|
||||||
|
destructor (ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
if (unwinding)
|
||||||
|
// [except.ctor]/3 If a destructor called during stack unwinding
|
||||||
|
// exits with an exception, terminate is called.
|
||||||
|
std::terminate ();
|
||||||
|
__uncatch_exception ();
|
||||||
|
__cxa_vec_dtor (array_address, ix, element_size, destructor);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* destruct and release array */
|
||||||
|
extern "C" void
|
||||||
|
__cxa_vec_delete (void *array_address,
|
||||||
|
size_t element_size,
|
||||||
|
size_t padding_size,
|
||||||
|
void (*destructor) (void *))
|
||||||
|
{
|
||||||
|
__cxa_vec_delete2 (array_address, element_size, padding_size,
|
||||||
|
destructor,
|
||||||
|
&operator delete []);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__cxa_vec_delete2 (void *array_address,
|
||||||
|
size_t element_size,
|
||||||
|
size_t padding_size,
|
||||||
|
void (*destructor) (void *),
|
||||||
|
void (*dealloc) (void *))
|
||||||
|
{
|
||||||
|
char *base = static_cast <char *> (array_address);
|
||||||
|
|
||||||
|
if (padding_size)
|
||||||
|
{
|
||||||
|
size_t element_count = reinterpret_cast <size_t *> (base)[-1];
|
||||||
|
base -= padding_size;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
__cxa_vec_dtor (array_address, element_count, element_size,
|
||||||
|
destructor);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
__uncatch_exception ();
|
||||||
|
dealloc (base);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dealloc (base);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__cxa_vec_delete3 (void *array_address,
|
||||||
|
size_t element_size,
|
||||||
|
size_t padding_size,
|
||||||
|
void (*destructor) (void *),
|
||||||
|
void (*dealloc) (void *, size_t))
|
||||||
|
{
|
||||||
|
char *base = static_cast <char *> (array_address);
|
||||||
|
size_t size = 0;
|
||||||
|
|
||||||
|
if (padding_size)
|
||||||
|
{
|
||||||
|
size_t element_count = reinterpret_cast <size_t *> (base)[-1];
|
||||||
|
base -= padding_size;
|
||||||
|
size = element_count * element_size + padding_size;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
__cxa_vec_dtor (array_address, element_count, element_size,
|
||||||
|
destructor);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
__uncatch_exception ();
|
||||||
|
dealloc (base, size);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dealloc (base, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace __cxxabiv1
|
||||||
|
|
||||||
|
#endif // defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
|
||||||
Loading…
Reference in New Issue