OSDN Git Service

2011-12-12 Paolo Carlini <paolo.carlini@oracle.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / libsupc++ / cxxabi.h
index 2775b08..aeaf4cc 100644 (file)
@@ -1,41 +1,36 @@
-// new abi support -*- C++ -*-
-  
-// Copyright (C) 2000, 2002, 2003, 2004, 2006, 2007, 2009
+// ABI Support -*- C++ -*-
+
+// Copyright (C) 2000, 2002, 2003, 2004, 2006, 2007, 2009, 2010, 2011
 // Free Software Foundation, Inc.
 //
 // This file is part of GCC.
 //
 // GCC is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2, or (at your option)
+// the Free Software Foundation; either version 3, or (at your option)
 // any later version.
-// 
+//
 // GCC is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 // GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with GCC; see the file COPYING.  If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02110-1301, USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction.  Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License.  This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
+//
+// 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.  */
 #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 <cxxabi-forced.h>
-#ifdef __cplusplus
-#define _GLIBCXX_NOTHROW throw() 
-#else
-#define _GLIBCXX_NOTHROW __attribute__((nothrow))
-#endif
+#include <bits/cxxabi_forced.h>
 
 #ifdef __cplusplus
 namespace __cxxabiv1
-{  
-  extern "C" 
+{
+  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_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), 
+                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), 
+                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);
+                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);
+  __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 
+  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 __element_size, __cxa_cdtor_type destructor);
-  
+                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 
+  void
   __cxa_vec_delete(void* __array_address, size_t __element_size,
-                  size_t __padding_size, __cxa_cdtor_type destructor);
+                  size_t __padding_size, __cxa_cdtor_type __destructor);
 
-  void 
+  void
   __cxa_vec_delete2(void* __array_address, size_t __element_size,
-                   size_t __padding_size, __cxa_cdtor_type destructor,
+                   size_t __padding_size, __cxa_cdtor_type __destructor,
                    void (*__dealloc) (void*));
-                  
-  void 
+
+  void
   __cxa_vec_delete3(void* __array_address, size_t __element_size,
-                   size_t __padding_size, __cxa_cdtor_type destructor,
+                   size_t __padding_size, __cxa_cdtor_type __destructor,
                    void (*__dealloc) (void*, size_t));
 
-  int 
+  int
   __cxa_guard_acquire(__guard*);
 
-  void 
-  __cxa_guard_release(__guard*);
-
-  void 
-  __cxa_guard_abort(__guard*);
-
-  // Pure virtual functions.
-  void
-  __cxa_pure_virtual(void);
-
-  // Exception handling.
   void
-  __cxa_bad_cast();
+  __cxa_guard_release(__guard*) _GLIBCXX_NOTHROW;
 
   void
-  __cxa_bad_typeid();
+  __cxa_guard_abort(__guard*) _GLIBCXX_NOTHROW;
 
   // DSO destruction.
   int
@@ -149,9 +130,23 @@ namespace __cxxabiv1
   int
   __cxa_finalize(void*);
 
+  // Pure virtual functions.
+  void
+  __cxa_pure_virtual(void) __attribute__ ((__noreturn__));
+
+  void
+  __cxa_deleted_virtual(void) __attribute__ ((__noreturn__));
+
+  // Exception handling auxillary.
+  void 
+  __cxa_bad_cast() __attribute__((__noreturn__));
+
+  void 
+  __cxa_bad_typeid() __attribute__((__noreturn__));
+
 
   /**
-   *  @brief Demangling routine. 
+   *  @brief Demangling routine.
    *  ABI-mandated entry point in the C++ runtime library for demangling.
    *
    *  @param __mangled_name A NUL-terminated character string
@@ -169,7 +164,7 @@ namespace __cxxabiv1
    *
    *  @param __status @a *__status is set to one of the following values:
    *   0: The demangling operation succeeded.
-   *  -1: A memory allocation failiure occurred.
+   *  -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.
    *
@@ -180,7 +175,7 @@ namespace __cxxabiv1
    *  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.
    *
@@ -193,6 +188,7 @@ namespace __cxxabiv1
   char*
   __cxa_demangle(const char* __mangled_name, char* __output_buffer,
                 size_t* __length, int* __status);
+
 #ifdef __cplusplus
   }
 } // namespace __cxxabiv1
@@ -208,10 +204,10 @@ namespace __cxxabiv1
   class __fundamental_type_info : public std::type_info
   {
   public:
-    explicit 
+    explicit
     __fundamental_type_info(const char* __n) : std::type_info(__n) { }
 
-    virtual 
+    virtual
     ~__fundamental_type_info();
   };
 
@@ -219,10 +215,10 @@ namespace __cxxabiv1
   class __array_type_info : public std::type_info
   {
   public:
-    explicit 
+    explicit
     __array_type_info(const char* __n) : std::type_info(__n) { }
 
-    virtual 
+    virtual
     ~__array_type_info();
   };
 
@@ -230,15 +226,15 @@ namespace __cxxabiv1
   class __function_type_info : public std::type_info
   {
   public:
-    explicit 
+    explicit
     __function_type_info(const char* __n) : std::type_info(__n) { }
 
-    virtual 
+    virtual
     ~__function_type_info();
 
   protected:
     // Implementation defined member function.
-    virtual bool 
+    virtual bool
     __is_function_p() const;
   };
 
@@ -246,10 +242,10 @@ namespace __cxxabiv1
   class __enum_type_info : public std::type_info
   {
   public:
-    explicit 
+    explicit
     __enum_type_info(const char* __n) : std::type_info(__n) { }
 
-    virtual 
+    virtual
     ~__enum_type_info();
   };
 
@@ -260,17 +256,17 @@ namespace __cxxabiv1
     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, 
+    explicit
+    __pbase_type_info(const char* __n, int __quals,
                      const std::type_info* __type)
     : std::type_info(__n), __flags(__quals), __pointee(__type)
     { }
-    
-    virtual 
+
+    virtual
     ~__pbase_type_info();
 
     // Implementation defined type.
-    enum __masks 
+    enum __masks
       {
        __const_mask = 0x1,
        __volatile_mask = 0x2,
@@ -286,11 +282,11 @@ namespace __cxxabiv1
     operator=(const __pbase_type_info&);
 
     // Implementation defined member functions.
-    virtual bool 
-    __do_catch(const std::type_info* __thr_type, void** __thr_obj, 
+    virtual bool
+    __do_catch(const std::type_info* __thr_type, void** __thr_obj,
               unsigned int __outer) const;
 
-    inline virtual bool 
+    inline virtual bool
     __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj,
                    unsigned __outer) const;
   };
@@ -299,22 +295,22 @@ namespace __cxxabiv1
   class __pointer_type_info : public __pbase_type_info
   {
   public:
-    explicit 
-    __pointer_type_info(const char* __n, int __quals, 
+    explicit
+    __pointer_type_info(const char* __n, int __quals,
                        const std::type_info* __type)
     : __pbase_type_info (__n, __quals, __type) { }
 
 
-    virtual 
+    virtual
     ~__pointer_type_info();
 
   protected:
     // Implementation defined member functions.
-    virtual bool 
+    virtual bool
     __is_pointer_p() const;
 
-    virtual bool 
-    __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, 
+    virtual bool
+    __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj,
                    unsigned __outer) const;
   };
 
@@ -326,13 +322,13 @@ namespace __cxxabiv1
   public:
     __class_type_info* __context;   // Class of the member.
 
-    explicit 
+    explicit
     __pointer_to_member_type_info(const char* __n, int __quals,
-                                 const std::type_info* __type, 
+                                 const std::type_info* __type,
                                  __class_type_info* __klass)
     : __pbase_type_info(__n, __quals, __type), __context(__klass) { }
 
-    virtual 
+    virtual
     ~__pointer_to_member_type_info();
 
   protected:
@@ -342,7 +338,7 @@ namespace __cxxabiv1
     operator=(const __pointer_to_member_type_info&);
 
     // Implementation defined member function.
-    virtual bool 
+    virtual bool
     __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj,
                    unsigned __outer) const;
   };
@@ -354,26 +350,26 @@ namespace __cxxabiv1
     const __class_type_info*   __base_type;  // Base class type.
     long                       __offset_flags;  // Offset and info.
 
-    enum __offset_flags_masks 
+    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 
+    bool
     __is_virtual_p() const
     { return __offset_flags & __virtual_mask; }
 
-    bool 
+    bool
     __is_public_p() const
     { return __offset_flags & __public_mask; }
 
-    ptrdiff_t 
+    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.
@@ -385,10 +381,10 @@ namespace __cxxabiv1
   class __class_type_info : public std::type_info
   {
   public:
-    explicit 
+    explicit
     __class_type_info (const char *__n) : type_info(__n) { }
 
-    virtual 
+    virtual
     ~__class_type_info ();
 
     // Implementation defined types.
@@ -399,24 +395,24 @@ namespace __cxxabiv1
     enum __sub_kind
       {
        // We have no idea.
-       __unknown = 0, 
+       __unknown = 0,
 
        // Not contained within us (in some circumstances this might
        // mean not contained publicly)
-       __not_contained, 
+       __not_contained,
 
        // Contained ambiguously.
-       __contained_ambig, 
-    
+       __contained_ambig,
+
        // Via a virtual path.
-       __contained_virtual_mask = __base_class_type_info::__virtual_mask, 
+       __contained_virtual_mask = __base_class_type_info::__virtual_mask,
 
        // Via a public path.
-       __contained_public_mask = __base_class_type_info::__public_mask,   
+       __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
       };
@@ -426,17 +422,17 @@ namespace __cxxabiv1
 
   protected:
     // Implementation defined member functions.
-    virtual bool 
+    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, 
+    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 
+    // 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;
 
@@ -446,9 +442,9 @@ namespace __cxxabiv1
     // 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 
+    inline __sub_kind
     __find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr,
-                     const __class_type_info* __src_type, 
+                     const __class_type_info* __src_type,
                      const void* __src_ptr) const;
 
     // Helper for dynamic cast. ACCESS_PATH gives the access from the
@@ -458,17 +454,17 @@ namespace __cxxabiv1
     // 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 
+    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, 
+                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 
+    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;
@@ -480,11 +476,11 @@ namespace __cxxabiv1
   public:
     const __class_type_info* __base_type;
 
-    explicit 
+    explicit
     __si_class_type_info(const char *__n, const __class_type_info *__base)
     : __class_type_info(__n), __base_type(__base) { }
 
-    virtual 
+    virtual
     ~__si_class_type_info();
 
   protected:
@@ -494,24 +490,24 @@ namespace __cxxabiv1
     operator=(const __si_class_type_info&);
 
     // Implementation defined member functions.
-    virtual bool 
+    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 
+    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 
+    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 
+  class __vmi_class_type_info : public __class_type_info
   {
   public:
     unsigned int               __flags;  // Details about the class hierarchy.
@@ -522,15 +518,15 @@ namespace __cxxabiv1
     // internally generated by the compiler.
     __base_class_type_info     __base_info[1];  // Array of bases.
 
-    explicit 
+    explicit
     __vmi_class_type_info(const char* __n, int ___flags)
     : __class_type_info(__n), __flags(___flags), __base_count(0) { }
 
-    virtual 
+    virtual
     ~__vmi_class_type_info();
 
     // Implementation defined types.
-    enum __flags_masks 
+    enum __flags_masks
       {
        __non_diamond_repeat_mask = 0x1, // Distinct instance of repeated base.
        __diamond_shaped_mask = 0x2, // Diamond shaped multiple inheritance.
@@ -539,40 +535,99 @@ namespace __cxxabiv1
 
   protected:
     // Implementation defined member functions.
-    virtual bool 
+    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, 
+    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 
+
+    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
-  extern "C" void*
+  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 (*) (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.
-  extern "C" std::type_info*
-  __cxa_current_exception_type();
+  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.
@@ -587,11 +642,11 @@ 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'.
+ *  alias 'abi'.
  *
  *  A brief overview of an ABI is given in the libstdc++ FAQ, question
  *  5.8 (you may have a copy of the FAQ locally, or you can view the online
- *  version at http://gcc.gnu.org/onlinedocs/libstdc++/faq/index.html#5_8).
+ *  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
@@ -599,15 +654,36 @@ namespace __cxxabiv1
  *  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
+ *  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>
+ *  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 
+#endif // __CXXABI_H