Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 6553 → Rev 6554

/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/Makefile
0,0 → 1,105
LIBRARY= libsupc++
 
CC = kos32-gcc
AR = kos32-ar
LD = kos32-ld
CPP= kos32-g++
STRIP = kos32-strip
 
CFLAGS = -U_Win32 -U_WIN32 -U__MINGW32__ -c -O2 -fno-ident -fomit-frame-pointer
CPPFLAGS = -fno-rtti
 
ARFLAGS= crs
 
INCLUDES= -I. -I../include/mingw32 -I../include -I../../newlib/libc/include -I/home/autobuild/tools/win32/include
 
LIBS:= -ldll -lc.dll
 
DEFINES= -DHAVE_CONFIG_H -DIN_GCC -DIN_GLIBCPP_V3 -DUSE_EMUTLS=1 -D_GLIBCXX_HAVE_TLS
 
 
SOURCES = \
cp-demangle.c \
array_type_info.cc \
atexit_thread.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_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_tm.cc \
eh_type.c \
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
 
OBJECTS = $(patsubst %.cc, %.o, $(patsubst %.c, %.o, $(SOURCES)))
 
# targets
 
all:$(LIBRARY).a
 
$(LIBRARY).a: $(OBJECTS) Makefile
$(AR) $(ARFLAGS) $(LIBRARY).a $(OBJECTS)
mv -f $(LIBRARY).a ../../../lib
 
%.o : %.c Makefile
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
 
%.o : %.cc Makefile
$(CPP) $(CFLAGS) $(CPPFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
 
eh_ptr.o: eh_ptr.cc
$(CPP) $(CFLAGS) -std=gnu++0x $(CPPFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
 
eh_throw.o: eh_throw.cc
$(CPP) $(CFLAGS) -std=gnu++0x $(CPPFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
 
guard.o: guard.cc
$(CPP) $(CFLAGS) -std=gnu++0x $(CPPFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
 
atexit_thread.o: atexit_thread.cc
$(CPP) $(CFLAGS) -std=gnu++0x $(CPPFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
 
nested_exception.o: nested_exception.cc
$(CPP) $(CFLAGS) -std=gnu++0x $(CPPFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
 
clean:
-rm -f *.o
 
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/array_type_info.cc
0,0 → 1,32
// Copyright (C) 1994-2015 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 "tinfo.h"
 
namespace __cxxabiv1 {
 
__array_type_info::
~__array_type_info ()
{}
 
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/atexit_arm.cc
0,0 → 1,39
// Copyright (C) 2007-2015 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__)
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/atexit_thread.cc
0,0 → 1,165
// Copyright (C) 2012-2015 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 <cstdlib>
#include <new>
#include "bits/gthr.h"
#ifdef _GLIBCXX_THREAD_ATEXIT_WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
 
#if _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL
 
extern "C" int __cxa_thread_atexit_impl (void (*func) (void *),
void *arg, void *d);
extern "C" int
__cxxabiv1::__cxa_thread_atexit (void (*dtor)(void *),
void *obj, void *dso_handle)
_GLIBCXX_NOTHROW
{
return __cxa_thread_atexit_impl (dtor, obj, dso_handle);
}
 
#else /* _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
 
namespace {
// One element in a singly-linked stack of cleanups.
struct elt
{
void (*destructor)(void *);
void *object;
elt *next;
#ifdef _GLIBCXX_THREAD_ATEXIT_WIN32
HMODULE dll;
#endif
};
 
// Keep a per-thread list of cleanups in gthread_key storage.
__gthread_key_t key;
// But also support non-threaded mode.
elt *single_thread;
 
// Run the specified stack of cleanups.
void run (void *p)
{
elt *e = static_cast<elt*>(p);
while (e)
{
elt *old_e = e;
e->destructor (e->object);
#ifdef _GLIBCXX_THREAD_ATEXIT_WIN32
/* Decrement DLL count */
if (e->dll)
FreeLibrary (e->dll);
#endif
e = e->next;
delete (old_e);
}
}
 
// Run the stack of cleanups for the current thread.
void run ()
{
void *e;
if (__gthread_active_p ())
{
e = __gthread_getspecific (key);
__gthread_setspecific (key, NULL);
}
else
{
e = single_thread;
single_thread = NULL;
}
run (e);
}
 
// Initialize the key for the cleanup stack. We use a static local for
// key init/delete rather than atexit so that delete is run on dlclose.
void key_init() {
struct key_s {
key_s() { __gthread_key_create (&key, run); }
~key_s() { __gthread_key_delete (key); }
};
static key_s ks;
// Also make sure the destructors are run by std::exit.
// FIXME TLS cleanups should run before static cleanups and atexit
// cleanups.
std::atexit (run);
}
}
 
extern "C" int
__cxxabiv1::__cxa_thread_atexit (void (*dtor)(void *), void *obj, void */*dso_handle*/)
_GLIBCXX_NOTHROW
{
// Do this initialization once.
if (__gthread_active_p ())
{
// When threads are active use __gthread_once.
static __gthread_once_t once = __GTHREAD_ONCE_INIT;
__gthread_once (&once, key_init);
}
else
{
// And when threads aren't active use a static local guard.
static bool queued;
if (!queued)
{
queued = true;
std::atexit (run);
}
}
 
elt *first;
if (__gthread_active_p ())
first = static_cast<elt*>(__gthread_getspecific (key));
else
first = single_thread;
 
elt *new_elt = new (std::nothrow) elt;
if (!new_elt)
return -1;
new_elt->destructor = dtor;
new_elt->object = obj;
new_elt->next = first;
#ifdef _GLIBCXX_THREAD_ATEXIT_WIN32
/* Store the DLL address for a later call to FreeLibrary in new_elt and
increment DLL load count. This blocks the unloading of the DLL
before the thread-local dtors have been called. This does NOT help
if FreeLibrary/dlclose is called in excess. */
GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCWSTR) dtor, &new_elt->dll);
#endif
 
if (__gthread_active_p ())
__gthread_setspecific (key, new_elt);
else
single_thread = new_elt;
 
return 0;
}
 
#endif /* _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/atomic_lockfree_defines.h
0,0 → 1,63
// -*- C++ -*- header.
 
// Copyright (C) 2008-2015 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/atomic_lockfree_defines.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{atomic}
*/
 
#ifndef _GLIBCXX_ATOMIC_LOCK_FREE_H
#define _GLIBCXX_ATOMIC_LOCK_FREE_H 1
 
#pragma GCC system_header
 
/**
* @addtogroup atomics
* @{
*/
 
/**
* Lock-free property.
*
* 0 indicates that the types are never lock-free.
* 1 indicates that the types are sometimes lock-free.
* 2 indicates that the types are always lock-free.
*/
 
#if __cplusplus >= 201103L
#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
#endif
 
// @} group atomics
 
#endif
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/bad_alloc.cc
0,0 → 1,34
// Implementation file for the -*- C++ -*- dynamic memory management header.
 
// Copyright (C) 2010-2015 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 "new"
 
std::bad_alloc::~bad_alloc() _GLIBCXX_USE_NOEXCEPT { }
 
const char*
std::bad_alloc::what() const _GLIBCXX_USE_NOEXCEPT
{
return "std::bad_alloc";
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/bad_array_length.cc
0,0 → 1,57
// Copyright (C) 2013-2015 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 <new>
 
namespace std
{
// From N3639. This was voted in and then back out of C++14, and is now
// just here for backward link compatibility with code built with 4.9.
class bad_array_length : public bad_alloc
{
public:
bad_array_length() throw() { };
 
// This declaration is not useless:
// http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
virtual ~bad_array_length() throw();
 
// See comment in eh_exception.cc.
virtual const char* what() const throw();
};
 
bad_array_length::~bad_array_length() _GLIBCXX_USE_NOEXCEPT { }
 
const char*
bad_array_length::what() const _GLIBCXX_USE_NOEXCEPT
{ return "std::bad_array_length"; }
 
} // namespace std
 
namespace __cxxabiv1 {
 
extern "C" void
__cxa_throw_bad_array_length ()
{ _GLIBCXX_THROW_OR_ABORT(std::bad_array_length()); }
 
} // namespace __cxxabiv1
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/bad_array_new.cc
0,0 → 1,35
// Copyright (C) 2013-2015 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 <new>
 
namespace std
{
 
bad_array_new_length::~bad_array_new_length() _GLIBCXX_USE_NOEXCEPT { }
 
const char*
bad_array_new_length::what() const _GLIBCXX_USE_NOEXCEPT
{ return "std::bad_array_new_length"; }
 
} // namespace std
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/bad_cast.cc
0,0 → 1,36
// Copyright (C) 1994-2015 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>
 
namespace std {
 
bad_cast::~bad_cast() _GLIBCXX_USE_NOEXCEPT { }
 
const char*
bad_cast::what() const _GLIBCXX_USE_NOEXCEPT
{
return "std::bad_cast";
}
 
} // namespace std
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/bad_typeid.cc
0,0 → 1,36
// Copyright (C) 1994-2015 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>
 
namespace std {
 
bad_typeid::~bad_typeid() _GLIBCXX_USE_NOEXCEPT { }
 
const char*
bad_typeid::what() const _GLIBCXX_USE_NOEXCEPT
{
return "std::bad_typeid";
}
 
} // namespace std
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/class_type_info.cc
0,0 → 1,110
// Copyright (C) 1994-2015 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 "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;
}
 
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/config.h
0,0 → 1,500
/* config.h. Generated from config.in by configure. */
/* config.in. Generated from configure.ac by autoheader. */
 
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
 
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
This function is required for alloca.c support on those systems. */
/* #undef CRAY_STACKSEG_END */
 
/* Define to 1 if you have the <alloca.h> header file. */
#define HAVE_ALLOCA_H 1
 
/* Define to 1 if you have the `asprintf' function. */
#define HAVE_ASPRINTF 1
 
/* Define to 1 if you have the `atexit' function. */
#define HAVE_ATEXIT 1
 
/* Define to 1 if you have the `basename' function. */
#define HAVE_BASENAME 1
 
/* Define to 1 if you have the `bcmp' function. */
/* #undef HAVE_BCMP */
 
/* Define to 1 if you have the `bcopy' function. */
/* #undef HAVE_BCOPY */
 
/* Define to 1 if you have the `bsearch' function. */
#define HAVE_BSEARCH 1
 
/* Define to 1 if you have the `bzero' function. */
/* #undef HAVE_BZERO */
 
/* Define to 1 if you have the `calloc' function. */
#define HAVE_CALLOC 1
 
/* Define to 1 if you have the `canonicalize_file_name' function. */
/* #undef HAVE_CANONICALIZE_FILE_NAME */
 
/* Define to 1 if you have the `clock' function. */
#define HAVE_CLOCK 1
 
/* Define to 1 if you have the declaration of `asprintf', and to 0 if you
don't. */
#define HAVE_DECL_ASPRINTF 0
 
/* Define to 1 if you have the declaration of `basename(char *)', and to 0 if
you don't. */
#define HAVE_DECL_BASENAME 0
 
/* Define to 1 if you have the declaration of `calloc', and to 0 if you don't.
*/
#define HAVE_DECL_CALLOC 1
 
/* Define to 1 if you have the declaration of `ffs', and to 0 if you don't. */
#define HAVE_DECL_FFS 0
 
/* Define to 1 if you have the declaration of `getenv', and to 0 if you don't.
*/
#define HAVE_DECL_GETENV 1
 
/* Define to 1 if you have the declaration of `getopt', and to 0 if you don't.
*/
#define HAVE_DECL_GETOPT 1
 
/* Define to 1 if you have the declaration of `malloc', and to 0 if you don't.
*/
#define HAVE_DECL_MALLOC 1
 
/* Define to 1 if you have the declaration of `realloc', and to 0 if you
don't. */
#define HAVE_DECL_REALLOC 1
 
/* Define to 1 if you have the declaration of `sbrk', and to 0 if you don't.
*/
#define HAVE_DECL_SBRK 0
 
/* Define to 1 if you have the declaration of `snprintf', and to 0 if you
don't. */
#define HAVE_DECL_SNPRINTF 1
 
/* Define to 1 if you have the declaration of `strverscmp', and to 0 if you
don't. */
#define HAVE_DECL_STRVERSCMP 0
 
/* Define to 1 if you have the declaration of `vasprintf', and to 0 if you
don't. */
#define HAVE_DECL_VASPRINTF 0
 
/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you
don't. */
#define HAVE_DECL_VSNPRINTF 1
 
/* Define to 1 if you have the `dup3' function. */
/* #undef HAVE_DUP3 */
 
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
 
/* Define to 1 if you have the `ffs' function. */
/* #undef HAVE_FFS */
 
/* Define to 1 if you have the `fork' function. */
/* #undef HAVE_FORK */
 
/* Define to 1 if you have the `getcwd' function. */
#define HAVE_GETCWD 1
 
/* Define to 1 if you have the `getpagesize' function. */
#define HAVE_GETPAGESIZE 1
 
/* Define to 1 if you have the `getrlimit' function. */
/* #undef HAVE_GETRLIMIT */
 
/* Define to 1 if you have the `getrusage' function. */
/* #undef HAVE_GETRUSAGE */
 
/* Define to 1 if you have the `getsysinfo' function. */
/* #undef HAVE_GETSYSINFO */
 
/* Define to 1 if you have the `gettimeofday' function. */
#define HAVE_GETTIMEOFDAY 1
 
/* Define to 1 if you have the `index' function. */
/* #undef HAVE_INDEX */
 
/* Define to 1 if you have the `insque' function. */
/* #undef HAVE_INSQUE */
 
/* Define to 1 if the system has the type `intptr_t'. */
#define HAVE_INTPTR_T 1
 
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
 
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
 
/* Define to 1 if you have the <machine/hal_sysinfo.h> header file. */
/* #undef HAVE_MACHINE_HAL_SYSINFO_H */
 
/* Define to 1 if you have the <malloc.h> header file. */
#define HAVE_MALLOC_H 1
 
/* Define to 1 if you have the `memchr' function. */
#define HAVE_MEMCHR 1
 
/* Define to 1 if you have the `memcmp' function. */
#define HAVE_MEMCMP 1
 
/* Define to 1 if you have the `memcpy' function. */
#define HAVE_MEMCPY 1
 
/* Define to 1 if you have the `memmem' function. */
/* #undef HAVE_MEMMEM */
 
/* Define to 1 if you have the `memmove' function. */
#define HAVE_MEMMOVE 1
 
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
 
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
 
/* Define to 1 if you have the `mkstemps' function. */
/* #undef HAVE_MKSTEMPS */
 
/* Define to 1 if you have a working `mmap' system call. */
/* #undef HAVE_MMAP */
 
/* Define to 1 if you have the `on_exit' function. */
/* #undef HAVE_ON_EXIT */
 
/* Define to 1 if you have the <process.h> header file. */
#define HAVE_PROCESS_H 1
 
/* Define to 1 if you have the `psignal' function. */
/* #undef HAVE_PSIGNAL */
 
/* Define to 1 if you have the `pstat_getdynamic' function. */
/* #undef HAVE_PSTAT_GETDYNAMIC */
 
/* Define to 1 if you have the `pstat_getstatic' function. */
/* #undef HAVE_PSTAT_GETSTATIC */
 
/* Define to 1 if you have the `putenv' function. */
#define HAVE_PUTENV 1
 
/* Define to 1 if you have the `random' function. */
/* #undef HAVE_RANDOM */
 
/* Define to 1 if you have the `realpath' function. */
/* #undef HAVE_REALPATH */
 
/* Define to 1 if you have the `rename' function. */
#define HAVE_RENAME 1
 
/* Define to 1 if you have the `rindex' function. */
/* #undef HAVE_RINDEX */
 
/* Define to 1 if you have the `sbrk' function. */
/* #undef HAVE_SBRK */
 
/* Define to 1 if you have the `setenv' function. */
/* #undef HAVE_SETENV */
 
/* Define to 1 if you have the `setproctitle' function. */
/* #undef HAVE_SETPROCTITLE */
 
/* Define to 1 if you have the `setrlimit' function. */
/* #undef HAVE_SETRLIMIT */
 
/* Define to 1 if you have the `sigsetmask' function. */
/* #undef HAVE_SIGSETMASK */
 
/* Define to 1 if you have the `snprintf' function. */
#define HAVE_SNPRINTF 1
 
/* Define to 1 if you have the `spawnve' function. */
#define HAVE_SPAWNVE 1
 
/* Define to 1 if you have the `spawnvpe' function. */
#define HAVE_SPAWNVPE 1
 
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
 
/* Define to 1 if you have the <stdio_ext.h> header file. */
/* #undef HAVE_STDIO_EXT_H */
 
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
 
/* Define to 1 if you have the `stpcpy' function. */
/* #undef HAVE_STPCPY */
 
/* Define to 1 if you have the `stpncpy' function. */
/* #undef HAVE_STPNCPY */
 
/* Define to 1 if you have the `strcasecmp' function. */
/* #undef HAVE_STRCASECMP */
 
/* Define to 1 if you have the `strchr' function. */
#define HAVE_STRCHR 1
 
/* Define to 1 if you have the `strdup' function. */
#define HAVE_STRDUP 1
 
/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR 1
 
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
 
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
 
/* Define to 1 if you have the `strncasecmp' function. */
/* #undef HAVE_STRNCASECMP */
 
/* Define to 1 if you have the `strndup' function. */
/* #undef HAVE_STRNDUP */
 
/* Define to 1 if you have the `strnlen' function. */
/* #undef HAVE_STRNLEN */
 
/* Define to 1 if you have the `strrchr' function. */
#define HAVE_STRRCHR 1
 
/* Define to 1 if you have the `strsignal' function. */
/* #undef HAVE_STRSIGNAL */
 
/* Define to 1 if you have the `strstr' function. */
#define HAVE_STRSTR 1
 
/* Define to 1 if you have the `strtod' function. */
#define HAVE_STRTOD 1
 
/* Define to 1 if you have the `strtol' function. */
#define HAVE_STRTOL 1
 
/* Define to 1 if you have the `strtoul' function. */
#define HAVE_STRTOUL 1
 
/* Define to 1 if you have the `strverscmp' function. */
/* #undef HAVE_STRVERSCMP */
 
/* Define to 1 if you have the `sysconf' function. */
/* #undef HAVE_SYSCONF */
 
/* Define to 1 if you have the `sysctl' function. */
/* #undef HAVE_SYSCTL */
 
/* Define to 1 if you have the `sysmp' function. */
/* #undef HAVE_SYSMP */
 
/* Define if you have the sys_errlist variable. */
#define HAVE_SYS_ERRLIST 1
 
/* Define to 1 if you have the <sys/file.h> header file. */
#define HAVE_SYS_FILE_H 1
 
/* Define to 1 if you have the <sys/mman.h> header file. */
/* #undef HAVE_SYS_MMAN_H */
 
/* Define if you have the sys_nerr variable. */
#define HAVE_SYS_NERR 1
 
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
 
/* Define to 1 if you have the <sys/prctl.h> header file. */
/* #undef HAVE_SYS_PRCTL_H */
 
/* Define to 1 if you have the <sys/pstat.h> header file. */
/* #undef HAVE_SYS_PSTAT_H */
 
/* Define to 1 if you have the <sys/resource.h> header file. */
/* #undef HAVE_SYS_RESOURCE_H */
 
/* Define if you have the sys_siglist variable. */
/* #undef HAVE_SYS_SIGLIST */
 
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
 
/* Define to 1 if you have the <sys/sysctl.h> header file. */
/* #undef HAVE_SYS_SYSCTL_H */
 
/* Define to 1 if you have the <sys/sysinfo.h> header file. */
/* #undef HAVE_SYS_SYSINFO_H */
 
/* Define to 1 if you have the <sys/sysmp.h> header file. */
/* #undef HAVE_SYS_SYSMP_H */
 
/* Define to 1 if you have the <sys/systemcfg.h> header file. */
/* #undef HAVE_SYS_SYSTEMCFG_H */
 
/* Define to 1 if you have the <sys/table.h> header file. */
/* #undef HAVE_SYS_TABLE_H */
 
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
 
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
 
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
/* #undef HAVE_SYS_WAIT_H */
 
/* Define to 1 if you have the `table' function. */
/* #undef HAVE_TABLE */
 
/* Define to 1 if you have the `times' function. */
/* #undef HAVE_TIMES */
 
/* Define to 1 if you have the <time.h> header file. */
#define HAVE_TIME_H 1
 
/* Define to 1 if you have the `tmpnam' function. */
#define HAVE_TMPNAM 1
 
/* Define if you have the \`uintptr_t' type. */
#define HAVE_UINTPTR_T 1
 
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
 
/* Define to 1 if you have the `vasprintf' function. */
/* #undef HAVE_VASPRINTF */
 
/* Define to 1 if you have the `vfork' function. */
/* #undef HAVE_VFORK */
 
/* Define to 1 if you have the <vfork.h> header file. */
/* #undef HAVE_VFORK_H */
 
/* Define to 1 if you have the `vfprintf' function. */
#define HAVE_VFPRINTF 1
 
/* Define to 1 if you have the `vprintf' function. */
#define HAVE_VPRINTF 1
 
/* Define to 1 if you have the `vsprintf' function. */
#define HAVE_VSPRINTF 1
 
/* Define to 1 if you have the `wait3' function. */
/* #undef HAVE_WAIT3 */
 
/* Define to 1 if you have the `wait4' function. */
/* #undef HAVE_WAIT4 */
 
/* Define to 1 if you have the `waitpid' function. */
/* #undef HAVE_WAITPID */
 
/* Define to 1 if `fork' works. */
/* #undef HAVE_WORKING_FORK */
 
/* Define to 1 if `vfork' works. */
/* #undef HAVE_WORKING_VFORK */
 
/* Define to 1 if you have the `_doprnt' function. */
/* #undef HAVE__DOPRNT */
 
/* Define if you have the _system_configuration variable. */
/* #undef HAVE__SYSTEM_CONFIGURATION */
 
/* Define to 1 if you have the `__fsetlocking' function. */
/* #undef HAVE___FSETLOCKING */
 
/* Define if canonicalize_file_name is not declared in system header files. */
#define NEED_DECLARATION_CANONICALIZE_FILE_NAME 1
 
/* Define if errno must be declared even when <errno.h> is included. */
/* #undef NEED_DECLARATION_ERRNO */
 
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
/* #undef NO_MINUS_C_MINUS_O */
 
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
 
/* Define to the full name of this package. */
#define PACKAGE_NAME ""
 
/* Define to the full name and version of this package. */
#define PACKAGE_STRING ""
 
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME ""
 
/* Define to the home page for this package. */
#define PACKAGE_URL ""
 
/* Define to the version of this package. */
#define PACKAGE_VERSION ""
 
/* The size of `int', as computed by sizeof. */
#define SIZEOF_INT 4
 
/* Define if you know the direction of stack growth for your system; otherwise
it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows
toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
#define STACK_DIRECTION -1
 
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
 
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1
 
/* Define to an unsigned 64-bit type available in the compiler. */
#define UNSIGNED_64BIT_TYPE uint64_t
 
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
 
/* Number of bits in a file offset, on hosts where this is settable. */
/* #undef _FILE_OFFSET_BITS */
 
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */
 
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
 
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif
 
/* Define to the type of a signed integer type wide enough to hold a pointer,
if such a type exists, and if the system does not define it. */
/* #undef intptr_t */
 
/* Define to `int' if <sys/types.h> does not define. */
/* #undef pid_t */
 
/* Define to `int' if <sys/types.h> does not define. */
/* #undef ssize_t */
 
/* Define to the type of an unsigned integer type wide enough to hold a
pointer, if such a type exists, and if the system does not define it. */
/* #undef uintptr_t */
 
/* Define as `fork' if `vfork' does not work. */
#define vfork fork
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/cp-demangle.c
0,0 → 1,6450
/* Demangler for g++ V3 ABI.
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2014
Free Software Foundation, Inc.
Written by Ian Lance Taylor <ian@wasabisystems.com>.
 
This file is part of the libiberty library, which is part of GCC.
 
This file is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combined
executable.)
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
 
/* This code implements a demangler for the g++ V3 ABI. The ABI is
described on this web page:
http://www.codesourcery.com/cxx-abi/abi.html#mangling
 
This code was written while looking at the demangler written by
Alex Samuel <samuel@codesourcery.com>.
 
This code first pulls the mangled name apart into a list of
components, and then walks the list generating the demangled
name.
 
This file will normally define the following functions, q.v.:
char *cplus_demangle_v3(const char *mangled, int options)
char *java_demangle_v3(const char *mangled)
int cplus_demangle_v3_callback(const char *mangled, int options,
demangle_callbackref callback)
int java_demangle_v3_callback(const char *mangled,
demangle_callbackref callback)
enum gnu_v3_ctor_kinds is_gnu_v3_mangled_ctor (const char *name)
enum gnu_v3_dtor_kinds is_gnu_v3_mangled_dtor (const char *name)
 
Also, the interface to the component list is public, and defined in
demangle.h. The interface consists of these types, which are
defined in demangle.h:
enum demangle_component_type
struct demangle_component
demangle_callbackref
and these functions defined in this file:
cplus_demangle_fill_name
cplus_demangle_fill_extended_operator
cplus_demangle_fill_ctor
cplus_demangle_fill_dtor
cplus_demangle_print
cplus_demangle_print_callback
and other functions defined in the file cp-demint.c.
 
This file also defines some other functions and variables which are
only to be used by the file cp-demint.c.
 
Preprocessor macros you can define while compiling this file:
 
IN_LIBGCC2
If defined, this file defines the following functions, q.v.:
char *__cxa_demangle (const char *mangled, char *buf, size_t *len,
int *status)
int __gcclibcxx_demangle_callback (const char *,
void (*)
(const char *, size_t, void *),
void *)
instead of cplus_demangle_v3[_callback]() and
java_demangle_v3[_callback]().
 
IN_GLIBCPP_V3
If defined, this file defines only __cxa_demangle() and
__gcclibcxx_demangle_callback(), and no other publically visible
functions or variables.
 
STANDALONE_DEMANGLER
If defined, this file defines a main() function which demangles
any arguments, or, if none, demangles stdin.
 
CP_DEMANGLE_DEBUG
If defined, turns on debugging mode, which prints information on
stdout about the mangled string. This is not generally useful.
*/
 
#if defined (_AIX) && !defined (__GNUC__)
#pragma alloca
#endif
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
 
#include <stdio.h>
 
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
 
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#else
# ifndef alloca
# ifdef __GNUC__
# define alloca __builtin_alloca
# else
extern char *alloca ();
# endif /* __GNUC__ */
# endif /* alloca */
#endif /* HAVE_ALLOCA_H */
 
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifndef INT_MAX
# define INT_MAX (int)(((unsigned int) ~0) >> 1) /* 0x7FFFFFFF */
#endif
 
#include "ansidecl.h"
#include "libiberty.h"
#include "demangle.h"
#include "cp-demangle.h"
 
/* If IN_GLIBCPP_V3 is defined, some functions are made static. We
also rename them via #define to avoid compiler errors when the
static definition conflicts with the extern declaration in a header
file. */
#ifdef IN_GLIBCPP_V3
 
#define CP_STATIC_IF_GLIBCPP_V3 static
 
#define cplus_demangle_fill_name d_fill_name
static int d_fill_name (struct demangle_component *, const char *, int);
 
#define cplus_demangle_fill_extended_operator d_fill_extended_operator
static int
d_fill_extended_operator (struct demangle_component *, int,
struct demangle_component *);
 
#define cplus_demangle_fill_ctor d_fill_ctor
static int
d_fill_ctor (struct demangle_component *, enum gnu_v3_ctor_kinds,
struct demangle_component *);
 
#define cplus_demangle_fill_dtor d_fill_dtor
static int
d_fill_dtor (struct demangle_component *, enum gnu_v3_dtor_kinds,
struct demangle_component *);
 
#define cplus_demangle_mangled_name d_mangled_name
static struct demangle_component *d_mangled_name (struct d_info *, int);
 
#define cplus_demangle_type d_type
static struct demangle_component *d_type (struct d_info *);
 
#define cplus_demangle_print d_print
static char *d_print (int, const struct demangle_component *, int, size_t *);
 
#define cplus_demangle_print_callback d_print_callback
static int d_print_callback (int, const struct demangle_component *,
demangle_callbackref, void *);
 
#define cplus_demangle_init_info d_init_info
static void d_init_info (const char *, int, size_t, struct d_info *);
 
#else /* ! defined(IN_GLIBCPP_V3) */
#define CP_STATIC_IF_GLIBCPP_V3
#endif /* ! defined(IN_GLIBCPP_V3) */
 
/* See if the compiler supports dynamic arrays. */
 
#ifdef __GNUC__
#define CP_DYNAMIC_ARRAYS
#else
#ifdef __STDC__
#ifdef __STDC_VERSION__
#if __STDC_VERSION__ >= 199901L
#define CP_DYNAMIC_ARRAYS
#endif /* __STDC__VERSION >= 199901L */
#endif /* defined (__STDC_VERSION__) */
#endif /* defined (__STDC__) */
#endif /* ! defined (__GNUC__) */
 
/* We avoid pulling in the ctype tables, to prevent pulling in
additional unresolved symbols when this code is used in a library.
FIXME: Is this really a valid reason? This comes from the original
V3 demangler code.
 
As of this writing this file has the following undefined references
when compiled with -DIN_GLIBCPP_V3: realloc, free, memcpy, strcpy,
strcat, strlen. */
 
#define IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
#define IS_UPPER(c) ((c) >= 'A' && (c) <= 'Z')
#define IS_LOWER(c) ((c) >= 'a' && (c) <= 'z')
 
/* The prefix prepended by GCC to an identifier represnting the
anonymous namespace. */
#define ANONYMOUS_NAMESPACE_PREFIX "_GLOBAL_"
#define ANONYMOUS_NAMESPACE_PREFIX_LEN \
(sizeof (ANONYMOUS_NAMESPACE_PREFIX) - 1)
 
/* Information we keep for the standard substitutions. */
 
struct d_standard_sub_info
{
/* The code for this substitution. */
char code;
/* The simple string it expands to. */
const char *simple_expansion;
/* The length of the simple expansion. */
int simple_len;
/* The results of a full, verbose, expansion. This is used when
qualifying a constructor/destructor, or when in verbose mode. */
const char *full_expansion;
/* The length of the full expansion. */
int full_len;
/* What to set the last_name field of d_info to; NULL if we should
not set it. This is only relevant when qualifying a
constructor/destructor. */
const char *set_last_name;
/* The length of set_last_name. */
int set_last_name_len;
};
 
/* Accessors for subtrees of struct demangle_component. */
 
#define d_left(dc) ((dc)->u.s_binary.left)
#define d_right(dc) ((dc)->u.s_binary.right)
 
/* A list of templates. This is used while printing. */
 
struct d_print_template
{
/* Next template on the list. */
struct d_print_template *next;
/* This template. */
const struct demangle_component *template_decl;
};
 
/* A list of type modifiers. This is used while printing. */
 
struct d_print_mod
{
/* Next modifier on the list. These are in the reverse of the order
in which they appeared in the mangled string. */
struct d_print_mod *next;
/* The modifier. */
const struct demangle_component *mod;
/* Whether this modifier was printed. */
int printed;
/* The list of templates which applies to this modifier. */
struct d_print_template *templates;
};
 
/* We use these structures to hold information during printing. */
 
struct d_growable_string
{
/* Buffer holding the result. */
char *buf;
/* Current length of data in buffer. */
size_t len;
/* Allocated size of buffer. */
size_t alc;
/* Set to 1 if we had a memory allocation failure. */
int allocation_failure;
};
 
/* Stack of components, innermost first, used to avoid loops. */
 
struct d_component_stack
{
/* This component. */
const struct demangle_component *dc;
/* This component's parent. */
const struct d_component_stack *parent;
};
 
/* A demangle component and some scope captured when it was first
traversed. */
 
struct d_saved_scope
{
/* The component whose scope this is. */
const struct demangle_component *container;
/* The list of templates, if any, that was current when this
scope was captured. */
struct d_print_template *templates;
};
 
/* Checkpoint structure to allow backtracking. This holds copies
of the fields of struct d_info that need to be restored
if a trial parse needs to be backtracked over. */
 
struct d_info_checkpoint
{
const char *n;
int next_comp;
int next_sub;
int did_subs;
int expansion;
};
 
enum { D_PRINT_BUFFER_LENGTH = 256 };
struct d_print_info
{
/* Fixed-length allocated buffer for demangled data, flushed to the
callback with a NUL termination once full. */
char buf[D_PRINT_BUFFER_LENGTH];
/* Current length of data in buffer. */
size_t len;
/* The last character printed, saved individually so that it survives
any buffer flush. */
char last_char;
/* Callback function to handle demangled buffer flush. */
demangle_callbackref callback;
/* Opaque callback argument. */
void *opaque;
/* The current list of templates, if any. */
struct d_print_template *templates;
/* The current list of modifiers (e.g., pointer, reference, etc.),
if any. */
struct d_print_mod *modifiers;
/* Set to 1 if we saw a demangling error. */
int demangle_failure;
/* The current index into any template argument packs we are using
for printing. */
int pack_index;
/* Number of d_print_flush calls so far. */
unsigned long int flush_count;
/* Stack of components, innermost first, used to avoid loops. */
const struct d_component_stack *component_stack;
/* Array of saved scopes for evaluating substitutions. */
struct d_saved_scope *saved_scopes;
/* Index of the next unused saved scope in the above array. */
int next_saved_scope;
/* Number of saved scopes in the above array. */
int num_saved_scopes;
/* Array of templates for saving into scopes. */
struct d_print_template *copy_templates;
/* Index of the next unused copy template in the above array. */
int next_copy_template;
/* Number of copy templates in the above array. */
int num_copy_templates;
/* The nearest enclosing template, if any. */
const struct demangle_component *current_template;
};
 
#ifdef CP_DEMANGLE_DEBUG
static void d_dump (struct demangle_component *, int);
#endif
 
static struct demangle_component *
d_make_empty (struct d_info *);
 
static struct demangle_component *
d_make_comp (struct d_info *, enum demangle_component_type,
struct demangle_component *,
struct demangle_component *);
 
static struct demangle_component *
d_make_name (struct d_info *, const char *, int);
 
static struct demangle_component *
d_make_demangle_mangled_name (struct d_info *, const char *);
 
static struct demangle_component *
d_make_builtin_type (struct d_info *,
const struct demangle_builtin_type_info *);
 
static struct demangle_component *
d_make_operator (struct d_info *,
const struct demangle_operator_info *);
 
static struct demangle_component *
d_make_extended_operator (struct d_info *, int,
struct demangle_component *);
 
static struct demangle_component *
d_make_ctor (struct d_info *, enum gnu_v3_ctor_kinds,
struct demangle_component *);
 
static struct demangle_component *
d_make_dtor (struct d_info *, enum gnu_v3_dtor_kinds,
struct demangle_component *);
 
static struct demangle_component *
d_make_template_param (struct d_info *, int);
 
static struct demangle_component *
d_make_sub (struct d_info *, const char *, int);
 
static int
has_return_type (struct demangle_component *);
 
static int
is_ctor_dtor_or_conversion (struct demangle_component *);
 
static struct demangle_component *d_encoding (struct d_info *, int);
 
static struct demangle_component *d_name (struct d_info *);
 
static struct demangle_component *d_nested_name (struct d_info *);
 
static struct demangle_component *d_prefix (struct d_info *);
 
static struct demangle_component *d_unqualified_name (struct d_info *);
 
static struct demangle_component *d_source_name (struct d_info *);
 
static int d_number (struct d_info *);
 
static struct demangle_component *d_identifier (struct d_info *, int);
 
static struct demangle_component *d_operator_name (struct d_info *);
 
static struct demangle_component *d_special_name (struct d_info *);
 
static int d_call_offset (struct d_info *, int);
 
static struct demangle_component *d_ctor_dtor_name (struct d_info *);
 
static struct demangle_component **
d_cv_qualifiers (struct d_info *, struct demangle_component **, int);
 
static struct demangle_component *
d_ref_qualifier (struct d_info *, struct demangle_component *);
 
static struct demangle_component *
d_function_type (struct d_info *);
 
static struct demangle_component *
d_bare_function_type (struct d_info *, int);
 
static struct demangle_component *
d_class_enum_type (struct d_info *);
 
static struct demangle_component *d_array_type (struct d_info *);
 
static struct demangle_component *d_vector_type (struct d_info *);
 
static struct demangle_component *
d_pointer_to_member_type (struct d_info *);
 
static struct demangle_component *
d_template_param (struct d_info *);
 
static struct demangle_component *d_template_args (struct d_info *);
 
static struct demangle_component *
d_template_arg (struct d_info *);
 
static struct demangle_component *d_expression (struct d_info *);
 
static struct demangle_component *d_expr_primary (struct d_info *);
 
static struct demangle_component *d_local_name (struct d_info *);
 
static int d_discriminator (struct d_info *);
 
static struct demangle_component *d_lambda (struct d_info *);
 
static struct demangle_component *d_unnamed_type (struct d_info *);
 
static struct demangle_component *
d_clone_suffix (struct d_info *, struct demangle_component *);
 
static int
d_add_substitution (struct d_info *, struct demangle_component *);
 
static struct demangle_component *d_substitution (struct d_info *, int);
 
static void d_checkpoint (struct d_info *, struct d_info_checkpoint *);
 
static void d_backtrack (struct d_info *, struct d_info_checkpoint *);
 
static void d_growable_string_init (struct d_growable_string *, size_t);
 
static inline void
d_growable_string_resize (struct d_growable_string *, size_t);
 
static inline void
d_growable_string_append_buffer (struct d_growable_string *,
const char *, size_t);
static void
d_growable_string_callback_adapter (const char *, size_t, void *);
 
static void
d_print_init (struct d_print_info *, demangle_callbackref, void *,
const struct demangle_component *);
 
static inline void d_print_error (struct d_print_info *);
 
static inline int d_print_saw_error (struct d_print_info *);
 
static inline void d_print_flush (struct d_print_info *);
 
static inline void d_append_char (struct d_print_info *, char);
 
static inline void d_append_buffer (struct d_print_info *,
const char *, size_t);
 
static inline void d_append_string (struct d_print_info *, const char *);
 
static inline char d_last_char (struct d_print_info *);
 
static void
d_print_comp (struct d_print_info *, int, const struct demangle_component *);
 
static void
d_print_java_identifier (struct d_print_info *, const char *, int);
 
static void
d_print_mod_list (struct d_print_info *, int, struct d_print_mod *, int);
 
static void
d_print_mod (struct d_print_info *, int, const struct demangle_component *);
 
static void
d_print_function_type (struct d_print_info *, int,
const struct demangle_component *,
struct d_print_mod *);
 
static void
d_print_array_type (struct d_print_info *, int,
const struct demangle_component *,
struct d_print_mod *);
 
static void
d_print_expr_op (struct d_print_info *, int, const struct demangle_component *);
 
static void d_print_cast (struct d_print_info *, int,
const struct demangle_component *);
static void d_print_conversion (struct d_print_info *, int,
const struct demangle_component *);
 
static int d_demangle_callback (const char *, int,
demangle_callbackref, void *);
static char *d_demangle (const char *, int, size_t *);
 
#ifdef CP_DEMANGLE_DEBUG
 
static void
d_dump (struct demangle_component *dc, int indent)
{
int i;
 
if (dc == NULL)
{
if (indent == 0)
printf ("failed demangling\n");
return;
}
 
for (i = 0; i < indent; ++i)
putchar (' ');
 
switch (dc->type)
{
case DEMANGLE_COMPONENT_NAME:
printf ("name '%.*s'\n", dc->u.s_name.len, dc->u.s_name.s);
return;
case DEMANGLE_COMPONENT_TAGGED_NAME:
printf ("tagged name\n");
d_dump (dc->u.s_binary.left, indent + 2);
d_dump (dc->u.s_binary.right, indent + 2);
return;
case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
printf ("template parameter %ld\n", dc->u.s_number.number);
return;
case DEMANGLE_COMPONENT_FUNCTION_PARAM:
printf ("function parameter %ld\n", dc->u.s_number.number);
return;
case DEMANGLE_COMPONENT_CTOR:
printf ("constructor %d\n", (int) dc->u.s_ctor.kind);
d_dump (dc->u.s_ctor.name, indent + 2);
return;
case DEMANGLE_COMPONENT_DTOR:
printf ("destructor %d\n", (int) dc->u.s_dtor.kind);
d_dump (dc->u.s_dtor.name, indent + 2);
return;
case DEMANGLE_COMPONENT_SUB_STD:
printf ("standard substitution %s\n", dc->u.s_string.string);
return;
case DEMANGLE_COMPONENT_BUILTIN_TYPE:
printf ("builtin type %s\n", dc->u.s_builtin.type->name);
return;
case DEMANGLE_COMPONENT_OPERATOR:
printf ("operator %s\n", dc->u.s_operator.op->name);
return;
case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
printf ("extended operator with %d args\n",
dc->u.s_extended_operator.args);
d_dump (dc->u.s_extended_operator.name, indent + 2);
return;
 
case DEMANGLE_COMPONENT_QUAL_NAME:
printf ("qualified name\n");
break;
case DEMANGLE_COMPONENT_LOCAL_NAME:
printf ("local name\n");
break;
case DEMANGLE_COMPONENT_TYPED_NAME:
printf ("typed name\n");
break;
case DEMANGLE_COMPONENT_TEMPLATE:
printf ("template\n");
break;
case DEMANGLE_COMPONENT_VTABLE:
printf ("vtable\n");
break;
case DEMANGLE_COMPONENT_VTT:
printf ("VTT\n");
break;
case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
printf ("construction vtable\n");
break;
case DEMANGLE_COMPONENT_TYPEINFO:
printf ("typeinfo\n");
break;
case DEMANGLE_COMPONENT_TYPEINFO_NAME:
printf ("typeinfo name\n");
break;
case DEMANGLE_COMPONENT_TYPEINFO_FN:
printf ("typeinfo function\n");
break;
case DEMANGLE_COMPONENT_THUNK:
printf ("thunk\n");
break;
case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
printf ("virtual thunk\n");
break;
case DEMANGLE_COMPONENT_COVARIANT_THUNK:
printf ("covariant thunk\n");
break;
case DEMANGLE_COMPONENT_JAVA_CLASS:
printf ("java class\n");
break;
case DEMANGLE_COMPONENT_GUARD:
printf ("guard\n");
break;
case DEMANGLE_COMPONENT_REFTEMP:
printf ("reference temporary\n");
break;
case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
printf ("hidden alias\n");
break;
case DEMANGLE_COMPONENT_TRANSACTION_CLONE:
printf ("transaction clone\n");
break;
case DEMANGLE_COMPONENT_NONTRANSACTION_CLONE:
printf ("non-transaction clone\n");
break;
case DEMANGLE_COMPONENT_RESTRICT:
printf ("restrict\n");
break;
case DEMANGLE_COMPONENT_VOLATILE:
printf ("volatile\n");
break;
case DEMANGLE_COMPONENT_CONST:
printf ("const\n");
break;
case DEMANGLE_COMPONENT_RESTRICT_THIS:
printf ("restrict this\n");
break;
case DEMANGLE_COMPONENT_VOLATILE_THIS:
printf ("volatile this\n");
break;
case DEMANGLE_COMPONENT_CONST_THIS:
printf ("const this\n");
break;
case DEMANGLE_COMPONENT_REFERENCE_THIS:
printf ("reference this\n");
break;
case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
printf ("rvalue reference this\n");
break;
case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
printf ("vendor type qualifier\n");
break;
case DEMANGLE_COMPONENT_POINTER:
printf ("pointer\n");
break;
case DEMANGLE_COMPONENT_REFERENCE:
printf ("reference\n");
break;
case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
printf ("rvalue reference\n");
break;
case DEMANGLE_COMPONENT_COMPLEX:
printf ("complex\n");
break;
case DEMANGLE_COMPONENT_IMAGINARY:
printf ("imaginary\n");
break;
case DEMANGLE_COMPONENT_VENDOR_TYPE:
printf ("vendor type\n");
break;
case DEMANGLE_COMPONENT_FUNCTION_TYPE:
printf ("function type\n");
break;
case DEMANGLE_COMPONENT_ARRAY_TYPE:
printf ("array type\n");
break;
case DEMANGLE_COMPONENT_PTRMEM_TYPE:
printf ("pointer to member type\n");
break;
case DEMANGLE_COMPONENT_FIXED_TYPE:
printf ("fixed-point type, accum? %d, sat? %d\n",
dc->u.s_fixed.accum, dc->u.s_fixed.sat);
d_dump (dc->u.s_fixed.length, indent + 2);
break;
case DEMANGLE_COMPONENT_ARGLIST:
printf ("argument list\n");
break;
case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
printf ("template argument list\n");
break;
case DEMANGLE_COMPONENT_INITIALIZER_LIST:
printf ("initializer list\n");
break;
case DEMANGLE_COMPONENT_CAST:
printf ("cast\n");
break;
case DEMANGLE_COMPONENT_CONVERSION:
printf ("conversion operator\n");
break;
case DEMANGLE_COMPONENT_NULLARY:
printf ("nullary operator\n");
break;
case DEMANGLE_COMPONENT_UNARY:
printf ("unary operator\n");
break;
case DEMANGLE_COMPONENT_BINARY:
printf ("binary operator\n");
break;
case DEMANGLE_COMPONENT_BINARY_ARGS:
printf ("binary operator arguments\n");
break;
case DEMANGLE_COMPONENT_TRINARY:
printf ("trinary operator\n");
break;
case DEMANGLE_COMPONENT_TRINARY_ARG1:
printf ("trinary operator arguments 1\n");
break;
case DEMANGLE_COMPONENT_TRINARY_ARG2:
printf ("trinary operator arguments 1\n");
break;
case DEMANGLE_COMPONENT_LITERAL:
printf ("literal\n");
break;
case DEMANGLE_COMPONENT_LITERAL_NEG:
printf ("negative literal\n");
break;
case DEMANGLE_COMPONENT_JAVA_RESOURCE:
printf ("java resource\n");
break;
case DEMANGLE_COMPONENT_COMPOUND_NAME:
printf ("compound name\n");
break;
case DEMANGLE_COMPONENT_CHARACTER:
printf ("character '%c'\n", dc->u.s_character.character);
return;
case DEMANGLE_COMPONENT_NUMBER:
printf ("number %ld\n", dc->u.s_number.number);
return;
case DEMANGLE_COMPONENT_DECLTYPE:
printf ("decltype\n");
break;
case DEMANGLE_COMPONENT_PACK_EXPANSION:
printf ("pack expansion\n");
break;
case DEMANGLE_COMPONENT_TLS_INIT:
printf ("tls init function\n");
break;
case DEMANGLE_COMPONENT_TLS_WRAPPER:
printf ("tls wrapper function\n");
break;
case DEMANGLE_COMPONENT_DEFAULT_ARG:
printf ("default argument %d\n", dc->u.s_unary_num.num);
d_dump (dc->u.s_unary_num.sub, indent+2);
return;
case DEMANGLE_COMPONENT_LAMBDA:
printf ("lambda %d\n", dc->u.s_unary_num.num);
d_dump (dc->u.s_unary_num.sub, indent+2);
return;
}
 
d_dump (d_left (dc), indent + 2);
d_dump (d_right (dc), indent + 2);
}
 
#endif /* CP_DEMANGLE_DEBUG */
 
/* Fill in a DEMANGLE_COMPONENT_NAME. */
 
CP_STATIC_IF_GLIBCPP_V3
int
cplus_demangle_fill_name (struct demangle_component *p, const char *s, int len)
{
if (p == NULL || s == NULL || len == 0)
return 0;
p->type = DEMANGLE_COMPONENT_NAME;
p->u.s_name.s = s;
p->u.s_name.len = len;
return 1;
}
 
/* Fill in a DEMANGLE_COMPONENT_EXTENDED_OPERATOR. */
 
CP_STATIC_IF_GLIBCPP_V3
int
cplus_demangle_fill_extended_operator (struct demangle_component *p, int args,
struct demangle_component *name)
{
if (p == NULL || args < 0 || name == NULL)
return 0;
p->type = DEMANGLE_COMPONENT_EXTENDED_OPERATOR;
p->u.s_extended_operator.args = args;
p->u.s_extended_operator.name = name;
return 1;
}
 
/* Fill in a DEMANGLE_COMPONENT_CTOR. */
 
CP_STATIC_IF_GLIBCPP_V3
int
cplus_demangle_fill_ctor (struct demangle_component *p,
enum gnu_v3_ctor_kinds kind,
struct demangle_component *name)
{
if (p == NULL
|| name == NULL
|| (int) kind < gnu_v3_complete_object_ctor
|| (int) kind > gnu_v3_object_ctor_group)
return 0;
p->type = DEMANGLE_COMPONENT_CTOR;
p->u.s_ctor.kind = kind;
p->u.s_ctor.name = name;
return 1;
}
 
/* Fill in a DEMANGLE_COMPONENT_DTOR. */
 
CP_STATIC_IF_GLIBCPP_V3
int
cplus_demangle_fill_dtor (struct demangle_component *p,
enum gnu_v3_dtor_kinds kind,
struct demangle_component *name)
{
if (p == NULL
|| name == NULL
|| (int) kind < gnu_v3_deleting_dtor
|| (int) kind > gnu_v3_object_dtor_group)
return 0;
p->type = DEMANGLE_COMPONENT_DTOR;
p->u.s_dtor.kind = kind;
p->u.s_dtor.name = name;
return 1;
}
 
/* Add a new component. */
 
static struct demangle_component *
d_make_empty (struct d_info *di)
{
struct demangle_component *p;
 
if (di->next_comp >= di->num_comps)
return NULL;
p = &di->comps[di->next_comp];
++di->next_comp;
return p;
}
 
/* Add a new generic component. */
 
static struct demangle_component *
d_make_comp (struct d_info *di, enum demangle_component_type type,
struct demangle_component *left,
struct demangle_component *right)
{
struct demangle_component *p;
 
/* We check for errors here. A typical error would be a NULL return
from a subroutine. We catch those here, and return NULL
upward. */
switch (type)
{
/* These types require two parameters. */
case DEMANGLE_COMPONENT_QUAL_NAME:
case DEMANGLE_COMPONENT_LOCAL_NAME:
case DEMANGLE_COMPONENT_TYPED_NAME:
case DEMANGLE_COMPONENT_TAGGED_NAME:
case DEMANGLE_COMPONENT_TEMPLATE:
case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
case DEMANGLE_COMPONENT_PTRMEM_TYPE:
case DEMANGLE_COMPONENT_UNARY:
case DEMANGLE_COMPONENT_BINARY:
case DEMANGLE_COMPONENT_BINARY_ARGS:
case DEMANGLE_COMPONENT_TRINARY:
case DEMANGLE_COMPONENT_TRINARY_ARG1:
case DEMANGLE_COMPONENT_LITERAL:
case DEMANGLE_COMPONENT_LITERAL_NEG:
case DEMANGLE_COMPONENT_COMPOUND_NAME:
case DEMANGLE_COMPONENT_VECTOR_TYPE:
case DEMANGLE_COMPONENT_CLONE:
if (left == NULL || right == NULL)
return NULL;
break;
 
/* These types only require one parameter. */
case DEMANGLE_COMPONENT_VTABLE:
case DEMANGLE_COMPONENT_VTT:
case DEMANGLE_COMPONENT_TYPEINFO:
case DEMANGLE_COMPONENT_TYPEINFO_NAME:
case DEMANGLE_COMPONENT_TYPEINFO_FN:
case DEMANGLE_COMPONENT_THUNK:
case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
case DEMANGLE_COMPONENT_COVARIANT_THUNK:
case DEMANGLE_COMPONENT_JAVA_CLASS:
case DEMANGLE_COMPONENT_GUARD:
case DEMANGLE_COMPONENT_TLS_INIT:
case DEMANGLE_COMPONENT_TLS_WRAPPER:
case DEMANGLE_COMPONENT_REFTEMP:
case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
case DEMANGLE_COMPONENT_TRANSACTION_CLONE:
case DEMANGLE_COMPONENT_NONTRANSACTION_CLONE:
case DEMANGLE_COMPONENT_POINTER:
case DEMANGLE_COMPONENT_REFERENCE:
case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
case DEMANGLE_COMPONENT_COMPLEX:
case DEMANGLE_COMPONENT_IMAGINARY:
case DEMANGLE_COMPONENT_VENDOR_TYPE:
case DEMANGLE_COMPONENT_CAST:
case DEMANGLE_COMPONENT_CONVERSION:
case DEMANGLE_COMPONENT_JAVA_RESOURCE:
case DEMANGLE_COMPONENT_DECLTYPE:
case DEMANGLE_COMPONENT_PACK_EXPANSION:
case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS:
case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS:
case DEMANGLE_COMPONENT_NULLARY:
case DEMANGLE_COMPONENT_TRINARY_ARG2:
if (left == NULL)
return NULL;
break;
 
/* This needs a right parameter, but the left parameter can be
empty. */
case DEMANGLE_COMPONENT_ARRAY_TYPE:
case DEMANGLE_COMPONENT_INITIALIZER_LIST:
if (right == NULL)
return NULL;
break;
 
/* These are allowed to have no parameters--in some cases they
will be filled in later. */
case DEMANGLE_COMPONENT_FUNCTION_TYPE:
case DEMANGLE_COMPONENT_RESTRICT:
case DEMANGLE_COMPONENT_VOLATILE:
case DEMANGLE_COMPONENT_CONST:
case DEMANGLE_COMPONENT_RESTRICT_THIS:
case DEMANGLE_COMPONENT_VOLATILE_THIS:
case DEMANGLE_COMPONENT_CONST_THIS:
case DEMANGLE_COMPONENT_REFERENCE_THIS:
case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
case DEMANGLE_COMPONENT_ARGLIST:
case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
break;
 
/* Other types should not be seen here. */
default:
return NULL;
}
 
p = d_make_empty (di);
if (p != NULL)
{
p->type = type;
p->u.s_binary.left = left;
p->u.s_binary.right = right;
}
return p;
}
 
/* Add a new demangle mangled name component. */
 
static struct demangle_component *
d_make_demangle_mangled_name (struct d_info *di, const char *s)
{
if (d_peek_char (di) != '_' || d_peek_next_char (di) != 'Z')
return d_make_name (di, s, strlen (s));
d_advance (di, 2);
return d_encoding (di, 0);
}
 
/* Add a new name component. */
 
static struct demangle_component *
d_make_name (struct d_info *di, const char *s, int len)
{
struct demangle_component *p;
 
p = d_make_empty (di);
if (! cplus_demangle_fill_name (p, s, len))
return NULL;
return p;
}
 
/* Add a new builtin type component. */
 
static struct demangle_component *
d_make_builtin_type (struct d_info *di,
const struct demangle_builtin_type_info *type)
{
struct demangle_component *p;
 
if (type == NULL)
return NULL;
p = d_make_empty (di);
if (p != NULL)
{
p->type = DEMANGLE_COMPONENT_BUILTIN_TYPE;
p->u.s_builtin.type = type;
}
return p;
}
 
/* Add a new operator component. */
 
static struct demangle_component *
d_make_operator (struct d_info *di, const struct demangle_operator_info *op)
{
struct demangle_component *p;
 
p = d_make_empty (di);
if (p != NULL)
{
p->type = DEMANGLE_COMPONENT_OPERATOR;
p->u.s_operator.op = op;
}
return p;
}
 
/* Add a new extended operator component. */
 
static struct demangle_component *
d_make_extended_operator (struct d_info *di, int args,
struct demangle_component *name)
{
struct demangle_component *p;
 
p = d_make_empty (di);
if (! cplus_demangle_fill_extended_operator (p, args, name))
return NULL;
return p;
}
 
static struct demangle_component *
d_make_default_arg (struct d_info *di, int num,
struct demangle_component *sub)
{
struct demangle_component *p = d_make_empty (di);
if (p)
{
p->type = DEMANGLE_COMPONENT_DEFAULT_ARG;
p->u.s_unary_num.num = num;
p->u.s_unary_num.sub = sub;
}
return p;
}
 
/* Add a new constructor component. */
 
static struct demangle_component *
d_make_ctor (struct d_info *di, enum gnu_v3_ctor_kinds kind,
struct demangle_component *name)
{
struct demangle_component *p;
 
p = d_make_empty (di);
if (! cplus_demangle_fill_ctor (p, kind, name))
return NULL;
return p;
}
 
/* Add a new destructor component. */
 
static struct demangle_component *
d_make_dtor (struct d_info *di, enum gnu_v3_dtor_kinds kind,
struct demangle_component *name)
{
struct demangle_component *p;
 
p = d_make_empty (di);
if (! cplus_demangle_fill_dtor (p, kind, name))
return NULL;
return p;
}
 
/* Add a new template parameter. */
 
static struct demangle_component *
d_make_template_param (struct d_info *di, int i)
{
struct demangle_component *p;
 
p = d_make_empty (di);
if (p != NULL)
{
p->type = DEMANGLE_COMPONENT_TEMPLATE_PARAM;
p->u.s_number.number = i;
}
return p;
}
 
/* Add a new function parameter. */
 
static struct demangle_component *
d_make_function_param (struct d_info *di, int i)
{
struct demangle_component *p;
 
p = d_make_empty (di);
if (p != NULL)
{
p->type = DEMANGLE_COMPONENT_FUNCTION_PARAM;
p->u.s_number.number = i;
}
return p;
}
 
/* Add a new standard substitution component. */
 
static struct demangle_component *
d_make_sub (struct d_info *di, const char *name, int len)
{
struct demangle_component *p;
 
p = d_make_empty (di);
if (p != NULL)
{
p->type = DEMANGLE_COMPONENT_SUB_STD;
p->u.s_string.string = name;
p->u.s_string.len = len;
}
return p;
}
 
/* <mangled-name> ::= _Z <encoding> [<clone-suffix>]*
 
TOP_LEVEL is non-zero when called at the top level. */
 
CP_STATIC_IF_GLIBCPP_V3
struct demangle_component *
cplus_demangle_mangled_name (struct d_info *di, int top_level)
{
struct demangle_component *p;
 
if (! d_check_char (di, '_')
/* Allow missing _ if not at toplevel to work around a
bug in G++ abi-version=2 mangling; see the comment in
write_template_arg. */
&& top_level)
return NULL;
if (! d_check_char (di, 'Z'))
return NULL;
p = d_encoding (di, top_level);
 
/* If at top level and parsing parameters, check for a clone
suffix. */
if (top_level && (di->options & DMGL_PARAMS) != 0)
while (d_peek_char (di) == '.'
&& (IS_LOWER (d_peek_next_char (di))
|| d_peek_next_char (di) == '_'
|| IS_DIGIT (d_peek_next_char (di))))
p = d_clone_suffix (di, p);
 
return p;
}
 
/* Return whether a function should have a return type. The argument
is the function name, which may be qualified in various ways. The
rules are that template functions have return types with some
exceptions, function types which are not part of a function name
mangling have return types with some exceptions, and non-template
function names do not have return types. The exceptions are that
constructors, destructors, and conversion operators do not have
return types. */
 
static int
has_return_type (struct demangle_component *dc)
{
if (dc == NULL)
return 0;
switch (dc->type)
{
default:
return 0;
case DEMANGLE_COMPONENT_TEMPLATE:
return ! is_ctor_dtor_or_conversion (d_left (dc));
case DEMANGLE_COMPONENT_RESTRICT_THIS:
case DEMANGLE_COMPONENT_VOLATILE_THIS:
case DEMANGLE_COMPONENT_CONST_THIS:
case DEMANGLE_COMPONENT_REFERENCE_THIS:
case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
return has_return_type (d_left (dc));
}
}
 
/* Return whether a name is a constructor, a destructor, or a
conversion operator. */
 
static int
is_ctor_dtor_or_conversion (struct demangle_component *dc)
{
if (dc == NULL)
return 0;
switch (dc->type)
{
default:
return 0;
case DEMANGLE_COMPONENT_QUAL_NAME:
case DEMANGLE_COMPONENT_LOCAL_NAME:
return is_ctor_dtor_or_conversion (d_right (dc));
case DEMANGLE_COMPONENT_CTOR:
case DEMANGLE_COMPONENT_DTOR:
case DEMANGLE_COMPONENT_CONVERSION:
return 1;
}
}
 
/* <encoding> ::= <(function) name> <bare-function-type>
::= <(data) name>
::= <special-name>
 
TOP_LEVEL is non-zero when called at the top level, in which case
if DMGL_PARAMS is not set we do not demangle the function
parameters. We only set this at the top level, because otherwise
we would not correctly demangle names in local scopes. */
 
static struct demangle_component *
d_encoding (struct d_info *di, int top_level)
{
char peek = d_peek_char (di);
 
if (peek == 'G' || peek == 'T')
return d_special_name (di);
else
{
struct demangle_component *dc;
 
dc = d_name (di);
 
if (dc != NULL && top_level && (di->options & DMGL_PARAMS) == 0)
{
/* Strip off any initial CV-qualifiers, as they really apply
to the `this' parameter, and they were not output by the
v2 demangler without DMGL_PARAMS. */
while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS
|| dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS
|| dc->type == DEMANGLE_COMPONENT_CONST_THIS
|| dc->type == DEMANGLE_COMPONENT_REFERENCE_THIS
|| dc->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS)
dc = d_left (dc);
 
/* If the top level is a DEMANGLE_COMPONENT_LOCAL_NAME, then
there may be CV-qualifiers on its right argument which
really apply here; this happens when parsing a class
which is local to a function. */
if (dc->type == DEMANGLE_COMPONENT_LOCAL_NAME)
{
struct demangle_component *dcr;
 
dcr = d_right (dc);
while (dcr->type == DEMANGLE_COMPONENT_RESTRICT_THIS
|| dcr->type == DEMANGLE_COMPONENT_VOLATILE_THIS
|| dcr->type == DEMANGLE_COMPONENT_CONST_THIS
|| dcr->type == DEMANGLE_COMPONENT_REFERENCE_THIS
|| dcr->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS)
dcr = d_left (dcr);
dc->u.s_binary.right = dcr;
}
 
return dc;
}
 
peek = d_peek_char (di);
if (dc == NULL || peek == '\0' || peek == 'E')
return dc;
return d_make_comp (di, DEMANGLE_COMPONENT_TYPED_NAME, dc,
d_bare_function_type (di, has_return_type (dc)));
}
}
 
/* <tagged-name> ::= <name> B <source-name> */
 
static struct demangle_component *
d_abi_tags (struct d_info *di, struct demangle_component *dc)
{
char peek;
while (peek = d_peek_char (di),
peek == 'B')
{
struct demangle_component *tag;
d_advance (di, 1);
tag = d_source_name (di);
dc = d_make_comp (di, DEMANGLE_COMPONENT_TAGGED_NAME, dc, tag);
}
return dc;
}
 
/* <name> ::= <nested-name>
::= <unscoped-name>
::= <unscoped-template-name> <template-args>
::= <local-name>
 
<unscoped-name> ::= <unqualified-name>
::= St <unqualified-name>
 
<unscoped-template-name> ::= <unscoped-name>
::= <substitution>
*/
 
static struct demangle_component *
d_name (struct d_info *di)
{
char peek = d_peek_char (di);
struct demangle_component *dc;
 
switch (peek)
{
case 'N':
return d_nested_name (di);
 
case 'Z':
return d_local_name (di);
 
case 'U':
return d_unqualified_name (di);
 
case 'S':
{
int subst;
 
if (d_peek_next_char (di) != 't')
{
dc = d_substitution (di, 0);
subst = 1;
}
else
{
d_advance (di, 2);
dc = d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME,
d_make_name (di, "std", 3),
d_unqualified_name (di));
di->expansion += 3;
subst = 0;
}
 
if (d_peek_char (di) != 'I')
{
/* The grammar does not permit this case to occur if we
called d_substitution() above (i.e., subst == 1). We
don't bother to check. */
}
else
{
/* This is <template-args>, which means that we just saw
<unscoped-template-name>, which is a substitution
candidate if we didn't just get it from a
substitution. */
if (! subst)
{
if (! d_add_substitution (di, dc))
return NULL;
}
dc = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, dc,
d_template_args (di));
}
 
return dc;
}
 
case 'L':
default:
dc = d_unqualified_name (di);
if (d_peek_char (di) == 'I')
{
/* This is <template-args>, which means that we just saw
<unscoped-template-name>, which is a substitution
candidate. */
if (! d_add_substitution (di, dc))
return NULL;
dc = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, dc,
d_template_args (di));
}
return dc;
}
}
 
/* <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
*/
 
static struct demangle_component *
d_nested_name (struct d_info *di)
{
struct demangle_component *ret;
struct demangle_component **pret;
struct demangle_component *rqual;
 
if (! d_check_char (di, 'N'))
return NULL;
 
pret = d_cv_qualifiers (di, &ret, 1);
if (pret == NULL)
return NULL;
 
/* Parse the ref-qualifier now and then attach it
once we have something to attach it to. */
rqual = d_ref_qualifier (di, NULL);
 
*pret = d_prefix (di);
if (*pret == NULL)
return NULL;
 
if (rqual)
{
d_left (rqual) = ret;
ret = rqual;
}
 
if (! d_check_char (di, 'E'))
return NULL;
 
return ret;
}
 
/* <prefix> ::= <prefix> <unqualified-name>
::= <template-prefix> <template-args>
::= <template-param>
::= <decltype>
::=
::= <substitution>
 
<template-prefix> ::= <prefix> <(template) unqualified-name>
::= <template-param>
::= <substitution>
*/
 
static struct demangle_component *
d_prefix (struct d_info *di)
{
struct demangle_component *ret = NULL;
 
while (1)
{
char peek;
enum demangle_component_type comb_type;
struct demangle_component *dc;
 
peek = d_peek_char (di);
if (peek == '\0')
return NULL;
 
/* The older code accepts a <local-name> here, but I don't see
that in the grammar. The older code does not accept a
<template-param> here. */
 
comb_type = DEMANGLE_COMPONENT_QUAL_NAME;
if (peek == 'D')
{
char peek2 = d_peek_next_char (di);
if (peek2 == 'T' || peek2 == 't')
/* Decltype. */
dc = cplus_demangle_type (di);
else
/* Destructor name. */
dc = d_unqualified_name (di);
}
else if (IS_DIGIT (peek)
|| IS_LOWER (peek)
|| peek == 'C'
|| peek == 'U'
|| peek == 'L')
dc = d_unqualified_name (di);
else if (peek == 'S')
dc = d_substitution (di, 1);
else if (peek == 'I')
{
if (ret == NULL)
return NULL;
comb_type = DEMANGLE_COMPONENT_TEMPLATE;
dc = d_template_args (di);
}
else if (peek == 'T')
dc = d_template_param (di);
else if (peek == 'E')
return ret;
else if (peek == 'M')
{
/* Initializer scope for a lambda. We don't need to represent
this; the normal code will just treat the variable as a type
scope, which gives appropriate output. */
if (ret == NULL)
return NULL;
d_advance (di, 1);
continue;
}
else
return NULL;
 
if (ret == NULL)
ret = dc;
else
ret = d_make_comp (di, comb_type, ret, dc);
 
if (peek != 'S' && d_peek_char (di) != 'E')
{
if (! d_add_substitution (di, ret))
return NULL;
}
}
}
 
/* <unqualified-name> ::= <operator-name>
::= <ctor-dtor-name>
::= <source-name>
::= <local-source-name>
 
<local-source-name> ::= L <source-name> <discriminator>
*/
 
static struct demangle_component *
d_unqualified_name (struct d_info *di)
{
struct demangle_component *ret;
char peek;
 
peek = d_peek_char (di);
if (IS_DIGIT (peek))
ret = d_source_name (di);
else if (IS_LOWER (peek))
{
ret = d_operator_name (di);
if (ret != NULL && ret->type == DEMANGLE_COMPONENT_OPERATOR)
{
di->expansion += sizeof "operator" + ret->u.s_operator.op->len - 2;
if (!strcmp (ret->u.s_operator.op->code, "li"))
ret = d_make_comp (di, DEMANGLE_COMPONENT_UNARY, ret,
d_source_name (di));
}
}
else if (peek == 'C' || peek == 'D')
ret = d_ctor_dtor_name (di);
else if (peek == 'L')
{
d_advance (di, 1);
 
ret = d_source_name (di);
if (ret == NULL)
return NULL;
if (! d_discriminator (di))
return NULL;
}
else if (peek == 'U')
{
switch (d_peek_next_char (di))
{
case 'l':
ret = d_lambda (di);
break;
case 't':
ret = d_unnamed_type (di);
break;
default:
return NULL;
}
}
else
return NULL;
 
if (d_peek_char (di) == 'B')
ret = d_abi_tags (di, ret);
return ret;
}
 
/* <source-name> ::= <(positive length) number> <identifier> */
 
static struct demangle_component *
d_source_name (struct d_info *di)
{
int len;
struct demangle_component *ret;
 
len = d_number (di);
if (len <= 0)
return NULL;
ret = d_identifier (di, len);
di->last_name = ret;
return ret;
}
 
/* number ::= [n] <(non-negative decimal integer)> */
 
static int
d_number (struct d_info *di)
{
int negative;
char peek;
int ret;
 
negative = 0;
peek = d_peek_char (di);
if (peek == 'n')
{
negative = 1;
d_advance (di, 1);
peek = d_peek_char (di);
}
 
ret = 0;
while (1)
{
if (! IS_DIGIT (peek))
{
if (negative)
ret = - ret;
return ret;
}
ret = ret * 10 + peek - '0';
d_advance (di, 1);
peek = d_peek_char (di);
}
}
 
/* Like d_number, but returns a demangle_component. */
 
static struct demangle_component *
d_number_component (struct d_info *di)
{
struct demangle_component *ret = d_make_empty (di);
if (ret)
{
ret->type = DEMANGLE_COMPONENT_NUMBER;
ret->u.s_number.number = d_number (di);
}
return ret;
}
 
/* identifier ::= <(unqualified source code identifier)> */
 
static struct demangle_component *
d_identifier (struct d_info *di, int len)
{
const char *name;
 
name = d_str (di);
 
if (di->send - name < len)
return NULL;
 
d_advance (di, len);
 
/* A Java mangled name may have a trailing '$' if it is a C++
keyword. This '$' is not included in the length count. We just
ignore the '$'. */
if ((di->options & DMGL_JAVA) != 0
&& d_peek_char (di) == '$')
d_advance (di, 1);
 
/* Look for something which looks like a gcc encoding of an
anonymous namespace, and replace it with a more user friendly
name. */
if (len >= (int) ANONYMOUS_NAMESPACE_PREFIX_LEN + 2
&& memcmp (name, ANONYMOUS_NAMESPACE_PREFIX,
ANONYMOUS_NAMESPACE_PREFIX_LEN) == 0)
{
const char *s;
 
s = name + ANONYMOUS_NAMESPACE_PREFIX_LEN;
if ((*s == '.' || *s == '_' || *s == '$')
&& s[1] == 'N')
{
di->expansion -= len - sizeof "(anonymous namespace)";
return d_make_name (di, "(anonymous namespace)",
sizeof "(anonymous namespace)" - 1);
}
}
 
return d_make_name (di, name, len);
}
 
/* operator_name ::= many different two character encodings.
::= cv <type>
::= v <digit> <source-name>
 
This list is sorted for binary search. */
 
#define NL(s) s, (sizeof s) - 1
 
CP_STATIC_IF_GLIBCPP_V3
const struct demangle_operator_info cplus_demangle_operators[] =
{
{ "aN", NL ("&="), 2 },
{ "aS", NL ("="), 2 },
{ "aa", NL ("&&"), 2 },
{ "ad", NL ("&"), 1 },
{ "an", NL ("&"), 2 },
{ "at", NL ("alignof "), 1 },
{ "az", NL ("alignof "), 1 },
{ "cc", NL ("const_cast"), 2 },
{ "cl", NL ("()"), 2 },
{ "cm", NL (","), 2 },
{ "co", NL ("~"), 1 },
{ "dV", NL ("/="), 2 },
{ "da", NL ("delete[] "), 1 },
{ "dc", NL ("dynamic_cast"), 2 },
{ "de", NL ("*"), 1 },
{ "dl", NL ("delete "), 1 },
{ "ds", NL (".*"), 2 },
{ "dt", NL ("."), 2 },
{ "dv", NL ("/"), 2 },
{ "eO", NL ("^="), 2 },
{ "eo", NL ("^"), 2 },
{ "eq", NL ("=="), 2 },
{ "ge", NL (">="), 2 },
{ "gs", NL ("::"), 1 },
{ "gt", NL (">"), 2 },
{ "ix", NL ("[]"), 2 },
{ "lS", NL ("<<="), 2 },
{ "le", NL ("<="), 2 },
{ "li", NL ("operator\"\" "), 1 },
{ "ls", NL ("<<"), 2 },
{ "lt", NL ("<"), 2 },
{ "mI", NL ("-="), 2 },
{ "mL", NL ("*="), 2 },
{ "mi", NL ("-"), 2 },
{ "ml", NL ("*"), 2 },
{ "mm", NL ("--"), 1 },
{ "na", NL ("new[]"), 3 },
{ "ne", NL ("!="), 2 },
{ "ng", NL ("-"), 1 },
{ "nt", NL ("!"), 1 },
{ "nw", NL ("new"), 3 },
{ "oR", NL ("|="), 2 },
{ "oo", NL ("||"), 2 },
{ "or", NL ("|"), 2 },
{ "pL", NL ("+="), 2 },
{ "pl", NL ("+"), 2 },
{ "pm", NL ("->*"), 2 },
{ "pp", NL ("++"), 1 },
{ "ps", NL ("+"), 1 },
{ "pt", NL ("->"), 2 },
{ "qu", NL ("?"), 3 },
{ "rM", NL ("%="), 2 },
{ "rS", NL (">>="), 2 },
{ "rc", NL ("reinterpret_cast"), 2 },
{ "rm", NL ("%"), 2 },
{ "rs", NL (">>"), 2 },
{ "sc", NL ("static_cast"), 2 },
{ "st", NL ("sizeof "), 1 },
{ "sz", NL ("sizeof "), 1 },
{ "tr", NL ("throw"), 0 },
{ "tw", NL ("throw "), 1 },
{ NULL, NULL, 0, 0 }
};
 
static struct demangle_component *
d_operator_name (struct d_info *di)
{
char c1;
char c2;
 
c1 = d_next_char (di);
c2 = d_next_char (di);
if (c1 == 'v' && IS_DIGIT (c2))
return d_make_extended_operator (di, c2 - '0', d_source_name (di));
else if (c1 == 'c' && c2 == 'v')
{
struct demangle_component *type;
int was_conversion = di->is_conversion;
struct demangle_component *res;
 
di->is_conversion = ! di->is_expression;
type = cplus_demangle_type (di);
if (di->is_conversion)
res = d_make_comp (di, DEMANGLE_COMPONENT_CONVERSION, type, NULL);
else
res = d_make_comp (di, DEMANGLE_COMPONENT_CAST, type, NULL);
di->is_conversion = was_conversion;
return res;
}
else
{
/* LOW is the inclusive lower bound. */
int low = 0;
/* HIGH is the exclusive upper bound. We subtract one to ignore
the sentinel at the end of the array. */
int high = ((sizeof (cplus_demangle_operators)
/ sizeof (cplus_demangle_operators[0]))
- 1);
 
while (1)
{
int i;
const struct demangle_operator_info *p;
 
i = low + (high - low) / 2;
p = cplus_demangle_operators + i;
 
if (c1 == p->code[0] && c2 == p->code[1])
return d_make_operator (di, p);
 
if (c1 < p->code[0] || (c1 == p->code[0] && c2 < p->code[1]))
high = i;
else
low = i + 1;
if (low == high)
return NULL;
}
}
}
 
static struct demangle_component *
d_make_character (struct d_info *di, int c)
{
struct demangle_component *p;
p = d_make_empty (di);
if (p != NULL)
{
p->type = DEMANGLE_COMPONENT_CHARACTER;
p->u.s_character.character = c;
}
return p;
}
 
static struct demangle_component *
d_java_resource (struct d_info *di)
{
struct demangle_component *p = NULL;
struct demangle_component *next = NULL;
int len, i;
char c;
const char *str;
 
len = d_number (di);
if (len <= 1)
return NULL;
 
/* Eat the leading '_'. */
if (d_next_char (di) != '_')
return NULL;
len--;
 
str = d_str (di);
i = 0;
 
while (len > 0)
{
c = str[i];
if (!c)
return NULL;
 
/* Each chunk is either a '$' escape... */
if (c == '$')
{
i++;
switch (str[i++])
{
case 'S':
c = '/';
break;
case '_':
c = '.';
break;
case '$':
c = '$';
break;
default:
return NULL;
}
next = d_make_character (di, c);
d_advance (di, i);
str = d_str (di);
len -= i;
i = 0;
if (next == NULL)
return NULL;
}
/* ... or a sequence of characters. */
else
{
while (i < len && str[i] && str[i] != '$')
i++;
 
next = d_make_name (di, str, i);
d_advance (di, i);
str = d_str (di);
len -= i;
i = 0;
if (next == NULL)
return NULL;
}
 
if (p == NULL)
p = next;
else
{
p = d_make_comp (di, DEMANGLE_COMPONENT_COMPOUND_NAME, p, next);
if (p == NULL)
return NULL;
}
}
 
p = d_make_comp (di, DEMANGLE_COMPONENT_JAVA_RESOURCE, p, NULL);
 
return p;
}
 
/* <special-name> ::= TV <type>
::= TT <type>
::= TI <type>
::= TS <type>
::= GV <(object) name>
::= T <call-offset> <(base) encoding>
::= Tc <call-offset> <call-offset> <(base) encoding>
Also g++ extensions:
::= TC <type> <(offset) number> _ <(base) type>
::= TF <type>
::= TJ <type>
::= GR <name>
::= GA <encoding>
::= Gr <resource name>
::= GTt <encoding>
::= GTn <encoding>
*/
 
static struct demangle_component *
d_special_name (struct d_info *di)
{
di->expansion += 20;
if (d_check_char (di, 'T'))
{
switch (d_next_char (di))
{
case 'V':
di->expansion -= 5;
return d_make_comp (di, DEMANGLE_COMPONENT_VTABLE,
cplus_demangle_type (di), NULL);
case 'T':
di->expansion -= 10;
return d_make_comp (di, DEMANGLE_COMPONENT_VTT,
cplus_demangle_type (di), NULL);
case 'I':
return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO,
cplus_demangle_type (di), NULL);
case 'S':
return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO_NAME,
cplus_demangle_type (di), NULL);
 
case 'h':
if (! d_call_offset (di, 'h'))
return NULL;
return d_make_comp (di, DEMANGLE_COMPONENT_THUNK,
d_encoding (di, 0), NULL);
 
case 'v':
if (! d_call_offset (di, 'v'))
return NULL;
return d_make_comp (di, DEMANGLE_COMPONENT_VIRTUAL_THUNK,
d_encoding (di, 0), NULL);
 
case 'c':
if (! d_call_offset (di, '\0'))
return NULL;
if (! d_call_offset (di, '\0'))
return NULL;
return d_make_comp (di, DEMANGLE_COMPONENT_COVARIANT_THUNK,
d_encoding (di, 0), NULL);
 
case 'C':
{
struct demangle_component *derived_type;
int offset;
struct demangle_component *base_type;
 
derived_type = cplus_demangle_type (di);
offset = d_number (di);
if (offset < 0)
return NULL;
if (! d_check_char (di, '_'))
return NULL;
base_type = cplus_demangle_type (di);
/* We don't display the offset. FIXME: We should display
it in verbose mode. */
di->expansion += 5;
return d_make_comp (di, DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE,
base_type, derived_type);
}
 
case 'F':
return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO_FN,
cplus_demangle_type (di), NULL);
case 'J':
return d_make_comp (di, DEMANGLE_COMPONENT_JAVA_CLASS,
cplus_demangle_type (di), NULL);
 
case 'H':
return d_make_comp (di, DEMANGLE_COMPONENT_TLS_INIT,
d_name (di), NULL);
 
case 'W':
return d_make_comp (di, DEMANGLE_COMPONENT_TLS_WRAPPER,
d_name (di), NULL);
 
default:
return NULL;
}
}
else if (d_check_char (di, 'G'))
{
switch (d_next_char (di))
{
case 'V':
return d_make_comp (di, DEMANGLE_COMPONENT_GUARD, d_name (di), NULL);
 
case 'R':
{
struct demangle_component *name = d_name (di);
return d_make_comp (di, DEMANGLE_COMPONENT_REFTEMP, name,
d_number_component (di));
}
 
case 'A':
return d_make_comp (di, DEMANGLE_COMPONENT_HIDDEN_ALIAS,
d_encoding (di, 0), NULL);
 
case 'T':
switch (d_next_char (di))
{
case 'n':
return d_make_comp (di, DEMANGLE_COMPONENT_NONTRANSACTION_CLONE,
d_encoding (di, 0), NULL);
default:
/* ??? The proposal is that other letters (such as 'h') stand
for different variants of transaction cloning, such as
compiling directly for hardware transaction support. But
they still should all be transactional clones of some sort
so go ahead and call them that. */
case 't':
return d_make_comp (di, DEMANGLE_COMPONENT_TRANSACTION_CLONE,
d_encoding (di, 0), NULL);
}
 
case 'r':
return d_java_resource (di);
 
default:
return NULL;
}
}
else
return NULL;
}
 
/* <call-offset> ::= h <nv-offset> _
::= v <v-offset> _
 
<nv-offset> ::= <(offset) number>
 
<v-offset> ::= <(offset) number> _ <(virtual offset) number>
 
The C parameter, if not '\0', is a character we just read which is
the start of the <call-offset>.
 
We don't display the offset information anywhere. FIXME: We should
display it in verbose mode. */
 
static int
d_call_offset (struct d_info *di, int c)
{
if (c == '\0')
c = d_next_char (di);
 
if (c == 'h')
d_number (di);
else if (c == 'v')
{
d_number (di);
if (! d_check_char (di, '_'))
return 0;
d_number (di);
}
else
return 0;
 
if (! d_check_char (di, '_'))
return 0;
 
return 1;
}
 
/* <ctor-dtor-name> ::= C1
::= C2
::= C3
::= D0
::= D1
::= D2
*/
 
static struct demangle_component *
d_ctor_dtor_name (struct d_info *di)
{
if (di->last_name != NULL)
{
if (di->last_name->type == DEMANGLE_COMPONENT_NAME)
di->expansion += di->last_name->u.s_name.len;
else if (di->last_name->type == DEMANGLE_COMPONENT_SUB_STD)
di->expansion += di->last_name->u.s_string.len;
}
switch (d_peek_char (di))
{
case 'C':
{
enum gnu_v3_ctor_kinds kind;
 
switch (d_peek_next_char (di))
{
case '1':
kind = gnu_v3_complete_object_ctor;
break;
case '2':
kind = gnu_v3_base_object_ctor;
break;
case '3':
kind = gnu_v3_complete_object_allocating_ctor;
break;
case '4':
kind = gnu_v3_unified_ctor;
break;
case '5':
kind = gnu_v3_object_ctor_group;
break;
default:
return NULL;
}
d_advance (di, 2);
return d_make_ctor (di, kind, di->last_name);
}
 
case 'D':
{
enum gnu_v3_dtor_kinds kind;
 
switch (d_peek_next_char (di))
{
case '0':
kind = gnu_v3_deleting_dtor;
break;
case '1':
kind = gnu_v3_complete_object_dtor;
break;
case '2':
kind = gnu_v3_base_object_dtor;
break;
/* digit '3' is not used */
case '4':
kind = gnu_v3_unified_dtor;
break;
case '5':
kind = gnu_v3_object_dtor_group;
break;
default:
return NULL;
}
d_advance (di, 2);
return d_make_dtor (di, kind, di->last_name);
}
 
default:
return NULL;
}
}
 
/* <type> ::= <builtin-type>
::= <function-type>
::= <class-enum-type>
::= <array-type>
::= <pointer-to-member-type>
::= <template-param>
::= <template-template-param> <template-args>
::= <substitution>
::= <CV-qualifiers> <type>
::= P <type>
::= R <type>
::= O <type> (C++0x)
::= C <type>
::= G <type>
::= U <source-name> <type>
 
<builtin-type> ::= various one letter codes
::= u <source-name>
*/
 
CP_STATIC_IF_GLIBCPP_V3
const struct demangle_builtin_type_info
cplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT] =
{
/* a */ { NL ("signed char"), NL ("signed char"), D_PRINT_DEFAULT },
/* b */ { NL ("bool"), NL ("boolean"), D_PRINT_BOOL },
/* c */ { NL ("char"), NL ("byte"), D_PRINT_DEFAULT },
/* d */ { NL ("double"), NL ("double"), D_PRINT_FLOAT },
/* e */ { NL ("long double"), NL ("long double"), D_PRINT_FLOAT },
/* f */ { NL ("float"), NL ("float"), D_PRINT_FLOAT },
/* g */ { NL ("__float128"), NL ("__float128"), D_PRINT_FLOAT },
/* h */ { NL ("unsigned char"), NL ("unsigned char"), D_PRINT_DEFAULT },
/* i */ { NL ("int"), NL ("int"), D_PRINT_INT },
/* j */ { NL ("unsigned int"), NL ("unsigned"), D_PRINT_UNSIGNED },
/* k */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT },
/* l */ { NL ("long"), NL ("long"), D_PRINT_LONG },
/* m */ { NL ("unsigned long"), NL ("unsigned long"), D_PRINT_UNSIGNED_LONG },
/* n */ { NL ("__int128"), NL ("__int128"), D_PRINT_DEFAULT },
/* o */ { NL ("unsigned __int128"), NL ("unsigned __int128"),
D_PRINT_DEFAULT },
/* p */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT },
/* q */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT },
/* r */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT },
/* s */ { NL ("short"), NL ("short"), D_PRINT_DEFAULT },
/* t */ { NL ("unsigned short"), NL ("unsigned short"), D_PRINT_DEFAULT },
/* u */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT },
/* v */ { NL ("void"), NL ("void"), D_PRINT_VOID },
/* w */ { NL ("wchar_t"), NL ("char"), D_PRINT_DEFAULT },
/* x */ { NL ("long long"), NL ("long"), D_PRINT_LONG_LONG },
/* y */ { NL ("unsigned long long"), NL ("unsigned long long"),
D_PRINT_UNSIGNED_LONG_LONG },
/* z */ { NL ("..."), NL ("..."), D_PRINT_DEFAULT },
/* 26 */ { NL ("decimal32"), NL ("decimal32"), D_PRINT_DEFAULT },
/* 27 */ { NL ("decimal64"), NL ("decimal64"), D_PRINT_DEFAULT },
/* 28 */ { NL ("decimal128"), NL ("decimal128"), D_PRINT_DEFAULT },
/* 29 */ { NL ("half"), NL ("half"), D_PRINT_FLOAT },
/* 30 */ { NL ("char16_t"), NL ("char16_t"), D_PRINT_DEFAULT },
/* 31 */ { NL ("char32_t"), NL ("char32_t"), D_PRINT_DEFAULT },
/* 32 */ { NL ("decltype(nullptr)"), NL ("decltype(nullptr)"),
D_PRINT_DEFAULT },
};
 
CP_STATIC_IF_GLIBCPP_V3
struct demangle_component *
cplus_demangle_type (struct d_info *di)
{
char peek;
struct demangle_component *ret;
int can_subst;
 
/* The ABI specifies that when CV-qualifiers are used, the base type
is substitutable, and the fully qualified type is substitutable,
but the base type with a strict subset of the CV-qualifiers is
not substitutable. The natural recursive implementation of the
CV-qualifiers would cause subsets to be substitutable, so instead
we pull them all off now.
 
FIXME: The ABI says that order-insensitive vendor qualifiers
should be handled in the same way, but we have no way to tell
which vendor qualifiers are order-insensitive and which are
order-sensitive. So we just assume that they are all
order-sensitive. g++ 3.4 supports only one vendor qualifier,
__vector, and it treats it as order-sensitive when mangling
names. */
 
peek = d_peek_char (di);
if (peek == 'r' || peek == 'V' || peek == 'K')
{
struct demangle_component **pret;
 
pret = d_cv_qualifiers (di, &ret, 0);
if (pret == NULL)
return NULL;
if (d_peek_char (di) == 'F')
{
/* cv-qualifiers before a function type apply to 'this',
so avoid adding the unqualified function type to
the substitution list. */
*pret = d_function_type (di);
}
else
*pret = cplus_demangle_type (di);
if (!*pret)
return NULL;
if ((*pret)->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS
|| (*pret)->type == DEMANGLE_COMPONENT_REFERENCE_THIS)
{
/* Move the ref-qualifier outside the cv-qualifiers so that
they are printed in the right order. */
struct demangle_component *fn = d_left (*pret);
d_left (*pret) = ret;
ret = *pret;
*pret = fn;
}
if (! d_add_substitution (di, ret))
return NULL;
return ret;
}
 
can_subst = 1;
 
switch (peek)
{
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
case 'h': case 'i': case 'j': case 'l': case 'm': case 'n':
case 'o': case 's': case 't':
case 'v': case 'w': case 'x': case 'y': case 'z':
ret = d_make_builtin_type (di,
&cplus_demangle_builtin_types[peek - 'a']);
di->expansion += ret->u.s_builtin.type->len;
can_subst = 0;
d_advance (di, 1);
break;
 
case 'u':
d_advance (di, 1);
ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE,
d_source_name (di), NULL);
break;
 
case 'F':
ret = d_function_type (di);
break;
 
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case 'N':
case 'Z':
ret = d_class_enum_type (di);
break;
 
case 'A':
ret = d_array_type (di);
break;
 
case 'M':
ret = d_pointer_to_member_type (di);
break;
 
case 'T':
ret = d_template_param (di);
if (d_peek_char (di) == 'I')
{
/* This may be <template-template-param> <template-args>.
If this is the type for a conversion operator, we can
have a <template-template-param> here only by following
a derivation like this:
 
<nested-name>
-> <template-prefix> <template-args>
-> <prefix> <template-unqualified-name> <template-args>
-> <unqualified-name> <template-unqualified-name> <template-args>
-> <source-name> <template-unqualified-name> <template-args>
-> <source-name> <operator-name> <template-args>
-> <source-name> cv <type> <template-args>
-> <source-name> cv <template-template-param> <template-args> <template-args>
 
where the <template-args> is followed by another.
Otherwise, we must have a derivation like this:
 
<nested-name>
-> <template-prefix> <template-args>
-> <prefix> <template-unqualified-name> <template-args>
-> <unqualified-name> <template-unqualified-name> <template-args>
-> <source-name> <template-unqualified-name> <template-args>
-> <source-name> <operator-name> <template-args>
-> <source-name> cv <type> <template-args>
-> <source-name> cv <template-param> <template-args>
 
where we need to leave the <template-args> to be processed
by d_prefix (following the <template-prefix>).
 
The <template-template-param> part is a substitution
candidate. */
if (! di->is_conversion)
{
if (! d_add_substitution (di, ret))
return NULL;
ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
d_template_args (di));
}
else
{
struct demangle_component *args;
struct d_info_checkpoint checkpoint;
 
d_checkpoint (di, &checkpoint);
args = d_template_args (di);
if (d_peek_char (di) == 'I')
{
if (! d_add_substitution (di, ret))
return NULL;
ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
args);
}
else
d_backtrack (di, &checkpoint);
}
}
break;
 
case 'S':
/* If this is a special substitution, then it is the start of
<class-enum-type>. */
{
char peek_next;
 
peek_next = d_peek_next_char (di);
if (IS_DIGIT (peek_next)
|| peek_next == '_'
|| IS_UPPER (peek_next))
{
ret = d_substitution (di, 0);
/* The substituted name may have been a template name and
may be followed by tepmlate args. */
if (d_peek_char (di) == 'I')
ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
d_template_args (di));
else
can_subst = 0;
}
else
{
ret = d_class_enum_type (di);
/* If the substitution was a complete type, then it is not
a new substitution candidate. However, if the
substitution was followed by template arguments, then
the whole thing is a substitution candidate. */
if (ret != NULL && ret->type == DEMANGLE_COMPONENT_SUB_STD)
can_subst = 0;
}
}
break;
 
case 'O':
d_advance (di, 1);
ret = d_make_comp (di, DEMANGLE_COMPONENT_RVALUE_REFERENCE,
cplus_demangle_type (di), NULL);
break;
 
case 'P':
d_advance (di, 1);
ret = d_make_comp (di, DEMANGLE_COMPONENT_POINTER,
cplus_demangle_type (di), NULL);
break;
 
case 'R':
d_advance (di, 1);
ret = d_make_comp (di, DEMANGLE_COMPONENT_REFERENCE,
cplus_demangle_type (di), NULL);
break;
 
case 'C':
d_advance (di, 1);
ret = d_make_comp (di, DEMANGLE_COMPONENT_COMPLEX,
cplus_demangle_type (di), NULL);
break;
 
case 'G':
d_advance (di, 1);
ret = d_make_comp (di, DEMANGLE_COMPONENT_IMAGINARY,
cplus_demangle_type (di), NULL);
break;
 
case 'U':
d_advance (di, 1);
ret = d_source_name (di);
ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
cplus_demangle_type (di), ret);
break;
 
case 'D':
can_subst = 0;
d_advance (di, 1);
peek = d_next_char (di);
switch (peek)
{
case 'T':
case 't':
/* decltype (expression) */
ret = d_make_comp (di, DEMANGLE_COMPONENT_DECLTYPE,
d_expression (di), NULL);
if (ret && d_next_char (di) != 'E')
ret = NULL;
can_subst = 1;
break;
case 'p':
/* Pack expansion. */
ret = d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION,
cplus_demangle_type (di), NULL);
can_subst = 1;
break;
 
case 'a':
/* auto */
ret = d_make_name (di, "auto", 4);
break;
case 'f':
/* 32-bit decimal floating point */
ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[26]);
di->expansion += ret->u.s_builtin.type->len;
break;
case 'd':
/* 64-bit DFP */
ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[27]);
di->expansion += ret->u.s_builtin.type->len;
break;
case 'e':
/* 128-bit DFP */
ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[28]);
di->expansion += ret->u.s_builtin.type->len;
break;
case 'h':
/* 16-bit half-precision FP */
ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[29]);
di->expansion += ret->u.s_builtin.type->len;
break;
case 's':
/* char16_t */
ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[30]);
di->expansion += ret->u.s_builtin.type->len;
break;
case 'i':
/* char32_t */
ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[31]);
di->expansion += ret->u.s_builtin.type->len;
break;
 
case 'F':
/* Fixed point types. DF<int bits><length><fract bits><sat> */
ret = d_make_empty (di);
ret->type = DEMANGLE_COMPONENT_FIXED_TYPE;
if ((ret->u.s_fixed.accum = IS_DIGIT (d_peek_char (di))))
/* For demangling we don't care about the bits. */
d_number (di);
ret->u.s_fixed.length = cplus_demangle_type (di);
if (ret->u.s_fixed.length == NULL)
return NULL;
d_number (di);
peek = d_next_char (di);
ret->u.s_fixed.sat = (peek == 's');
break;
 
case 'v':
ret = d_vector_type (di);
can_subst = 1;
break;
 
case 'n':
/* decltype(nullptr) */
ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[32]);
di->expansion += ret->u.s_builtin.type->len;
break;
 
default:
return NULL;
}
break;
 
default:
return NULL;
}
 
if (can_subst)
{
if (! d_add_substitution (di, ret))
return NULL;
}
 
return ret;
}
 
/* <CV-qualifiers> ::= [r] [V] [K] */
 
static struct demangle_component **
d_cv_qualifiers (struct d_info *di,
struct demangle_component **pret, int member_fn)
{
struct demangle_component **pstart;
char peek;
 
pstart = pret;
peek = d_peek_char (di);
while (peek == 'r' || peek == 'V' || peek == 'K')
{
enum demangle_component_type t;
 
d_advance (di, 1);
if (peek == 'r')
{
t = (member_fn
? DEMANGLE_COMPONENT_RESTRICT_THIS
: DEMANGLE_COMPONENT_RESTRICT);
di->expansion += sizeof "restrict";
}
else if (peek == 'V')
{
t = (member_fn
? DEMANGLE_COMPONENT_VOLATILE_THIS
: DEMANGLE_COMPONENT_VOLATILE);
di->expansion += sizeof "volatile";
}
else
{
t = (member_fn
? DEMANGLE_COMPONENT_CONST_THIS
: DEMANGLE_COMPONENT_CONST);
di->expansion += sizeof "const";
}
 
*pret = d_make_comp (di, t, NULL, NULL);
if (*pret == NULL)
return NULL;
pret = &d_left (*pret);
 
peek = d_peek_char (di);
}
 
if (!member_fn && peek == 'F')
{
while (pstart != pret)
{
switch ((*pstart)->type)
{
case DEMANGLE_COMPONENT_RESTRICT:
(*pstart)->type = DEMANGLE_COMPONENT_RESTRICT_THIS;
break;
case DEMANGLE_COMPONENT_VOLATILE:
(*pstart)->type = DEMANGLE_COMPONENT_VOLATILE_THIS;
break;
case DEMANGLE_COMPONENT_CONST:
(*pstart)->type = DEMANGLE_COMPONENT_CONST_THIS;
break;
default:
break;
}
pstart = &d_left (*pstart);
}
}
 
return pret;
}
 
/* <ref-qualifier> ::= R
::= O */
 
static struct demangle_component *
d_ref_qualifier (struct d_info *di, struct demangle_component *sub)
{
struct demangle_component *ret = sub;
char peek;
 
peek = d_peek_char (di);
if (peek == 'R' || peek == 'O')
{
enum demangle_component_type t;
if (peek == 'R')
{
t = DEMANGLE_COMPONENT_REFERENCE_THIS;
di->expansion += sizeof "&";
}
else
{
t = DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS;
di->expansion += sizeof "&&";
}
d_advance (di, 1);
 
ret = d_make_comp (di, t, ret, NULL);
}
 
return ret;
}
 
/* <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E */
 
static struct demangle_component *
d_function_type (struct d_info *di)
{
struct demangle_component *ret;
 
if (! d_check_char (di, 'F'))
return NULL;
if (d_peek_char (di) == 'Y')
{
/* Function has C linkage. We don't print this information.
FIXME: We should print it in verbose mode. */
d_advance (di, 1);
}
ret = d_bare_function_type (di, 1);
ret = d_ref_qualifier (di, ret);
 
if (! d_check_char (di, 'E'))
return NULL;
return ret;
}
 
/* <type>+ */
 
static struct demangle_component *
d_parmlist (struct d_info *di)
{
struct demangle_component *tl;
struct demangle_component **ptl;
 
tl = NULL;
ptl = &tl;
while (1)
{
struct demangle_component *type;
 
char peek = d_peek_char (di);
if (peek == '\0' || peek == 'E' || peek == '.')
break;
if ((peek == 'R' || peek == 'O')
&& d_peek_next_char (di) == 'E')
/* Function ref-qualifier, not a ref prefix for a parameter type. */
break;
type = cplus_demangle_type (di);
if (type == NULL)
return NULL;
*ptl = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, type, NULL);
if (*ptl == NULL)
return NULL;
ptl = &d_right (*ptl);
}
 
/* There should be at least one parameter type besides the optional
return type. A function which takes no arguments will have a
single parameter type void. */
if (tl == NULL)
return NULL;
 
/* If we have a single parameter type void, omit it. */
if (d_right (tl) == NULL
&& d_left (tl)->type == DEMANGLE_COMPONENT_BUILTIN_TYPE
&& d_left (tl)->u.s_builtin.type->print == D_PRINT_VOID)
{
di->expansion -= d_left (tl)->u.s_builtin.type->len;
d_left (tl) = NULL;
}
 
return tl;
}
 
/* <bare-function-type> ::= [J]<type>+ */
 
static struct demangle_component *
d_bare_function_type (struct d_info *di, int has_return_type)
{
struct demangle_component *return_type;
struct demangle_component *tl;
char peek;
 
/* Detect special qualifier indicating that the first argument
is the return type. */
peek = d_peek_char (di);
if (peek == 'J')
{
d_advance (di, 1);
has_return_type = 1;
}
 
if (has_return_type)
{
return_type = cplus_demangle_type (di);
if (return_type == NULL)
return NULL;
}
else
return_type = NULL;
 
tl = d_parmlist (di);
if (tl == NULL)
return NULL;
 
return d_make_comp (di, DEMANGLE_COMPONENT_FUNCTION_TYPE,
return_type, tl);
}
 
/* <class-enum-type> ::= <name> */
 
static struct demangle_component *
d_class_enum_type (struct d_info *di)
{
return d_name (di);
}
 
/* <array-type> ::= A <(positive dimension) number> _ <(element) type>
::= A [<(dimension) expression>] _ <(element) type>
*/
 
static struct demangle_component *
d_array_type (struct d_info *di)
{
char peek;
struct demangle_component *dim;
 
if (! d_check_char (di, 'A'))
return NULL;
 
peek = d_peek_char (di);
if (peek == '_')
dim = NULL;
else if (IS_DIGIT (peek))
{
const char *s;
 
s = d_str (di);
do
{
d_advance (di, 1);
peek = d_peek_char (di);
}
while (IS_DIGIT (peek));
dim = d_make_name (di, s, d_str (di) - s);
if (dim == NULL)
return NULL;
}
else
{
dim = d_expression (di);
if (dim == NULL)
return NULL;
}
 
if (! d_check_char (di, '_'))
return NULL;
 
return d_make_comp (di, DEMANGLE_COMPONENT_ARRAY_TYPE, dim,
cplus_demangle_type (di));
}
 
/* <vector-type> ::= Dv <number> _ <type>
::= Dv _ <expression> _ <type> */
 
static struct demangle_component *
d_vector_type (struct d_info *di)
{
char peek;
struct demangle_component *dim;
 
peek = d_peek_char (di);
if (peek == '_')
{
d_advance (di, 1);
dim = d_expression (di);
}
else
dim = d_number_component (di);
 
if (dim == NULL)
return NULL;
 
if (! d_check_char (di, '_'))
return NULL;
 
return d_make_comp (di, DEMANGLE_COMPONENT_VECTOR_TYPE, dim,
cplus_demangle_type (di));
}
 
/* <pointer-to-member-type> ::= M <(class) type> <(member) type> */
 
static struct demangle_component *
d_pointer_to_member_type (struct d_info *di)
{
struct demangle_component *cl;
struct demangle_component *mem;
 
if (! d_check_char (di, 'M'))
return NULL;
 
cl = cplus_demangle_type (di);
if (cl == NULL)
return NULL;
 
/* The ABI says, "The type of a non-static member function is considered
to be different, for the purposes of substitution, from the type of a
namespace-scope or static member function whose type appears
similar. The types of two non-static member functions are considered
to be different, for the purposes of substitution, if the functions
are members of different classes. In other words, for the purposes of
substitution, the class of which the function is a member is
considered part of the type of function."
 
For a pointer to member function, this call to cplus_demangle_type
will end up adding a (possibly qualified) non-member function type to
the substitution table, which is not correct; however, the member
function type will never be used in a substitution, so putting the
wrong type in the substitution table is harmless. */
 
mem = cplus_demangle_type (di);
if (mem == NULL)
return NULL;
 
return d_make_comp (di, DEMANGLE_COMPONENT_PTRMEM_TYPE, cl, mem);
}
 
/* <non-negative number> _ */
 
static int
d_compact_number (struct d_info *di)
{
int num;
if (d_peek_char (di) == '_')
num = 0;
else if (d_peek_char (di) == 'n')
return -1;
else
num = d_number (di) + 1;
 
if (num < 0 || ! d_check_char (di, '_'))
return -1;
return num;
}
 
/* <template-param> ::= T_
::= T <(parameter-2 non-negative) number> _
*/
 
static struct demangle_component *
d_template_param (struct d_info *di)
{
int param;
 
if (! d_check_char (di, 'T'))
return NULL;
 
param = d_compact_number (di);
if (param < 0)
return NULL;
 
++di->did_subs;
 
return d_make_template_param (di, param);
}
 
/* <template-args> ::= I <template-arg>+ E */
 
static struct demangle_component *
d_template_args (struct d_info *di)
{
struct demangle_component *hold_last_name;
struct demangle_component *al;
struct demangle_component **pal;
 
/* Preserve the last name we saw--don't let the template arguments
clobber it, as that would give us the wrong name for a subsequent
constructor or destructor. */
hold_last_name = di->last_name;
 
if (d_peek_char (di) != 'I'
&& d_peek_char (di) != 'J')
return NULL;
d_advance (di, 1);
 
if (d_peek_char (di) == 'E')
{
/* An argument pack can be empty. */
d_advance (di, 1);
return d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, NULL, NULL);
}
 
al = NULL;
pal = &al;
while (1)
{
struct demangle_component *a;
 
a = d_template_arg (di);
if (a == NULL)
return NULL;
 
*pal = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, a, NULL);
if (*pal == NULL)
return NULL;
pal = &d_right (*pal);
 
if (d_peek_char (di) == 'E')
{
d_advance (di, 1);
break;
}
}
 
di->last_name = hold_last_name;
 
return al;
}
 
/* <template-arg> ::= <type>
::= X <expression> E
::= <expr-primary>
*/
 
static struct demangle_component *
d_template_arg (struct d_info *di)
{
struct demangle_component *ret;
 
switch (d_peek_char (di))
{
case 'X':
d_advance (di, 1);
ret = d_expression (di);
if (! d_check_char (di, 'E'))
return NULL;
return ret;
 
case 'L':
return d_expr_primary (di);
 
case 'I':
case 'J':
/* An argument pack. */
return d_template_args (di);
 
default:
return cplus_demangle_type (di);
}
}
 
/* Parse a sequence of expressions until we hit the terminator
character. */
 
static struct demangle_component *
d_exprlist (struct d_info *di, char terminator)
{
struct demangle_component *list = NULL;
struct demangle_component **p = &list;
 
if (d_peek_char (di) == terminator)
{
d_advance (di, 1);
return d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, NULL, NULL);
}
 
while (1)
{
struct demangle_component *arg = d_expression (di);
if (arg == NULL)
return NULL;
 
*p = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, arg, NULL);
if (*p == NULL)
return NULL;
p = &d_right (*p);
 
if (d_peek_char (di) == terminator)
{
d_advance (di, 1);
break;
}
}
 
return list;
}
 
/* Returns nonzero iff OP is an operator for a C++ cast: const_cast,
dynamic_cast, static_cast or reinterpret_cast. */
 
static int
op_is_new_cast (struct demangle_component *op)
{
const char *code = op->u.s_operator.op->code;
return (code[1] == 'c'
&& (code[0] == 's' || code[0] == 'd'
|| code[0] == 'c' || code[0] == 'r'));
}
 
/* <expression> ::= <(unary) operator-name> <expression>
::= <(binary) operator-name> <expression> <expression>
::= <(trinary) operator-name> <expression> <expression> <expression>
::= cl <expression>+ E
::= st <type>
::= <template-param>
::= sr <type> <unqualified-name>
::= sr <type> <unqualified-name> <template-args>
::= <expr-primary>
*/
 
static inline struct demangle_component *
d_expression_1 (struct d_info *di)
{
char peek;
 
peek = d_peek_char (di);
if (peek == 'L')
return d_expr_primary (di);
else if (peek == 'T')
return d_template_param (di);
else if (peek == 's' && d_peek_next_char (di) == 'r')
{
struct demangle_component *type;
struct demangle_component *name;
 
d_advance (di, 2);
type = cplus_demangle_type (di);
name = d_unqualified_name (di);
if (d_peek_char (di) != 'I')
return d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, type, name);
else
return d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, type,
d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
d_template_args (di)));
}
else if (peek == 's' && d_peek_next_char (di) == 'p')
{
d_advance (di, 2);
return d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION,
d_expression_1 (di), NULL);
}
else if (peek == 'f' && d_peek_next_char (di) == 'p')
{
/* Function parameter used in a late-specified return type. */
int index;
d_advance (di, 2);
if (d_peek_char (di) == 'T')
{
/* 'this' parameter. */
d_advance (di, 1);
index = 0;
}
else
{
index = d_compact_number (di);
if (index == INT_MAX || index == -1)
return NULL;
index++;
}
return d_make_function_param (di, index);
}
else if (IS_DIGIT (peek)
|| (peek == 'o' && d_peek_next_char (di) == 'n'))
{
/* We can get an unqualified name as an expression in the case of
a dependent function call, i.e. decltype(f(t)). */
struct demangle_component *name;
 
if (peek == 'o')
/* operator-function-id, i.e. operator+(t). */
d_advance (di, 2);
 
name = d_unqualified_name (di);
if (name == NULL)
return NULL;
if (d_peek_char (di) == 'I')
return d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
d_template_args (di));
else
return name;
}
else if ((peek == 'i' || peek == 't')
&& d_peek_next_char (di) == 'l')
{
/* Brace-enclosed initializer list, untyped or typed. */
struct demangle_component *type = NULL;
if (peek == 't')
type = cplus_demangle_type (di);
if (!d_peek_next_char (di))
return NULL;
d_advance (di, 2);
return d_make_comp (di, DEMANGLE_COMPONENT_INITIALIZER_LIST,
type, d_exprlist (di, 'E'));
}
else
{
struct demangle_component *op;
const char *code = NULL;
int args;
 
op = d_operator_name (di);
if (op == NULL)
return NULL;
 
if (op->type == DEMANGLE_COMPONENT_OPERATOR)
{
code = op->u.s_operator.op->code;
di->expansion += op->u.s_operator.op->len - 2;
if (strcmp (code, "st") == 0)
return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
cplus_demangle_type (di));
}
 
switch (op->type)
{
default:
return NULL;
case DEMANGLE_COMPONENT_OPERATOR:
args = op->u.s_operator.op->args;
break;
case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
args = op->u.s_extended_operator.args;
break;
case DEMANGLE_COMPONENT_CAST:
args = 1;
break;
}
 
switch (args)
{
case 0:
return d_make_comp (di, DEMANGLE_COMPONENT_NULLARY, op, NULL);
 
case 1:
{
struct demangle_component *operand;
int suffix = 0;
 
if (code && (code[0] == 'p' || code[0] == 'm')
&& code[1] == code[0])
/* pp_ and mm_ are the prefix variants. */
suffix = !d_check_char (di, '_');
 
if (op->type == DEMANGLE_COMPONENT_CAST
&& d_check_char (di, '_'))
operand = d_exprlist (di, 'E');
else
operand = d_expression_1 (di);
 
if (suffix)
/* Indicate the suffix variant for d_print_comp. */
return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
d_make_comp (di,
DEMANGLE_COMPONENT_BINARY_ARGS,
operand, operand));
else
return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
operand);
}
case 2:
{
struct demangle_component *left;
struct demangle_component *right;
 
if (code == NULL)
return NULL;
if (op_is_new_cast (op))
left = cplus_demangle_type (di);
else
left = d_expression_1 (di);
if (!strcmp (code, "cl"))
right = d_exprlist (di, 'E');
else if (!strcmp (code, "dt") || !strcmp (code, "pt"))
{
right = d_unqualified_name (di);
if (d_peek_char (di) == 'I')
right = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE,
right, d_template_args (di));
}
else
right = d_expression_1 (di);
 
return d_make_comp (di, DEMANGLE_COMPONENT_BINARY, op,
d_make_comp (di,
DEMANGLE_COMPONENT_BINARY_ARGS,
left, right));
}
case 3:
{
struct demangle_component *first;
struct demangle_component *second;
struct demangle_component *third;
 
if (code == NULL)
return NULL;
else if (!strcmp (code, "qu"))
{
/* ?: expression. */
first = d_expression_1 (di);
second = d_expression_1 (di);
third = d_expression_1 (di);
}
else if (code[0] == 'n')
{
/* new-expression. */
if (code[1] != 'w' && code[1] != 'a')
return NULL;
first = d_exprlist (di, '_');
second = cplus_demangle_type (di);
if (d_peek_char (di) == 'E')
{
d_advance (di, 1);
third = NULL;
}
else if (d_peek_char (di) == 'p'
&& d_peek_next_char (di) == 'i')
{
/* Parenthesized initializer. */
d_advance (di, 2);
third = d_exprlist (di, 'E');
}
else if (d_peek_char (di) == 'i'
&& d_peek_next_char (di) == 'l')
/* initializer-list. */
third = d_expression_1 (di);
else
return NULL;
}
else
return NULL;
return d_make_comp (di, DEMANGLE_COMPONENT_TRINARY, op,
d_make_comp (di,
DEMANGLE_COMPONENT_TRINARY_ARG1,
first,
d_make_comp (di,
DEMANGLE_COMPONENT_TRINARY_ARG2,
second, third)));
}
default:
return NULL;
}
}
}
 
static struct demangle_component *
d_expression (struct d_info *di)
{
struct demangle_component *ret;
int was_expression = di->is_expression;
 
di->is_expression = 1;
ret = d_expression_1 (di);
di->is_expression = was_expression;
return ret;
}
 
/* <expr-primary> ::= L <type> <(value) number> E
::= L <type> <(value) float> E
::= L <mangled-name> E
*/
 
static struct demangle_component *
d_expr_primary (struct d_info *di)
{
struct demangle_component *ret;
 
if (! d_check_char (di, 'L'))
return NULL;
if (d_peek_char (di) == '_'
/* Workaround for G++ bug; see comment in write_template_arg. */
|| d_peek_char (di) == 'Z')
ret = cplus_demangle_mangled_name (di, 0);
else
{
struct demangle_component *type;
enum demangle_component_type t;
const char *s;
 
type = cplus_demangle_type (di);
if (type == NULL)
return NULL;
 
/* If we have a type we know how to print, we aren't going to
print the type name itself. */
if (type->type == DEMANGLE_COMPONENT_BUILTIN_TYPE
&& type->u.s_builtin.type->print != D_PRINT_DEFAULT)
di->expansion -= type->u.s_builtin.type->len;
 
/* Rather than try to interpret the literal value, we just
collect it as a string. Note that it's possible to have a
floating point literal here. The ABI specifies that the
format of such literals is machine independent. That's fine,
but what's not fine is that versions of g++ up to 3.2 with
-fabi-version=1 used upper case letters in the hex constant,
and dumped out gcc's internal representation. That makes it
hard to tell where the constant ends, and hard to dump the
constant in any readable form anyhow. We don't attempt to
handle these cases. */
 
t = DEMANGLE_COMPONENT_LITERAL;
if (d_peek_char (di) == 'n')
{
t = DEMANGLE_COMPONENT_LITERAL_NEG;
d_advance (di, 1);
}
s = d_str (di);
while (d_peek_char (di) != 'E')
{
if (d_peek_char (di) == '\0')
return NULL;
d_advance (di, 1);
}
ret = d_make_comp (di, t, type, d_make_name (di, s, d_str (di) - s));
}
if (! d_check_char (di, 'E'))
return NULL;
return ret;
}
 
/* <local-name> ::= Z <(function) encoding> E <(entity) name> [<discriminator>]
::= Z <(function) encoding> E s [<discriminator>]
::= Z <(function) encoding> E d [<parameter> number>] _ <entity name>
*/
 
static struct demangle_component *
d_local_name (struct d_info *di)
{
struct demangle_component *function;
 
if (! d_check_char (di, 'Z'))
return NULL;
 
function = d_encoding (di, 0);
 
if (! d_check_char (di, 'E'))
return NULL;
 
if (d_peek_char (di) == 's')
{
d_advance (di, 1);
if (! d_discriminator (di))
return NULL;
return d_make_comp (di, DEMANGLE_COMPONENT_LOCAL_NAME, function,
d_make_name (di, "string literal",
sizeof "string literal" - 1));
}
else
{
struct demangle_component *name;
int num = -1;
 
if (d_peek_char (di) == 'd')
{
/* Default argument scope: d <number> _. */
d_advance (di, 1);
num = d_compact_number (di);
if (num < 0)
return NULL;
}
 
name = d_name (di);
if (name)
switch (name->type)
{
/* Lambdas and unnamed types have internal discriminators. */
case DEMANGLE_COMPONENT_LAMBDA:
case DEMANGLE_COMPONENT_UNNAMED_TYPE:
break;
default:
if (! d_discriminator (di))
return NULL;
}
if (num >= 0)
name = d_make_default_arg (di, num, name);
return d_make_comp (di, DEMANGLE_COMPONENT_LOCAL_NAME, function, name);
}
}
 
/* <discriminator> ::= _ <(non-negative) number>
 
We demangle the discriminator, but we don't print it out. FIXME:
We should print it out in verbose mode. */
 
static int
d_discriminator (struct d_info *di)
{
int discrim;
 
if (d_peek_char (di) != '_')
return 1;
d_advance (di, 1);
discrim = d_number (di);
if (discrim < 0)
return 0;
return 1;
}
 
/* <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _ */
 
static struct demangle_component *
d_lambda (struct d_info *di)
{
struct demangle_component *tl;
struct demangle_component *ret;
int num;
 
if (! d_check_char (di, 'U'))
return NULL;
if (! d_check_char (di, 'l'))
return NULL;
 
tl = d_parmlist (di);
if (tl == NULL)
return NULL;
 
if (! d_check_char (di, 'E'))
return NULL;
 
num = d_compact_number (di);
if (num < 0)
return NULL;
 
ret = d_make_empty (di);
if (ret)
{
ret->type = DEMANGLE_COMPONENT_LAMBDA;
ret->u.s_unary_num.sub = tl;
ret->u.s_unary_num.num = num;
}
 
if (! d_add_substitution (di, ret))
return NULL;
 
return ret;
}
 
/* <unnamed-type-name> ::= Ut [ <nonnegative number> ] _ */
 
static struct demangle_component *
d_unnamed_type (struct d_info *di)
{
struct demangle_component *ret;
int num;
 
if (! d_check_char (di, 'U'))
return NULL;
if (! d_check_char (di, 't'))
return NULL;
 
num = d_compact_number (di);
if (num < 0)
return NULL;
 
ret = d_make_empty (di);
if (ret)
{
ret->type = DEMANGLE_COMPONENT_UNNAMED_TYPE;
ret->u.s_number.number = num;
}
 
if (! d_add_substitution (di, ret))
return NULL;
 
return ret;
}
 
/* <clone-suffix> ::= [ . <clone-type-identifier> ] [ . <nonnegative number> ]*
*/
 
static struct demangle_component *
d_clone_suffix (struct d_info *di, struct demangle_component *encoding)
{
const char *suffix = d_str (di);
const char *pend = suffix;
struct demangle_component *n;
 
if (*pend == '.' && (IS_LOWER (pend[1]) || pend[1] == '_'))
{
pend += 2;
while (IS_LOWER (*pend) || *pend == '_')
++pend;
}
while (*pend == '.' && IS_DIGIT (pend[1]))
{
pend += 2;
while (IS_DIGIT (*pend))
++pend;
}
d_advance (di, pend - suffix);
n = d_make_name (di, suffix, pend - suffix);
return d_make_comp (di, DEMANGLE_COMPONENT_CLONE, encoding, n);
}
 
/* Add a new substitution. */
 
static int
d_add_substitution (struct d_info *di, struct demangle_component *dc)
{
if (dc == NULL)
return 0;
if (di->next_sub >= di->num_subs)
return 0;
di->subs[di->next_sub] = dc;
++di->next_sub;
return 1;
}
 
/* <substitution> ::= S <seq-id> _
::= S_
::= St
::= Sa
::= Sb
::= Ss
::= Si
::= So
::= Sd
 
If PREFIX is non-zero, then this type is being used as a prefix in
a qualified name. In this case, for the standard substitutions, we
need to check whether we are being used as a prefix for a
constructor or destructor, and return a full template name.
Otherwise we will get something like std::iostream::~iostream()
which does not correspond particularly well to any function which
actually appears in the source.
*/
 
static const struct d_standard_sub_info standard_subs[] =
{
{ 't', NL ("std"),
NL ("std"),
NULL, 0 },
{ 'a', NL ("std::allocator"),
NL ("std::allocator"),
NL ("allocator") },
{ 'b', NL ("std::basic_string"),
NL ("std::basic_string"),
NL ("basic_string") },
{ 's', NL ("std::string"),
NL ("std::basic_string<char, std::char_traits<char>, std::allocator<char> >"),
NL ("basic_string") },
{ 'i', NL ("std::istream"),
NL ("std::basic_istream<char, std::char_traits<char> >"),
NL ("basic_istream") },
{ 'o', NL ("std::ostream"),
NL ("std::basic_ostream<char, std::char_traits<char> >"),
NL ("basic_ostream") },
{ 'd', NL ("std::iostream"),
NL ("std::basic_iostream<char, std::char_traits<char> >"),
NL ("basic_iostream") }
};
 
static struct demangle_component *
d_substitution (struct d_info *di, int prefix)
{
char c;
 
if (! d_check_char (di, 'S'))
return NULL;
 
c = d_next_char (di);
if (c == '_' || IS_DIGIT (c) || IS_UPPER (c))
{
unsigned int id;
 
id = 0;
if (c != '_')
{
do
{
unsigned int new_id;
 
if (IS_DIGIT (c))
new_id = id * 36 + c - '0';
else if (IS_UPPER (c))
new_id = id * 36 + c - 'A' + 10;
else
return NULL;
if (new_id < id)
return NULL;
id = new_id;
c = d_next_char (di);
}
while (c != '_');
 
++id;
}
 
if (id >= (unsigned int) di->next_sub)
return NULL;
 
++di->did_subs;
 
return di->subs[id];
}
else
{
int verbose;
const struct d_standard_sub_info *p;
const struct d_standard_sub_info *pend;
 
verbose = (di->options & DMGL_VERBOSE) != 0;
if (! verbose && prefix)
{
char peek;
 
peek = d_peek_char (di);
if (peek == 'C' || peek == 'D')
verbose = 1;
}
 
pend = (&standard_subs[0]
+ sizeof standard_subs / sizeof standard_subs[0]);
for (p = &standard_subs[0]; p < pend; ++p)
{
if (c == p->code)
{
const char *s;
int len;
struct demangle_component *c;
 
if (p->set_last_name != NULL)
di->last_name = d_make_sub (di, p->set_last_name,
p->set_last_name_len);
if (verbose)
{
s = p->full_expansion;
len = p->full_len;
}
else
{
s = p->simple_expansion;
len = p->simple_len;
}
di->expansion += len;
c = d_make_sub (di, s, len);
if (d_peek_char (di) == 'B')
{
/* If there are ABI tags on the abbreviation, it becomes
a substitution candidate. */
c = d_abi_tags (di, c);
d_add_substitution (di, c);
}
return c;
}
}
 
return NULL;
}
}
 
static void
d_checkpoint (struct d_info *di, struct d_info_checkpoint *checkpoint)
{
checkpoint->n = di->n;
checkpoint->next_comp = di->next_comp;
checkpoint->next_sub = di->next_sub;
checkpoint->did_subs = di->did_subs;
checkpoint->expansion = di->expansion;
}
 
static void
d_backtrack (struct d_info *di, struct d_info_checkpoint *checkpoint)
{
di->n = checkpoint->n;
di->next_comp = checkpoint->next_comp;
di->next_sub = checkpoint->next_sub;
di->did_subs = checkpoint->did_subs;
di->expansion = checkpoint->expansion;
}
 
/* Initialize a growable string. */
 
static void
d_growable_string_init (struct d_growable_string *dgs, size_t estimate)
{
dgs->buf = NULL;
dgs->len = 0;
dgs->alc = 0;
dgs->allocation_failure = 0;
 
if (estimate > 0)
d_growable_string_resize (dgs, estimate);
}
 
/* Grow a growable string to a given size. */
 
static inline void
d_growable_string_resize (struct d_growable_string *dgs, size_t need)
{
size_t newalc;
char *newbuf;
 
if (dgs->allocation_failure)
return;
 
/* Start allocation at two bytes to avoid any possibility of confusion
with the special value of 1 used as a return in *palc to indicate
allocation failures. */
newalc = dgs->alc > 0 ? dgs->alc : 2;
while (newalc < need)
newalc <<= 1;
 
newbuf = (char *) realloc (dgs->buf, newalc);
if (newbuf == NULL)
{
free (dgs->buf);
dgs->buf = NULL;
dgs->len = 0;
dgs->alc = 0;
dgs->allocation_failure = 1;
return;
}
dgs->buf = newbuf;
dgs->alc = newalc;
}
 
/* Append a buffer to a growable string. */
 
static inline void
d_growable_string_append_buffer (struct d_growable_string *dgs,
const char *s, size_t l)
{
size_t need;
 
need = dgs->len + l + 1;
if (need > dgs->alc)
d_growable_string_resize (dgs, need);
 
if (dgs->allocation_failure)
return;
 
memcpy (dgs->buf + dgs->len, s, l);
dgs->buf[dgs->len + l] = '\0';
dgs->len += l;
}
 
/* Bridge growable strings to the callback mechanism. */
 
static void
d_growable_string_callback_adapter (const char *s, size_t l, void *opaque)
{
struct d_growable_string *dgs = (struct d_growable_string*) opaque;
 
d_growable_string_append_buffer (dgs, s, l);
}
 
/* Walk the tree, counting the number of templates encountered, and
the number of times a scope might be saved. These counts will be
used to allocate data structures for d_print_comp, so the logic
here must mirror the logic d_print_comp will use. It is not
important that the resulting numbers are exact, so long as they
are larger than the actual numbers encountered. */
 
static void
d_count_templates_scopes (int *num_templates, int *num_scopes,
const struct demangle_component *dc)
{
if (dc == NULL)
return;
 
switch (dc->type)
{
case DEMANGLE_COMPONENT_NAME:
case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
case DEMANGLE_COMPONENT_FUNCTION_PARAM:
case DEMANGLE_COMPONENT_SUB_STD:
case DEMANGLE_COMPONENT_BUILTIN_TYPE:
case DEMANGLE_COMPONENT_OPERATOR:
case DEMANGLE_COMPONENT_CHARACTER:
case DEMANGLE_COMPONENT_NUMBER:
case DEMANGLE_COMPONENT_UNNAMED_TYPE:
break;
 
case DEMANGLE_COMPONENT_TEMPLATE:
(*num_templates)++;
goto recurse_left_right;
 
case DEMANGLE_COMPONENT_REFERENCE:
case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
if (d_left (dc)->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM)
(*num_scopes)++;
goto recurse_left_right;
 
case DEMANGLE_COMPONENT_QUAL_NAME:
case DEMANGLE_COMPONENT_LOCAL_NAME:
case DEMANGLE_COMPONENT_TYPED_NAME:
case DEMANGLE_COMPONENT_VTABLE:
case DEMANGLE_COMPONENT_VTT:
case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
case DEMANGLE_COMPONENT_TYPEINFO:
case DEMANGLE_COMPONENT_TYPEINFO_NAME:
case DEMANGLE_COMPONENT_TYPEINFO_FN:
case DEMANGLE_COMPONENT_THUNK:
case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
case DEMANGLE_COMPONENT_COVARIANT_THUNK:
case DEMANGLE_COMPONENT_JAVA_CLASS:
case DEMANGLE_COMPONENT_GUARD:
case DEMANGLE_COMPONENT_TLS_INIT:
case DEMANGLE_COMPONENT_TLS_WRAPPER:
case DEMANGLE_COMPONENT_REFTEMP:
case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
case DEMANGLE_COMPONENT_RESTRICT:
case DEMANGLE_COMPONENT_VOLATILE:
case DEMANGLE_COMPONENT_CONST:
case DEMANGLE_COMPONENT_RESTRICT_THIS:
case DEMANGLE_COMPONENT_VOLATILE_THIS:
case DEMANGLE_COMPONENT_CONST_THIS:
case DEMANGLE_COMPONENT_REFERENCE_THIS:
case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
case DEMANGLE_COMPONENT_POINTER:
case DEMANGLE_COMPONENT_COMPLEX:
case DEMANGLE_COMPONENT_IMAGINARY:
case DEMANGLE_COMPONENT_VENDOR_TYPE:
case DEMANGLE_COMPONENT_FUNCTION_TYPE:
case DEMANGLE_COMPONENT_ARRAY_TYPE:
case DEMANGLE_COMPONENT_PTRMEM_TYPE:
case DEMANGLE_COMPONENT_VECTOR_TYPE:
case DEMANGLE_COMPONENT_ARGLIST:
case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
case DEMANGLE_COMPONENT_INITIALIZER_LIST:
case DEMANGLE_COMPONENT_CAST:
case DEMANGLE_COMPONENT_CONVERSION:
case DEMANGLE_COMPONENT_NULLARY:
case DEMANGLE_COMPONENT_UNARY:
case DEMANGLE_COMPONENT_BINARY:
case DEMANGLE_COMPONENT_BINARY_ARGS:
case DEMANGLE_COMPONENT_TRINARY:
case DEMANGLE_COMPONENT_TRINARY_ARG1:
case DEMANGLE_COMPONENT_TRINARY_ARG2:
case DEMANGLE_COMPONENT_LITERAL:
case DEMANGLE_COMPONENT_LITERAL_NEG:
case DEMANGLE_COMPONENT_JAVA_RESOURCE:
case DEMANGLE_COMPONENT_COMPOUND_NAME:
case DEMANGLE_COMPONENT_DECLTYPE:
case DEMANGLE_COMPONENT_TRANSACTION_CLONE:
case DEMANGLE_COMPONENT_NONTRANSACTION_CLONE:
case DEMANGLE_COMPONENT_PACK_EXPANSION:
case DEMANGLE_COMPONENT_TAGGED_NAME:
case DEMANGLE_COMPONENT_CLONE:
recurse_left_right:
d_count_templates_scopes (num_templates, num_scopes,
d_left (dc));
d_count_templates_scopes (num_templates, num_scopes,
d_right (dc));
break;
 
case DEMANGLE_COMPONENT_CTOR:
d_count_templates_scopes (num_templates, num_scopes,
dc->u.s_ctor.name);
break;
 
case DEMANGLE_COMPONENT_DTOR:
d_count_templates_scopes (num_templates, num_scopes,
dc->u.s_dtor.name);
break;
 
case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
d_count_templates_scopes (num_templates, num_scopes,
dc->u.s_extended_operator.name);
break;
 
case DEMANGLE_COMPONENT_FIXED_TYPE:
d_count_templates_scopes (num_templates, num_scopes,
dc->u.s_fixed.length);
break;
 
case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS:
case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS:
d_count_templates_scopes (num_templates, num_scopes,
d_left (dc));
break;
 
case DEMANGLE_COMPONENT_LAMBDA:
case DEMANGLE_COMPONENT_DEFAULT_ARG:
d_count_templates_scopes (num_templates, num_scopes,
dc->u.s_unary_num.sub);
break;
}
}
 
/* Initialize a print information structure. */
 
static void
d_print_init (struct d_print_info *dpi, demangle_callbackref callback,
void *opaque, const struct demangle_component *dc)
{
dpi->len = 0;
dpi->last_char = '\0';
dpi->templates = NULL;
dpi->modifiers = NULL;
dpi->pack_index = 0;
dpi->flush_count = 0;
 
dpi->callback = callback;
dpi->opaque = opaque;
 
dpi->demangle_failure = 0;
 
dpi->component_stack = NULL;
 
dpi->saved_scopes = NULL;
dpi->next_saved_scope = 0;
dpi->num_saved_scopes = 0;
 
dpi->copy_templates = NULL;
dpi->next_copy_template = 0;
dpi->num_copy_templates = 0;
 
d_count_templates_scopes (&dpi->num_copy_templates,
&dpi->num_saved_scopes, dc);
dpi->num_copy_templates *= dpi->num_saved_scopes;
 
dpi->current_template = NULL;
}
 
/* Indicate that an error occurred during printing, and test for error. */
 
static inline void
d_print_error (struct d_print_info *dpi)
{
dpi->demangle_failure = 1;
}
 
static inline int
d_print_saw_error (struct d_print_info *dpi)
{
return dpi->demangle_failure != 0;
}
 
/* Flush buffered characters to the callback. */
 
static inline void
d_print_flush (struct d_print_info *dpi)
{
dpi->buf[dpi->len] = '\0';
dpi->callback (dpi->buf, dpi->len, dpi->opaque);
dpi->len = 0;
dpi->flush_count++;
}
 
/* Append characters and buffers for printing. */
 
static inline void
d_append_char (struct d_print_info *dpi, char c)
{
if (dpi->len == sizeof (dpi->buf) - 1)
d_print_flush (dpi);
 
dpi->buf[dpi->len++] = c;
dpi->last_char = c;
}
 
static inline void
d_append_buffer (struct d_print_info *dpi, const char *s, size_t l)
{
size_t i;
 
for (i = 0; i < l; i++)
d_append_char (dpi, s[i]);
}
 
static inline void
d_append_string (struct d_print_info *dpi, const char *s)
{
d_append_buffer (dpi, s, strlen (s));
}
 
static inline void
d_append_num (struct d_print_info *dpi, int l)
{
char buf[25];
sprintf (buf,"%d", l);
d_append_string (dpi, buf);
}
 
static inline char
d_last_char (struct d_print_info *dpi)
{
return dpi->last_char;
}
 
/* Turn components into a human readable string. OPTIONS is the
options bits passed to the demangler. DC is the tree to print.
CALLBACK is a function to call to flush demangled string segments
as they fill the intermediate buffer, and OPAQUE is a generalized
callback argument. On success, this returns 1. On failure,
it returns 0, indicating a bad parse. It does not use heap
memory to build an output string, so cannot encounter memory
allocation failure. */
 
CP_STATIC_IF_GLIBCPP_V3
int
cplus_demangle_print_callback (int options,
const struct demangle_component *dc,
demangle_callbackref callback, void *opaque)
{
struct d_print_info dpi;
 
d_print_init (&dpi, callback, opaque, dc);
 
{
#ifdef CP_DYNAMIC_ARRAYS
__extension__ struct d_saved_scope scopes[dpi.num_saved_scopes];
__extension__ struct d_print_template temps[dpi.num_copy_templates];
 
dpi.saved_scopes = scopes;
dpi.copy_templates = temps;
#else
dpi.saved_scopes = alloca (dpi.num_saved_scopes
* sizeof (*dpi.saved_scopes));
dpi.copy_templates = alloca (dpi.num_copy_templates
* sizeof (*dpi.copy_templates));
#endif
 
d_print_comp (&dpi, options, dc);
}
 
d_print_flush (&dpi);
 
return ! d_print_saw_error (&dpi);
}
 
/* Turn components into a human readable string. OPTIONS is the
options bits passed to the demangler. DC is the tree to print.
ESTIMATE is a guess at the length of the result. This returns a
string allocated by malloc, or NULL on error. On success, this
sets *PALC to the size of the allocated buffer. On failure, this
sets *PALC to 0 for a bad parse, or to 1 for a memory allocation
failure. */
 
CP_STATIC_IF_GLIBCPP_V3
char *
cplus_demangle_print (int options, const struct demangle_component *dc,
int estimate, size_t *palc)
{
struct d_growable_string dgs;
 
d_growable_string_init (&dgs, estimate);
 
if (! cplus_demangle_print_callback (options, dc,
d_growable_string_callback_adapter,
&dgs))
{
free (dgs.buf);
*palc = 0;
return NULL;
}
 
*palc = dgs.allocation_failure ? 1 : dgs.alc;
return dgs.buf;
}
 
/* Returns the I'th element of the template arglist ARGS, or NULL on
failure. */
 
static struct demangle_component *
d_index_template_argument (struct demangle_component *args, int i)
{
struct demangle_component *a;
 
for (a = args;
a != NULL;
a = d_right (a))
{
if (a->type != DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
return NULL;
if (i <= 0)
break;
--i;
}
if (i != 0 || a == NULL)
return NULL;
 
return d_left (a);
}
 
/* Returns the template argument from the current context indicated by DC,
which is a DEMANGLE_COMPONENT_TEMPLATE_PARAM, or NULL. */
 
static struct demangle_component *
d_lookup_template_argument (struct d_print_info *dpi,
const struct demangle_component *dc)
{
if (dpi->templates == NULL)
{
d_print_error (dpi);
return NULL;
}
return d_index_template_argument
(d_right (dpi->templates->template_decl),
dc->u.s_number.number);
}
 
/* Returns a template argument pack used in DC (any will do), or NULL. */
 
static struct demangle_component *
d_find_pack (struct d_print_info *dpi,
const struct demangle_component *dc)
{
struct demangle_component *a;
if (dc == NULL)
return NULL;
 
switch (dc->type)
{
case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
a = d_lookup_template_argument (dpi, dc);
if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
return a;
return NULL;
 
case DEMANGLE_COMPONENT_PACK_EXPANSION:
return NULL;
case DEMANGLE_COMPONENT_LAMBDA:
case DEMANGLE_COMPONENT_NAME:
case DEMANGLE_COMPONENT_TAGGED_NAME:
case DEMANGLE_COMPONENT_OPERATOR:
case DEMANGLE_COMPONENT_BUILTIN_TYPE:
case DEMANGLE_COMPONENT_SUB_STD:
case DEMANGLE_COMPONENT_CHARACTER:
case DEMANGLE_COMPONENT_FUNCTION_PARAM:
case DEMANGLE_COMPONENT_UNNAMED_TYPE:
case DEMANGLE_COMPONENT_FIXED_TYPE:
case DEMANGLE_COMPONENT_DEFAULT_ARG:
case DEMANGLE_COMPONENT_NUMBER:
return NULL;
 
case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
return d_find_pack (dpi, dc->u.s_extended_operator.name);
case DEMANGLE_COMPONENT_CTOR:
return d_find_pack (dpi, dc->u.s_ctor.name);
case DEMANGLE_COMPONENT_DTOR:
return d_find_pack (dpi, dc->u.s_dtor.name);
 
default:
a = d_find_pack (dpi, d_left (dc));
if (a)
return a;
return d_find_pack (dpi, d_right (dc));
}
}
 
/* Returns the length of the template argument pack DC. */
 
static int
d_pack_length (const struct demangle_component *dc)
{
int count = 0;
while (dc && dc->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST
&& d_left (dc) != NULL)
{
++count;
dc = d_right (dc);
}
return count;
}
 
/* DC is a component of a mangled expression. Print it, wrapped in parens
if needed. */
 
static void
d_print_subexpr (struct d_print_info *dpi, int options,
const struct demangle_component *dc)
{
int simple = 0;
if (dc->type == DEMANGLE_COMPONENT_NAME
|| dc->type == DEMANGLE_COMPONENT_QUAL_NAME
|| dc->type == DEMANGLE_COMPONENT_INITIALIZER_LIST
|| dc->type == DEMANGLE_COMPONENT_FUNCTION_PARAM)
simple = 1;
if (!simple)
d_append_char (dpi, '(');
d_print_comp (dpi, options, dc);
if (!simple)
d_append_char (dpi, ')');
}
 
/* Save the current scope. */
 
static void
d_save_scope (struct d_print_info *dpi,
const struct demangle_component *container)
{
struct d_saved_scope *scope;
struct d_print_template *src, **link;
 
if (dpi->next_saved_scope >= dpi->num_saved_scopes)
{
d_print_error (dpi);
return;
}
scope = &dpi->saved_scopes[dpi->next_saved_scope];
dpi->next_saved_scope++;
 
scope->container = container;
link = &scope->templates;
 
for (src = dpi->templates; src != NULL; src = src->next)
{
struct d_print_template *dst;
 
if (dpi->next_copy_template >= dpi->num_copy_templates)
{
d_print_error (dpi);
return;
}
dst = &dpi->copy_templates[dpi->next_copy_template];
dpi->next_copy_template++;
 
dst->template_decl = src->template_decl;
*link = dst;
link = &dst->next;
}
 
*link = NULL;
}
 
/* Attempt to locate a previously saved scope. Returns NULL if no
corresponding saved scope was found. */
 
static struct d_saved_scope *
d_get_saved_scope (struct d_print_info *dpi,
const struct demangle_component *container)
{
int i;
 
for (i = 0; i < dpi->next_saved_scope; i++)
if (dpi->saved_scopes[i].container == container)
return &dpi->saved_scopes[i];
 
return NULL;
}
 
/* Subroutine to handle components. */
 
static void
d_print_comp_inner (struct d_print_info *dpi, int options,
const struct demangle_component *dc)
{
/* Magic variable to let reference smashing skip over the next modifier
without needing to modify *dc. */
const struct demangle_component *mod_inner = NULL;
 
/* Variable used to store the current templates while a previously
captured scope is used. */
struct d_print_template *saved_templates;
 
/* Nonzero if templates have been stored in the above variable. */
int need_template_restore = 0;
 
if (dc == NULL)
{
d_print_error (dpi);
return;
}
if (d_print_saw_error (dpi))
return;
 
switch (dc->type)
{
case DEMANGLE_COMPONENT_NAME:
if ((options & DMGL_JAVA) == 0)
d_append_buffer (dpi, dc->u.s_name.s, dc->u.s_name.len);
else
d_print_java_identifier (dpi, dc->u.s_name.s, dc->u.s_name.len);
return;
 
case DEMANGLE_COMPONENT_TAGGED_NAME:
d_print_comp (dpi, options, d_left (dc));
d_append_string (dpi, "[abi:");
d_print_comp (dpi, options, d_right (dc));
d_append_char (dpi, ']');
return;
 
case DEMANGLE_COMPONENT_QUAL_NAME:
case DEMANGLE_COMPONENT_LOCAL_NAME:
d_print_comp (dpi, options, d_left (dc));
if ((options & DMGL_JAVA) == 0)
d_append_string (dpi, "::");
else
d_append_char (dpi, '.');
{
struct demangle_component *local_name = d_right (dc);
if (local_name->type == DEMANGLE_COMPONENT_DEFAULT_ARG)
{
d_append_string (dpi, "{default arg#");
d_append_num (dpi, local_name->u.s_unary_num.num + 1);
d_append_string (dpi, "}::");
local_name = local_name->u.s_unary_num.sub;
}
d_print_comp (dpi, options, local_name);
}
return;
 
case DEMANGLE_COMPONENT_TYPED_NAME:
{
struct d_print_mod *hold_modifiers;
struct demangle_component *typed_name;
struct d_print_mod adpm[4];
unsigned int i;
struct d_print_template dpt;
 
/* Pass the name down to the type so that it can be printed in
the right place for the type. We also have to pass down
any CV-qualifiers, which apply to the this parameter. */
hold_modifiers = dpi->modifiers;
dpi->modifiers = 0;
i = 0;
typed_name = d_left (dc);
while (typed_name != NULL)
{
if (i >= sizeof adpm / sizeof adpm[0])
{
d_print_error (dpi);
return;
}
 
adpm[i].next = dpi->modifiers;
dpi->modifiers = &adpm[i];
adpm[i].mod = typed_name;
adpm[i].printed = 0;
adpm[i].templates = dpi->templates;
++i;
 
if (typed_name->type != DEMANGLE_COMPONENT_RESTRICT_THIS
&& typed_name->type != DEMANGLE_COMPONENT_VOLATILE_THIS
&& typed_name->type != DEMANGLE_COMPONENT_CONST_THIS
&& typed_name->type != DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS
&& typed_name->type != DEMANGLE_COMPONENT_REFERENCE_THIS)
break;
 
typed_name = d_left (typed_name);
}
 
if (typed_name == NULL)
{
d_print_error (dpi);
return;
}
 
/* If typed_name is a template, then it applies to the
function type as well. */
if (typed_name->type == DEMANGLE_COMPONENT_TEMPLATE)
{
dpt.next = dpi->templates;
dpi->templates = &dpt;
dpt.template_decl = typed_name;
}
 
/* If typed_name is a DEMANGLE_COMPONENT_LOCAL_NAME, then
there may be CV-qualifiers on its right argument which
really apply here; this happens when parsing a class which
is local to a function. */
if (typed_name->type == DEMANGLE_COMPONENT_LOCAL_NAME)
{
struct demangle_component *local_name;
 
local_name = d_right (typed_name);
if (local_name->type == DEMANGLE_COMPONENT_DEFAULT_ARG)
local_name = local_name->u.s_unary_num.sub;
if (local_name == NULL)
{
d_print_error (dpi);
return;
}
while (local_name->type == DEMANGLE_COMPONENT_RESTRICT_THIS
|| local_name->type == DEMANGLE_COMPONENT_VOLATILE_THIS
|| local_name->type == DEMANGLE_COMPONENT_CONST_THIS
|| local_name->type == DEMANGLE_COMPONENT_REFERENCE_THIS
|| (local_name->type
== DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS))
{
if (i >= sizeof adpm / sizeof adpm[0])
{
d_print_error (dpi);
return;
}
 
adpm[i] = adpm[i - 1];
adpm[i].next = &adpm[i - 1];
dpi->modifiers = &adpm[i];
 
adpm[i - 1].mod = local_name;
adpm[i - 1].printed = 0;
adpm[i - 1].templates = dpi->templates;
++i;
 
local_name = d_left (local_name);
}
}
 
d_print_comp (dpi, options, d_right (dc));
 
if (typed_name->type == DEMANGLE_COMPONENT_TEMPLATE)
dpi->templates = dpt.next;
 
/* If the modifiers didn't get printed by the type, print them
now. */
while (i > 0)
{
--i;
if (! adpm[i].printed)
{
d_append_char (dpi, ' ');
d_print_mod (dpi, options, adpm[i].mod);
}
}
 
dpi->modifiers = hold_modifiers;
 
return;
}
 
case DEMANGLE_COMPONENT_TEMPLATE:
{
struct d_print_mod *hold_dpm;
struct demangle_component *dcl;
const struct demangle_component *hold_current;
 
/* This template may need to be referenced by a cast operator
contained in its subtree. */
hold_current = dpi->current_template;
dpi->current_template = dc;
 
/* Don't push modifiers into a template definition. Doing so
could give the wrong definition for a template argument.
Instead, treat the template essentially as a name. */
 
hold_dpm = dpi->modifiers;
dpi->modifiers = NULL;
 
dcl = d_left (dc);
 
if ((options & DMGL_JAVA) != 0
&& dcl->type == DEMANGLE_COMPONENT_NAME
&& dcl->u.s_name.len == 6
&& strncmp (dcl->u.s_name.s, "JArray", 6) == 0)
{
/* Special-case Java arrays, so that JArray<TYPE> appears
instead as TYPE[]. */
 
d_print_comp (dpi, options, d_right (dc));
d_append_string (dpi, "[]");
}
else
{
d_print_comp (dpi, options, dcl);
if (d_last_char (dpi) == '<')
d_append_char (dpi, ' ');
d_append_char (dpi, '<');
d_print_comp (dpi, options, d_right (dc));
/* Avoid generating two consecutive '>' characters, to avoid
the C++ syntactic ambiguity. */
if (d_last_char (dpi) == '>')
d_append_char (dpi, ' ');
d_append_char (dpi, '>');
}
 
dpi->modifiers = hold_dpm;
dpi->current_template = hold_current;
 
return;
}
 
case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
{
struct d_print_template *hold_dpt;
struct demangle_component *a = d_lookup_template_argument (dpi, dc);
 
if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
a = d_index_template_argument (a, dpi->pack_index);
 
if (a == NULL)
{
d_print_error (dpi);
return;
}
 
/* While processing this parameter, we need to pop the list of
templates. This is because the template parameter may
itself be a reference to a parameter of an outer
template. */
 
hold_dpt = dpi->templates;
dpi->templates = hold_dpt->next;
 
d_print_comp (dpi, options, a);
 
dpi->templates = hold_dpt;
 
return;
}
 
case DEMANGLE_COMPONENT_CTOR:
d_print_comp (dpi, options, dc->u.s_ctor.name);
return;
 
case DEMANGLE_COMPONENT_DTOR:
d_append_char (dpi, '~');
d_print_comp (dpi, options, dc->u.s_dtor.name);
return;
 
case DEMANGLE_COMPONENT_VTABLE:
d_append_string (dpi, "vtable for ");
d_print_comp (dpi, options, d_left (dc));
return;
 
case DEMANGLE_COMPONENT_VTT:
d_append_string (dpi, "VTT for ");
d_print_comp (dpi, options, d_left (dc));
return;
 
case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
d_append_string (dpi, "construction vtable for ");
d_print_comp (dpi, options, d_left (dc));
d_append_string (dpi, "-in-");
d_print_comp (dpi, options, d_right (dc));
return;
 
case DEMANGLE_COMPONENT_TYPEINFO:
d_append_string (dpi, "typeinfo for ");
d_print_comp (dpi, options, d_left (dc));
return;
 
case DEMANGLE_COMPONENT_TYPEINFO_NAME:
d_append_string (dpi, "typeinfo name for ");
d_print_comp (dpi, options, d_left (dc));
return;
 
case DEMANGLE_COMPONENT_TYPEINFO_FN:
d_append_string (dpi, "typeinfo fn for ");
d_print_comp (dpi, options, d_left (dc));
return;
 
case DEMANGLE_COMPONENT_THUNK:
d_append_string (dpi, "non-virtual thunk to ");
d_print_comp (dpi, options, d_left (dc));
return;
 
case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
d_append_string (dpi, "virtual thunk to ");
d_print_comp (dpi, options, d_left (dc));
return;
 
case DEMANGLE_COMPONENT_COVARIANT_THUNK:
d_append_string (dpi, "covariant return thunk to ");
d_print_comp (dpi, options, d_left (dc));
return;
 
case DEMANGLE_COMPONENT_JAVA_CLASS:
d_append_string (dpi, "java Class for ");
d_print_comp (dpi, options, d_left (dc));
return;
 
case DEMANGLE_COMPONENT_GUARD:
d_append_string (dpi, "guard variable for ");
d_print_comp (dpi, options, d_left (dc));
return;
 
case DEMANGLE_COMPONENT_TLS_INIT:
d_append_string (dpi, "TLS init function for ");
d_print_comp (dpi, options, d_left (dc));
return;
 
case DEMANGLE_COMPONENT_TLS_WRAPPER:
d_append_string (dpi, "TLS wrapper function for ");
d_print_comp (dpi, options, d_left (dc));
return;
 
case DEMANGLE_COMPONENT_REFTEMP:
d_append_string (dpi, "reference temporary #");
d_print_comp (dpi, options, d_right (dc));
d_append_string (dpi, " for ");
d_print_comp (dpi, options, d_left (dc));
return;
 
case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
d_append_string (dpi, "hidden alias for ");
d_print_comp (dpi, options, d_left (dc));
return;
 
case DEMANGLE_COMPONENT_TRANSACTION_CLONE:
d_append_string (dpi, "transaction clone for ");
d_print_comp (dpi, options, d_left (dc));
return;
 
case DEMANGLE_COMPONENT_NONTRANSACTION_CLONE:
d_append_string (dpi, "non-transaction clone for ");
d_print_comp (dpi, options, d_left (dc));
return;
 
case DEMANGLE_COMPONENT_SUB_STD:
d_append_buffer (dpi, dc->u.s_string.string, dc->u.s_string.len);
return;
 
case DEMANGLE_COMPONENT_RESTRICT:
case DEMANGLE_COMPONENT_VOLATILE:
case DEMANGLE_COMPONENT_CONST:
{
struct d_print_mod *pdpm;
 
/* When printing arrays, it's possible to have cases where the
same CV-qualifier gets pushed on the stack multiple times.
We only need to print it once. */
 
for (pdpm = dpi->modifiers; pdpm != NULL; pdpm = pdpm->next)
{
if (! pdpm->printed)
{
if (pdpm->mod->type != DEMANGLE_COMPONENT_RESTRICT
&& pdpm->mod->type != DEMANGLE_COMPONENT_VOLATILE
&& pdpm->mod->type != DEMANGLE_COMPONENT_CONST)
break;
if (pdpm->mod->type == dc->type)
{
d_print_comp (dpi, options, d_left (dc));
return;
}
}
}
}
goto modifier;
 
case DEMANGLE_COMPONENT_REFERENCE:
case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
{
/* Handle reference smashing: & + && = &. */
const struct demangle_component *sub = d_left (dc);
if (sub->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM)
{
struct d_saved_scope *scope = d_get_saved_scope (dpi, sub);
struct demangle_component *a;
 
if (scope == NULL)
{
/* This is the first time SUB has been traversed.
We need to capture the current templates so
they can be restored if SUB is reentered as a
substitution. */
d_save_scope (dpi, sub);
if (d_print_saw_error (dpi))
return;
}
else
{
const struct d_component_stack *dcse;
int found_self_or_parent = 0;
 
/* This traversal is reentering SUB as a substition.
If we are not beneath SUB or DC in the tree then we
need to restore SUB's template stack temporarily. */
for (dcse = dpi->component_stack; dcse != NULL;
dcse = dcse->parent)
{
if (dcse->dc == sub
|| (dcse->dc == dc
&& dcse != dpi->component_stack))
{
found_self_or_parent = 1;
break;
}
}
 
if (!found_self_or_parent)
{
saved_templates = dpi->templates;
dpi->templates = scope->templates;
need_template_restore = 1;
}
}
 
a = d_lookup_template_argument (dpi, sub);
if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
a = d_index_template_argument (a, dpi->pack_index);
 
if (a == NULL)
{
if (need_template_restore)
dpi->templates = saved_templates;
 
d_print_error (dpi);
return;
}
 
sub = a;
}
 
if (sub->type == DEMANGLE_COMPONENT_REFERENCE
|| sub->type == dc->type)
dc = sub;
else if (sub->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE)
mod_inner = d_left (sub);
}
/* Fall through. */
 
case DEMANGLE_COMPONENT_RESTRICT_THIS:
case DEMANGLE_COMPONENT_VOLATILE_THIS:
case DEMANGLE_COMPONENT_CONST_THIS:
case DEMANGLE_COMPONENT_REFERENCE_THIS:
case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
case DEMANGLE_COMPONENT_POINTER:
case DEMANGLE_COMPONENT_COMPLEX:
case DEMANGLE_COMPONENT_IMAGINARY:
modifier:
{
/* We keep a list of modifiers on the stack. */
struct d_print_mod dpm;
 
dpm.next = dpi->modifiers;
dpi->modifiers = &dpm;
dpm.mod = dc;
dpm.printed = 0;
dpm.templates = dpi->templates;
 
if (!mod_inner)
mod_inner = d_left (dc);
 
d_print_comp (dpi, options, mod_inner);
 
/* If the modifier didn't get printed by the type, print it
now. */
if (! dpm.printed)
d_print_mod (dpi, options, dc);
 
dpi->modifiers = dpm.next;
 
if (need_template_restore)
dpi->templates = saved_templates;
 
return;
}
 
case DEMANGLE_COMPONENT_BUILTIN_TYPE:
if ((options & DMGL_JAVA) == 0)
d_append_buffer (dpi, dc->u.s_builtin.type->name,
dc->u.s_builtin.type->len);
else
d_append_buffer (dpi, dc->u.s_builtin.type->java_name,
dc->u.s_builtin.type->java_len);
return;
 
case DEMANGLE_COMPONENT_VENDOR_TYPE:
d_print_comp (dpi, options, d_left (dc));
return;
 
case DEMANGLE_COMPONENT_FUNCTION_TYPE:
{
if ((options & DMGL_RET_POSTFIX) != 0)
d_print_function_type (dpi,
options & ~(DMGL_RET_POSTFIX | DMGL_RET_DROP),
dc, dpi->modifiers);
 
/* Print return type if present */
if (d_left (dc) != NULL && (options & DMGL_RET_POSTFIX) != 0)
d_print_comp (dpi, options & ~(DMGL_RET_POSTFIX | DMGL_RET_DROP),
d_left (dc));
else if (d_left (dc) != NULL && (options & DMGL_RET_DROP) == 0)
{
struct d_print_mod dpm;
 
/* We must pass this type down as a modifier in order to
print it in the right location. */
dpm.next = dpi->modifiers;
dpi->modifiers = &dpm;
dpm.mod = dc;
dpm.printed = 0;
dpm.templates = dpi->templates;
 
d_print_comp (dpi, options & ~(DMGL_RET_POSTFIX | DMGL_RET_DROP),
d_left (dc));
 
dpi->modifiers = dpm.next;
 
if (dpm.printed)
return;
 
/* In standard prefix notation, there is a space between the
return type and the function signature. */
if ((options & DMGL_RET_POSTFIX) == 0)
d_append_char (dpi, ' ');
}
 
if ((options & DMGL_RET_POSTFIX) == 0)
d_print_function_type (dpi,
options & ~(DMGL_RET_POSTFIX | DMGL_RET_DROP),
dc, dpi->modifiers);
 
return;
}
 
case DEMANGLE_COMPONENT_ARRAY_TYPE:
{
struct d_print_mod *hold_modifiers;
struct d_print_mod adpm[4];
unsigned int i;
struct d_print_mod *pdpm;
 
/* We must pass this type down as a modifier in order to print
multi-dimensional arrays correctly. If the array itself is
CV-qualified, we act as though the element type were
CV-qualified. We do this by copying the modifiers down
rather than fiddling pointers, so that we don't wind up
with a d_print_mod higher on the stack pointing into our
stack frame after we return. */
 
hold_modifiers = dpi->modifiers;
 
adpm[0].next = hold_modifiers;
dpi->modifiers = &adpm[0];
adpm[0].mod = dc;
adpm[0].printed = 0;
adpm[0].templates = dpi->templates;
 
i = 1;
pdpm = hold_modifiers;
while (pdpm != NULL
&& (pdpm->mod->type == DEMANGLE_COMPONENT_RESTRICT
|| pdpm->mod->type == DEMANGLE_COMPONENT_VOLATILE
|| pdpm->mod->type == DEMANGLE_COMPONENT_CONST))
{
if (! pdpm->printed)
{
if (i >= sizeof adpm / sizeof adpm[0])
{
d_print_error (dpi);
return;
}
 
adpm[i] = *pdpm;
adpm[i].next = dpi->modifiers;
dpi->modifiers = &adpm[i];
pdpm->printed = 1;
++i;
}
 
pdpm = pdpm->next;
}
 
d_print_comp (dpi, options, d_right (dc));
 
dpi->modifiers = hold_modifiers;
 
if (adpm[0].printed)
return;
 
while (i > 1)
{
--i;
d_print_mod (dpi, options, adpm[i].mod);
}
 
d_print_array_type (dpi, options, dc, dpi->modifiers);
 
return;
}
 
case DEMANGLE_COMPONENT_PTRMEM_TYPE:
case DEMANGLE_COMPONENT_VECTOR_TYPE:
{
struct d_print_mod dpm;
 
dpm.next = dpi->modifiers;
dpi->modifiers = &dpm;
dpm.mod = dc;
dpm.printed = 0;
dpm.templates = dpi->templates;
 
d_print_comp (dpi, options, d_right (dc));
 
/* If the modifier didn't get printed by the type, print it
now. */
if (! dpm.printed)
d_print_mod (dpi, options, dc);
 
dpi->modifiers = dpm.next;
 
return;
}
 
case DEMANGLE_COMPONENT_FIXED_TYPE:
if (dc->u.s_fixed.sat)
d_append_string (dpi, "_Sat ");
/* Don't print "int _Accum". */
if (dc->u.s_fixed.length->u.s_builtin.type
!= &cplus_demangle_builtin_types['i'-'a'])
{
d_print_comp (dpi, options, dc->u.s_fixed.length);
d_append_char (dpi, ' ');
}
if (dc->u.s_fixed.accum)
d_append_string (dpi, "_Accum");
else
d_append_string (dpi, "_Fract");
return;
 
case DEMANGLE_COMPONENT_ARGLIST:
case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
if (d_left (dc) != NULL)
d_print_comp (dpi, options, d_left (dc));
if (d_right (dc) != NULL)
{
size_t len;
unsigned long int flush_count;
/* Make sure ", " isn't flushed by d_append_string, otherwise
dpi->len -= 2 wouldn't work. */
if (dpi->len >= sizeof (dpi->buf) - 2)
d_print_flush (dpi);
d_append_string (dpi, ", ");
len = dpi->len;
flush_count = dpi->flush_count;
d_print_comp (dpi, options, d_right (dc));
/* If that didn't print anything (which can happen with empty
template argument packs), remove the comma and space. */
if (dpi->flush_count == flush_count && dpi->len == len)
dpi->len -= 2;
}
return;
 
case DEMANGLE_COMPONENT_INITIALIZER_LIST:
{
struct demangle_component *type = d_left (dc);
struct demangle_component *list = d_right (dc);
 
if (type)
d_print_comp (dpi, options, type);
d_append_char (dpi, '{');
d_print_comp (dpi, options, list);
d_append_char (dpi, '}');
}
return;
 
case DEMANGLE_COMPONENT_OPERATOR:
{
const struct demangle_operator_info *op = dc->u.s_operator.op;
int len = op->len;
 
d_append_string (dpi, "operator");
/* Add a space before new/delete. */
if (IS_LOWER (op->name[0]))
d_append_char (dpi, ' ');
/* Omit a trailing space. */
if (op->name[len-1] == ' ')
--len;
d_append_buffer (dpi, op->name, len);
return;
}
 
case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
d_append_string (dpi, "operator ");
d_print_comp (dpi, options, dc->u.s_extended_operator.name);
return;
 
case DEMANGLE_COMPONENT_CONVERSION:
d_append_string (dpi, "operator ");
d_print_conversion (dpi, options, dc);
return;
 
case DEMANGLE_COMPONENT_NULLARY:
d_print_expr_op (dpi, options, d_left (dc));
return;
 
case DEMANGLE_COMPONENT_UNARY:
{
struct demangle_component *op = d_left (dc);
struct demangle_component *operand = d_right (dc);
const char *code = NULL;
 
if (op->type == DEMANGLE_COMPONENT_OPERATOR)
{
code = op->u.s_operator.op->code;
if (!strcmp (code, "ad"))
{
/* Don't print the argument list for the address of a
function. */
if (operand->type == DEMANGLE_COMPONENT_TYPED_NAME
&& d_left (operand)->type == DEMANGLE_COMPONENT_QUAL_NAME
&& d_right (operand)->type == DEMANGLE_COMPONENT_FUNCTION_TYPE)
operand = d_left (operand);
}
if (operand->type == DEMANGLE_COMPONENT_BINARY_ARGS)
{
/* This indicates a suffix operator. */
operand = d_left (operand);
d_print_subexpr (dpi, options, operand);
d_print_expr_op (dpi, options, op);
return;
}
}
 
if (op->type != DEMANGLE_COMPONENT_CAST)
d_print_expr_op (dpi, options, op);
else
{
d_append_char (dpi, '(');
d_print_cast (dpi, options, op);
d_append_char (dpi, ')');
}
if (code && !strcmp (code, "gs"))
/* Avoid parens after '::'. */
d_print_comp (dpi, options, operand);
else if (code && !strcmp (code, "st"))
/* Always print parens for sizeof (type). */
{
d_append_char (dpi, '(');
d_print_comp (dpi, options, operand);
d_append_char (dpi, ')');
}
else
d_print_subexpr (dpi, options, operand);
}
return;
 
case DEMANGLE_COMPONENT_BINARY:
if (d_right (dc)->type != DEMANGLE_COMPONENT_BINARY_ARGS)
{
d_print_error (dpi);
return;
}
 
if (op_is_new_cast (d_left (dc)))
{
d_print_expr_op (dpi, options, d_left (dc));
d_append_char (dpi, '<');
d_print_comp (dpi, options, d_left (d_right (dc)));
d_append_string (dpi, ">(");
d_print_comp (dpi, options, d_right (d_right (dc)));
d_append_char (dpi, ')');
return;
}
 
/* We wrap an expression which uses the greater-than operator in
an extra layer of parens so that it does not get confused
with the '>' which ends the template parameters. */
if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
&& d_left (dc)->u.s_operator.op->len == 1
&& d_left (dc)->u.s_operator.op->name[0] == '>')
d_append_char (dpi, '(');
 
if (strcmp (d_left (dc)->u.s_operator.op->code, "cl") == 0
&& d_left (d_right (dc))->type == DEMANGLE_COMPONENT_TYPED_NAME)
{
/* Function call used in an expression should not have printed types
of the function arguments. Values of the function arguments still
get printed below. */
 
const struct demangle_component *func = d_left (d_right (dc));
 
if (d_right (func)->type != DEMANGLE_COMPONENT_FUNCTION_TYPE)
d_print_error (dpi);
d_print_subexpr (dpi, options, d_left (func));
}
else
d_print_subexpr (dpi, options, d_left (d_right (dc)));
if (strcmp (d_left (dc)->u.s_operator.op->code, "ix") == 0)
{
d_append_char (dpi, '[');
d_print_comp (dpi, options, d_right (d_right (dc)));
d_append_char (dpi, ']');
}
else
{
if (strcmp (d_left (dc)->u.s_operator.op->code, "cl") != 0)
d_print_expr_op (dpi, options, d_left (dc));
d_print_subexpr (dpi, options, d_right (d_right (dc)));
}
 
if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
&& d_left (dc)->u.s_operator.op->len == 1
&& d_left (dc)->u.s_operator.op->name[0] == '>')
d_append_char (dpi, ')');
 
return;
 
case DEMANGLE_COMPONENT_BINARY_ARGS:
/* We should only see this as part of DEMANGLE_COMPONENT_BINARY. */
d_print_error (dpi);
return;
 
case DEMANGLE_COMPONENT_TRINARY:
if (d_right (dc)->type != DEMANGLE_COMPONENT_TRINARY_ARG1
|| d_right (d_right (dc))->type != DEMANGLE_COMPONENT_TRINARY_ARG2)
{
d_print_error (dpi);
return;
}
{
struct demangle_component *op = d_left (dc);
struct demangle_component *first = d_left (d_right (dc));
struct demangle_component *second = d_left (d_right (d_right (dc)));
struct demangle_component *third = d_right (d_right (d_right (dc)));
 
if (!strcmp (op->u.s_operator.op->code, "qu"))
{
d_print_subexpr (dpi, options, first);
d_print_expr_op (dpi, options, op);
d_print_subexpr (dpi, options, second);
d_append_string (dpi, " : ");
d_print_subexpr (dpi, options, third);
}
else
{
d_append_string (dpi, "new ");
if (d_left (first) != NULL)
{
d_print_subexpr (dpi, options, first);
d_append_char (dpi, ' ');
}
d_print_comp (dpi, options, second);
if (third)
d_print_subexpr (dpi, options, third);
}
}
return;
 
case DEMANGLE_COMPONENT_TRINARY_ARG1:
case DEMANGLE_COMPONENT_TRINARY_ARG2:
/* We should only see these are part of DEMANGLE_COMPONENT_TRINARY. */
d_print_error (dpi);
return;
 
case DEMANGLE_COMPONENT_LITERAL:
case DEMANGLE_COMPONENT_LITERAL_NEG:
{
enum d_builtin_type_print tp;
 
/* For some builtin types, produce simpler output. */
tp = D_PRINT_DEFAULT;
if (d_left (dc)->type == DEMANGLE_COMPONENT_BUILTIN_TYPE)
{
tp = d_left (dc)->u.s_builtin.type->print;
switch (tp)
{
case D_PRINT_INT:
case D_PRINT_UNSIGNED:
case D_PRINT_LONG:
case D_PRINT_UNSIGNED_LONG:
case D_PRINT_LONG_LONG:
case D_PRINT_UNSIGNED_LONG_LONG:
if (d_right (dc)->type == DEMANGLE_COMPONENT_NAME)
{
if (dc->type == DEMANGLE_COMPONENT_LITERAL_NEG)
d_append_char (dpi, '-');
d_print_comp (dpi, options, d_right (dc));
switch (tp)
{
default:
break;
case D_PRINT_UNSIGNED:
d_append_char (dpi, 'u');
break;
case D_PRINT_LONG:
d_append_char (dpi, 'l');
break;
case D_PRINT_UNSIGNED_LONG:
d_append_string (dpi, "ul");
break;
case D_PRINT_LONG_LONG:
d_append_string (dpi, "ll");
break;
case D_PRINT_UNSIGNED_LONG_LONG:
d_append_string (dpi, "ull");
break;
}
return;
}
break;
 
case D_PRINT_BOOL:
if (d_right (dc)->type == DEMANGLE_COMPONENT_NAME
&& d_right (dc)->u.s_name.len == 1
&& dc->type == DEMANGLE_COMPONENT_LITERAL)
{
switch (d_right (dc)->u.s_name.s[0])
{
case '0':
d_append_string (dpi, "false");
return;
case '1':
d_append_string (dpi, "true");
return;
default:
break;
}
}
break;
 
default:
break;
}
}
 
d_append_char (dpi, '(');
d_print_comp (dpi, options, d_left (dc));
d_append_char (dpi, ')');
if (dc->type == DEMANGLE_COMPONENT_LITERAL_NEG)
d_append_char (dpi, '-');
if (tp == D_PRINT_FLOAT)
d_append_char (dpi, '[');
d_print_comp (dpi, options, d_right (dc));
if (tp == D_PRINT_FLOAT)
d_append_char (dpi, ']');
}
return;
 
case DEMANGLE_COMPONENT_NUMBER:
d_append_num (dpi, dc->u.s_number.number);
return;
 
case DEMANGLE_COMPONENT_JAVA_RESOURCE:
d_append_string (dpi, "java resource ");
d_print_comp (dpi, options, d_left (dc));
return;
 
case DEMANGLE_COMPONENT_COMPOUND_NAME:
d_print_comp (dpi, options, d_left (dc));
d_print_comp (dpi, options, d_right (dc));
return;
 
case DEMANGLE_COMPONENT_CHARACTER:
d_append_char (dpi, dc->u.s_character.character);
return;
 
case DEMANGLE_COMPONENT_DECLTYPE:
d_append_string (dpi, "decltype (");
d_print_comp (dpi, options, d_left (dc));
d_append_char (dpi, ')');
return;
 
case DEMANGLE_COMPONENT_PACK_EXPANSION:
{
int len;
int i;
struct demangle_component *a = d_find_pack (dpi, d_left (dc));
if (a == NULL)
{
/* d_find_pack won't find anything if the only packs involved
in this expansion are function parameter packs; in that
case, just print the pattern and "...". */
d_print_subexpr (dpi, options, d_left (dc));
d_append_string (dpi, "...");
return;
}
 
len = d_pack_length (a);
dc = d_left (dc);
for (i = 0; i < len; ++i)
{
dpi->pack_index = i;
d_print_comp (dpi, options, dc);
if (i < len-1)
d_append_string (dpi, ", ");
}
}
return;
 
case DEMANGLE_COMPONENT_FUNCTION_PARAM:
{
long num = dc->u.s_number.number;
if (num == 0)
d_append_string (dpi, "this");
else
{
d_append_string (dpi, "{parm#");
d_append_num (dpi, num);
d_append_char (dpi, '}');
}
}
return;
 
case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS:
d_append_string (dpi, "global constructors keyed to ");
d_print_comp (dpi, options, dc->u.s_binary.left);
return;
 
case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS:
d_append_string (dpi, "global destructors keyed to ");
d_print_comp (dpi, options, dc->u.s_binary.left);
return;
 
case DEMANGLE_COMPONENT_LAMBDA:
d_append_string (dpi, "{lambda(");
d_print_comp (dpi, options, dc->u.s_unary_num.sub);
d_append_string (dpi, ")#");
d_append_num (dpi, dc->u.s_unary_num.num + 1);
d_append_char (dpi, '}');
return;
 
case DEMANGLE_COMPONENT_UNNAMED_TYPE:
d_append_string (dpi, "{unnamed type#");
d_append_num (dpi, dc->u.s_number.number + 1);
d_append_char (dpi, '}');
return;
 
case DEMANGLE_COMPONENT_CLONE:
d_print_comp (dpi, options, d_left (dc));
d_append_string (dpi, " [clone ");
d_print_comp (dpi, options, d_right (dc));
d_append_char (dpi, ']');
return;
 
default:
d_print_error (dpi);
return;
}
}
 
static void
d_print_comp (struct d_print_info *dpi, int options,
const struct demangle_component *dc)
{
struct d_component_stack self;
 
self.dc = dc;
self.parent = dpi->component_stack;
dpi->component_stack = &self;
 
d_print_comp_inner (dpi, options, dc);
 
dpi->component_stack = self.parent;
}
 
/* Print a Java dentifier. For Java we try to handle encoded extended
Unicode characters. The C++ ABI doesn't mention Unicode encoding,
so we don't it for C++. Characters are encoded as
__U<hex-char>+_. */
 
static void
d_print_java_identifier (struct d_print_info *dpi, const char *name, int len)
{
const char *p;
const char *end;
 
end = name + len;
for (p = name; p < end; ++p)
{
if (end - p > 3
&& p[0] == '_'
&& p[1] == '_'
&& p[2] == 'U')
{
unsigned long c;
const char *q;
 
c = 0;
for (q = p + 3; q < end; ++q)
{
int dig;
 
if (IS_DIGIT (*q))
dig = *q - '0';
else if (*q >= 'A' && *q <= 'F')
dig = *q - 'A' + 10;
else if (*q >= 'a' && *q <= 'f')
dig = *q - 'a' + 10;
else
break;
 
c = c * 16 + dig;
}
/* If the Unicode character is larger than 256, we don't try
to deal with it here. FIXME. */
if (q < end && *q == '_' && c < 256)
{
d_append_char (dpi, c);
p = q;
continue;
}
}
 
d_append_char (dpi, *p);
}
}
 
/* Print a list of modifiers. SUFFIX is 1 if we are printing
qualifiers on this after printing a function. */
 
static void
d_print_mod_list (struct d_print_info *dpi, int options,
struct d_print_mod *mods, int suffix)
{
struct d_print_template *hold_dpt;
 
if (mods == NULL || d_print_saw_error (dpi))
return;
 
if (mods->printed
|| (! suffix
&& (mods->mod->type == DEMANGLE_COMPONENT_RESTRICT_THIS
|| mods->mod->type == DEMANGLE_COMPONENT_VOLATILE_THIS
|| mods->mod->type == DEMANGLE_COMPONENT_CONST_THIS
|| mods->mod->type == DEMANGLE_COMPONENT_REFERENCE_THIS
|| (mods->mod->type
== DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS))))
{
d_print_mod_list (dpi, options, mods->next, suffix);
return;
}
 
mods->printed = 1;
 
hold_dpt = dpi->templates;
dpi->templates = mods->templates;
 
if (mods->mod->type == DEMANGLE_COMPONENT_FUNCTION_TYPE)
{
d_print_function_type (dpi, options, mods->mod, mods->next);
dpi->templates = hold_dpt;
return;
}
else if (mods->mod->type == DEMANGLE_COMPONENT_ARRAY_TYPE)
{
d_print_array_type (dpi, options, mods->mod, mods->next);
dpi->templates = hold_dpt;
return;
}
else if (mods->mod->type == DEMANGLE_COMPONENT_LOCAL_NAME)
{
struct d_print_mod *hold_modifiers;
struct demangle_component *dc;
 
/* When this is on the modifier stack, we have pulled any
qualifiers off the right argument already. Otherwise, we
print it as usual, but don't let the left argument see any
modifiers. */
 
hold_modifiers = dpi->modifiers;
dpi->modifiers = NULL;
d_print_comp (dpi, options, d_left (mods->mod));
dpi->modifiers = hold_modifiers;
 
if ((options & DMGL_JAVA) == 0)
d_append_string (dpi, "::");
else
d_append_char (dpi, '.');
 
dc = d_right (mods->mod);
 
if (dc->type == DEMANGLE_COMPONENT_DEFAULT_ARG)
{
d_append_string (dpi, "{default arg#");
d_append_num (dpi, dc->u.s_unary_num.num + 1);
d_append_string (dpi, "}::");
dc = dc->u.s_unary_num.sub;
}
 
while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS
|| dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS
|| dc->type == DEMANGLE_COMPONENT_CONST_THIS
|| dc->type == DEMANGLE_COMPONENT_REFERENCE_THIS
|| dc->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS)
dc = d_left (dc);
 
d_print_comp (dpi, options, dc);
 
dpi->templates = hold_dpt;
return;
}
 
d_print_mod (dpi, options, mods->mod);
 
dpi->templates = hold_dpt;
 
d_print_mod_list (dpi, options, mods->next, suffix);
}
 
/* Print a modifier. */
 
static void
d_print_mod (struct d_print_info *dpi, int options,
const struct demangle_component *mod)
{
switch (mod->type)
{
case DEMANGLE_COMPONENT_RESTRICT:
case DEMANGLE_COMPONENT_RESTRICT_THIS:
d_append_string (dpi, " restrict");
return;
case DEMANGLE_COMPONENT_VOLATILE:
case DEMANGLE_COMPONENT_VOLATILE_THIS:
d_append_string (dpi, " volatile");
return;
case DEMANGLE_COMPONENT_CONST:
case DEMANGLE_COMPONENT_CONST_THIS:
d_append_string (dpi, " const");
return;
case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
d_append_char (dpi, ' ');
d_print_comp (dpi, options, d_right (mod));
return;
case DEMANGLE_COMPONENT_POINTER:
/* There is no pointer symbol in Java. */
if ((options & DMGL_JAVA) == 0)
d_append_char (dpi, '*');
return;
case DEMANGLE_COMPONENT_REFERENCE_THIS:
/* For the ref-qualifier, put a space before the &. */
d_append_char (dpi, ' ');
case DEMANGLE_COMPONENT_REFERENCE:
d_append_char (dpi, '&');
return;
case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
d_append_char (dpi, ' ');
case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
d_append_string (dpi, "&&");
return;
case DEMANGLE_COMPONENT_COMPLEX:
d_append_string (dpi, "complex ");
return;
case DEMANGLE_COMPONENT_IMAGINARY:
d_append_string (dpi, "imaginary ");
return;
case DEMANGLE_COMPONENT_PTRMEM_TYPE:
if (d_last_char (dpi) != '(')
d_append_char (dpi, ' ');
d_print_comp (dpi, options, d_left (mod));
d_append_string (dpi, "::*");
return;
case DEMANGLE_COMPONENT_TYPED_NAME:
d_print_comp (dpi, options, d_left (mod));
return;
case DEMANGLE_COMPONENT_VECTOR_TYPE:
d_append_string (dpi, " __vector(");
d_print_comp (dpi, options, d_left (mod));
d_append_char (dpi, ')');
return;
 
default:
/* Otherwise, we have something that won't go back on the
modifier stack, so we can just print it. */
d_print_comp (dpi, options, mod);
return;
}
}
 
/* Print a function type, except for the return type. */
 
static void
d_print_function_type (struct d_print_info *dpi, int options,
const struct demangle_component *dc,
struct d_print_mod *mods)
{
int need_paren;
int need_space;
struct d_print_mod *p;
struct d_print_mod *hold_modifiers;
 
need_paren = 0;
need_space = 0;
for (p = mods; p != NULL; p = p->next)
{
if (p->printed)
break;
 
switch (p->mod->type)
{
case DEMANGLE_COMPONENT_POINTER:
case DEMANGLE_COMPONENT_REFERENCE:
case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
need_paren = 1;
break;
case DEMANGLE_COMPONENT_RESTRICT:
case DEMANGLE_COMPONENT_VOLATILE:
case DEMANGLE_COMPONENT_CONST:
case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
case DEMANGLE_COMPONENT_COMPLEX:
case DEMANGLE_COMPONENT_IMAGINARY:
case DEMANGLE_COMPONENT_PTRMEM_TYPE:
need_space = 1;
need_paren = 1;
break;
case DEMANGLE_COMPONENT_RESTRICT_THIS:
case DEMANGLE_COMPONENT_VOLATILE_THIS:
case DEMANGLE_COMPONENT_CONST_THIS:
case DEMANGLE_COMPONENT_REFERENCE_THIS:
case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
break;
default:
break;
}
if (need_paren)
break;
}
 
if (need_paren)
{
if (! need_space)
{
if (d_last_char (dpi) != '('
&& d_last_char (dpi) != '*')
need_space = 1;
}
if (need_space && d_last_char (dpi) != ' ')
d_append_char (dpi, ' ');
d_append_char (dpi, '(');
}
 
hold_modifiers = dpi->modifiers;
dpi->modifiers = NULL;
 
d_print_mod_list (dpi, options, mods, 0);
 
if (need_paren)
d_append_char (dpi, ')');
 
d_append_char (dpi, '(');
 
if (d_right (dc) != NULL)
d_print_comp (dpi, options, d_right (dc));
 
d_append_char (dpi, ')');
 
d_print_mod_list (dpi, options, mods, 1);
 
dpi->modifiers = hold_modifiers;
}
 
/* Print an array type, except for the element type. */
 
static void
d_print_array_type (struct d_print_info *dpi, int options,
const struct demangle_component *dc,
struct d_print_mod *mods)
{
int need_space;
 
need_space = 1;
if (mods != NULL)
{
int need_paren;
struct d_print_mod *p;
 
need_paren = 0;
for (p = mods; p != NULL; p = p->next)
{
if (! p->printed)
{
if (p->mod->type == DEMANGLE_COMPONENT_ARRAY_TYPE)
{
need_space = 0;
break;
}
else
{
need_paren = 1;
need_space = 1;
break;
}
}
}
 
if (need_paren)
d_append_string (dpi, " (");
 
d_print_mod_list (dpi, options, mods, 0);
 
if (need_paren)
d_append_char (dpi, ')');
}
 
if (need_space)
d_append_char (dpi, ' ');
 
d_append_char (dpi, '[');
 
if (d_left (dc) != NULL)
d_print_comp (dpi, options, d_left (dc));
 
d_append_char (dpi, ']');
}
 
/* Print an operator in an expression. */
 
static void
d_print_expr_op (struct d_print_info *dpi, int options,
const struct demangle_component *dc)
{
if (dc->type == DEMANGLE_COMPONENT_OPERATOR)
d_append_buffer (dpi, dc->u.s_operator.op->name,
dc->u.s_operator.op->len);
else
d_print_comp (dpi, options, dc);
}
 
/* Print a cast. */
 
static void
d_print_cast (struct d_print_info *dpi, int options,
const struct demangle_component *dc)
{
d_print_comp (dpi, options, d_left (dc));
}
 
/* Print a conversion operator. */
 
static void
d_print_conversion (struct d_print_info *dpi, int options,
const struct demangle_component *dc)
{
struct d_print_template dpt;
 
/* For a conversion operator, we need the template parameters from
the enclosing template in scope for processing the type. */
if (dpi->current_template != NULL)
{
dpt.next = dpi->templates;
dpi->templates = &dpt;
dpt.template_decl = dpi->current_template;
}
 
if (d_left (dc)->type != DEMANGLE_COMPONENT_TEMPLATE)
{
d_print_comp (dpi, options, d_left (dc));
if (dpi->current_template != NULL)
dpi->templates = dpt.next;
}
else
{
d_print_comp (dpi, options, d_left (d_left (dc)));
 
/* For a templated cast operator, we need to remove the template
parameters from scope after printing the operator name,
so we need to handle the template printing here. */
if (dpi->current_template != NULL)
dpi->templates = dpt.next;
 
if (d_last_char (dpi) == '<')
d_append_char (dpi, ' ');
d_append_char (dpi, '<');
d_print_comp (dpi, options, d_right (d_left (dc)));
/* Avoid generating two consecutive '>' characters, to avoid
the C++ syntactic ambiguity. */
if (d_last_char (dpi) == '>')
d_append_char (dpi, ' ');
d_append_char (dpi, '>');
}
}
 
/* Initialize the information structure we use to pass around
information. */
 
CP_STATIC_IF_GLIBCPP_V3
void
cplus_demangle_init_info (const char *mangled, int options, size_t len,
struct d_info *di)
{
di->s = mangled;
di->send = mangled + len;
di->options = options;
 
di->n = mangled;
 
/* We can not need more components than twice the number of chars in
the mangled string. Most components correspond directly to
chars, but the ARGLIST types are exceptions. */
di->num_comps = 2 * len;
di->next_comp = 0;
 
/* Similarly, we can not need more substitutions than there are
chars in the mangled string. */
di->num_subs = len;
di->next_sub = 0;
di->did_subs = 0;
 
di->last_name = NULL;
 
di->expansion = 0;
di->is_expression = 0;
di->is_conversion = 0;
}
 
/* Internal implementation for the demangler. If MANGLED is a g++ v3 ABI
mangled name, return strings in repeated callback giving the demangled
name. OPTIONS is the usual libiberty demangler options. On success,
this returns 1. On failure, returns 0. */
 
static int
d_demangle_callback (const char *mangled, int options,
demangle_callbackref callback, void *opaque)
{
enum
{
DCT_TYPE,
DCT_MANGLED,
DCT_GLOBAL_CTORS,
DCT_GLOBAL_DTORS
}
type;
struct d_info di;
struct demangle_component *dc;
int status;
 
if (mangled[0] == '_' && mangled[1] == 'Z')
type = DCT_MANGLED;
else if (strncmp (mangled, "_GLOBAL_", 8) == 0
&& (mangled[8] == '.' || mangled[8] == '_' || mangled[8] == '$')
&& (mangled[9] == 'D' || mangled[9] == 'I')
&& mangled[10] == '_')
type = mangled[9] == 'I' ? DCT_GLOBAL_CTORS : DCT_GLOBAL_DTORS;
else
{
if ((options & DMGL_TYPES) == 0)
return 0;
type = DCT_TYPE;
}
 
cplus_demangle_init_info (mangled, options, strlen (mangled), &di);
 
{
#ifdef CP_DYNAMIC_ARRAYS
__extension__ struct demangle_component comps[di.num_comps];
__extension__ struct demangle_component *subs[di.num_subs];
 
di.comps = comps;
di.subs = subs;
#else
di.comps = alloca (di.num_comps * sizeof (*di.comps));
di.subs = alloca (di.num_subs * sizeof (*di.subs));
#endif
 
switch (type)
{
case DCT_TYPE:
dc = cplus_demangle_type (&di);
break;
case DCT_MANGLED:
dc = cplus_demangle_mangled_name (&di, 1);
break;
case DCT_GLOBAL_CTORS:
case DCT_GLOBAL_DTORS:
d_advance (&di, 11);
dc = d_make_comp (&di,
(type == DCT_GLOBAL_CTORS
? DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS
: DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS),
d_make_demangle_mangled_name (&di, d_str (&di)),
NULL);
d_advance (&di, strlen (d_str (&di)));
break;
default:
abort (); /* We have listed all the cases. */
}
 
/* If DMGL_PARAMS is set, then if we didn't consume the entire
mangled string, then we didn't successfully demangle it. If
DMGL_PARAMS is not set, we didn't look at the trailing
parameters. */
if (((options & DMGL_PARAMS) != 0) && d_peek_char (&di) != '\0')
dc = NULL;
 
#ifdef CP_DEMANGLE_DEBUG
d_dump (dc, 0);
#endif
 
status = (dc != NULL)
? cplus_demangle_print_callback (options, dc, callback, opaque)
: 0;
}
 
return status;
}
 
/* Entry point for the demangler. If MANGLED is a g++ v3 ABI mangled
name, return a buffer allocated with malloc holding the demangled
name. OPTIONS is the usual libiberty demangler options. On
success, this sets *PALC to the allocated size of the returned
buffer. On failure, this sets *PALC to 0 for a bad name, or 1 for
a memory allocation failure, and returns NULL. */
 
static char *
d_demangle (const char *mangled, int options, size_t *palc)
{
struct d_growable_string dgs;
int status;
 
d_growable_string_init (&dgs, 0);
 
status = d_demangle_callback (mangled, options,
d_growable_string_callback_adapter, &dgs);
if (status == 0)
{
free (dgs.buf);
*palc = 0;
return NULL;
}
 
*palc = dgs.allocation_failure ? 1 : dgs.alc;
return dgs.buf;
}
 
#if defined(IN_LIBGCC2) || defined(IN_GLIBCPP_V3)
 
extern char *__cxa_demangle (const char *, char *, size_t *, int *);
 
/* ia64 ABI-mandated entry point in the C++ runtime library for
performing demangling. MANGLED_NAME is a NUL-terminated character
string containing the name to be demangled.
 
OUTPUT_BUFFER is a region of memory, allocated with malloc, of
*LENGTH bytes, into which the demangled name is stored. If
OUTPUT_BUFFER is not long enough, it is expanded using realloc.
OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
is placed in a region of memory allocated with malloc.
 
If LENGTH is non-NULL, the length of the buffer containing the
demangled name, is placed in *LENGTH.
 
The return value is 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 free.
 
*STATUS is set to one of the following values:
0: The demangling operation succeeded.
-1: A memory allocation failure occurred.
-2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
-3: One of the arguments is invalid.
 
The demangling is performed using the C++ ABI mangling rules, with
GNU extensions. */
 
char *
__cxa_demangle (const char *mangled_name, char *output_buffer,
size_t *length, int *status)
{
char *demangled;
size_t alc;
 
if (mangled_name == NULL)
{
if (status != NULL)
*status = -3;
return NULL;
}
 
if (output_buffer != NULL && length == NULL)
{
if (status != NULL)
*status = -3;
return NULL;
}
 
demangled = d_demangle (mangled_name, DMGL_PARAMS | DMGL_TYPES, &alc);
 
if (demangled == NULL)
{
if (status != NULL)
{
if (alc == 1)
*status = -1;
else
*status = -2;
}
return NULL;
}
 
if (output_buffer == NULL)
{
if (length != NULL)
*length = alc;
}
else
{
if (strlen (demangled) < *length)
{
strcpy (output_buffer, demangled);
free (demangled);
demangled = output_buffer;
}
else
{
free (output_buffer);
*length = alc;
}
}
 
if (status != NULL)
*status = 0;
 
return demangled;
}
 
extern int __gcclibcxx_demangle_callback (const char *,
void (*)
(const char *, size_t, void *),
void *);
 
/* Alternative, allocationless entry point in the C++ runtime library
for performing demangling. MANGLED_NAME is a NUL-terminated character
string containing the name to be demangled.
 
CALLBACK is a callback function, called with demangled string
segments as demangling progresses; it is called at least once,
but may be called more than once. OPAQUE is a generalized pointer
used as a callback argument.
 
The return code is one of the following values, equivalent to
the STATUS values of __cxa_demangle() (excluding -1, since this
function performs no memory allocations):
0: The demangling operation succeeded.
-2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
-3: One of the arguments is invalid.
 
The demangling is performed using the C++ ABI mangling rules, with
GNU extensions. */
 
int
__gcclibcxx_demangle_callback (const char *mangled_name,
void (*callback) (const char *, size_t, void *),
void *opaque)
{
int status;
 
if (mangled_name == NULL || callback == NULL)
return -3;
 
status = d_demangle_callback (mangled_name, DMGL_PARAMS | DMGL_TYPES,
callback, opaque);
if (status == 0)
return -2;
 
return 0;
}
 
#else /* ! (IN_LIBGCC2 || IN_GLIBCPP_V3) */
 
/* Entry point for libiberty demangler. If MANGLED is a g++ v3 ABI
mangled name, return a buffer allocated with malloc holding the
demangled name. Otherwise, return NULL. */
 
char *
cplus_demangle_v3 (const char *mangled, int options)
{
size_t alc;
 
return d_demangle (mangled, options, &alc);
}
 
int
cplus_demangle_v3_callback (const char *mangled, int options,
demangle_callbackref callback, void *opaque)
{
return d_demangle_callback (mangled, options, callback, opaque);
}
 
/* Demangle a Java symbol. Java uses a subset of the V3 ABI C++ mangling
conventions, but the output formatting is a little different.
This instructs the C++ demangler not to emit pointer characters ("*"), to
use Java's namespace separator symbol ("." instead of "::"), and to output
JArray<TYPE> as TYPE[]. */
 
char *
java_demangle_v3 (const char *mangled)
{
size_t alc;
 
return d_demangle (mangled, DMGL_JAVA | DMGL_PARAMS | DMGL_RET_POSTFIX, &alc);
}
 
int
java_demangle_v3_callback (const char *mangled,
demangle_callbackref callback, void *opaque)
{
return d_demangle_callback (mangled,
DMGL_JAVA | DMGL_PARAMS | DMGL_RET_POSTFIX,
callback, opaque);
}
 
#endif /* IN_LIBGCC2 || IN_GLIBCPP_V3 */
 
#ifndef IN_GLIBCPP_V3
 
/* Demangle a string in order to find out whether it is a constructor
or destructor. Return non-zero on success. Set *CTOR_KIND and
*DTOR_KIND appropriately. */
 
static int
is_ctor_or_dtor (const char *mangled,
enum gnu_v3_ctor_kinds *ctor_kind,
enum gnu_v3_dtor_kinds *dtor_kind)
{
struct d_info di;
struct demangle_component *dc;
int ret;
 
*ctor_kind = (enum gnu_v3_ctor_kinds) 0;
*dtor_kind = (enum gnu_v3_dtor_kinds) 0;
 
cplus_demangle_init_info (mangled, DMGL_GNU_V3, strlen (mangled), &di);
 
{
#ifdef CP_DYNAMIC_ARRAYS
__extension__ struct demangle_component comps[di.num_comps];
__extension__ struct demangle_component *subs[di.num_subs];
 
di.comps = comps;
di.subs = subs;
#else
di.comps = alloca (di.num_comps * sizeof (*di.comps));
di.subs = alloca (di.num_subs * sizeof (*di.subs));
#endif
 
dc = cplus_demangle_mangled_name (&di, 1);
 
/* Note that because we did not pass DMGL_PARAMS, we don't expect
to demangle the entire string. */
 
ret = 0;
while (dc != NULL)
{
switch (dc->type)
{
/* These cannot appear on a constructor or destructor. */
case DEMANGLE_COMPONENT_RESTRICT_THIS:
case DEMANGLE_COMPONENT_VOLATILE_THIS:
case DEMANGLE_COMPONENT_CONST_THIS:
case DEMANGLE_COMPONENT_REFERENCE_THIS:
case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
default:
dc = NULL;
break;
case DEMANGLE_COMPONENT_TYPED_NAME:
case DEMANGLE_COMPONENT_TEMPLATE:
dc = d_left (dc);
break;
case DEMANGLE_COMPONENT_QUAL_NAME:
case DEMANGLE_COMPONENT_LOCAL_NAME:
dc = d_right (dc);
break;
case DEMANGLE_COMPONENT_CTOR:
*ctor_kind = dc->u.s_ctor.kind;
ret = 1;
dc = NULL;
break;
case DEMANGLE_COMPONENT_DTOR:
*dtor_kind = dc->u.s_dtor.kind;
ret = 1;
dc = NULL;
break;
}
}
}
 
return ret;
}
 
/* Return whether NAME is the mangled form of a g++ V3 ABI constructor
name. A non-zero return indicates the type of constructor. */
 
enum gnu_v3_ctor_kinds
is_gnu_v3_mangled_ctor (const char *name)
{
enum gnu_v3_ctor_kinds ctor_kind;
enum gnu_v3_dtor_kinds dtor_kind;
 
if (! is_ctor_or_dtor (name, &ctor_kind, &dtor_kind))
return (enum gnu_v3_ctor_kinds) 0;
return ctor_kind;
}
 
 
/* Return whether NAME is the mangled form of a g++ V3 ABI destructor
name. A non-zero return indicates the type of destructor. */
 
enum gnu_v3_dtor_kinds
is_gnu_v3_mangled_dtor (const char *name)
{
enum gnu_v3_ctor_kinds ctor_kind;
enum gnu_v3_dtor_kinds dtor_kind;
 
if (! is_ctor_or_dtor (name, &ctor_kind, &dtor_kind))
return (enum gnu_v3_dtor_kinds) 0;
return dtor_kind;
}
 
#endif /* IN_GLIBCPP_V3 */
 
#ifdef STANDALONE_DEMANGLER
 
#include "getopt.h"
#include "dyn-string.h"
 
static void print_usage (FILE* fp, int exit_value);
 
#define IS_ALPHA(CHAR) \
(((CHAR) >= 'a' && (CHAR) <= 'z') \
|| ((CHAR) >= 'A' && (CHAR) <= 'Z'))
 
/* Non-zero if CHAR is a character than can occur in a mangled name. */
#define is_mangled_char(CHAR) \
(IS_ALPHA (CHAR) || IS_DIGIT (CHAR) \
|| (CHAR) == '_' || (CHAR) == '.' || (CHAR) == '$')
 
/* The name of this program, as invoked. */
const char* program_name;
 
/* Prints usage summary to FP and then exits with EXIT_VALUE. */
 
static void
print_usage (FILE* fp, int exit_value)
{
fprintf (fp, "Usage: %s [options] [names ...]\n", program_name);
fprintf (fp, "Options:\n");
fprintf (fp, " -h,--help Display this message.\n");
fprintf (fp, " -p,--no-params Don't display function parameters\n");
fprintf (fp, " -v,--verbose Produce verbose demanglings.\n");
fprintf (fp, "If names are provided, they are demangled. Otherwise filters standard input.\n");
 
exit (exit_value);
}
 
/* Option specification for getopt_long. */
static const struct option long_options[] =
{
{ "help", no_argument, NULL, 'h' },
{ "no-params", no_argument, NULL, 'p' },
{ "verbose", no_argument, NULL, 'v' },
{ NULL, no_argument, NULL, 0 },
};
 
/* Main entry for a demangling filter executable. It will demangle
its command line arguments, if any. If none are provided, it will
filter stdin to stdout, replacing any recognized mangled C++ names
with their demangled equivalents. */
 
int
main (int argc, char *argv[])
{
int i;
int opt_char;
int options = DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES;
 
/* Use the program name of this program, as invoked. */
program_name = argv[0];
 
/* Parse options. */
do
{
opt_char = getopt_long (argc, argv, "hpv", long_options, NULL);
switch (opt_char)
{
case '?': /* Unrecognized option. */
print_usage (stderr, 1);
break;
 
case 'h':
print_usage (stdout, 0);
break;
 
case 'p':
options &= ~ DMGL_PARAMS;
break;
 
case 'v':
options |= DMGL_VERBOSE;
break;
}
}
while (opt_char != -1);
 
if (optind == argc)
/* No command line arguments were provided. Filter stdin. */
{
dyn_string_t mangled = dyn_string_new (3);
char *s;
 
/* Read all of input. */
while (!feof (stdin))
{
char c;
 
/* Pile characters into mangled until we hit one that can't
occur in a mangled name. */
c = getchar ();
while (!feof (stdin) && is_mangled_char (c))
{
dyn_string_append_char (mangled, c);
if (feof (stdin))
break;
c = getchar ();
}
 
if (dyn_string_length (mangled) > 0)
{
#ifdef IN_GLIBCPP_V3
s = __cxa_demangle (dyn_string_buf (mangled), NULL, NULL, NULL);
#else
s = cplus_demangle_v3 (dyn_string_buf (mangled), options);
#endif
 
if (s != NULL)
{
fputs (s, stdout);
free (s);
}
else
{
/* It might not have been a mangled name. Print the
original text. */
fputs (dyn_string_buf (mangled), stdout);
}
 
dyn_string_clear (mangled);
}
 
/* If we haven't hit EOF yet, we've read one character that
can't occur in a mangled name, so print it out. */
if (!feof (stdin))
putchar (c);
}
 
dyn_string_delete (mangled);
}
else
/* Demangle command line arguments. */
{
/* Loop over command line arguments. */
for (i = optind; i < argc; ++i)
{
char *s;
#ifdef IN_GLIBCPP_V3
int status;
#endif
 
/* Attempt to demangle. */
#ifdef IN_GLIBCPP_V3
s = __cxa_demangle (argv[i], NULL, NULL, &status);
#else
s = cplus_demangle_v3 (argv[i], options);
#endif
 
/* If it worked, print the demangled name. */
if (s != NULL)
{
printf ("%s\n", s);
free (s);
}
else
{
#ifdef IN_GLIBCPP_V3
fprintf (stderr, "Failed: %s (status %d)\n", argv[i], status);
#else
fprintf (stderr, "Failed: %s\n", argv[i]);
#endif
}
}
}
 
return 0;
}
 
#endif /* STANDALONE_DEMANGLER */
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/cp-demangle.h
0,0 → 1,169
/* Internal demangler interface for g++ V3 ABI.
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010
Free Software Foundation, Inc.
Written by Ian Lance Taylor <ian@wasabisystems.com>.
 
This file is part of the libiberty library, which is part of GCC.
 
This file is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combined
executable.)
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
 
/* This file provides some definitions shared by cp-demangle.c and
cp-demint.c. It should not be included by any other files. */
 
/* Information we keep for operators. */
 
struct demangle_operator_info
{
/* Mangled name. */
const char *code;
/* Real name. */
const char *name;
/* Length of real name. */
int len;
/* Number of arguments. */
int args;
};
 
/* How to print the value of a builtin type. */
 
enum d_builtin_type_print
{
/* Print as (type)val. */
D_PRINT_DEFAULT,
/* Print as integer. */
D_PRINT_INT,
/* Print as unsigned integer, with trailing "u". */
D_PRINT_UNSIGNED,
/* Print as long, with trailing "l". */
D_PRINT_LONG,
/* Print as unsigned long, with trailing "ul". */
D_PRINT_UNSIGNED_LONG,
/* Print as long long, with trailing "ll". */
D_PRINT_LONG_LONG,
/* Print as unsigned long long, with trailing "ull". */
D_PRINT_UNSIGNED_LONG_LONG,
/* Print as bool. */
D_PRINT_BOOL,
/* Print as float--put value in square brackets. */
D_PRINT_FLOAT,
/* Print in usual way, but here to detect void. */
D_PRINT_VOID
};
 
/* Information we keep for a builtin type. */
 
struct demangle_builtin_type_info
{
/* Type name. */
const char *name;
/* Length of type name. */
int len;
/* Type name when using Java. */
const char *java_name;
/* Length of java name. */
int java_len;
/* How to print a value of this type. */
enum d_builtin_type_print print;
};
 
/* The information structure we pass around. */
 
struct d_info
{
/* The string we are demangling. */
const char *s;
/* The end of the string we are demangling. */
const char *send;
/* The options passed to the demangler. */
int options;
/* The next character in the string to consider. */
const char *n;
/* The array of components. */
struct demangle_component *comps;
/* The index of the next available component. */
int next_comp;
/* The number of available component structures. */
int num_comps;
/* The array of substitutions. */
struct demangle_component **subs;
/* The index of the next substitution. */
int next_sub;
/* The number of available entries in the subs array. */
int num_subs;
/* The number of substitutions which we actually made from the subs
array, plus the number of template parameter references we
saw. */
int did_subs;
/* The last name we saw, for constructors and destructors. */
struct demangle_component *last_name;
/* A running total of the length of large expansions from the
mangled name to the demangled name, such as standard
substitutions and builtin types. */
int expansion;
};
 
/* To avoid running past the ending '\0', don't:
- call d_peek_next_char if d_peek_char returned '\0'
- call d_advance with an 'i' that is too large
- call d_check_char(di, '\0')
Everything else is safe. */
#define d_peek_char(di) (*((di)->n))
#define d_peek_next_char(di) ((di)->n[1])
#define d_advance(di, i) ((di)->n += (i))
#define d_check_char(di, c) (d_peek_char(di) == c ? ((di)->n++, 1) : 0)
#define d_next_char(di) (d_peek_char(di) == '\0' ? '\0' : *((di)->n++))
#define d_str(di) ((di)->n)
 
/* Functions and arrays in cp-demangle.c which are referenced by
functions in cp-demint.c. */
#ifdef IN_GLIBCPP_V3
#define CP_STATIC_IF_GLIBCPP_V3 static
#else
#define CP_STATIC_IF_GLIBCPP_V3 extern
#endif
 
#ifndef IN_GLIBCPP_V3
extern const struct demangle_operator_info cplus_demangle_operators[];
#endif
 
#define D_BUILTIN_TYPE_COUNT (33)
 
CP_STATIC_IF_GLIBCPP_V3
const struct demangle_builtin_type_info
cplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT];
 
CP_STATIC_IF_GLIBCPP_V3
struct demangle_component *
cplus_demangle_mangled_name (struct d_info *, int);
 
CP_STATIC_IF_GLIBCPP_V3
struct demangle_component *
cplus_demangle_type (struct d_info *);
 
extern void
cplus_demangle_init_info (const char *, int, size_t, struct d_info *);
 
/* cp-demangle.c needs to define this a little differently */
#undef CP_STATIC_IF_GLIBCPP_V3
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/cxxabi.h
0,0 → 1,710
// ABI Support -*- C++ -*-
 
// Copyright (C) 2000-2015 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>
 
#ifndef _GLIBCXX_CDTOR_CALLABI
#define _GLIBCXX_CDTOR_CALLABI
#endif
 
#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;
 
// DSO destruction.
int
__cxa_atexit(void (*)(void*), void*, void*) _GLIBCXX_NOTHROW;
 
int
__cxa_finalize(void*);
 
// TLS destruction.
int
__cxa_thread_atexit(void (*)(void*), void*, void *) _GLIBCXX_NOTHROW;
 
// Pure virtual functions.
void
__cxa_pure_virtual(void) __attribute__ ((__noreturn__));
 
void
__cxa_deleted_virtual(void) __attribute__ ((__noreturn__));
 
// Exception handling auxiliary.
void
__cxa_bad_cast() __attribute__((__noreturn__));
 
void
__cxa_bad_typeid() __attribute__((__noreturn__));
 
void
__cxa_throw_bad_array_new_length() __attribute__((__noreturn__));
 
/**
* @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;
};
 
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);
}
 
// 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.
#ifdef _GLIBCXX_LLP64
long long __offset_flags; // Offset and info.
#else
long __offset_flags; // Offset and info.
#endif
 
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;
};
 
// Exception handling forward declarations.
struct __cxa_exception;
struct __cxa_refcounted_exception;
struct __cxa_dependent_exception;
struct __cxa_eh_globals;
 
extern "C"
{
// 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
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.
 
 
// Exception handling runtime.
 
// 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.
__cxa_eh_globals*
__cxa_get_globals() _GLIBCXX_NOTHROW __attribute__ ((__const__));
 
__cxa_eh_globals*
__cxa_get_globals_fast() _GLIBCXX_NOTHROW __attribute__ ((__const__));
 
// Allocate memory for the primary exception plus the thrown object.
void*
__cxa_allocate_exception(size_t) _GLIBCXX_NOTHROW;
 
// Free the space allocated for the primary exception.
void
__cxa_free_exception(void*) _GLIBCXX_NOTHROW;
 
// Throw the exception.
void
__cxa_throw(void*, std::type_info*, void (_GLIBCXX_CDTOR_CALLABI *) (void *))
__attribute__((__noreturn__));
 
// Used to implement exception handlers.
void*
__cxa_get_exception_ptr(void*) _GLIBCXX_NOTHROW __attribute__ ((__pure__));
 
void*
__cxa_begin_catch(void*) _GLIBCXX_NOTHROW;
 
void
__cxa_end_catch();
 
void
__cxa_rethrow() __attribute__((__noreturn__));
 
// Returns the type_info for the currently handled exception [15.3/8], or
// null if there is none.
std::type_info*
__cxa_current_exception_type() _GLIBCXX_NOTHROW __attribute__ ((__pure__));
 
// GNU Extensions.
 
// Allocate memory for a dependent exception.
__cxa_dependent_exception*
__cxa_allocate_dependent_exception() _GLIBCXX_NOTHROW;
 
// Free the space allocated for the dependent exception.
void
__cxa_free_dependent_exception(__cxa_dependent_exception*) _GLIBCXX_NOTHROW;
 
} // extern "C"
 
// A magic placeholder class that can be caught by reference
// to recognize foreign exceptions.
class __foreign_exception
{
virtual ~__foreign_exception() throw();
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.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
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/cxxabi_forced.h
0,0 → 1,60
// cxxabi.h subset for cancellation -*- C++ -*-
// Copyright (C) 2007-2015 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
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/del_op.cc
0,0 → 1,47
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
 
// Copyright (C) 1997-2015 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>
 
#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) _GLIBCXX_USE_NOEXCEPT
{
std::free(ptr);
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/del_opnt.cc
0,0 → 1,47
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
 
// Copyright (C) 1997-2015 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>
 
#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, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
{
std::free(ptr);
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/del_ops.cc
0,0 → 1,33
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
 
// Copyright (C) 1997-2015 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 "new"
 
_GLIBCXX_WEAK_DEFINITION void
operator delete(void* ptr, std::size_t) _GLIBCXX_USE_NOEXCEPT
{
::operator delete (ptr);
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/del_opv.cc
0,0 → 1,33
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
 
// Copyright (C) 1997-2015 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 "new"
 
_GLIBCXX_WEAK_DEFINITION void
operator delete[] (void *ptr) _GLIBCXX_USE_NOEXCEPT
{
::operator delete (ptr);
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/del_opvnt.cc
0,0 → 1,33
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
 
// Copyright (C) 1997-2015 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 "new"
 
_GLIBCXX_WEAK_DEFINITION void
operator delete[] (void *ptr, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
{
::operator delete (ptr);
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/del_opvs.cc
0,0 → 1,33
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
 
// Copyright (C) 1997-2015 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 "new"
 
_GLIBCXX_WEAK_DEFINITION void
operator delete[] (void *ptr, std::size_t) _GLIBCXX_USE_NOEXCEPT
{
::operator delete[] (ptr);
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/demangle.h
0,0 → 1,671
/* Defs for interface to demanglers.
Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002,
2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License
as published by the Free Software Foundation; either version 2, or
(at your option) any later version.
 
In addition to the permissions in the GNU Library General Public
License, the Free Software Foundation gives you unlimited
permission to link the compiled version of this file into
combinations with other programs, and to distribute those
combinations without any restriction coming from the use of this
file. (The Library Public License restrictions do apply in other
respects; for example, they cover modification of the file, and
distribution when not linked into a combined executable.)
 
This program 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
Library General Public License for more details.
 
You should have received a copy of the GNU Library General Public
License along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
 
 
#if !defined (DEMANGLE_H)
#define DEMANGLE_H
 
#include "libiberty.h"
 
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
 
/* Options passed to cplus_demangle (in 2nd parameter). */
 
#define DMGL_NO_OPTS 0 /* For readability... */
#define DMGL_PARAMS (1 << 0) /* Include function args */
#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
#define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */
#define DMGL_VERBOSE (1 << 3) /* Include implementation details. */
#define DMGL_TYPES (1 << 4) /* Also try to demangle type encodings. */
#define DMGL_RET_POSTFIX (1 << 5) /* Print function return types (when
present) after function signature.
It applies only to the toplevel
function type. */
#define DMGL_RET_DROP (1 << 6) /* Suppress printing function return
types, even if present. It applies
only to the toplevel function type.
*/
 
#define DMGL_AUTO (1 << 8)
#define DMGL_GNU (1 << 9)
#define DMGL_LUCID (1 << 10)
#define DMGL_ARM (1 << 11)
#define DMGL_HP (1 << 12) /* For the HP aCC compiler;
same as ARM except for
template arguments, etc. */
#define DMGL_EDG (1 << 13)
#define DMGL_GNU_V3 (1 << 14)
#define DMGL_GNAT (1 << 15)
 
/* If none of these are set, use 'current_demangling_style' as the default. */
#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT)
 
/* Enumeration of possible demangling styles.
 
Lucid and ARM styles are still kept logically distinct, even though
they now both behave identically. The resulting style is actual the
union of both. I.E. either style recognizes both "__pt__" and "__rf__"
for operator "->", even though the first is lucid style and the second
is ARM style. (FIXME?) */
 
extern enum demangling_styles
{
no_demangling = -1,
unknown_demangling = 0,
auto_demangling = DMGL_AUTO,
gnu_demangling = DMGL_GNU,
lucid_demangling = DMGL_LUCID,
arm_demangling = DMGL_ARM,
hp_demangling = DMGL_HP,
edg_demangling = DMGL_EDG,
gnu_v3_demangling = DMGL_GNU_V3,
java_demangling = DMGL_JAVA,
gnat_demangling = DMGL_GNAT
} current_demangling_style;
 
/* Define string names for the various demangling styles. */
 
#define NO_DEMANGLING_STYLE_STRING "none"
#define AUTO_DEMANGLING_STYLE_STRING "auto"
#define GNU_DEMANGLING_STYLE_STRING "gnu"
#define LUCID_DEMANGLING_STYLE_STRING "lucid"
#define ARM_DEMANGLING_STYLE_STRING "arm"
#define HP_DEMANGLING_STYLE_STRING "hp"
#define EDG_DEMANGLING_STYLE_STRING "edg"
#define GNU_V3_DEMANGLING_STYLE_STRING "gnu-v3"
#define JAVA_DEMANGLING_STYLE_STRING "java"
#define GNAT_DEMANGLING_STYLE_STRING "gnat"
 
/* Some macros to test what demangling style is active. */
 
#define CURRENT_DEMANGLING_STYLE current_demangling_style
#define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO)
#define GNU_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU)
#define LUCID_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_LUCID)
#define ARM_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_ARM)
#define HP_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_HP)
#define EDG_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_EDG)
#define GNU_V3_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU_V3)
#define JAVA_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_JAVA)
#define GNAT_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNAT)
 
/* Provide information about the available demangle styles. This code is
pulled from gdb into libiberty because it is useful to binutils also. */
 
extern const struct demangler_engine
{
const char *const demangling_style_name;
const enum demangling_styles demangling_style;
const char *const demangling_style_doc;
} libiberty_demanglers[];
 
extern char *
cplus_demangle (const char *mangled, int options);
 
extern int
cplus_demangle_opname (const char *opname, char *result, int options);
 
extern const char *
cplus_mangle_opname (const char *opname, int options);
 
/* Note: This sets global state. FIXME if you care about multi-threading. */
 
extern void
set_cplus_marker_for_demangling (int ch);
 
extern enum demangling_styles
cplus_demangle_set_style (enum demangling_styles style);
 
extern enum demangling_styles
cplus_demangle_name_to_style (const char *name);
 
/* Callback typedef for allocation-less demangler interfaces. */
typedef void (*demangle_callbackref) (const char *, size_t, void *);
 
/* V3 ABI demangling entry points, defined in cp-demangle.c. Callback
variants return non-zero on success, zero on error. char* variants
return a string allocated by malloc on success, NULL on error. */
extern int
cplus_demangle_v3_callback (const char *mangled, int options,
demangle_callbackref callback, void *opaque);
 
extern char*
cplus_demangle_v3 (const char *mangled, int options);
 
extern int
java_demangle_v3_callback (const char *mangled,
demangle_callbackref callback, void *opaque);
 
extern char*
java_demangle_v3 (const char *mangled);
 
char *
ada_demangle (const char *mangled, int options);
 
enum gnu_v3_ctor_kinds {
gnu_v3_complete_object_ctor = 1,
gnu_v3_base_object_ctor,
gnu_v3_complete_object_allocating_ctor,
gnu_v3_object_ctor_group
};
 
/* Return non-zero iff NAME is the mangled form of a constructor name
in the G++ V3 ABI demangling style. Specifically, return an `enum
gnu_v3_ctor_kinds' value indicating what kind of constructor
it is. */
extern enum gnu_v3_ctor_kinds
is_gnu_v3_mangled_ctor (const char *name);
 
 
enum gnu_v3_dtor_kinds {
gnu_v3_deleting_dtor = 1,
gnu_v3_complete_object_dtor,
gnu_v3_base_object_dtor,
gnu_v3_object_dtor_group
};
 
/* Return non-zero iff NAME is the mangled form of a destructor name
in the G++ V3 ABI demangling style. Specifically, return an `enum
gnu_v3_dtor_kinds' value, indicating what kind of destructor
it is. */
extern enum gnu_v3_dtor_kinds
is_gnu_v3_mangled_dtor (const char *name);
 
/* The V3 demangler works in two passes. The first pass builds a tree
representation of the mangled name, and the second pass turns the
tree representation into a demangled string. Here we define an
interface to permit a caller to build their own tree
representation, which they can pass to the demangler to get a
demangled string. This can be used to canonicalize user input into
something which the demangler might output. It could also be used
by other demanglers in the future. */
 
/* These are the component types which may be found in the tree. Many
component types have one or two subtrees, referred to as left and
right (a component type with only one subtree puts it in the left
subtree). */
 
enum demangle_component_type
{
/* A name, with a length and a pointer to a string. */
DEMANGLE_COMPONENT_NAME,
/* A qualified name. The left subtree is a class or namespace or
some such thing, and the right subtree is a name qualified by
that class. */
DEMANGLE_COMPONENT_QUAL_NAME,
/* A local name. The left subtree describes a function, and the
right subtree is a name which is local to that function. */
DEMANGLE_COMPONENT_LOCAL_NAME,
/* A typed name. The left subtree is a name, and the right subtree
describes that name as a function. */
DEMANGLE_COMPONENT_TYPED_NAME,
/* A template. The left subtree is a template name, and the right
subtree is a template argument list. */
DEMANGLE_COMPONENT_TEMPLATE,
/* A template parameter. This holds a number, which is the template
parameter index. */
DEMANGLE_COMPONENT_TEMPLATE_PARAM,
/* A function parameter. This holds a number, which is the index. */
DEMANGLE_COMPONENT_FUNCTION_PARAM,
/* A constructor. This holds a name and the kind of
constructor. */
DEMANGLE_COMPONENT_CTOR,
/* A destructor. This holds a name and the kind of destructor. */
DEMANGLE_COMPONENT_DTOR,
/* A vtable. This has one subtree, the type for which this is a
vtable. */
DEMANGLE_COMPONENT_VTABLE,
/* A VTT structure. This has one subtree, the type for which this
is a VTT. */
DEMANGLE_COMPONENT_VTT,
/* A construction vtable. The left subtree is the type for which
this is a vtable, and the right subtree is the derived type for
which this vtable is built. */
DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE,
/* A typeinfo structure. This has one subtree, the type for which
this is the tpeinfo structure. */
DEMANGLE_COMPONENT_TYPEINFO,
/* A typeinfo name. This has one subtree, the type for which this
is the typeinfo name. */
DEMANGLE_COMPONENT_TYPEINFO_NAME,
/* A typeinfo function. This has one subtree, the type for which
this is the tpyeinfo function. */
DEMANGLE_COMPONENT_TYPEINFO_FN,
/* A thunk. This has one subtree, the name for which this is a
thunk. */
DEMANGLE_COMPONENT_THUNK,
/* A virtual thunk. This has one subtree, the name for which this
is a virtual thunk. */
DEMANGLE_COMPONENT_VIRTUAL_THUNK,
/* A covariant thunk. This has one subtree, the name for which this
is a covariant thunk. */
DEMANGLE_COMPONENT_COVARIANT_THUNK,
/* A Java class. This has one subtree, the type. */
DEMANGLE_COMPONENT_JAVA_CLASS,
/* A guard variable. This has one subtree, the name for which this
is a guard variable. */
DEMANGLE_COMPONENT_GUARD,
/* The init and wrapper functions for C++11 thread_local variables. */
DEMANGLE_COMPONENT_TLS_INIT,
DEMANGLE_COMPONENT_TLS_WRAPPER,
/* A reference temporary. This has one subtree, the name for which
this is a temporary. */
DEMANGLE_COMPONENT_REFTEMP,
/* A hidden alias. This has one subtree, the encoding for which it
is providing alternative linkage. */
DEMANGLE_COMPONENT_HIDDEN_ALIAS,
/* A standard substitution. This holds the name of the
substitution. */
DEMANGLE_COMPONENT_SUB_STD,
/* The restrict qualifier. The one subtree is the type which is
being qualified. */
DEMANGLE_COMPONENT_RESTRICT,
/* The volatile qualifier. The one subtree is the type which is
being qualified. */
DEMANGLE_COMPONENT_VOLATILE,
/* The const qualifier. The one subtree is the type which is being
qualified. */
DEMANGLE_COMPONENT_CONST,
/* The restrict qualifier modifying a member function. The one
subtree is the type which is being qualified. */
DEMANGLE_COMPONENT_RESTRICT_THIS,
/* The volatile qualifier modifying a member function. The one
subtree is the type which is being qualified. */
DEMANGLE_COMPONENT_VOLATILE_THIS,
/* The const qualifier modifying a member function. The one subtree
is the type which is being qualified. */
DEMANGLE_COMPONENT_CONST_THIS,
/* C++11 A reference modifying a member function. The one subtree is the
type which is being referenced. */
DEMANGLE_COMPONENT_REFERENCE_THIS,
/* C++11: An rvalue reference modifying a member function. The one
subtree is the type which is being referenced. */
DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS,
/* A vendor qualifier. The left subtree is the type which is being
qualified, and the right subtree is the name of the
qualifier. */
DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
/* A pointer. The one subtree is the type which is being pointed
to. */
DEMANGLE_COMPONENT_POINTER,
/* A reference. The one subtree is the type which is being
referenced. */
DEMANGLE_COMPONENT_REFERENCE,
/* C++0x: An rvalue reference. The one subtree is the type which is
being referenced. */
DEMANGLE_COMPONENT_RVALUE_REFERENCE,
/* A complex type. The one subtree is the base type. */
DEMANGLE_COMPONENT_COMPLEX,
/* An imaginary type. The one subtree is the base type. */
DEMANGLE_COMPONENT_IMAGINARY,
/* A builtin type. This holds the builtin type information. */
DEMANGLE_COMPONENT_BUILTIN_TYPE,
/* A vendor's builtin type. This holds the name of the type. */
DEMANGLE_COMPONENT_VENDOR_TYPE,
/* A function type. The left subtree is the return type. The right
subtree is a list of ARGLIST nodes. Either or both may be
NULL. */
DEMANGLE_COMPONENT_FUNCTION_TYPE,
/* An array type. The left subtree is the dimension, which may be
NULL, or a string (represented as DEMANGLE_COMPONENT_NAME), or an
expression. The right subtree is the element type. */
DEMANGLE_COMPONENT_ARRAY_TYPE,
/* A pointer to member type. The left subtree is the class type,
and the right subtree is the member type. CV-qualifiers appear
on the latter. */
DEMANGLE_COMPONENT_PTRMEM_TYPE,
/* A fixed-point type. */
DEMANGLE_COMPONENT_FIXED_TYPE,
/* A vector type. The left subtree is the number of elements,
the right subtree is the element type. */
DEMANGLE_COMPONENT_VECTOR_TYPE,
/* An argument list. The left subtree is the current argument, and
the right subtree is either NULL or another ARGLIST node. */
DEMANGLE_COMPONENT_ARGLIST,
/* A template argument list. The left subtree is the current
template argument, and the right subtree is either NULL or
another TEMPLATE_ARGLIST node. */
DEMANGLE_COMPONENT_TEMPLATE_ARGLIST,
/* An initializer list. The left subtree is either an explicit type or
NULL, and the right subtree is a DEMANGLE_COMPONENT_ARGLIST. */
DEMANGLE_COMPONENT_INITIALIZER_LIST,
/* An operator. This holds information about a standard
operator. */
DEMANGLE_COMPONENT_OPERATOR,
/* An extended operator. This holds the number of arguments, and
the name of the extended operator. */
DEMANGLE_COMPONENT_EXTENDED_OPERATOR,
/* A typecast, represented as a unary operator. The one subtree is
the type to which the argument should be cast. */
DEMANGLE_COMPONENT_CAST,
/* A nullary expression. The left subtree is the operator. */
DEMANGLE_COMPONENT_NULLARY,
/* A unary expression. The left subtree is the operator, and the
right subtree is the single argument. */
DEMANGLE_COMPONENT_UNARY,
/* A binary expression. The left subtree is the operator, and the
right subtree is a BINARY_ARGS. */
DEMANGLE_COMPONENT_BINARY,
/* Arguments to a binary expression. The left subtree is the first
argument, and the right subtree is the second argument. */
DEMANGLE_COMPONENT_BINARY_ARGS,
/* A trinary expression. The left subtree is the operator, and the
right subtree is a TRINARY_ARG1. */
DEMANGLE_COMPONENT_TRINARY,
/* Arguments to a trinary expression. The left subtree is the first
argument, and the right subtree is a TRINARY_ARG2. */
DEMANGLE_COMPONENT_TRINARY_ARG1,
/* More arguments to a trinary expression. The left subtree is the
second argument, and the right subtree is the third argument. */
DEMANGLE_COMPONENT_TRINARY_ARG2,
/* A literal. The left subtree is the type, and the right subtree
is the value, represented as a DEMANGLE_COMPONENT_NAME. */
DEMANGLE_COMPONENT_LITERAL,
/* A negative literal. Like LITERAL, but the value is negated.
This is a minor hack: the NAME used for LITERAL points directly
to the mangled string, but since negative numbers are mangled
using 'n' instead of '-', we want a way to indicate a negative
number which involves neither modifying the mangled string nor
allocating a new copy of the literal in memory. */
DEMANGLE_COMPONENT_LITERAL_NEG,
/* A libgcj compiled resource. The left subtree is the name of the
resource. */
DEMANGLE_COMPONENT_JAVA_RESOURCE,
/* A name formed by the concatenation of two parts. The left
subtree is the first part and the right subtree the second. */
DEMANGLE_COMPONENT_COMPOUND_NAME,
/* A name formed by a single character. */
DEMANGLE_COMPONENT_CHARACTER,
/* A number. */
DEMANGLE_COMPONENT_NUMBER,
/* A decltype type. */
DEMANGLE_COMPONENT_DECLTYPE,
/* Global constructors keyed to name. */
DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS,
/* Global destructors keyed to name. */
DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS,
/* A lambda closure type. */
DEMANGLE_COMPONENT_LAMBDA,
/* A default argument scope. */
DEMANGLE_COMPONENT_DEFAULT_ARG,
/* An unnamed type. */
DEMANGLE_COMPONENT_UNNAMED_TYPE,
/* A transactional clone. This has one subtree, the encoding for
which it is providing alternative linkage. */
DEMANGLE_COMPONENT_TRANSACTION_CLONE,
/* A non-transactional clone entry point. In the i386/x86_64 abi,
the unmangled symbol of a tm_callable becomes a thunk and the
non-transactional function version is mangled thus. */
DEMANGLE_COMPONENT_NONTRANSACTION_CLONE,
/* A pack expansion. */
DEMANGLE_COMPONENT_PACK_EXPANSION,
/* A name with an ABI tag. */
DEMANGLE_COMPONENT_TAGGED_NAME,
/* A cloned function. */
DEMANGLE_COMPONENT_CLONE
};
 
/* Types which are only used internally. */
 
struct demangle_operator_info;
struct demangle_builtin_type_info;
 
/* A node in the tree representation is an instance of a struct
demangle_component. Note that the field names of the struct are
not well protected against macros defined by the file including
this one. We can fix this if it ever becomes a problem. */
 
struct demangle_component
{
/* The type of this component. */
enum demangle_component_type type;
 
union
{
/* For DEMANGLE_COMPONENT_NAME. */
struct
{
/* A pointer to the name (which need not NULL terminated) and
its length. */
const char *s;
int len;
} s_name;
 
/* For DEMANGLE_COMPONENT_OPERATOR. */
struct
{
/* Operator. */
const struct demangle_operator_info *op;
} s_operator;
 
/* For DEMANGLE_COMPONENT_EXTENDED_OPERATOR. */
struct
{
/* Number of arguments. */
int args;
/* Name. */
struct demangle_component *name;
} s_extended_operator;
 
/* For DEMANGLE_COMPONENT_FIXED_TYPE. */
struct
{
/* The length, indicated by a C integer type name. */
struct demangle_component *length;
/* _Accum or _Fract? */
short accum;
/* Saturating or not? */
short sat;
} s_fixed;
 
/* For DEMANGLE_COMPONENT_CTOR. */
struct
{
/* Kind of constructor. */
enum gnu_v3_ctor_kinds kind;
/* Name. */
struct demangle_component *name;
} s_ctor;
 
/* For DEMANGLE_COMPONENT_DTOR. */
struct
{
/* Kind of destructor. */
enum gnu_v3_dtor_kinds kind;
/* Name. */
struct demangle_component *name;
} s_dtor;
 
/* For DEMANGLE_COMPONENT_BUILTIN_TYPE. */
struct
{
/* Builtin type. */
const struct demangle_builtin_type_info *type;
} s_builtin;
 
/* For DEMANGLE_COMPONENT_SUB_STD. */
struct
{
/* Standard substitution string. */
const char* string;
/* Length of string. */
int len;
} s_string;
 
/* For DEMANGLE_COMPONENT_*_PARAM. */
struct
{
/* Parameter index. */
long number;
} s_number;
 
/* For DEMANGLE_COMPONENT_CHARACTER. */
struct
{
int character;
} s_character;
 
/* For other types. */
struct
{
/* Left (or only) subtree. */
struct demangle_component *left;
/* Right subtree. */
struct demangle_component *right;
} s_binary;
 
struct
{
/* subtree, same place as d_left. */
struct demangle_component *sub;
/* integer. */
int num;
} s_unary_num;
 
} u;
};
 
/* People building mangled trees are expected to allocate instances of
struct demangle_component themselves. They can then call one of
the following functions to fill them in. */
 
/* Fill in most component types with a left subtree and a right
subtree. Returns non-zero on success, zero on failure, such as an
unrecognized or inappropriate component type. */
 
extern int
cplus_demangle_fill_component (struct demangle_component *fill,
enum demangle_component_type,
struct demangle_component *left,
struct demangle_component *right);
 
/* Fill in a DEMANGLE_COMPONENT_NAME. Returns non-zero on success,
zero for bad arguments. */
 
extern int
cplus_demangle_fill_name (struct demangle_component *fill,
const char *, int);
 
/* Fill in a DEMANGLE_COMPONENT_BUILTIN_TYPE, using the name of the
builtin type (e.g., "int", etc.). Returns non-zero on success,
zero if the type is not recognized. */
 
extern int
cplus_demangle_fill_builtin_type (struct demangle_component *fill,
const char *type_name);
 
/* Fill in a DEMANGLE_COMPONENT_OPERATOR, using the name of the
operator and the number of arguments which it takes (the latter is
used to disambiguate operators which can be both binary and unary,
such as '-'). Returns non-zero on success, zero if the operator is
not recognized. */
 
extern int
cplus_demangle_fill_operator (struct demangle_component *fill,
const char *opname, int args);
 
/* Fill in a DEMANGLE_COMPONENT_EXTENDED_OPERATOR, providing the
number of arguments and the name. Returns non-zero on success,
zero for bad arguments. */
 
extern int
cplus_demangle_fill_extended_operator (struct demangle_component *fill,
int numargs,
struct demangle_component *nm);
 
/* Fill in a DEMANGLE_COMPONENT_CTOR. Returns non-zero on success,
zero for bad arguments. */
 
extern int
cplus_demangle_fill_ctor (struct demangle_component *fill,
enum gnu_v3_ctor_kinds kind,
struct demangle_component *name);
 
/* Fill in a DEMANGLE_COMPONENT_DTOR. Returns non-zero on success,
zero for bad arguments. */
 
extern int
cplus_demangle_fill_dtor (struct demangle_component *fill,
enum gnu_v3_dtor_kinds kind,
struct demangle_component *name);
 
/* This function translates a mangled name into a struct
demangle_component tree. The first argument is the mangled name.
The second argument is DMGL_* options. This returns a pointer to a
tree on success, or NULL on failure. On success, the third
argument is set to a block of memory allocated by malloc. This
block should be passed to free when the tree is no longer
needed. */
 
extern struct demangle_component *
cplus_demangle_v3_components (const char *mangled, int options, void **mem);
 
/* This function takes a struct demangle_component tree and returns
the corresponding demangled string. The first argument is DMGL_*
options. The second is the tree to demangle. The third is a guess
at the length of the demangled string, used to initially allocate
the return buffer. The fourth is a pointer to a size_t. On
success, this function returns a buffer allocated by malloc(), and
sets the size_t pointed to by the fourth argument to the size of
the allocated buffer (not the length of the returned string). On
failure, this function returns NULL, and sets the size_t pointed to
by the fourth argument to 0 for an invalid tree, or to 1 for a
memory allocation error. */
 
extern char *
cplus_demangle_print (int options,
const struct demangle_component *tree,
int estimated_length,
size_t *p_allocated_size);
 
/* This function takes a struct demangle_component tree and passes back
a demangled string in one or more calls to a callback function.
The first argument is DMGL_* options. The second is the tree to
demangle. The third is a pointer to a callback function; on each call
this receives an element of the demangled string, its length, and an
opaque value. The fourth is the opaque value passed to the callback.
The callback is called once or more to return the full demangled
string. The demangled element string is always nul-terminated, though
its length is also provided for convenience. In contrast to
cplus_demangle_print(), this function does not allocate heap memory
to grow output strings (except perhaps where alloca() is implemented
by malloc()), and so is normally safe for use where the heap has been
corrupted. On success, this function returns 1; on failure, 0. */
 
extern int
cplus_demangle_print_callback (int options,
const struct demangle_component *tree,
demangle_callbackref callback, void *opaque);
 
#ifdef __cplusplus
}
#endif /* __cplusplus */
 
#endif /* DEMANGLE_H */
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/dyncast.cc
0,0 → 1,97
// Copyright (C) 1994-2015 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 "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;
 
// If the whole object vptr doesn't refer to the whole object type, we're
// in the middle of constructing a primary base, and src is a separate
// base. This has undefined behavior and we can't find anything outside
// of the base we're actually constructing, so fail now rather than
// segfault later trying to use a vbase offset that doesn't exist.
const void *whole_vtable = *static_cast <const void *const *> (whole_ptr);
const vtable_prefix *whole_prefix =
adjust_pointer <vtable_prefix> (whole_vtable,
-offsetof (vtable_prefix, origin));
if (whole_prefix->whole_type != whole_type)
return NULL;
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;
}
 
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/eh_alloc.cc
0,0 → 1,307
// -*- C++ -*- Allocate exception objects.
// Copyright (C) 2001-2015 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>
#include <new>
 
#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 !defined (_GLIBCXX_LLP64) && 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
 
 
namespace
{
// A fixed-size heap, variable size object allocator
class pool
{
public:
pool();
 
void *allocate (std::size_t);
void free (void *);
 
bool in_pool (void *);
 
private:
struct free_entry {
std::size_t size;
free_entry *next;
};
struct allocated_entry {
std::size_t size;
char data[] __attribute__((aligned));
};
 
// A single mutex controlling emergency allocations.
__gnu_cxx::__mutex emergency_mutex;
 
// The free-list
free_entry *first_free_entry;
// The arena itself - we need to keep track of these only
// to implement in_pool.
char *arena;
std::size_t arena_size;
};
 
pool::pool()
{
// Allocate the arena - we could add a GLIBCXX_EH_ARENA_SIZE environment
// to make this tunable.
arena_size = (EMERGENCY_OBJ_SIZE * EMERGENCY_OBJ_COUNT
+ EMERGENCY_OBJ_COUNT * sizeof (__cxa_dependent_exception));
arena = (char *)malloc (arena_size);
if (!arena)
{
// If the allocation failed go without an emergency pool.
arena_size = 0;
first_free_entry = NULL;
return;
}
 
// Populate the free-list with a single entry covering the whole arena
first_free_entry = reinterpret_cast <free_entry *> (arena);
new (first_free_entry) free_entry;
first_free_entry->size = arena_size;
first_free_entry->next = NULL;
}
 
void *pool::allocate (std::size_t size)
{
__gnu_cxx::__scoped_lock sentry(emergency_mutex);
// We need an additional size_t member plus the padding to
// ensure proper alignment of data.
size += offsetof (allocated_entry, data);
// And we need to at least hand out objects of the size of
// a freelist entry.
if (size < sizeof (free_entry))
size = sizeof (free_entry);
// And we need to align objects we hand out to the maximum
// alignment required on the target (this really aligns the
// tail which will become a new freelist entry).
size = ((size + __alignof__ (allocated_entry::data) - 1)
& ~(__alignof__ (allocated_entry::data) - 1));
// Search for an entry of proper size on the freelist.
free_entry **e;
for (e = &first_free_entry;
*e && (*e)->size < size;
e = &(*e)->next)
;
if (!*e)
return NULL;
allocated_entry *x;
if ((*e)->size - size >= sizeof (free_entry))
{
// Slit block if it is too large.
free_entry *f = reinterpret_cast <free_entry *>
(reinterpret_cast <char *> (*e) + size);
std::size_t sz = (*e)->size;
free_entry *next = (*e)->next;
new (f) free_entry;
f->next = next;
f->size = sz - size;
x = reinterpret_cast <allocated_entry *> (*e);
new (x) allocated_entry;
x->size = size;
*e = f;
}
else
{
// Exact size match or too small overhead for a free entry.
std::size_t sz = (*e)->size;
free_entry *next = (*e)->next;
x = reinterpret_cast <allocated_entry *> (*e);
new (x) allocated_entry;
x->size = sz;
*e = next;
}
return &x->data;
}
 
void pool::free (void *data)
{
__gnu_cxx::__scoped_lock sentry(emergency_mutex);
allocated_entry *e = reinterpret_cast <allocated_entry *>
(reinterpret_cast <char *> (data) - offsetof (allocated_entry, data));
std::size_t sz = e->size;
if (!first_free_entry)
{
// If the free list is empty just put the entry there.
free_entry *f = reinterpret_cast <free_entry *> (e);
new (f) free_entry;
f->size = sz;
f->next = NULL;
first_free_entry = f;
}
else if (reinterpret_cast <char *> (e) + sz
== reinterpret_cast <char *> (first_free_entry))
{
// Check if we can merge with the first free entry being right
// after us.
free_entry *f = reinterpret_cast <free_entry *> (e);
new (f) free_entry;
f->size = sz + first_free_entry->size;
f->next = first_free_entry->next;
first_free_entry = f;
}
else
{
// Else search for a free item we can merge with at its end.
free_entry **fe;
for (fe = &first_free_entry;
(*fe)->next
&& (reinterpret_cast <char *> ((*fe)->next)
> reinterpret_cast <char *> (e) + sz);
fe = &(*fe)->next)
;
if (reinterpret_cast <char *> (*fe) + (*fe)->size
== reinterpret_cast <char *> (e))
/* Merge with the freelist entry. */
(*fe)->size += sz;
else
{
// Else put it after it which keeps the freelist sorted.
free_entry *f = reinterpret_cast <free_entry *> (e);
new (f) free_entry;
f->size = sz;
f->next = (*fe)->next;
(*fe)->next = f;
}
}
}
 
bool pool::in_pool (void *ptr)
{
char *p = reinterpret_cast <char *> (ptr);
return (p > arena
&& p < arena + arena_size);
}
 
pool emergency_pool;
}
 
extern "C" void *
__cxxabiv1::__cxa_allocate_exception(std::size_t thrown_size) _GLIBCXX_NOTHROW
{
void *ret;
 
thrown_size += sizeof (__cxa_refcounted_exception);
ret = malloc (thrown_size);
 
if (!ret)
ret = emergency_pool.allocate (thrown_size);
 
if (!ret)
std::terminate ();
 
memset (ret, 0, sizeof (__cxa_refcounted_exception));
 
return (void *)((char *)ret + sizeof (__cxa_refcounted_exception));
}
 
 
extern "C" void
__cxxabiv1::__cxa_free_exception(void *vptr) _GLIBCXX_NOTHROW
{
char *ptr = (char *) vptr - sizeof (__cxa_refcounted_exception);
if (emergency_pool.in_pool (ptr))
emergency_pool.free (ptr);
else
free (ptr);
}
 
 
extern "C" __cxa_dependent_exception*
__cxxabiv1::__cxa_allocate_dependent_exception() _GLIBCXX_NOTHROW
{
__cxa_dependent_exception *ret;
 
ret = static_cast<__cxa_dependent_exception*>
(malloc (sizeof (__cxa_dependent_exception)));
 
if (!ret)
ret = static_cast <__cxa_dependent_exception*>
(emergency_pool.allocate (sizeof (__cxa_dependent_exception)));
 
if (!ret)
std::terminate ();
 
memset (ret, 0, sizeof (__cxa_dependent_exception));
 
return ret;
}
 
 
extern "C" void
__cxxabiv1::__cxa_free_dependent_exception
(__cxa_dependent_exception *vptr) _GLIBCXX_NOTHROW
{
if (emergency_pool.in_pool (vptr))
emergency_pool.free (vptr);
else
free (vptr);
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/eh_arm.cc
0,0 → 1,227
// -*- C++ -*- ARM specific Exception handling support routines.
// Copyright (C) 2004-2015 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, exception object UE_HEADER and a
// type CATCH_TYPE to compare against, return whether or not there is
// a match and if so, update *THROWN_PTR_P to point to either the
// type-matched object, or in the case of a pointer type, the object
// pointed to by the pointer.
 
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;
void *thrown_ptr = 0;
 
if (forced_unwind)
throw_type = &typeid(abi::__forced_unwind);
else if (foreign_exception)
throw_type = &typeid(abi::__foreign_exception);
else
{
if (dependent_exception)
xh = __get_exception_header_from_obj (dx->primaryException);
throw_type = xh->exceptionType;
// We used to require the caller set the target of thrown_ptr_p,
// but that's incorrect -- the EHABI makes no such requirement
// -- and not all callers will set it. Fortunately callers that
// do initialize will always pass us the value we calculate
// here, so there's no backwards compatibility problem.
thrown_ptr = __get_object_from_ue (ue_header);
}
__cxa_type_match_result result = ctm_succeeded;
 
// 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;
// We need to indicate the indirection to our caller.
result = ctm_succeeded_with_ptr_to_base;
}
 
if (catch_type->__do_catch(throw_type, &thrown_ptr, 1))
{
*thrown_ptr_p = thrown_ptr;
return result;
}
 
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;
}
 
#ifdef __TMS320C6X__
// Assembly wrapper to call __gnu_end_cleanup without clobbering
// function arguments to _Unwind_Resume.
asm (".global __cxa_end_cleanup\n"
" .type __cxa_end_cleanup, \"function\"\n"
"__cxa_end_cleanup:\n"
" stw .d2t2 B9, *B15--[10]\n"
" stw .d2t2 B8, *+B15[9]\n"
" stw .d2t2 B7, *+B15[8]\n"
" stw .d2t2 B6, *+B15[7]\n"
" stw .d2t2 B5, *+B15[6]\n"
" stw .d2t2 B4, *+B15[5]\n"
" stw .d2t1 A9, *+B15[4]\n"
" stw .d2t1 A8, *+B15[3]\n"
" stw .d2t1 A7, *+B15[2]\n"
" stw .d2t1 A6, *+B15[1]\n"
#ifdef _TMS320C6400_PLUS
" callp .s2 (__gnu_end_cleanup), B3\n"
#elif defined(_TMS320C6400)
" call .s2 (__gnu_end_cleanup)\n"
" addkpc .s2 1f, B3, 0\n"
" nop 4\n"
"1:\n"
#else
" call .s2 (__gnu_end_cleanup)\n"
" mvkl .s2 1f, B3\n"
" mvkh .s2 1f, B3\n"
" nop 3\n"
"1:\n"
#endif
" ldw .d2t1 *+B15[1], A6\n"
" ldw .d2t1 *+B15[2], A7\n"
" ldw .d2t1 *+B15[3], A8\n"
" ldw .d2t1 *+B15[4], A9\n"
" ldw .d2t2 *+B15[5], B4\n"
" ldw .d2t2 *+B15[6], B5\n"
" ldw .d2t2 *+B15[7], B6\n"
" ldw .d2t2 *+B15[8], B7\n"
" ldw .d2t2 *+B15[9], B8\n"
" ldw .d2t2 *++B15[10], B9\n"
" b .s2 _Unwind_Resume\n"
" nop 5\n");
#else
// 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
 
#endif
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/eh_aux_runtime.cc
0,0 → 1,42
// -*- C++ -*- Common throw conditions.
// Copyright (C) 1994-2015 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 "exception"
#include "new"
#include <cstdlib>
#include "unwind-cxx.h"
#include <bits/exception_defines.h>
 
extern "C" void
__cxxabiv1::__cxa_bad_cast ()
{ _GLIBCXX_THROW_OR_ABORT(std::bad_cast()); }
 
extern "C" void
__cxxabiv1::__cxa_bad_typeid ()
{ _GLIBCXX_THROW_OR_ABORT(std::bad_typeid()); }
 
extern "C" void
__cxxabiv1::__cxa_throw_bad_array_new_length ()
{ _GLIBCXX_THROW_OR_ABORT(std::bad_array_new_length()); }
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/eh_call.cc
0,0 → 1,161
// -*- C++ -*- Helpers for calling unextected and terminate
// Copyright (C) 2001-2015 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;
_Unwind_Ptr rtti_base = 0;
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_base = (_Unwind_Ptr) exc_obj->barrier_cache.bitpattern[2];
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_typeinfo_ptr(rtti_base, 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 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 NULL.
void* obj = NULL;
if (catch_type->__do_catch(&bad_exc, &obj, 1))
bad_exception_allowed = true;
}
 
// If the exception spec allows std::bad_exception, throw that.
#if __cpp_exceptions
if (bad_exception_allowed)
throw std::bad_exception();
#endif
 
// Otherwise, die.
__terminate(terminateHandler);
}
}
#endif // __ARM_EABI_UNWINDER__
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/eh_catch.cc
0,0 → 1,141
// -*- C++ -*- Exception handling routines for catching.
// Copyright (C) 2001-2015 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) _GLIBCXX_NOTHROW
{
_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) _GLIBCXX_NOTHROW
{
_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);
 
PROBE2 (catch, objectp, header->exceptionType);
 
#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;
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/eh_exception.cc
0,0 → 1,50
// -*- C++ -*- std::exception implementation.
// Copyright (C) 1994-2015 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 "exception"
#include <cxxabi.h>
 
std::exception::~exception() _GLIBCXX_USE_NOEXCEPT { }
 
std::bad_exception::~bad_exception() _GLIBCXX_USE_NOEXCEPT { }
 
abi::__forced_unwind::~__forced_unwind() throw() { }
 
abi::__foreign_exception::~__foreign_exception() throw() { }
 
const char*
std::exception::what() const _GLIBCXX_USE_NOEXCEPT
{
// 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 _GLIBCXX_USE_NOEXCEPT
{
return "std::bad_exception";
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/eh_globals.cc
0,0 → 1,159
// -*- C++ -*- Manage the thread-local exception globals.
// Copyright (C) 2001-2015 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() _GLIBCXX_NOTHROW
{
static __thread abi::__cxa_eh_globals global;
return &global;
}
} // anonymous namespace
 
extern "C" __cxa_eh_globals*
__cxxabiv1::__cxa_get_globals_fast() _GLIBCXX_NOTHROW
{ return get_global(); }
 
extern "C" __cxa_eh_globals*
__cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW
{ 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() _GLIBCXX_NOTHROW
{
__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() _GLIBCXX_NOTHROW
{
__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() _GLIBCXX_NOTHROW
{ return &eh_globals; }
 
extern "C" __cxa_eh_globals*
__cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW
{ return &eh_globals; }
 
#endif
 
#endif
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/eh_personality.cc
0,0 → 1,803
// -*- C++ -*- The GNU C++ exception personality routine.
// Copyright (C) 2001-2015 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;
 
#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)
{
#if _GLIBCXX_OVERRIDE_TTYPE_ENCODING
/* Older ARM EABI toolchains set this value incorrectly, so use a
hardcoded OS-specific format. */
info->ttype_encoding = _GLIBCXX_OVERRIDE_TTYPE_ENCODING;
#endif
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;
}
 
// 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);
}
 
#ifdef __ARM_EABI_UNWINDER__
 
// 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_typeinfo_ptr(info->ttype_base, (_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, UNWIND_STACK_REG);
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;
 
 
// 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
#elif defined(__SEH__) && !defined (_GLIBCXX_SJLJ_EXCEPTIONS)
#define PERSONALITY_FUNCTION __gxx_personality_imp
#else
#define PERSONALITY_FUNCTION __gxx_personality_v0
#endif
 
#if defined (__SEH__) && !defined (_GLIBCXX_SJLJ_EXCEPTIONS)
static
#else
extern "C"
#endif
_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:
// If the unwind state pattern is
// _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND
// then we don't need to search for any handler as it is not a real
// exception. Just unwind the stack.
if (state & _US_FORCE_UNWIND)
CONTINUE_UNWINDING;
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,
UNWIND_STACK_REG))
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 a
// virtual scratch register point at the UCB.
ip = (_Unwind_Ptr) ue_header;
_Unwind_SetGR(context, UNWIND_POINTER_REG, 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
#if __cpp_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);
info.ttype_base = base_of_encoded_value (info.ttype_encoding,
context);
 
#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
ue_header->barrier_cache.bitpattern[2] = info.ttype_base;
// 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 __cpp_exceptions && __cpp_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
 
#if defined (__SEH__) && !defined (_GLIBCXX_SJLJ_EXCEPTIONS)
extern "C"
EXCEPTION_DISPOSITION
__gxx_personality_seh0 (PEXCEPTION_RECORD ms_exc, void *this_frame,
PCONTEXT ms_orig_context, PDISPATCHER_CONTEXT ms_disp)
{
return _GCC_specific_handler (ms_exc, this_frame, ms_orig_context,
ms_disp, __gxx_personality_imp);
}
#endif /* SEH */
 
} // namespace __cxxabiv1
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/eh_ptr.cc
0,0 → 1,264
// -*- C++ -*- Implement the members of exception_ptr.
// Copyright (C) 2008-2015 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 <bits/atomic_lockfree_defines.h>
 
#if ATOMIC_INT_LOCK_FREE > 1
 
#define _GLIBCXX_EH_PTR_COMPAT
 
#include <exception>
#include <bits/exception_ptr.h>
#include "unwind-cxx.h"
 
using namespace __cxxabiv1;
 
// Verify assumptions about member layout in exception types
namespace
{
template<typename Ex>
constexpr std::size_t unwindhdr()
{ return offsetof(Ex, unwindHeader); }
 
template<typename Ex>
constexpr std::size_t termHandler()
{ return unwindhdr<Ex>() - offsetof(Ex, terminateHandler); }
 
static_assert( termHandler<__cxa_exception>()
== termHandler<__cxa_dependent_exception>(),
"__cxa_dependent_exception::termHandler layout must be"
" consistent with __cxa_exception::termHandler" );
 
#ifndef __ARM_EABI_UNWINDER__
template<typename Ex>
constexpr std::ptrdiff_t adjptr()
{ return unwindhdr<Ex>() - offsetof(Ex, adjustedPtr); }
 
static_assert( adjptr<__cxa_exception>()
== adjptr<__cxa_dependent_exception>(),
"__cxa_dependent_exception::adjustedPtr layout must be"
" consistent with __cxa_exception::adjustedPtr" );
#endif
}
 
std::__exception_ptr::exception_ptr::exception_ptr() _GLIBCXX_USE_NOEXCEPT
: _M_exception_object(0) { }
 
 
std::__exception_ptr::exception_ptr::exception_ptr(void* obj)
_GLIBCXX_USE_NOEXCEPT
: _M_exception_object(obj) { _M_addref(); }
 
 
std::__exception_ptr::exception_ptr::exception_ptr(__safe_bool)
_GLIBCXX_USE_NOEXCEPT
: _M_exception_object(0) { }
 
 
std::__exception_ptr::
exception_ptr::exception_ptr(const exception_ptr& other) _GLIBCXX_USE_NOEXCEPT
: _M_exception_object(other._M_exception_object)
{ _M_addref(); }
 
 
std::__exception_ptr::exception_ptr::~exception_ptr() _GLIBCXX_USE_NOEXCEPT
{ _M_release(); }
 
 
std::__exception_ptr::exception_ptr&
std::__exception_ptr::
exception_ptr::operator=(const exception_ptr& other) _GLIBCXX_USE_NOEXCEPT
{
exception_ptr(other).swap(*this);
return *this;
}
 
 
void
std::__exception_ptr::exception_ptr::_M_addref() _GLIBCXX_USE_NOEXCEPT
{
if (_M_exception_object)
{
__cxa_refcounted_exception *eh =
__get_refcounted_exception_header_from_obj (_M_exception_object);
__atomic_add_fetch (&eh->referenceCount, 1, __ATOMIC_ACQ_REL);
}
}
 
 
void
std::__exception_ptr::exception_ptr::_M_release() _GLIBCXX_USE_NOEXCEPT
{
if (_M_exception_object)
{
__cxa_refcounted_exception *eh =
__get_refcounted_exception_header_from_obj (_M_exception_object);
if (__atomic_sub_fetch (&eh->referenceCount, 1, __ATOMIC_ACQ_REL) == 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 _GLIBCXX_USE_NOEXCEPT
{ return _M_exception_object; }
 
 
void
std::__exception_ptr::exception_ptr::swap(exception_ptr &other)
_GLIBCXX_USE_NOEXCEPT
{
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()
_GLIBCXX_USE_NOEXCEPT { }
 
 
// Retained for compatibility with CXXABI_1.3.
bool
std::__exception_ptr::exception_ptr::operator!() const _GLIBCXX_USE_NOEXCEPT
{ return _M_exception_object == 0; }
 
 
// Retained for compatibility with CXXABI_1.3.
std::__exception_ptr::exception_ptr::operator __safe_bool() const
_GLIBCXX_USE_NOEXCEPT
{
return _M_exception_object ? &exception_ptr::_M_safe_bool_dummy : 0;
}
 
 
const std::type_info*
std::__exception_ptr::exception_ptr::__cxa_exception_type() const
_GLIBCXX_USE_NOEXCEPT
{
__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)
_GLIBCXX_USE_NOEXCEPT
{ return lhs._M_exception_object == rhs._M_exception_object; }
 
 
bool std::__exception_ptr::operator!=(const exception_ptr& lhs,
const exception_ptr& rhs)
_GLIBCXX_USE_NOEXCEPT
{ return !(lhs == rhs);}
 
 
std::exception_ptr
std::current_exception() _GLIBCXX_USE_NOEXCEPT
{
__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 (__atomic_sub_fetch (&header->referenceCount, 1, __ATOMIC_ACQ_REL) == 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;
__atomic_add_fetch (&eh->referenceCount, 1, __ATOMIC_ACQ_REL);
 
dep->unexpectedHandler = get_unexpected ();
dep->terminateHandler = get_terminate ();
__GXX_INIT_DEPENDENT_EXCEPTION_CLASS(dep->unwindHeader.exception_class);
dep->unwindHeader.exception_cleanup = __gxx_dependent_exception_cleanup;
 
__cxa_eh_globals *globals = __cxa_get_globals ();
globals->uncaughtExceptions += 1;
 
#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
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/eh_term_handler.cc
0,0 → 1,44
// -*- C++ -*- std::terminate handler
// Copyright (C) 2002-2015 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"
 
/* 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 configuring GCC with
--disable-libstdcxx-verbose and rebuilding the library.
In a freestanding environment, we default to this latter approach. */
 
#if _GLIBCXX_HOSTED && _GLIBCXX_VERBOSE
/* The current installed user handler. */
std::terminate_handler __cxxabiv1::__terminate_handler =
__gnu_cxx::__verbose_terminate_handler;
#else
# include <cstdlib>
/* The current installed user handler. */
std::terminate_handler __cxxabiv1::__terminate_handler = std::abort;
#endif
 
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/eh_terminate.cc
0,0 → 1,125
// -*- C++ -*- std::terminate, std::unexpected and friends.
// Copyright (C) 1994-2015 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 "exception"
#include <cstdlib>
#include "unwind-cxx.h"
#include <bits/exception_defines.h>
#include <bits/atomic_lockfree_defines.h>
 
#if ATOMIC_POINTER_LOCK_FREE < 2
#include <ext/concurrence.h>
namespace
{
__gnu_cxx::__mutex mx;
}
#endif
 
using namespace __cxxabiv1;
 
void
__cxxabiv1::__terminate (std::terminate_handler handler) throw ()
{
__try
{
handler ();
std::abort ();
}
__catch(...)
{ std::abort (); }
}
 
void
std::terminate () throw()
{
__terminate (get_terminate ());
}
 
void
__cxxabiv1::__unexpected (std::unexpected_handler handler)
{
handler();
std::terminate ();
}
 
void
std::unexpected ()
{
__unexpected (get_unexpected ());
}
 
std::terminate_handler
std::set_terminate (std::terminate_handler func) throw()
{
std::terminate_handler old;
#if ATOMIC_POINTER_LOCK_FREE > 1
__atomic_exchange (&__terminate_handler, &func, &old, __ATOMIC_ACQ_REL);
#else
__gnu_cxx::__scoped_lock l(mx);
old = __terminate_handler;
__terminate_handler = func;
#endif
return old;
}
 
std::terminate_handler
std::get_terminate () noexcept
{
std::terminate_handler func;
#if ATOMIC_POINTER_LOCK_FREE > 1
__atomic_load (&__terminate_handler, &func, __ATOMIC_ACQUIRE);
#else
__gnu_cxx::__scoped_lock l(mx);
func = __terminate_handler;
#endif
return func;
}
 
std::unexpected_handler
std::set_unexpected (std::unexpected_handler func) throw()
{
std::unexpected_handler old;
#if ATOMIC_POINTER_LOCK_FREE > 1
__atomic_exchange (&__unexpected_handler, &func, &old, __ATOMIC_ACQ_REL);
#else
__gnu_cxx::__scoped_lock l(mx);
old = __unexpected_handler;
__unexpected_handler = func;
#endif
return old;
}
 
std::unexpected_handler
std::get_unexpected () noexcept
{
std::unexpected_handler func;
#if ATOMIC_POINTER_LOCK_FREE > 1
__atomic_load (&__unexpected_handler, &func, __ATOMIC_ACQUIRE);
#else
__gnu_cxx::__scoped_lock l(mx);
func = __unexpected_handler;
#endif
return func;
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/eh_throw.cc
0,0 → 1,126
// -*- C++ -*- Exception handling routines for throwing.
// Copyright (C) 2001-2015 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);
 
#if ATOMIC_INT_LOCK_FREE > 1
if (__atomic_sub_fetch (&header->referenceCount, 1, __ATOMIC_ACQ_REL) == 0)
{
#endif
if (header->exc.exceptionDestructor)
header->exc.exceptionDestructor (header + 1);
 
__cxa_free_exception (header + 1);
#if ATOMIC_INT_LOCK_FREE > 1
}
#endif
}
 
 
extern "C" void
__cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo,
void (_GLIBCXX_CDTOR_CALLABI *dest) (void *))
{
PROBE2 (throw, obj, tinfo);
 
__cxa_eh_globals *globals = __cxa_get_globals ();
globals->uncaughtExceptions += 1;
 
// 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 = std::get_unexpected ();
header->exc.terminateHandler = std::get_terminate ();
__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;
// Only notify probe for C++ exceptions.
PROBE2 (rethrow, __get_object_from_ambiguous_exception(header),
header->exceptionType);
}
 
#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 ();
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/eh_tm.cc
0,0 → 1,126
// -*- C++ -*- Exception handling routines for Transactional Memory.
// Copyright (C) 2009-2015 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;
 
// Free one C++ exception.
 
static void
free_any_cxa_exception (_Unwind_Exception *eo)
{
__cxa_refcounted_exception *h
= __get_refcounted_exception_header_from_ue (eo);
 
if (__is_dependent_exception (eo->exception_class))
{
__cxa_dependent_exception *dep
= __get_dependent_exception_from_ue (eo);
 
h = __get_refcounted_exception_header_from_obj (dep->primaryException);
 
__cxa_free_dependent_exception (dep);
}
 
#if __GCC_ATOMIC_INT_LOCK_FREE > 1
if (__atomic_sub_fetch (&h->referenceCount, 1, __ATOMIC_ACQ_REL) == 0)
#endif
__cxa_free_exception (h + 1);
}
 
// Cleanup exception handling state while rolling back state for
// a software transactional memory transaction.
//
// UNTHROWN_OBJ is non-null if we've called __cxa_allocate_exception
// but not yet called __cxa_throw for it.
//
// CLEANUP_EXC is non-null if we're currently processing a cleanup
// along an exception path, but we've not caught the exception yet.
//
// CAUGHT_COUNT is the nesting depth of __cxa_begin_catch within
// the transaction; undo as if calling __cxa_end_catch that many times.
 
extern "C" void
__cxxabiv1::__cxa_tm_cleanup (void *unthrown_obj,
void *cleanup_exc,
unsigned int caught_count) throw()
{
__cxa_eh_globals *globals = __cxa_get_globals_fast ();
 
// Handle a C++ exception not yet thrown.
if (unthrown_obj)
{
globals->uncaughtExceptions -= 1;
__cxa_free_exception (unthrown_obj);
}
 
// Handle an exception not yet caught ie. processing a cleanup
// in between the throw and the catch.
if (cleanup_exc)
{
_Unwind_Exception *eo
= reinterpret_cast <_Unwind_Exception *>(cleanup_exc);
if (__is_gxx_exception_class (eo->exception_class))
free_any_cxa_exception (eo);
else
_Unwind_DeleteException (eo);
}
 
// Do __cxa_end_catch caught_count times, but don't bother running
// the destructors for the objects involved. All of that is being
// undone by the transaction restart.
if (caught_count > 0)
{
__cxa_exception *h = globals->caughtExceptions;
 
// Rethrown foreign exceptions are removed from the stack immediately.
// We would have freed this exception via THIS_EXC above.
if (h == NULL)
return;
 
do
{
__cxa_exception *next;
_Unwind_Exception *eo = &h->unwindHeader;
 
if (__is_gxx_exception_class (eo->exception_class))
{
next = h->nextException;
free_any_cxa_exception (eo);
}
else
{
_Unwind_DeleteException (eo);
next = 0;
}
 
h = next;
}
while (--caught_count);
 
globals->caughtExceptions = h;
}
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/eh_type.cc
0,0 → 1,54
// -*- C++ -*- Exception handling routines for catching.
// Copyright (C) 2001-2015 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 () _GLIBCXX_NOTHROW
{
__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
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/eh_unex_handler.cc
0,0 → 1,29
// -*- C++ -*- std::unexpected handler
// Copyright (C) 2002-2015 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 "unwind-cxx.h"
 
/* The current installed user handler. */
std::unexpected_handler __cxxabiv1::__unexpected_handler = std::terminate;
 
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/enum_type_info.cc
0,0 → 1,32
// Copyright (C) 1994-2015 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 "tinfo.h"
 
namespace __cxxabiv1 {
 
__enum_type_info::
~__enum_type_info ()
{}
 
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/exception
0,0 → 1,166
// Exception Handling support header for -*- C++ -*-
 
// Copyright (C) 1995-2015 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 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>
#include <bits/atomic_lockfree_defines.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() _GLIBCXX_USE_NOEXCEPT { }
virtual ~exception() _GLIBCXX_USE_NOEXCEPT;
 
/** Returns a C-style character string describing the general cause
* of the current error. */
virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
};
 
/** 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() _GLIBCXX_USE_NOEXCEPT { }
 
// This declaration is not useless:
// http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
virtual ~bad_exception() _GLIBCXX_USE_NOEXCEPT;
 
// See comment in eh_exception.cc.
virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
};
 
/// 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) _GLIBCXX_USE_NOEXCEPT;
 
#if __cplusplus >= 201103L
/// Return the current terminate handler.
terminate_handler get_terminate() noexcept;
#endif
 
/** 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() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__noreturn__));
 
/// Takes a new handler function as an argument, returns the old function.
unexpected_handler set_unexpected(unexpected_handler) _GLIBCXX_USE_NOEXCEPT;
 
#if __cplusplus >= 201103L
/// Return the current unexpected handler.
unexpected_handler get_unexpected() noexcept;
#endif
 
/** 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() _GLIBCXX_USE_NOEXCEPT __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 (__cplusplus >= 201103L) && (ATOMIC_INT_LOCK_FREE > 1)
#include <bits/exception_ptr.h>
#include <bits/nested_exception.h>
#endif
 
#endif
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/exception_defines.h
0,0 → 1,45
// -fno-exceptions Support -*- C++ -*-
 
// Copyright (C) 2001-2015 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
 
#if ! __cpp_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
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/exception_ptr.h
0,0 → 1,205
// Exception Handling support header (exception_ptr class) for -*- C++ -*-
 
// Copyright (C) 2008-2015 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/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 ATOMIC_INT_LOCK_FREE < 2
# error This platform does not support exception propagation.
#endif
 
extern "C++" {
 
namespace std
{
class type_info;
 
/**
* @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() _GLIBCXX_USE_NOEXCEPT;
 
/// 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) _GLIBCXX_USE_NOEXCEPT;
 
void _M_addref() _GLIBCXX_USE_NOEXCEPT;
void _M_release() _GLIBCXX_USE_NOEXCEPT;
 
void *_M_get() const _GLIBCXX_NOEXCEPT __attribute__ ((__pure__));
 
friend exception_ptr std::current_exception() _GLIBCXX_USE_NOEXCEPT;
friend void std::rethrow_exception(exception_ptr);
 
public:
exception_ptr() _GLIBCXX_USE_NOEXCEPT;
 
exception_ptr(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT;
 
#if __cplusplus >= 201103L
exception_ptr(nullptr_t) noexcept
: _M_exception_object(0)
{ }
 
exception_ptr(exception_ptr&& __o) noexcept
: _M_exception_object(__o._M_exception_object)
{ __o._M_exception_object = 0; }
#endif
 
#if (__cplusplus < 201103L) || defined (_GLIBCXX_EH_PTR_COMPAT)
typedef void (exception_ptr::*__safe_bool)();
 
// For construction from nullptr or 0.
exception_ptr(__safe_bool) _GLIBCXX_USE_NOEXCEPT;
#endif
 
exception_ptr&
operator=(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT;
 
#if __cplusplus >= 201103L
exception_ptr&
operator=(exception_ptr&& __o) noexcept
{
exception_ptr(static_cast<exception_ptr&&>(__o)).swap(*this);
return *this;
}
#endif
 
~exception_ptr() _GLIBCXX_USE_NOEXCEPT;
 
void
swap(exception_ptr&) _GLIBCXX_USE_NOEXCEPT;
 
#ifdef _GLIBCXX_EH_PTR_COMPAT
// Retained for compatibility with CXXABI_1.3.
void _M_safe_bool_dummy() _GLIBCXX_USE_NOEXCEPT
__attribute__ ((__const__));
bool operator!() const _GLIBCXX_USE_NOEXCEPT
__attribute__ ((__pure__));
operator __safe_bool() const _GLIBCXX_USE_NOEXCEPT;
#endif
 
#if __cplusplus >= 201103L
explicit operator bool() const
{ return _M_exception_object; }
#endif
 
friend bool
operator==(const exception_ptr&, const exception_ptr&)
_GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__));
 
const class std::type_info*
__cxa_exception_type() const _GLIBCXX_USE_NOEXCEPT
__attribute__ ((__pure__));
};
 
bool
operator==(const exception_ptr&, const exception_ptr&)
_GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__));
 
bool
operator!=(const exception_ptr&, const exception_ptr&)
_GLIBCXX_USE_NOEXCEPT __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
make_exception_ptr(_Ex __ex) _GLIBCXX_USE_NOEXCEPT
{
#if __cpp_exceptions
try
{
throw __ex;
}
catch(...)
{
return current_exception();
}
#else
return exception_ptr();
#endif
}
 
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 1130. copy_exception name misleading
/// Obtain an exception_ptr pointing to a copy of the supplied object.
/// This function is deprecated, use std::make_exception_ptr instead.
template<typename _Ex>
exception_ptr
copy_exception(_Ex __ex) _GLIBCXX_USE_NOEXCEPT _GLIBCXX_DEPRECATED;
 
template<typename _Ex>
exception_ptr
copy_exception(_Ex __ex) _GLIBCXX_USE_NOEXCEPT
{ return std::make_exception_ptr<_Ex>(__ex); }
 
// @} group exceptions
} // namespace std
 
} // extern "C++"
 
#pragma GCC visibility pop
 
#endif
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/function_type_info.cc
0,0 → 1,38
// Copyright (C) 1994-2015 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 "tinfo.h"
 
namespace __cxxabiv1 {
 
__function_type_info::
~__function_type_info ()
{}
 
bool __function_type_info::
__is_function_p () const
{
return true;
}
 
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/fundamental_type_info.cc
0,0 → 1,35
// Copyright (C) 1994-2015 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 "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 ()
{}
 
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/gthr-default.h
0,0 → 1,772
/* Threads compatibility routines for libgcc2 and libobjc. */
/* Compile this one with gcc. */
 
/* Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2008, 2009
Free Software Foundation, Inc.
Contributed by Mumit Khan <khan@xraylith.wisc.edu>.
 
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/>. */
 
#ifndef GCC_GTHR_WIN32_H
#define GCC_GTHR_WIN32_H
 
/* Make sure CONST_CAST2 (origin in system.h) is declared. */
#ifndef CONST_CAST2
#define CONST_CAST2(TOTYPE,FROMTYPE,X) ((__extension__(union {FROMTYPE _q; TOTYPE _nq;})(X))._nq)
#endif
 
/* Windows32 threads specific definitions. The windows32 threading model
does not map well into pthread-inspired gcc's threading model, and so
there are caveats one needs to be aware of.
 
1. The destructor supplied to __gthread_key_create is ignored for
generic x86-win32 ports. This will certainly cause memory leaks
due to unreclaimed eh contexts (sizeof (eh_context) is at least
24 bytes for x86 currently).
 
This memory leak may be significant for long-running applications
that make heavy use of C++ EH.
 
However, Mingw runtime (version 0.3 or newer) provides a mechanism
to emulate pthreads key dtors; the runtime provides a special DLL,
linked in if -mthreads option is specified, that runs the dtors in
the reverse order of registration when each thread exits. If
-mthreads option is not given, a stub is linked in instead of the
DLL, which results in memory leak. Other x86-win32 ports can use
the same technique of course to avoid the leak.
 
2. The error codes returned are non-POSIX like, and cast into ints.
This may cause incorrect error return due to truncation values on
hw where sizeof (DWORD) > sizeof (int).
 
3. We are currently using a special mutex instead of the Critical
Sections, since Win9x does not support TryEnterCriticalSection
(while NT does).
 
The basic framework should work well enough. In the long term, GCC
needs to use Structured Exception Handling on Windows32. */
 
#define __GTHREADS 1
 
#include <errno.h>
#ifdef __MINGW32__
#include <_mingw.h>
#endif
 
#ifndef __UNUSED_PARAM
#define __UNUSED_PARAM(x) x
#endif
 
#ifdef _LIBOBJC
 
/* This is necessary to prevent windef.h (included from windows.h) from
defining its own BOOL as a typedef. */
#ifndef __OBJC__
#define __OBJC__
#endif
#include <windows.h>
/* Now undef the windows BOOL. */
#undef BOOL
 
/* Key structure for maintaining thread specific storage */
static DWORD __gthread_objc_data_tls = (DWORD) -1;
 
/* Backend initialization functions */
 
/* Initialize the threads subsystem. */
int
__gthread_objc_init_thread_system (void)
{
/* Initialize the thread storage key. */
if ((__gthread_objc_data_tls = TlsAlloc ()) != (DWORD) -1)
return 0;
else
return -1;
}
 
/* Close the threads subsystem. */
int
__gthread_objc_close_thread_system (void)
{
if (__gthread_objc_data_tls != (DWORD) -1)
TlsFree (__gthread_objc_data_tls);
return 0;
}
 
/* Backend thread functions */
 
/* Create a new thread of execution. */
objc_thread_t
__gthread_objc_thread_detach (void (*func)(void *arg), void *arg)
{
DWORD thread_id = 0;
HANDLE win32_handle;
 
if (!(win32_handle = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) func,
arg, 0, &thread_id)))
thread_id = 0;
 
return (objc_thread_t) (INT_PTR) thread_id;
}
 
/* Set the current thread's priority. */
int
__gthread_objc_thread_set_priority (int priority)
{
int sys_priority = 0;
 
switch (priority)
{
case OBJC_THREAD_INTERACTIVE_PRIORITY:
sys_priority = THREAD_PRIORITY_NORMAL;
break;
default:
case OBJC_THREAD_BACKGROUND_PRIORITY:
sys_priority = THREAD_PRIORITY_BELOW_NORMAL;
break;
case OBJC_THREAD_LOW_PRIORITY:
sys_priority = THREAD_PRIORITY_LOWEST;
break;
}
 
/* Change priority */
if (SetThreadPriority (GetCurrentThread (), sys_priority))
return 0;
else
return -1;
}
 
/* Return the current thread's priority. */
int
__gthread_objc_thread_get_priority (void)
{
int sys_priority;
 
sys_priority = GetThreadPriority (GetCurrentThread ());
 
switch (sys_priority)
{
case THREAD_PRIORITY_HIGHEST:
case THREAD_PRIORITY_TIME_CRITICAL:
case THREAD_PRIORITY_ABOVE_NORMAL:
case THREAD_PRIORITY_NORMAL:
return OBJC_THREAD_INTERACTIVE_PRIORITY;
 
default:
case THREAD_PRIORITY_BELOW_NORMAL:
return OBJC_THREAD_BACKGROUND_PRIORITY;
 
case THREAD_PRIORITY_IDLE:
case THREAD_PRIORITY_LOWEST:
return OBJC_THREAD_LOW_PRIORITY;
}
 
/* Couldn't get priority. */
return -1;
}
 
/* Yield our process time to another thread. */
void
__gthread_objc_thread_yield (void)
{
Sleep (0);
}
 
/* Terminate the current thread. */
int
__gthread_objc_thread_exit (void)
{
/* exit the thread */
ExitThread (__objc_thread_exit_status);
 
/* Failed if we reached here */
return -1;
}
 
/* Returns an integer value which uniquely describes a thread. */
objc_thread_t
__gthread_objc_thread_id (void)
{
return (objc_thread_t) (INT_PTR) GetCurrentThreadId ();
}
 
/* Sets the thread's local storage pointer. */
int
__gthread_objc_thread_set_data (void *value)
{
if (TlsSetValue (__gthread_objc_data_tls, value))
return 0;
else
return -1;
}
 
/* Returns the thread's local storage pointer. */
void *
__gthread_objc_thread_get_data (void)
{
DWORD lasterror;
void *ptr;
 
lasterror = GetLastError ();
 
ptr = TlsGetValue (__gthread_objc_data_tls); /* Return thread data. */
 
SetLastError (lasterror);
 
return ptr;
}
 
/* Backend mutex functions */
 
/* Allocate a mutex. */
int
__gthread_objc_mutex_allocate (objc_mutex_t mutex)
{
if ((mutex->backend = (void *) CreateMutex (NULL, 0, NULL)) == NULL)
return -1;
else
return 0;
}
 
/* Deallocate a mutex. */
int
__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
{
CloseHandle ((HANDLE) (mutex->backend));
return 0;
}
 
/* Grab a lock on a mutex. */
int
__gthread_objc_mutex_lock (objc_mutex_t mutex)
{
int status;
 
status = WaitForSingleObject ((HANDLE) (mutex->backend), INFINITE);
if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED)
return -1;
else
return 0;
}
 
/* Try to grab a lock on a mutex. */
int
__gthread_objc_mutex_trylock (objc_mutex_t mutex)
{
int status;
 
status = WaitForSingleObject ((HANDLE) (mutex->backend), 0);
if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED)
return -1;
else
return 0;
}
 
/* Unlock the mutex */
int
__gthread_objc_mutex_unlock (objc_mutex_t mutex)
{
if (ReleaseMutex ((HANDLE) (mutex->backend)) == 0)
return -1;
else
return 0;
}
 
/* Backend condition mutex functions */
 
/* Allocate a condition. */
int
__gthread_objc_condition_allocate (objc_condition_t __UNUSED_PARAM(condition))
{
/* Unimplemented. */
return -1;
}
 
/* Deallocate a condition. */
int
__gthread_objc_condition_deallocate (objc_condition_t __UNUSED_PARAM(condition))
{
/* Unimplemented. */
return -1;
}
 
/* Wait on the condition */
int
__gthread_objc_condition_wait (objc_condition_t __UNUSED_PARAM(condition),
objc_mutex_t __UNUSED_PARAM(mutex))
{
/* Unimplemented. */
return -1;
}
 
/* Wake up all threads waiting on this condition. */
int
__gthread_objc_condition_broadcast (objc_condition_t __UNUSED_PARAM(condition))
{
/* Unimplemented. */
return -1;
}
 
/* Wake up one thread waiting on this condition. */
int
__gthread_objc_condition_signal (objc_condition_t __UNUSED_PARAM(condition))
{
/* Unimplemented. */
return -1;
}
 
#else /* _LIBOBJC */
 
#ifdef __cplusplus
extern "C" {
#endif
 
typedef unsigned long __gthread_key_t;
 
typedef struct {
int done;
long started;
} __gthread_once_t;
 
typedef struct {
long counter;
void *sema;
} __gthread_mutex_t;
 
typedef struct {
long counter;
long depth;
unsigned long owner;
void *sema;
} __gthread_recursive_mutex_t;
 
#define __GTHREAD_ONCE_INIT {0, -1}
#define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
#define __GTHREAD_MUTEX_INIT_DEFAULT {-1, 0}
#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION \
__gthread_recursive_mutex_init_function
#define __GTHREAD_RECURSIVE_MUTEX_INIT_DEFAULT {-1, 0, 0, 0}
 
#if defined (_WIN32) && !defined(__CYGWIN__)
#define MINGW32_SUPPORTS_MT_EH 1
/* Mingw runtime >= v0.3 provides a magic variable that is set to nonzero
if -mthreads option was specified, or 0 otherwise. This is to get around
the lack of weak symbols in PE-COFF. */
extern int _CRT_MT;
extern int __mingwthr_key_dtor (unsigned long, void (*) (void *));
#endif /* _WIN32 && !__CYGWIN__ */
 
/* The Windows95 kernel does not export InterlockedCompareExchange.
This provides a substitute. When building apps that reference
gthread_mutex_try_lock, the __GTHREAD_I486_INLINE_LOCK_PRIMITIVES
macro must be defined if Windows95 is a target. Currently
gthread_mutex_try_lock is not referenced by libgcc or libstdc++. */
#ifdef __GTHREAD_I486_INLINE_LOCK_PRIMITIVES
static inline long
__gthr_i486_lock_cmp_xchg(long *__dest, long __xchg, long __comperand)
{
long result;
__asm__ __volatile__ ("\n\
lock\n\
cmpxchg{l} {%4, %1|%1, %4}\n"
: "=a" (result), "=m" (*__dest)
: "0" (__comperand), "m" (*__dest), "r" (__xchg)
: "cc");
return result;
}
#define __GTHR_W32_InterlockedCompareExchange __gthr_i486_lock_cmp_xchg
#else /* __GTHREAD_I486_INLINE_LOCK_PRIMITIVES */
#define __GTHR_W32_InterlockedCompareExchange InterlockedCompareExchange
#endif /* __GTHREAD_I486_INLINE_LOCK_PRIMITIVES */
 
static inline int
__gthread_active_p (void)
{
#ifdef MINGW32_SUPPORTS_MT_EH
return _CRT_MT;
#else
return 1;
#endif
}
 
#if __GTHREAD_HIDE_WIN32API
 
/* The implementations are in config/i386/gthr-win32.c in libgcc.a.
Only stubs are exposed to avoid polluting the C++ namespace with
windows api definitions. */
 
extern int __gthr_win32_once (__gthread_once_t *, void (*) (void));
extern int __gthr_win32_key_create (__gthread_key_t *, void (*) (void*));
extern int __gthr_win32_key_delete (__gthread_key_t);
extern void * __gthr_win32_getspecific (__gthread_key_t);
extern int __gthr_win32_setspecific (__gthread_key_t, const void *);
extern void __gthr_win32_mutex_init_function (__gthread_mutex_t *);
extern int __gthr_win32_mutex_lock (__gthread_mutex_t *);
extern int __gthr_win32_mutex_trylock (__gthread_mutex_t *);
extern int __gthr_win32_mutex_unlock (__gthread_mutex_t *);
extern void
__gthr_win32_recursive_mutex_init_function (__gthread_recursive_mutex_t *);
extern int __gthr_win32_recursive_mutex_lock (__gthread_recursive_mutex_t *);
extern int
__gthr_win32_recursive_mutex_trylock (__gthread_recursive_mutex_t *);
extern int __gthr_win32_recursive_mutex_unlock (__gthread_recursive_mutex_t *);
extern void __gthr_win32_mutex_destroy (__gthread_mutex_t *);
 
static inline int
__gthread_once (__gthread_once_t *__once, void (*__func) (void))
{
if (__gthread_active_p ())
return __gthr_win32_once (__once, __func);
else
return -1;
}
 
static inline int
__gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
{
return __gthr_win32_key_create (__key, __dtor);
}
 
static inline int
__gthread_key_delete (__gthread_key_t __key)
{
return __gthr_win32_key_delete (__key);
}
 
static inline void *
__gthread_getspecific (__gthread_key_t __key)
{
return __gthr_win32_getspecific (__key);
}
 
static inline int
__gthread_setspecific (__gthread_key_t __key, const void *__ptr)
{
return __gthr_win32_setspecific (__key, __ptr);
}
 
static inline void
__gthread_mutex_init_function (__gthread_mutex_t *__mutex)
{
__gthr_win32_mutex_init_function (__mutex);
}
 
static inline void
__gthread_mutex_destroy (__gthread_mutex_t *__mutex)
{
__gthr_win32_mutex_destroy (__mutex);
}
 
static inline int
__gthread_mutex_lock (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
return __gthr_win32_mutex_lock (__mutex);
else
return 0;
}
 
static inline int
__gthread_mutex_trylock (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
return __gthr_win32_mutex_trylock (__mutex);
else
return 0;
}
 
static inline int
__gthread_mutex_unlock (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
return __gthr_win32_mutex_unlock (__mutex);
else
return 0;
}
 
static inline void
__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
{
__gthr_win32_recursive_mutex_init_function (__mutex);
}
 
static inline int
__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
{
if (__gthread_active_p ())
return __gthr_win32_recursive_mutex_lock (__mutex);
else
return 0;
}
 
static inline int
__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
{
if (__gthread_active_p ())
return __gthr_win32_recursive_mutex_trylock (__mutex);
else
return 0;
}
 
static inline int
__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
{
if (__gthread_active_p ())
return __gthr_win32_recursive_mutex_unlock (__mutex);
else
return 0;
}
 
#else /* ! __GTHREAD_HIDE_WIN32API */
 
#include <windows.h>
#include <errno.h>
 
static inline int
__gthread_once (__gthread_once_t *__once, void (*__func) (void))
{
if (! __gthread_active_p ())
return -1;
else if (__once == NULL || __func == NULL)
return EINVAL;
 
if (! __once->done)
{
if (InterlockedIncrement (&(__once->started)) == 0)
{
(*__func) ();
__once->done = TRUE;
}
else
{
/* Another thread is currently executing the code, so wait for it
to finish; yield the CPU in the meantime. If performance
does become an issue, the solution is to use an Event that
we wait on here (and set above), but that implies a place to
create the event before this routine is called. */
while (! __once->done)
Sleep (0);
}
}
 
return 0;
}
 
/* Windows32 thread local keys don't support destructors; this leads to
leaks, especially in threaded applications making extensive use of
C++ EH. Mingw uses a thread-support DLL to work-around this problem. */
static inline int
__gthread_key_create (__gthread_key_t *__key,
void (*__dtor) (void *) __attribute__((unused)))
{
int __status = 0;
DWORD __tls_index = TlsAlloc ();
if (__tls_index != 0xFFFFFFFF)
{
*__key = __tls_index;
#ifdef MINGW32_SUPPORTS_MT_EH
/* Mingw runtime will run the dtors in reverse order for each thread
when the thread exits. */
__status = __mingwthr_key_dtor (*__key, __dtor);
#endif
}
else
__status = (int) GetLastError ();
return __status;
}
 
static inline int
__gthread_key_delete (__gthread_key_t __key)
{
return (TlsFree (__key) != 0) ? 0 : (int) GetLastError ();
}
 
static inline void *
__gthread_getspecific (__gthread_key_t __key)
{
DWORD __lasterror;
void *__ptr;
 
__lasterror = GetLastError ();
 
__ptr = TlsGetValue (__key);
 
SetLastError (__lasterror);
 
return __ptr;
}
 
static inline int
__gthread_setspecific (__gthread_key_t __key, const void *__ptr)
{
if (TlsSetValue (__key, CONST_CAST2(void *, const void *, __ptr)) != 0)
return 0;
else
return GetLastError ();
}
 
static inline void
__gthread_mutex_init_function (__gthread_mutex_t *__mutex)
{
__mutex->counter = -1;
__mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL);
}
 
static inline void
__gthread_mutex_destroy (__gthread_mutex_t *__mutex)
{
CloseHandle ((HANDLE) __mutex->sema);
}
 
static inline int
__gthread_mutex_lock (__gthread_mutex_t *__mutex)
{
int __status = 0;
 
if (__gthread_active_p ())
{
if (InterlockedIncrement (&__mutex->counter) == 0 ||
WaitForSingleObject (__mutex->sema, INFINITE) == WAIT_OBJECT_0)
__status = 0;
else
{
/* WaitForSingleObject returns WAIT_FAILED, and we can only do
some best-effort cleanup here. */
InterlockedDecrement (&__mutex->counter);
__status = 1;
}
}
return __status;
}
 
static inline int
__gthread_mutex_trylock (__gthread_mutex_t *__mutex)
{
int __status = 0;
 
if (__gthread_active_p ())
{
if (__GTHR_W32_InterlockedCompareExchange (&__mutex->counter, 0, -1) < 0)
__status = 0;
else
__status = 1;
}
return __status;
}
 
static inline int
__gthread_mutex_unlock (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
{
if (InterlockedDecrement (&__mutex->counter) >= 0)
return ReleaseSemaphore (__mutex->sema, 1, NULL) ? 0 : 1;
}
return 0;
}
 
static inline void
__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
{
__mutex->counter = -1;
__mutex->depth = 0;
__mutex->owner = 0;
__mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL);
}
 
static inline int
__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
{
if (__gthread_active_p ())
{
DWORD __me = GetCurrentThreadId();
if (InterlockedIncrement (&__mutex->counter) == 0)
{
__mutex->depth = 1;
__mutex->owner = __me;
}
else if (__mutex->owner == __me)
{
InterlockedDecrement (&__mutex->counter);
++(__mutex->depth);
}
else if (WaitForSingleObject (__mutex->sema, INFINITE) == WAIT_OBJECT_0)
{
__mutex->depth = 1;
__mutex->owner = __me;
}
else
{
/* WaitForSingleObject returns WAIT_FAILED, and we can only do
some best-effort cleanup here. */
InterlockedDecrement (&__mutex->counter);
return 1;
}
}
return 0;
}
 
static inline int
__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
{
if (__gthread_active_p ())
{
DWORD __me = GetCurrentThreadId();
if (__GTHR_W32_InterlockedCompareExchange (&__mutex->counter, 0, -1) < 0)
{
__mutex->depth = 1;
__mutex->owner = __me;
}
else if (__mutex->owner == __me)
++(__mutex->depth);
else
return 1;
}
return 0;
}
 
static inline int
__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
{
if (__gthread_active_p ())
{
--(__mutex->depth);
if (__mutex->depth == 0)
{
__mutex->owner = 0;
 
if (InterlockedDecrement (&__mutex->counter) >= 0)
return ReleaseSemaphore (__mutex->sema, 1, NULL) ? 0 : 1;
}
}
return 0;
}
 
#endif /* __GTHREAD_HIDE_WIN32API */
 
#ifdef __cplusplus
}
#endif
 
#endif /* _LIBOBJC */
 
#endif /* ! GCC_GTHR_WIN32_H */
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/gthr_mutex.c
0,0 → 1,150
#include <stdlib.h>
#include <sys/errno.h>
#include <kos32sys.h>
 
void __mutex_lock(volatile int *val);
 
static inline int tls_get(int key)
{
int val;
__asm__ __volatile__(
"movl %%fs:(%1), %0"
:"=r"(val)
:"r"(key));
 
return val;
};
 
typedef struct {
int done;
long started;
} __gthread_once_t;
 
typedef struct {
int counter;
void *sema;
} __gthread_mutex_t;
 
typedef struct {
int counter;
int depth;
unsigned long owner;
int sema;
} __gthread_recursive_mutex_t;
 
 
int
__gthr_win32_once (__gthread_once_t *once, void (*func) (void))
{
if (once == NULL || func == NULL)
return EINVAL;
 
if (! once->done)
{
if (__sync_add_and_fetch (&(once->started), 1) == 0)
{
(*func) ();
once->done = 1;
}
else
{
/* Another thread is currently executing the code, so wait for it
to finish; yield the CPU in the meantime. If performance
does become an issue, the solution is to use an Event that
we wait on here (and set above), but that implies a place to
create the event before this routine is called. */
while (! once->done)
delay(1);
}
}
return 0;
}
 
void __gthr_win32_mutex_init_function (__gthread_mutex_t *mutex)
{
mutex->counter = 0;
mutex->sema = 0;
}
 
int __gthr_win32_mutex_lock (__gthread_mutex_t *mutex)
{
__mutex_lock(&mutex->counter);
return 0;
}
 
int
__gthr_win32_mutex_unlock (__gthread_mutex_t *mutex)
{
mutex->counter = 0;
return 0;
}
 
void
__gthr_win32_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
{
mutex->counter = -1;
mutex->depth = 0;
mutex->owner = 0;
mutex->sema = 0;
}
 
void
__gthr_win32_mutex_destroy (__gthread_mutex_t *mutex)
{ }
 
int
__gthr_win32_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
{
int me = tls_get(0);
if ( __sync_add_and_fetch(&mutex->counter, 1) == 0)
{
mutex->depth = 1;
mutex->owner = me;
mutex->sema = 1;
}
else if (mutex->owner == me)
{
__sync_sub_and_fetch(&mutex->counter, 1);
++(mutex->depth);
}
else
{
__mutex_lock(&mutex->sema);
mutex->depth = 1;
mutex->owner = me;
}
return 0;
}
 
int
__gthr_win32_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
{
int me = tls_get(0);
if (__sync_val_compare_and_swap (&mutex->counter, -1, 0) < 0)
{
mutex->depth = 1;
mutex->owner = me;
mutex->sema = 1;
}
else if (mutex->owner == me)
++(mutex->depth);
else
return 1;
 
return 0;
}
 
int
__gthr_win32_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
{
--(mutex->depth);
if (mutex->depth == 0)
{
mutex->owner = 0;
 
if (__sync_sub_and_fetch (&mutex->counter, 1) >= 0)
mutex->sema = 0;
}
 
return 0;
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/guard.cc
0,0 → 1,415
// Copyright (C) 2002-2015 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) \
&& (ATOMIC_INT_LOCK_FREE > 1) && defined(_GLIBCXX_HAVE_LINUX_FUTEX)
# include <climits>
# include <syscall.h>
# include <unistd.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 condition 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 initialization 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
// initialization 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 acquire 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. However,
// we need to use the POSIX thread condition 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 condition variables. For platforms that do not support condition
// variables, we need to fall back to the old code.
 
// If _GLIBCXX_USE_FUTEX, no global mutex or condition 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()
{
#if __cpp_exceptions
throw __gnu_cxx::recursive_init_error();
#else
// Use __builtin_trap so we don't require abort().
__builtin_trap();
#endif
}
 
// acquire() 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 __atomic_* 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 expected(0);
if (__atomic_compare_exchange_n(gi, &expected, pending_bit, false,
__ATOMIC_ACQ_REL,
__ATOMIC_ACQUIRE))
{
// This thread should do the initialization.
return 1;
}
if (expected == guard_bit)
{
// Already initialized.
return 0;
}
 
if (expected == pending_bit)
{
// Use acquire here.
int newv = expected | waiting_bit;
if (!__atomic_compare_exchange_n(gi, &expected, newv, false,
__ATOMIC_ACQ_REL,
__ATOMIC_ACQUIRE))
{
if (expected == guard_bit)
{
// Make a thread that failed to set the
// waiting bit exit the function earlier,
// if it detects that another thread has
// successfully finished initialising.
return 0;
}
if (expected == 0)
continue;
}
expected = newv;
}
 
syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAIT, expected, 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
// condition 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 condition 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 __atomic_* 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 = __atomic_exchange_n (gi, 0, __ATOMIC_ACQ_REL);
 
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 condition 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
// condition variables.
if (__gthread_active_p ())
static_mutex->unlock();
#endif
}
 
extern "C"
void __cxa_guard_release (__guard *g) throw ()
{
#ifdef _GLIBCXX_USE_FUTEX
// If __atomic_* 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 = __atomic_exchange_n (gi, guard_bit, __ATOMIC_ACQ_REL);
 
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
// condition variables.
if (__gthread_active_p())
static_mutex->unlock();
#endif
}
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/guard_error.cc
0,0 → 1,31
// Copyright (C) 2011-2015 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() { }
}
 
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/hash_bytes.cc
0,0 → 1,190
// Definition of _Hash_bytes. -*- C++ -*-
 
// Copyright (C) 2010-2015 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 = (((size_t) 0xc6a4a793UL) << 32UL)
+ (size_t) 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
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/hash_bytes.h
0,0 → 1,59
// Declarations for hash functions. -*- C++ -*-
 
// Copyright (C) 2010-2015 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
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/initializer_list
0,0 → 1,107
// std::initializer_list support -*- C++ -*-
 
// Copyright (C) 2008-2015 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
 
#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else // C++0x
 
#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() noexcept
: _M_array(0), _M_len(0) { }
 
// Number of elements.
constexpr size_type
size() const noexcept { return _M_len; }
 
// First element.
constexpr const_iterator
begin() const noexcept { return _M_array; }
 
// One past the last element.
constexpr const_iterator
end() const noexcept { return begin() + size(); }
};
 
/**
* @brief Return an iterator pointing to the first element of
* the initializer_list.
* @param __ils Initializer list.
*/
template<class _Tp>
constexpr const _Tp*
begin(initializer_list<_Tp> __ils) noexcept
{ return __ils.begin(); }
 
/**
* @brief Return an iterator pointing to one past the last element
* of the initializer_list.
* @param __ils Initializer list.
*/
template<class _Tp>
constexpr const _Tp*
end(initializer_list<_Tp> __ils) noexcept
{ return __ils.end(); }
}
 
#pragma GCC visibility pop
 
#endif // C++11
 
#endif // _INITIALIZER_LIST
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/libiberty.h
0,0 → 1,686
/* Function declarations for libiberty.
 
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
Note - certain prototypes declared in this header file are for
functions whoes implementation copyright does not belong to the
FSF. Those prototypes are present in this file for reference
purposes only and their presence in this file should not construed
as an indication of ownership by the FSF of the implementation of
those functions in any way or form whatsoever.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA.
Written by Cygnus Support, 1994.
 
The libiberty library provides a number of functions which are
missing on some operating systems. We do not declare those here,
to avoid conflicts with the system header files on operating
systems that do support those functions. In this file we only
declare those functions which are specific to libiberty. */
 
#ifndef LIBIBERTY_H
#define LIBIBERTY_H
 
#ifdef __cplusplus
extern "C" {
#endif
 
#include "ansidecl.h"
 
/* Get a definition for size_t. */
#include <stddef.h>
/* Get a definition for va_list. */
#include <stdarg.h>
 
#include <stdio.h>
 
/* If the OS supports it, ensure that the supplied stream is setup to
avoid any multi-threaded locking. Otherwise leave the FILE pointer
unchanged. If the stream is NULL do nothing. */
 
extern void unlock_stream (FILE *);
 
/* If the OS supports it, ensure that the standard I/O streams, stdin,
stdout and stderr are setup to avoid any multi-threaded locking.
Otherwise do nothing. */
 
extern void unlock_std_streams (void);
 
/* Open and return a FILE pointer. If the OS supports it, ensure that
the stream is setup to avoid any multi-threaded locking. Otherwise
return the FILE pointer unchanged. */
 
extern FILE *fopen_unlocked (const char *, const char *);
extern FILE *fdopen_unlocked (int, const char *);
extern FILE *freopen_unlocked (const char *, const char *, FILE *);
 
/* Build an argument vector from a string. Allocates memory using
malloc. Use freeargv to free the vector. */
 
extern char **buildargv (const char *) ATTRIBUTE_MALLOC;
 
/* Free a vector returned by buildargv. */
 
extern void freeargv (char **);
 
/* Duplicate an argument vector. Allocates memory using malloc. Use
freeargv to free the vector. */
 
extern char **dupargv (char **) ATTRIBUTE_MALLOC;
 
/* Expand "@file" arguments in argv. */
 
extern void expandargv (int *, char ***);
 
/* Write argv to an @-file, inserting necessary quoting. */
 
extern int writeargv (char **, FILE *);
 
/* Return the number of elements in argv. */
 
extern int countargv (char**);
 
/* Return the last component of a path name. Note that we can't use a
prototype here because the parameter is declared inconsistently
across different systems, sometimes as "char *" and sometimes as
"const char *" */
 
/* HAVE_DECL_* is a three-state macro: undefined, 0 or 1. If it is
undefined, we haven't run the autoconf check so provide the
declaration without arguments. If it is 0, we checked and failed
to find the declaration so provide a fully prototyped one. If it
is 1, we found it so don't provide any declaration at all. */
#if !HAVE_DECL_BASENAME
#if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__) || defined (__CYGWIN__) || defined (__CYGWIN32__) || defined (__MINGW32__) || defined (HAVE_DECL_BASENAME)
extern char *basename (const char *);
#else
/* Do not allow basename to be used if there is no prototype seen. We
either need to use the above prototype or have one from
autoconf which would result in HAVE_DECL_BASENAME being set. */
#define basename basename_cannot_be_used_without_a_prototype
#endif
#endif
 
/* A well-defined basename () that is always compiled in. */
 
extern const char *lbasename (const char *);
 
/* Same, but assumes DOS semantics (drive name, backslash is also a
dir separator) regardless of host. */
 
extern const char *dos_lbasename (const char *);
 
/* Same, but assumes Unix semantics (absolute paths always start with
a slash, only forward slash is accepted as dir separator)
regardless of host. */
 
extern const char *unix_lbasename (const char *);
 
/* A well-defined realpath () that is always compiled in. */
 
extern char *lrealpath (const char *);
 
/* Concatenate an arbitrary number of strings. You must pass NULL as
the last argument of this function, to terminate the list of
strings. Allocates memory using xmalloc. */
 
extern char *concat (const char *, ...) ATTRIBUTE_MALLOC ATTRIBUTE_SENTINEL;
 
/* Concatenate an arbitrary number of strings. You must pass NULL as
the last argument of this function, to terminate the list of
strings. Allocates memory using xmalloc. The first argument is
not one of the strings to be concatenated, but if not NULL is a
pointer to be freed after the new string is created, similar to the
way xrealloc works. */
 
extern char *reconcat (char *, const char *, ...) ATTRIBUTE_MALLOC ATTRIBUTE_SENTINEL;
 
/* Determine the length of concatenating an arbitrary number of
strings. You must pass NULL as the last argument of this function,
to terminate the list of strings. */
 
extern unsigned long concat_length (const char *, ...) ATTRIBUTE_SENTINEL;
 
/* Concatenate an arbitrary number of strings into a SUPPLIED area of
memory. You must pass NULL as the last argument of this function,
to terminate the list of strings. The supplied memory is assumed
to be large enough. */
 
extern char *concat_copy (char *, const char *, ...) ATTRIBUTE_SENTINEL;
 
/* Concatenate an arbitrary number of strings into a GLOBAL area of
memory. You must pass NULL as the last argument of this function,
to terminate the list of strings. The supplied memory is assumed
to be large enough. */
 
extern char *concat_copy2 (const char *, ...) ATTRIBUTE_SENTINEL;
 
/* This is the global area used by concat_copy2. */
 
extern char *libiberty_concat_ptr;
 
/* Concatenate an arbitrary number of strings. You must pass NULL as
the last argument of this function, to terminate the list of
strings. Allocates memory using alloca. The arguments are
evaluated twice! */
#define ACONCAT(ACONCAT_PARAMS) \
(libiberty_concat_ptr = (char *) alloca (concat_length ACONCAT_PARAMS + 1), \
concat_copy2 ACONCAT_PARAMS)
 
/* Check whether two file descriptors refer to the same file. */
 
extern int fdmatch (int fd1, int fd2);
 
/* Return the position of the first bit set in the argument. */
/* Prototypes vary from system to system, so we only provide a
prototype on systems where we know that we need it. */
#if defined (HAVE_DECL_FFS) && !HAVE_DECL_FFS
extern int ffs(int);
#endif
 
/* Get the working directory. The result is cached, so don't call
chdir() between calls to getpwd(). */
 
extern char * getpwd (void);
 
/* Get the current time. */
/* Prototypes vary from system to system, so we only provide a
prototype on systems where we know that we need it. */
#ifdef __MINGW32__
/* Forward declaration to avoid #include <sys/time.h>. */
struct timeval;
extern int gettimeofday (struct timeval *, void *);
#endif
 
/* Get the amount of time the process has run, in microseconds. */
 
extern long get_run_time (void);
 
/* Generate a relocated path to some installation directory. Allocates
return value using malloc. */
 
extern char *make_relative_prefix (const char *, const char *,
const char *) ATTRIBUTE_MALLOC;
 
/* Generate a relocated path to some installation directory without
attempting to follow any soft links. Allocates
return value using malloc. */
 
extern char *make_relative_prefix_ignore_links (const char *, const char *,
const char *) ATTRIBUTE_MALLOC;
 
/* Choose a temporary directory to use for scratch files. */
 
extern char *choose_temp_base (void) ATTRIBUTE_MALLOC;
 
/* Return a temporary file name or NULL if unable to create one. */
 
extern char *make_temp_file (const char *) ATTRIBUTE_MALLOC;
 
/* Remove a link to a file unless it is special. */
 
extern int unlink_if_ordinary (const char *);
 
/* Allocate memory filled with spaces. Allocates using malloc. */
 
extern const char *spaces (int count);
 
/* Return the maximum error number for which strerror will return a
string. */
 
extern int errno_max (void);
 
/* Return the name of an errno value (e.g., strerrno (EINVAL) returns
"EINVAL"). */
 
extern const char *strerrno (int);
 
/* Given the name of an errno value, return the value. */
 
extern int strtoerrno (const char *);
 
/* ANSI's strerror(), but more robust. */
 
extern char *xstrerror (int);
 
/* Return the maximum signal number for which strsignal will return a
string. */
 
extern int signo_max (void);
 
/* Return a signal message string for a signal number
(e.g., strsignal (SIGHUP) returns something like "Hangup"). */
/* This is commented out as it can conflict with one in system headers.
We still document its existence though. */
 
/*extern const char *strsignal (int);*/
 
/* Return the name of a signal number (e.g., strsigno (SIGHUP) returns
"SIGHUP"). */
 
extern const char *strsigno (int);
 
/* Given the name of a signal, return its number. */
 
extern int strtosigno (const char *);
 
/* Register a function to be run by xexit. Returns 0 on success. */
 
extern int xatexit (void (*fn) (void));
 
/* Exit, calling all the functions registered with xatexit. */
 
extern void xexit (int status) ATTRIBUTE_NORETURN;
 
/* Set the program name used by xmalloc. */
 
extern void xmalloc_set_program_name (const char *);
 
/* Report an allocation failure. */
extern void xmalloc_failed (size_t) ATTRIBUTE_NORETURN;
 
/* Allocate memory without fail. If malloc fails, this will print a
message to stderr (using the name set by xmalloc_set_program_name,
if any) and then call xexit. */
 
extern void *xmalloc (size_t) ATTRIBUTE_MALLOC;
 
/* Reallocate memory without fail. This works like xmalloc. Note,
realloc type functions are not suitable for attribute malloc since
they may return the same address across multiple calls. */
 
extern void *xrealloc (void *, size_t);
 
/* Allocate memory without fail and set it to zero. This works like
xmalloc. */
 
extern void *xcalloc (size_t, size_t) ATTRIBUTE_MALLOC;
 
/* Copy a string into a memory buffer without fail. */
 
extern char *xstrdup (const char *) ATTRIBUTE_MALLOC;
 
/* Copy at most N characters from string into a buffer without fail. */
 
extern char *xstrndup (const char *, size_t) ATTRIBUTE_MALLOC;
 
/* Copy an existing memory buffer to a new memory buffer without fail. */
 
extern void *xmemdup (const void *, size_t, size_t) ATTRIBUTE_MALLOC;
 
/* Physical memory routines. Return values are in BYTES. */
extern double physmem_total (void);
extern double physmem_available (void);
 
/* Compute the 32-bit CRC of a block of memory. */
extern unsigned int xcrc32 (const unsigned char *, int, unsigned int);
 
/* These macros provide a K&R/C89/C++-friendly way of allocating structures
with nice encapsulation. The XDELETE*() macros are technically
superfluous, but provided here for symmetry. Using them consistently
makes it easier to update client code to use different allocators such
as new/delete and new[]/delete[]. */
 
/* Scalar allocators. */
 
#define XALLOCA(T) ((T *) alloca (sizeof (T)))
#define XNEW(T) ((T *) xmalloc (sizeof (T)))
#define XCNEW(T) ((T *) xcalloc (1, sizeof (T)))
#define XDUP(T, P) ((T *) xmemdup ((P), sizeof (T), sizeof (T)))
#define XDELETE(P) free ((void*) (P))
 
/* Array allocators. */
 
#define XALLOCAVEC(T, N) ((T *) alloca (sizeof (T) * (N)))
#define XNEWVEC(T, N) ((T *) xmalloc (sizeof (T) * (N)))
#define XCNEWVEC(T, N) ((T *) xcalloc ((N), sizeof (T)))
#define XDUPVEC(T, P, N) ((T *) xmemdup ((P), sizeof (T) * (N), sizeof (T) * (N)))
#define XRESIZEVEC(T, P, N) ((T *) xrealloc ((void *) (P), sizeof (T) * (N)))
#define XDELETEVEC(P) free ((void*) (P))
 
/* Allocators for variable-sized structures and raw buffers. */
 
#define XALLOCAVAR(T, S) ((T *) alloca ((S)))
#define XNEWVAR(T, S) ((T *) xmalloc ((S)))
#define XCNEWVAR(T, S) ((T *) xcalloc (1, (S)))
#define XDUPVAR(T, P, S1, S2) ((T *) xmemdup ((P), (S1), (S2)))
#define XRESIZEVAR(T, P, S) ((T *) xrealloc ((P), (S)))
 
/* Type-safe obstack allocator. */
 
#define XOBNEW(O, T) ((T *) obstack_alloc ((O), sizeof (T)))
#define XOBNEWVEC(O, T, N) ((T *) obstack_alloc ((O), sizeof (T) * (N)))
#define XOBNEWVAR(O, T, S) ((T *) obstack_alloc ((O), (S)))
#define XOBFINISH(O, T) ((T) obstack_finish ((O)))
 
/* hex character manipulation routines */
 
#define _hex_array_size 256
#define _hex_bad 99
extern const unsigned char _hex_value[_hex_array_size];
extern void hex_init (void);
#define hex_p(c) (hex_value (c) != _hex_bad)
/* If you change this, note well: Some code relies on side effects in
the argument being performed exactly once. */
#define hex_value(c) ((unsigned int) _hex_value[(unsigned char) (c)])
 
/* Flags for pex_init. These are bits to be or'ed together. */
 
/* Record subprocess times, if possible. */
#define PEX_RECORD_TIMES 0x1
 
/* Use pipes for communication between processes, if possible. */
#define PEX_USE_PIPES 0x2
 
/* Save files used for communication between processes. */
#define PEX_SAVE_TEMPS 0x4
 
/* Prepare to execute one or more programs, with standard output of
each program fed to standard input of the next.
FLAGS As above.
PNAME The name of the program to report in error messages.
TEMPBASE A base name to use for temporary files; may be NULL to
use a random name.
Returns NULL on error. */
 
extern struct pex_obj *pex_init (int flags, const char *pname,
const char *tempbase);
 
/* Flags for pex_run. These are bits to be or'ed together. */
 
/* Last program in pipeline. Standard output of program goes to
OUTNAME, or, if OUTNAME is NULL, to standard output of caller. Do
not set this if you want to call pex_read_output. After this is
set, pex_run may no longer be called with the same struct
pex_obj. */
#define PEX_LAST 0x1
 
/* Search for program in executable search path. */
#define PEX_SEARCH 0x2
 
/* OUTNAME is a suffix. */
#define PEX_SUFFIX 0x4
 
/* Send program's standard error to standard output. */
#define PEX_STDERR_TO_STDOUT 0x8
 
/* Input file should be opened in binary mode. This flag is ignored
on Unix. */
#define PEX_BINARY_INPUT 0x10
 
/* Output file should be opened in binary mode. This flag is ignored
on Unix. For proper behaviour PEX_BINARY_INPUT and
PEX_BINARY_OUTPUT have to match appropriately--i.e., a call using
PEX_BINARY_OUTPUT should be followed by a call using
PEX_BINARY_INPUT. */
#define PEX_BINARY_OUTPUT 0x20
 
/* Capture stderr to a pipe. The output can be read by
calling pex_read_err and reading from the returned
FILE object. This flag may be specified only for
the last program in a pipeline.
 
This flag is supported only on Unix and Windows. */
#define PEX_STDERR_TO_PIPE 0x40
 
/* Capture stderr in binary mode. This flag is ignored
on Unix. */
#define PEX_BINARY_ERROR 0x80
 
 
/* Execute one program. Returns NULL on success. On error returns an
error string (typically just the name of a system call); the error
string is statically allocated.
 
OBJ Returned by pex_init.
 
FLAGS As above.
 
EXECUTABLE The program to execute.
 
ARGV NULL terminated array of arguments to pass to the program.
 
OUTNAME Sets the output file name as follows:
 
PEX_SUFFIX set (OUTNAME may not be NULL):
TEMPBASE parameter to pex_init not NULL:
Output file name is the concatenation of TEMPBASE
and OUTNAME.
TEMPBASE is NULL:
Output file name is a random file name ending in
OUTNAME.
PEX_SUFFIX not set:
OUTNAME not NULL:
Output file name is OUTNAME.
OUTNAME NULL, TEMPBASE not NULL:
Output file name is randomly chosen using
TEMPBASE.
OUTNAME NULL, TEMPBASE NULL:
Output file name is randomly chosen.
 
If PEX_LAST is not set, the output file name is the
name to use for a temporary file holding stdout, if
any (there will not be a file if PEX_USE_PIPES is set
and the system supports pipes). If a file is used, it
will be removed when no longer needed unless
PEX_SAVE_TEMPS is set.
 
If PEX_LAST is set, and OUTNAME is not NULL, standard
output is written to the output file name. The file
will not be removed. If PEX_LAST and PEX_SUFFIX are
both set, TEMPBASE may not be NULL.
 
ERRNAME If not NULL, this is the name of a file to which
standard error is written. If NULL, standard error of
the program is standard error of the caller.
 
ERR On an error return, *ERR is set to an errno value, or
to 0 if there is no relevant errno.
*/
 
extern const char *pex_run (struct pex_obj *obj, int flags,
const char *executable, char * const *argv,
const char *outname, const char *errname,
int *err);
 
/* As for pex_run (), but takes an extra parameter to enable the
environment for the child process to be specified.
 
ENV The environment for the child process, specified as
an array of character pointers. Each element of the
array should point to a string of the form VAR=VALUE,
with the exception of the last element which must be
a null pointer.
*/
 
extern const char *pex_run_in_environment (struct pex_obj *obj, int flags,
const char *executable,
char * const *argv,
char * const *env,
const char *outname,
const char *errname, int *err);
 
/* Return a stream for a temporary file to pass to the first program
in the pipeline as input. The file name is chosen as for pex_run.
pex_run closes the file automatically; don't close it yourself. */
 
extern FILE *pex_input_file (struct pex_obj *obj, int flags,
const char *in_name);
 
/* Return a stream for a pipe connected to the standard input of the
first program in the pipeline. You must have passed
`PEX_USE_PIPES' to `pex_init'. Close the returned stream
yourself. */
 
extern FILE *pex_input_pipe (struct pex_obj *obj, int binary);
 
/* Read the standard output of the last program to be executed.
pex_run can not be called after this. BINARY should be non-zero if
the file should be opened in binary mode; this is ignored on Unix.
Returns NULL on error. Don't call fclose on the returned FILE; it
will be closed by pex_free. */
 
extern FILE *pex_read_output (struct pex_obj *, int binary);
 
/* Read the standard error of the last program to be executed.
pex_run can not be called after this. BINARY should be non-zero if
the file should be opened in binary mode; this is ignored on Unix.
Returns NULL on error. Don't call fclose on the returned FILE; it
will be closed by pex_free. */
 
extern FILE *pex_read_err (struct pex_obj *, int binary);
 
/* Return exit status of all programs in VECTOR. COUNT indicates the
size of VECTOR. The status codes in the vector are in the order of
the calls to pex_run. Returns 0 on error, 1 on success. */
 
extern int pex_get_status (struct pex_obj *, int count, int *vector);
 
/* Return times of all programs in VECTOR. COUNT indicates the size
of VECTOR. struct pex_time is really just struct timeval, but that
is not portable to all systems. Returns 0 on error, 1 on
success. */
 
struct pex_time
{
unsigned long user_seconds;
unsigned long user_microseconds;
unsigned long system_seconds;
unsigned long system_microseconds;
};
 
extern int pex_get_times (struct pex_obj *, int count,
struct pex_time *vector);
 
/* Clean up a pex_obj. If you have not called pex_get_times or
pex_get_status, this will try to kill the subprocesses. */
 
extern void pex_free (struct pex_obj *);
 
/* Just execute one program. Return value is as for pex_run.
FLAGS Combination of PEX_SEARCH and PEX_STDERR_TO_STDOUT.
EXECUTABLE As for pex_run.
ARGV As for pex_run.
PNAME As for pex_init.
OUTNAME As for pex_run when PEX_LAST is set.
ERRNAME As for pex_run.
STATUS Set to exit status on success.
ERR As for pex_run.
*/
 
extern const char *pex_one (int flags, const char *executable,
char * const *argv, const char *pname,
const char *outname, const char *errname,
int *status, int *err);
 
/* pexecute and pwait are the old pexecute interface, still here for
backward compatibility. Don't use these for new code. Instead,
use pex_init/pex_run/pex_get_status/pex_free, or pex_one. */
 
/* Definitions used by the pexecute routine. */
 
#define PEXECUTE_FIRST 1
#define PEXECUTE_LAST 2
#define PEXECUTE_ONE (PEXECUTE_FIRST + PEXECUTE_LAST)
#define PEXECUTE_SEARCH 4
#define PEXECUTE_VERBOSE 8
 
/* Execute a program. */
 
extern int pexecute (const char *, char * const *, const char *,
const char *, char **, char **, int);
 
/* Wait for pexecute to finish. */
 
extern int pwait (int, int *, int);
 
#if !HAVE_DECL_ASPRINTF
/* Like sprintf but provides a pointer to malloc'd storage, which must
be freed by the caller. */
 
extern int asprintf (char **, const char *, ...) ATTRIBUTE_PRINTF_2;
#endif
 
#if !HAVE_DECL_VASPRINTF
/* Like vsprintf but provides a pointer to malloc'd storage, which
must be freed by the caller. */
 
extern int vasprintf (char **, const char *, va_list) ATTRIBUTE_PRINTF(2,0);
#endif
 
#if defined(HAVE_DECL_SNPRINTF) && !HAVE_DECL_SNPRINTF
/* Like sprintf but prints at most N characters. */
extern int snprintf (char *, size_t, const char *, ...) ATTRIBUTE_PRINTF_3;
#endif
 
#if defined(HAVE_DECL_VSNPRINTF) && !HAVE_DECL_VSNPRINTF
/* Like vsprintf but prints at most N characters. */
extern int vsnprintf (char *, size_t, const char *, va_list) ATTRIBUTE_PRINTF(3,0);
#endif
 
#if defined(HAVE_DECL_STRVERSCMP) && !HAVE_DECL_STRVERSCMP
/* Compare version strings. */
extern int strverscmp (const char *, const char *);
#endif
 
/* Set the title of a process */
extern void setproctitle (const char *name, ...);
 
/* Increase stack limit if possible. */
extern void stack_limit_increase (unsigned long);
 
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
 
/* Drastically simplified alloca configurator. If we're using GCC,
we use __builtin_alloca; otherwise we use the C alloca. The C
alloca is always available. You can override GCC by defining
USE_C_ALLOCA yourself. The canonical autoconf macro C_ALLOCA is
also set/unset as it is often used to indicate whether code needs
to call alloca(0). */
extern void *C_alloca (size_t) ATTRIBUTE_MALLOC;
#undef alloca
#if GCC_VERSION >= 2000 && !defined USE_C_ALLOCA
# define alloca(x) __builtin_alloca(x)
# undef C_ALLOCA
# define ASTRDUP(X) \
(__extension__ ({ const char *const libiberty_optr = (X); \
const unsigned long libiberty_len = strlen (libiberty_optr) + 1; \
char *const libiberty_nptr = (char *const) alloca (libiberty_len); \
(char *) memcpy (libiberty_nptr, libiberty_optr, libiberty_len); }))
#else
# define alloca(x) C_alloca(x)
# undef USE_C_ALLOCA
# define USE_C_ALLOCA 1
# undef C_ALLOCA
# define C_ALLOCA 1
extern const char *libiberty_optr;
extern char *libiberty_nptr;
extern unsigned long libiberty_len;
# define ASTRDUP(X) \
(libiberty_optr = (X), \
libiberty_len = strlen (libiberty_optr) + 1, \
libiberty_nptr = (char *) alloca (libiberty_len), \
(char *) memcpy (libiberty_nptr, libiberty_optr, libiberty_len))
#endif
 
#ifdef __cplusplus
}
#endif
 
 
#endif /* ! defined (LIBIBERTY_H) */
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/nested_exception.cc
0,0 → 1,31
// Copyright (C) 2011-2015 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 <exception>
 
namespace std
{
#if ATOMIC_INT_LOCK_FREE > 1
nested_exception::~nested_exception() noexcept = default;
#endif
} // namespace std
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/nested_exception.h
0,0 → 1,173
// Nested Exception support header (nested_exception class) for -*- C++ -*-
 
// Copyright (C) 2009-2015 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)
 
#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else
 
#include <bits/c++config.h>
 
#if ATOMIC_INT_LOCK_FREE < 2
# 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() noexcept : _M_ptr(current_exception()) { }
 
nested_exception(const nested_exception&) noexcept = default;
 
nested_exception& operator=(const nested_exception&) noexcept = default;
 
virtual ~nested_exception() noexcept;
 
[[noreturn]]
void
rethrow_nested() const
{
if (_M_ptr)
rethrow_exception(_M_ptr);
std::terminate();
}
 
exception_ptr
nested_ptr() const noexcept
{ return _M_ptr; }
};
 
template<typename _Except>
struct _Nested_exception : public _Except, public nested_exception
{
explicit _Nested_exception(const _Except& __ex)
: _Except(__ex)
{ }
 
explicit _Nested_exception(_Except&& __ex)
: _Except(static_cast<_Except&&>(__ex))
{ }
};
 
template<typename _Tp,
bool __with_nested = !__is_base_of(nested_exception, _Tp)>
struct _Throw_with_nested_impl
{
template<typename _Up>
static void _S_throw(_Up&& __t)
{ throw _Nested_exception<_Tp>{static_cast<_Up&&>(__t)}; }
};
 
template<typename _Tp>
struct _Throw_with_nested_impl<_Tp, false>
{
template<typename _Up>
static void _S_throw(_Up&& __t)
{ throw static_cast<_Up&&>(__t); }
};
 
template<typename _Tp, bool = __is_class(_Tp) && !__is_final(_Tp)>
struct _Throw_with_nested_helper : _Throw_with_nested_impl<_Tp>
{ };
 
template<typename _Tp>
struct _Throw_with_nested_helper<_Tp, false>
: _Throw_with_nested_impl<_Tp, false>
{ };
 
template<typename _Tp>
struct _Throw_with_nested_helper<_Tp&, false>
: _Throw_with_nested_helper<_Tp>
{ };
 
template<typename _Tp>
struct _Throw_with_nested_helper<_Tp&&, false>
: _Throw_with_nested_helper<_Tp>
{ };
 
/// If @p __t is derived from nested_exception, throws @p __t.
/// Else, throws an implementation-defined object derived from both.
template<typename _Tp>
[[noreturn]]
inline void
throw_with_nested(_Tp&& __t)
{
_Throw_with_nested_helper<_Tp>::_S_throw(static_cast<_Tp&&>(__t));
}
template<typename _Tp, bool = __is_polymorphic(_Tp)>
struct _Rethrow_if_nested_impl
{
static void _S_rethrow(const _Tp& __t)
{
if (auto __tp = dynamic_cast<const nested_exception*>(&__t))
__tp->rethrow_nested();
}
};
 
template<typename _Tp>
struct _Rethrow_if_nested_impl<_Tp, false>
{
static void _S_rethrow(const _Tp&) { }
};
 
/// If @p __ex is derived from nested_exception, @p __ex.rethrow_nested().
template<typename _Ex>
inline void
rethrow_if_nested(const _Ex& __ex)
{
_Rethrow_if_nested_impl<_Ex>::_S_rethrow(__ex);
}
 
// @} group exceptions
} // namespace std
 
} // extern "C++"
 
#endif // C++11
 
#pragma GCC visibility pop
 
#endif // _GLIBCXX_NESTED_EXCEPTION_H
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/new
0,0 → 1,142
// The -*- C++ -*- dynamic memory management header.
 
// Copyright (C) 1994-2015 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 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();
};
 
#if __cplusplus >= 201103L
class bad_array_new_length : public bad_alloc
{
public:
bad_array_new_length() throw() { };
 
// This declaration is not useless:
// http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
virtual ~bad_array_new_length() throw();
 
// See comment in eh_exception.cc.
virtual const char* what() const throw();
};
#endif
 
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();
 
#if __cplusplus >= 201103L
/// Return the current new handler.
new_handler get_new_handler() noexcept;
#endif
} // 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) _GLIBCXX_THROW (std::bad_alloc)
__attribute__((__externally_visible__));
void* operator new[](std::size_t) _GLIBCXX_THROW (std::bad_alloc)
__attribute__((__externally_visible__));
void operator delete(void*) _GLIBCXX_USE_NOEXCEPT
__attribute__((__externally_visible__));
void operator delete[](void*) _GLIBCXX_USE_NOEXCEPT
__attribute__((__externally_visible__));
void* operator new(std::size_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
__attribute__((__externally_visible__));
void* operator new[](std::size_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
__attribute__((__externally_visible__));
void operator delete(void*, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
__attribute__((__externally_visible__));
void operator delete[](void*, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
__attribute__((__externally_visible__));
 
// Default placement versions of operator new.
inline void* operator new(std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
{ return __p; }
inline void* operator new[](std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
{ return __p; }
 
// Default placement versions of operator delete.
inline void operator delete (void*, void*) _GLIBCXX_USE_NOEXCEPT { }
inline void operator delete[](void*, void*) _GLIBCXX_USE_NOEXCEPT { }
//@}
} // extern "C++"
 
#pragma GCC visibility pop
 
#endif
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/new_handler.cc
0,0 → 1,71
// Implementation file for the -*- C++ -*- dynamic memory management header.
 
// Copyright (C) 1996-2015 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 "new"
#include <bits/atomic_lockfree_defines.h>
 
#if ATOMIC_POINTER_LOCK_FREE < 2
#include <ext/concurrence.h>
namespace
{
__gnu_cxx::__mutex mx;
}
#endif
 
const std::nothrow_t std::nothrow = { };
 
using std::new_handler;
namespace
{
new_handler __new_handler;
}
 
new_handler
std::set_new_handler (new_handler handler) throw()
{
new_handler prev_handler;
#if ATOMIC_POINTER_LOCK_FREE > 1
__atomic_exchange (&__new_handler, &handler, &prev_handler,
__ATOMIC_ACQ_REL);
#else
__gnu_cxx::__scoped_lock l(mx);
prev_handler = __new_handler;
__new_handler = handler;
#endif
return prev_handler;
}
 
new_handler
std::get_new_handler () noexcept
{
new_handler handler;
#if ATOMIC_POINTER_LOCK_FREE > 1
__atomic_load (&__new_handler, &handler, __ATOMIC_ACQUIRE);
#else
__gnu_cxx::__scoped_lock l(mx);
handler = __new_handler;
#endif
return handler;
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/new_op.cc
0,0 → 1,59
// Support routines for the -*- C++ -*- dynamic memory management.
 
// Copyright (C) 1997-2015 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 "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
 
_GLIBCXX_WEAK_DEFINITION void *
operator new (std::size_t sz) _GLIBCXX_THROW (std::bad_alloc)
{
void *p;
 
/* malloc (0) is unpredictable; avoid it. */
if (sz == 0)
sz = 1;
 
while (__builtin_expect ((p = malloc (sz)) == 0, false))
{
new_handler handler = std::get_new_handler ();
if (! handler)
_GLIBCXX_THROW_OR_ABORT(bad_alloc());
handler ();
}
 
return p;
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/new_opnt.cc
0,0 → 1,59
// Support routines for the -*- C++ -*- dynamic memory management.
// Copyright (C) 1997-2015 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 <bits/exception_defines.h>
#include "new"
 
using std::new_handler;
using std::bad_alloc;
 
extern "C" void *malloc (std::size_t);
 
_GLIBCXX_WEAK_DEFINITION void *
operator new (std::size_t sz, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
{
void *p;
 
/* malloc (0) is unpredictable; avoid it. */
if (sz == 0)
sz = 1;
 
while (__builtin_expect ((p = malloc (sz)) == 0, false))
{
new_handler handler = std::get_new_handler ();
if (! handler)
return 0;
__try
{
handler ();
}
__catch(const bad_alloc&)
{
return 0;
}
}
 
return p;
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/new_opv.cc
0,0 → 1,33
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
 
// Copyright (C) 1997-2015 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 "new"
 
_GLIBCXX_WEAK_DEFINITION void*
operator new[] (std::size_t sz) _GLIBCXX_THROW (std::bad_alloc)
{
return ::operator new(sz);
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/new_opvnt.cc
0,0 → 1,34
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
 
// Copyright (C) 1997-2015 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 "new"
_GLIBCXX_WEAK_DEFINITION void*
operator new[] (std::size_t sz, const std::nothrow_t& nothrow)
_GLIBCXX_USE_NOEXCEPT
{
return ::operator new(sz, nothrow);
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/pbase_type_info.cc
0,0 → 1,64
// Copyright (C) 1994-2015 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 "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
 
#if __cpp_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);
}
 
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/pmem_type_info.cc
0,0 → 1,48
// Copyright (C) 1994-2015 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 "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);
}
 
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/pointer_type_info.cc
0,0 → 1,54
// Copyright (C) 1994-2015 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 "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
{
#if __cpp_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);
}
 
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/pure.cc
0,0 → 1,58
// -*- C++ -*-
// Copyright (C) 2000-2015 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>
#include "unwind-cxx.h"
 
#if _GLIBCXX_HOSTED && _GLIBCXX_VERBOSE
#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 ();
}
 
extern "C" void
__cxxabiv1::__cxa_deleted_virtual (void)
{
writestr ("deleted virtual method called\n");
std::terminate ();
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/si_class_type_info.cc
0,0 → 1,84
// Copyright (C) 1994-2015 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 "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);
}
 
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/tinfo.cc
0,0 → 1,82
// Methods for type_info for -*- C++ -*- Run Time Type Identification.
// Copyright (C) 1994-2015 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 <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 _GLIBCXX_NOEXCEPT
{
#if __GXX_MERGED_TYPEINFO_NAMES
return name () == arg.name ();
#else
/* The name() method will strip any leading '*' prefix. Therefore
take care to look at __name rather than name() when looking for
the "pointer" prefix. */
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;
}
 
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/tinfo.h
0,0 → 1,174
// RTTI support internals for -*- C++ -*-
// Copyright (C) 1994-2015 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 <cstddef>
 
// Class declarations shared between the typeinfo implementation files.
 
#include <cxxabi.h>
 
namespace __cxxabiv1 {
 
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);
}
 
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/tinfo2.cc
0,0 → 1,44
// Methods for type_info for -*- C++ -*- Run Time Type Identification.
 
// Copyright (C) 1994-2015 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 <cstddef>
#include "tinfo.h"
 
using std::type_info;
 
#if !__GXX_TYPEINFO_EQUALITY_INLINE
 
bool
type_info::before (const type_info &arg) const _GLIBCXX_NOEXCEPT
{
#if __GXX_MERGED_TYPEINFO_NAMES
return name () < arg.name ();
#else
return (name ()[0] == '*') ? name () < arg.name ()
: __builtin_strcmp (name (), arg.name ()) < 0;
#endif
}
 
#endif
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/typeinfo
0,0 → 1,222
// RTTI support for -*- C++ -*-
// Copyright (C) 1994-2015 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 typeinfo
* This is a Standard C++ Library header.
*/
 
#ifndef _TYPEINFO
#define _TYPEINFO
 
#pragma GCC system_header
 
#include <exception>
#if __cplusplus >= 201103L
#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 _GLIBCXX_NOEXCEPT
{ 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 _GLIBCXX_NOEXCEPT;
bool operator==(const type_info& __arg) const _GLIBCXX_NOEXCEPT;
#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 _GLIBCXX_NOEXCEPT
{ return (__name[0] == '*' && __arg.__name[0] == '*')
? __name < __arg.__name
: __builtin_strcmp (__name, __arg.__name) < 0; }
 
bool operator==(const type_info& __arg) const _GLIBCXX_NOEXCEPT
{
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 _GLIBCXX_NOEXCEPT
{ return __name < __arg.__name; }
 
bool operator==(const type_info& __arg) const _GLIBCXX_NOEXCEPT
{ return __name == __arg.__name; }
#endif
#endif
bool operator!=(const type_info& __arg) const _GLIBCXX_NOEXCEPT
{ return !operator==(__arg); }
 
#if __cplusplus >= 201103L
size_t hash_code() const noexcept
{
# 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 // C++11
 
// 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() _GLIBCXX_USE_NOEXCEPT { }
 
// This declaration is not useless:
// http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
virtual ~bad_cast() _GLIBCXX_USE_NOEXCEPT;
 
// See comment in eh_exception.cc.
virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
};
 
/**
* @brief Thrown when a NULL pointer in a @c typeid expression is used.
* @ingroup exceptions
*/
class bad_typeid : public exception
{
public:
bad_typeid () _GLIBCXX_USE_NOEXCEPT { }
 
// This declaration is not useless:
// http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
virtual ~bad_typeid() _GLIBCXX_USE_NOEXCEPT;
 
// See comment in eh_exception.cc.
virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
};
} // namespace std
 
} // extern "C++"
 
#pragma GCC visibility pop
 
#endif
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/unwind-cxx.h
0,0 → 1,399
// -*- C++ -*- Exception handling and frame unwind runtime interface routines.
// Copyright (C) 2001-2015 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>
#include <cxxabi.h>
 
#ifdef _GLIBCXX_HAVE_SYS_SDT_H
#include <sys/sdt.h>
/* We only want to use stap probes starting with v3. Earlier versions
added too much startup cost. */
#if defined (STAP_PROBE2) && _SDT_NOTE_TYPE >= 3
#define PROBE2(name, arg1, arg2) STAP_PROBE2 (libstdcxx, name, arg1, arg2)
#endif
#endif
 
#ifndef PROBE2
#define PROBE2(name, arg1, arg2)
#endif
 
#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 (_GLIBCXX_CDTOR_CALLABI *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 number 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;
 
// Unused member to get similar layout to __cxa_exception, otherwise the
// alignment requirements of _Unwind_Exception would require padding bytes
// before the unwindHeader member.
void (_GLIBCXX_CDTOR_CALLABI *__padding)(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 number 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
};
 
// @@@ 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
 
// Handles cleanup from transactional memory restart.
extern "C" void __cxa_tm_cleanup (void *, void *, unsigned int) throw();
 
// 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
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/unwind-pe.h
0,0 → 1,289
/* Exception handling and frame unwind runtime interface routines.
Copyright (C) 2001, 2002, 2003, 2004, 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/>. */
 
/* @@@ Really this should be out of line, but this also causes link
compatibility problems with the base ABI. This is slightly better
than duplicating code, however. */
 
#ifndef GCC_UNWIND_PE_H
#define GCC_UNWIND_PE_H
 
/* If using C++, references to abort have to be qualified with std::. */
#if __cplusplus
#define __gxx_abort std::abort
#else
#define __gxx_abort abort
#endif
 
/* Pointer encodings, from dwarf2.h. */
#define DW_EH_PE_absptr 0x00
#define DW_EH_PE_omit 0xff
 
#define DW_EH_PE_uleb128 0x01
#define DW_EH_PE_udata2 0x02
#define DW_EH_PE_udata4 0x03
#define DW_EH_PE_udata8 0x04
#define DW_EH_PE_sleb128 0x09
#define DW_EH_PE_sdata2 0x0A
#define DW_EH_PE_sdata4 0x0B
#define DW_EH_PE_sdata8 0x0C
#define DW_EH_PE_signed 0x08
 
#define DW_EH_PE_pcrel 0x10
#define DW_EH_PE_textrel 0x20
#define DW_EH_PE_datarel 0x30
#define DW_EH_PE_funcrel 0x40
#define DW_EH_PE_aligned 0x50
 
#define DW_EH_PE_indirect 0x80
 
#ifndef NO_SIZE_OF_ENCODED_VALUE
 
/* Given an encoding, return the number of bytes the format occupies.
This is only defined for fixed-size encodings, and so does not
include leb128. */
 
static unsigned int
size_of_encoded_value (unsigned char encoding) __attribute__ ((unused));
 
static unsigned int
size_of_encoded_value (unsigned char encoding)
{
if (encoding == DW_EH_PE_omit)
return 0;
 
switch (encoding & 0x07)
{
case DW_EH_PE_absptr:
return sizeof (void *);
case DW_EH_PE_udata2:
return 2;
case DW_EH_PE_udata4:
return 4;
case DW_EH_PE_udata8:
return 8;
}
__gxx_abort ();
}
 
#endif
 
#ifndef NO_BASE_OF_ENCODED_VALUE
 
/* Given an encoding and an _Unwind_Context, return the base to which
the encoding is relative. This base may then be passed to
read_encoded_value_with_base for use when the _Unwind_Context is
not available. */
 
static _Unwind_Ptr
base_of_encoded_value (unsigned char encoding, struct _Unwind_Context *context)
{
if (encoding == DW_EH_PE_omit)
return 0;
 
switch (encoding & 0x70)
{
case DW_EH_PE_absptr:
case DW_EH_PE_pcrel:
case DW_EH_PE_aligned:
return 0;
 
case DW_EH_PE_textrel:
return _Unwind_GetTextRelBase (context);
case DW_EH_PE_datarel:
return _Unwind_GetDataRelBase (context);
case DW_EH_PE_funcrel:
return _Unwind_GetRegionStart (context);
}
__gxx_abort ();
}
 
#endif
 
/* Read an unsigned leb128 value from P, store the value in VAL, return
P incremented past the value. We assume that a word is large enough to
hold any value so encoded; if it is smaller than a pointer on some target,
pointers should not be leb128 encoded on that target. */
 
static const unsigned char *
read_uleb128 (const unsigned char *p, _uleb128_t *val)
{
unsigned int shift = 0;
unsigned char byte;
_uleb128_t result;
 
result = 0;
do
{
byte = *p++;
result |= ((_uleb128_t)byte & 0x7f) << shift;
shift += 7;
}
while (byte & 0x80);
 
*val = result;
return p;
}
 
/* Similar, but read a signed leb128 value. */
 
static const unsigned char *
read_sleb128 (const unsigned char *p, _sleb128_t *val)
{
unsigned int shift = 0;
unsigned char byte;
_uleb128_t result;
 
result = 0;
do
{
byte = *p++;
result |= ((_uleb128_t)byte & 0x7f) << shift;
shift += 7;
}
while (byte & 0x80);
 
/* Sign-extend a negative value. */
if (shift < 8 * sizeof(result) && (byte & 0x40) != 0)
result |= -(((_uleb128_t)1L) << shift);
 
*val = (_sleb128_t) result;
return p;
}
 
/* Load an encoded value from memory at P. The value is returned in VAL;
The function returns P incremented past the value. BASE is as given
by base_of_encoded_value for this encoding in the appropriate context. */
 
static const unsigned char *
read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
const unsigned char *p, _Unwind_Ptr *val)
{
union unaligned
{
void *ptr;
unsigned u2 __attribute__ ((mode (HI)));
unsigned u4 __attribute__ ((mode (SI)));
unsigned u8 __attribute__ ((mode (DI)));
signed s2 __attribute__ ((mode (HI)));
signed s4 __attribute__ ((mode (SI)));
signed s8 __attribute__ ((mode (DI)));
} __attribute__((__packed__));
 
const union unaligned *u = (const union unaligned *) p;
_Unwind_Internal_Ptr result;
 
if (encoding == DW_EH_PE_aligned)
{
_Unwind_Internal_Ptr a = (_Unwind_Internal_Ptr) p;
a = (a + sizeof (void *) - 1) & - sizeof(void *);
result = *(_Unwind_Internal_Ptr *) a;
p = (const unsigned char *) (_Unwind_Internal_Ptr) (a + sizeof (void *));
}
else
{
switch (encoding & 0x0f)
{
case DW_EH_PE_absptr:
result = (_Unwind_Internal_Ptr) u->ptr;
p += sizeof (void *);
break;
 
case DW_EH_PE_uleb128:
{
_uleb128_t tmp;
p = read_uleb128 (p, &tmp);
result = (_Unwind_Internal_Ptr) tmp;
}
break;
 
case DW_EH_PE_sleb128:
{
_sleb128_t tmp;
p = read_sleb128 (p, &tmp);
result = (_Unwind_Internal_Ptr) tmp;
}
break;
 
case DW_EH_PE_udata2:
result = u->u2;
p += 2;
break;
case DW_EH_PE_udata4:
result = u->u4;
p += 4;
break;
case DW_EH_PE_udata8:
result = u->u8;
p += 8;
break;
 
case DW_EH_PE_sdata2:
result = u->s2;
p += 2;
break;
case DW_EH_PE_sdata4:
result = u->s4;
p += 4;
break;
case DW_EH_PE_sdata8:
result = u->s8;
p += 8;
break;
 
default:
__gxx_abort ();
}
 
if (result != 0)
{
result += ((encoding & 0x70) == DW_EH_PE_pcrel
? (_Unwind_Internal_Ptr) u : base);
if (encoding & DW_EH_PE_indirect)
result = *(_Unwind_Internal_Ptr *) result;
}
}
 
*val = result;
return p;
}
 
#ifndef NO_BASE_OF_ENCODED_VALUE
 
/* Like read_encoded_value_with_base, but get the base from the context
rather than providing it directly. */
 
static inline const unsigned char *
read_encoded_value (struct _Unwind_Context *context, unsigned char encoding,
const unsigned char *p, _Unwind_Ptr *val)
{
return read_encoded_value_with_base (encoding,
base_of_encoded_value (encoding, context),
p, val);
}
 
#endif
 
#endif /* unwind-pe.h */
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/vec.cc
0,0 → 1,530
// New abi Support -*- C++ -*-
 
// Copyright (C) 2000-2015 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;
}
 
// Compute the total size with overflow checking.
std::size_t compute_size(std::size_t element_count,
std::size_t element_size,
std::size_t padding_size)
{
if (element_size && element_count > std::size_t(-1) / element_size)
_GLIBCXX_THROW_OR_ABORT(std::bad_alloc());
std::size_t size = element_count * element_size;
if (size + padding_size < size)
_GLIBCXX_THROW_OR_ABORT(std::bad_alloc());
return size + padding_size;
}
}
 
// 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
= compute_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
= compute_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__)
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/vmi_class_type_info.cc
0,0 → 1,390
// Copyright (C) 1994-2015 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 "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;
}
 
}
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/vterminate.cc
0,0 → 1,101
// Verbose terminate_handler -*- C++ -*-
 
// Copyright (C) 2001-2015 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/>.
 
#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; }
#if __cpp_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
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/vterminate.idb
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/toolchain/gcc/5x/libstdc++-v3/libsupc++/vtv_stubs.cc
0,0 → 1,134
// Copyright (C) 2012-2015 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 is part of the vtable verification runtime library. For more
information about this feature, see the comments in libvtv/vtv_rts.cc. */
 
/* The functions in this file are used to create the libvtv_stubs
library, as part of the vtable verification feature. When building
a binary without vtable verification, and linking it with a
(possibly pre-built third-party) library that was built with
verification, it is possible that vtable verification will fail due
to incomplete data (rather than due to corrupt vtable pointers). In
this case we need to give programmers a way of turning off the
vtable verification in their libraries. They can do so by linking
with the libvtv_stubs library, which (as you can see) will replace
the real verification functions with a set of functions that do
nothing (so no more verification failures/aborts). */
 
#include <cstddef>
 
/* weak symbols on Windows work differently than on Linux. To be able
to switch vtv on and off on Windows two dlls are built. One with
the sources from libvtv, the other from these stubs. Depending on
which dll is placed in the folder of the executable the functions
from libvtv or the stubs functions are used. */
#if defined (__CYGWIN__) || defined (__MINGW32__)
extern "C"
void
__VLTChangePermission(int);
 
void
__VLTRegisterSet(void**, const void*, std::size_t, std::size_t,
void**);
 
void
__VLTRegisterPair(void**, const void*, std::size_t,
const void*);
 
const void*
__VLTVerifyVtablePointer(void**, const void*);
 
void
__VLTRegisterSetDebug(void**, const void*, std::size_t, std::size_t,
void**);
 
void
__VLTRegisterPairDebug(void**, const void*, std::size_t, const void*,
const char*, const char*);
 
const void*
__VLTVerifyVtablePointerDebug(void**, const void*, const char*,
const char*);
#else
// Declare as weak for libsupc++, strong definitions are in libvtv.
#if __GXX_WEAK__
extern "C"
void
__VLTChangePermission(int) __attribute__((weak));
 
void
__VLTRegisterSet(void**, const void*, std::size_t, std::size_t,
void**) __attribute__((weak));
 
void
__VLTRegisterPair(void**, const void*, std::size_t,
const void*) __attribute__((weak));
 
const void*
__VLTVerifyVtablePointer(void**, const void*) __attribute__((weak));
 
void
__VLTRegisterSetDebug(void**, const void*, std::size_t, std::size_t,
void**) __attribute__((weak));
 
void
__VLTRegisterPairDebug(void**, const void*, std::size_t, const void*,
const char*, const char*) __attribute__((weak));
 
const void*
__VLTVerifyVtablePointerDebug(void**, const void*, const char*,
const char*) __attribute__((weak));
#endif
#endif
 
// Stub definitions.
extern "C"
void
__VLTChangePermission(int)
{ }
 
void
__VLTRegisterSet(void**, const void*, std::size_t, std::size_t, void**)
{ }
 
void
__VLTRegisterPair(void**, const void*, std::size_t, const void*)
{ }
 
const void*
__VLTVerifyVtablePointer(void**, const void* vtable_ptr)
{ return vtable_ptr; }
 
void
__VLTRegisterSetDebug(void**, const void*, std::size_t, std::size_t, void**)
{ }
 
void
__VLTRegisterPairDebug(void**, const void*, std::size_t, const void*,
const char*, const char*)
{ }
 
const void*
__VLTVerifyVtablePointerDebug(void**, const void* vtable_ptr, const char*,
const char*)
{ return vtable_ptr; }