diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libstdc++-v3/libsupc++ | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libstdc++-v3/libsupc++')
61 files changed, 8636 insertions, 0 deletions
diff --git a/libstdc++-v3/libsupc++/Makefile.am b/libstdc++-v3/libsupc++/Makefile.am new file mode 100644 index 000000000..701c2d9a7 --- /dev/null +++ b/libstdc++-v3/libsupc++/Makefile.am @@ -0,0 +1,219 @@ +## Makefile for the GNU C++ Support library. +## +## Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +## 2009, 2010, 2011 +## Free Software Foundation, Inc. +## +## Process this file with automake to produce Makefile.in. +## +## This file is part of GCC. +## +## GCC 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 3, or (at your option) +## any later version. +## +## GCC 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 GCC; see the file COPYING3. If not see +## <http://www.gnu.org/licenses/>. + +include $(top_srcdir)/fragment.am + +# 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 + +std_HEADERS = \ + cxxabi.h exception initializer_list new typeinfo + +bits_HEADERS = \ + cxxabi_forced.h hash_bytes.h \ + exception_defines.h exception_ptr.h nested_exception.h + +headers = $(std_HEADERS) $(bits_HEADERS) + +if GLIBCXX_HOSTED + c_sources = \ + cp-demangle.c +endif + +sources = \ + array_type_info.cc \ + atexit_arm.cc \ + bad_alloc.cc \ + bad_cast.cc \ + bad_typeid.cc \ + class_type_info.cc \ + del_op.cc \ + del_opnt.cc \ + del_opv.cc \ + del_opvnt.cc \ + dyncast.cc \ + eh_alloc.cc \ + eh_arm.cc \ + eh_aux_runtime.cc \ + eh_call.cc \ + eh_catch.cc \ + eh_exception.cc \ + eh_globals.cc \ + eh_personality.cc \ + eh_ptr.cc \ + eh_term_handler.cc \ + eh_terminate.cc \ + eh_throw.cc \ + eh_type.cc \ + eh_unex_handler.cc \ + enum_type_info.cc \ + function_type_info.cc \ + fundamental_type_info.cc \ + guard.cc \ + guard_error.cc \ + hash_bytes.cc \ + nested_exception.cc \ + new_handler.cc \ + new_op.cc \ + new_opnt.cc \ + new_opv.cc \ + new_opvnt.cc \ + pbase_type_info.cc \ + pmem_type_info.cc \ + pointer_type_info.cc \ + pure.cc \ + si_class_type_info.cc \ + tinfo.cc \ + tinfo2.cc \ + vec.cc \ + vmi_class_type_info.cc \ + vterminate.cc + +libsupc___la_SOURCES = $(sources) $(c_sources) +libsupc__convenience_la_SOURCES = $(sources) $(c_sources) + +# 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. +AM_CXXFLAGS = \ + -fno-implicit-templates \ + $(LIBSUPCXX_PICFLAGS) \ + $(WARN_CXXFLAGS) \ + $(OPTIMIZE_CXXFLAGS) \ + $(CONFIG_CXXFLAGS) + +AM_MAKEFLAGS = \ + "gxx_include_dir=$(gxx_include_dir)" + + +# Use special rules for pulling things out of libiberty. These +# objects should be compiled with the "C" compiler, not the C++ +# compiler, and also should not use the C++ includes. +C_INCLUDES = -I.. -I$(toplevel_srcdir)/libiberty -I$(toplevel_srcdir)/include +C_COMPILE = \ + $(CC) $(DEFS) $(C_INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) + +# LTCOMPILE is copied from LTCXXCOMPILE below. +LTCOMPILE = $(LIBTOOL) --tag CC --tag disable-shared $(LIBTOOLFLAGS) --mode=compile \ + $(CC) $(DEFS) $(C_INCLUDES) $(LIBSUPCXX_PICFLAGS) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) + +cp-demangle.c: + rm -f $@ + $(LN_S) $(toplevel_srcdir)/libiberty/cp-demangle.c $@ +cp-demangle.lo: cp-demangle.c + $(LTCOMPILE) -DIN_GLIBCPP_V3 -Wno-error -c $< +cp-demangle.o: cp-demangle.c + $(C_COMPILE) -DIN_GLIBCPP_V3 -Wno-error -c $< + + +nested_exception.lo: nested_exception.cc + $(LTCXXCOMPILE) -std=gnu++0x -c $< +nested_exception.o: nested_exception.cc + $(CXXCOMPILE) -std=gnu++0x -c $< + +# 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 $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) + +LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) + +# 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 $(LIBTOOLFLAGS) \ + --mode=link $(CXX) \ + $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@ + + +# Install notes +# We have to have rules modified from the default to counteract SUN make +# prepending each of $(*_HEADERS) with VPATH below. +stddir = $(gxx_include_dir) +bitsdir = $(gxx_include_dir)/bits + +install-stdHEADERS: $(std_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(stddir) + @list='$(std_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)$(stddir)/$$q"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(stddir)/$$q; \ + done + +install-bitsHEADERS: $(bits_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bitsdir) + @list='$(bits_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)$(bitsdir)/$$q"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(bitsdir)/$$q; \ + done + +uninstall-stdHEADERS: + @$(NORMAL_UNINSTALL) + list='$(std_HEADERS)'; for p in $$list; do \ + q=`echo $$p | sed -e 's,.*/,,'`; \ + rm -f $(DESTDIR)$(stddir)/$$q; \ + done + +uninstall-bitsHEADERS: + @$(NORMAL_UNINSTALL) + list='$(bits_HEADERS)'; for p in $$list; do \ + q=`echo $$p | sed -e 's,.*/,,'`; \ + rm -f $(DESTDIR)$(bitsdir)/$$q; \ + done diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in new file mode 100644 index 000000000..18ba84018 --- /dev/null +++ b/libstdc++-v3/libsupc++/Makefile.in @@ -0,0 +1,811 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +DIST_COMMON = $(top_srcdir)/fragment.am $(srcdir)/Makefile.in \ + $(srcdir)/Makefile.am $(bits_HEADERS) $(std_HEADERS) +subdir = libsupc++ +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ + $(top_srcdir)/../config/enable.m4 \ + $(top_srcdir)/../config/futex.m4 \ + $(top_srcdir)/../config/iconv.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ + $(top_srcdir)/../config/lib-ld.m4 \ + $(top_srcdir)/../config/lib-link.m4 \ + $(top_srcdir)/../config/lib-prefix.m4 \ + $(top_srcdir)/../config/lthostflags.m4 \ + $(top_srcdir)/../config/multi.m4 \ + $(top_srcdir)/../config/no-executables.m4 \ + $(top_srcdir)/../config/override.m4 \ + $(top_srcdir)/../config/stdint.m4 \ + $(top_srcdir)/../config/unwind_ipinfo.m4 \ + $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \ + $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \ + $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/crossconfig.m4 \ + $(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/../config/gc++filt.m4 \ + $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(bitsdir)" \ + "$(DESTDIR)$(stddir)" +LTLIBRARIES = $(noinst_LTLIBRARIES) $(toolexeclib_LTLIBRARIES) +libsupc___la_LIBADD = +am__objects_1 = array_type_info.lo atexit_arm.lo bad_alloc.lo \ + bad_cast.lo bad_typeid.lo class_type_info.lo del_op.lo \ + del_opnt.lo del_opv.lo del_opvnt.lo dyncast.lo eh_alloc.lo \ + eh_arm.lo eh_aux_runtime.lo eh_call.lo eh_catch.lo \ + eh_exception.lo eh_globals.lo eh_personality.lo eh_ptr.lo \ + eh_term_handler.lo eh_terminate.lo eh_throw.lo eh_type.lo \ + eh_unex_handler.lo enum_type_info.lo function_type_info.lo \ + fundamental_type_info.lo guard.lo guard_error.lo hash_bytes.lo \ + nested_exception.lo new_handler.lo new_op.lo new_opnt.lo \ + new_opv.lo new_opvnt.lo pbase_type_info.lo pmem_type_info.lo \ + pointer_type_info.lo pure.lo si_class_type_info.lo tinfo.lo \ + tinfo2.lo vec.lo vmi_class_type_info.lo vterminate.lo +@GLIBCXX_HOSTED_TRUE@am__objects_2 = cp-demangle.lo +am_libsupc___la_OBJECTS = $(am__objects_1) $(am__objects_2) +libsupc___la_OBJECTS = $(am_libsupc___la_OBJECTS) +libsupc__convenience_la_LIBADD = +am_libsupc__convenience_la_OBJECTS = $(am__objects_1) $(am__objects_2) +libsupc__convenience_la_OBJECTS = \ + $(am_libsupc__convenience_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = +am__depfiles_maybe = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +SOURCES = $(libsupc___la_SOURCES) $(libsupc__convenience_la_SOURCES) +HEADERS = $(bits_HEADERS) $(std_HEADERS) +ETAGS = etags +CTAGS = ctags +ABI_TWEAKS_SRCDIR = @ABI_TWEAKS_SRCDIR@ +ACLOCAL = @ACLOCAL@ +ALLOCATOR_H = @ALLOCATOR_H@ +ALLOCATOR_NAME = @ALLOCATOR_NAME@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +ATOMICITY_SRCDIR = @ATOMICITY_SRCDIR@ +ATOMIC_FLAGS = @ATOMIC_FLAGS@ +ATOMIC_WORD_SRCDIR = @ATOMIC_WORD_SRCDIR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BASIC_FILE_CC = @BASIC_FILE_CC@ +BASIC_FILE_H = @BASIC_FILE_H@ +CC = @CC@ +CCODECVT_CC = @CCODECVT_CC@ +CCOLLATE_CC = @CCOLLATE_CC@ +CCTYPE_CC = @CCTYPE_CC@ +CFLAGS = @CFLAGS@ +CLOCALE_CC = @CLOCALE_CC@ +CLOCALE_H = @CLOCALE_H@ +CLOCALE_INTERNAL_H = @CLOCALE_INTERNAL_H@ +CMESSAGES_CC = @CMESSAGES_CC@ +CMESSAGES_H = @CMESSAGES_H@ +CMONEY_CC = @CMONEY_CC@ +CNUMERIC_CC = @CNUMERIC_CC@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPU_DEFINES_SRCDIR = @CPU_DEFINES_SRCDIR@ +CSTDIO_H = @CSTDIO_H@ +CTIME_CC = @CTIME_CC@ +CTIME_H = @CTIME_H@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXFILT = @CXXFILT@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +C_INCLUDE_DIR = @C_INCLUDE_DIR@ +DBLATEX = @DBLATEX@ +DBTOEPUB = @DBTOEPUB@ +DEBUG_FLAGS = @DEBUG_FLAGS@ +DEFS = @DEFS@ +DOT = @DOT@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ERROR_CONSTANTS_SRCDIR = @ERROR_CONSTANTS_SRCDIR@ +EXEEXT = @EXEEXT@ +EXTRA_CXX_FLAGS = @EXTRA_CXX_FLAGS@ +FGREP = @FGREP@ +GLIBCXX_INCLUDES = @GLIBCXX_INCLUDES@ +GLIBCXX_LIBS = @GLIBCXX_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTIMIZE_CXXFLAGS = @OPTIMIZE_CXXFLAGS@ +OPT_LDFLAGS = @OPT_LDFLAGS@ +OS_INC_SRCDIR = @OS_INC_SRCDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PDFLATEX = @PDFLATEX@ +RANLIB = @RANLIB@ +RUBY = @RUBY@ +SECTION_FLAGS = @SECTION_FLAGS@ +SECTION_LDFLAGS = @SECTION_LDFLAGS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYMVER_FILE = @SYMVER_FILE@ +TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +WARN_FLAGS = @WARN_FLAGS@ +WERROR = @WERROR@ +XMLLINT = @XMLLINT@ +XSLTPROC = @XSLTPROC@ +XSL_STYLE_DIR = @XSL_STYLE_DIR@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__leading_dot = @am__leading_dot@ +am__tar = @am__tar@ +am__untar = @am__untar@ +baseline_dir = @baseline_dir@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +check_msgfmt = @check_msgfmt@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +enable_shared = @enable_shared@ +enable_static = @enable_static@ +exec_prefix = @exec_prefix@ +glibcxx_MOFILES = @glibcxx_MOFILES@ +glibcxx_PCHFLAGS = @glibcxx_PCHFLAGS@ +glibcxx_POFILES = @glibcxx_POFILES@ +glibcxx_builddir = @glibcxx_builddir@ +glibcxx_localedir = @glibcxx_localedir@ +glibcxx_prefixdir = @glibcxx_prefixdir@ +glibcxx_srcdir = @glibcxx_srcdir@ +glibcxx_thread_h = @glibcxx_thread_h@ +glibcxx_toolexecdir = @glibcxx_toolexecdir@ +glibcxx_toolexeclibdir = @glibcxx_toolexeclibdir@ +gxx_include_dir = @gxx_include_dir@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libtool_VERSION = @libtool_VERSION@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_host_flags = @lt_host_flags@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +multi_basedir = @multi_basedir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +port_specific_symbol_files = @port_specific_symbol_files@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +toplevel_srcdir = @toplevel_srcdir@ + +# May be used by various substitution variables. +gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER) +MAINT_CHARSET = latin1 +mkinstalldirs = $(SHELL) $(toplevel_srcdir)/mkinstalldirs +PWD_COMMAND = $${PWDCMD-pwd} +STAMP = echo timestamp > +toolexecdir = $(glibcxx_toolexecdir) +toolexeclibdir = $(glibcxx_toolexeclibdir) + +# These bits are all figured out from configure. Look in acinclude.m4 +# or configure.ac to see how they are set. See GLIBCXX_EXPORT_FLAGS. +CONFIG_CXXFLAGS = \ + $(SECTION_FLAGS) $(EXTRA_CXX_FLAGS) + +WARN_CXXFLAGS = \ + $(WARN_FLAGS) $(WERROR) -fdiagnostics-show-location=once + + +# -I/-D flags to pass when compiling. +AM_CPPFLAGS = $(GLIBCXX_INCLUDES) + +# 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 +std_HEADERS = \ + cxxabi.h exception initializer_list new typeinfo + +bits_HEADERS = \ + cxxabi_forced.h hash_bytes.h \ + exception_defines.h exception_ptr.h nested_exception.h + +headers = $(std_HEADERS) $(bits_HEADERS) +@GLIBCXX_HOSTED_TRUE@c_sources = \ +@GLIBCXX_HOSTED_TRUE@ cp-demangle.c + +sources = \ + array_type_info.cc \ + atexit_arm.cc \ + bad_alloc.cc \ + bad_cast.cc \ + bad_typeid.cc \ + class_type_info.cc \ + del_op.cc \ + del_opnt.cc \ + del_opv.cc \ + del_opvnt.cc \ + dyncast.cc \ + eh_alloc.cc \ + eh_arm.cc \ + eh_aux_runtime.cc \ + eh_call.cc \ + eh_catch.cc \ + eh_exception.cc \ + eh_globals.cc \ + eh_personality.cc \ + eh_ptr.cc \ + eh_term_handler.cc \ + eh_terminate.cc \ + eh_throw.cc \ + eh_type.cc \ + eh_unex_handler.cc \ + enum_type_info.cc \ + function_type_info.cc \ + fundamental_type_info.cc \ + guard.cc \ + guard_error.cc \ + hash_bytes.cc \ + nested_exception.cc \ + new_handler.cc \ + new_op.cc \ + new_opnt.cc \ + new_opv.cc \ + new_opvnt.cc \ + pbase_type_info.cc \ + pmem_type_info.cc \ + pointer_type_info.cc \ + pure.cc \ + si_class_type_info.cc \ + tinfo.cc \ + tinfo2.cc \ + vec.cc \ + vmi_class_type_info.cc \ + vterminate.cc + +libsupc___la_SOURCES = $(sources) $(c_sources) +libsupc__convenience_la_SOURCES = $(sources) $(c_sources) + +# 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. +AM_CXXFLAGS = \ + -fno-implicit-templates \ + $(LIBSUPCXX_PICFLAGS) \ + $(WARN_CXXFLAGS) \ + $(OPTIMIZE_CXXFLAGS) \ + $(CONFIG_CXXFLAGS) + +AM_MAKEFLAGS = \ + "gxx_include_dir=$(gxx_include_dir)" + + +# Use special rules for pulling things out of libiberty. These +# objects should be compiled with the "C" compiler, not the C++ +# compiler, and also should not use the C++ includes. +C_INCLUDES = -I.. -I$(toplevel_srcdir)/libiberty -I$(toplevel_srcdir)/include +C_COMPILE = \ + $(CC) $(DEFS) $(C_INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) + + +# LTCOMPILE is copied from LTCXXCOMPILE below. +LTCOMPILE = $(LIBTOOL) --tag CC --tag disable-shared $(LIBTOOLFLAGS) --mode=compile \ + $(CC) $(DEFS) $(C_INCLUDES) $(LIBSUPCXX_PICFLAGS) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) + + +# 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 $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) + +LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) + +# 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 $(LIBTOOLFLAGS) \ + --mode=link $(CXX) \ + $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@ + + +# Install notes +# We have to have rules modified from the default to counteract SUN make +# prepending each of $(*_HEADERS) with VPATH below. +stddir = $(gxx_include_dir) +bitsdir = $(gxx_include_dir)/bits +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .cc .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/fragment.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps libsupc++/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign --ignore-deps libsupc++/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +install-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(toolexeclibdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibdir)" + @list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(toolexeclibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(toolexeclibdir)"; \ + } + +uninstall-toolexeclibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(toolexeclibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(toolexeclibdir)/$$f"; \ + done + +clean-toolexeclibLTLIBRARIES: + -test -z "$(toolexeclib_LTLIBRARIES)" || rm -f $(toolexeclib_LTLIBRARIES) + @list='$(toolexeclib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libsupc++.la: $(libsupc___la_OBJECTS) $(libsupc___la_DEPENDENCIES) + $(CXXLINK) -rpath $(toolexeclibdir) $(libsupc___la_OBJECTS) $(libsupc___la_LIBADD) $(LIBS) +libsupc++convenience.la: $(libsupc__convenience_la_OBJECTS) $(libsupc__convenience_la_DEPENDENCIES) + $(CXXLINK) $(libsupc__convenience_la_OBJECTS) $(libsupc__convenience_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +.c.o: + $(COMPILE) -c $< + +.c.obj: + $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: + $(LTCOMPILE) -c -o $@ $< + +.cc.o: + $(CXXCOMPILE) -c -o $@ $< + +.cc.obj: + $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cc.lo: + $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(bitsdir)" "$(DESTDIR)$(stddir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-toolexeclibLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-bitsHEADERS install-stdHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-toolexeclibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-bitsHEADERS uninstall-stdHEADERS \ + uninstall-toolexeclibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES \ + clean-toolexeclibLTLIBRARIES ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags dvi dvi-am \ + html html-am info info-am install install-am \ + install-bitsHEADERS install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-stdHEADERS install-strip \ + install-toolexeclibLTLIBRARIES installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-bitsHEADERS uninstall-stdHEADERS \ + uninstall-toolexeclibLTLIBRARIES + + +cp-demangle.c: + rm -f $@ + $(LN_S) $(toplevel_srcdir)/libiberty/cp-demangle.c $@ +cp-demangle.lo: cp-demangle.c + $(LTCOMPILE) -DIN_GLIBCPP_V3 -Wno-error -c $< +cp-demangle.o: cp-demangle.c + $(C_COMPILE) -DIN_GLIBCPP_V3 -Wno-error -c $< + +nested_exception.lo: nested_exception.cc + $(LTCXXCOMPILE) -std=gnu++0x -c $< +nested_exception.o: nested_exception.cc + $(CXXCOMPILE) -std=gnu++0x -c $< + +install-stdHEADERS: $(std_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(stddir) + @list='$(std_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)$(stddir)/$$q"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(stddir)/$$q; \ + done + +install-bitsHEADERS: $(bits_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bitsdir) + @list='$(bits_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)$(bitsdir)/$$q"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(bitsdir)/$$q; \ + done + +uninstall-stdHEADERS: + @$(NORMAL_UNINSTALL) + list='$(std_HEADERS)'; for p in $$list; do \ + q=`echo $$p | sed -e 's,.*/,,'`; \ + rm -f $(DESTDIR)$(stddir)/$$q; \ + done + +uninstall-bitsHEADERS: + @$(NORMAL_UNINSTALL) + list='$(bits_HEADERS)'; for p in $$list; do \ + q=`echo $$p | sed -e 's,.*/,,'`; \ + rm -f $(DESTDIR)$(bitsdir)/$$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/libstdc++-v3/libsupc++/array_type_info.cc b/libstdc++-v3/libsupc++/array_type_info.cc new file mode 100644 index 000000000..17f911be8 --- /dev/null +++ b/libstdc++-v3/libsupc++/array_type_info.cc @@ -0,0 +1,33 @@ +// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007, +// 2009 Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include "tinfo.h" + +namespace __cxxabiv1 { + +__array_type_info:: +~__array_type_info () +{} + +} diff --git a/libstdc++-v3/libsupc++/atexit_arm.cc b/libstdc++-v3/libsupc++/atexit_arm.cc new file mode 100644 index 000000000..757d6c958 --- /dev/null +++ b/libstdc++-v3/libsupc++/atexit_arm.cc @@ -0,0 +1,39 @@ +// Copyright (C) 2007, 2009 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <cxxabi.h> + +#if defined(__arm__) && defined(__ARM_EABI__) + +namespace __aeabiv1 +{ + extern "C" int + __aeabi_atexit (void *object, + void (*destructor) (void *), + void *dso_handle) throw () + { + return abi::__cxa_atexit(destructor, object, dso_handle); + } +} // namespace __aeabiv1 + +#endif // defined(__arm__) && defined(__ARM_EABI__) diff --git a/libstdc++-v3/libsupc++/bad_alloc.cc b/libstdc++-v3/libsupc++/bad_alloc.cc new file mode 100644 index 000000000..16076cef9 --- /dev/null +++ b/libstdc++-v3/libsupc++/bad_alloc.cc @@ -0,0 +1,34 @@ +// Implementation file for the -*- C++ -*- dynamic memory management header. + +// Copyright (C) 2010 Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include "new" + +std::bad_alloc::~bad_alloc() throw() { } + +const char* +std::bad_alloc::what() const throw() +{ + return "std::bad_alloc"; +} diff --git a/libstdc++-v3/libsupc++/bad_cast.cc b/libstdc++-v3/libsupc++/bad_cast.cc new file mode 100644 index 000000000..2f56e4e82 --- /dev/null +++ b/libstdc++-v3/libsupc++/bad_cast.cc @@ -0,0 +1,37 @@ +// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007, +// 2009 Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <typeinfo> + +namespace std { + +bad_cast::~bad_cast() throw() { } + +const char* +bad_cast::what() const throw() +{ + return "std::bad_cast"; +} + +} // namespace std diff --git a/libstdc++-v3/libsupc++/bad_typeid.cc b/libstdc++-v3/libsupc++/bad_typeid.cc new file mode 100644 index 000000000..54d7ef59d --- /dev/null +++ b/libstdc++-v3/libsupc++/bad_typeid.cc @@ -0,0 +1,37 @@ +// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007, +// 2009 Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <typeinfo> + +namespace std { + +bad_typeid::~bad_typeid() throw() { } + +const char* +bad_typeid::what() const throw() +{ + return "std::bad_typeid"; +} + +} // namespace std diff --git a/libstdc++-v3/libsupc++/class_type_info.cc b/libstdc++-v3/libsupc++/class_type_info.cc new file mode 100644 index 000000000..9d40d0c6b --- /dev/null +++ b/libstdc++-v3/libsupc++/class_type_info.cc @@ -0,0 +1,111 @@ +// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007, +// 2009 Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include "tinfo.h" + +namespace __cxxabiv1 { + +__class_type_info:: +~__class_type_info () +{} + +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 <void *> (result.dst_ptr); + return true; +} + +__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; +} + +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 __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; +} + +} diff --git a/libstdc++-v3/libsupc++/cxxabi.h b/libstdc++-v3/libsupc++/cxxabi.h new file mode 100644 index 000000000..c93085a07 --- /dev/null +++ b/libstdc++-v3/libsupc++/cxxabi.h @@ -0,0 +1,626 @@ +// ABI Support -*- C++ -*- + +// Copyright (C) 2000, 2002, 2003, 2004, 2006, 2007, 2009, 2010, 2011 +// Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// Written by Nathan Sidwell, Codesourcery LLC, <nathan@codesourcery.com> + +/* This file declares the new abi entry points into the runtime. It is not + normally necessary for user programs to include this header, or use the + entry points directly. However, this header is available should that be + needed. + + Some of the entry points are intended for both C and C++, thus this header + is includable from both C and C++. Though the C++ specific parts are not + available in C, naturally enough. */ + +/** @file cxxabi.h + * The header provides an interface to the C++ ABI. + */ + +#ifndef _CXXABI_H +#define _CXXABI_H 1 + +#pragma GCC system_header + +#pragma GCC visibility push(default) + +#include <stddef.h> +#include <bits/c++config.h> +#include <bits/cxxabi_tweaks.h> +#include <bits/cxxabi_forced.h> + +#ifdef __cplusplus +namespace __cxxabiv1 +{ + extern "C" + { +#endif + + typedef __cxa_cdtor_return_type (*__cxa_cdtor_type)(void *); + + // Allocate array. + void* + __cxa_vec_new(size_t __element_count, size_t __element_size, + size_t __padding_size, __cxa_cdtor_type __constructor, + __cxa_cdtor_type __destructor); + + void* + __cxa_vec_new2(size_t __element_count, size_t __element_size, + size_t __padding_size, __cxa_cdtor_type __constructor, + __cxa_cdtor_type __destructor, void *(*__alloc) (size_t), + void (*__dealloc) (void*)); + + void* + __cxa_vec_new3(size_t __element_count, size_t __element_size, + size_t __padding_size, __cxa_cdtor_type __constructor, + __cxa_cdtor_type __destructor, void *(*__alloc) (size_t), + void (*__dealloc) (void*, size_t)); + + // Construct array. + __cxa_vec_ctor_return_type + __cxa_vec_ctor(void* __array_address, size_t __element_count, + size_t __element_size, __cxa_cdtor_type __constructor, + __cxa_cdtor_type __destructor); + + __cxa_vec_ctor_return_type + __cxa_vec_cctor(void* __dest_array, void* __src_array, + size_t __element_count, size_t __element_size, + __cxa_cdtor_return_type (*__constructor) (void*, void*), + __cxa_cdtor_type __destructor); + + // Destruct array. + void + __cxa_vec_dtor(void* __array_address, size_t __element_count, + size_t __element_size, __cxa_cdtor_type __destructor); + + void + __cxa_vec_cleanup(void* __array_address, size_t __element_count, size_t __s, + __cxa_cdtor_type __destructor) _GLIBCXX_NOTHROW; + + // Destruct and release array. + void + __cxa_vec_delete(void* __array_address, size_t __element_size, + size_t __padding_size, __cxa_cdtor_type __destructor); + + void + __cxa_vec_delete2(void* __array_address, size_t __element_size, + size_t __padding_size, __cxa_cdtor_type __destructor, + void (*__dealloc) (void*)); + + void + __cxa_vec_delete3(void* __array_address, size_t __element_size, + size_t __padding_size, __cxa_cdtor_type __destructor, + void (*__dealloc) (void*, size_t)); + + int + __cxa_guard_acquire(__guard*); + + void + __cxa_guard_release(__guard*) _GLIBCXX_NOTHROW; + + void + __cxa_guard_abort(__guard*) _GLIBCXX_NOTHROW; + + // Pure virtual functions. + void + __cxa_pure_virtual(void) __attribute__ ((__noreturn__)); + + // Exception handling. + void + __cxa_bad_cast(); + + void + __cxa_bad_typeid(); + + // DSO destruction. + int + __cxa_atexit(void (*)(void*), void*, void*) _GLIBCXX_NOTHROW; + + int + __cxa_finalize(void*); + + + /** + * @brief Demangling routine. + * ABI-mandated entry point in the C++ runtime library for demangling. + * + * @param __mangled_name A NUL-terminated character string + * containing the name to be demangled. + * + * @param __output_buffer A region of memory, allocated with + * malloc, of @a *__length bytes, into which the demangled name is + * stored. If @a __output_buffer is not long enough, it is + * expanded using realloc. @a __output_buffer may instead be NULL; + * in that case, the demangled name is placed in a region of memory + * allocated with malloc. + * + * @param __length If @a __length is non-NULL, the length of the + * buffer containing the demangled name is placed in @a *__length. + * + * @param __status @a *__status is set to one of the following values: + * 0: The demangling operation succeeded. + * -1: A memory allocation failure occurred. + * -2: @a mangled_name is not a valid name under the C++ ABI mangling rules. + * -3: One of the arguments is invalid. + * + * @return A pointer to the start of the NUL-terminated demangled + * name, or NULL if the demangling fails. The caller is + * responsible for deallocating this memory using @c free. + * + * The demangling is performed using the C++ ABI mangling rules, + * with GNU extensions. For example, this function is used in + * __gnu_cxx::__verbose_terminate_handler. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt12ch39.html + * for other examples of use. + * + * @note The same demangling functionality is available via + * libiberty (@c <libiberty/demangle.h> and @c libiberty.a) in GCC + * 3.1 and later, but that requires explicit installation (@c + * --enable-install-libiberty) and uses a different API, although + * the ABI is unchanged. + */ + char* + __cxa_demangle(const char* __mangled_name, char* __output_buffer, + size_t* __length, int* __status); +#ifdef __cplusplus + } +} // namespace __cxxabiv1 +#endif + +#ifdef __cplusplus + +#include <typeinfo> + +namespace __cxxabiv1 +{ + // Type information for int, float etc. + class __fundamental_type_info : public std::type_info + { + public: + explicit + __fundamental_type_info(const char* __n) : std::type_info(__n) { } + + virtual + ~__fundamental_type_info(); + }; + + // Type information for array objects. + class __array_type_info : public std::type_info + { + public: + explicit + __array_type_info(const char* __n) : std::type_info(__n) { } + + virtual + ~__array_type_info(); + }; + + // Type information for functions (both member and non-member). + class __function_type_info : public std::type_info + { + public: + explicit + __function_type_info(const char* __n) : std::type_info(__n) { } + + virtual + ~__function_type_info(); + + protected: + // Implementation defined member function. + virtual bool + __is_function_p() const; + }; + + // Type information for enumerations. + class __enum_type_info : public std::type_info + { + public: + explicit + __enum_type_info(const char* __n) : std::type_info(__n) { } + + virtual + ~__enum_type_info(); + }; + + // Common type information for simple pointers and pointers to member. + class __pbase_type_info : public std::type_info + { + public: + unsigned int __flags; // Qualification of the target object. + const std::type_info* __pointee; // Type of pointed to object. + + explicit + __pbase_type_info(const char* __n, int __quals, + const std::type_info* __type) + : std::type_info(__n), __flags(__quals), __pointee(__type) + { } + + virtual + ~__pbase_type_info(); + + // Implementation defined type. + enum __masks + { + __const_mask = 0x1, + __volatile_mask = 0x2, + __restrict_mask = 0x4, + __incomplete_mask = 0x8, + __incomplete_class_mask = 0x10 + }; + + protected: + __pbase_type_info(const __pbase_type_info&); + + __pbase_type_info& + operator=(const __pbase_type_info&); + + // Implementation defined member functions. + virtual bool + __do_catch(const std::type_info* __thr_type, void** __thr_obj, + unsigned int __outer) const; + + 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 + { + public: + explicit + __pointer_type_info(const char* __n, int __quals, + const std::type_info* __type) + : __pbase_type_info (__n, __quals, __type) { } + + + virtual + ~__pointer_type_info(); + + protected: + // Implementation defined member functions. + virtual bool + __is_pointer_p() const; + + virtual bool + __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, + unsigned __outer) const; + }; + + class __class_type_info; + + // Type information for a pointer to member variable. + class __pointer_to_member_type_info : public __pbase_type_info + { + public: + __class_type_info* __context; // Class of the member. + + 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(__klass) { } + + virtual + ~__pointer_to_member_type_info(); + + protected: + __pointer_to_member_type_info(const __pointer_to_member_type_info&); + + __pointer_to_member_type_info& + operator=(const __pointer_to_member_type_info&); + + // Implementation defined member function. + virtual bool + __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, + unsigned __outer) const; + }; + + // Helper class for __vmi_class_type. + class __base_class_type_info + { + public: + const __class_type_info* __base_type; // Base class type. + long __offset_flags; // Offset and info. + + enum __offset_flags_masks + { + __virtual_mask = 0x1, + __public_mask = 0x2, + __hwm_bit = 2, + __offset_shift = 8 // Bits to shift offset. + }; + + // Implementation defined member functions. + bool + __is_virtual_p() const + { return __offset_flags & __virtual_mask; } + + bool + __is_public_p() const + { return __offset_flags & __public_mask; } + + ptrdiff_t + __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_t>(__offset_flags) >> __offset_shift; + } + }; + + // Type information for a class. + class __class_type_info : public std::type_info + { + public: + explicit + __class_type_info (const char *__n) : type_info(__n) { } + + virtual + ~__class_type_info (); + + // Implementation defined types. + // The type 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 + { + // We have no idea. + __unknown = 0, + + // Not contained within us (in some circumstances this might + // mean not contained publicly) + __not_contained, + + // Contained ambiguously. + __contained_ambig, + + // Via a virtual path. + __contained_virtual_mask = __base_class_type_info::__virtual_mask, + + // Via a public path. + __contained_public_mask = __base_class_type_info::__public_mask, + + // Contained within us. + __contained_mask = 1 << __base_class_type_info::__hwm_bit, + + __contained_private = __contained_mask, + __contained_public = __contained_mask | __contained_public_mask + }; + + struct __upcast_result; + struct __dyncast_result; + + protected: + // Implementation defined member functions. + virtual bool + __do_upcast(const __class_type_info* __dst_type, void**__obj_ptr) const; + + 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; + + // Indicate whether SRC_PTR of type SRC_TYPE is contained publicly + // within OBJ_PTR. OBJ_PTR points to a base object of our type, + // which is the destination type. SRC2DST indicates how SRC + // objects might be contained within this type. If SRC_PTR is one + // of our SRC_TYPE bases, indicate the virtuality. Returns + // not_contained for non containment or private containment. + inline __sub_kind + __find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, + const __class_type_info* __src_type, + const void* __src_ptr) const; + + // Helper for dynamic cast. ACCESS_PATH gives the access from the + // most derived object to this base. DST_TYPE indicates the + // desired type we want. OBJ_PTR points to a base of our type + // within the complete object. SRC_TYPE indicates the static type + // started from and SRC_PTR points to that base within the most + // derived object. Fill in RESULT with what we find. Return true + // if we have located an ambiguous match. + virtual bool + __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, + const __class_type_info* __dst_type, const void* __obj_ptr, + const __class_type_info* __src_type, const void* __src_ptr, + __dyncast_result& __result) const; + + // Helper for find_public_subobj. SRC2DST indicates how SRC_TYPE + // bases are inherited by the type started from -- which is not + // necessarily the current type. The current type will be a base + // of the destination type. OBJ_PTR points to the current base. + virtual __sub_kind + __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, + const __class_type_info* __src_type, + const void* __src_ptr) const; + }; + + // Type information for a class with a single non-virtual base. + class __si_class_type_info : public __class_type_info + { + public: + const __class_type_info* __base_type; + + explicit + __si_class_type_info(const char *__n, const __class_type_info *__base) + : __class_type_info(__n), __base_type(__base) { } + + virtual + ~__si_class_type_info(); + + protected: + __si_class_type_info(const __si_class_type_info&); + + __si_class_type_info& + operator=(const __si_class_type_info&); + + // Implementation defined member functions. + virtual bool + __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, + const __class_type_info* __dst_type, const void* __obj_ptr, + const __class_type_info* __src_type, const void* __src_ptr, + __dyncast_result& __result) const; + + virtual __sub_kind + __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, + const __class_type_info* __src_type, + const void* __sub_ptr) const; + + virtual bool + __do_upcast(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 + { + public: + unsigned int __flags; // Details about the class hierarchy. + unsigned int __base_count; // Number of direct 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. + __base_class_type_info __base_info[1]; // Array of bases. + + explicit + __vmi_class_type_info(const char* __n, int ___flags) + : __class_type_info(__n), __flags(___flags), __base_count(0) { } + + virtual + ~__vmi_class_type_info(); + + // Implementation defined types. + enum __flags_masks + { + __non_diamond_repeat_mask = 0x1, // Distinct instance of repeated base. + __diamond_shaped_mask = 0x2, // Diamond shaped multiple inheritance. + __flags_unknown_mask = 0x10 + }; + + protected: + // Implementation defined member functions. + virtual bool + __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, + const __class_type_info* __dst_type, const void* __obj_ptr, + const __class_type_info* __src_type, const void* __src_ptr, + __dyncast_result& __result) const; + + virtual __sub_kind + __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, + const __class_type_info* __src_type, + const void* __src_ptr) const; + + virtual bool + __do_upcast(const __class_type_info* __dst, const void* __obj, + __upcast_result& __restrict __result) const; + }; + + // Dynamic cast runtime. + // src2dst has the following possible values + // >-1: 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 + extern "C" void* + __dynamic_cast(const void* __src_ptr, // Starting object. + const __class_type_info* __src_type, // Static type of object. + const __class_type_info* __dst_type, // Desired target type. + ptrdiff_t __src2dst); // How src and dst are related. + + + // 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() _GLIBCXX_NOTHROW __attribute__ ((__pure__)); + + // A magic placeholder class that can be caught by reference + // to recognize foreign exceptions. + class __foreign_exception + { + virtual ~__foreign_exception() _GLIBCXX_NOTHROW; + virtual void __pure_dummy() = 0; // prevent catch by value + }; + +} // namespace __cxxabiv1 + +/** @namespace abi + * @brief The cross-vendor C++ Application Binary Interface. A + * namespace alias to __cxxabiv1, but user programs should use the + * alias 'abi'. + * + * A brief overview of an ABI is given in the libstdc++ FAQ, question + * 5.8 (you may have a copy of the FAQ locally, or you can view the online + * version at http://gcc.gnu.org/onlinedocs/libstdc++/faq/index.html#5_8). + * + * GCC subscribes to a cross-vendor ABI for C++, sometimes + * called the IA64 ABI because it happens to be the native ABI for that + * platform. It is summarized at http://www.codesourcery.com/cxx-abi/ + * along with the current specification. + * + * For users of GCC greater than or equal to 3.x, entry points are + * available in <cxxabi.h>, which notes, <em>'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.'</em> +*/ +namespace abi = __cxxabiv1; + +namespace __gnu_cxx +{ + /** + * @brief Exception thrown by __cxa_guard_acquire. + * @ingroup exceptions + * + * 6.7[stmt.dcl]/4: If control re-enters the declaration (recursively) + * while the object is being initialized, the behavior is undefined. + * + * Since we already have a library function to handle locking, we might + * as well check for this situation and throw an exception. + * We use the second byte of the guard variable to remember that we're + * in the middle of an initialization. + */ + class recursive_init_error: public std::exception + { + public: + recursive_init_error() throw() { } + virtual ~recursive_init_error() throw (); + }; +} +#endif // __cplusplus + +#pragma GCC visibility pop + +#endif // __CXXABI_H diff --git a/libstdc++-v3/libsupc++/cxxabi_forced.h b/libstdc++-v3/libsupc++/cxxabi_forced.h new file mode 100644 index 000000000..c45ce799d --- /dev/null +++ b/libstdc++-v3/libsupc++/cxxabi_forced.h @@ -0,0 +1,60 @@ +// cxxabi.h subset for cancellation -*- C++ -*- + +// Copyright (C) 2007, 2009, 2010, 2011 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file bits/cxxabi_forced.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{cxxabi.h} + */ + +#ifndef _CXXABI_FORCED_H +#define _CXXABI_FORCED_H 1 + +#pragma GCC system_header + +#pragma GCC visibility push(default) + +#ifdef __cplusplus +namespace __cxxabiv1 +{ + /** + * @brief Thrown as part of forced unwinding. + * @ingroup exceptions + * + * A magic placeholder class that can be caught by reference to + * recognize forced unwinding. + */ + class __forced_unwind + { + virtual ~__forced_unwind() throw(); + + // Prevent catch by value. + virtual void __pure_dummy() = 0; + }; +} +#endif // __cplusplus + +#pragma GCC visibility pop + +#endif // __CXXABI_FORCED_H diff --git a/libstdc++-v3/libsupc++/del_op.cc b/libstdc++-v3/libsupc++/del_op.cc new file mode 100644 index 000000000..86d4c1e29 --- /dev/null +++ b/libstdc++-v3/libsupc++/del_op.cc @@ -0,0 +1,48 @@ +// Boilerplate support routines for -*- C++ -*- dynamic memory management. + +// Copyright (C) 1997, 1998, 1999, 2000, 2004, 2007, 2009 Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <bits/c++config.h> + +#if !_GLIBCXX_HOSTED +// A freestanding C runtime may not provide "free" -- but there is no +// other reasonable way to implement "operator delete". +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + extern "C" void free(void*); +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace +#else +# include <cstdlib> +#endif + +#include "new" + +_GLIBCXX_WEAK_DEFINITION void +operator delete(void* ptr) throw () +{ + if (ptr) + std::free(ptr); +} diff --git a/libstdc++-v3/libsupc++/del_opnt.cc b/libstdc++-v3/libsupc++/del_opnt.cc new file mode 100644 index 000000000..75051d5be --- /dev/null +++ b/libstdc++-v3/libsupc++/del_opnt.cc @@ -0,0 +1,36 @@ +// Boilerplate support routines for -*- C++ -*- dynamic memory management. + +// Copyright (C) 1997, 1998, 1999, 2000, 2004, 2009 Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <bits/c++config.h> +#include "new" + +extern "C" void free (void *); + +_GLIBCXX_WEAK_DEFINITION void +operator delete (void *ptr, const std::nothrow_t&) throw () +{ + if (ptr) + free (ptr); +} diff --git a/libstdc++-v3/libsupc++/del_opv.cc b/libstdc++-v3/libsupc++/del_opv.cc new file mode 100644 index 000000000..c56df07d9 --- /dev/null +++ b/libstdc++-v3/libsupc++/del_opv.cc @@ -0,0 +1,33 @@ +// Boilerplate support routines for -*- C++ -*- dynamic memory management. + +// Copyright (C) 1997, 1998, 1999, 2000, 2004, 2009 Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <bits/c++config.h> +#include "new" + +_GLIBCXX_WEAK_DEFINITION void +operator delete[] (void *ptr) throw () +{ + ::operator delete (ptr); +} diff --git a/libstdc++-v3/libsupc++/del_opvnt.cc b/libstdc++-v3/libsupc++/del_opvnt.cc new file mode 100644 index 000000000..fec64953e --- /dev/null +++ b/libstdc++-v3/libsupc++/del_opvnt.cc @@ -0,0 +1,33 @@ +// Boilerplate support routines for -*- C++ -*- dynamic memory management. + +// Copyright (C) 1997, 1998, 1999, 2000, 2004, 2009 Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <bits/c++config.h> +#include "new" + +_GLIBCXX_WEAK_DEFINITION void +operator delete[] (void *ptr, const std::nothrow_t&) throw () +{ + ::operator delete (ptr); +} diff --git a/libstdc++-v3/libsupc++/dyncast.cc b/libstdc++-v3/libsupc++/dyncast.cc new file mode 100644 index 000000000..cb97bc50e --- /dev/null +++ b/libstdc++-v3/libsupc++/dyncast.cc @@ -0,0 +1,86 @@ +// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007, 2009 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include "tinfo.h" + +namespace __cxxabiv1 { + + +// this is the external interface to the dynamic cast machinery +/* sub: source address to be adjusted; nonnull, and since the + * source object is polymorphic, *(void**)sub is a virtual pointer. + * src: static type of the source object. + * dst: destination type (the "T" in "dynamic_cast<T>(v)"). + * src2dst_offset: a static hint about the location of the + * source subobject with respect to the complete object; + * special negative values are: + * -1: no hint + * -2: src is not a public base of dst + * -3: src is a multiple public base type but never a + * virtual base type + * otherwise, the src type is a unique public nonvirtual + * base type of dst at offset src2dst_offset from the + * origin of dst. */ +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 <const void *const *> (src_ptr); + const vtable_prefix *prefix = + adjust_pointer <vtable_prefix> (vtable, + -offsetof (vtable_prefix, origin)); + const void *whole_ptr = + adjust_pointer <void> (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 <void *> (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 <void *> (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 <void *> (result.dst_ptr); + // Must be an invalid down cast, or the cross cast wasn't bettered + return NULL; +} + +} diff --git a/libstdc++-v3/libsupc++/eh_alloc.cc b/libstdc++-v3/libsupc++/eh_alloc.cc new file mode 100644 index 000000000..818af0fe1 --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_alloc.cc @@ -0,0 +1,220 @@ +// -*- C++ -*- Allocate exception objects. +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 +// Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// This is derived from the C++ ABI for IA-64. Where we diverge +// for cross-architecture compatibility are noted with "@@@". + +#include <bits/c++config.h> +#include <cstdlib> +#if _GLIBCXX_HOSTED +#include <cstring> +#endif +#include <climits> +#include <exception> +#include "unwind-cxx.h" +#include <ext/concurrence.h> + +#if _GLIBCXX_HOSTED +using std::free; +using std::malloc; +using std::memset; +#else +// In a freestanding environment, these functions may not be available +// -- but for now, we assume that they are. +extern "C" void *malloc (std::size_t); +extern "C" void free(void *); +extern "C" void *memset (void *, int, std::size_t); +#endif + +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; + +static __cxa_dependent_exception dependents_buffer[EMERGENCY_OBJ_COUNT]; +static bitmask_type dependents_used; + +namespace +{ + // A single mutex controlling emergency allocations. + __gnu_cxx::__mutex emergency_mutex; +} + +extern "C" void * +__cxxabiv1::__cxa_allocate_exception(std::size_t thrown_size) throw() +{ + void *ret; + + thrown_size += sizeof (__cxa_refcounted_exception); + ret = malloc (thrown_size); + + if (! ret) + { + __gnu_cxx::__scoped_lock sentry(emergency_mutex); + + 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:; + + if (!ret) + std::terminate (); + } + + // We have an uncaught exception as soon as we allocate memory. This + // yields uncaught_exception() true during the copy-constructor that + // initializes the exception object. See Issue 475. + __cxa_eh_globals *globals = __cxa_get_globals (); + globals->uncaughtExceptions += 1; + + memset (ret, 0, sizeof (__cxa_refcounted_exception)); + + return (void *)((char *)ret + sizeof (__cxa_refcounted_exception)); +} + + +extern "C" void +__cxxabiv1::__cxa_free_exception(void *vptr) throw() +{ + char *base = (char *) emergency_buffer; + char *ptr = (char *) vptr; + if (ptr >= base + && ptr < base + sizeof (emergency_buffer)) + { + const unsigned int which + = (unsigned) (ptr - base) / EMERGENCY_OBJ_SIZE; + + __gnu_cxx::__scoped_lock sentry(emergency_mutex); + emergency_used &= ~((bitmask_type)1 << which); + } + else + free (ptr - sizeof (__cxa_refcounted_exception)); +} + + +extern "C" __cxa_dependent_exception* +__cxxabiv1::__cxa_allocate_dependent_exception() throw() +{ + __cxa_dependent_exception *ret; + + ret = static_cast<__cxa_dependent_exception*> + (malloc (sizeof (__cxa_dependent_exception))); + + if (!ret) + { + __gnu_cxx::__scoped_lock sentry(emergency_mutex); + + bitmask_type used = dependents_used; + unsigned int which = 0; + + while (used & 1) + { + used >>= 1; + if (++which >= EMERGENCY_OBJ_COUNT) + goto failed; + } + + dependents_used |= (bitmask_type)1 << which; + ret = &dependents_buffer[which]; + + failed:; + + if (!ret) + std::terminate (); + } + + // We have an uncaught exception as soon as we allocate memory. This + // yields uncaught_exception() true during the copy-constructor that + // initializes the exception object. See Issue 475. + __cxa_eh_globals *globals = __cxa_get_globals (); + globals->uncaughtExceptions += 1; + + memset (ret, 0, sizeof (__cxa_dependent_exception)); + + return ret; +} + + +extern "C" void +__cxxabiv1::__cxa_free_dependent_exception + (__cxa_dependent_exception *vptr) throw() +{ + char *base = (char *) dependents_buffer; + char *ptr = (char *) vptr; + if (ptr >= base + && ptr < base + sizeof (dependents_buffer)) + { + const unsigned int which + = (unsigned) (ptr - base) / sizeof (__cxa_dependent_exception); + + __gnu_cxx::__scoped_lock sentry(emergency_mutex); + dependents_used &= ~((bitmask_type)1 << which); + } + else + free (vptr); +} diff --git a/libstdc++-v3/libsupc++/eh_arm.cc b/libstdc++-v3/libsupc++/eh_arm.cc new file mode 100644 index 000000000..f0acb705e --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_arm.cc @@ -0,0 +1,182 @@ +// -*- C++ -*- ARM specific Exception handling support routines. +// Copyright (C) 2004, 2005, 2008, 2009, 2010 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. +// +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <cxxabi.h> +#include "unwind-cxx.h" + +#ifdef __ARM_EABI_UNWINDER__ + +using namespace __cxxabiv1; + + +// 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. + +extern "C" __cxa_type_match_result +__cxa_type_match(_Unwind_Exception* ue_header, + const std::type_info* catch_type, + bool is_reference __attribute__((__unused__)), + void** thrown_ptr_p) +{ + bool forced_unwind = __is_gxx_forced_unwind_class(ue_header->exception_class); + bool foreign_exception = !forced_unwind && !__is_gxx_exception_class(ue_header->exception_class); + bool dependent_exception = + __is_dependent_exception(ue_header->exception_class); + __cxa_exception* xh = __get_exception_header_from_ue(ue_header); + __cxa_dependent_exception *dx = __get_dependent_exception_from_ue(ue_header); + const std::type_info* throw_type; + + if (forced_unwind) + throw_type = &typeid(abi::__forced_unwind); + else if (foreign_exception) + throw_type = &typeid(abi::__foreign_exception); + else if (dependent_exception) + throw_type = __get_exception_header_from_obj + (dx->primaryException)->exceptionType; + else + throw_type = xh->exceptionType; + + 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; + + if (typeid(*catch_type) == typeid (typeid(void*))) + { + const __pointer_type_info *catch_pointer_type = + static_cast<const __pointer_type_info *> (catch_type); + const __pointer_type_info *throw_pointer_type = + static_cast<const __pointer_type_info *> (throw_type); + + if (typeid (*catch_pointer_type->__pointee) != typeid (void) + && (*catch_pointer_type->__pointee != + *throw_pointer_type->__pointee)) + return ctm_succeeded_with_ptr_to_base; + } + + return ctm_succeeded; + } + + return ctm_failed; +} + +// ABI defined routine called at the start of a cleanup handler. +extern "C" bool +__cxa_begin_cleanup(_Unwind_Exception* ue_header) +{ + __cxa_eh_globals *globals = __cxa_get_globals(); + __cxa_exception *header = __get_exception_header_from_ue(ue_header); + bool native = __is_gxx_exception_class(header->unwindHeader.exception_class); + + + if (native) + { + header->propagationCount++; + // Add it to the chain if this is the first time we've seen this + // exception. + if (header->propagationCount == 1) + { + header->nextPropagatingException = globals->propagatingExceptions; + globals->propagatingExceptions = header; + } + } + else + { + // Remember the exception object, so end_cleanup can return it. + // These cannot be stacked, so we must abort if we already have + // a propagating exception. + if (globals->propagatingExceptions) + std::terminate (); + globals->propagatingExceptions = header; + } + + return true; +} + +// Do the work for __cxa_end_cleanup. Returns the currently propagating +// exception object. +extern "C" _Unwind_Exception * +__gnu_end_cleanup(void) +{ + __cxa_exception *header; + __cxa_eh_globals *globals = __cxa_get_globals(); + + header = globals->propagatingExceptions; + + // Check something hasn't gone horribly wrong. + if (!header) + std::terminate(); + + if (__is_gxx_exception_class(header->unwindHeader.exception_class)) + { + header->propagationCount--; + if (header->propagationCount == 0) + { + // Remove exception from chain. + globals->propagatingExceptions = header->nextPropagatingException; + header->nextPropagatingException = NULL; + } + } + else + globals->propagatingExceptions = NULL; + + return &header->unwindHeader; +} + +// Assembly wrapper to call __gnu_end_cleanup without clobbering r1-r3. +// Also push r4 to preserve stack alignment. +#ifdef __thumb__ +asm (" .pushsection .text.__cxa_end_cleanup\n" +" .global __cxa_end_cleanup\n" +" .type __cxa_end_cleanup, \"function\"\n" +" .thumb_func\n" +"__cxa_end_cleanup:\n" +" push\t{r1, r2, r3, r4}\n" +" bl\t__gnu_end_cleanup\n" +" pop\t{r1, r2, r3, r4}\n" +" bl\t_Unwind_Resume @ Never returns\n" +" .popsection\n"); +#else +asm (" .pushsection .text.__cxa_end_cleanup\n" +" .global __cxa_end_cleanup\n" +" .type __cxa_end_cleanup, \"function\"\n" +"__cxa_end_cleanup:\n" +" stmfd\tsp!, {r1, r2, r3, r4}\n" +" bl\t__gnu_end_cleanup\n" +" ldmfd\tsp!, {r1, r2, r3, r4}\n" +" bl\t_Unwind_Resume @ Never returns\n" +" .popsection\n"); +#endif + +#endif diff --git a/libstdc++-v3/libsupc++/eh_aux_runtime.cc b/libstdc++-v3/libsupc++/eh_aux_runtime.cc new file mode 100644 index 000000000..c6abe3546 --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_aux_runtime.cc @@ -0,0 +1,51 @@ +// -*- C++ -*- Common throw conditions. +// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2009, 2011 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. +// +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include "typeinfo" +#include "exception" +#include <cstdlib> +#include "unwind-cxx.h" +#include <bits/exception_defines.h> + +extern "C" void +__cxxabiv1::__cxa_bad_cast () +{ +#ifdef __EXCEPTIONS + throw std::bad_cast(); +#else + std::abort(); +#endif +} + +extern "C" void +__cxxabiv1::__cxa_bad_typeid () +{ +#ifdef __EXCEPTIONS + throw std::bad_typeid(); +#else + std::abort(); +#endif +} + diff --git a/libstdc++-v3/libsupc++/eh_call.cc b/libstdc++-v3/libsupc++/eh_call.cc new file mode 100644 index 000000000..f519f35f0 --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_call.cc @@ -0,0 +1,158 @@ +// -*- C++ -*- Helpers for calling unextected and terminate +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, +// 2011 +// Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <bits/c++config.h> +#include <cstdlib> +#include <bits/exception_defines.h> +#include "unwind-cxx.h" + +using namespace __cxxabiv1; + +#include "unwind-pe.h" + + +// Helper routine for when the exception handling code needs to call +// terminate. + +extern "C" void +__cxa_call_terminate(_Unwind_Exception* ue_header) throw () +{ + + if (ue_header) + { + // terminate is classed as a catch handler. + __cxa_begin_catch(ue_header); + + // Call the terminate handler that was in effect when we threw this + // exception. */ + if (__is_gxx_exception_class(ue_header->exception_class)) + { + __cxa_exception* xh; + + xh = __get_exception_header_from_ue(ue_header); + __terminate(xh->terminateHandler); + } + } + /* Call the global routine if we don't have anything better. */ + std::terminate(); +} + + +#ifdef __ARM_EABI_UNWINDER__ +// The ARM EABI __cxa_call_unexpected has the same semantics as the generic +// routine, but the exception specification has a different format. +extern "C" void +__cxa_call_unexpected(void* exc_obj_in) +{ + _Unwind_Exception* exc_obj + = reinterpret_cast<_Unwind_Exception*>(exc_obj_in); + + int rtti_count = 0; + _Unwind_Word rtti_stride = 0; + _Unwind_Word* rtti_list = NULL; + bool foreign_exception; + std::unexpected_handler unexpectedHandler = NULL; + std::terminate_handler terminateHandler = NULL; + __cxa_exception* xh; + if (__is_gxx_exception_class(exc_obj->exception_class)) + { + // Save data from the EO, which may be clobbered by _cxa_begin_catch. + xh = __get_exception_header_from_ue(exc_obj); + unexpectedHandler = xh->unexpectedHandler; + terminateHandler = xh->terminateHandler; + rtti_count = exc_obj->barrier_cache.bitpattern[1]; + + rtti_stride = exc_obj->barrier_cache.bitpattern[3]; + rtti_list = (_Unwind_Word*) exc_obj->barrier_cache.bitpattern[4]; + foreign_exception = false; + } + else + foreign_exception = true; + + /* This must be called after extracting data from the EO, but before + calling unexpected(). */ + __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; + + + __try + { + if (foreign_exception) + std::unexpected(); + else + __unexpected(unexpectedHandler); + } + __catch(...) + { + /* See if the new exception matches the rtti list. */ + if (foreign_exception) + std::terminate(); + + // Get the exception thrown from unexpected. + + __cxa_eh_globals* globals = __cxa_get_globals_fast(); + __cxa_exception* new_xh = globals->caughtExceptions; + void* new_ptr = __get_object_from_ambiguous_exception (new_xh); + const std::type_info* catch_type; + int n; + bool bad_exception_allowed = false; + const std::type_info& bad_exc = typeid(std::bad_exception); + + // Check the new exception against the rtti list + for (n = 0; n < rtti_count; n++) + { + _Unwind_Word offset; + + offset = (_Unwind_Word) &rtti_list[n * (rtti_stride >> 2)]; + offset = _Unwind_decode_target2(offset); + catch_type = (const std::type_info*) (offset); + + if (__cxa_type_match(&new_xh->unwindHeader, catch_type, false, + &new_ptr) != ctm_failed) + __throw_exception_again; + + if (catch_type->__do_catch(&bad_exc, 0, 1)) + bad_exception_allowed = true; + } + + // If the exception spec allows std::bad_exception, throw that. +#ifdef __EXCEPTIONS + if (bad_exception_allowed) + throw std::bad_exception(); +#endif + + // Otherwise, die. + __terminate(terminateHandler); + } +} +#endif // __ARM_EABI_UNWINDER__ diff --git a/libstdc++-v3/libsupc++/eh_catch.cc b/libstdc++-v3/libsupc++/eh_catch.cc new file mode 100644 index 000000000..567222aa5 --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_catch.cc @@ -0,0 +1,138 @@ +// -*- C++ -*- Exception handling routines for catching. +// Copyright (C) 2001, 2003, 2004, 2009 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <cstdlib> +#include "unwind-cxx.h" + +using namespace __cxxabiv1; + +extern "C" void * +__cxxabiv1::__cxa_get_exception_ptr(void *exc_obj_in) throw() +{ + _Unwind_Exception *exceptionObject + = reinterpret_cast <_Unwind_Exception *>(exc_obj_in); + + return __gxx_caught_object(exceptionObject); +} + +extern "C" void * +__cxxabiv1::__cxa_begin_catch (void *exc_obj_in) throw() +{ + _Unwind_Exception *exceptionObject + = reinterpret_cast <_Unwind_Exception *>(exc_obj_in); + __cxa_eh_globals *globals = __cxa_get_globals (); + __cxa_exception *prev = globals->caughtExceptions; + __cxa_exception *header = __get_exception_header_from_ue (exceptionObject); + void* objectp; + + // Foreign exceptions can't be stacked here. If the exception stack is + // empty, then fine. Otherwise we really have no choice but to terminate. + // Note that this use of "header" is a lie. It's fine so long as we only + // examine header->unwindHeader though. + if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) + { + if (prev != 0) + std::terminate (); + + // Remember for end_catch and rethrow. + globals->caughtExceptions = header; + + // ??? No sensible value to return; we don't know what the + // object is, much less where it is in relation to the header. + return 0; + } + + int count = header->handlerCount; + // Count is less than zero if this exception was rethrown from an + // immediately enclosing region. + if (count < 0) + count = -count + 1; + else + count += 1; + header->handlerCount = count; + globals->uncaughtExceptions -= 1; + + if (header != prev) + { + header->nextException = prev; + globals->caughtExceptions = header; + } + + objectp = __gxx_caught_object(exceptionObject); +#ifdef __ARM_EABI_UNWINDER__ + _Unwind_Complete(exceptionObject); +#endif + return objectp; +} + + +extern "C" void +__cxxabiv1::__cxa_end_catch () +{ + __cxa_eh_globals *globals = __cxa_get_globals_fast (); + __cxa_exception *header = globals->caughtExceptions; + + // A rethrow of a foreign exception will be removed from the + // the exception stack immediately by __cxa_rethrow. + if (!header) + return; + + // A foreign exception couldn't have been stacked (see above), + // so by definition processing must be complete. + if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) + { + globals->caughtExceptions = 0; + _Unwind_DeleteException (&header->unwindHeader); + return; + } + + 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->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::terminate (); + + header->handlerCount = count; +} + + +bool +std::uncaught_exception() throw() +{ + __cxa_eh_globals *globals = __cxa_get_globals (); + return globals->uncaughtExceptions != 0; +} diff --git a/libstdc++-v3/libsupc++/eh_exception.cc b/libstdc++-v3/libsupc++/eh_exception.cc new file mode 100644 index 000000000..2f752b310 --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_exception.cc @@ -0,0 +1,52 @@ +// -*- C++ -*- std::exception implementation. +// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +// 2003, 2004, 2005, 2006, 2007, 2009 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include "typeinfo" +#include "exception" +#include <cxxabi.h> + +std::exception::~exception() throw() { } + +std::bad_exception::~bad_exception() throw() { } + +abi::__forced_unwind::~__forced_unwind() throw() { } + +abi::__foreign_exception::~__foreign_exception() throw() { } + +const char* +std::exception::what() const throw() +{ + // NB: Another elegant option would be returning typeid(*this).name() + // and not overriding what() in bad_exception, bad_alloc, etc. In + // that case, however, mangled names would be returned, PR 14493. + return "std::exception"; +} + +const char* +std::bad_exception::what() const throw() +{ + return "std::bad_exception"; +} diff --git a/libstdc++-v3/libsupc++/eh_globals.cc b/libstdc++-v3/libsupc++/eh_globals.cc new file mode 100644 index 000000000..63f46a99e --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_globals.cc @@ -0,0 +1,160 @@ +// -*- C++ -*- Manage the thread-local exception globals. +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009 +// Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <bits/c++config.h> +#include <exception> +#include <cstdlib> +#include "cxxabi.h" +#include "unwind-cxx.h" +#include "bits/gthr.h" + +#if _GLIBCXX_HOSTED +using std::free; +using std::malloc; +#else +// In a freestanding environment, these functions may not be +// available -- but for now, we assume that they are. +extern "C" void *malloc (std::size_t); +extern "C" void free(void *); +#endif + +using namespace __cxxabiv1; + +#if _GLIBCXX_HAVE_TLS + +namespace +{ + abi::__cxa_eh_globals* + get_global() throw() + { + static __thread abi::__cxa_eh_globals global; + return &global; + } +} // anonymous namespace + +extern "C" __cxa_eh_globals* +__cxxabiv1::__cxa_get_globals_fast() throw() +{ return get_global(); } + +extern "C" __cxa_eh_globals* +__cxxabiv1::__cxa_get_globals() throw() +{ return get_global(); } + + +#else + +// Single-threaded fallback buffer. +static __cxa_eh_globals eh_globals; + +#if __GTHREADS + +static void +eh_globals_dtor(void* ptr) +{ + if (ptr) + { + __cxa_eh_globals* g = reinterpret_cast<__cxa_eh_globals*>(ptr); + __cxa_exception* exn = g->caughtExceptions; + __cxa_exception* next; + while (exn) + { + next = exn->nextException; + _Unwind_DeleteException(&exn->unwindHeader); + exn = next; + } + free(ptr); + } +} + +struct __eh_globals_init +{ + __gthread_key_t _M_key; + bool _M_init; + + __eh_globals_init() : _M_init(false) + { + if (__gthread_active_p()) + _M_init = __gthread_key_create(&_M_key, eh_globals_dtor) == 0; + } + + ~__eh_globals_init() + { + if (_M_init) + __gthread_key_delete(_M_key); + _M_init = false; + } +}; + +static __eh_globals_init init; + +extern "C" __cxa_eh_globals* +__cxxabiv1::__cxa_get_globals_fast() throw() +{ + __cxa_eh_globals* g; + if (init._M_init) + g = static_cast<__cxa_eh_globals*>(__gthread_getspecific(init._M_key)); + else + g = &eh_globals; + return g; +} + +extern "C" __cxa_eh_globals* +__cxxabiv1::__cxa_get_globals() throw() +{ + __cxa_eh_globals* g; + if (init._M_init) + { + g = static_cast<__cxa_eh_globals*>(__gthread_getspecific(init._M_key)); + if (!g) + { + void* v = malloc(sizeof(__cxa_eh_globals)); + if (v == 0 || __gthread_setspecific(init._M_key, v) != 0) + std::terminate(); + g = static_cast<__cxa_eh_globals*>(v); + g->caughtExceptions = 0; + g->uncaughtExceptions = 0; +#ifdef __ARM_EABI_UNWINDER__ + g->propagatingExceptions = 0; +#endif + } + } + else + g = &eh_globals; + return g; +} + +#else + +extern "C" __cxa_eh_globals* +__cxxabiv1::__cxa_get_globals_fast() throw() +{ return &eh_globals; } + +extern "C" __cxa_eh_globals* +__cxxabiv1::__cxa_get_globals() throw() +{ return &eh_globals; } + +#endif + +#endif diff --git a/libstdc++-v3/libsupc++/eh_personality.cc b/libstdc++-v3/libsupc++/eh_personality.cc new file mode 100644 index 000000000..19c204473 --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_personality.cc @@ -0,0 +1,789 @@ +// -*- C++ -*- The GNU C++ exception personality routine. +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +// 2011 +// Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <bits/c++config.h> +#include <cstdlib> +#include <bits/exception_defines.h> +#include <cxxabi.h> +#include "unwind-cxx.h" + +using namespace __cxxabiv1; + +#ifdef __ARM_EABI_UNWINDER__ +#define NO_SIZE_OF_ENCODED_VALUE +#endif + +#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) +{ + _uleb128_t 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; +} + +#ifdef __ARM_EABI_UNWINDER__ + +// Return an element from a type table. + +static const std::type_info* +get_ttype_entry(lsda_header_info* info, _uleb128_t i) +{ + _Unwind_Ptr ptr; + + ptr = (_Unwind_Ptr) (info->TType - (i * 4)); + ptr = _Unwind_decode_target2(ptr); + + return reinterpret_cast<const std::type_info *>(ptr); +} + +// The ABI provides a routine for matching exception object types. +typedef _Unwind_Control_Block _throw_typet; +#define get_adjusted_ptr(catch_type, throw_type, thrown_ptr_p) \ + (__cxa_type_match (throw_type, catch_type, false, thrown_ptr_p) \ + != ctm_failed) + +// Return true if THROW_TYPE matches one if the filter types. + +static bool +check_exception_spec(lsda_header_info* info, _throw_typet* throw_type, + void* thrown_ptr, _sleb128_t filter_value) +{ + const _uleb128_t* e = ((const _uleb128_t*) info->TType) + - filter_value - 1; + + while (1) + { + const std::type_info* catch_type; + _uleb128_t tmp; + + tmp = *e; + + // 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; + + tmp = _Unwind_decode_target2((_Unwind_Word) e); + + // Match a ttype entry. + catch_type = reinterpret_cast<const std::type_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; + + // Advance to the next entry. + e++; + } +} + + +// Save stage1 handler information in the exception object + +static inline void +save_caught_exception(struct _Unwind_Exception* ue_header, + struct _Unwind_Context* context, + void* thrown_ptr, + int handler_switch_value, + const unsigned char* language_specific_data, + _Unwind_Ptr landing_pad, + const unsigned char* action_record + __attribute__((__unused__))) +{ + ue_header->barrier_cache.sp = _Unwind_GetGR(context, 13); + ue_header->barrier_cache.bitpattern[0] = (_uw) thrown_ptr; + ue_header->barrier_cache.bitpattern[1] + = (_uw) handler_switch_value; + ue_header->barrier_cache.bitpattern[2] + = (_uw) language_specific_data; + ue_header->barrier_cache.bitpattern[3] = (_uw) landing_pad; +} + + +// Restore the catch handler data saved during phase1. + +static inline void +restore_caught_exception(struct _Unwind_Exception* ue_header, + int& handler_switch_value, + const unsigned char*& language_specific_data, + _Unwind_Ptr& landing_pad) +{ + handler_switch_value = (int) ue_header->barrier_cache.bitpattern[1]; + language_specific_data = + (const unsigned char*) ue_header->barrier_cache.bitpattern[2]; + landing_pad = (_Unwind_Ptr) ue_header->barrier_cache.bitpattern[3]; +} + +#define CONTINUE_UNWINDING \ + do \ + { \ + if (__gnu_unwind_frame(ue_header, context) != _URC_OK) \ + return _URC_FAILURE; \ + return _URC_CONTINUE_UNWIND; \ + } \ + while (0) + +// Return true if the filter spec is empty, ie throw(). + +static bool +empty_exception_spec (lsda_header_info *info, _Unwind_Sword filter_value) +{ + const _Unwind_Word* e = ((const _Unwind_Word*) info->TType) + - filter_value - 1; + + return *e == 0; +} + +#else +typedef const std::type_info _throw_typet; + + +// Return an element from a type table. + +static const std::type_info * +get_ttype_entry (lsda_header_info *info, _uleb128_t 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<const std::type_info *>(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; +} + +// Return true if THROW_TYPE matches one if the filter types. + +static bool +check_exception_spec(lsda_header_info* info, _throw_typet* throw_type, + void* thrown_ptr, _sleb128_t filter_value) +{ + const unsigned char *e = info->TType - filter_value - 1; + + while (1) + { + const std::type_info *catch_type; + _uleb128_t 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; + } +} + + +// Save stage1 handler information in the exception object + +static inline void +save_caught_exception(struct _Unwind_Exception* ue_header, + struct _Unwind_Context* context + __attribute__((__unused__)), + void* thrown_ptr, + int handler_switch_value, + const unsigned char* language_specific_data, + _Unwind_Ptr landing_pad __attribute__((__unused__)), + const unsigned char* action_record) +{ + __cxa_exception* xh = __get_exception_header_from_ue(ue_header); + + 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 = landing_pad; +} + + +// Restore the catch handler information saved during phase1. + +static inline void +restore_caught_exception(struct _Unwind_Exception* ue_header, + int& handler_switch_value, + const unsigned char*& language_specific_data, + _Unwind_Ptr& landing_pad) +{ + __cxa_exception* xh = __get_exception_header_from_ue(ue_header); + handler_switch_value = xh->handlerSwitchValue; + language_specific_data = xh->languageSpecificData; + landing_pad = (_Unwind_Ptr) xh->catchTemp; +} + +#define CONTINUE_UNWINDING return _URC_CONTINUE_UNWIND + +// Return true if the filter spec is empty, ie throw(). + +static bool +empty_exception_spec (lsda_header_info *info, _Unwind_Sword filter_value) +{ + const unsigned char *e = info->TType - filter_value - 1; + _uleb128_t tmp; + + e = read_uleb128 (e, &tmp); + return tmp == 0; +} + +#endif // !__ARM_EABI_UNWINDER__ + +namespace __cxxabiv1 +{ + +// Using a different personality function name causes link failures +// when trying to mix code using different exception handling models. +#ifdef _GLIBCXX_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 +#ifdef __ARM_EABI_UNWINDER__ +PERSONALITY_FUNCTION (_Unwind_State state, + struct _Unwind_Exception* ue_header, + struct _Unwind_Context* context) +#else +PERSONALITY_FUNCTION (int version, + _Unwind_Action actions, + _Unwind_Exception_Class exception_class, + struct _Unwind_Exception *ue_header, + struct _Unwind_Context *context) +#endif +{ + 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 = 0; + bool foreign_exception; + int ip_before_insn = 0; + +#ifdef __ARM_EABI_UNWINDER__ + _Unwind_Action actions; + + switch (state & _US_ACTION_MASK) + { + case _US_VIRTUAL_UNWIND_FRAME: + actions = _UA_SEARCH_PHASE; + break; + + case _US_UNWIND_FRAME_STARTING: + actions = _UA_CLEANUP_PHASE; + if (!(state & _US_FORCE_UNWIND) + && ue_header->barrier_cache.sp == _Unwind_GetGR(context, 13)) + actions |= _UA_HANDLER_FRAME; + break; + + case _US_UNWIND_FRAME_RESUME: + CONTINUE_UNWINDING; + break; + + default: + std::abort(); + } + actions |= state & _US_FORCE_UNWIND; + + // We don't know which runtime we're working with, so can't check this. + // However the ABI routines hide this from us, and we don't actually need + // to know. + foreign_exception = false; + + // The dwarf unwinder assumes the context structure holds things like the + // function and LSDA pointers. The ARM implementation caches these in + // the exception header (UCB). To avoid rewriting everything we make the + // virtual IP register point at the UCB. + ip = (_Unwind_Ptr) ue_header; + _Unwind_SetGR(context, 12, ip); +#else + __cxa_exception* xh = __get_exception_header_from_ue(ue_header); + + // Interface version check. + if (version != 1) + return _URC_FATAL_PHASE1_ERROR; + foreign_exception = !__is_gxx_exception_class(exception_class); +#endif + + // Shortcut for phase 2 found handler for domestic exception. + if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME) + && !foreign_exception) + { + restore_caught_exception(ue_header, handler_switch_value, + language_specific_data, landing_pad); + 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) + CONTINUE_UNWINDING; + + // Parse the LSDA header. + p = parse_lsda_header (context, language_specific_data, &info); + info.ttype_base = base_of_encoded_value (info.ttype_encoding, context); +#ifdef _GLIBCXX_HAVE_GETIPINFO + ip = _Unwind_GetIPInfo (context, &ip_before_insn); +#else + ip = _Unwind_GetIP (context); +#endif + if (! ip_before_insn) + --ip; + landing_pad = 0; + action_record = 0; + handler_switch_value = 0; + +#ifdef _GLIBCXX_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 + { + _uleb128_t 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; + _uleb128_t 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 // _GLIBCXX_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 = 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. + + _sleb128_t ar_filter, ar_disp; + const std::type_info* catch_type; + _throw_typet* throw_type; + bool saw_cleanup = false; + bool saw_handler = false; + +#ifdef __ARM_EABI_UNWINDER__ + // ??? How does this work - more importantly, how does it interact with + // dependent exceptions? + throw_type = ue_header; + if (actions & _UA_FORCE_UNWIND) + { + __GXX_INIT_FORCED_UNWIND_CLASS(ue_header->exception_class); + } + else if (!foreign_exception) + thrown_ptr = __get_object_from_ue (ue_header); +#else +#ifdef __GXX_RTTI + // During forced unwinding, match a magic exception type. + if (actions & _UA_FORCE_UNWIND) + { + throw_type = &typeid(abi::__forced_unwind); + } + // With a foreign exception class, there's no exception type. + // ??? What to do about GNU Java and GNU Ada exceptions? + else if (foreign_exception) + { + throw_type = &typeid(abi::__foreign_exception); + } + else +#endif + { + thrown_ptr = __get_object_from_ue (ue_header); + throw_type = __get_exception_header_from_obj + (thrown_ptr)->exceptionType; + } +#endif + + 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. Otherwise we must match types. + if (! catch_type + || (throw_type + && 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. + // Allow them iff the exception spec is non-empty. I.e. + // a throw() specification results in __unexpected. + if ((throw_type + && !(actions & _UA_FORCE_UNWIND) + && !foreign_exception) + ? ! check_exception_spec (&info, throw_type, thrown_ptr, + ar_filter) + : empty_exception_spec (&info, 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) + CONTINUE_UNWINDING; + + if (actions & _UA_SEARCH_PHASE) + { + if (found_type == found_cleanup) + CONTINUE_UNWINDING; + + // For domestic exceptions, we cache data from phase 1 for phase 2. + if (!foreign_exception) + { + save_caught_exception(ue_header, context, thrown_ptr, + handler_switch_value, language_specific_data, + landing_pad, action_record); + } + return _URC_HANDLER_FOUND; + } + + install_context: + + // We can't use any of the cxa routines with foreign exceptions, + // because they all expect ue_header to be a struct __cxa_exception. + // So in that case, call terminate or unexpected directly. + if ((actions & _UA_FORCE_UNWIND) + || foreign_exception) + { + if (found_type == found_terminate) + std::terminate (); + else if (handler_switch_value < 0) + { + __try + { std::unexpected (); } + __catch(...) + { std::terminate (); } + } + } + else + { + if (found_type == found_terminate) + __cxa_call_terminate(ue_header); + + // 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, language_specific_data, &info); + +#ifdef __ARM_EABI_UNWINDER__ + const _Unwind_Word* e; + _Unwind_Word n; + + e = ((const _Unwind_Word*) info.TType) - handler_switch_value - 1; + // Count the number of rtti objects. + n = 0; + while (e[n] != 0) + n++; + + // Count. + ue_header->barrier_cache.bitpattern[1] = n; + // Base (obsolete) + ue_header->barrier_cache.bitpattern[2] = 0; + // Stride. + ue_header->barrier_cache.bitpattern[3] = 4; + // List head. + ue_header->barrier_cache.bitpattern[4] = (_Unwind_Word) e; +#else + xh->catchTemp = base_of_encoded_value (info.ttype_encoding, context); +#endif + } + } + + /* For targets with pointers smaller than the word size, we must extend the + pointer, and this extension is target dependent. */ + _Unwind_SetGR (context, __builtin_eh_return_data_regno (0), + __builtin_extend_pointer (ue_header)); + _Unwind_SetGR (context, __builtin_eh_return_data_regno (1), + handler_switch_value); + _Unwind_SetIP (context, landing_pad); +#ifdef __ARM_EABI_UNWINDER__ + if (found_type == found_cleanup) + __cxa_begin_cleanup(ue_header); +#endif + return _URC_INSTALL_CONTEXT; +} + +/* The ARM EABI implementation of __cxa_call_unexpected is in a + different file so that the personality routine (PR) can be used + standalone. The generic routine shared datastructures with the PR + so it is most convenient to implement it here. */ +#ifndef __ARM_EABI_UNWINDER__ +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. + + __cxa_eh_globals *globals = __cxa_get_globals_fast (); + __cxa_exception *new_xh = globals->caughtExceptions; + void *new_ptr = __get_object_from_ambiguous_exception (new_xh); + + // 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, __get_exception_header_from_obj + (new_ptr)->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. +#if defined(__EXCEPTIONS) && defined(__GXX_RTTI) + 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); + } +} +#endif + +} // namespace __cxxabiv1 diff --git a/libstdc++-v3/libsupc++/eh_ptr.cc b/libstdc++-v3/libsupc++/eh_ptr.cc new file mode 100644 index 000000000..94c28427d --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_ptr.cc @@ -0,0 +1,224 @@ +// -*- C++ -*- Implement the members of exception_ptr. +// Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <bits/c++config.h> + +#ifdef _GLIBCXX_ATOMIC_BUILTINS_4 + +#define _GLIBCXX_EH_PTR_COMPAT + +#include <exception> +#include <bits/exception_ptr.h> +#include "unwind-cxx.h" + +using namespace __cxxabiv1; + +std::__exception_ptr::exception_ptr::exception_ptr() throw() +: _M_exception_object(0) { } + + +std::__exception_ptr::exception_ptr::exception_ptr(void* obj) throw() +: _M_exception_object(obj) { _M_addref(); } + + +std::__exception_ptr::exception_ptr::exception_ptr(__safe_bool) throw() +: _M_exception_object(0) { } + + +std::__exception_ptr:: +exception_ptr::exception_ptr(const exception_ptr& other) throw() +: _M_exception_object(other._M_exception_object) +{ _M_addref(); } + + +std::__exception_ptr::exception_ptr::~exception_ptr() throw() +{ _M_release(); } + + +std::__exception_ptr::exception_ptr& +std::__exception_ptr:: +exception_ptr::operator=(const exception_ptr& other) throw() +{ + exception_ptr(other).swap(*this); + return *this; +} + + +void +std::__exception_ptr::exception_ptr::_M_addref() throw() +{ + if (_M_exception_object) + { + __cxa_refcounted_exception *eh = + __get_refcounted_exception_header_from_obj (_M_exception_object); + __sync_add_and_fetch (&eh->referenceCount, 1); + } +} + + +void +std::__exception_ptr::exception_ptr::_M_release() throw() +{ + if (_M_exception_object) + { + __cxa_refcounted_exception *eh = + __get_refcounted_exception_header_from_obj (_M_exception_object); + if (__sync_sub_and_fetch (&eh->referenceCount, 1) == 0) + { + if (eh->exc.exceptionDestructor) + eh->exc.exceptionDestructor (_M_exception_object); + + __cxa_free_exception (_M_exception_object); + _M_exception_object = 0; + } + } +} + + +void* +std::__exception_ptr::exception_ptr::_M_get() const throw() +{ return _M_exception_object; } + + +void +std::__exception_ptr::exception_ptr::swap(exception_ptr &other) throw() +{ + void *tmp = _M_exception_object; + _M_exception_object = other._M_exception_object; + other._M_exception_object = tmp; +} + + +// Retained for compatibility with CXXABI_1.3. +void +std::__exception_ptr::exception_ptr::_M_safe_bool_dummy() throw () { } + + +// Retained for compatibility with CXXABI_1.3. +bool +std::__exception_ptr::exception_ptr::operator!() const throw() +{ return _M_exception_object == 0; } + + +// Retained for compatibility with CXXABI_1.3. +std::__exception_ptr::exception_ptr::operator __safe_bool() const throw() +{ + return _M_exception_object ? &exception_ptr::_M_safe_bool_dummy : 0; +} + + +const std::type_info* +std::__exception_ptr::exception_ptr::__cxa_exception_type() const throw() +{ + __cxa_exception *eh = __get_exception_header_from_obj (_M_exception_object); + return eh->exceptionType; +} + + +bool std::__exception_ptr::operator==(const exception_ptr& lhs, + const exception_ptr& rhs) throw() +{ return lhs._M_exception_object == rhs._M_exception_object; } + + +bool std::__exception_ptr::operator!=(const exception_ptr& lhs, + const exception_ptr& rhs) throw() +{ return !(lhs == rhs);} + + +std::exception_ptr +std::current_exception() throw() +{ + __cxa_eh_globals *globals = __cxa_get_globals (); + __cxa_exception *header = globals->caughtExceptions; + + if (!header) + return std::exception_ptr(); + + // Since foreign exceptions can't be counted, we can't return them. + if (!__is_gxx_exception_class (header->unwindHeader.exception_class)) + return std::exception_ptr(); + + return std::exception_ptr( + __get_object_from_ambiguous_exception (header)); +} + + +static void +__gxx_dependent_exception_cleanup(_Unwind_Reason_Code code, + _Unwind_Exception *exc) +{ + // This cleanup is set only for dependents. + __cxa_dependent_exception *dep = __get_dependent_exception_from_ue (exc); + __cxa_refcounted_exception *header = + __get_refcounted_exception_header_from_obj (dep->primaryException); + + // We only want to be called through _Unwind_DeleteException. + // _Unwind_DeleteException in the HP-UX IA64 libunwind library + // returns _URC_NO_REASON and not _URC_FOREIGN_EXCEPTION_CAUGHT + // like the GCC _Unwind_DeleteException function does. + if (code != _URC_FOREIGN_EXCEPTION_CAUGHT && code != _URC_NO_REASON) + __terminate (header->exc.terminateHandler); + + __cxa_free_dependent_exception (dep); + + if (__sync_sub_and_fetch (&header->referenceCount, 1) == 0) + { + if (header->exc.exceptionDestructor) + header->exc.exceptionDestructor (header + 1); + + __cxa_free_exception (header + 1); + } +} + + +void +std::rethrow_exception(std::exception_ptr ep) +{ + void *obj = ep._M_get(); + __cxa_refcounted_exception *eh + = __get_refcounted_exception_header_from_obj (obj); + + __cxa_dependent_exception *dep = __cxa_allocate_dependent_exception (); + dep->primaryException = obj; + __sync_add_and_fetch (&eh->referenceCount, 1); + + dep->unexpectedHandler = __unexpected_handler; + dep->terminateHandler = __terminate_handler; + __GXX_INIT_DEPENDENT_EXCEPTION_CLASS(dep->unwindHeader.exception_class); + dep->unwindHeader.exception_cleanup = __gxx_dependent_exception_cleanup; + +#ifdef _GLIBCXX_SJLJ_EXCEPTIONS + _Unwind_SjLj_RaiseException (&dep->unwindHeader); +#else + _Unwind_RaiseException (&dep->unwindHeader); +#endif + + // Some sort of unwinding error. Note that terminate is a handler. + __cxa_begin_catch (&dep->unwindHeader); + std::terminate(); +} + +#undef _GLIBCXX_EH_PTR_COMPAT + +#endif diff --git a/libstdc++-v3/libsupc++/eh_term_handler.cc b/libstdc++-v3/libsupc++/eh_term_handler.cc new file mode 100644 index 000000000..52a074596 --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_term_handler.cc @@ -0,0 +1,46 @@ +// -*- C++ -*- std::terminate handler +// Copyright (C) 2002, 2003, 2009 Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <bits/c++config.h> +#include "unwind-cxx.h" + +/* We default to the talkative, informative handler in a normal hosted + library. This pulls in the demangler, the dyn-string utilities, and + elements of the I/O library. For a low-memory environment, you can return + to the earlier "silent death" handler by including <cstdlib>, initializing + to "std::abort", and rebuilding the library. In a freestanding mode, we + default to this latter approach. */ + +#if ! _GLIBCXX_HOSTED +# include <cstdlib> +#endif + +/* The current installed user handler. */ +std::terminate_handler __cxxabiv1::__terminate_handler = +#if _GLIBCXX_HOSTED + __gnu_cxx::__verbose_terminate_handler; +#else + std::abort; +#endif + diff --git a/libstdc++-v3/libsupc++/eh_terminate.cc b/libstdc++-v3/libsupc++/eh_terminate.cc new file mode 100644 index 000000000..87359d09f --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_terminate.cc @@ -0,0 +1,80 @@ +// -*- C++ -*- std::terminate, std::unexpected and friends. +// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2009, +// 2011 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include "typeinfo" +#include "exception" +#include <cstdlib> +#include "unwind-cxx.h" +#include <bits/exception_defines.h> + +using namespace __cxxabiv1; + +void +__cxxabiv1::__terminate (std::terminate_handler handler) throw () +{ + __try + { + handler (); + std::abort (); + } + __catch(...) + { std::abort (); } +} + +void +std::terminate () throw() +{ + __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/libstdc++-v3/libsupc++/eh_throw.cc b/libstdc++-v3/libsupc++/eh_throw.cc new file mode 100644 index 000000000..78cfc1395 --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_throw.cc @@ -0,0 +1,117 @@ +// -*- C++ -*- Exception handling routines for throwing. +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +// Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <bits/c++config.h> +#include "unwind-cxx.h" + +using namespace __cxxabiv1; + + +static void +__gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc) +{ + // This cleanup is set only for primaries. + __cxa_refcounted_exception *header + = __get_refcounted_exception_header_from_ue (exc); + + // We only want to be called through _Unwind_DeleteException. + // _Unwind_DeleteException in the HP-UX IA64 libunwind library + // returns _URC_NO_REASON and not _URC_FOREIGN_EXCEPTION_CAUGHT + // like the GCC _Unwind_DeleteException function does. + if (code != _URC_FOREIGN_EXCEPTION_CAUGHT && code != _URC_NO_REASON) + __terminate (header->exc.terminateHandler); + +#ifdef _GLIBCXX_ATOMIC_BUILTINS_4 + if (__sync_sub_and_fetch (&header->referenceCount, 1) == 0) + { +#endif + if (header->exc.exceptionDestructor) + header->exc.exceptionDestructor (header + 1); + + __cxa_free_exception (header + 1); +#ifdef _GLIBCXX_ATOMIC_BUILTINS_4 + } +#endif +} + + +extern "C" void +__cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo, + void (*dest) (void *)) +{ + // Definitely a primary. + __cxa_refcounted_exception *header + = __get_refcounted_exception_header_from_obj (obj); + header->referenceCount = 1; + header->exc.exceptionType = tinfo; + header->exc.exceptionDestructor = dest; + header->exc.unexpectedHandler = __unexpected_handler; + header->exc.terminateHandler = __terminate_handler; + __GXX_INIT_PRIMARY_EXCEPTION_CLASS(header->exc.unwindHeader.exception_class); + header->exc.unwindHeader.exception_cleanup = __gxx_exception_cleanup; + +#ifdef _GLIBCXX_SJLJ_EXCEPTIONS + _Unwind_SjLj_RaiseException (&header->exc.unwindHeader); +#else + _Unwind_RaiseException (&header->exc.unwindHeader); +#endif + + // Some sort of unwinding error. Note that terminate is a handler. + __cxa_begin_catch (&header->exc.unwindHeader); + std::terminate (); +} + +extern "C" void +__cxxabiv1::__cxa_rethrow () +{ + __cxa_eh_globals *globals = __cxa_get_globals (); + __cxa_exception *header = globals->caughtExceptions; + + globals->uncaughtExceptions += 1; + + // Watch for luser rethrowing with no active exception. + if (header) + { + // Tell __cxa_end_catch this is a rethrow. + if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) + globals->caughtExceptions = 0; + else + header->handlerCount = -header->handlerCount; + +#ifdef _GLIBCXX_SJLJ_EXCEPTIONS + _Unwind_SjLj_Resume_or_Rethrow (&header->unwindHeader); +#else +#if defined(_LIBUNWIND_STD_ABI) + _Unwind_RaiseException (&header->unwindHeader); +#else + _Unwind_Resume_or_Rethrow (&header->unwindHeader); +#endif +#endif + + // Some sort of unwinding error. Note that terminate is a handler. + __cxa_begin_catch (&header->unwindHeader); + } + std::terminate (); +} diff --git a/libstdc++-v3/libsupc++/eh_type.cc b/libstdc++-v3/libsupc++/eh_type.cc new file mode 100644 index 000000000..bb8be0b75 --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_type.cc @@ -0,0 +1,54 @@ +// -*- C++ -*- Exception handling routines for catching. +// Copyright (C) 2001, 2008, 2009 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + + +#include <typeinfo> +#include <cxxabi.h> +#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 () throw() +{ + __cxa_eh_globals *globals = __cxa_get_globals (); + __cxa_exception *header = globals->caughtExceptions; + if (header) + { + if (__is_dependent_exception (header->unwindHeader.exception_class)) + { + __cxa_dependent_exception *de = + __get_dependent_exception_from_ue (&header->unwindHeader); + header = __get_exception_header_from_obj (de->primaryException); + } + return header->exceptionType; + } + else + return 0; +} + +} // namespace __cxxabiv1 diff --git a/libstdc++-v3/libsupc++/eh_unex_handler.cc b/libstdc++-v3/libsupc++/eh_unex_handler.cc new file mode 100644 index 000000000..e4f390620 --- /dev/null +++ b/libstdc++-v3/libsupc++/eh_unex_handler.cc @@ -0,0 +1,29 @@ +// -*- C++ -*- std::unexpected handler +// Copyright (C) 2002, 2009 Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include "unwind-cxx.h" + +/* The current installed user handler. */ +std::unexpected_handler __cxxabiv1::__unexpected_handler = std::terminate; + diff --git a/libstdc++-v3/libsupc++/enum_type_info.cc b/libstdc++-v3/libsupc++/enum_type_info.cc new file mode 100644 index 000000000..1e87b4dbe --- /dev/null +++ b/libstdc++-v3/libsupc++/enum_type_info.cc @@ -0,0 +1,33 @@ +// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007, 2009 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include "tinfo.h" + +namespace __cxxabiv1 { + +__enum_type_info:: +~__enum_type_info () +{} + +} diff --git a/libstdc++-v3/libsupc++/exception b/libstdc++-v3/libsupc++/exception new file mode 100644 index 000000000..db75ad115 --- /dev/null +++ b/libstdc++-v3/libsupc++/exception @@ -0,0 +1,158 @@ +// Exception Handling support header for -*- C++ -*- + +// Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, +// 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file exception + * This is a Standard C++ Library header. + */ + +#ifndef __EXCEPTION__ +#define __EXCEPTION__ + +#pragma GCC system_header + +#pragma GCC visibility push(default) + +#include <bits/c++config.h> + +extern "C++" { + +namespace std +{ + /** + * @defgroup exceptions Exceptions + * @ingroup diagnostics + * + * Classes and functions for reporting errors via exception classes. + * @{ + */ + + /** + * @brief Base class for all library exceptions. + * + * 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). + */ + 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(); + + // See comment in eh_exception.cc. + virtual const char* what() const 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. It can also be called by the user. */ + void terminate() throw() __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() __attribute__ ((__pure__)); + + // @} group exceptions +} // namespace std + +namespace __gnu_cxx +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @brief A replacement for the standard terminate_handler which + * prints more information about the terminating exception (if any) + * on stderr. + * + * @ingroup exceptions + * + * Call + * @code + * std::set_terminate(__gnu_cxx::__verbose_terminate_handler) + * @endcode + * to use. For more info, see + * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt02ch06s02.html + * + * In 3.4 and later, this is on by default. + */ + void __verbose_terminate_handler(); + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace + +} // extern "C++" + +#pragma GCC visibility pop + +#if (defined(__GXX_EXPERIMENTAL_CXX0X__) \ + && defined(_GLIBCXX_ATOMIC_BUILTINS_4)) +#include <bits/exception_ptr.h> +#include <bits/nested_exception.h> +#endif + +#endif diff --git a/libstdc++-v3/libsupc++/exception_defines.h b/libstdc++-v3/libsupc++/exception_defines.h new file mode 100644 index 000000000..269937cff --- /dev/null +++ b/libstdc++-v3/libsupc++/exception_defines.h @@ -0,0 +1,47 @@ +// -fno-exceptions Support -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2006, 2007, 2008, 2009, +// 2011 +// 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 3, 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file bits/exception_defines.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{exception} + */ + +#ifndef _EXCEPTION_DEFINES_H +#define _EXCEPTION_DEFINES_H 1 + +#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 __try try +# define __catch(X) catch(X) +# define __throw_exception_again throw +#endif + +#endif diff --git a/libstdc++-v3/libsupc++/exception_ptr.h b/libstdc++-v3/libsupc++/exception_ptr.h new file mode 100644 index 000000000..26117cd5d --- /dev/null +++ b/libstdc++-v3/libsupc++/exception_ptr.h @@ -0,0 +1,191 @@ +// Exception Handling support header (exception_ptr class) for -*- C++ -*- + +// Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file bits/exception_ptr.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{exception} + */ + +#ifndef _EXCEPTION_PTR_H +#define _EXCEPTION_PTR_H + +#pragma GCC visibility push(default) + +#include <bits/c++config.h> +#include <bits/exception_defines.h> + +#if !defined(_GLIBCXX_ATOMIC_BUILTINS_4) +# error This platform does not support exception propagation. +#endif + +extern "C++" { + +namespace std +{ + /** + * @addtogroup exceptions + * @{ + */ + namespace __exception_ptr + { + class exception_ptr; + } + + using __exception_ptr::exception_ptr; + + /** Obtain an exception_ptr to the currently handled exception. If there + * is none, or the currently handled exception is foreign, return the null + * value. + */ + exception_ptr current_exception() throw(); + + /// Throw the object pointed to by the exception_ptr. + void rethrow_exception(exception_ptr) __attribute__ ((__noreturn__)); + + namespace __exception_ptr + { + /** + * @brief An opaque pointer to an arbitrary exception. + * @ingroup exceptions + */ + class exception_ptr + { + void* _M_exception_object; + + explicit exception_ptr(void* __e) throw(); + + void _M_addref() throw(); + void _M_release() throw(); + + void *_M_get() const throw() __attribute__ ((__pure__)); + + friend exception_ptr std::current_exception() throw(); + friend void std::rethrow_exception(exception_ptr); + + public: + exception_ptr() throw(); + + exception_ptr(const exception_ptr&) throw(); + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + exception_ptr(nullptr_t) throw() + : _M_exception_object(0) + { } + + exception_ptr(exception_ptr&& __o) throw() + : _M_exception_object(__o._M_exception_object) + { __o._M_exception_object = 0; } +#else + typedef void (exception_ptr::*__safe_bool)(); + + // For construction from nullptr or 0. + exception_ptr(__safe_bool) throw(); +#endif + + exception_ptr& + operator=(const exception_ptr&) throw(); + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + exception_ptr& + operator=(exception_ptr&& __o) throw() + { + exception_ptr(static_cast<exception_ptr&&>(__o)).swap(*this); + return *this; + } +#endif + + ~exception_ptr() throw(); + + void + swap(exception_ptr&) throw(); + +#ifdef _GLIBCXX_EH_PTR_COMPAT + // Retained for compatibility with CXXABI_1.3. + void _M_safe_bool_dummy() throw() __attribute__ ((__const__)); + bool operator!() const throw() __attribute__ ((__pure__)); + operator __safe_bool() const throw(); +#endif + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + explicit operator bool() const + { return _M_exception_object; } +#endif + + friend bool + operator==(const exception_ptr&, const exception_ptr&) throw() + __attribute__ ((__pure__)); + + const class type_info* + __cxa_exception_type() const throw() __attribute__ ((__pure__)); + }; + + bool + operator==(const exception_ptr&, const exception_ptr&) throw() + __attribute__ ((__pure__)); + + bool + operator!=(const exception_ptr&, const exception_ptr&) throw() + __attribute__ ((__pure__)); + + inline void + swap(exception_ptr& __lhs, exception_ptr& __rhs) + { __lhs.swap(__rhs); } + + } // namespace __exception_ptr + + + /// Obtain an exception_ptr pointing to a copy of the supplied object. + template<typename _Ex> + exception_ptr + copy_exception(_Ex __ex) throw() + { + __try + { +#ifdef __EXCEPTIONS + throw __ex; +#endif + } + __catch(...) + { + return current_exception(); + } + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 1130. copy_exception name misleading + /// Obtain an exception_ptr pointing to a copy of the supplied object. + template<typename _Ex> + exception_ptr + make_exception_ptr(_Ex __ex) throw() + { return std::copy_exception<_Ex>(__ex); } + + // @} group exceptions +} // namespace std + +} // extern "C++" + +#pragma GCC visibility pop + +#endif diff --git a/libstdc++-v3/libsupc++/function_type_info.cc b/libstdc++-v3/libsupc++/function_type_info.cc new file mode 100644 index 000000000..e210088d2 --- /dev/null +++ b/libstdc++-v3/libsupc++/function_type_info.cc @@ -0,0 +1,39 @@ +// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007, 2009 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include "tinfo.h" + +namespace __cxxabiv1 { + +__function_type_info:: +~__function_type_info () +{} + +bool __function_type_info:: +__is_function_p () const +{ + return true; +} + +} diff --git a/libstdc++-v3/libsupc++/fundamental_type_info.cc b/libstdc++-v3/libsupc++/fundamental_type_info.cc new file mode 100644 index 000000000..de069382f --- /dev/null +++ b/libstdc++-v3/libsupc++/fundamental_type_info.cc @@ -0,0 +1,36 @@ +// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007, 2009 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include "tinfo.h" + +namespace __cxxabiv1 { + +// 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 () +{} + +} diff --git a/libstdc++-v3/libsupc++/guard.cc b/libstdc++-v3/libsupc++/guard.cc new file mode 100644 index 000000000..6e3d415cd --- /dev/null +++ b/libstdc++-v3/libsupc++/guard.cc @@ -0,0 +1,393 @@ +// Copyright (C) 2002, 2004, 2006, 2008, 2009, 2010, 2011 +// Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// Written by Mark Mitchell, CodeSourcery LLC, <mark@codesourcery.com> +// Thread support written by Jason Merrill, Red Hat Inc. <jason@redhat.com> + +#include <bits/c++config.h> +#include <cxxabi.h> +#include <exception> +#include <new> +#include <ext/atomicity.h> +#include <ext/concurrence.h> +#if defined(__GTHREADS) && defined(__GTHREAD_HAS_COND) \ + && defined(_GLIBCXX_ATOMIC_BUILTINS_4) && defined(_GLIBCXX_HAVE_LINUX_FUTEX) +# include <climits> +# include <syscall.h> +# define _GLIBCXX_USE_FUTEX +# define _GLIBCXX_FUTEX_WAIT 0 +# define _GLIBCXX_FUTEX_WAKE 1 +#endif + +// The IA64/generic ABI uses the first byte of the guard variable. +// The ARM EABI uses the least significant bit. + +// Thread-safe static local initialization support. +#ifdef __GTHREADS +# ifndef _GLIBCXX_USE_FUTEX +namespace +{ + // A single mutex controlling all static initializations. + static __gnu_cxx::__recursive_mutex* static_mutex; + + typedef char fake_recursive_mutex[sizeof(__gnu_cxx::__recursive_mutex)] + __attribute__ ((aligned(__alignof__(__gnu_cxx::__recursive_mutex)))); + fake_recursive_mutex fake_mutex; + + static void init() + { static_mutex = new (&fake_mutex) __gnu_cxx::__recursive_mutex(); } + + __gnu_cxx::__recursive_mutex& + get_static_mutex() + { + static __gthread_once_t once = __GTHREAD_ONCE_INIT; + __gthread_once(&once, init); + return *static_mutex; + } + + // Simple wrapper for exception safety. + struct mutex_wrapper + { + bool unlock; + mutex_wrapper() : unlock(true) + { get_static_mutex().lock(); } + + ~mutex_wrapper() + { + if (unlock) + static_mutex->unlock(); + } + }; +} +# endif + +# if defined(__GTHREAD_HAS_COND) && !defined(_GLIBCXX_USE_FUTEX) +namespace +{ + // A single conditional variable controlling all static initializations. + static __gnu_cxx::__cond* static_cond; + + // using a fake type to avoid initializing a static class. + typedef char fake_cond_t[sizeof(__gnu_cxx::__cond)] + __attribute__ ((aligned(__alignof__(__gnu_cxx::__cond)))); + fake_cond_t fake_cond; + + static void init_static_cond() + { static_cond = new (&fake_cond) __gnu_cxx::__cond(); } + + __gnu_cxx::__cond& + get_static_cond() + { + static __gthread_once_t once = __GTHREAD_ONCE_INIT; + __gthread_once(&once, init_static_cond); + return *static_cond; + } +} +# endif + +# ifndef _GLIBCXX_GUARD_TEST_AND_ACQUIRE +inline bool +__test_and_acquire (__cxxabiv1::__guard *g) +{ + bool b = _GLIBCXX_GUARD_TEST (g); + _GLIBCXX_READ_MEM_BARRIER; + return b; +} +# define _GLIBCXX_GUARD_TEST_AND_ACQUIRE(G) __test_and_acquire (G) +# endif + +# ifndef _GLIBCXX_GUARD_SET_AND_RELEASE +inline void +__set_and_release (__cxxabiv1::__guard *g) +{ + _GLIBCXX_WRITE_MEM_BARRIER; + _GLIBCXX_GUARD_SET (g); +} +# define _GLIBCXX_GUARD_SET_AND_RELEASE(G) __set_and_release (G) +# endif + +#else /* !__GTHREADS */ + +# undef _GLIBCXX_GUARD_TEST_AND_ACQUIRE +# undef _GLIBCXX_GUARD_SET_AND_RELEASE +# define _GLIBCXX_GUARD_SET_AND_RELEASE(G) _GLIBCXX_GUARD_SET (G) + +#endif /* __GTHREADS */ + +// +// Here are C++ run-time routines for guarded initiailization of static +// variables. There are 4 scenarios under which these routines are called: +// +// 1. Threads not supported (__GTHREADS not defined) +// 2. Threads are supported but not enabled at run-time. +// 3. Threads enabled at run-time but __gthreads_* are not fully POSIX. +// 4. Threads enabled at run-time and __gthreads_* support all POSIX threads +// primitives we need here. +// +// The old code supported scenarios 1-3 but was broken since it used a global +// mutex for all threads and had the mutex locked during the whole duration of +// initlization of a guarded static variable. The following created a dead-lock +// with the old code. +// +// Thread 1 acquires the global mutex. +// Thread 1 starts initializing static variable. +// Thread 1 creates thread 2 during initialization. +// Thread 2 attempts to acuqire mutex to initialize another variable. +// Thread 2 blocks since thread 1 is locking the mutex. +// Thread 1 waits for result from thread 2 and also blocks. A deadlock. +// +// The new code here can handle this situation and thus is more robust. Howere, +// we need to use the POSIX thread conditional variable, which is not supported +// in all platforms, notably older versions of Microsoft Windows. The gthr*.h +// headers define a symbol __GTHREAD_HAS_COND for platforms that support POSIX +// like conditional variables. For platforms that do not support conditional +// variables, we need to fall back to the old code. + +// If _GLIBCXX_USE_FUTEX, no global mutex or conditional variable is used, +// only atomic operations are used together with futex syscall. +// Valid values of the first integer in guard are: +// 0 No thread encountered the guarded init +// yet or it has been aborted. +// _GLIBCXX_GUARD_BIT The guarded static var has been successfully +// initialized. +// _GLIBCXX_GUARD_PENDING_BIT The guarded static var is being initialized +// and no other thread is waiting for its +// initialization. +// (_GLIBCXX_GUARD_PENDING_BIT The guarded static var is being initialized +// | _GLIBCXX_GUARD_WAITING_BIT) and some other threads are waiting until +// it is initialized. + +namespace __cxxabiv1 +{ +#ifdef _GLIBCXX_USE_FUTEX + namespace + { + static inline int __guard_test_bit (const int __byte, const int __val) + { + union { int __i; char __c[sizeof (int)]; } __u = { 0 }; + __u.__c[__byte] = __val; + return __u.__i; + } + } +#endif + + static inline int + init_in_progress_flag(__guard* g) + { return ((char *)g)[1]; } + + static inline void + set_init_in_progress_flag(__guard* g, int v) + { ((char *)g)[1] = v; } + + static inline void + throw_recursive_init_exception() + { +#ifdef __EXCEPTIONS + throw __gnu_cxx::recursive_init_error(); +#else + // Use __builtin_trap so we don't require abort(). + __builtin_trap(); +#endif + } + + // acuire() is a helper function used to acquire guard if thread support is + // not compiled in or is compiled in but not enabled at run-time. + static int + acquire(__guard *g) + { + // Quit if the object is already initialized. + if (_GLIBCXX_GUARD_TEST(g)) + return 0; + + if (init_in_progress_flag(g)) + throw_recursive_init_exception(); + + set_init_in_progress_flag(g, 1); + return 1; + } + + extern "C" + int __cxa_guard_acquire (__guard *g) + { +#ifdef __GTHREADS + // If the target can reorder loads, we need to insert a read memory + // barrier so that accesses to the guarded variable happen after the + // guard test. + if (_GLIBCXX_GUARD_TEST_AND_ACQUIRE (g)) + return 0; + +# ifdef _GLIBCXX_USE_FUTEX + // If __sync_* and futex syscall are supported, don't use any global + // mutex. + if (__gthread_active_p ()) + { + int *gi = (int *) (void *) g; + const int guard_bit = _GLIBCXX_GUARD_BIT; + const int pending_bit = _GLIBCXX_GUARD_PENDING_BIT; + const int waiting_bit = _GLIBCXX_GUARD_WAITING_BIT; + + while (1) + { + int old = __sync_val_compare_and_swap (gi, 0, pending_bit); + if (old == 0) + return 1; // This thread should do the initialization. + + if (old == guard_bit) + return 0; // Already initialized. + + if (old == pending_bit) + { + int newv = old | waiting_bit; + if (__sync_val_compare_and_swap (gi, old, newv) != old) + continue; + + old = newv; + } + + syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAIT, old, 0); + } + } +# else + if (__gthread_active_p ()) + { + mutex_wrapper mw; + + while (1) // When this loop is executing, mutex is locked. + { +# ifdef __GTHREAD_HAS_COND + // The static is already initialized. + if (_GLIBCXX_GUARD_TEST(g)) + return 0; // The mutex will be unlocked via wrapper + + if (init_in_progress_flag(g)) + { + // The guarded static is currently being initialized by + // another thread, so we release mutex and wait for the + // conditional variable. We will lock the mutex again after + // this. + get_static_cond().wait_recursive(&get_static_mutex()); + } + else + { + set_init_in_progress_flag(g, 1); + return 1; // The mutex will be unlocked via wrapper. + } +# else + // This provides compatibility with older systems not supporting + // POSIX like conditional variables. + if (acquire(g)) + { + mw.unlock = false; + return 1; // The mutex still locked. + } + return 0; // The mutex will be unlocked via wrapper. +# endif + } + } +# endif +#endif + + return acquire (g); + } + + extern "C" + void __cxa_guard_abort (__guard *g) throw () + { +#ifdef _GLIBCXX_USE_FUTEX + // If __sync_* and futex syscall are supported, don't use any global + // mutex. + if (__gthread_active_p ()) + { + int *gi = (int *) (void *) g; + const int waiting_bit = _GLIBCXX_GUARD_WAITING_BIT; + int old = __sync_lock_test_and_set (gi, 0); + + if ((old & waiting_bit) != 0) + syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAKE, INT_MAX); + return; + } +#elif defined(__GTHREAD_HAS_COND) + if (__gthread_active_p()) + { + mutex_wrapper mw; + + set_init_in_progress_flag(g, 0); + + // If we abort, we still need to wake up all other threads waiting for + // the conditional variable. + get_static_cond().broadcast(); + return; + } +#endif + + set_init_in_progress_flag(g, 0); +#if defined(__GTHREADS) && !defined(__GTHREAD_HAS_COND) + // This provides compatibility with older systems not supporting POSIX like + // conditional variables. + if (__gthread_active_p ()) + static_mutex->unlock(); +#endif + } + + extern "C" + void __cxa_guard_release (__guard *g) throw () + { +#ifdef _GLIBCXX_USE_FUTEX + // If __sync_* and futex syscall are supported, don't use any global + // mutex. + if (__gthread_active_p ()) + { + int *gi = (int *) (void *) g; + const int guard_bit = _GLIBCXX_GUARD_BIT; + const int waiting_bit = _GLIBCXX_GUARD_WAITING_BIT; + int old = __sync_lock_test_and_set (gi, guard_bit); + + if ((old & waiting_bit) != 0) + syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAKE, INT_MAX); + return; + } +#elif defined(__GTHREAD_HAS_COND) + if (__gthread_active_p()) + { + mutex_wrapper mw; + + set_init_in_progress_flag(g, 0); + _GLIBCXX_GUARD_SET_AND_RELEASE(g); + + get_static_cond().broadcast(); + return; + } +#endif + + set_init_in_progress_flag(g, 0); + _GLIBCXX_GUARD_SET_AND_RELEASE (g); + +#if defined(__GTHREADS) && !defined(__GTHREAD_HAS_COND) + // This provides compatibility with older systems not supporting POSIX like + // conditional variables. + if (__gthread_active_p()) + static_mutex->unlock(); +#endif + } +} diff --git a/libstdc++-v3/libsupc++/guard_error.cc b/libstdc++-v3/libsupc++/guard_error.cc new file mode 100644 index 000000000..7c06bcd0d --- /dev/null +++ b/libstdc++-v3/libsupc++/guard_error.cc @@ -0,0 +1,31 @@ +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <bits/c++config.h> +#include <cxxabi.h> + +namespace __gnu_cxx +{ + recursive_init_error::~recursive_init_error() throw() { } +} + diff --git a/libstdc++-v3/libsupc++/hash_bytes.cc b/libstdc++-v3/libsupc++/hash_bytes.cc new file mode 100644 index 000000000..07e77cf8d --- /dev/null +++ b/libstdc++-v3/libsupc++/hash_bytes.cc @@ -0,0 +1,189 @@ +// Definition of _Hash_bytes. -*- C++ -*- + +// Copyright (C) 2010, 2011 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 3, 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// This file defines Hash_bytes, a primitive used for defining hash +// functions. Based on public domain MurmurHashUnaligned2, by Austin +// Appleby. http://murmurhash.googlepages.com/ + +// This file also defines _Fnv_hash_bytes, another primitive with +// exactly the same interface but using a different hash algorithm, +// Fowler / Noll / Vo (FNV) Hash (type FNV-1a). The Murmur hash +// function apears to be better in both speed and hash quality, and +// FNV is provided primarily for backward compatibility. + +#include <bits/hash_bytes.h> + +namespace +{ + inline std::size_t + unaligned_load(const char* p) + { + std::size_t result; + __builtin_memcpy(&result, p, sizeof(result)); + return result; + } + +#if __SIZEOF_SIZE_T__ == 8 + // Loads n bytes, where 1 <= n < 8. + inline std::size_t + load_bytes(const char* p, int n) + { + std::size_t result = 0; + --n; + do + result = (result << 8) + static_cast<unsigned char>(p[n]); + while (--n >= 0); + return result; + } + + inline std::size_t + shift_mix(std::size_t v) + { return v ^ (v >> 47);} +#endif +} + +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +#if __SIZEOF_SIZE_T__ == 4 + + // Implementation of Murmur hash for 32-bit size_t. + size_t + _Hash_bytes(const void* ptr, size_t len, size_t seed) + { + const size_t m = 0x5bd1e995; + size_t hash = seed ^ len; + const char* buf = static_cast<const char*>(ptr); + + // Mix 4 bytes at a time into the hash. + while(len >= 4) + { + size_t k = unaligned_load(buf); + k *= m; + k ^= k >> 24; + k *= m; + hash *= m; + hash ^= k; + buf += 4; + len -= 4; + } + + // Handle the last few bytes of the input array. + switch(len) + { + case 3: + hash ^= static_cast<unsigned char>(buf[2]) << 16; + case 2: + hash ^= static_cast<unsigned char>(buf[1]) << 8; + case 1: + hash ^= static_cast<unsigned char>(buf[0]); + hash *= m; + }; + + // Do a few final mixes of the hash. + hash ^= hash >> 13; + hash *= m; + hash ^= hash >> 15; + return hash; + } + + // Implementation of FNV hash for 32-bit size_t. + size_t + _Fnv_hash_bytes(const void* ptr, size_t len, size_t hash) + { + const char* cptr = static_cast<const char*>(ptr); + for (; len; --len) + { + hash ^= static_cast<size_t>(*cptr++); + hash *= static_cast<size_t>(16777619UL); + } + return hash; + } + +#elif __SIZEOF_SIZE_T__ == 8 + + // Implementation of Murmur hash for 64-bit size_t. + size_t + _Hash_bytes(const void* ptr, size_t len, size_t seed) + { + static const size_t mul = (0xc6a4a793UL << 32UL) + 0x5bd1e995UL; + const char* const buf = static_cast<const char*>(ptr); + + // Remove the bytes not divisible by the sizeof(size_t). This + // allows the main loop to process the data as 64-bit integers. + const int len_aligned = len & ~0x7; + const char* const end = buf + len_aligned; + size_t hash = seed ^ (len * mul); + for (const char* p = buf; p != end; p += 8) + { + const size_t data = shift_mix(unaligned_load(p) * mul) * mul; + hash ^= data; + hash *= mul; + } + if ((len & 0x7) != 0) + { + const size_t data = load_bytes(end, len & 0x7); + hash ^= data; + hash *= mul; + } + hash = shift_mix(hash) * mul; + hash = shift_mix(hash); + return hash; + } + + // Implementation of FNV hash for 64-bit size_t. + size_t + _Fnv_hash_bytes(const void* ptr, size_t len, size_t hash) + { + const char* cptr = static_cast<const char*>(ptr); + for (; len; --len) + { + hash ^= static_cast<size_t>(*cptr++); + hash *= static_cast<size_t>(1099511628211ULL); + } + return hash; + } + +#else + + // Dummy hash implementation for unusual sizeof(size_t). + size_t + _Hash_bytes(const void* ptr, size_t len, size_t seed) + { + size_t hash = seed; + const char* cptr = reinterpret_cast<const char*>(ptr); + for (; len; --len) + hash = (hash * 131) + *cptr++; + return hash; + } + + size_t + _Fnv_hash_bytes(const void* ptr, size_t len, size_t seed) + { return _Hash_bytes(ptr, len, seed); } + +#endif /* __SIZEOF_SIZE_T__ */ + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace diff --git a/libstdc++-v3/libsupc++/hash_bytes.h b/libstdc++-v3/libsupc++/hash_bytes.h new file mode 100644 index 000000000..2f0c0eac6 --- /dev/null +++ b/libstdc++-v3/libsupc++/hash_bytes.h @@ -0,0 +1,59 @@ +// Declarations for hash functions. -*- C++ -*- + +// Copyright (C) 2010, 2011 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 3, 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file bits/hash_bytes.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{functional} + */ + +#ifndef _HASH_BYTES_H +#define _HASH_BYTES_H 1 + +#pragma GCC system_header + +#include <bits/c++config.h> + +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // Hash function implementation for the nontrivial specialization. + // All of them are based on a primitive that hashes a pointer to a + // byte array. The actual hash algorithm is not guaranteed to stay + // the same from release to release -- it may be updated or tuned to + // improve hash quality or speed. + size_t + _Hash_bytes(const void* __ptr, size_t __len, size_t __seed); + + // A similar hash primitive, using the FNV hash algorithm. This + // algorithm is guaranteed to stay the same from release to release. + // (although it might not produce the same values on different + // machines.) + size_t + _Fnv_hash_bytes(const void* __ptr, size_t __len, size_t __seed); + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace + +#endif diff --git a/libstdc++-v3/libsupc++/initializer_list b/libstdc++-v3/libsupc++/initializer_list new file mode 100644 index 000000000..1048d44de --- /dev/null +++ b/libstdc++-v3/libsupc++/initializer_list @@ -0,0 +1,102 @@ +// std::initializer_list support -*- C++ -*- + +// Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file initializer_list + * This is a Standard C++ Library header. + */ + +#ifndef _INITIALIZER_LIST +#define _INITIALIZER_LIST + +#pragma GCC system_header + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + +#pragma GCC visibility push(default) + +#include <bits/c++config.h> + +namespace std +{ + /// initializer_list + template<class _E> + class initializer_list + { + public: + typedef _E value_type; + typedef const _E& reference; + typedef const _E& const_reference; + typedef size_t size_type; + typedef const _E* iterator; + typedef const _E* const_iterator; + + private: + iterator _M_array; + size_type _M_len; + + // The compiler can call a private constructor. + constexpr initializer_list(const_iterator __a, size_type __l) + : _M_array(__a), _M_len(__l) { } + + public: + constexpr initializer_list() : _M_array(0), _M_len(0) { } + + // Number of elements. + constexpr size_type + size() { return _M_len; } + + // First element. + constexpr const_iterator + begin() { return _M_array; } + + // One past the last element. + constexpr const_iterator + end() { return begin() + size(); } + }; + + /** + * @brief Return an iterator pointing to the first element of + * the initilizer_list. + * @param il Initializer list. + */ + template<class _Tp> + constexpr const _Tp* + begin(initializer_list<_Tp> __ils) + { return __ils.begin(); } + + /** + * @brief Return an iterator pointing to one past the last element + * of the initilizer_list. + * @param il Initializer list. + */ + template<class _Tp> + constexpr const _Tp* + end(initializer_list<_Tp> __ils) + { return __ils.end(); } +} + +#pragma GCC visibility pop +#endif // C++0x +#endif // _INITIALIZER_LIST diff --git a/libstdc++-v3/libsupc++/nested_exception.cc b/libstdc++-v3/libsupc++/nested_exception.cc new file mode 100644 index 000000000..ecbc4c811 --- /dev/null +++ b/libstdc++-v3/libsupc++/nested_exception.cc @@ -0,0 +1,31 @@ +// Copyright (C) 2011 Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <exception> + +namespace std +{ +#ifdef _GLIBCXX_ATOMIC_BUILTINS_4 + nested_exception::~nested_exception() = default; +#endif +} // namespace std diff --git a/libstdc++-v3/libsupc++/nested_exception.h b/libstdc++-v3/libsupc++/nested_exception.h new file mode 100644 index 000000000..d4804bbed --- /dev/null +++ b/libstdc++-v3/libsupc++/nested_exception.h @@ -0,0 +1,166 @@ +// Nested Exception support header (nested_exception class) for -*- C++ -*- + +// Copyright (C) 2009, 2010, 2011 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 3, 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file bits/nested_exception.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{exception} + */ + +#ifndef _GLIBCXX_NESTED_EXCEPTION_H +#define _GLIBCXX_NESTED_EXCEPTION_H 1 + +#pragma GCC visibility push(default) + +#ifndef __GXX_EXPERIMENTAL_CXX0X__ +# include <bits/c++0x_warning.h> +#else + +#include <bits/c++config.h> + +#if !defined(_GLIBCXX_ATOMIC_BUILTINS_4) +# error This platform does not support exception propagation. +#endif + +extern "C++" { + +namespace std +{ + /** + * @addtogroup exceptions + * @{ + */ + + /// Exception class with exception_ptr data member. + class nested_exception + { + exception_ptr _M_ptr; + + public: + nested_exception() throw() : _M_ptr(current_exception()) { } + + nested_exception(const nested_exception&) = default; + + nested_exception& operator=(const nested_exception&) = default; + + virtual ~nested_exception(); + + void + rethrow_nested() const __attribute__ ((__noreturn__)) + { rethrow_exception(_M_ptr); } + + exception_ptr + nested_ptr() const + { return _M_ptr; } + }; + + template<typename _Except> + struct _Nested_exception : public _Except, public nested_exception + { + explicit _Nested_exception(_Except&& __ex) + : _Except(static_cast<_Except&&>(__ex)) + { } + }; + + template<typename _Ex> + struct __get_nested_helper + { + static const nested_exception* + _S_get(const _Ex& __ex) + { return dynamic_cast<const nested_exception*>(&__ex); } + }; + + template<typename _Ex> + struct __get_nested_helper<_Ex*> + { + static const nested_exception* + _S_get(const _Ex* __ex) + { return dynamic_cast<const nested_exception*>(__ex); } + }; + + template<typename _Ex> + inline const nested_exception* + __get_nested_exception(const _Ex& __ex) + { return __get_nested_helper<_Ex>::_S_get(__ex); } + + template<typename _Ex> + void + __throw_with_nested(_Ex&&, const nested_exception* = 0) + __attribute__ ((__noreturn__)); + + template<typename _Ex> + void + __throw_with_nested(_Ex&&, ...) __attribute__ ((__noreturn__)); + + // This function should never be called, but is needed to avoid a warning + // about ambiguous base classes when instantiating throw_with_nested<_Ex>() + // with a type that has an accessible nested_exception base. + template<typename _Ex> + inline void + __throw_with_nested(_Ex&& __ex, const nested_exception*) + { throw __ex; } + + template<typename _Ex> + inline void + __throw_with_nested(_Ex&& __ex, ...) + { throw _Nested_exception<_Ex>(static_cast<_Ex&&>(__ex)); } + + template<typename _Ex> + void + throw_with_nested(_Ex __ex) __attribute__ ((__noreturn__)); + + /// If @p __ex is derived from nested_exception, @p __ex. + /// Else, an implementation-defined object derived from both. + template<typename _Ex> + inline void + throw_with_nested(_Ex __ex) + { + if (__get_nested_exception(__ex)) + throw __ex; + __throw_with_nested(static_cast<_Ex&&>(__ex), &__ex); + } + + /// If @p __ex is derived from nested_exception, @p __ex.rethrow_nested(). + template<typename _Ex> + inline void + rethrow_if_nested(const _Ex& __ex) + { + if (const nested_exception* __nested = __get_nested_exception(__ex)) + __nested->rethrow_nested(); + } + + /// Overload, See N2619 + inline void + rethrow_if_nested(const nested_exception& __ex) + { __ex.rethrow_nested(); } + + // @} group exceptions +} // namespace std + +} // extern "C++" + +#endif // __GXX_EXPERIMENTAL_CXX0X__ + +#pragma GCC visibility pop + +#endif // _GLIBCXX_NESTED_EXCEPTION_H diff --git a/libstdc++-v3/libsupc++/new b/libstdc++-v3/libsupc++/new new file mode 100644 index 000000000..80ee3ba0f --- /dev/null +++ b/libstdc++-v3/libsupc++/new @@ -0,0 +1,114 @@ +// The -*- C++ -*- dynamic memory management header. + +// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +// 2003, 2004, 2005, 2006, 2007, 2009, 2010 +// Free Software Foundation + +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file new + * This is a Standard C++ Library header. + * + * 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 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <exception> + +#pragma GCC visibility push(default) + +extern "C++" { + +namespace std +{ + /** + * @brief Exception possibly thrown by @c new. + * @ingroup exceptions + * + * @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(); + + // See comment in eh_exception.cc. + virtual const char* what() const 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) throw(); +} // 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; } + +// Default placement versions of operator delete. +inline void operator delete (void*, void*) throw() { } +inline void operator delete[](void*, void*) throw() { } +//@} +} // extern "C++" + +#pragma GCC visibility pop + +#endif diff --git a/libstdc++-v3/libsupc++/new_handler.cc b/libstdc++-v3/libsupc++/new_handler.cc new file mode 100644 index 000000000..4e3c93545 --- /dev/null +++ b/libstdc++-v3/libsupc++/new_handler.cc @@ -0,0 +1,41 @@ +// Implementation file for the -*- C++ -*- dynamic memory management header. + +// Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +// 2005, 2006, 2007, 2008, 2009, 2010 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#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) throw() +{ + new_handler prev_handler = __new_handler; + __new_handler = handler; + return prev_handler; +} diff --git a/libstdc++-v3/libsupc++/new_op.cc b/libstdc++-v3/libsupc++/new_op.cc new file mode 100644 index 000000000..c61e941bc --- /dev/null +++ b/libstdc++-v3/libsupc++/new_op.cc @@ -0,0 +1,67 @@ +// Support routines for the -*- C++ -*- dynamic memory management. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2009, 2011 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <bits/c++config.h> +#include <cstdlib> +#include <bits/exception_defines.h> +#include "new" + +using std::new_handler; +using std::bad_alloc; +#if _GLIBCXX_HOSTED +using std::malloc; +#else +// A freestanding C runtime may not provide "malloc" -- but there is no +// other reasonable way to implement "operator new". +extern "C" void *malloc (std::size_t); +#endif + +extern new_handler __new_handler; + +_GLIBCXX_WEAK_DEFINITION 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/libstdc++-v3/libsupc++/new_opnt.cc b/libstdc++-v3/libsupc++/new_opnt.cc new file mode 100644 index 000000000..1bcdead58 --- /dev/null +++ b/libstdc++-v3/libsupc++/new_opnt.cc @@ -0,0 +1,63 @@ +// Support routines for the -*- C++ -*- dynamic memory management. +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2004, 2009, 2011 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <bits/c++config.h> +#include <bits/exception_defines.h> +#include "new" + +using std::new_handler; +using std::bad_alloc; + +extern "C" void *malloc (std::size_t); +extern new_handler __new_handler; + +_GLIBCXX_WEAK_DEFINITION 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(const bad_alloc&) + { + return 0; + } + + p = (void *) malloc (sz); + } + + return p; +} diff --git a/libstdc++-v3/libsupc++/new_opv.cc b/libstdc++-v3/libsupc++/new_opv.cc new file mode 100644 index 000000000..b200e23c3 --- /dev/null +++ b/libstdc++-v3/libsupc++/new_opv.cc @@ -0,0 +1,33 @@ +// Boilerplate support routines for -*- C++ -*- dynamic memory management. + +// Copyright (C) 1997, 1998, 1999, 2000, 2004, 2009 Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <bits/c++config.h> +#include "new" + +_GLIBCXX_WEAK_DEFINITION void* +operator new[] (std::size_t sz) throw (std::bad_alloc) +{ + return ::operator new(sz); +} diff --git a/libstdc++-v3/libsupc++/new_opvnt.cc b/libstdc++-v3/libsupc++/new_opvnt.cc new file mode 100644 index 000000000..da4ae80b6 --- /dev/null +++ b/libstdc++-v3/libsupc++/new_opvnt.cc @@ -0,0 +1,33 @@ +// Boilerplate support routines for -*- C++ -*- dynamic memory management. + +// Copyright (C) 1997, 1998, 1999, 2000, 2004, 2009 Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <bits/c++config.h> +#include "new" + +_GLIBCXX_WEAK_DEFINITION void* +operator new[] (std::size_t sz, const std::nothrow_t& nothrow) throw() +{ + return ::operator new(sz, nothrow); +} diff --git a/libstdc++-v3/libsupc++/pbase_type_info.cc b/libstdc++-v3/libsupc++/pbase_type_info.cc new file mode 100644 index 000000000..f79d9e968 --- /dev/null +++ b/libstdc++-v3/libsupc++/pbase_type_info.cc @@ -0,0 +1,66 @@ +// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007, +// 2009, 2010 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include "tinfo.h" + +namespace __cxxabiv1 { + +__pbase_type_info:: +~__pbase_type_info () +{} + +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 + +#ifdef __GXX_RTTI + if (typeid (*this) != typeid (*thr_type)) + return false; // not both same kind of pointers +#endif + + if (!(outer & 1)) + // We're not the same and our outer pointers are not all const qualified + // Therefore there must at least be a qualification conversion involved + // But for that to be valid, our outer pointers must be const qualified. + return false; + + const __pbase_type_info *thrown_type = + static_cast <const __pbase_type_info *> (thr_type); + + if (thrown_type->__flags & ~__flags) + // We're less qualified. + return false; + + if (!(__flags & __const_mask)) + outer &= ~1; + + return __pointer_catch (thrown_type, thr_obj, outer); +} + +} diff --git a/libstdc++-v3/libsupc++/pmem_type_info.cc b/libstdc++-v3/libsupc++/pmem_type_info.cc new file mode 100644 index 000000000..b0409172d --- /dev/null +++ b/libstdc++-v3/libsupc++/pmem_type_info.cc @@ -0,0 +1,49 @@ +// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007, 2009 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include "tinfo.h" + +namespace __cxxabiv1 { + +__pointer_to_member_type_info:: +~__pointer_to_member_type_info () +{} + +bool __pointer_to_member_type_info:: +__pointer_catch (const __pbase_type_info *thr_type, + void **thr_obj, + unsigned outer) const +{ + // This static cast is always valid, as our caller will have determined that + // thr_type is really a __pointer_to_member_type_info. + const __pointer_to_member_type_info *thrown_type = + static_cast <const __pointer_to_member_type_info *> (thr_type); + + if (*__context != *thrown_type->__context) + return false; // not pointers to member of same class + + return __pbase_type_info::__pointer_catch (thrown_type, thr_obj, outer); +} + +} diff --git a/libstdc++-v3/libsupc++/pointer_type_info.cc b/libstdc++-v3/libsupc++/pointer_type_info.cc new file mode 100644 index 000000000..be96308bf --- /dev/null +++ b/libstdc++-v3/libsupc++/pointer_type_info.cc @@ -0,0 +1,56 @@ +// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007, +// 2009, 2010 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include "tinfo.h" + +namespace __cxxabiv1 { + +__pointer_type_info:: +~__pointer_type_info () +{} + +bool __pointer_type_info:: +__is_pointer_p () const +{ + return true; +} + +bool __pointer_type_info:: +__pointer_catch (const __pbase_type_info *thrown_type, + void **thr_obj, + unsigned outer) const +{ +#ifdef __GXX_RTTI + if (outer < 2 && *__pointee == typeid (void)) + { + // conversion to void + return !thrown_type->__pointee->__is_function_p (); + } +#endif + + return __pbase_type_info::__pointer_catch (thrown_type, thr_obj, outer); +} + +} diff --git a/libstdc++-v3/libsupc++/pure.cc b/libstdc++-v3/libsupc++/pure.cc new file mode 100644 index 000000000..acf72327a --- /dev/null +++ b/libstdc++-v3/libsupc++/pure.cc @@ -0,0 +1,51 @@ +// -*- C++ -*- +// Copyright (C) 2000, 2001, 2009 Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <bits/c++config.h> +#include <cxxabi.h> +#include "unwind-cxx.h" + +#if _GLIBCXX_HOSTED +#ifdef _GLIBCXX_HAVE_UNISTD_H +# include <unistd.h> +# 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 <cstdio> +# define writestr(str) std::fputs(str, stderr) +#endif +#else +# define writestr(str) /* Empty */ +#endif + +extern "C" void +__cxxabiv1::__cxa_pure_virtual (void) +{ + writestr ("pure virtual method called\n"); + std::terminate (); +} diff --git a/libstdc++-v3/libsupc++/si_class_type_info.cc b/libstdc++-v3/libsupc++/si_class_type_info.cc new file mode 100644 index 000000000..829e71fad --- /dev/null +++ b/libstdc++-v3/libsupc++/si_class_type_info.cc @@ -0,0 +1,85 @@ +// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007, 2009 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include "tinfo.h" + +namespace __cxxabiv1 { + +__si_class_type_info:: +~__si_class_type_info () +{} + +__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); +} + +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 <void> (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); +} + +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); +} + +} diff --git a/libstdc++-v3/libsupc++/tinfo.cc b/libstdc++-v3/libsupc++/tinfo.cc new file mode 100644 index 000000000..d939a3fda --- /dev/null +++ b/libstdc++-v3/libsupc++/tinfo.cc @@ -0,0 +1,81 @@ +// Methods for type_info for -*- C++ -*- Run Time Type Identification. +// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +// 2003, 2004, 2005, 2006, 2007, 2009 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <bits/c++config.h> +#include <cstddef> +#include "tinfo.h" + +std::type_info:: +~type_info () +{ } + +#if !__GXX_TYPEINFO_EQUALITY_INLINE + +// We can't rely on common symbols being shared between shared objects. +bool std::type_info:: +operator== (const std::type_info& arg) const +{ +#if __GXX_MERGED_TYPEINFO_NAMES + return name () == arg.name (); +#else + return (&arg == this) + || (name ()[0] != '*' && (__builtin_strcmp (name (), arg.name ()) == 0)); +#endif +} + +#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; +} + +} diff --git a/libstdc++-v3/libsupc++/tinfo.h b/libstdc++-v3/libsupc++/tinfo.h new file mode 100644 index 000000000..b3e22232f --- /dev/null +++ b/libstdc++-v3/libsupc++/tinfo.h @@ -0,0 +1,183 @@ +// RTTI support internals for -*- C++ -*- +// Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2004, 2009 +// Free Software Foundation + +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include "typeinfo" +#include <cstddef> + +// Class declarations shared between the typeinfo implementation files. + +#include <cxxabi.h> + +namespace __cxxabiv1 { + +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); +} + +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 +{ + // Offset to most derived object. + ptrdiff_t whole_object; + + // Additional padding if necessary. +#ifdef _GLIBCXX_VTABLE_PADDING + ptrdiff_t padding1; +#endif + + // Pointer to most derived type_info. + const __class_type_info *whole_type; + + // Additional padding if necessary. +#ifdef _GLIBCXX_VTABLE_PADDING + ptrdiff_t padding2; +#endif + + // What a class's vptr points to. + const void *origin; +}; + +template <typename T> +inline const T * +adjust_pointer (const void *base, ptrdiff_t offset) +{ + return reinterpret_cast <const T *> + (reinterpret_cast <const char *> (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 <const void *const *> (addr); + + offset = *adjust_pointer<ptrdiff_t> (vtable, offset); + } + + return adjust_pointer<void> (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 <const __class_type_info *> (0) + 1; + +} // namespace + +// __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 + __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 + + __dyncast_result (int details_ = __vmi_class_type_info::__flags_unknown_mask) + :dst_ptr (NULL), whole2dst (__unknown), + whole2src (__unknown), dst2src (__unknown), + whole_details (details_) + {} + +protected: + __dyncast_result(const __dyncast_result&); + + __dyncast_result& + operator=(const __dyncast_result&); +}; + +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 <void> (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); +} + +} diff --git a/libstdc++-v3/libsupc++/tinfo2.cc b/libstdc++-v3/libsupc++/tinfo2.cc new file mode 100644 index 000000000..0182c6cc0 --- /dev/null +++ b/libstdc++-v3/libsupc++/tinfo2.cc @@ -0,0 +1,45 @@ +// Methods for type_info for -*- C++ -*- Run Time Type Identification. + +// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2009 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <cstddef> +#include "tinfo.h" + +using std::type_info; + +#if !__GXX_TYPEINFO_EQUALITY_INLINE + +bool +type_info::before (const type_info &arg) const +{ +#if __GXX_MERGED_TYPEINFO_NAMES + return name () < arg.name (); +#else + return (name ()[0] == '*') ? name () < arg.name () + : __builtin_strcmp (name (), arg.name ()) < 0; +#endif +} + +#endif diff --git a/libstdc++-v3/libsupc++/typeinfo b/libstdc++-v3/libsupc++/typeinfo new file mode 100644 index 000000000..69311d69e --- /dev/null +++ b/libstdc++-v3/libsupc++/typeinfo @@ -0,0 +1,224 @@ +// RTTI support for -*- C++ -*- +// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +// 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file typeinfo + * This is a Standard C++ Library header. + */ + +#ifndef _TYPEINFO +#define _TYPEINFO + +#pragma GCC system_header + +#include <exception> +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +#include <bits/hash_bytes.h> +#endif + + +#pragma GCC visibility push(default) + +extern "C++" { + +namespace __cxxabiv1 +{ + class __class_type_info; +} // namespace __cxxabiv1 + +// Determine whether typeinfo names for the same type are merged (in which +// case comparison can just compare pointers) or not (in which case strings +// must be compared), and whether comparison is to be implemented inline or +// not. We used to do inline pointer comparison by default if weak symbols +// are available, but even with weak symbols sometimes names are not merged +// when objects are loaded with RTLD_LOCAL, so now we always use strcmp by +// default. For ABI compatibility, we do the strcmp inline if weak symbols +// are available, and out-of-line if not. Out-of-line pointer comparison +// is used where the object files are to be portable to multiple systems, +// some of which may not be able to use pointer comparison, but the +// particular system for which libstdc++ is being built can use pointer +// comparison; in particular for most ARM EABI systems, where the ABI +// specifies out-of-line comparison. The compiler's target configuration +// can override the defaults by defining __GXX_TYPEINFO_EQUALITY_INLINE to +// 1 or 0 to indicate whether or not comparison is inline, and +// __GXX_MERGED_TYPEINFO_NAMES to 1 or 0 to indicate whether or not pointer +// comparison can be used. + +#ifndef __GXX_MERGED_TYPEINFO_NAMES +// By default, typeinfo names are not merged. +#define __GXX_MERGED_TYPEINFO_NAMES 0 +#endif + +// By default follow the old inline rules to avoid ABI changes. +#ifndef __GXX_TYPEINFO_EQUALITY_INLINE + #if !__GXX_WEAK__ + #define __GXX_TYPEINFO_EQUALITY_INLINE 0 + #else + #define __GXX_TYPEINFO_EQUALITY_INLINE 1 + #endif +#endif + +namespace std +{ + /** + * @brief Part of RTTI. + * + * The @c type_info class describes type information generated by + * an implementation. + */ + class type_info + { + public: + /** Destructor first. 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(); + + /** Returns an @e implementation-defined byte string; this is not + * portable between compilers! */ + const char* name() const + { return __name[0] == '*' ? __name + 1 : __name; } + +#if !__GXX_TYPEINFO_EQUALITY_INLINE + // 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 before(const type_info& __arg) const; + bool operator==(const type_info& __arg) const; +#else + #if !__GXX_MERGED_TYPEINFO_NAMES + /** Returns true if @c *this precedes @c __arg in the implementation's + * collation order. */ + // Even with the new abi, on systems that support dlopen + // we can run into cases where type_info names aren't merged, + // so we still need to do string comparison. + bool before(const type_info& __arg) const + { return (__name[0] == '*' && __arg.__name[0] == '*') + ? __name < __arg.__name + : __builtin_strcmp (__name, __arg.__name) < 0; } + + bool operator==(const type_info& __arg) const + { + return ((__name == __arg.__name) + || (__name[0] != '*' && + __builtin_strcmp (__name, __arg.__name) == 0)); + } + #else + // On some targets 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 +#endif + bool operator!=(const type_info& __arg) const + { return !operator==(__arg); } + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + size_t hash_code() const throw() + { +# if !__GXX_MERGED_TYPEINFO_NAMES + return _Hash_bytes(name(), __builtin_strlen(name()), + static_cast<size_t>(0xc70f6907UL)); +# else + return reinterpret_cast<size_t>(__name); +# endif + } +#endif // __GXX_EXPERIMENTAL_CXX0X__ + + // 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; + + protected: + const char *__name; + + explicit type_info(const char *__n): __name(__n) { } + + private: + /// Assigning type_info is not supported. + type_info& operator=(const type_info&); + type_info(const type_info&); + }; + + /** + * @brief Thrown during incorrect typecasting. + * @ingroup exceptions + * + * 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(); + + // See comment in eh_exception.cc. + virtual const char* what() const throw(); + }; + + /** + * @brief Thrown when a NULL pointer in a @c typeid expression is used. + * @ingroup exceptions + */ + 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(); + + // See comment in eh_exception.cc. + virtual const char* what() const throw(); + }; +} // namespace std + +#pragma GCC visibility pop + +} // extern "C++" +#endif diff --git a/libstdc++-v3/libsupc++/unwind-cxx.h b/libstdc++-v3/libsupc++/unwind-cxx.h new file mode 100644 index 000000000..e62ea7c38 --- /dev/null +++ b/libstdc++-v3/libsupc++/unwind-cxx.h @@ -0,0 +1,419 @@ +// -*- C++ -*- Exception handling and frame unwind runtime interface routines. +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 +// Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// 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 <typeinfo> +#include <exception> +#include <cstddef> +#include "unwind.h" +#include <bits/atomic_word.h> + +#pragma GCC visibility push(default) + +namespace __cxxabiv1 +{ + +// A primary 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; + +#ifdef __ARM_EABI_UNWINDER__ + // Stack of exceptions in cleanups. + __cxa_exception* nextPropagatingException; + + // The nuber of active cleanup handlers for this exception. + int propagationCount; +#else + // 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; + _Unwind_Ptr catchTemp; + void *adjustedPtr; +#endif + + // The generic exception header. Must be last. + _Unwind_Exception unwindHeader; +}; + +struct __cxa_refcounted_exception +{ + // Manage this header. + _Atomic_word referenceCount; + // __cxa_exception must be last, and no padding can be after it. + __cxa_exception exc; +}; + +// A dependent C++ exception object consists of a wrapper around an unwind +// object header with additional C++ specific information, containing a pointer +// to a primary exception object. + +struct __cxa_dependent_exception +{ + // The primary exception this thing depends on. + void *primaryException; + + // 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; + +#ifdef __ARM_EABI_UNWINDER__ + // Stack of exceptions in cleanups. + __cxa_exception* nextPropagatingException; + + // The nuber of active cleanup handlers for this exception. + int propagationCount; +#else + // 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; + _Unwind_Ptr catchTemp; + void *adjustedPtr; +#endif + + // 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; +#ifdef __ARM_EABI_UNWINDER__ + __cxa_exception* propagatingExceptions; +#endif +}; + + +// 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() + __attribute__ ((__const__)); +extern "C" __cxa_eh_globals *__cxa_get_globals_fast () throw() + __attribute__ ((__const__)); + +// Allocate memory for the primary exception plus the thrown object. +extern "C" void *__cxa_allocate_exception(std::size_t thrown_size) throw(); + +// Free the space allocated for the primary exception. +extern "C" void __cxa_free_exception(void *thrown_exception) throw(); + +// Allocate memory for a dependent exception. +extern "C" __cxa_dependent_exception* +__cxa_allocate_dependent_exception() throw(); + +// Free the space allocated for the dependent exception. +extern "C" void +__cxa_free_dependent_exception(__cxa_dependent_exception *ex) 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_get_exception_ptr (void *) throw() + __attribute__ ((__pure__)); +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 () __attribute__((__noreturn__)); +extern "C" void __cxa_bad_typeid () __attribute__((__noreturn__)); + +// @@@ 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__)); +extern "C" void __cxa_call_terminate (_Unwind_Exception*) throw () + __attribute__((__noreturn__)); + +#ifdef __ARM_EABI_UNWINDER__ +// Arm EABI specified routines. +typedef enum { + ctm_failed = 0, + ctm_succeeded = 1, + ctm_succeeded_with_ptr_to_base = 2 +} __cxa_type_match_result; +extern "C" __cxa_type_match_result __cxa_type_match(_Unwind_Exception*, + const std::type_info*, + bool, void**); +extern "C" bool __cxa_begin_cleanup (_Unwind_Exception*); +extern "C" void __cxa_end_cleanup (void); +#endif + +// Invokes given handler, dying appropriately if the user handler was +// so inconsiderate as to return. +extern void __terminate(std::terminate_handler) throw () + __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. + +// 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; +} + +// Acquire the C++ refcounted exception header from the C++ object. +static inline __cxa_refcounted_exception * +__get_refcounted_exception_header_from_obj (void *ptr) +{ + return reinterpret_cast<__cxa_refcounted_exception *>(ptr) - 1; +} + +// Acquire the C++ refcounted exception header from the generic exception +// header. +static inline __cxa_refcounted_exception * +__get_refcounted_exception_header_from_ue (_Unwind_Exception *exc) +{ + return reinterpret_cast<__cxa_refcounted_exception *>(exc + 1) - 1; +} + +static inline __cxa_dependent_exception * +__get_dependent_exception_from_ue (_Unwind_Exception *exc) +{ + return reinterpret_cast<__cxa_dependent_exception *>(exc + 1) - 1; +} + +#ifdef __ARM_EABI_UNWINDER__ +static inline bool +__is_gxx_exception_class(_Unwind_Exception_Class c) +{ + // TODO: Take advantage of the fact that c will always be word aligned. + return c[0] == 'G' + && c[1] == 'N' + && c[2] == 'U' + && c[3] == 'C' + && c[4] == 'C' + && c[5] == '+' + && c[6] == '+' + && (c[7] == '\0' || c[7] == '\x01'); +} + +// Only checks for primary or dependent, but not that it is a C++ exception at +// all. +static inline bool +__is_dependent_exception(_Unwind_Exception_Class c) +{ + return c[7] == '\x01'; +} + +static inline void +__GXX_INIT_PRIMARY_EXCEPTION_CLASS(_Unwind_Exception_Class c) +{ + c[0] = 'G'; + c[1] = 'N'; + c[2] = 'U'; + c[3] = 'C'; + c[4] = 'C'; + c[5] = '+'; + c[6] = '+'; + c[7] = '\0'; +} + +static inline void +__GXX_INIT_DEPENDENT_EXCEPTION_CLASS(_Unwind_Exception_Class c) +{ + c[0] = 'G'; + c[1] = 'N'; + c[2] = 'U'; + c[3] = 'C'; + c[4] = 'C'; + c[5] = '+'; + c[6] = '+'; + c[7] = '\x01'; +} + +static inline bool +__is_gxx_forced_unwind_class(_Unwind_Exception_Class c) +{ + return c[0] == 'G' + && c[1] == 'N' + && c[2] == 'U' + && c[3] == 'C' + && c[4] == 'F' + && c[5] == 'O' + && c[6] == 'R' + && c[7] == '\0'; +} + +static inline void +__GXX_INIT_FORCED_UNWIND_CLASS(_Unwind_Exception_Class c) +{ + c[0] = 'G'; + c[1] = 'N'; + c[2] = 'U'; + c[3] = 'C'; + c[4] = 'F'; + c[5] = 'O'; + c[6] = 'R'; + c[7] = '\0'; +} + +static inline void* +__gxx_caught_object(_Unwind_Exception* eo) +{ + return (void*)eo->barrier_cache.bitpattern[0]; +} +#else // !__ARM_EABI_UNWINDER__ +// This is the primary exception class we report -- "GNUCC++\0". +const _Unwind_Exception_Class __gxx_primary_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'); + +// This is the dependent (from std::rethrow_exception) exception class we report +// "GNUCC++\x01" +const _Unwind_Exception_Class __gxx_dependent_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) '\x01'); + +static inline bool +__is_gxx_exception_class(_Unwind_Exception_Class c) +{ + return c == __gxx_primary_exception_class + || c == __gxx_dependent_exception_class; +} + +// Only checks for primary or dependent, but not that it is a C++ exception at +// all. +static inline bool +__is_dependent_exception(_Unwind_Exception_Class c) +{ + return (c & 1); +} + +#define __GXX_INIT_PRIMARY_EXCEPTION_CLASS(c) c = __gxx_primary_exception_class +#define __GXX_INIT_DEPENDENT_EXCEPTION_CLASS(c) \ + c = __gxx_dependent_exception_class + +// 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 *); + +static inline void* +__gxx_caught_object(_Unwind_Exception* eo) +{ + // Bad as it looks, this actually works for dependent exceptions too. + __cxa_exception* header = __get_exception_header_from_ue (eo); + return header->adjustedPtr; +} +#endif // !__ARM_EABI_UNWINDER__ + +static inline void* +__get_object_from_ue(_Unwind_Exception* eo) throw() +{ + return __is_dependent_exception (eo->exception_class) ? + __get_dependent_exception_from_ue (eo)->primaryException : + eo + 1; +} + +static inline void * +__get_object_from_ambiguous_exception(__cxa_exception *p_or_d) throw() +{ + return __get_object_from_ue (&p_or_d->unwindHeader); +} + + +} /* namespace __cxxabiv1 */ + +#pragma GCC visibility pop + +#endif // _UNWIND_CXX_H diff --git a/libstdc++-v3/libsupc++/vec.cc b/libstdc++-v3/libsupc++/vec.cc new file mode 100644 index 000000000..700c5ef43 --- /dev/null +++ b/libstdc++-v3/libsupc++/vec.cc @@ -0,0 +1,516 @@ +// New abi Support -*- C++ -*- + +// Copyright (C) 2000, 2001, 2003, 2004, 2009, 2011 +// Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// Written by Nathan Sidwell, Codesourcery LLC, <nathan@codesourcery.com> + +#include <cxxabi.h> +#include <new> +#include <exception> +#include <bits/exception_defines.h> +#include "unwind-cxx.h" + +namespace __cxxabiv1 +{ + namespace + { + struct uncatch_exception + { + uncatch_exception(); + ~uncatch_exception () { __cxa_begin_catch (&p->unwindHeader); } + + __cxa_exception* p; + + private: + uncatch_exception& + operator=(const uncatch_exception&); + + uncatch_exception(const uncatch_exception&); + }; + + uncatch_exception::uncatch_exception() : p(0) + { + __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, + __cxa_cdtor_type constructor, + __cxa_cdtor_type destructor) + { + 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, + __cxa_cdtor_type constructor, + __cxa_cdtor_type destructor, + void *(*alloc) (std::size_t), + void (*dealloc) (void *)) + { + std::size_t size = element_count * element_size + padding_size; + char *base = static_cast <char *> (alloc (size)); + if (!base) + return base; + + if (padding_size) + { + base += padding_size; + reinterpret_cast <std::size_t *> (base)[-1] = element_count; +#ifdef _GLIBCXX_ELTSIZE_IN_COOKIE + reinterpret_cast <std::size_t *> (base)[-2] = element_size; +#endif + } + __try + { + __cxa_vec_ctor(base, element_count, element_size, + constructor, destructor); + } + __catch(...) + { + { + uncatch_exception ue; + // Core issue 901 will probably be resolved such that a + // deleted operator delete means not freeing memory here. + if (dealloc) + 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, + __cxa_cdtor_type constructor, + __cxa_cdtor_type destructor, + 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<char *>(alloc (size)); + if (!base) + return base; + + if (padding_size) + { + base += padding_size; + reinterpret_cast<std::size_t *>(base)[-1] = element_count; +#ifdef _GLIBCXX_ELTSIZE_IN_COOKIE + reinterpret_cast <std::size_t *> (base)[-2] = element_size; +#endif + } + __try + { + __cxa_vec_ctor(base, element_count, element_size, + constructor, destructor); + } + __catch(...) + { + { + uncatch_exception ue; + if (dealloc) + dealloc(base - padding_size, size); + } + __throw_exception_again; + } + return base; + } + + // Construct array. + extern "C" __cxa_vec_ctor_return_type + __cxa_vec_ctor(void *array_address, + std::size_t element_count, + std::size_t element_size, + __cxa_cdtor_type constructor, + __cxa_cdtor_type destructor) + { + std::size_t ix = 0; + char *ptr = static_cast<char *>(array_address); + + __try + { + if (constructor) + for (; ix != element_count; ix++, ptr += element_size) + constructor(ptr); + } + __catch(...) + { + { + uncatch_exception ue; + __cxa_vec_cleanup(array_address, ix, element_size, destructor); + } + __throw_exception_again; + } + _GLIBCXX_CXA_VEC_CTOR_RETURN (array_address); + } + + // Construct an array by copying. + extern "C" __cxa_vec_ctor_return_type + __cxa_vec_cctor(void *dest_array, + void *src_array, + std::size_t element_count, + std::size_t element_size, + __cxa_cdtor_return_type (*constructor) (void *, void *), + __cxa_cdtor_type destructor) + { + std::size_t ix = 0; + char *dest_ptr = static_cast<char *>(dest_array); + char *src_ptr = static_cast<char *>(src_array); + + __try + { + if (constructor) + for (; ix != element_count; + ix++, src_ptr += element_size, dest_ptr += element_size) + constructor(dest_ptr, src_ptr); + } + __catch(...) + { + { + uncatch_exception ue; + __cxa_vec_cleanup(dest_array, ix, element_size, destructor); + } + __throw_exception_again; + } + _GLIBCXX_CXA_VEC_CTOR_RETURN (dest_array); + } + + // Destruct array. + extern "C" void + __cxa_vec_dtor(void *array_address, + std::size_t element_count, + std::size_t element_size, + __cxa_cdtor_type destructor) + { + if (destructor) + { + char *ptr = static_cast<char *>(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, + __cxa_cdtor_type destructor) throw() + { + if (destructor) + { + char *ptr = static_cast <char *> (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, + __cxa_cdtor_type destructor) + { + __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, + __cxa_cdtor_type destructor, + void (*dealloc) (void *)) + { + if (!array_address) + return; + + char* base = static_cast<char *>(array_address); + + if (padding_size) + { + std::size_t element_count = reinterpret_cast<std::size_t *>(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, + __cxa_cdtor_type destructor, + void (*dealloc) (void *, std::size_t)) + { + if (!array_address) + return; + + char* base = static_cast <char *> (array_address); + std::size_t size = 0; + + if (padding_size) + { + std::size_t element_count = reinterpret_cast<std::size_t *> (base)[-1]; + base -= padding_size; + size = element_count * element_size + padding_size; + __try + { + __cxa_vec_dtor(array_address, element_count, element_size, + destructor); + } + __catch(...) + { + { + uncatch_exception ue; + dealloc(base, size); + } + __throw_exception_again; + } + } + dealloc(base, size); + } +} // namespace __cxxabiv1 + +#if defined(__arm__) && defined(__ARM_EABI__) + +// The ARM C++ ABI requires that the library provide these additional +// helper functions. There are placed in this file, despite being +// architecture-specifier, so that the compiler can inline the __cxa +// functions into these functions as appropriate. + +namespace __aeabiv1 +{ + extern "C" void * + __aeabi_vec_ctor_nocookie_nodtor (void *array_address, + abi::__cxa_cdtor_type constructor, + std::size_t element_size, + std::size_t element_count) + { + return abi::__cxa_vec_ctor (array_address, element_count, element_size, + constructor, /*destructor=*/NULL); + } + + extern "C" void * + __aeabi_vec_ctor_cookie_nodtor (void *array_address, + abi::__cxa_cdtor_type constructor, + std::size_t element_size, + std::size_t element_count) + { + if (array_address == NULL) + return NULL; + + array_address = reinterpret_cast<std::size_t *>(array_address) + 2; + reinterpret_cast<std::size_t *>(array_address)[-2] = element_size; + reinterpret_cast<std::size_t *>(array_address)[-1] = element_count; + return abi::__cxa_vec_ctor (array_address, + element_count, element_size, + constructor, /*destructor=*/NULL); + } + + extern "C" void * + __aeabi_vec_cctor_nocookie_nodtor (void *dest_array, + void *src_array, + std::size_t element_size, + std::size_t element_count, + void *(*constructor) (void *, void *)) + { + return abi::__cxa_vec_cctor (dest_array, src_array, + element_count, element_size, + constructor, NULL); + } + + extern "C" void * + __aeabi_vec_new_cookie_noctor (std::size_t element_size, + std::size_t element_count) + { + return abi::__cxa_vec_new(element_count, element_size, + 2 * sizeof (std::size_t), + /*constructor=*/NULL, /*destructor=*/NULL); + } + + extern "C" void * + __aeabi_vec_new_nocookie (std::size_t element_size, + std::size_t element_count, + abi::__cxa_cdtor_type constructor) + { + return abi::__cxa_vec_new (element_count, element_size, 0, constructor, + NULL); + } + + extern "C" void * + __aeabi_vec_new_cookie_nodtor (std::size_t element_size, + std::size_t element_count, + abi::__cxa_cdtor_type constructor) + { + return abi::__cxa_vec_new(element_count, element_size, + 2 * sizeof (std::size_t), + constructor, NULL); + } + + extern "C" void * + __aeabi_vec_new_cookie(std::size_t element_size, + std::size_t element_count, + abi::__cxa_cdtor_type constructor, + abi::__cxa_cdtor_type destructor) + { + return abi::__cxa_vec_new (element_count, element_size, + 2 * sizeof (std::size_t), + constructor, destructor); + } + + + extern "C" void * + __aeabi_vec_dtor (void *array_address, + abi::__cxa_cdtor_type destructor, + std::size_t element_size, + std::size_t element_count) + { + abi::__cxa_vec_dtor (array_address, element_count, element_size, + destructor); + return reinterpret_cast<std::size_t*> (array_address) - 2; + } + + extern "C" void * + __aeabi_vec_dtor_cookie (void *array_address, + abi::__cxa_cdtor_type destructor) + { + if (!array_address) + return NULL; + + abi::__cxa_vec_dtor (array_address, + reinterpret_cast<std::size_t *>(array_address)[-1], + reinterpret_cast<std::size_t *>(array_address)[-2], + destructor); + return reinterpret_cast<std::size_t*> (array_address) - 2; + } + + + extern "C" void + __aeabi_vec_delete (void *array_address, + abi::__cxa_cdtor_type destructor) + { + if (!array_address) + return; + + abi::__cxa_vec_delete (array_address, + reinterpret_cast<std::size_t *>(array_address)[-2], + 2 * sizeof (std::size_t), + destructor); + } + + extern "C" void + __aeabi_vec_delete3 (void *array_address, + abi::__cxa_cdtor_type destructor, + void (*dealloc) (void *, std::size_t)) + { + if (!array_address) + return; + + abi::__cxa_vec_delete3 (array_address, + reinterpret_cast<std::size_t *>(array_address)[-2], + 2 * sizeof (std::size_t), + destructor, dealloc); + } + + extern "C" void + __aeabi_vec_delete3_nodtor (void *array_address, + void (*dealloc) (void *, std::size_t)) + { + if (!array_address) + return; + + abi::__cxa_vec_delete3 (array_address, + reinterpret_cast<std::size_t *>(array_address)[-2], + 2 * sizeof (std::size_t), + /*destructor=*/NULL, dealloc); + } +} // namespace __aeabiv1 + +#endif // defined(__arm__) && defined(__ARM_EABI__) diff --git a/libstdc++-v3/libsupc++/vmi_class_type_info.cc b/libstdc++-v3/libsupc++/vmi_class_type_info.cc new file mode 100644 index 000000000..195061d72 --- /dev/null +++ b/libstdc++-v3/libsupc++/vmi_class_type_info.cc @@ -0,0 +1,391 @@ +// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007, 2009 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC 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 3, or (at your option) +// any later version. + +// GCC 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include "tinfo.h" + +namespace __cxxabiv1 { + +__vmi_class_type_info:: +~__vmi_class_type_info () +{} + +__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_type->__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; +} + +// 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 <void> (obj_ptr, src2dst) == src_ptr + ? __contained_public : __not_contained; + else if (src2dst == -2) + result.dst2src = __not_contained; + return false; + } + + // If src_type is a unique non-virtual base of dst_type, we have a good + // guess at the address we want, so in the first pass try skipping any + // bases which don't contain that address. + const void *dst_cand = NULL; + if (src2dst >= 0) + dst_cand = adjust_pointer<void>(src_ptr, -src2dst); + bool first_pass = true; + bool skipped = false; + + bool result_ambig = false; + again: + 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 (dst_cand) + { + bool skip_on_first_pass = base > dst_cand; + if (skip_on_first_pass == first_pass) + { + // We aren't interested in this base on this pass: either + // we're on the first pass and this base doesn't contain the + // likely address, or we're on the second pass and we checked + // this base on the first pass. + skipped = true; + continue; + } + } + + 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_type->__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 && result2.dst_ptr != 0) + || (result.dst_ptr != 0 && result2_ambig) + || (result2.dst_ptr != 0 && result_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; + } + + if (skipped && first_pass) + { + // We didn't find dst where we expected it, so let's go back and try + // the bases we skipped (if any). + first_pass = false; + goto again; + } + + return result_ambig; +} + +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_type->__do_upcast (dst, base, result2)) + { + if (result2.base_type == nonvirtual_base_type && is_virtual) + result2.base_type = __base_info[i].__base_type; + 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; +} + +} diff --git a/libstdc++-v3/libsupc++/vterminate.cc b/libstdc++-v3/libsupc++/vterminate.cc new file mode 100644 index 000000000..96824bb0f --- /dev/null +++ b/libstdc++-v3/libsupc++/vterminate.cc @@ -0,0 +1,101 @@ +// Verbose terminate_handler -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004, 2005, 2009, 2011 Free Software Foundation +// +// 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 3, 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <bits/c++config.h> + +#if _GLIBCXX_HOSTED +#include <cstdlib> +#include <exception> +#include <bits/exception_defines.h> +#include <cxxabi.h> +# include <cstdio> + +using namespace std; +using namespace abi; + +namespace __gnu_cxx +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // A replacement for the standard terminate_handler which prints + // more information about the terminating exception (if any) on + // stderr. + void __verbose_terminate_handler() + { + static bool terminating; + if (terminating) + { + fputs("terminate called recursively\n", stderr); + abort (); + } + terminating = true; + + // Make sure there was an exception; terminate is also called for an + // attempt to rethrow when there is no suitable exception. + type_info *t = __cxa_current_exception_type(); + if (t) + { + // Note that "name" is the mangled name. + char const *name = t->name(); + { + int status = -1; + char *dem = 0; + + dem = __cxa_demangle(name, 0, 0, &status); + + fputs("terminate called after throwing an instance of '", stderr); + if (status == 0) + fputs(dem, stderr); + else + fputs(name, stderr); + fputs("'\n", stderr); + + if (status == 0) + free(dem); + } + + // If the exception is derived from std::exception, we can + // give more information. + __try { __throw_exception_again; } +#ifdef __EXCEPTIONS + __catch(const exception& exc) + { + char const *w = exc.what(); + fputs(" what(): ", stderr); + fputs(w, stderr); + fputs("\n", stderr); + } +#endif + __catch(...) { } + } + else + fputs("terminate called without an active exception\n", stderr); + + abort(); + } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace + +#endif |