mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-22 21:31:19 +08:00
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>
|
||||
|
||||
* configure.in: Add AIX multithread support fragment.
|
||||
|
@ -19,7 +19,11 @@ INTERFACE = 3
|
||||
|
||||
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
|
||||
|
||||
# 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 \
|
||||
memory numeric pthread_alloc queue rope set slist stack utility \
|
||||
vector fstream iomanip iostream strstream iosfwd bitset valarray \
|
||||
sstream
|
||||
sstream exception new typeinfo
|
||||
|
||||
ARLIB = libstdc++.a.$(VERSION)
|
||||
ARLINK = libstdc++.a
|
||||
@ -131,12 +135,29 @@ STRFUNCS = REP MAIN TRAITS ADDSS ADDPS ADDCS ADDSP ADDSC \
|
||||
STRIO = EXTRACT INSERT GETLINE
|
||||
|
||||
# These are here for SunOS VPATH.
|
||||
cstringi.o: cstringi.cc
|
||||
cstdlibi.o: cstdlibi.cc
|
||||
cinst.o: cinst.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
|
||||
stlinst.o: stlinst.cc
|
||||
tinfo.o: tinfo.cc tinfo.hP typeinfo new
|
||||
tinfo2.o: tinfo2.cc tinfo.hP typeinfo new
|
||||
valarray.o: valarray.cc
|
||||
vec.o: vec.cc
|
||||
pure.o: pure.c
|
||||
|
||||
# Later do wide strings, too.
|
||||
stmp-string: ${srcdir}/sinst.cc ${srcdir}/std/bastring.h \
|
||||
|
@ -134,7 +134,7 @@ ${moveifchange} temp.mt target-mkfrag
|
||||
LIBDIR=yes
|
||||
TO_TOPDIR=../
|
||||
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)'
|
||||
CLEAN='$(CLEAN_JUNK)'
|
||||
EXTRA_DISTCLEAN='target-mkfrag'
|
||||
|
519
libstdc++/cxxabi.h
Normal file
519
libstdc++/cxxabi.h
Normal file
@ -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 */
|
39
libstdc++/del_op.cc
Normal file
39
libstdc++/del_op.cc
Normal file
@ -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);
|
||||
}
|
39
libstdc++/del_opnt.cc
Normal file
39
libstdc++/del_opnt.cc
Normal file
@ -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);
|
||||
}
|
36
libstdc++/del_opv.cc
Normal file
36
libstdc++/del_opv.cc
Normal file
@ -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);
|
||||
}
|
36
libstdc++/del_opvnt.cc
Normal file
36
libstdc++/del_opvnt.cc
Normal file
@ -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);
|
||||
}
|
65
libstdc++/exception
Normal file
65
libstdc++/exception
Normal file
@ -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
|
403
libstdc++/exception.cc
Normal file
403
libstdc++/exception.cc
Normal file
@ -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 ();
|
||||
}
|
68
libstdc++/new
Normal file
68
libstdc++/new
Normal file
@ -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
|
38
libstdc++/new.h
Normal file
38
libstdc++/new.h
Normal file
@ -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__
|
44
libstdc++/new_handler.cc
Normal file
44
libstdc++/new_handler.cc
Normal file
@ -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;
|
||||
}
|
56
libstdc++/new_op.cc
Normal file
56
libstdc++/new_op.cc
Normal file
@ -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;
|
||||
}
|
64
libstdc++/new_opnt.cc
Normal file
64
libstdc++/new_opnt.cc
Normal file
@ -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;
|
||||
}
|
36
libstdc++/new_opv.cc
Normal file
36
libstdc++/new_opv.cc
Normal file
@ -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);
|
||||
}
|
36
libstdc++/new_opvnt.cc
Normal file
36
libstdc++/new_opvnt.cc
Normal file
@ -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);
|
||||
}
|
16
libstdc++/pure.c
Normal file
16
libstdc++/pure.c
Normal file
@ -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 ();
|
||||
}
|
1210
libstdc++/tinfo.cc
Normal file
1210
libstdc++/tinfo.cc
Normal file
File diff suppressed because it is too large
Load Diff
223
libstdc++/tinfo.hP
Normal file
223
libstdc++/tinfo.hP
Normal file
@ -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
|
452
libstdc++/tinfo2.cc
Normal file
452
libstdc++/tinfo2.cc
Normal file
@ -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
|
134
libstdc++/typeinfo
Normal file
134
libstdc++/typeinfo
Normal file
@ -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
|
279
libstdc++/vec.cc
Normal file
279
libstdc++/vec.cc
Normal file
@ -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…
x
Reference in New Issue
Block a user