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