From 0895e1acb698e05d503c26bec5471de2e88b7d93 Mon Sep 17 00:00:00 2001 From: obrien Date: Tue, 28 May 2002 16:16:03 +0000 Subject: Gcc 3.1.0 pre-release's C++ support bits from the FSF anoncvs repo on 9-May-2002 15:57:15 EDT. --- contrib/libstdc++/libsupc++/Makefile.am | 189 +++++++ contrib/libstdc++/libsupc++/Makefile.in | 600 ++++++++++++++++++++ contrib/libstdc++/libsupc++/cxxabi.h | 526 +++++++++++++++++ contrib/libstdc++/libsupc++/del_op.cc | 40 ++ contrib/libstdc++/libsupc++/del_opnt.cc | 40 ++ contrib/libstdc++/libsupc++/del_opv.cc | 37 ++ contrib/libstdc++/libsupc++/del_opvnt.cc | 37 ++ contrib/libstdc++/libsupc++/eh_alloc.cc | 163 ++++++ contrib/libstdc++/libsupc++/eh_aux_runtime.cc | 57 ++ contrib/libstdc++/libsupc++/eh_catch.cc | 106 ++++ contrib/libstdc++/libsupc++/eh_exception.cc | 44 ++ contrib/libstdc++/libsupc++/eh_globals.cc | 118 ++++ contrib/libstdc++/libsupc++/eh_personality.cc | 485 ++++++++++++++++ contrib/libstdc++/libsupc++/eh_terminate.cc | 87 +++ contrib/libstdc++/libsupc++/eh_throw.cc | 102 ++++ contrib/libstdc++/libsupc++/eh_type.cc | 50 ++ contrib/libstdc++/libsupc++/exception | 116 ++++ contrib/libstdc++/libsupc++/exception_defines.h | 42 ++ contrib/libstdc++/libsupc++/new | 94 +++ contrib/libstdc++/libsupc++/new_handler.cc | 47 ++ contrib/libstdc++/libsupc++/new_op.cc | 63 +++ contrib/libstdc++/libsupc++/new_opnt.cc | 66 +++ contrib/libstdc++/libsupc++/new_opv.cc | 37 ++ contrib/libstdc++/libsupc++/new_opvnt.cc | 37 ++ contrib/libstdc++/libsupc++/pure.cc | 51 ++ contrib/libstdc++/libsupc++/tinfo.cc | 721 ++++++++++++++++++++++++ contrib/libstdc++/libsupc++/tinfo.h | 10 + contrib/libstdc++/libsupc++/tinfo2.cc | 167 ++++++ contrib/libstdc++/libsupc++/typeinfo | 150 +++++ contrib/libstdc++/libsupc++/unwind-cxx.h | 171 ++++++ contrib/libstdc++/libsupc++/vec.cc | 336 +++++++++++ 31 files changed, 4789 insertions(+) create mode 100644 contrib/libstdc++/libsupc++/Makefile.am create mode 100644 contrib/libstdc++/libsupc++/Makefile.in create mode 100644 contrib/libstdc++/libsupc++/cxxabi.h create mode 100644 contrib/libstdc++/libsupc++/del_op.cc create mode 100644 contrib/libstdc++/libsupc++/del_opnt.cc create mode 100644 contrib/libstdc++/libsupc++/del_opv.cc create mode 100644 contrib/libstdc++/libsupc++/del_opvnt.cc create mode 100644 contrib/libstdc++/libsupc++/eh_alloc.cc create mode 100644 contrib/libstdc++/libsupc++/eh_aux_runtime.cc create mode 100644 contrib/libstdc++/libsupc++/eh_catch.cc create mode 100644 contrib/libstdc++/libsupc++/eh_exception.cc create mode 100644 contrib/libstdc++/libsupc++/eh_globals.cc create mode 100644 contrib/libstdc++/libsupc++/eh_personality.cc create mode 100644 contrib/libstdc++/libsupc++/eh_terminate.cc create mode 100644 contrib/libstdc++/libsupc++/eh_throw.cc create mode 100644 contrib/libstdc++/libsupc++/eh_type.cc create mode 100644 contrib/libstdc++/libsupc++/exception create mode 100644 contrib/libstdc++/libsupc++/exception_defines.h create mode 100644 contrib/libstdc++/libsupc++/new create mode 100644 contrib/libstdc++/libsupc++/new_handler.cc create mode 100644 contrib/libstdc++/libsupc++/new_op.cc create mode 100644 contrib/libstdc++/libsupc++/new_opnt.cc create mode 100644 contrib/libstdc++/libsupc++/new_opv.cc create mode 100644 contrib/libstdc++/libsupc++/new_opvnt.cc create mode 100644 contrib/libstdc++/libsupc++/pure.cc create mode 100644 contrib/libstdc++/libsupc++/tinfo.cc create mode 100644 contrib/libstdc++/libsupc++/tinfo.h create mode 100644 contrib/libstdc++/libsupc++/tinfo2.cc create mode 100644 contrib/libstdc++/libsupc++/typeinfo create mode 100644 contrib/libstdc++/libsupc++/unwind-cxx.h create mode 100644 contrib/libstdc++/libsupc++/vec.cc (limited to 'contrib/libstdc++/libsupc++') diff --git a/contrib/libstdc++/libsupc++/Makefile.am b/contrib/libstdc++/libsupc++/Makefile.am new file mode 100644 index 0000000..e37613f --- /dev/null +++ b/contrib/libstdc++/libsupc++/Makefile.am @@ -0,0 +1,189 @@ +## Makefile for the GNU C++ Support library. +## +## Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. +## +## Process this file with automake to produce Makefile.in. +## +## 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. + +AUTOMAKE_OPTIONS = 1.3 cygnus +MAINT_CHARSET = latin1 + +mkinstalldirs = $(SHELL) $(toplevel_srcdir)/mkinstalldirs + +# Cross compiler and multilib support. +CC = @CC@ +CXX = @glibcpp_CXX@ +toolexecdir = @glibcpp_toolexecdir@ +toolexeclibdir = @glibcpp_toolexeclibdir@ + + +# Need this library to both be part of libstdc++.a, and installed +# separately too. +# 1) separate libsupc++.la +toolexeclib_LTLIBRARIES = libsupc++.la +# 2) integrated libsupc++convenience.la that is to be a part of libstdc++.a +noinst_LTLIBRARIES = libsupc++convenience.la + + +# Compile flags that should be constant throughout the build, both for +# SUBDIRS and for libstdc++-v3 in general. +OPTIMIZE_CXXFLAGS = @OPTIMIZE_CXXFLAGS@ + +# These bits are all figured out from configure. Look in acinclude.m4 +# or configure.in to see how they are set. See GLIBCPP_EXPORT_FLAGS +# NB: DEBUGFLAGS have to be at the end so that -O2 can be overridden. +CONFIG_CXXFLAGS = \ + @EXTRA_CXX_FLAGS@ @SECTION_FLAGS@ @CSHADOW_FLAGS@ @DEBUG_FLAGS@ + +# Warning flags to use. +WARN_CXXFLAGS = \ + @WARN_FLAGS@ $(WERROR) -fdiagnostics-show-location=once + +# Use common includes from acinclude.m4/GLIBCPP_EXPORT_INCLUDES +GLIBCPP_INCLUDES = @GLIBCPP_INCLUDES@ +LIBSUPCXX_INCLUDES = @LIBSUPCXX_INCLUDES@ + +INCLUDES = \ + -I$(toplevel_srcdir)/gcc -I$(toplevel_srcdir)/include \ + $(GLIBCPP_INCLUDES) $(LIBSUPCXX_INCLUDES) + +headers = \ + exception new typeinfo cxxabi.h exception_defines.h + +sources = \ + cxa_demangle.c \ + del_op.cc \ + del_opnt.cc \ + del_opv.cc \ + del_opvnt.cc \ + dyn-string.c \ + eh_alloc.cc \ + eh_aux_runtime.cc \ + eh_catch.cc \ + eh_exception.cc \ + eh_globals.cc \ + eh_personality.cc \ + eh_terminate.cc \ + eh_throw.cc \ + eh_type.cc \ + new_handler.cc \ + new_op.cc \ + new_opnt.cc \ + new_opv.cc \ + new_opvnt.cc \ + pure.cc \ + tinfo.cc \ + tinfo2.cc \ + vec.cc + +libsupc___la_SOURCES = $(sources) +libsupc__convenience_la_SOURCES = $(sources) + +glibcppinstalldir = @gxx_include_dir@ +glibcppinstall_HEADERS = $(headers) + +LIBSUPCXX_CXXFLAGS = $(LIBSUPCXX_PICFLAGS) + +# Use special rules for pulling things out of libiberty. +cxa_demangle.c: + rm -f $@ + $(LN_S) $(toplevel_srcdir)/libiberty/cp-demangle.c $@ +cxa_demangle.lo: cxa_demangle.c + $(LTCOMPILE) -DIN_GLIBCPP_V3 -Wno-error -c $< +cxa_demangle.o: cxa_demangle.c + $(COMPILE) -DIN_GLIBCPP_V3 -Wno-error -c $< +dyn-string.c: + rm -f $@ + $(LN_S) $(toplevel_srcdir)/libiberty/dyn-string.c $@ +dyn-string.lo: dyn-string.c + $(LTCOMPILE) -DIN_GLIBCPP_V3 -Wno-error -c $< +dyn-string.o: dyn-string.c + $(COMPILE) -DIN_GLIBCPP_V3 -Wno-error -c $< + +# LTCOMPILE is copied from LTCXXCOMPILE below. +LTCOMPILE = $(LIBTOOL) --tag CC --tag disable-shared \ + --mode=compile $(CC) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(AM_CXXFLAGS) + + +# AM_CXXFLAGS needs to be in each subdirectory so that it can be +# modified in a per-library or per-sub-library way. Need to manually +# set this option because CONFIG_CXXFLAGS has to be after +# OPTIMIZE_CXXFLAGS on the compile line so that -O2 can be overridden +# as the occasion call for it. (ie, --enable-debug) +AM_CXXFLAGS = \ + -fno-implicit-templates \ + $(LIBSUPCXX_CXXFLAGS) \ + $(WARN_CXXFLAGS) \ + $(OPTIMIZE_CXXFLAGS) \ + $(CONFIG_CXXFLAGS) + +# libstdc++ libtool notes + +# 1) Need to explicitly set LTCXXCOMPILE so that AM_CXXFLAGS is +# last. (That way, things like -O2 passed down from the toplevel can +# be overridden by --enable-debug.) + +# 2) In general, libtool expects an argument such as `--tag=CXX' when +# using the C++ compiler, because that will enable the settings +# detected when C++ support was being configured. However, when no +# such flag is given in the command line, libtool attempts to figure +# it out by matching the compiler name in each configuration section +# against a prefix of the command line. The problem is that, if the +# compiler name and its initial flags stored in the libtool +# configuration file don't match those in the command line, libtool +# can't decide which configuration to use, and it gives up. The +# correct solution is to add `--tag CXX' to LTCXXCOMPILE and maybe +# CXXLINK, just after $(LIBTOOL), so that libtool doesn't have to +# attempt to infer which configuration to use. +# +# We have to put --tag disable-shared after --tag CXX lest things +# CXX undo the affect of disable-shared. +LTCXXCOMPILE = $(LIBTOOL) --tag CXX --tag disable-shared \ + --mode=compile $(CXX) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(AM_CXXFLAGS) + +# 3) We'd have a problem when building the shared libstdc++ object if +# the rules automake generates would be used. We cannot allow g++ to +# be used since this would add -lstdc++ to the link line which of +# course is problematic at this point. So, we get the top-level +# directory to configure libstdc++-v3 to use gcc as the C++ +# compilation driver. +CXXLINK = $(LIBTOOL) --tag CXX --tag disable-shared \ + --mode=link $(CXX) \ + @OPT_LDFLAGS@ @SECTION_LDFLAGS@ $(AM_CXXFLAGS) $(LDFLAGS) -o $@ + +# We have to have rules modified from the default to counteract SUN make +# prepending each of $(glibcppinstall_HEADERS) with VPATH below. +install-glibcppinstallHEADERS: $(glibcppinstall_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(glibcppinstalldir) + @list='$(glibcppinstall_HEADERS)'; for p in $$list; do \ + q=`echo $$p | sed -e 's,.*/,,'`; \ + if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(glibcppinstalldir)/$$q"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(glibcppinstalldir)/$$q; \ + done + +uninstall-glibcppinstallHEADERS: + @$(NORMAL_UNINSTALL) + list='$(glibcppinstall_HEADERS)'; for p in $$list; do \ + q=`echo $$p | sed -e 's,.*/,,'`; \ + rm -f $(DESTDIR)$(glibcppinstalldir)/$$q; \ + done diff --git a/contrib/libstdc++/libsupc++/Makefile.in b/contrib/libstdc++/libsupc++/Makefile.in new file mode 100644 index 0000000..84f85d3 --- /dev/null +++ b/contrib/libstdc++/libsupc++/Makefile.in @@ -0,0 +1,600 @@ +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AR = @AR@ +AS = @AS@ +ATOMICITY_INC_SRCDIR = @ATOMICITY_INC_SRCDIR@ +AWK = @AWK@ +BASIC_FILE_H = @BASIC_FILE_H@ +BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CCODECVT_C = @CCODECVT_C@ +CCODECVT_H = @CCODECVT_H@ +CLOCALE_H = @CLOCALE_H@ +CMESSAGES_H = @CMESSAGES_H@ +CPP = @CPP@ +CPU_LIMITS_INC_SRCDIR = @CPU_LIMITS_INC_SRCDIR@ +CSHADOW_FLAGS = @CSHADOW_FLAGS@ +CSTDIO_H = @CSTDIO_H@ +CXXCPP = @CXXCPP@ +C_INCLUDE_DIR = @C_INCLUDE_DIR@ +DATADIRNAME = @DATADIRNAME@ +DEBUG_FLAGS = @DEBUG_FLAGS@ +DLLTOOL = @DLLTOOL@ +EXEEXT = @EXEEXT@ +EXTRA_CXX_FLAGS = @EXTRA_CXX_FLAGS@ +GCJ = @GCJ@ +GCJFLAGS = @GCJFLAGS@ +GENCAT = @GENCAT@ +GLIBC21 = @GLIBC21@ +GLIBCPP_IS_CROSS_COMPILING = @GLIBCPP_IS_CROSS_COMPILING@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +INSTOBJEXT = @INSTOBJEXT@ +INTLBISON = @INTLBISON@ +INTLLIBS = @INTLLIBS@ +INTLOBJS = @INTLOBJS@ +INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@ +LIBICONV = @LIBICONV@ +LIBIO_INCLUDES = @LIBIO_INCLUDES@ +LIBMATHOBJS = @LIBMATHOBJS@ +LIBMATH_INCLUDES = @LIBMATH_INCLUDES@ +LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@ +LIBTOOL = @LIBTOOL@ +LIBUNWIND_FLAG = @LIBUNWIND_FLAG@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPT_LDFLAGS = @OPT_LDFLAGS@ +OS_INC_SRCDIR = @OS_INC_SRCDIR@ +PACKAGE = @PACKAGE@ +POFILES = @POFILES@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +SECTION_FLAGS = @SECTION_FLAGS@ +SECTION_LDFLAGS = @SECTION_LDFLAGS@ +STRIP = @STRIP@ +TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +WARN_FLAGS = @WARN_FLAGS@ +WERROR = @WERROR@ +check_msgfmt = @check_msgfmt@ +enable_shared = @enable_shared@ +enable_static = @enable_static@ +glibcpp_CXX = @glibcpp_CXX@ +glibcpp_MOFILES = @glibcpp_MOFILES@ +glibcpp_POFILES = @glibcpp_POFILES@ +glibcpp_basedir = @glibcpp_basedir@ +glibcpp_builddir = @glibcpp_builddir@ +glibcpp_localedir = @glibcpp_localedir@ +glibcpp_prefixdir = @glibcpp_prefixdir@ +glibcpp_srcdir = @glibcpp_srcdir@ +glibcpp_thread_h = @glibcpp_thread_h@ +glibcpp_toolexecdir = @glibcpp_toolexecdir@ +glibcpp_toolexeclibdir = @glibcpp_toolexeclibdir@ +gxx_include_dir = @gxx_include_dir@ +ifGNUmake = @ifGNUmake@ +libio_la = @libio_la@ +libtool_VERSION = @libtool_VERSION@ +release_VERSION = @release_VERSION@ +toplevel_srcdir = @toplevel_srcdir@ + +AUTOMAKE_OPTIONS = 1.3 cygnus +MAINT_CHARSET = latin1 + +mkinstalldirs = $(SHELL) $(toplevel_srcdir)/mkinstalldirs + +# Cross compiler and multilib support. +CC = @CC@ +CXX = @glibcpp_CXX@ +toolexecdir = @glibcpp_toolexecdir@ +toolexeclibdir = @glibcpp_toolexeclibdir@ + +# Need this library to both be part of libstdc++.a, and installed +# separately too. +# 1) separate libsupc++.la +toolexeclib_LTLIBRARIES = libsupc++.la +# 2) integrated libsupc++convenience.la that is to be a part of libstdc++.a +noinst_LTLIBRARIES = libsupc++convenience.la + +# Compile flags that should be constant throughout the build, both for +# SUBDIRS and for libstdc++-v3 in general. +OPTIMIZE_CXXFLAGS = @OPTIMIZE_CXXFLAGS@ + +# These bits are all figured out from configure. Look in acinclude.m4 +# or configure.in to see how they are set. See GLIBCPP_EXPORT_FLAGS +# NB: DEBUGFLAGS have to be at the end so that -O2 can be overridden. +CONFIG_CXXFLAGS = \ + @EXTRA_CXX_FLAGS@ @SECTION_FLAGS@ @CSHADOW_FLAGS@ @DEBUG_FLAGS@ + + +# Warning flags to use. +WARN_CXXFLAGS = \ + @WARN_FLAGS@ $(WERROR) -fdiagnostics-show-location=once + + +# Use common includes from acinclude.m4/GLIBCPP_EXPORT_INCLUDES +GLIBCPP_INCLUDES = @GLIBCPP_INCLUDES@ +LIBSUPCXX_INCLUDES = @LIBSUPCXX_INCLUDES@ + +INCLUDES = \ + -I$(toplevel_srcdir)/gcc -I$(toplevel_srcdir)/include \ + $(GLIBCPP_INCLUDES) $(LIBSUPCXX_INCLUDES) + + +headers = \ + exception new typeinfo cxxabi.h exception_defines.h + + +sources = \ + cxa_demangle.c \ + del_op.cc \ + del_opnt.cc \ + del_opv.cc \ + del_opvnt.cc \ + dyn-string.c \ + eh_alloc.cc \ + eh_aux_runtime.cc \ + eh_catch.cc \ + eh_exception.cc \ + eh_globals.cc \ + eh_personality.cc \ + eh_terminate.cc \ + eh_throw.cc \ + eh_type.cc \ + new_handler.cc \ + new_op.cc \ + new_opnt.cc \ + new_opv.cc \ + new_opvnt.cc \ + pure.cc \ + tinfo.cc \ + tinfo2.cc \ + vec.cc + + +libsupc___la_SOURCES = $(sources) +libsupc__convenience_la_SOURCES = $(sources) + +glibcppinstalldir = @gxx_include_dir@ +glibcppinstall_HEADERS = $(headers) + +LIBSUPCXX_CXXFLAGS = $(LIBSUPCXX_PICFLAGS) + +# LTCOMPILE is copied from LTCXXCOMPILE below. +LTCOMPILE = $(LIBTOOL) --tag CC --tag disable-shared \ + --mode=compile $(CC) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(AM_CXXFLAGS) + + +# AM_CXXFLAGS needs to be in each subdirectory so that it can be +# modified in a per-library or per-sub-library way. Need to manually +# set this option because CONFIG_CXXFLAGS has to be after +# OPTIMIZE_CXXFLAGS on the compile line so that -O2 can be overridden +# as the occasion call for it. (ie, --enable-debug) +AM_CXXFLAGS = \ + -fno-implicit-templates \ + $(LIBSUPCXX_CXXFLAGS) \ + $(WARN_CXXFLAGS) \ + $(OPTIMIZE_CXXFLAGS) \ + $(CONFIG_CXXFLAGS) + + +# libstdc++ libtool notes + +# 1) Need to explicitly set LTCXXCOMPILE so that AM_CXXFLAGS is +# last. (That way, things like -O2 passed down from the toplevel can +# be overridden by --enable-debug.) + +# 2) In general, libtool expects an argument such as `--tag=CXX' when +# using the C++ compiler, because that will enable the settings +# detected when C++ support was being configured. However, when no +# such flag is given in the command line, libtool attempts to figure +# it out by matching the compiler name in each configuration section +# against a prefix of the command line. The problem is that, if the +# compiler name and its initial flags stored in the libtool +# configuration file don't match those in the command line, libtool +# can't decide which configuration to use, and it gives up. The +# correct solution is to add `--tag CXX' to LTCXXCOMPILE and maybe +# CXXLINK, just after $(LIBTOOL), so that libtool doesn't have to +# attempt to infer which configuration to use. +# +# We have to put --tag disable-shared after --tag CXX lest things +# CXX undo the affect of disable-shared. +LTCXXCOMPILE = $(LIBTOOL) --tag CXX --tag disable-shared \ + --mode=compile $(CXX) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(AM_CXXFLAGS) + + +# 3) We'd have a problem when building the shared libstdc++ object if +# the rules automake generates would be used. We cannot allow g++ to +# be used since this would add -lstdc++ to the link line which of +# course is problematic at this point. So, we get the top-level +# directory to configure libstdc++-v3 to use gcc as the C++ +# compilation driver. +CXXLINK = $(LIBTOOL) --tag CXX --tag disable-shared \ + --mode=link $(CXX) \ + @OPT_LDFLAGS@ @SECTION_LDFLAGS@ $(AM_CXXFLAGS) $(LDFLAGS) -o $@ + +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) $(toolexeclib_LTLIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I.. +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +libsupc__convenience_la_LDFLAGS = +libsupc__convenience_la_LIBADD = +libsupc__convenience_la_OBJECTS = cxa_demangle.lo del_op.lo del_opnt.lo \ +del_opv.lo del_opvnt.lo dyn-string.lo eh_alloc.lo eh_aux_runtime.lo \ +eh_catch.lo eh_exception.lo eh_globals.lo eh_personality.lo \ +eh_terminate.lo eh_throw.lo eh_type.lo new_handler.lo new_op.lo \ +new_opnt.lo new_opv.lo new_opvnt.lo pure.lo tinfo.lo tinfo2.lo vec.lo +libsupc___la_LDFLAGS = +libsupc___la_LIBADD = +libsupc___la_OBJECTS = cxa_demangle.lo del_op.lo del_opnt.lo del_opv.lo \ +del_opvnt.lo dyn-string.lo eh_alloc.lo eh_aux_runtime.lo eh_catch.lo \ +eh_exception.lo eh_globals.lo eh_personality.lo eh_terminate.lo \ +eh_throw.lo eh_type.lo new_handler.lo new_op.lo new_opnt.lo new_opv.lo \ +new_opvnt.lo pure.lo tinfo.lo tinfo2.lo vec.lo +CXXFLAGS = @CXXFLAGS@ +CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +HEADERS = $(glibcppinstall_HEADERS) + +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(libsupc__convenience_la_SOURCES) $(libsupc___la_SOURCES) +OBJECTS = $(libsupc__convenience_la_OBJECTS) $(libsupc___la_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .cc .lo .o .obj .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --cygnus libsupc++/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-noinstLTLIBRARIES: + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + +distclean-noinstLTLIBRARIES: + +maintainer-clean-noinstLTLIBRARIES: + +mostlyclean-toolexeclibLTLIBRARIES: + +clean-toolexeclibLTLIBRARIES: + -test -z "$(toolexeclib_LTLIBRARIES)" || rm -f $(toolexeclib_LTLIBRARIES) + +distclean-toolexeclibLTLIBRARIES: + +maintainer-clean-toolexeclibLTLIBRARIES: + +install-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(toolexeclibdir) + @list='$(toolexeclib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(toolexeclibdir)/$$p"; \ + $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(toolexeclibdir)/$$p; \ + else :; fi; \ + done + +uninstall-toolexeclibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(toolexeclib_LTLIBRARIES)'; for p in $$list; do \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(toolexeclibdir)/$$p; \ + done + +.c.o: + $(COMPILE) -c $< + +# FIXME: We should only use cygpath when building on Windows, +# and only if it is available. +.c.obj: + $(COMPILE) -c `cygpath -w $<` + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + -rm -f *.$(OBJEXT) + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libsupc++convenience.la: $(libsupc__convenience_la_OBJECTS) $(libsupc__convenience_la_DEPENDENCIES) + $(CXXLINK) $(libsupc__convenience_la_LDFLAGS) $(libsupc__convenience_la_OBJECTS) $(libsupc__convenience_la_LIBADD) $(LIBS) + +libsupc++.la: $(libsupc___la_OBJECTS) $(libsupc___la_DEPENDENCIES) + $(CXXLINK) -rpath $(toolexeclibdir) $(libsupc___la_LDFLAGS) $(libsupc___la_OBJECTS) $(libsupc___la_LIBADD) $(LIBS) +.cc.o: + $(CXXCOMPILE) -c $< +.cc.obj: + $(CXXCOMPILE) -c `cygpath -w $<` +.cc.lo: + $(LTCXXCOMPILE) -c $< + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = libsupc++ + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: +check: check-am +installcheck-am: +installcheck: installcheck-am +install-info-am: +install-info: install-info-am +install-exec-am: install-toolexeclibLTLIBRARIES +install-exec: install-exec-am + +install-data-am: install-glibcppinstallHEADERS +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-toolexeclibLTLIBRARIES \ + uninstall-glibcppinstallHEADERS +uninstall: uninstall-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(toolexeclibdir) \ + $(DESTDIR)$(glibcppinstalldir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-noinstLTLIBRARIES \ + mostlyclean-toolexeclibLTLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags \ + mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-noinstLTLIBRARIES clean-toolexeclibLTLIBRARIES \ + clean-compile clean-libtool clean-tags clean-generic \ + mostlyclean-am + +clean: clean-am + +distclean-am: distclean-noinstLTLIBRARIES \ + distclean-toolexeclibLTLIBRARIES distclean-compile \ + distclean-libtool distclean-tags distclean-generic \ + clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-noinstLTLIBRARIES \ + maintainer-clean-toolexeclibLTLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-noinstLTLIBRARIES distclean-noinstLTLIBRARIES \ +clean-noinstLTLIBRARIES maintainer-clean-noinstLTLIBRARIES \ +mostlyclean-toolexeclibLTLIBRARIES distclean-toolexeclibLTLIBRARIES \ +clean-toolexeclibLTLIBRARIES maintainer-clean-toolexeclibLTLIBRARIES \ +uninstall-toolexeclibLTLIBRARIES install-toolexeclibLTLIBRARIES \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile mostlyclean-libtool distclean-libtool \ +clean-libtool maintainer-clean-libtool uninstall-glibcppinstallHEADERS \ +install-glibcppinstallHEADERS tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-info-am install-info \ +install-exec-am install-exec install-data-am install-data install-am \ +install uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Use special rules for pulling things out of libiberty. +cxa_demangle.c: + rm -f $@ + $(LN_S) $(toplevel_srcdir)/libiberty/cp-demangle.c $@ +cxa_demangle.lo: cxa_demangle.c + $(LTCOMPILE) -DIN_GLIBCPP_V3 -Wno-error -c $< +cxa_demangle.o: cxa_demangle.c + $(COMPILE) -DIN_GLIBCPP_V3 -Wno-error -c $< +dyn-string.c: + rm -f $@ + $(LN_S) $(toplevel_srcdir)/libiberty/dyn-string.c $@ +dyn-string.lo: dyn-string.c + $(LTCOMPILE) -DIN_GLIBCPP_V3 -Wno-error -c $< +dyn-string.o: dyn-string.c + $(COMPILE) -DIN_GLIBCPP_V3 -Wno-error -c $< + +# We have to have rules modified from the default to counteract SUN make +# prepending each of $(glibcppinstall_HEADERS) with VPATH below. +install-glibcppinstallHEADERS: $(glibcppinstall_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(glibcppinstalldir) + @list='$(glibcppinstall_HEADERS)'; for p in $$list; do \ + q=`echo $$p | sed -e 's,.*/,,'`; \ + if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(glibcppinstalldir)/$$q"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(glibcppinstalldir)/$$q; \ + done + +uninstall-glibcppinstallHEADERS: + @$(NORMAL_UNINSTALL) + list='$(glibcppinstall_HEADERS)'; for p in $$list; do \ + q=`echo $$p | sed -e 's,.*/,,'`; \ + rm -f $(DESTDIR)$(glibcppinstalldir)/$$q; \ + done + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/libstdc++/libsupc++/cxxabi.h b/contrib/libstdc++/libsupc++/cxxabi.h new file mode 100644 index 0000000..dd6b774 --- /dev/null +++ b/contrib/libstdc++/libsupc++/cxxabi.h @@ -0,0 +1,526 @@ +// new abi support -*- C++ -*- + +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// 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. + +// Written by Nathan Sidwell, Codesourcery LLC, + +/* This file declares the new abi entry points into the runtime. It is not + normally necessary for user programs to include this header, or use the + entry points directly. However, this header is available should that be + needed. + + Some of the entry points are intended for both C and C++, thus this header + is includable from both C and C++. Though the C++ specific parts are not + available in C, naturally enough. */ + +#ifndef __CXXABI_H +#define __CXXABI_H 1 + +#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 independent of +// the conformance level of and whether -fhonor-std was supplied. +// is not currently available during compiler building anyway. +// Including would be wrong, as that would rudely place size_t in +// the global namespace. + +#include + +namespace __cxxabiv1 +{ + +/* type information for int, float etc */ +class __fundamental_type_info + : public std::type_info +{ +public: + virtual ~__fundamental_type_info (); +public: + explicit __fundamental_type_info (const char *__n) + : std::type_info (__n) + { } +}; + +/* type information for 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 hierarchy */ + 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 array */ +extern "C" +void __cxa_vec_cleanup (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); + +// Returns the type_info for the currently handled exception [15.3/8], or +// null if there is none. +extern "C" +std::type_info *__cxa_current_exception_type (); + +} /* namespace __cxxabiv1 */ + +/* User programs should use the alias `abi'. */ +namespace abi = __cxxabiv1; + +#else +#endif /* __cplusplus */ + + +#endif /* __CXXABI_H */ diff --git a/contrib/libstdc++/libsupc++/del_op.cc b/contrib/libstdc++/libsupc++/del_op.cc new file mode 100644 index 0000000..f433024 --- /dev/null +++ b/contrib/libstdc++/libsupc++/del_op.cc @@ -0,0 +1,40 @@ +// 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); +} diff --git a/contrib/libstdc++/libsupc++/del_opnt.cc b/contrib/libstdc++/libsupc++/del_opnt.cc new file mode 100644 index 0000000..032ea68 --- /dev/null +++ b/contrib/libstdc++/libsupc++/del_opnt.cc @@ -0,0 +1,40 @@ +// 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); +} diff --git a/contrib/libstdc++/libsupc++/del_opv.cc b/contrib/libstdc++/libsupc++/del_opv.cc new file mode 100644 index 0000000..47d7842 --- /dev/null +++ b/contrib/libstdc++/libsupc++/del_opv.cc @@ -0,0 +1,37 @@ +// 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); +} diff --git a/contrib/libstdc++/libsupc++/del_opvnt.cc b/contrib/libstdc++/libsupc++/del_opvnt.cc new file mode 100644 index 0000000..3504d99a --- /dev/null +++ b/contrib/libstdc++/libsupc++/del_opvnt.cc @@ -0,0 +1,37 @@ +// 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); +} diff --git a/contrib/libstdc++/libsupc++/eh_alloc.cc b/contrib/libstdc++/libsupc++/eh_alloc.cc new file mode 100644 index 0000000..1f59ec4 --- /dev/null +++ b/contrib/libstdc++/libsupc++/eh_alloc.cc @@ -0,0 +1,163 @@ +// -*- C++ -*- Allocate exception objects. +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// 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 is derived from the C++ ABI for IA-64. Where we diverge +// for cross-architecture compatibility are noted with "@@@". + +#include +#include +#include +#include +#include "unwind-cxx.h" +#include "bits/c++config.h" +#include "bits/gthr.h" + +using namespace __cxxabiv1; + + +// ??? How to control these parameters. + +// Guess from the size of basic types how large a buffer is reasonable. +// Note that the basic c++ exception header has 13 pointers and 2 ints, +// so on a system with PSImode pointers we're talking about 56 bytes +// just for overhead. + +#if INT_MAX == 32767 +# define EMERGENCY_OBJ_SIZE 128 +# define EMERGENCY_OBJ_COUNT 16 +#elif LONG_MAX == 2147483647 +# define EMERGENCY_OBJ_SIZE 512 +# define EMERGENCY_OBJ_COUNT 32 +#else +# define EMERGENCY_OBJ_SIZE 1024 +# define EMERGENCY_OBJ_COUNT 64 +#endif + +#ifndef __GTHREADS +# undef EMERGENCY_OBJ_COUNT +# define EMERGENCY_OBJ_COUNT 4 +#endif + +#if INT_MAX == 32767 || EMERGENCY_OBJ_COUNT <= 32 +typedef unsigned int bitmask_type; +#else +typedef unsigned long bitmask_type; +#endif + + +typedef char one_buffer[EMERGENCY_OBJ_SIZE] __attribute__((aligned)); +static one_buffer emergency_buffer[EMERGENCY_OBJ_COUNT]; +static bitmask_type emergency_used; + + +#ifdef __GTHREADS +#ifdef __GTHREAD_MUTEX_INIT +static __gthread_mutex_t emergency_mutex =__GTHREAD_MUTEX_INIT; +#else +static __gthread_mutex_t emergency_mutex; +#endif + +#ifdef __GTHREAD_MUTEX_INIT_FUNCTION +static void +emergency_mutex_init () +{ + __GTHREAD_MUTEX_INIT_FUNCTION (&emergency_mutex); +} +#endif +#endif + + +extern "C" void * +__cxa_allocate_exception(std::size_t thrown_size) +{ + void *ret; + + thrown_size += sizeof (__cxa_exception); + ret = std::malloc (thrown_size); + + if (! ret) + { +#ifdef __GTHREADS +#ifdef __GTHREAD_MUTEX_INIT_FUNCTION + static __gthread_once_t once = __GTHREAD_ONCE_INIT; + __gthread_once (&once, emergency_mutex_init); +#endif + __gthread_mutex_lock (&emergency_mutex); +#endif + + bitmask_type used = emergency_used; + unsigned int which = 0; + + if (thrown_size > EMERGENCY_OBJ_SIZE) + goto failed; + while (used & 1) + { + used >>= 1; + if (++which >= EMERGENCY_OBJ_COUNT) + goto failed; + } + + emergency_used |= (bitmask_type)1 << which; + ret = &emergency_buffer[which][0]; + + failed:; +#ifdef __GTHREADS + __gthread_mutex_unlock (&emergency_mutex); +#endif + if (!ret) + std::terminate (); + } + + std::memset (ret, 0, sizeof (__cxa_exception)); + + return (void *)((char *)ret + sizeof (__cxa_exception)); +} + + +extern "C" void +__cxa_free_exception(void *vptr) +{ + char *ptr = (char *) vptr; + if (ptr >= &emergency_buffer[0][0] + && ptr < &emergency_buffer[0][0] + sizeof (emergency_buffer)) + { + unsigned int which + = (unsigned)(ptr - &emergency_buffer[0][0]) / EMERGENCY_OBJ_SIZE; + +#ifdef __GTHREADS + __gthread_mutex_lock (&emergency_mutex); + emergency_used &= ~((bitmask_type)1 << which); + __gthread_mutex_unlock (&emergency_mutex); +#else + emergency_used &= ~((bitmask_type)1 << which); +#endif + } + else + std::free (ptr - sizeof (__cxa_exception)); +} diff --git a/contrib/libstdc++/libsupc++/eh_aux_runtime.cc b/contrib/libstdc++/libsupc++/eh_aux_runtime.cc new file mode 100644 index 0000000..118aa91 --- /dev/null +++ b/contrib/libstdc++/libsupc++/eh_aux_runtime.cc @@ -0,0 +1,57 @@ +// -*- C++ -*- Common throw conditions. +// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +// 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 "typeinfo" +#include "exception" +#include +#include "unwind-cxx.h" +#include "exception_defines.h" + + +extern "C" void +__cxa_bad_cast () +{ +#ifdef __EXCEPTIONS + throw std::bad_cast(); +#else + std::abort(); +#endif +} + +extern "C" void +__cxa_bad_typeid () +{ +#ifdef __EXCEPTIONS + throw std::bad_typeid(); +#else + std::abort(); +#endif +} + diff --git a/contrib/libstdc++/libsupc++/eh_catch.cc b/contrib/libstdc++/libsupc++/eh_catch.cc new file mode 100644 index 0000000..ba49dfe --- /dev/null +++ b/contrib/libstdc++/libsupc++/eh_catch.cc @@ -0,0 +1,106 @@ +// -*- C++ -*- Exception handling routines for catching. +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// 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 +#include "unwind-cxx.h" + +using namespace __cxxabiv1; + + +extern "C" void * +__cxa_begin_catch (void *exc_obj_in) +{ + _Unwind_Exception *exceptionObject + = reinterpret_cast <_Unwind_Exception *>(exc_obj_in); + + // ??? Foreign exceptions can't be stacked here, and there doesn't + // appear to be any place to store for __cxa_end_catch to destroy. + + __cxa_exception *header = __get_exception_header_from_ue (exceptionObject); + __cxa_eh_globals *globals = __cxa_get_globals (); + __cxa_exception *prev = globals->caughtExceptions; + int count = header->handlerCount; + + if (count < 0) + // This exception was rethrown from an immediately enclosing region. + count = -count + 1; + else + count += 1; + header->handlerCount = count; + + globals->uncaughtExceptions -= 1; + if (header != prev) + { + header->nextException = prev; + globals->caughtExceptions = header; + } + + return header->adjustedPtr; +} + + +extern "C" void +__cxa_end_catch () +{ + __cxa_eh_globals *globals = __cxa_get_globals_fast (); + __cxa_exception *header = globals->caughtExceptions; + int count = header->handlerCount; + + if (count < 0) + { + // This exception was rethrown. Decrement the (inverted) catch + // count and remove it from the chain when it reaches zero. + if (++count == 0) + { + globals->uncaughtExceptions += 1; + globals->caughtExceptions = header->nextException; + } + } + else if (--count == 0) + { + // Handling for this exception is complete. Destroy the object. + globals->caughtExceptions = header->nextException; + _Unwind_DeleteException (&header->unwindHeader); + return; + } + else if (count < 0) + // A bug in the exception handling library or compiler. + std::abort (); + + header->handlerCount = count; +} + + +bool +std::uncaught_exception() throw() +{ + __cxa_eh_globals *globals = __cxa_get_globals (); + return globals->uncaughtExceptions != 0; +} diff --git a/contrib/libstdc++/libsupc++/eh_exception.cc b/contrib/libstdc++/libsupc++/eh_exception.cc new file mode 100644 index 0000000..a581be7 --- /dev/null +++ b/contrib/libstdc++/libsupc++/eh_exception.cc @@ -0,0 +1,44 @@ +// -*- C++ -*- std::exception implementation. +// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 +// 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 "typeinfo" +#include "exception" +#include "unwind-cxx.h" + +std::exception::~exception() throw() { } + +std::bad_exception::~bad_exception() throw() { } + +const char* +std::exception::what() const throw() +{ + return typeid (*this).name (); +} diff --git a/contrib/libstdc++/libsupc++/eh_globals.cc b/contrib/libstdc++/libsupc++/eh_globals.cc new file mode 100644 index 0000000..3033619 --- /dev/null +++ b/contrib/libstdc++/libsupc++/eh_globals.cc @@ -0,0 +1,118 @@ +// -*- C++ -*- Manage the thread-local exception globals. +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// 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 +#include +#include "unwind-cxx.h" +#include "bits/c++config.h" +#include "bits/gthr.h" + +using namespace __cxxabiv1; + + +// Single-threaded fallback buffer. +static __cxa_eh_globals globals_static; + +#if __GTHREADS +static __gthread_key_t globals_key; +static int use_thread_key = -1; + +static void +get_globals_dtor (void *ptr) +{ + __gthread_key_dtor (globals_key, ptr); + if (ptr) + std::free (ptr); +} + +static void +get_globals_init () +{ + use_thread_key = + (__gthread_key_create (&globals_key, get_globals_dtor) == 0); +} + +static void +get_globals_init_once () +{ + static __gthread_once_t once = __GTHREAD_ONCE_INIT; + if (__gthread_once (&once, get_globals_init) != 0 + || use_thread_key < 0) + use_thread_key = 0; +} +#endif + +extern "C" __cxa_eh_globals * +__cxa_get_globals_fast () +{ +#if __GTHREADS + if (use_thread_key) + return (__cxa_eh_globals *) __gthread_getspecific (globals_key); + else + return &globals_static; +#else + return &globals_static; +#endif +} + +extern "C" __cxa_eh_globals * +__cxa_get_globals () +{ +#if __GTHREADS + __cxa_eh_globals *g; + + if (use_thread_key == 0) + return &globals_static; + + if (use_thread_key < 0) + { + get_globals_init_once (); + + // Make sure use_thread_key got initialized. + if (use_thread_key == 0) + return &globals_static; + } + + g = (__cxa_eh_globals *) __gthread_getspecific (globals_key); + if (! g) + { + if ((g = (__cxa_eh_globals *) + std::malloc (sizeof (__cxa_eh_globals))) == 0 + || __gthread_setspecific (globals_key, (void *) g) != 0) + std::terminate (); + g->caughtExceptions = 0; + g->uncaughtExceptions = 0; + } + + return g; +#else + return &globals_static; +#endif +} diff --git a/contrib/libstdc++/libsupc++/eh_personality.cc b/contrib/libstdc++/libsupc++/eh_personality.cc new file mode 100644 index 0000000..35e93a3 --- /dev/null +++ b/contrib/libstdc++/libsupc++/eh_personality.cc @@ -0,0 +1,485 @@ +// -*- C++ -*- The GNU C++ exception personality routine. +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// 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 +#include +#include +#include "unwind-cxx.h" + +using namespace __cxxabiv1; + +#include "unwind-pe.h" + + +struct lsda_header_info +{ + _Unwind_Ptr Start; + _Unwind_Ptr LPStart; + _Unwind_Ptr ttype_base; + const unsigned char *TType; + const unsigned char *action_table; + unsigned char ttype_encoding; + unsigned char call_site_encoding; +}; + +static const unsigned char * +parse_lsda_header (_Unwind_Context *context, const unsigned char *p, + lsda_header_info *info) +{ + _Unwind_Word tmp; + unsigned char lpstart_encoding; + + info->Start = (context ? _Unwind_GetRegionStart (context) : 0); + + // Find @LPStart, the base to which landing pad offsets are relative. + lpstart_encoding = *p++; + if (lpstart_encoding != DW_EH_PE_omit) + p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart); + else + info->LPStart = info->Start; + + // Find @TType, the base of the handler and exception spec type data. + info->ttype_encoding = *p++; + if (info->ttype_encoding != DW_EH_PE_omit) + { + p = read_uleb128 (p, &tmp); + info->TType = p + tmp; + } + else + info->TType = 0; + + // The encoding and length of the call-site table; the action table + // immediately follows. + info->call_site_encoding = *p++; + p = read_uleb128 (p, &tmp); + info->action_table = p + tmp; + + return p; +} + +static const std::type_info * +get_ttype_entry (lsda_header_info *info, _Unwind_Word i) +{ + _Unwind_Ptr ptr; + + i *= size_of_encoded_value (info->ttype_encoding); + read_encoded_value_with_base (info->ttype_encoding, info->ttype_base, + info->TType - i, &ptr); + + return reinterpret_cast(ptr); +} + +// Given the thrown type THROW_TYPE, pointer to a variable containing a +// pointer to the exception object THROWN_PTR_P and a type CATCH_TYPE to +// compare against, return whether or not there is a match and if so, +// update *THROWN_PTR_P. + +static bool +get_adjusted_ptr (const std::type_info *catch_type, + const std::type_info *throw_type, + void **thrown_ptr_p) +{ + void *thrown_ptr = *thrown_ptr_p; + + // Pointer types need to adjust the actual pointer, not + // the pointer to pointer that is the exception object. + // This also has the effect of passing pointer types + // "by value" through the __cxa_begin_catch return value. + if (throw_type->__is_pointer_p ()) + thrown_ptr = *(void **) thrown_ptr; + + if (catch_type->__do_catch (throw_type, &thrown_ptr, 1)) + { + *thrown_ptr_p = thrown_ptr; + return true; + } + + return false; +} + +static bool +check_exception_spec (lsda_header_info *info, const std::type_info *throw_type, + void *thrown_ptr, _Unwind_Sword filter_value) +{ + const unsigned char *e = info->TType - filter_value - 1; + + while (1) + { + const std::type_info *catch_type; + _Unwind_Word tmp; + + e = read_uleb128 (e, &tmp); + + // Zero signals the end of the list. If we've not found + // a match by now, then we've failed the specification. + if (tmp == 0) + return false; + + // Match a ttype entry. + catch_type = get_ttype_entry (info, tmp); + + // ??? There is currently no way to ask the RTTI code about the + // relationship between two types without reference to a specific + // object. There should be; then we wouldn't need to mess with + // thrown_ptr here. + if (get_adjusted_ptr (catch_type, throw_type, &thrown_ptr)) + return true; + } +} + +// Using a different personality function name causes link failures +// when trying to mix code using different exception handling models. +#ifdef _GLIBCPP_SJLJ_EXCEPTIONS +#define PERSONALITY_FUNCTION __gxx_personality_sj0 +#define __builtin_eh_return_data_regno(x) x +#else +#define PERSONALITY_FUNCTION __gxx_personality_v0 +#endif + +extern "C" _Unwind_Reason_Code +PERSONALITY_FUNCTION (int version, + _Unwind_Action actions, + _Unwind_Exception_Class exception_class, + struct _Unwind_Exception *ue_header, + struct _Unwind_Context *context) +{ + __cxa_exception *xh = __get_exception_header_from_ue (ue_header); + + enum found_handler_type + { + found_nothing, + found_terminate, + found_cleanup, + found_handler + } found_type; + + lsda_header_info info; + const unsigned char *language_specific_data; + const unsigned char *action_record; + const unsigned char *p; + _Unwind_Ptr landing_pad, ip; + int handler_switch_value; + void *thrown_ptr = xh + 1; + + // Interface version check. + if (version != 1) + return _URC_FATAL_PHASE1_ERROR; + + // Shortcut for phase 2 found handler for domestic exception. + if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME) + && exception_class == __gxx_exception_class) + { + handler_switch_value = xh->handlerSwitchValue; + landing_pad = (_Unwind_Ptr) xh->catchTemp; + found_type = (landing_pad == 0 ? found_terminate : found_handler); + goto install_context; + } + + language_specific_data = (const unsigned char *) + _Unwind_GetLanguageSpecificData (context); + + // If no LSDA, then there are no handlers or cleanups. + if (! language_specific_data) + return _URC_CONTINUE_UNWIND; + + // Parse the LSDA header. + p = parse_lsda_header (context, language_specific_data, &info); + info.ttype_base = base_of_encoded_value (info.ttype_encoding, context); + ip = _Unwind_GetIP (context) - 1; + landing_pad = 0; + action_record = 0; + handler_switch_value = 0; + +#ifdef _GLIBCPP_SJLJ_EXCEPTIONS + // The given "IP" is an index into the call-site table, with two + // exceptions -- -1 means no-action, and 0 means terminate. But + // since we're using uleb128 values, we've not got random access + // to the array. + if ((int) ip < 0) + return _URC_CONTINUE_UNWIND; + else if (ip == 0) + { + // Fall through to set found_terminate. + } + else + { + _Unwind_Word cs_lp, cs_action; + do + { + p = read_uleb128 (p, &cs_lp); + p = read_uleb128 (p, &cs_action); + } + while (--ip); + + // Can never have null landing pad for sjlj -- that would have + // been indicated by a -1 call site index. + landing_pad = cs_lp + 1; + if (cs_action) + action_record = info.action_table + cs_action - 1; + goto found_something; + } +#else + // Search the call-site table for the action associated with this IP. + while (p < info.action_table) + { + _Unwind_Ptr cs_start, cs_len, cs_lp; + _Unwind_Word cs_action; + + // Note that all call-site encodings are "absolute" displacements. + p = read_encoded_value (0, info.call_site_encoding, p, &cs_start); + p = read_encoded_value (0, info.call_site_encoding, p, &cs_len); + p = read_encoded_value (0, info.call_site_encoding, p, &cs_lp); + p = read_uleb128 (p, &cs_action); + + // The table is sorted, so if we've passed the ip, stop. + if (ip < info.Start + cs_start) + p = info.action_table; + else if (ip < info.Start + cs_start + cs_len) + { + if (cs_lp) + landing_pad = info.LPStart + cs_lp; + if (cs_action) + action_record = info.action_table + cs_action - 1; + goto found_something; + } + } +#endif // _GLIBCPP_SJLJ_EXCEPTIONS + + // If ip is not present in the table, call terminate. This is for + // a destructor inside a cleanup, or a library routine the compiler + // was not expecting to throw. + found_type = (actions & _UA_FORCE_UNWIND ? found_nothing : found_terminate); + goto do_something; + + found_something: + if (landing_pad == 0) + { + // If ip is present, and has a null landing pad, there are + // no cleanups or handlers to be run. + found_type = found_nothing; + } + else if (action_record == 0) + { + // If ip is present, has a non-null landing pad, and a null + // action table offset, then there are only cleanups present. + // Cleanups use a zero switch value, as set above. + found_type = found_cleanup; + } + else + { + // Otherwise we have a catch handler or exception specification. + + _Unwind_Sword ar_filter, ar_disp; + const std::type_info *throw_type, *catch_type; + bool saw_cleanup = false; + bool saw_handler = false; + + // During forced unwinding, we only run cleanups. With a foreign + // exception class, there's no exception type. + // ??? What to do about GNU Java and GNU Ada exceptions. + + if ((actions & _UA_FORCE_UNWIND) + || exception_class != __gxx_exception_class) + throw_type = 0; + else + throw_type = xh->exceptionType; + + while (1) + { + p = action_record; + p = read_sleb128 (p, &ar_filter); + read_sleb128 (p, &ar_disp); + + if (ar_filter == 0) + { + // Zero filter values are cleanups. + saw_cleanup = true; + } + else if (ar_filter > 0) + { + // Positive filter values are handlers. + catch_type = get_ttype_entry (&info, ar_filter); + + // Null catch type is a catch-all handler. We can catch + // foreign exceptions with this. + if (! catch_type) + { + if (!(actions & _UA_FORCE_UNWIND)) + { + saw_handler = true; + break; + } + } + else if (throw_type) + { + if (get_adjusted_ptr (catch_type, throw_type, &thrown_ptr)) + { + saw_handler = true; + break; + } + } + } + else + { + // Negative filter values are exception specifications. + // ??? How do foreign exceptions fit in? As far as I can + // see we can't match because there's no __cxa_exception + // object to stuff bits in for __cxa_call_unexpected to use. + if (throw_type + && ! check_exception_spec (&info, throw_type, thrown_ptr, + ar_filter)) + { + saw_handler = true; + break; + } + } + + if (ar_disp == 0) + break; + action_record = p + ar_disp; + } + + if (saw_handler) + { + handler_switch_value = ar_filter; + found_type = found_handler; + } + else + found_type = (saw_cleanup ? found_cleanup : found_nothing); + } + + do_something: + if (found_type == found_nothing) + return _URC_CONTINUE_UNWIND; + + if (actions & _UA_SEARCH_PHASE) + { + if (found_type == found_cleanup) + return _URC_CONTINUE_UNWIND; + + // For domestic exceptions, we cache data from phase 1 for phase 2. + if (exception_class == __gxx_exception_class) + { + xh->handlerSwitchValue = handler_switch_value; + xh->actionRecord = action_record; + xh->languageSpecificData = language_specific_data; + xh->adjustedPtr = thrown_ptr; + + // ??? Completely unknown what this field is supposed to be for. + // ??? Need to cache TType encoding base for call_unexpected. + xh->catchTemp = (void *) (_Unwind_Ptr) landing_pad; + } + return _URC_HANDLER_FOUND; + } + + install_context: + if (found_type == found_terminate) + { + __cxa_begin_catch (&xh->unwindHeader); + __terminate (xh->terminateHandler); + } + + // Cache the TType base value for __cxa_call_unexpected, as we won't + // have an _Unwind_Context then. + if (handler_switch_value < 0) + { + parse_lsda_header (context, xh->languageSpecificData, &info); + xh->catchTemp = (void *) base_of_encoded_value (info.ttype_encoding, + context); + } + + _Unwind_SetGR (context, __builtin_eh_return_data_regno (0), + (_Unwind_Ptr) &xh->unwindHeader); + _Unwind_SetGR (context, __builtin_eh_return_data_regno (1), + handler_switch_value); + _Unwind_SetIP (context, landing_pad); + return _URC_INSTALL_CONTEXT; +} + +extern "C" void +__cxa_call_unexpected (void *exc_obj_in) +{ + _Unwind_Exception *exc_obj + = reinterpret_cast <_Unwind_Exception *>(exc_obj_in); + + __cxa_begin_catch (exc_obj); + + // This function is a handler for our exception argument. If we exit + // by throwing a different exception, we'll need the original cleaned up. + struct end_catch_protect + { + end_catch_protect() { } + ~end_catch_protect() { __cxa_end_catch(); } + } end_catch_protect_obj; + + lsda_header_info info; + __cxa_exception *xh = __get_exception_header_from_ue (exc_obj); + const unsigned char *xh_lsda; + _Unwind_Sword xh_switch_value; + std::terminate_handler xh_terminate_handler; + + // If the unexpectedHandler rethrows the exception (e.g. to categorize it), + // it will clobber data about the current handler. So copy the data out now. + xh_lsda = xh->languageSpecificData; + xh_switch_value = xh->handlerSwitchValue; + xh_terminate_handler = xh->terminateHandler; + info.ttype_base = (_Unwind_Ptr) xh->catchTemp; + + try + { __unexpected (xh->unexpectedHandler); } + catch(...) + { + // Get the exception thrown from unexpected. + // ??? Foreign exceptions can't be stacked this way. + + __cxa_eh_globals *globals = __cxa_get_globals_fast (); + __cxa_exception *new_xh = globals->caughtExceptions; + void *new_ptr = new_xh + 1; + + // We don't quite have enough stuff cached; re-parse the LSDA. + parse_lsda_header (0, xh_lsda, &info); + + // If this new exception meets the exception spec, allow it. + if (check_exception_spec (&info, new_xh->exceptionType, + new_ptr, xh_switch_value)) + __throw_exception_again; + + // If the exception spec allows std::bad_exception, throw that. + // We don't have a thrown object to compare against, but since + // bad_exception doesn't have virtual bases, that's OK; just pass 0. +#ifdef __EXCEPTIONS + const std::type_info &bad_exc = typeid (std::bad_exception); + if (check_exception_spec (&info, &bad_exc, 0, xh_switch_value)) + throw std::bad_exception(); +#endif + // Otherwise, die. + __terminate (xh_terminate_handler); + } +} diff --git a/contrib/libstdc++/libsupc++/eh_terminate.cc b/contrib/libstdc++/libsupc++/eh_terminate.cc new file mode 100644 index 0000000..58a6ea4 --- /dev/null +++ b/contrib/libstdc++/libsupc++/eh_terminate.cc @@ -0,0 +1,87 @@ +// -*- C++ -*- std::terminate, std::unexpected and friends. +// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +// 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 "typeinfo" +#include "exception" +#include +#include "unwind-cxx.h" +#include "exception_defines.h" + +using namespace __cxxabiv1; + +/* The current installed user handlers. */ +std::terminate_handler __cxxabiv1::__terminate_handler = std::abort; +std::unexpected_handler __cxxabiv1::__unexpected_handler = std::terminate; + +void +__cxxabiv1::__terminate (std::terminate_handler handler) +{ + try { + handler (); + std::abort (); + } catch (...) { + std::abort (); + } +} + +void +std::terminate () +{ + __terminate (__terminate_handler); +} + +void +__cxxabiv1::__unexpected (std::unexpected_handler handler) +{ + handler(); + std::terminate (); +} + +void +std::unexpected () +{ + __unexpected (__unexpected_handler); +} + +std::terminate_handler +std::set_terminate (std::terminate_handler func) throw() +{ + std::terminate_handler old = __terminate_handler; + __terminate_handler = func; + return old; +} + +std::unexpected_handler +std::set_unexpected (std::unexpected_handler func) throw() +{ + std::unexpected_handler old = __unexpected_handler; + __unexpected_handler = func; + return old; +} diff --git a/contrib/libstdc++/libsupc++/eh_throw.cc b/contrib/libstdc++/libsupc++/eh_throw.cc new file mode 100644 index 0000000..407b829 --- /dev/null +++ b/contrib/libstdc++/libsupc++/eh_throw.cc @@ -0,0 +1,102 @@ +// -*- C++ -*- Exception handling routines for throwing. +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// 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 +#include "unwind-cxx.h" + + +using namespace __cxxabiv1; + + +static void +__gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc) +{ + __cxa_exception *header = __get_exception_header_from_ue (exc); + + // If we haven't been caught by a foreign handler, then this is + // some sort of unwind error. In that case just die immediately. + if (code != _URC_FOREIGN_EXCEPTION_CAUGHT) + __terminate (header->terminateHandler); + + if (header->exceptionDestructor) + header->exceptionDestructor (header + 1); + + __cxa_free_exception (header + 1); +} + + +extern "C" void +__cxa_throw (void *obj, std::type_info *tinfo, void (*dest) (void *)) +{ + __cxa_exception *header = __get_exception_header_from_obj (obj); + header->exceptionType = tinfo; + header->exceptionDestructor = dest; + header->unexpectedHandler = __unexpected_handler; + header->terminateHandler = __terminate_handler; + header->unwindHeader.exception_class = __gxx_exception_class; + header->unwindHeader.exception_cleanup = __gxx_exception_cleanup; + + __cxa_eh_globals *globals = __cxa_get_globals (); + globals->uncaughtExceptions += 1; + +#ifdef _GLIBCPP_SJLJ_EXCEPTIONS + _Unwind_SjLj_RaiseException (&header->unwindHeader); +#else + _Unwind_RaiseException (&header->unwindHeader); +#endif + + // Some sort of unwinding error. Note that terminate is a handler. + __cxa_begin_catch (&header->unwindHeader); + std::terminate (); +} + +extern "C" void +__cxa_rethrow () +{ + __cxa_eh_globals *globals = __cxa_get_globals (); + __cxa_exception *header = globals->caughtExceptions; + + // Watch for luser rethrowing with no active exception. + if (header) + { + // Tell __cxa_end_catch this is a rethrow. + header->handlerCount = -header->handlerCount; + +#ifdef _GLIBCPP_SJLJ_EXCEPTIONS + _Unwind_SjLj_RaiseException (&header->unwindHeader); +#else + _Unwind_RaiseException (&header->unwindHeader); +#endif + + // Some sort of unwinding error. Note that terminate is a handler. + __cxa_begin_catch (&header->unwindHeader); + } + std::terminate (); +} diff --git a/contrib/libstdc++/libsupc++/eh_type.cc b/contrib/libstdc++/libsupc++/eh_type.cc new file mode 100644 index 0000000..1c8afac --- /dev/null +++ b/contrib/libstdc++/libsupc++/eh_type.cc @@ -0,0 +1,50 @@ +// -*- C++ -*- Exception handling routines for catching. +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// 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 +#include "unwind-cxx.h" + +namespace __cxxabiv1 +{ + +// Returns the type_info for the currently handled exception [15.3/8], or +// null if there is none. +extern "C" +std::type_info *__cxa_current_exception_type () +{ + __cxa_eh_globals *globals = __cxa_get_globals (); + __cxa_exception *header = globals->caughtExceptions; + if (header) + return header->exceptionType; + else + return 0; +} + +} // namespace __cxxabiv1 diff --git a/contrib/libstdc++/libsupc++/exception b/contrib/libstdc++/libsupc++/exception new file mode 100644 index 0000000..b26cb6d --- /dev/null +++ b/contrib/libstdc++/libsupc++/exception @@ -0,0 +1,116 @@ +// Exception Handling support header for -*- C++ -*- + +// Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002 +// 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. + +/** @file exception + * This header defines several types and functions relating to the + * handling of exceptions in a C++ program. + */ + +#ifndef __EXCEPTION__ +#define __EXCEPTION__ + +extern "C++" { + +namespace std +{ + /** This is the base class for all exceptions thrown by the standard + * library, and by certain language expressions. You are free to derive + * your own %exception classes, or use a different hierarchy, or to + * throw non-class data (e.g., fundamental types). + * @brief Base class for all library exceptions. + */ + class exception + { + public: + exception() throw() { } + virtual ~exception() throw(); + /** Returns a C-style character string describing the general cause + * of the current error. */ + virtual const char* what() const throw(); + }; + + /** If an %exception is thrown which is not listed in a function's + * %exception specification, one of these may be thrown. */ + class bad_exception : public exception + { + public: + bad_exception() throw() { } + // This declaration is not useless: + // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 + virtual ~bad_exception() throw(); + }; + + /// If you write a replacement %terminate handler, it must be of this type. + typedef void (*terminate_handler) (); + /// If you write a replacement %unexpected handler, it must be of this type. + typedef void (*unexpected_handler) (); + + /// Takes a new handler function as an argument, returns the old function. + terminate_handler set_terminate(terminate_handler) throw(); + /** The runtime will call this function if %exception handling must be + * abandoned for any reason. */ + void terminate() __attribute__ ((__noreturn__)); + + /// Takes a new handler function as an argument, returns the old function. + unexpected_handler set_unexpected(unexpected_handler) throw(); + /** The runtime will call this function if an %exception is thrown which + * violates the function's %exception specification. */ + void unexpected() __attribute__ ((__noreturn__)); + + /** [18.6.4]/1: "Returns true after completing evaluation of a + * throw-expression until either completing initialization of the + * exception-declaration in the matching handler or entering @c unexpected() + * due to the throw; or after entering @c terminate() for any reason + * other than an explicit call to @c terminate(). [Note: This includes + * stack unwinding [15.2]. end note]" + * + * 2: "When @c uncaught_exception() is true, throwing an %exception can + * result in a call of @c terminate() (15.5.1)." + */ + bool uncaught_exception() throw(); +} // namespace std + +namespace __gnu_cxx +{ + /** A replacement for the standard terminate_handler which prints more + information about the terminating exception (if any) on stderr. Call + @code + std::set_terminate (__gnu_cxx::__verbose_terminate_handler) + @endcode + to use. For more info, see + http://gcc.gnu.org/onlinedocs/libstdc++/19_diagnostics/howto.html#4 + */ + void __verbose_terminate_handler (); +} // namespace __gnu_cxx + +} // extern "C++" + +#endif diff --git a/contrib/libstdc++/libsupc++/exception_defines.h b/contrib/libstdc++/libsupc++/exception_defines.h new file mode 100644 index 0000000..fca2d83 --- /dev/null +++ b/contrib/libstdc++/libsupc++/exception_defines.h @@ -0,0 +1,42 @@ +// -fno-exceptions Support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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. + +// This library 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 this library; 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. + +// +// ISO C++ 14882: 19.1 Exception classes +// + +#ifndef __EXCEPTIONS +// Iff -fno-exceptions, transform error handling code to work without it. +# define try if (true) +# define catch(X) if (false) +# define __throw_exception_again +#else +// Else proceed normally. +# define __throw_exception_again throw +#endif diff --git a/contrib/libstdc++/libsupc++/new b/contrib/libstdc++/libsupc++/new new file mode 100644 index 0000000..afa603a --- /dev/null +++ b/contrib/libstdc++/libsupc++/new @@ -0,0 +1,94 @@ +// The -*- C++ -*- dynamic memory management header. + +// Copyright (C) 1994, 1996, 1997, 1998, 2000, 2001, 2002 +// 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. + +/** @file new + * The header @c new defines several functions to manage dynamic memory and + * handling memory allocation errors; see + * http://gcc.gnu.org/onlinedocs/libstdc++/18_support/howto.html#4 for more. + */ + +#ifndef __NEW__ +#define __NEW__ + +#include +#include + +extern "C++" { + +namespace std +{ + /** @c bad_alloc (or classes derived from it) is used to report allocation + * errors from the throwing forms of @c new. */ + class bad_alloc : public exception + { + public: + bad_alloc() throw() { } + // This declaration is not useless: + // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 + virtual ~bad_alloc() throw(); + }; + + struct nothrow_t { }; + extern const nothrow_t nothrow; + /** If you write your own error handler to be called by @c new, it must + * be of this type. */ + typedef void (*new_handler)(); + /// Takes a replacement handler as the argument, returns the previous handler. + new_handler set_new_handler(new_handler); +} // namespace std + +//@{ +/** These are replaceable signatures: + * - normal single new and delete (no arguments, throw @c bad_alloc on error) + * - normal array new and delete (same) + * - @c nothrow single new and delete (take a @c nothrow argument, return + * @c NULL on error) + * - @c nothrow array new and delete (same) + * + * Placement new and delete signatures (take a memory address argument, + * does nothing) may not be replaced by a user's program. +*/ +void* operator new(std::size_t) throw (std::bad_alloc); +void* operator new[](std::size_t) throw (std::bad_alloc); +void operator delete(void*) throw(); +void operator delete[](void*) throw(); +void* operator new(std::size_t, const std::nothrow_t&) throw(); +void* operator new[](std::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(std::size_t, void* __p) throw() { return __p; } +inline void* operator new[](std::size_t, void* __p) throw() { return __p; } +//@} +} // extern "C++" + +#endif diff --git a/contrib/libstdc++/libsupc++/new_handler.cc b/contrib/libstdc++/libsupc++/new_handler.cc new file mode 100644 index 0000000..ed34bc8 --- /dev/null +++ b/contrib/libstdc++/libsupc++/new_handler.cc @@ -0,0 +1,47 @@ +// Implementation file for the -*- C++ -*- dynamic memory management header. + +// Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002 +// 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" + +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; +} + +std::bad_alloc::~bad_alloc() throw() { } diff --git a/contrib/libstdc++/libsupc++/new_op.cc b/contrib/libstdc++/libsupc++/new_op.cc new file mode 100644 index 0000000..df43e6e --- /dev/null +++ b/contrib/libstdc++/libsupc++/new_op.cc @@ -0,0 +1,63 @@ +// Support routines for the -*- C++ -*- dynamic memory management. +// Copyright (C) 1997, 1998, 1999, 2000, 2001 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" +#include +#include + +using std::new_handler; +using std::bad_alloc; + +extern "C" void *malloc (std::size_t); +extern new_handler __new_handler; + +void * +operator new (std::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) +#ifdef __EXCEPTIONS + throw bad_alloc(); +#else + std::abort(); +#endif + handler (); + p = (void *) malloc (sz); + } + + return p; +} diff --git a/contrib/libstdc++/libsupc++/new_opnt.cc b/contrib/libstdc++/libsupc++/new_opnt.cc new file mode 100644 index 0000000..e97ac98 --- /dev/null +++ b/contrib/libstdc++/libsupc++/new_opnt.cc @@ -0,0 +1,66 @@ +// Support routines for the -*- C++ -*- dynamic memory management. +// Copyright (C) 1997, 1998, 1999, 2000, 2001 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" +#include + +using std::new_handler; +using std::bad_alloc; + +extern "C" void *malloc (std::size_t); +extern new_handler __new_handler; + +void * +operator new (std::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; +} diff --git a/contrib/libstdc++/libsupc++/new_opv.cc b/contrib/libstdc++/libsupc++/new_opv.cc new file mode 100644 index 0000000..7b1b1ca --- /dev/null +++ b/contrib/libstdc++/libsupc++/new_opv.cc @@ -0,0 +1,37 @@ +// 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[] (std::size_t sz) throw (std::bad_alloc) +{ + return ::operator new(sz); +} diff --git a/contrib/libstdc++/libsupc++/new_opvnt.cc b/contrib/libstdc++/libsupc++/new_opvnt.cc new file mode 100644 index 0000000..ad5fbf4 --- /dev/null +++ b/contrib/libstdc++/libsupc++/new_opvnt.cc @@ -0,0 +1,37 @@ +// 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[] (std::size_t sz, const std::nothrow_t& nothrow) throw() +{ + return ::operator new(sz, nothrow); +} diff --git a/contrib/libstdc++/libsupc++/pure.cc b/contrib/libstdc++/libsupc++/pure.cc new file mode 100644 index 0000000..5f9b3c8 --- /dev/null +++ b/contrib/libstdc++/libsupc++/pure.cc @@ -0,0 +1,51 @@ +// -*- C++ -*- +// Copyright (C) 2000, 2001 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 +#include "unwind-cxx.h" + +#ifdef _GLIBCPP_HAVE_UNISTD_H +# include +# define writestr(str) write(2, str, sizeof(str) - 1) +# 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 +#else +# include +# define writestr(str) fputs(str, stderr) +#endif + +extern "C" void +__cxa_pure_virtual (void) +{ + writestr ("pure virtual method called\n"); + std::terminate (); +} diff --git a/contrib/libstdc++/libsupc++/tinfo.cc b/contrib/libstdc++/libsupc++/tinfo.cc new file mode 100644 index 0000000..1eecdeb --- /dev/null +++ b/contrib/libstdc++/libsupc++/tinfo.cc @@ -0,0 +1,721 @@ +// Methods for type_info for -*- C++ -*- Run Time Type Identification. +// Copyright (C) 1994, 1996, 1998, 1999, 2000, 2001, 2002 +// 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 +#include "tinfo.h" +#include "new" // for placement new + +// This file contains the minimal working set necessary to link with code +// that uses virtual functions and -frtti but does not actually use RTTI +// functionality. + +std::type_info:: +~type_info () +{ } + +std::bad_cast::~bad_cast() throw() { } +std::bad_typeid::~bad_typeid() throw() { } + +#if !__GXX_MERGED_TYPEINFO_NAMES + +// We can't rely on common symbols being shared between shared objects. +bool std::type_info:: +operator== (const std::type_info& arg) const +{ + return (&arg == this) || (__builtin_strcmp (name (), arg.name ()) == 0); +} + +#endif + +namespace std { + +// return true if this is a type_info for a pointer type +bool type_info:: +__is_pointer_p () const +{ + return false; +} + +// return true if this is a type_info for a function type +bool type_info:: +__is_function_p () const +{ + return false; +} + +// try and catch a thrown object. +bool type_info:: +__do_catch (const type_info *thr_type, void **, unsigned) const +{ + return *this == *thr_type; +} + +// upcast from this type to the target. __class_type_info will override +bool type_info:: +__do_upcast (const abi::__class_type_info *, void **) const +{ + return false; +} + +}; + +namespace { + +using namespace std; +using namespace abi; + +// initial part of a vtable, this structure is used with offsetof, so we don't +// have to keep alignments consistent manually. +struct vtable_prefix { + ptrdiff_t whole_object; // offset to most derived object + const __class_type_info *whole_type; // pointer to most derived type_info + const void *origin; // what a class's vptr points to +}; + +template +inline const T * +adjust_pointer (const void *base, ptrdiff_t offset) +{ + return reinterpret_cast + (reinterpret_cast (base) + offset); +} + +// ADDR is a pointer to an object. Convert it to a pointer to a base, +// using OFFSET. IS_VIRTUAL is true, if we are getting a virtual base. +inline void const * +convert_to_base (void const *addr, bool is_virtual, ptrdiff_t offset) +{ + if (is_virtual) + { + const void *vtable = *static_cast (addr); + + offset = *adjust_pointer (vtable, offset); + } + + return adjust_pointer (addr, offset); +} + +// some predicate functions for __class_type_info::__sub_kind +inline bool contained_p (__class_type_info::__sub_kind access_path) +{ + return access_path >= __class_type_info::__contained_mask; +} +inline bool public_p (__class_type_info::__sub_kind access_path) +{ + return access_path & __class_type_info::__contained_public_mask; +} +inline bool virtual_p (__class_type_info::__sub_kind access_path) +{ + return (access_path & __class_type_info::__contained_virtual_mask); +} +inline bool contained_public_p (__class_type_info::__sub_kind access_path) +{ + return ((access_path & __class_type_info::__contained_public) + == __class_type_info::__contained_public); +} +inline bool contained_nonpublic_p (__class_type_info::__sub_kind access_path) +{ + return ((access_path & __class_type_info::__contained_public) + == __class_type_info::__contained_mask); +} +inline bool contained_nonvirtual_p (__class_type_info::__sub_kind access_path) +{ + return ((access_path & (__class_type_info::__contained_mask + | __class_type_info::__contained_virtual_mask)) + == __class_type_info::__contained_mask); +} + +static const __class_type_info *const nonvirtual_base_type = + static_cast (0) + 1; + +}; // namespace + +namespace __cxxabiv1 +{ + +__class_type_info:: +~__class_type_info () +{} + +__si_class_type_info:: +~__si_class_type_info () +{} + +__vmi_class_type_info:: +~__vmi_class_type_info () +{} + +// __upcast_result is used to hold information during traversal of a class +// hierarchy when catch matching. +struct __class_type_info::__upcast_result +{ + const void *dst_ptr; // pointer to caught object + __sub_kind part2dst; // path from current base to target + int src_details; // hints about the source type hierarchy + const __class_type_info *base_type; // where we found the target, + // if in vbase the __class_type_info of vbase + // if a non-virtual base then 1 + // else NULL + public: + __upcast_result (int d) + :dst_ptr (NULL), part2dst (__unknown), src_details (d), base_type (NULL) + {} +}; + +// __dyncast_result is used to hold information during traversal of a class +// hierarchy when dynamic casting. +struct __class_type_info::__dyncast_result +{ + const void *dst_ptr; // pointer to target object or NULL + __sub_kind whole2dst; // path from most derived object to target + __sub_kind whole2src; // path from most derived object to sub object + __sub_kind dst2src; // path from target to sub object + int whole_details; // details of the whole class hierarchy + + public: + __dyncast_result (int details_ = __vmi_class_type_info::__flags_unknown_mask) + :dst_ptr (NULL), whole2dst (__unknown), + whole2src (__unknown), dst2src (__unknown), + whole_details (details_) + {} +}; + +bool __class_type_info:: +__do_catch (const type_info *thr_type, + void **thr_obj, + unsigned outer) const +{ + if (*this == *thr_type) + return true; + if (outer >= 4) + // Neither `A' nor `A *'. + return false; + return thr_type->__do_upcast (this, thr_obj); +} + +bool __class_type_info:: +__do_upcast (const __class_type_info *dst_type, + void **obj_ptr) const +{ + __upcast_result result (__vmi_class_type_info::__flags_unknown_mask); + + __do_upcast (dst_type, *obj_ptr, result); + if (!contained_public_p (result.part2dst)) + return false; + *obj_ptr = const_cast (result.dst_ptr); + return true; +} + +inline __class_type_info::__sub_kind __class_type_info:: +__find_public_src (ptrdiff_t src2dst, + const void *obj_ptr, + const __class_type_info *src_type, + const void *src_ptr) const +{ + if (src2dst >= 0) + return adjust_pointer (obj_ptr, src2dst) == src_ptr + ? __contained_public : __not_contained; + if (src2dst == -2) + return __not_contained; + return __do_find_public_src (src2dst, obj_ptr, src_type, src_ptr); +} + +__class_type_info::__sub_kind __class_type_info:: +__do_find_public_src (ptrdiff_t, + const void *obj_ptr, + const __class_type_info *, + const void *src_ptr) const +{ + if (src_ptr == obj_ptr) + // Must be our type, as the pointers match. + return __contained_public; + return __not_contained; +} + +__class_type_info::__sub_kind __si_class_type_info:: +__do_find_public_src (ptrdiff_t src2dst, + const void *obj_ptr, + const __class_type_info *src_type, + const void *src_ptr) const +{ + if (src_ptr == obj_ptr && *this == *src_type) + return __contained_public; + return __base_type->__do_find_public_src (src2dst, obj_ptr, src_type, src_ptr); +} + +__class_type_info::__sub_kind __vmi_class_type_info:: +__do_find_public_src (ptrdiff_t src2dst, + const void *obj_ptr, + const __class_type_info *src_type, + const void *src_ptr) const +{ + if (obj_ptr == src_ptr && *this == *src_type) + return __contained_public; + + for (std::size_t i = __base_count; i--;) + { + if (!__base_info[i].__is_public_p ()) + continue; // Not public, can't be here. + + const void *base = obj_ptr; + ptrdiff_t offset = __base_info[i].__offset (); + bool is_virtual = __base_info[i].__is_virtual_p (); + + if (is_virtual) + { + if (src2dst == -3) + continue; // Not a virtual base, so can't be here. + } + base = convert_to_base (base, is_virtual, offset); + + __sub_kind base_kind = __base_info[i].__base->__do_find_public_src + (src2dst, base, src_type, src_ptr); + if (contained_p (base_kind)) + { + if (is_virtual) + base_kind = __sub_kind (base_kind | __contained_virtual_mask); + return base_kind; + } + } + + return __not_contained; +} + +bool __class_type_info:: +__do_dyncast (ptrdiff_t, + __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 &__restrict result) const +{ + if (obj_ptr == src_ptr && *this == *src_type) + { + // The src object we started from. Indicate how we are accessible from + // the most derived object. + result.whole2src = access_path; + return false; + } + if (*this == *dst_type) + { + result.dst_ptr = obj_ptr; + result.whole2dst = access_path; + result.dst2src = __not_contained; + return false; + } + return false; +} + +bool __si_class_type_info:: +__do_dyncast (ptrdiff_t src2dst, + __sub_kind access_path, + const __class_type_info *dst_type, + const void *obj_ptr, + const __class_type_info *src_type, + const void *src_ptr, + __dyncast_result &__restrict result) const +{ + if (*this == *dst_type) + { + result.dst_ptr = obj_ptr; + result.whole2dst = access_path; + if (src2dst >= 0) + result.dst2src = adjust_pointer (obj_ptr, src2dst) == src_ptr + ? __contained_public : __not_contained; + else if (src2dst == -2) + result.dst2src = __not_contained; + return false; + } + if (obj_ptr == src_ptr && *this == *src_type) + { + // The src object we started from. Indicate how we are accessible from + // the most derived object. + result.whole2src = access_path; + return false; + } + return __base_type->__do_dyncast (src2dst, access_path, dst_type, obj_ptr, + src_type, src_ptr, result); +} + +// This is a big hairy function. Although the run-time behaviour of +// dynamic_cast is simple to describe, it gives rise to some non-obvious +// behaviour. We also desire to determine as early as possible any definite +// answer we can get. Because it is unknown what the run-time ratio of +// succeeding to failing dynamic casts is, we do not know in which direction +// to bias any optimizations. To that end we make no particular effort towards +// early fail answers or early success answers. Instead we try to minimize +// work by filling in things lazily (when we know we need the information), +// and opportunisticly take early success or failure results. +bool __vmi_class_type_info:: +__do_dyncast (ptrdiff_t src2dst, + __sub_kind access_path, + const __class_type_info *dst_type, + const void *obj_ptr, + const __class_type_info *src_type, + const void *src_ptr, + __dyncast_result &__restrict result) const +{ + if (result.whole_details & __flags_unknown_mask) + result.whole_details = __flags; + + if (obj_ptr == src_ptr && *this == *src_type) + { + // The src object we started from. Indicate how we are accessible from + // the most derived object. + result.whole2src = access_path; + return false; + } + if (*this == *dst_type) + { + result.dst_ptr = obj_ptr; + result.whole2dst = access_path; + if (src2dst >= 0) + result.dst2src = adjust_pointer (obj_ptr, src2dst) == src_ptr + ? __contained_public : __not_contained; + else if (src2dst == -2) + result.dst2src = __not_contained; + return false; + } + + bool result_ambig = false; + for (std::size_t i = __base_count; i--;) + { + __dyncast_result result2 (result.whole_details); + void const *base = obj_ptr; + __sub_kind base_access = access_path; + ptrdiff_t offset = __base_info[i].__offset (); + bool is_virtual = __base_info[i].__is_virtual_p (); + + if (is_virtual) + base_access = __sub_kind (base_access | __contained_virtual_mask); + base = convert_to_base (base, is_virtual, offset); + + if (!__base_info[i].__is_public_p ()) + { + if (src2dst == -2 && + !(result.whole_details + & (__non_diamond_repeat_mask | __diamond_shaped_mask))) + // The hierarchy has no duplicate bases (which might ambiguate + // things) and where we started is not a public base of what we + // want (so it cannot be a downcast). There is nothing of interest + // hiding in a non-public base. + continue; + base_access = __sub_kind (base_access & ~__contained_public_mask); + } + + bool result2_ambig + = __base_info[i].__base->__do_dyncast (src2dst, base_access, + dst_type, base, + src_type, src_ptr, result2); + result.whole2src = __sub_kind (result.whole2src | result2.whole2src); + if (result2.dst2src == __contained_public + || result2.dst2src == __contained_ambig) + { + result.dst_ptr = result2.dst_ptr; + result.whole2dst = result2.whole2dst; + result.dst2src = result2.dst2src; + // Found a downcast which can't be bettered or an ambiguous downcast + // which can't be disambiguated + return result2_ambig; + } + + if (!result_ambig && !result.dst_ptr) + { + // Not found anything yet. + result.dst_ptr = result2.dst_ptr; + result.whole2dst = result2.whole2dst; + result_ambig = result2_ambig; + if (result.dst_ptr && result.whole2src != __unknown + && !(__flags & __non_diamond_repeat_mask)) + // Found dst and src and we don't have repeated bases. + return result_ambig; + } + else if (result.dst_ptr && result.dst_ptr == result2.dst_ptr) + { + // Found at same address, must be via virtual. Pick the most + // accessible path. + result.whole2dst = + __sub_kind (result.whole2dst | result2.whole2dst); + } + else if ((result.dst_ptr != 0 | result_ambig) + && (result2.dst_ptr != 0 | result2_ambig)) + { + // Found two different DST_TYPE bases, or a valid one and a set of + // ambiguous ones, must disambiguate. See whether SRC_PTR is + // contained publicly within one of the non-ambiguous choices. If it + // is in only one, then that's the choice. If it is in both, then + // we're ambiguous and fail. If it is in neither, we're ambiguous, + // but don't yet fail as we might later find a third base which does + // contain SRC_PTR. + + __sub_kind new_sub_kind = result2.dst2src; + __sub_kind old_sub_kind = result.dst2src; + + if (contained_p (result.whole2src) + && (!virtual_p (result.whole2src) + || !(result.whole_details & __diamond_shaped_mask))) + { + // We already found SRC_PTR as a base of most derived, and + // either it was non-virtual, or the whole hierarchy is + // not-diamond shaped. Therefore if it is in either choice, it + // can only be in one of them, and we will already know. + if (old_sub_kind == __unknown) + old_sub_kind = __not_contained; + if (new_sub_kind == __unknown) + new_sub_kind = __not_contained; + } + else + { + if (old_sub_kind >= __not_contained) + ;// already calculated + else if (contained_p (new_sub_kind) + && (!virtual_p (new_sub_kind) + || !(__flags & __diamond_shaped_mask))) + // Already found inside the other choice, and it was + // non-virtual or we are not diamond shaped. + old_sub_kind = __not_contained; + else + old_sub_kind = dst_type->__find_public_src + (src2dst, result.dst_ptr, src_type, src_ptr); + + if (new_sub_kind >= __not_contained) + ;// already calculated + else if (contained_p (old_sub_kind) + && (!virtual_p (old_sub_kind) + || !(__flags & __diamond_shaped_mask))) + // Already found inside the other choice, and it was + // non-virtual or we are not diamond shaped. + new_sub_kind = __not_contained; + else + new_sub_kind = dst_type->__find_public_src + (src2dst, result2.dst_ptr, src_type, src_ptr); + } + + // Neither sub_kind can be contained_ambig -- we bail out early + // when we find those. + if (contained_p (__sub_kind (new_sub_kind ^ old_sub_kind))) + { + // Only on one choice, not ambiguous. + if (contained_p (new_sub_kind)) + { + // Only in new. + result.dst_ptr = result2.dst_ptr; + result.whole2dst = result2.whole2dst; + result_ambig = false; + old_sub_kind = new_sub_kind; + } + result.dst2src = old_sub_kind; + if (public_p (result.dst2src)) + return false; // Can't be an ambiguating downcast for later discovery. + if (!virtual_p (result.dst2src)) + return false; // Found non-virtually can't be bettered + } + else if (contained_p (__sub_kind (new_sub_kind & old_sub_kind))) + { + // In both. + result.dst_ptr = NULL; + result.dst2src = __contained_ambig; + return true; // Fail. + } + else + { + // In neither publicly, ambiguous for the moment, but keep + // looking. It is possible that it was private in one or + // both and therefore we should fail, but that's just tough. + result.dst_ptr = NULL; + result.dst2src = __not_contained; + result_ambig = true; + } + } + + if (result.whole2src == __contained_private) + // We found SRC_PTR as a private non-virtual base, therefore all + // cross casts will fail. We have already found a down cast, if + // there is one. + return result_ambig; + } + + return result_ambig; +} + +bool __class_type_info:: +__do_upcast (const __class_type_info *dst, const void *obj, + __upcast_result &__restrict result) const +{ + if (*this == *dst) + { + result.dst_ptr = obj; + result.base_type = nonvirtual_base_type; + result.part2dst = __contained_public; + return true; + } + return false; +} + +bool __si_class_type_info:: +__do_upcast (const __class_type_info *dst, const void *obj_ptr, + __upcast_result &__restrict result) const +{ + if (__class_type_info::__do_upcast (dst, obj_ptr, result)) + return true; + + return __base_type->__do_upcast (dst, obj_ptr, result); +} + +bool __vmi_class_type_info:: +__do_upcast (const __class_type_info *dst, const void *obj_ptr, + __upcast_result &__restrict result) const +{ + if (__class_type_info::__do_upcast (dst, obj_ptr, result)) + return true; + + int src_details = result.src_details; + if (src_details & __flags_unknown_mask) + src_details = __flags; + + for (std::size_t i = __base_count; i--;) + { + __upcast_result result2 (src_details); + const void *base = obj_ptr; + ptrdiff_t offset = __base_info[i].__offset (); + bool is_virtual = __base_info[i].__is_virtual_p (); + bool is_public = __base_info[i].__is_public_p (); + + if (!is_public && !(src_details & __non_diamond_repeat_mask)) + // original cannot have an ambiguous base, so skip private bases + continue; + + if (base) + base = convert_to_base (base, is_virtual, offset); + + if (__base_info[i].__base->__do_upcast (dst, base, result2)) + { + if (result2.base_type == nonvirtual_base_type && is_virtual) + result2.base_type = __base_info[i].__base; + if (contained_p (result2.part2dst) && !is_public) + result2.part2dst = __sub_kind (result2.part2dst & ~__contained_public_mask); + + if (!result.base_type) + { + result = result2; + if (!contained_p (result.part2dst)) + return true; // found ambiguously + + if (result.part2dst & __contained_public_mask) + { + if (!(__flags & __non_diamond_repeat_mask)) + return true; // cannot have an ambiguous other base + } + else + { + if (!virtual_p (result.part2dst)) + return true; // cannot have another path + if (!(__flags & __diamond_shaped_mask)) + return true; // cannot have a more accessible path + } + } + else if (result.dst_ptr != result2.dst_ptr) + { + // Found an ambiguity. + result.dst_ptr = NULL; + result.part2dst = __contained_ambig; + return true; + } + else if (result.dst_ptr) + { + // Ok, found real object via a virtual path. + result.part2dst + = __sub_kind (result.part2dst | result2.part2dst); + } + else + { + // Dealing with a null pointer, need to check vbase + // containing each of the two choices. + if (result2.base_type == nonvirtual_base_type + || result.base_type == nonvirtual_base_type + || !(*result2.base_type == *result.base_type)) + { + // Already ambiguous, not virtual or via different virtuals. + // Cannot match. + result.part2dst = __contained_ambig; + return true; + } + result.part2dst + = __sub_kind (result.part2dst | result2.part2dst); + } + } + } + return result.part2dst != __unknown; +} + +// this is the external interface to the dynamic cast machinery +extern "C" void * +__dynamic_cast (const void *src_ptr, // object started from + const __class_type_info *src_type, // type of the starting object + const __class_type_info *dst_type, // desired target type + ptrdiff_t src2dst) // how src and dst are related +{ + const void *vtable = *static_cast (src_ptr); + const vtable_prefix *prefix = + adjust_pointer (vtable, + -offsetof (vtable_prefix, origin)); + const void *whole_ptr = + adjust_pointer (src_ptr, prefix->whole_object); + const __class_type_info *whole_type = prefix->whole_type; + __class_type_info::__dyncast_result result; + + whole_type->__do_dyncast (src2dst, __class_type_info::__contained_public, + dst_type, whole_ptr, src_type, src_ptr, result); + if (!result.dst_ptr) + return NULL; + if (contained_public_p (result.dst2src)) + // Src is known to be a public base of dst. + return const_cast (result.dst_ptr); + if (contained_public_p (__class_type_info::__sub_kind (result.whole2src & result.whole2dst))) + // Both src and dst are known to be public bases of whole. Found a valid + // cross cast. + return const_cast (result.dst_ptr); + if (contained_nonvirtual_p (result.whole2src)) + // Src is known to be a non-public nonvirtual base of whole, and not a + // base of dst. Found an invalid cross cast, which cannot also be a down + // cast + return NULL; + if (result.dst2src == __class_type_info::__unknown) + result.dst2src = dst_type->__find_public_src (src2dst, result.dst_ptr, + src_type, src_ptr); + if (contained_public_p (result.dst2src)) + // Found a valid down cast + return const_cast (result.dst_ptr); + // Must be an invalid down cast, or the cross cast wasn't bettered + return NULL; +} + +}; // namespace __cxxabiv1 diff --git a/contrib/libstdc++/libsupc++/tinfo.h b/contrib/libstdc++/libsupc++/tinfo.h new file mode 100644 index 0000000..b7191900 --- /dev/null +++ b/contrib/libstdc++/libsupc++/tinfo.h @@ -0,0 +1,10 @@ +// RTTI support internals for -*- C++ -*- +// Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001 +// Free Software Foundation + +#include "typeinfo" +#include + +// Class declarations shared between the typeinfo implementation files. + +#include diff --git a/contrib/libstdc++/libsupc++/tinfo2.cc b/contrib/libstdc++/libsupc++/tinfo2.cc new file mode 100644 index 0000000..8f3d631 --- /dev/null +++ b/contrib/libstdc++/libsupc++/tinfo2.cc @@ -0,0 +1,167 @@ +// Methods for type_info for -*- C++ -*- Run Time Type Identification. + +// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001 +// 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 +#include "tinfo.h" +#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 !__GXX_MERGED_TYPEINFO_NAMES + +bool +type_info::before (const type_info &arg) const +{ + return __builtin_strcmp (name (), arg.name ()) < 0; +} + +#endif + +#include + +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 (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 (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 diff --git a/contrib/libstdc++/libsupc++/typeinfo b/contrib/libstdc++/libsupc++/typeinfo new file mode 100644 index 0000000..480dc4a --- /dev/null +++ b/contrib/libstdc++/libsupc++/typeinfo @@ -0,0 +1,150 @@ +// RTTI support for -*- C++ -*- +// Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002 +// 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. + +/** @file typeinfo + * This header provides RTTI support. + */ + +#ifndef __TYPEINFO__ +#define __TYPEINFO__ + +#include + +extern "C++" { + +namespace __cxxabiv1 +{ + class __class_type_info; +} // namespace __cxxabiv1 + +#if !__GXX_WEAK__ + // If weak symbols are not supported, typeinfo names are not merged. + #define __GXX_MERGED_TYPEINFO_NAMES 0 +#else + // On platforms that support weak symbols, typeinfo names are merged. + #define __GXX_MERGED_TYPEINFO_NAMES 1 +#endif + +namespace std +{ + /** The @c type_info class describes type information generated by + * an implementation. + * @brief Used in RTTI. */ + 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 + /** Returns an @e implementation-defined byte string; this is not + * portable between compilers! */ + const char* name() const + { return __name; } + +#if !__GXX_MERGED_TYPEINFO_NAMES + bool before(const type_info& __arg) const; + // In old abi, or when weak symbols are not supported, there can + // be multiple instances of a type_info object for one + // type. Uniqueness must use the _name value, not object address. + bool operator==(const type_info& __arg) const; +#else + /** Returns true if @c *this precedes @c __arg in the implementation's + * collation order. */ + // 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; } + bool operator==(const type_info& __arg) const + { return __name == __arg.__name; } +#endif + bool operator!=(const type_info& __arg) const + { return !operator==(__arg); } + + // the internal interface + 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; + }; + + /** If you attempt an invalid @c dynamic_cast expression, an instance of + * this class (or something derived from this class) is thrown. */ + class bad_cast : public exception + { + public: + bad_cast() throw() { } + // This declaration is not useless: + // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 + virtual ~bad_cast() throw(); + }; + + /** If you use a NULL pointer in a @c typeid expression, this is thrown. */ + class bad_typeid : public exception + { + public: + bad_typeid () throw() { } + // This declaration is not useless: + // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 + virtual ~bad_typeid() throw(); + }; +} // namespace std + +} // extern "C++" +#endif diff --git a/contrib/libstdc++/libsupc++/unwind-cxx.h b/contrib/libstdc++/libsupc++/unwind-cxx.h new file mode 100644 index 0000000..ea30eba --- /dev/null +++ b/contrib/libstdc++/libsupc++/unwind-cxx.h @@ -0,0 +1,171 @@ +// -*- C++ -*- Exception handling and frame unwind runtime interface routines. +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// 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 is derived from the C++ ABI for IA-64. Where we diverge +// for cross-architecture compatibility are noted with "@@@". + +#ifndef __UNWIND_CXX_H +#define __UNWIND_CXX_H 1 + +// Level 2: C++ ABI + +#include +#include +#include +#include "unwind.h" + +namespace __cxxabiv1 +{ + +// A C++ exception object consists of a header, which is a wrapper around +// an unwind object header with additional C++ specific information, +// followed by the exception object itself. + +struct __cxa_exception +{ + // Manage the exception object itself. + std::type_info *exceptionType; + void (*exceptionDestructor)(void *); + + // The C++ standard has entertaining rules wrt calling set_terminate + // and set_unexpected in the middle of the exception cleanup process. + std::unexpected_handler unexpectedHandler; + std::terminate_handler terminateHandler; + + // The caught exception stack threads through here. + __cxa_exception *nextException; + + // How many nested handlers have caught this exception. A negated + // value is a signal that this object has been rethrown. + int handlerCount; + + // Cache parsed handler data from the personality routine Phase 1 + // for Phase 2 and __cxa_call_unexpected. + int handlerSwitchValue; + const unsigned char *actionRecord; + const unsigned char *languageSpecificData; + void *catchTemp; + void *adjustedPtr; + + // The generic exception header. Must be last. + _Unwind_Exception unwindHeader; +}; + +// Each thread in a C++ program has access to a __cxa_eh_globals object. +struct __cxa_eh_globals +{ + __cxa_exception *caughtExceptions; + unsigned int uncaughtExceptions; +}; + + +// The __cxa_eh_globals for the current thread can be obtained by using +// either of the following functions. The "fast" version assumes at least +// one prior call of __cxa_get_globals has been made from the current +// thread, so no initialization is necessary. +extern "C" __cxa_eh_globals *__cxa_get_globals () throw(); +extern "C" __cxa_eh_globals *__cxa_get_globals_fast () throw(); + +// Allocate memory for the exception plus the thown object. +extern "C" void *__cxa_allocate_exception(std::size_t thrown_size) throw(); + +// Free the space allocated for the exception. +extern "C" void __cxa_free_exception(void *thrown_exception) throw(); + +// Throw the exception. +extern "C" void __cxa_throw (void *thrown_exception, + std::type_info *tinfo, + void (*dest) (void *)) + __attribute__((noreturn)); + +// Used to implement exception handlers. +extern "C" void *__cxa_begin_catch (void *) throw(); +extern "C" void __cxa_end_catch (); +extern "C" void __cxa_rethrow () __attribute__((noreturn)); + +// These facilitate code generation for recurring situations. +extern "C" void __cxa_bad_cast (); +extern "C" void __cxa_bad_typeid (); + +// @@@ These are not directly specified by the IA-64 C++ ABI. + +// Handles re-checking the exception specification if unexpectedHandler +// throws, and if bad_exception needs to be thrown. Called from the +// compiler. +extern "C" void __cxa_call_unexpected (void *) __attribute__((noreturn)); + +// Invokes given handler, dying appropriately if the user handler was +// so inconsiderate as to return. +extern void __terminate(std::terminate_handler) __attribute__((noreturn)); +extern void __unexpected(std::unexpected_handler) __attribute__((noreturn)); + +// The current installed user handlers. +extern std::terminate_handler __terminate_handler; +extern std::unexpected_handler __unexpected_handler; + +// These are explicitly GNU C++ specific. + +// This is the exception class we report -- "GNUCC++\0". +const _Unwind_Exception_Class __gxx_exception_class += ((((((((_Unwind_Exception_Class) 'G' + << 8 | (_Unwind_Exception_Class) 'N') + << 8 | (_Unwind_Exception_Class) 'U') + << 8 | (_Unwind_Exception_Class) 'C') + << 8 | (_Unwind_Exception_Class) 'C') + << 8 | (_Unwind_Exception_Class) '+') + << 8 | (_Unwind_Exception_Class) '+') + << 8 | (_Unwind_Exception_Class) '\0'); + +// GNU C++ personality routine, Version 0. +extern "C" _Unwind_Reason_Code __gxx_personality_v0 + (int, _Unwind_Action, _Unwind_Exception_Class, + struct _Unwind_Exception *, struct _Unwind_Context *); + +// GNU C++ sjlj personality routine, Version 0. +extern "C" _Unwind_Reason_Code __gxx_personality_sj0 + (int, _Unwind_Action, _Unwind_Exception_Class, + struct _Unwind_Exception *, struct _Unwind_Context *); + +// Acquire the C++ exception header from the C++ object. +static inline __cxa_exception * +__get_exception_header_from_obj (void *ptr) +{ + return reinterpret_cast<__cxa_exception *>(ptr) - 1; +} + +// Acquire the C++ exception header from the generic exception header. +static inline __cxa_exception * +__get_exception_header_from_ue (_Unwind_Exception *exc) +{ + return reinterpret_cast<__cxa_exception *>(exc + 1) - 1; +} + +} /* namespace __cxxabiv1 */ + +#endif // __UNWIND_CXX_H diff --git a/contrib/libstdc++/libsupc++/vec.cc b/contrib/libstdc++/libsupc++/vec.cc new file mode 100644 index 0000000..557fd03 --- /dev/null +++ b/contrib/libstdc++/libsupc++/vec.cc @@ -0,0 +1,336 @@ +// New abi Support -*- C++ -*- + +// Copyright (C) 2000, 2001 Free Software Foundation, Inc. +// +// 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. + +// Written by Nathan Sidwell, Codesourcery LLC, + +#include +#include +#include +#include +#include "unwind-cxx.h" + +namespace __cxxabiv1 +{ + namespace + { + struct uncatch_exception + { + uncatch_exception (); + ~uncatch_exception () { __cxa_begin_catch (&p->unwindHeader); } + + __cxa_exception *p; + }; + + uncatch_exception::uncatch_exception () + { + __cxa_eh_globals *globals = __cxa_get_globals_fast (); + + p = globals->caughtExceptions; + p->handlerCount -= 1; + globals->caughtExceptions = p->nextException; + globals->uncaughtExceptions += 1; + } + } + + // Allocate and construct array. + extern "C" void * + __cxa_vec_new(std::size_t element_count, + std::size_t element_size, + std::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(std::size_t element_count, + std::size_t element_size, + std::size_t padding_size, + void (*constructor) (void *), + void (*destructor) (void *), + void *(*alloc) (std::size_t), + void (*dealloc) (void *)) + { + std::size_t size = element_count * element_size + padding_size; + char *base = static_cast (alloc (size)); + + if (padding_size) + { + base += padding_size; + reinterpret_cast (base)[-1] = element_count; + } + try + { + __cxa_vec_ctor(base, element_count, element_size, + constructor, destructor); + } + catch (...) + { + { + uncatch_exception ue; + dealloc(base - padding_size); + } + __throw_exception_again; + } + return base; + } + + extern "C" void * + __cxa_vec_new3(std::size_t element_count, + std::size_t element_size, + std::size_t padding_size, + void (*constructor) (void *), + void (*destructor) (void *), + void *(*alloc) (std::size_t), + void (*dealloc) (void *, std::size_t)) + { + std::size_t size = element_count * element_size + padding_size; + char *base = static_cast(alloc (size)); + + if (padding_size) + { + base += padding_size; + reinterpret_cast(base)[-1] = element_count; + } + try + { + __cxa_vec_ctor(base, element_count, element_size, + constructor, destructor); + } + catch (...) + { + { + uncatch_exception ue; + dealloc(base - padding_size, size); + } + __throw_exception_again; + } + return base; + } + + // Construct array. + extern "C" void + __cxa_vec_ctor(void *array_address, + std::size_t element_count, + std::size_t element_size, + void (*constructor) (void *), + void (*destructor) (void *)) + { + std::size_t ix = 0; + char *ptr = static_cast(array_address); + + try + { + if (constructor) + for (; ix != element_count; ix++, ptr += element_size) + constructor(ptr); + } + catch (...) + { + { + uncatch_exception ue; + __cxa_vec_cleanup(array_address, ix, element_size, destructor); + } + __throw_exception_again; + } + } + + // Construct an array by copying. + extern "C" void + __cxa_vec_cctor(void *dest_array, + void *src_array, + std::size_t element_count, + std::size_t element_size, + void (*constructor) (void *, void *), + void (*destructor) (void *)) + { + std::size_t ix = 0; + char *dest_ptr = static_cast(dest_array); + char *src_ptr = static_cast(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 ue; + __cxa_vec_cleanup(dest_array, ix, element_size, destructor); + } + __throw_exception_again; + } + } + + // Destruct array. + extern "C" void + __cxa_vec_dtor(void *array_address, + std::size_t element_count, + std::size_t element_size, + void (*destructor) (void *)) + { + if (destructor) + { + char *ptr = static_cast(array_address); + std::size_t ix = element_count; + + ptr += element_count * element_size; + + try + { + while (ix--) + { + ptr -= element_size; + destructor(ptr); + } + } + catch (...) + { + { + uncatch_exception ue; + __cxa_vec_cleanup(array_address, ix, element_size, destructor); + } + __throw_exception_again; + } + } + } + + // Destruct array as a result of throwing an exception. + // [except.ctor]/3 If a destructor called during stack unwinding + // exits with an exception, terminate is called. + extern "C" void + __cxa_vec_cleanup(void *array_address, + std::size_t element_count, + std::size_t element_size, + void (*destructor) (void *)) + { + if (destructor) + { + char *ptr = static_cast (array_address); + std::size_t ix = element_count; + + ptr += element_count * element_size; + + try + { + while (ix--) + { + ptr -= element_size; + destructor(ptr); + } + } + catch (...) + { + std::terminate(); + } + } + } + + // Destruct and release array. + extern "C" void + __cxa_vec_delete(void *array_address, + std::size_t element_size, + std::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, + std::size_t element_size, + std::size_t padding_size, + void (*destructor) (void *), + void (*dealloc) (void *)) + { + char *base = static_cast(array_address); + + if (padding_size) + { + std::size_t element_count = reinterpret_cast(base)[-1]; + base -= padding_size; + try + { + __cxa_vec_dtor(array_address, element_count, element_size, + destructor); + } + catch (...) + { + { + uncatch_exception ue; + dealloc(base); + } + __throw_exception_again; + } + } + dealloc(base); + } + + extern "C" void + __cxa_vec_delete3(void *array_address, + std::size_t element_size, + std::size_t padding_size, + void (*destructor) (void *), + void (*dealloc) (void *, std::size_t)) + { + char *base = static_cast (array_address); + std::size_t size = 0; + + if (padding_size) + { + std::size_t element_count = reinterpret_cast (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 ue; + dealloc(base, size); + } + __throw_exception_again; + } + } + dealloc(base, size); + } +} // namespace __cxxabiv1 + -- cgit v1.1