libstdc++
cxxabi.h
Go to the documentation of this file.
00001 // ABI Support -*- C++ -*-
00002 
00003 // Copyright (C) 2000-2014 Free Software Foundation, Inc.
00004 //
00005 // This file is part of GCC.
00006 //
00007 // GCC is free software; you can redistribute it and/or modify
00008 // it under the terms of the GNU General Public License as published by
00009 // the Free Software Foundation; either version 3, or (at your option)
00010 // any later version.
00011 //
00012 // GCC is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // Under Section 7 of GPL version 3, you are granted additional
00018 // permissions described in the GCC Runtime Library Exception, version
00019 // 3.1, as published by the Free Software Foundation.
00020 
00021 // You should have received a copy of the GNU General Public License and
00022 // a copy of the GCC Runtime Library Exception along with this program;
00023 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00024 // <http://www.gnu.org/licenses/>.
00025 
00026 // Written by Nathan Sidwell, Codesourcery LLC, <nathan@codesourcery.com>
00027 
00028 /* This file declares the new abi entry points into the runtime. It is not
00029    normally necessary for user programs to include this header, or use the
00030    entry points directly. However, this header is available should that be
00031    needed.
00032 
00033    Some of the entry points are intended for both C and C++, thus this header
00034    is includable from both C and C++. Though the C++ specific parts are not
00035    available in C, naturally enough.  */
00036 
00037 /** @file cxxabi.h
00038  *  The header provides an interface to the C++ ABI.
00039  */
00040 
00041 #ifndef _CXXABI_H
00042 #define _CXXABI_H 1
00043 
00044 #pragma GCC system_header
00045 
00046 #pragma GCC visibility push(default)
00047 
00048 #include <stddef.h>
00049 #include <bits/c++config.h>
00050 #include <bits/cxxabi_tweaks.h>
00051 #include <bits/cxxabi_forced.h>
00052 
00053 #ifndef _GLIBCXX_CDTOR_CALLABI
00054 #define _GLIBCXX_CDTOR_CALLABI
00055 #endif
00056 
00057 #ifdef __cplusplus
00058 namespace __cxxabiv1
00059 {
00060   extern "C"
00061   {
00062 #endif
00063 
00064   typedef __cxa_cdtor_return_type (*__cxa_cdtor_type)(void *);
00065 
00066   // Allocate array.
00067   void*
00068   __cxa_vec_new(size_t __element_count, size_t __element_size,
00069         size_t __padding_size, __cxa_cdtor_type __constructor,
00070         __cxa_cdtor_type __destructor);
00071 
00072   void*
00073   __cxa_vec_new2(size_t __element_count, size_t __element_size,
00074          size_t __padding_size, __cxa_cdtor_type __constructor,
00075          __cxa_cdtor_type __destructor, void *(*__alloc) (size_t),
00076          void (*__dealloc) (void*));
00077 
00078   void*
00079   __cxa_vec_new3(size_t __element_count, size_t __element_size,
00080          size_t __padding_size, __cxa_cdtor_type __constructor,
00081          __cxa_cdtor_type __destructor, void *(*__alloc) (size_t),
00082          void (*__dealloc) (void*, size_t));
00083 
00084   // Construct array.
00085   __cxa_vec_ctor_return_type
00086   __cxa_vec_ctor(void* __array_address, size_t __element_count,
00087          size_t __element_size, __cxa_cdtor_type __constructor,
00088          __cxa_cdtor_type __destructor);
00089 
00090   __cxa_vec_ctor_return_type
00091   __cxa_vec_cctor(void* __dest_array, void* __src_array,
00092           size_t __element_count, size_t __element_size,
00093           __cxa_cdtor_return_type (*__constructor) (void*, void*),
00094           __cxa_cdtor_type __destructor);
00095 
00096   // Destruct array.
00097   void
00098   __cxa_vec_dtor(void* __array_address, size_t __element_count,
00099          size_t __element_size, __cxa_cdtor_type __destructor);
00100 
00101   void
00102   __cxa_vec_cleanup(void* __array_address, size_t __element_count, size_t __s,
00103             __cxa_cdtor_type __destructor) _GLIBCXX_NOTHROW;
00104 
00105   // Destruct and release array.
00106   void
00107   __cxa_vec_delete(void* __array_address, size_t __element_size,
00108            size_t __padding_size, __cxa_cdtor_type __destructor);
00109 
00110   void
00111   __cxa_vec_delete2(void* __array_address, size_t __element_size,
00112             size_t __padding_size, __cxa_cdtor_type __destructor,
00113             void (*__dealloc) (void*));
00114 
00115   void
00116   __cxa_vec_delete3(void* __array_address, size_t __element_size,
00117             size_t __padding_size, __cxa_cdtor_type __destructor,
00118             void (*__dealloc) (void*, size_t));
00119 
00120   int
00121   __cxa_guard_acquire(__guard*);
00122 
00123   void
00124   __cxa_guard_release(__guard*) _GLIBCXX_NOTHROW;
00125 
00126   void
00127   __cxa_guard_abort(__guard*) _GLIBCXX_NOTHROW;
00128 
00129   // DSO destruction.
00130   int
00131   __cxa_atexit(void (*)(void*), void*, void*) _GLIBCXX_NOTHROW;
00132 
00133   int
00134   __cxa_finalize(void*);
00135 
00136   // TLS destruction.
00137   int
00138   __cxa_thread_atexit(void (*)(void*), void*, void *) _GLIBCXX_NOTHROW;
00139 
00140   // Pure virtual functions.
00141   void
00142   __cxa_pure_virtual(void) __attribute__ ((__noreturn__));
00143 
00144   void
00145   __cxa_deleted_virtual(void) __attribute__ ((__noreturn__));
00146 
00147   // Exception handling auxiliary.
00148   void 
00149   __cxa_bad_cast() __attribute__((__noreturn__));
00150 
00151   void 
00152   __cxa_bad_typeid() __attribute__((__noreturn__));
00153 
00154   void
00155   __cxa_throw_bad_array_new_length() __attribute__((__noreturn__));
00156 
00157   void
00158   __cxa_throw_bad_array_length() __attribute__((__noreturn__));
00159 
00160   /**
00161    *  @brief Demangling routine.
00162    *  ABI-mandated entry point in the C++ runtime library for demangling.
00163    *
00164    *  @param __mangled_name A NUL-terminated character string
00165    *  containing the name to be demangled.
00166    *
00167    *  @param __output_buffer A region of memory, allocated with
00168    *  malloc, of @a *__length bytes, into which the demangled name is
00169    *  stored.  If @a __output_buffer is not long enough, it is
00170    *  expanded using realloc.  @a __output_buffer may instead be NULL;
00171    *  in that case, the demangled name is placed in a region of memory
00172    *  allocated with malloc.
00173    *
00174    *  @param __length If @a __length is non-NULL, the length of the
00175    *  buffer containing the demangled name is placed in @a *__length.
00176    *
00177    *  @param __status @a *__status is set to one of the following values:
00178    *   0: The demangling operation succeeded.
00179    *  -1: A memory allocation failure occurred.
00180    *  -2: @a mangled_name is not a valid name under the C++ ABI mangling rules.
00181    *  -3: One of the arguments is invalid.
00182    *
00183    *  @return A pointer to the start of the NUL-terminated demangled
00184    *  name, or NULL if the demangling fails.  The caller is
00185    *  responsible for deallocating this memory using @c free.
00186    *
00187    *  The demangling is performed using the C++ ABI mangling rules,
00188    *  with GNU extensions. For example, this function is used in
00189    *  __gnu_cxx::__verbose_terminate_handler.
00190    *
00191    *  See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt12ch39.html
00192    *  for other examples of use.
00193    *
00194    *  @note The same demangling functionality is available via
00195    *  libiberty (@c <libiberty/demangle.h> and @c libiberty.a) in GCC
00196    *  3.1 and later, but that requires explicit installation (@c
00197    *  --enable-install-libiberty) and uses a different API, although
00198    *  the ABI is unchanged.
00199    */
00200   char*
00201   __cxa_demangle(const char* __mangled_name, char* __output_buffer,
00202          size_t* __length, int* __status);
00203 
00204 #ifdef __cplusplus
00205   }
00206 } // namespace __cxxabiv1
00207 #endif
00208 
00209 #ifdef __cplusplus
00210 
00211 #include <typeinfo>
00212 
00213 namespace __cxxabiv1
00214 {
00215   // Type information for int, float etc.
00216   class __fundamental_type_info : public std::type_info
00217   {
00218   public:
00219     explicit
00220     __fundamental_type_info(const char* __n) : std::type_info(__n) { }
00221 
00222     virtual
00223     ~__fundamental_type_info();
00224   };
00225 
00226   // Type information for array objects.
00227   class __array_type_info : public std::type_info
00228   {
00229   public:
00230     explicit
00231     __array_type_info(const char* __n) : std::type_info(__n) { }
00232 
00233     virtual
00234     ~__array_type_info();
00235   };
00236 
00237   // Type information for functions (both member and non-member).
00238   class __function_type_info : public std::type_info
00239   {
00240   public:
00241     explicit
00242     __function_type_info(const char* __n) : std::type_info(__n) { }
00243 
00244     virtual
00245     ~__function_type_info();
00246 
00247   protected:
00248     // Implementation defined member function.
00249     virtual bool
00250     __is_function_p() const;
00251   };
00252 
00253   // Type information for enumerations.
00254   class __enum_type_info : public std::type_info
00255   {
00256   public:
00257     explicit
00258     __enum_type_info(const char* __n) : std::type_info(__n) { }
00259 
00260     virtual
00261     ~__enum_type_info();
00262   };
00263 
00264   // Common type information for simple pointers and pointers to member.
00265   class __pbase_type_info : public std::type_info
00266   {
00267   public:
00268     unsigned int        __flags; // Qualification of the target object.
00269     const std::type_info*   __pointee; // Type of pointed to object.
00270 
00271     explicit
00272     __pbase_type_info(const char* __n, int __quals,
00273               const std::type_info* __type)
00274     : std::type_info(__n), __flags(__quals), __pointee(__type)
00275     { }
00276 
00277     virtual
00278     ~__pbase_type_info();
00279 
00280     // Implementation defined type.
00281     enum __masks
00282       {
00283     __const_mask = 0x1,
00284     __volatile_mask = 0x2,
00285     __restrict_mask = 0x4,
00286     __incomplete_mask = 0x8,
00287     __incomplete_class_mask = 0x10
00288       };
00289 
00290   protected:
00291     __pbase_type_info(const __pbase_type_info&);
00292 
00293     __pbase_type_info&
00294     operator=(const __pbase_type_info&);
00295 
00296     // Implementation defined member functions.
00297     virtual bool
00298     __do_catch(const std::type_info* __thr_type, void** __thr_obj,
00299            unsigned int __outer) const;
00300 
00301     inline virtual bool
00302     __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj,
00303             unsigned __outer) const;
00304   };
00305 
00306   // Type information for simple pointers.
00307   class __pointer_type_info : public __pbase_type_info
00308   {
00309   public:
00310     explicit
00311     __pointer_type_info(const char* __n, int __quals,
00312             const std::type_info* __type)
00313     : __pbase_type_info (__n, __quals, __type) { }
00314 
00315 
00316     virtual
00317     ~__pointer_type_info();
00318 
00319   protected:
00320     // Implementation defined member functions.
00321     virtual bool
00322     __is_pointer_p() const;
00323 
00324     virtual bool
00325     __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj,
00326             unsigned __outer) const;
00327   };
00328 
00329   class __class_type_info;
00330 
00331   // Type information for a pointer to member variable.
00332   class __pointer_to_member_type_info : public __pbase_type_info
00333   {
00334   public:
00335     __class_type_info* __context;   // Class of the member.
00336 
00337     explicit
00338     __pointer_to_member_type_info(const char* __n, int __quals,
00339                   const std::type_info* __type,
00340                   __class_type_info* __klass)
00341     : __pbase_type_info(__n, __quals, __type), __context(__klass) { }
00342 
00343     virtual
00344     ~__pointer_to_member_type_info();
00345 
00346   protected:
00347     __pointer_to_member_type_info(const __pointer_to_member_type_info&);
00348 
00349     __pointer_to_member_type_info&
00350     operator=(const __pointer_to_member_type_info&);
00351 
00352     // Implementation defined member function.
00353     virtual bool
00354     __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj,
00355             unsigned __outer) const;
00356   };
00357 
00358   // Helper class for __vmi_class_type.
00359   class __base_class_type_info
00360   {
00361   public:
00362     const __class_type_info*    __base_type;  // Base class type.
00363 #ifdef _GLIBCXX_LLP64
00364     long long           __offset_flags;  // Offset and info.
00365 #else
00366     long            __offset_flags;  // Offset and info.
00367 #endif
00368 
00369     enum __offset_flags_masks
00370       {
00371     __virtual_mask = 0x1,
00372     __public_mask = 0x2,
00373     __hwm_bit = 2,
00374     __offset_shift = 8          // Bits to shift offset.
00375       };
00376 
00377     // Implementation defined member functions.
00378     bool
00379     __is_virtual_p() const
00380     { return __offset_flags & __virtual_mask; }
00381 
00382     bool
00383     __is_public_p() const
00384     { return __offset_flags & __public_mask; }
00385 
00386     ptrdiff_t
00387     __offset() const
00388     {
00389       // This shift, being of a signed type, is implementation
00390       // defined. GCC implements such shifts as arithmetic, which is
00391       // what we want.
00392       return static_cast<ptrdiff_t>(__offset_flags) >> __offset_shift;
00393     }
00394   };
00395 
00396   // Type information for a class.
00397   class __class_type_info : public std::type_info
00398   {
00399   public:
00400     explicit
00401     __class_type_info (const char *__n) : type_info(__n) { }
00402 
00403     virtual
00404     ~__class_type_info ();
00405 
00406     // Implementation defined types.
00407     // The type sub_kind tells us about how a base object is contained
00408     // within a derived object. We often do this lazily, hence the
00409     // UNKNOWN value. At other times we may use NOT_CONTAINED to mean
00410     // not publicly contained.
00411     enum __sub_kind
00412       {
00413     // We have no idea.
00414     __unknown = 0,
00415 
00416     // Not contained within us (in some circumstances this might
00417     // mean not contained publicly)
00418     __not_contained,
00419 
00420     // Contained ambiguously.
00421     __contained_ambig,
00422 
00423     // Via a virtual path.
00424     __contained_virtual_mask = __base_class_type_info::__virtual_mask,
00425 
00426     // Via a public path.
00427     __contained_public_mask = __base_class_type_info::__public_mask,
00428 
00429     // Contained within us.
00430     __contained_mask = 1 << __base_class_type_info::__hwm_bit,
00431 
00432     __contained_private = __contained_mask,
00433     __contained_public = __contained_mask | __contained_public_mask
00434       };
00435 
00436     struct __upcast_result;
00437     struct __dyncast_result;
00438 
00439   protected:
00440     // Implementation defined member functions.
00441     virtual bool
00442     __do_upcast(const __class_type_info* __dst_type, void**__obj_ptr) const;
00443 
00444     virtual bool
00445     __do_catch(const type_info* __thr_type, void** __thr_obj,
00446            unsigned __outer) const;
00447 
00448   public:
00449     // Helper for upcast. See if DST is us, or one of our bases.
00450     // Return false if not found, true if found.
00451     virtual bool
00452     __do_upcast(const __class_type_info* __dst, const void* __obj,
00453         __upcast_result& __restrict __result) const;
00454 
00455     // Indicate whether SRC_PTR of type SRC_TYPE is contained publicly
00456     // within OBJ_PTR. OBJ_PTR points to a base object of our type,
00457     // which is the destination type. SRC2DST indicates how SRC
00458     // objects might be contained within this type.  If SRC_PTR is one
00459     // of our SRC_TYPE bases, indicate the virtuality. Returns
00460     // not_contained for non containment or private containment.
00461     inline __sub_kind
00462     __find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr,
00463               const __class_type_info* __src_type,
00464               const void* __src_ptr) const;
00465 
00466     // Helper for dynamic cast. ACCESS_PATH gives the access from the
00467     // most derived object to this base. DST_TYPE indicates the
00468     // desired type we want. OBJ_PTR points to a base of our type
00469     // within the complete object. SRC_TYPE indicates the static type
00470     // started from and SRC_PTR points to that base within the most
00471     // derived object. Fill in RESULT with what we find. Return true
00472     // if we have located an ambiguous match.
00473     virtual bool
00474     __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path,
00475          const __class_type_info* __dst_type, const void* __obj_ptr,
00476          const __class_type_info* __src_type, const void* __src_ptr,
00477          __dyncast_result& __result) const;
00478 
00479     // Helper for find_public_subobj. SRC2DST indicates how SRC_TYPE
00480     // bases are inherited by the type started from -- which is not
00481     // necessarily the current type. The current type will be a base
00482     // of the destination type.  OBJ_PTR points to the current base.
00483     virtual __sub_kind
00484     __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr,
00485              const __class_type_info* __src_type,
00486              const void* __src_ptr) const;
00487   };
00488 
00489   // Type information for a class with a single non-virtual base.
00490   class __si_class_type_info : public __class_type_info
00491   {
00492   public:
00493     const __class_type_info* __base_type;
00494 
00495     explicit
00496     __si_class_type_info(const char *__n, const __class_type_info *__base)
00497     : __class_type_info(__n), __base_type(__base) { }
00498 
00499     virtual
00500     ~__si_class_type_info();
00501 
00502   protected:
00503     __si_class_type_info(const __si_class_type_info&);
00504 
00505     __si_class_type_info&
00506     operator=(const __si_class_type_info&);
00507 
00508     // Implementation defined member functions.
00509     virtual bool
00510     __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path,
00511          const __class_type_info* __dst_type, const void* __obj_ptr,
00512          const __class_type_info* __src_type, const void* __src_ptr,
00513          __dyncast_result& __result) const;
00514 
00515     virtual __sub_kind
00516     __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr,
00517              const __class_type_info* __src_type,
00518              const void* __sub_ptr) const;
00519 
00520     virtual bool
00521     __do_upcast(const __class_type_info*__dst, const void*__obj,
00522         __upcast_result& __restrict __result) const;
00523   };
00524 
00525   // Type information for a class with multiple and/or virtual bases.
00526   class __vmi_class_type_info : public __class_type_info
00527   {
00528   public:
00529     unsigned int        __flags;  // Details about the class hierarchy.
00530     unsigned int        __base_count;  // Number of direct bases.
00531 
00532     // The array of bases uses the trailing array struct hack so this
00533     // class is not constructable with a normal constructor. It is
00534     // internally generated by the compiler.
00535     __base_class_type_info  __base_info[1];  // Array of bases.
00536 
00537     explicit
00538     __vmi_class_type_info(const char* __n, int ___flags)
00539     : __class_type_info(__n), __flags(___flags), __base_count(0) { }
00540 
00541     virtual
00542     ~__vmi_class_type_info();
00543 
00544     // Implementation defined types.
00545     enum __flags_masks
00546       {
00547     __non_diamond_repeat_mask = 0x1, // Distinct instance of repeated base.
00548     __diamond_shaped_mask = 0x2, // Diamond shaped multiple inheritance.
00549     __flags_unknown_mask = 0x10
00550       };
00551 
00552   protected:
00553     // Implementation defined member functions.
00554     virtual bool
00555     __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path,
00556          const __class_type_info* __dst_type, const void* __obj_ptr,
00557          const __class_type_info* __src_type, const void* __src_ptr,
00558          __dyncast_result& __result) const;
00559 
00560     virtual __sub_kind
00561     __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr,
00562              const __class_type_info* __src_type,
00563              const void* __src_ptr) const;
00564 
00565     virtual bool
00566     __do_upcast(const __class_type_info* __dst, const void* __obj,
00567         __upcast_result& __restrict __result) const;
00568   };
00569 
00570   // Exception handling forward declarations.
00571   struct __cxa_exception;
00572   struct __cxa_refcounted_exception;
00573   struct __cxa_dependent_exception;
00574   struct __cxa_eh_globals;
00575 
00576   extern "C"
00577   {
00578   // Dynamic cast runtime.
00579 
00580   // src2dst has the following possible values
00581   //  >-1: src_type is a unique public non-virtual base of dst_type
00582   //       dst_ptr + src2dst == src_ptr
00583   //   -1: unspecified relationship
00584   //   -2: src_type is not a public base of dst_type
00585   //   -3: src_type is a multiple public non-virtual base of dst_type
00586   void*
00587   __dynamic_cast(const void* __src_ptr, // Starting object.
00588          const __class_type_info* __src_type, // Static type of object.
00589          const __class_type_info* __dst_type, // Desired target type.
00590          ptrdiff_t __src2dst); // How src and dst are related.
00591 
00592 
00593   // Exception handling runtime.
00594 
00595   // The __cxa_eh_globals for the current thread can be obtained by using
00596   // either of the following functions.  The "fast" version assumes at least
00597   // one prior call of __cxa_get_globals has been made from the current
00598   // thread, so no initialization is necessary.
00599   __cxa_eh_globals*
00600   __cxa_get_globals() _GLIBCXX_NOTHROW __attribute__ ((__const__));
00601 
00602   __cxa_eh_globals*
00603   __cxa_get_globals_fast() _GLIBCXX_NOTHROW __attribute__ ((__const__));
00604 
00605   // Allocate memory for the primary exception plus the thrown object.
00606   void*
00607   __cxa_allocate_exception(size_t) _GLIBCXX_NOTHROW;
00608 
00609   // Free the space allocated for the primary exception.
00610   void 
00611   __cxa_free_exception(void*) _GLIBCXX_NOTHROW;
00612 
00613   // Throw the exception.
00614   void
00615   __cxa_throw(void*, std::type_info*, void (_GLIBCXX_CDTOR_CALLABI *) (void *))
00616   __attribute__((__noreturn__));
00617 
00618   // Used to implement exception handlers.
00619   void*
00620   __cxa_get_exception_ptr(void*) _GLIBCXX_NOTHROW __attribute__ ((__pure__));
00621 
00622   void*
00623   __cxa_begin_catch(void*) _GLIBCXX_NOTHROW;
00624 
00625   void 
00626   __cxa_end_catch();
00627 
00628   void 
00629   __cxa_rethrow() __attribute__((__noreturn__));
00630 
00631   // Returns the type_info for the currently handled exception [15.3/8], or
00632   // null if there is none.
00633   std::type_info*
00634   __cxa_current_exception_type() _GLIBCXX_NOTHROW __attribute__ ((__pure__));
00635 
00636   // GNU Extensions.
00637 
00638   // Allocate memory for a dependent exception.
00639   __cxa_dependent_exception*
00640   __cxa_allocate_dependent_exception() _GLIBCXX_NOTHROW;
00641 
00642   // Free the space allocated for the dependent exception.
00643   void
00644   __cxa_free_dependent_exception(__cxa_dependent_exception*) _GLIBCXX_NOTHROW;
00645 
00646   } // extern "C"
00647 
00648   // A magic placeholder class that can be caught by reference
00649   // to recognize foreign exceptions.
00650   class __foreign_exception
00651   {
00652     virtual ~__foreign_exception() throw();
00653     virtual void __pure_dummy() = 0; // prevent catch by value
00654   };
00655 
00656 } // namespace __cxxabiv1
00657 
00658 /** @namespace abi
00659  *  @brief The cross-vendor C++ Application Binary Interface. A
00660  *  namespace alias to __cxxabiv1, but user programs should use the
00661  *  alias 'abi'.
00662  *
00663  *  A brief overview of an ABI is given in the libstdc++ FAQ, question
00664  *  5.8 (you may have a copy of the FAQ locally, or you can view the online
00665  *  version at http://gcc.gnu.org/onlinedocs/libstdc++/faq.html#5_8 ).
00666  *
00667  *  GCC subscribes to a cross-vendor ABI for C++, sometimes
00668  *  called the IA64 ABI because it happens to be the native ABI for that
00669  *  platform.  It is summarized at http://www.codesourcery.com/cxx-abi/
00670  *  along with the current specification.
00671  *
00672  *  For users of GCC greater than or equal to 3.x, entry points are
00673  *  available in <cxxabi.h>, which notes, <em>'It is not normally
00674  *  necessary for user programs to include this header, or use the
00675  *  entry points directly.  However, this header is available should
00676  *  that be needed.'</em>
00677 */
00678 namespace abi = __cxxabiv1;
00679 
00680 namespace __gnu_cxx
00681 {
00682   /**
00683    *  @brief Exception thrown by __cxa_guard_acquire.
00684    *  @ingroup exceptions
00685    *
00686    *  6.7[stmt.dcl]/4: If control re-enters the declaration (recursively)
00687    *  while the object is being initialized, the behavior is undefined.
00688    *
00689    *  Since we already have a library function to handle locking, we might
00690    *  as well check for this situation and throw an exception.
00691    *  We use the second byte of the guard variable to remember that we're
00692    *  in the middle of an initialization.
00693    */
00694   class recursive_init_error: public std::exception
00695   {
00696   public:
00697     recursive_init_error() throw() { }
00698     virtual ~recursive_init_error() throw ();
00699   };
00700 }
00701 #endif // __cplusplus
00702 
00703 #pragma GCC visibility pop
00704 
00705 #endif // __CXXABI_H