]>
Commit | Line | Data |
---|---|---|
dee74d2b | 1 | // ABI Support -*- C++ -*- |
2 | ||
fbd26352 | 3 | // Copyright (C) 2000-2019 Free Software Foundation, Inc. |
85d54afa | 4 | // |
908dad4c | 5 | // This file is part of GCC. |
72680597 | 6 | // |
908dad4c | 7 | // GCC is free software; you can redistribute it and/or modify |
72680597 | 8 | // it under the terms of the GNU General Public License as published by |
6bc9506f | 9 | // the Free Software Foundation; either version 3, or (at your option) |
72680597 | 10 | // any later version. |
dee74d2b | 11 | // |
908dad4c | 12 | // GCC is distributed in the hope that it will be useful, |
72680597 | 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | // GNU General Public License for more details. | |
dee74d2b | 16 | // |
6bc9506f | 17 | // Under Section 7 of GPL version 3, you are granted additional |
18 | // permissions described in the GCC Runtime Library Exception, version | |
19 | // 3.1, as published by the Free Software Foundation. | |
72680597 | 20 | |
6bc9506f | 21 | // You should have received a copy of the GNU General Public License and |
22 | // a copy of the GCC Runtime Library Exception along with this program; | |
23 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
24 | // <http://www.gnu.org/licenses/>. | |
72680597 | 25 | |
85d54afa | 26 | // Written by Nathan Sidwell, Codesourcery LLC, <nathan@codesourcery.com> |
dee74d2b | 27 | |
72680597 | 28 | /* This file declares the new abi entry points into the runtime. It is not |
29 | normally necessary for user programs to include this header, or use the | |
30 | entry points directly. However, this header is available should that be | |
31 | needed. | |
dee74d2b | 32 | |
72680597 | 33 | Some of the entry points are intended for both C and C++, thus this header |
34 | is includable from both C and C++. Though the C++ specific parts are not | |
35 | available in C, naturally enough. */ | |
36 | ||
b2a66747 | 37 | /** @file cxxabi.h |
38 | * The header provides an interface to the C++ ABI. | |
39 | */ | |
40 | ||
5a64d8cf | 41 | #ifndef _CXXABI_H |
42 | #define _CXXABI_H 1 | |
72680597 | 43 | |
1c59b93d | 44 | #pragma GCC system_header |
45 | ||
06587972 | 46 | #pragma GCC visibility push(default) |
47 | ||
21672b0b | 48 | #include <stddef.h> |
dee74d2b | 49 | #include <bits/c++config.h> |
21672b0b | 50 | #include <bits/cxxabi_tweaks.h> |
dee74d2b | 51 | #include <bits/cxxabi_forced.h> |
cce8e592 | 52 | #include <bits/cxxabi_init_exception.h> |
e01c35d8 | 53 | |
72680597 | 54 | #ifdef __cplusplus |
21672b0b | 55 | namespace __cxxabiv1 |
dee74d2b | 56 | { |
57 | extern "C" | |
21672b0b | 58 | { |
59 | #endif | |
60 | ||
61 | typedef __cxa_cdtor_return_type (*__cxa_cdtor_type)(void *); | |
62 | ||
63 | // Allocate array. | |
dee74d2b | 64 | void* |
65 | __cxa_vec_new(size_t __element_count, size_t __element_size, | |
056e71f0 | 66 | size_t __padding_size, __cxa_cdtor_type __constructor, |
67 | __cxa_cdtor_type __destructor); | |
21672b0b | 68 | |
69 | void* | |
70 | __cxa_vec_new2(size_t __element_count, size_t __element_size, | |
056e71f0 | 71 | size_t __padding_size, __cxa_cdtor_type __constructor, |
dee74d2b | 72 | __cxa_cdtor_type __destructor, void *(*__alloc) (size_t), |
21672b0b | 73 | void (*__dealloc) (void*)); |
74 | ||
75 | void* | |
76 | __cxa_vec_new3(size_t __element_count, size_t __element_size, | |
056e71f0 | 77 | size_t __padding_size, __cxa_cdtor_type __constructor, |
dee74d2b | 78 | __cxa_cdtor_type __destructor, void *(*__alloc) (size_t), |
21672b0b | 79 | void (*__dealloc) (void*, size_t)); |
80 | ||
81 | // Construct array. | |
82 | __cxa_vec_ctor_return_type | |
83 | __cxa_vec_ctor(void* __array_address, size_t __element_count, | |
056e71f0 | 84 | size_t __element_size, __cxa_cdtor_type __constructor, |
85 | __cxa_cdtor_type __destructor); | |
21672b0b | 86 | |
87 | __cxa_vec_ctor_return_type | |
056e71f0 | 88 | __cxa_vec_cctor(void* __dest_array, void* __src_array, |
dee74d2b | 89 | size_t __element_count, size_t __element_size, |
90 | __cxa_cdtor_return_type (*__constructor) (void*, void*), | |
056e71f0 | 91 | __cxa_cdtor_type __destructor); |
dee74d2b | 92 | |
21672b0b | 93 | // Destruct array. |
dee74d2b | 94 | void |
21672b0b | 95 | __cxa_vec_dtor(void* __array_address, size_t __element_count, |
056e71f0 | 96 | size_t __element_size, __cxa_cdtor_type __destructor); |
dee74d2b | 97 | |
98 | void | |
056e71f0 | 99 | __cxa_vec_cleanup(void* __array_address, size_t __element_count, size_t __s, |
100 | __cxa_cdtor_type __destructor) _GLIBCXX_NOTHROW; | |
dee74d2b | 101 | |
21672b0b | 102 | // Destruct and release array. |
dee74d2b | 103 | void |
21672b0b | 104 | __cxa_vec_delete(void* __array_address, size_t __element_size, |
056e71f0 | 105 | size_t __padding_size, __cxa_cdtor_type __destructor); |
21672b0b | 106 | |
dee74d2b | 107 | void |
21672b0b | 108 | __cxa_vec_delete2(void* __array_address, size_t __element_size, |
056e71f0 | 109 | size_t __padding_size, __cxa_cdtor_type __destructor, |
21672b0b | 110 | void (*__dealloc) (void*)); |
dee74d2b | 111 | |
112 | void | |
21672b0b | 113 | __cxa_vec_delete3(void* __array_address, size_t __element_size, |
056e71f0 | 114 | size_t __padding_size, __cxa_cdtor_type __destructor, |
21672b0b | 115 | void (*__dealloc) (void*, size_t)); |
116 | ||
dee74d2b | 117 | int |
21672b0b | 118 | __cxa_guard_acquire(__guard*); |
119 | ||
dee74d2b | 120 | void |
85522548 | 121 | __cxa_guard_release(__guard*) _GLIBCXX_NOTHROW; |
21672b0b | 122 | |
dee74d2b | 123 | void |
85522548 | 124 | __cxa_guard_abort(__guard*) _GLIBCXX_NOTHROW; |
21672b0b | 125 | |
96931769 | 126 | // DSO destruction. |
127 | int | |
128 | __cxa_atexit(void (*)(void*), void*, void*) _GLIBCXX_NOTHROW; | |
129 | ||
130 | int | |
131 | __cxa_finalize(void*); | |
132 | ||
db019d30 | 133 | // TLS destruction. |
134 | int | |
135 | __cxa_thread_atexit(void (*)(void*), void*, void *) _GLIBCXX_NOTHROW; | |
136 | ||
21672b0b | 137 | // Pure virtual functions. |
138 | void | |
85522548 | 139 | __cxa_pure_virtual(void) __attribute__ ((__noreturn__)); |
21672b0b | 140 | |
21672b0b | 141 | void |
96931769 | 142 | __cxa_deleted_virtual(void) __attribute__ ((__noreturn__)); |
21672b0b | 143 | |
7b96e840 | 144 | // Exception handling auxiliary. |
96931769 | 145 | void |
146 | __cxa_bad_cast() __attribute__((__noreturn__)); | |
21672b0b | 147 | |
96931769 | 148 | void |
149 | __cxa_bad_typeid() __attribute__((__noreturn__)); | |
21672b0b | 150 | |
bcb3170c | 151 | void |
152 | __cxa_throw_bad_array_new_length() __attribute__((__noreturn__)); | |
153 | ||
97a32de0 | 154 | /** |
dee74d2b | 155 | * @brief Demangling routine. |
97a32de0 | 156 | * ABI-mandated entry point in the C++ runtime library for demangling. |
157 | * | |
158 | * @param __mangled_name A NUL-terminated character string | |
159 | * containing the name to be demangled. | |
160 | * | |
161 | * @param __output_buffer A region of memory, allocated with | |
162 | * malloc, of @a *__length bytes, into which the demangled name is | |
163 | * stored. If @a __output_buffer is not long enough, it is | |
164 | * expanded using realloc. @a __output_buffer may instead be NULL; | |
165 | * in that case, the demangled name is placed in a region of memory | |
166 | * allocated with malloc. | |
167 | * | |
48a8427d | 168 | * @param __length If @a __length is non-null, the length of the |
97a32de0 | 169 | * buffer containing the demangled name is placed in @a *__length. |
170 | * | |
48a8427d | 171 | * @param __status If @a __status is non-null, @a *__status is set to |
172 | * one of the following values: | |
97a32de0 | 173 | * 0: The demangling operation succeeded. |
4c264311 | 174 | * -1: A memory allocation failure occurred. |
97a32de0 | 175 | * -2: @a mangled_name is not a valid name under the C++ ABI mangling rules. |
176 | * -3: One of the arguments is invalid. | |
177 | * | |
178 | * @return A pointer to the start of the NUL-terminated demangled | |
179 | * name, or NULL if the demangling fails. The caller is | |
180 | * responsible for deallocating this memory using @c free. | |
181 | * | |
182 | * The demangling is performed using the C++ ABI mangling rules, | |
183 | * with GNU extensions. For example, this function is used in | |
184 | * __gnu_cxx::__verbose_terminate_handler. | |
dee74d2b | 185 | * |
adc80827 | 186 | * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html |
97a32de0 | 187 | * for other examples of use. |
188 | * | |
189 | * @note The same demangling functionality is available via | |
190 | * libiberty (@c <libiberty/demangle.h> and @c libiberty.a) in GCC | |
191 | * 3.1 and later, but that requires explicit installation (@c | |
192 | * --enable-install-libiberty) and uses a different API, although | |
193 | * the ABI is unchanged. | |
194 | */ | |
21672b0b | 195 | char* |
196 | __cxa_demangle(const char* __mangled_name, char* __output_buffer, | |
197 | size_t* __length, int* __status); | |
96931769 | 198 | |
21672b0b | 199 | #ifdef __cplusplus |
200 | } | |
201 | } // namespace __cxxabiv1 | |
202 | #endif | |
203 | ||
204 | #ifdef __cplusplus | |
205 | ||
206 | #include <typeinfo> | |
207 | ||
208 | namespace __cxxabiv1 | |
209 | { | |
210 | // Type information for int, float etc. | |
211 | class __fundamental_type_info : public std::type_info | |
212 | { | |
213 | public: | |
dee74d2b | 214 | explicit |
21672b0b | 215 | __fundamental_type_info(const char* __n) : std::type_info(__n) { } |
216 | ||
dee74d2b | 217 | virtual |
21672b0b | 218 | ~__fundamental_type_info(); |
219 | }; | |
220 | ||
221 | // Type information for array objects. | |
222 | class __array_type_info : public std::type_info | |
223 | { | |
224 | public: | |
dee74d2b | 225 | explicit |
21672b0b | 226 | __array_type_info(const char* __n) : std::type_info(__n) { } |
227 | ||
dee74d2b | 228 | virtual |
21672b0b | 229 | ~__array_type_info(); |
230 | }; | |
231 | ||
232 | // Type information for functions (both member and non-member). | |
233 | class __function_type_info : public std::type_info | |
234 | { | |
235 | public: | |
dee74d2b | 236 | explicit |
21672b0b | 237 | __function_type_info(const char* __n) : std::type_info(__n) { } |
238 | ||
dee74d2b | 239 | virtual |
21672b0b | 240 | ~__function_type_info(); |
241 | ||
242 | protected: | |
243 | // Implementation defined member function. | |
dee74d2b | 244 | virtual bool |
21672b0b | 245 | __is_function_p() const; |
246 | }; | |
247 | ||
248 | // Type information for enumerations. | |
249 | class __enum_type_info : public std::type_info | |
250 | { | |
251 | public: | |
dee74d2b | 252 | explicit |
21672b0b | 253 | __enum_type_info(const char* __n) : std::type_info(__n) { } |
254 | ||
dee74d2b | 255 | virtual |
21672b0b | 256 | ~__enum_type_info(); |
257 | }; | |
258 | ||
259 | // Common type information for simple pointers and pointers to member. | |
260 | class __pbase_type_info : public std::type_info | |
261 | { | |
262 | public: | |
263 | unsigned int __flags; // Qualification of the target object. | |
264 | const std::type_info* __pointee; // Type of pointed to object. | |
265 | ||
dee74d2b | 266 | explicit |
267 | __pbase_type_info(const char* __n, int __quals, | |
21672b0b | 268 | const std::type_info* __type) |
269 | : std::type_info(__n), __flags(__quals), __pointee(__type) | |
270 | { } | |
dee74d2b | 271 | |
272 | virtual | |
21672b0b | 273 | ~__pbase_type_info(); |
274 | ||
275 | // Implementation defined type. | |
dee74d2b | 276 | enum __masks |
21672b0b | 277 | { |
278 | __const_mask = 0x1, | |
279 | __volatile_mask = 0x2, | |
280 | __restrict_mask = 0x4, | |
281 | __incomplete_mask = 0x8, | |
6d02e6b2 | 282 | __incomplete_class_mask = 0x10, |
2e9e9363 | 283 | __transaction_safe_mask = 0x20, |
284 | __noexcept_mask = 0x40 | |
21672b0b | 285 | }; |
286 | ||
287 | protected: | |
288 | __pbase_type_info(const __pbase_type_info&); | |
289 | ||
290 | __pbase_type_info& | |
291 | operator=(const __pbase_type_info&); | |
292 | ||
293 | // Implementation defined member functions. | |
dee74d2b | 294 | virtual bool |
295 | __do_catch(const std::type_info* __thr_type, void** __thr_obj, | |
21672b0b | 296 | unsigned int __outer) const; |
297 | ||
490d295f | 298 | inline virtual bool |
21672b0b | 299 | __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, |
490d295f | 300 | unsigned __outer) const; |
21672b0b | 301 | }; |
302 | ||
490d295f | 303 | inline bool __pbase_type_info:: |
304 | __pointer_catch (const __pbase_type_info *thrown_type, | |
305 | void **thr_obj, | |
306 | unsigned outer) const | |
307 | { | |
308 | return __pointee->__do_catch (thrown_type->__pointee, thr_obj, outer + 2); | |
309 | } | |
310 | ||
21672b0b | 311 | // Type information for simple pointers. |
312 | class __pointer_type_info : public __pbase_type_info | |
313 | { | |
314 | public: | |
dee74d2b | 315 | explicit |
316 | __pointer_type_info(const char* __n, int __quals, | |
21672b0b | 317 | const std::type_info* __type) |
318 | : __pbase_type_info (__n, __quals, __type) { } | |
319 | ||
320 | ||
dee74d2b | 321 | virtual |
21672b0b | 322 | ~__pointer_type_info(); |
323 | ||
324 | protected: | |
325 | // Implementation defined member functions. | |
dee74d2b | 326 | virtual bool |
21672b0b | 327 | __is_pointer_p() const; |
328 | ||
dee74d2b | 329 | virtual bool |
330 | __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, | |
21672b0b | 331 | unsigned __outer) const; |
332 | }; | |
333 | ||
334 | class __class_type_info; | |
335 | ||
336 | // Type information for a pointer to member variable. | |
337 | class __pointer_to_member_type_info : public __pbase_type_info | |
338 | { | |
339 | public: | |
340 | __class_type_info* __context; // Class of the member. | |
341 | ||
dee74d2b | 342 | explicit |
21672b0b | 343 | __pointer_to_member_type_info(const char* __n, int __quals, |
dee74d2b | 344 | const std::type_info* __type, |
21672b0b | 345 | __class_type_info* __klass) |
346 | : __pbase_type_info(__n, __quals, __type), __context(__klass) { } | |
347 | ||
dee74d2b | 348 | virtual |
21672b0b | 349 | ~__pointer_to_member_type_info(); |
350 | ||
351 | protected: | |
352 | __pointer_to_member_type_info(const __pointer_to_member_type_info&); | |
353 | ||
354 | __pointer_to_member_type_info& | |
355 | operator=(const __pointer_to_member_type_info&); | |
356 | ||
357 | // Implementation defined member function. | |
dee74d2b | 358 | virtual bool |
21672b0b | 359 | __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, |
360 | unsigned __outer) const; | |
361 | }; | |
362 | ||
363 | // Helper class for __vmi_class_type. | |
364 | class __base_class_type_info | |
365 | { | |
366 | public: | |
367 | const __class_type_info* __base_type; // Base class type. | |
4a0626ff | 368 | #ifdef _GLIBCXX_LLP64 |
369 | long long __offset_flags; // Offset and info. | |
370 | #else | |
21672b0b | 371 | long __offset_flags; // Offset and info. |
4a0626ff | 372 | #endif |
21672b0b | 373 | |
dee74d2b | 374 | enum __offset_flags_masks |
21672b0b | 375 | { |
376 | __virtual_mask = 0x1, | |
377 | __public_mask = 0x2, | |
378 | __hwm_bit = 2, | |
379 | __offset_shift = 8 // Bits to shift offset. | |
380 | }; | |
dee74d2b | 381 | |
21672b0b | 382 | // Implementation defined member functions. |
dee74d2b | 383 | bool |
21672b0b | 384 | __is_virtual_p() const |
385 | { return __offset_flags & __virtual_mask; } | |
386 | ||
dee74d2b | 387 | bool |
21672b0b | 388 | __is_public_p() const |
389 | { return __offset_flags & __public_mask; } | |
390 | ||
dee74d2b | 391 | ptrdiff_t |
21672b0b | 392 | __offset() const |
dee74d2b | 393 | { |
21672b0b | 394 | // This shift, being of a signed type, is implementation |
395 | // defined. GCC implements such shifts as arithmetic, which is | |
396 | // what we want. | |
397 | return static_cast<ptrdiff_t>(__offset_flags) >> __offset_shift; | |
398 | } | |
399 | }; | |
400 | ||
401 | // Type information for a class. | |
402 | class __class_type_info : public std::type_info | |
403 | { | |
404 | public: | |
dee74d2b | 405 | explicit |
21672b0b | 406 | __class_type_info (const char *__n) : type_info(__n) { } |
407 | ||
dee74d2b | 408 | virtual |
21672b0b | 409 | ~__class_type_info (); |
410 | ||
411 | // Implementation defined types. | |
412 | // The type sub_kind tells us about how a base object is contained | |
413 | // within a derived object. We often do this lazily, hence the | |
414 | // UNKNOWN value. At other times we may use NOT_CONTAINED to mean | |
415 | // not publicly contained. | |
416 | enum __sub_kind | |
417 | { | |
418 | // We have no idea. | |
dee74d2b | 419 | __unknown = 0, |
21672b0b | 420 | |
421 | // Not contained within us (in some circumstances this might | |
422 | // mean not contained publicly) | |
dee74d2b | 423 | __not_contained, |
21672b0b | 424 | |
425 | // Contained ambiguously. | |
dee74d2b | 426 | __contained_ambig, |
427 | ||
21672b0b | 428 | // Via a virtual path. |
dee74d2b | 429 | __contained_virtual_mask = __base_class_type_info::__virtual_mask, |
21672b0b | 430 | |
431 | // Via a public path. | |
dee74d2b | 432 | __contained_public_mask = __base_class_type_info::__public_mask, |
21672b0b | 433 | |
434 | // Contained within us. | |
435 | __contained_mask = 1 << __base_class_type_info::__hwm_bit, | |
dee74d2b | 436 | |
21672b0b | 437 | __contained_private = __contained_mask, |
438 | __contained_public = __contained_mask | __contained_public_mask | |
439 | }; | |
440 | ||
441 | struct __upcast_result; | |
442 | struct __dyncast_result; | |
443 | ||
444 | protected: | |
445 | // Implementation defined member functions. | |
dee74d2b | 446 | virtual bool |
21672b0b | 447 | __do_upcast(const __class_type_info* __dst_type, void**__obj_ptr) const; |
448 | ||
dee74d2b | 449 | virtual bool |
450 | __do_catch(const type_info* __thr_type, void** __thr_obj, | |
21672b0b | 451 | unsigned __outer) const; |
452 | ||
453 | public: | |
dee74d2b | 454 | // Helper for upcast. See if DST is us, or one of our bases. |
455 | // Return false if not found, true if found. | |
456 | virtual bool | |
21672b0b | 457 | __do_upcast(const __class_type_info* __dst, const void* __obj, |
458 | __upcast_result& __restrict __result) const; | |
459 | ||
460 | // Indicate whether SRC_PTR of type SRC_TYPE is contained publicly | |
461 | // within OBJ_PTR. OBJ_PTR points to a base object of our type, | |
462 | // which is the destination type. SRC2DST indicates how SRC | |
463 | // objects might be contained within this type. If SRC_PTR is one | |
464 | // of our SRC_TYPE bases, indicate the virtuality. Returns | |
465 | // not_contained for non containment or private containment. | |
dee74d2b | 466 | inline __sub_kind |
21672b0b | 467 | __find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, |
dee74d2b | 468 | const __class_type_info* __src_type, |
21672b0b | 469 | const void* __src_ptr) const; |
470 | ||
471 | // Helper for dynamic cast. ACCESS_PATH gives the access from the | |
472 | // most derived object to this base. DST_TYPE indicates the | |
473 | // desired type we want. OBJ_PTR points to a base of our type | |
474 | // within the complete object. SRC_TYPE indicates the static type | |
475 | // started from and SRC_PTR points to that base within the most | |
476 | // derived object. Fill in RESULT with what we find. Return true | |
477 | // if we have located an ambiguous match. | |
dee74d2b | 478 | virtual bool |
21672b0b | 479 | __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, |
dee74d2b | 480 | const __class_type_info* __dst_type, const void* __obj_ptr, |
481 | const __class_type_info* __src_type, const void* __src_ptr, | |
21672b0b | 482 | __dyncast_result& __result) const; |
dee74d2b | 483 | |
21672b0b | 484 | // Helper for find_public_subobj. SRC2DST indicates how SRC_TYPE |
485 | // bases are inherited by the type started from -- which is not | |
486 | // necessarily the current type. The current type will be a base | |
487 | // of the destination type. OBJ_PTR points to the current base. | |
dee74d2b | 488 | virtual __sub_kind |
21672b0b | 489 | __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, |
490 | const __class_type_info* __src_type, | |
491 | const void* __src_ptr) const; | |
492 | }; | |
493 | ||
494 | // Type information for a class with a single non-virtual base. | |
495 | class __si_class_type_info : public __class_type_info | |
496 | { | |
497 | public: | |
498 | const __class_type_info* __base_type; | |
499 | ||
dee74d2b | 500 | explicit |
21672b0b | 501 | __si_class_type_info(const char *__n, const __class_type_info *__base) |
502 | : __class_type_info(__n), __base_type(__base) { } | |
503 | ||
dee74d2b | 504 | virtual |
21672b0b | 505 | ~__si_class_type_info(); |
506 | ||
507 | protected: | |
508 | __si_class_type_info(const __si_class_type_info&); | |
509 | ||
510 | __si_class_type_info& | |
511 | operator=(const __si_class_type_info&); | |
512 | ||
513 | // Implementation defined member functions. | |
dee74d2b | 514 | virtual bool |
21672b0b | 515 | __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, |
516 | const __class_type_info* __dst_type, const void* __obj_ptr, | |
517 | const __class_type_info* __src_type, const void* __src_ptr, | |
518 | __dyncast_result& __result) const; | |
519 | ||
dee74d2b | 520 | virtual __sub_kind |
21672b0b | 521 | __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, |
522 | const __class_type_info* __src_type, | |
523 | const void* __sub_ptr) const; | |
524 | ||
dee74d2b | 525 | virtual bool |
21672b0b | 526 | __do_upcast(const __class_type_info*__dst, const void*__obj, |
527 | __upcast_result& __restrict __result) const; | |
528 | }; | |
529 | ||
530 | // Type information for a class with multiple and/or virtual bases. | |
dee74d2b | 531 | class __vmi_class_type_info : public __class_type_info |
21672b0b | 532 | { |
533 | public: | |
534 | unsigned int __flags; // Details about the class hierarchy. | |
535 | unsigned int __base_count; // Number of direct bases. | |
536 | ||
537 | // The array of bases uses the trailing array struct hack so this | |
538 | // class is not constructable with a normal constructor. It is | |
539 | // internally generated by the compiler. | |
540 | __base_class_type_info __base_info[1]; // Array of bases. | |
541 | ||
dee74d2b | 542 | explicit |
21672b0b | 543 | __vmi_class_type_info(const char* __n, int ___flags) |
544 | : __class_type_info(__n), __flags(___flags), __base_count(0) { } | |
545 | ||
dee74d2b | 546 | virtual |
21672b0b | 547 | ~__vmi_class_type_info(); |
548 | ||
549 | // Implementation defined types. | |
dee74d2b | 550 | enum __flags_masks |
21672b0b | 551 | { |
552 | __non_diamond_repeat_mask = 0x1, // Distinct instance of repeated base. | |
553 | __diamond_shaped_mask = 0x2, // Diamond shaped multiple inheritance. | |
554 | __flags_unknown_mask = 0x10 | |
555 | }; | |
556 | ||
557 | protected: | |
558 | // Implementation defined member functions. | |
dee74d2b | 559 | virtual bool |
21672b0b | 560 | __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, |
561 | const __class_type_info* __dst_type, const void* __obj_ptr, | |
562 | const __class_type_info* __src_type, const void* __src_ptr, | |
563 | __dyncast_result& __result) const; | |
564 | ||
dee74d2b | 565 | virtual __sub_kind |
566 | __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, | |
21672b0b | 567 | const __class_type_info* __src_type, |
568 | const void* __src_ptr) const; | |
dee74d2b | 569 | |
570 | virtual bool | |
21672b0b | 571 | __do_upcast(const __class_type_info* __dst, const void* __obj, |
572 | __upcast_result& __restrict __result) const; | |
573 | }; | |
574 | ||
96931769 | 575 | // Exception handling forward declarations. |
576 | struct __cxa_exception; | |
577 | struct __cxa_refcounted_exception; | |
578 | struct __cxa_dependent_exception; | |
579 | struct __cxa_eh_globals; | |
580 | ||
581 | extern "C" | |
582 | { | |
21672b0b | 583 | // Dynamic cast runtime. |
96931769 | 584 | |
21672b0b | 585 | // src2dst has the following possible values |
586 | // >-1: src_type is a unique public non-virtual base of dst_type | |
587 | // dst_ptr + src2dst == src_ptr | |
588 | // -1: unspecified relationship | |
589 | // -2: src_type is not a public base of dst_type | |
590 | // -3: src_type is a multiple public non-virtual base of dst_type | |
96931769 | 591 | void* |
21672b0b | 592 | __dynamic_cast(const void* __src_ptr, // Starting object. |
593 | const __class_type_info* __src_type, // Static type of object. | |
594 | const __class_type_info* __dst_type, // Desired target type. | |
595 | ptrdiff_t __src2dst); // How src and dst are related. | |
596 | ||
597 | ||
96931769 | 598 | // Exception handling runtime. |
599 | ||
600 | // The __cxa_eh_globals for the current thread can be obtained by using | |
601 | // either of the following functions. The "fast" version assumes at least | |
602 | // one prior call of __cxa_get_globals has been made from the current | |
603 | // thread, so no initialization is necessary. | |
604 | __cxa_eh_globals* | |
605 | __cxa_get_globals() _GLIBCXX_NOTHROW __attribute__ ((__const__)); | |
606 | ||
607 | __cxa_eh_globals* | |
608 | __cxa_get_globals_fast() _GLIBCXX_NOTHROW __attribute__ ((__const__)); | |
609 | ||
96931769 | 610 | // Free the space allocated for the primary exception. |
611 | void | |
612 | __cxa_free_exception(void*) _GLIBCXX_NOTHROW; | |
613 | ||
614 | // Throw the exception. | |
615 | void | |
e01c35d8 | 616 | __cxa_throw(void*, std::type_info*, void (_GLIBCXX_CDTOR_CALLABI *) (void *)) |
96931769 | 617 | __attribute__((__noreturn__)); |
618 | ||
619 | // Used to implement exception handlers. | |
620 | void* | |
621 | __cxa_get_exception_ptr(void*) _GLIBCXX_NOTHROW __attribute__ ((__pure__)); | |
622 | ||
623 | void* | |
624 | __cxa_begin_catch(void*) _GLIBCXX_NOTHROW; | |
625 | ||
626 | void | |
627 | __cxa_end_catch(); | |
628 | ||
629 | void | |
630 | __cxa_rethrow() __attribute__((__noreturn__)); | |
631 | ||
21672b0b | 632 | // Returns the type_info for the currently handled exception [15.3/8], or |
633 | // null if there is none. | |
96931769 | 634 | std::type_info* |
85522548 | 635 | __cxa_current_exception_type() _GLIBCXX_NOTHROW __attribute__ ((__pure__)); |
21672b0b | 636 | |
96931769 | 637 | // GNU Extensions. |
638 | ||
639 | // Allocate memory for a dependent exception. | |
640 | __cxa_dependent_exception* | |
641 | __cxa_allocate_dependent_exception() _GLIBCXX_NOTHROW; | |
642 | ||
643 | // Free the space allocated for the dependent exception. | |
644 | void | |
645 | __cxa_free_dependent_exception(__cxa_dependent_exception*) _GLIBCXX_NOTHROW; | |
646 | ||
647 | } // extern "C" | |
648 | ||
21672b0b | 649 | // A magic placeholder class that can be caught by reference |
650 | // to recognize foreign exceptions. | |
651 | class __foreign_exception | |
652 | { | |
96931769 | 653 | virtual ~__foreign_exception() throw(); |
21672b0b | 654 | virtual void __pure_dummy() = 0; // prevent catch by value |
655 | }; | |
656 | ||
657 | } // namespace __cxxabiv1 | |
0a421700 | 658 | |
97a32de0 | 659 | /** @namespace abi |
660 | * @brief The cross-vendor C++ Application Binary Interface. A | |
661 | * namespace alias to __cxxabiv1, but user programs should use the | |
73337dee | 662 | * alias 'abi'. |
97a32de0 | 663 | * |
664 | * A brief overview of an ABI is given in the libstdc++ FAQ, question | |
665 | * 5.8 (you may have a copy of the FAQ locally, or you can view the online | |
4fec39a9 | 666 | * version at http://gcc.gnu.org/onlinedocs/libstdc++/faq.html#5_8 ). |
97a32de0 | 667 | * |
668 | * GCC subscribes to a cross-vendor ABI for C++, sometimes | |
669 | * called the IA64 ABI because it happens to be the native ABI for that | |
670 | * platform. It is summarized at http://www.codesourcery.com/cxx-abi/ | |
671 | * along with the current specification. | |
672 | * | |
673 | * For users of GCC greater than or equal to 3.x, entry points are | |
73337dee | 674 | * available in <cxxabi.h>, which notes, <em>'It is not normally |
97a32de0 | 675 | * necessary for user programs to include this header, or use the |
676 | * entry points directly. However, this header is available should | |
73337dee | 677 | * that be needed.'</em> |
97a32de0 | 678 | */ |
72680597 | 679 | namespace abi = __cxxabiv1; |
680 | ||
2cc4eeef | 681 | namespace __gnu_cxx |
682 | { | |
683 | /** | |
684 | * @brief Exception thrown by __cxa_guard_acquire. | |
685 | * @ingroup exceptions | |
686 | * | |
687 | * 6.7[stmt.dcl]/4: If control re-enters the declaration (recursively) | |
688 | * while the object is being initialized, the behavior is undefined. | |
689 | * | |
690 | * Since we already have a library function to handle locking, we might | |
691 | * as well check for this situation and throw an exception. | |
692 | * We use the second byte of the guard variable to remember that we're | |
693 | * in the middle of an initialization. | |
694 | */ | |
695 | class recursive_init_error: public std::exception | |
696 | { | |
697 | public: | |
698 | recursive_init_error() throw() { } | |
699 | virtual ~recursive_init_error() throw (); | |
700 | }; | |
701 | } | |
0a421700 | 702 | #endif // __cplusplus |
72680597 | 703 | |
06587972 | 704 | #pragma GCC visibility pop |
705 | ||
dee74d2b | 706 | #endif // __CXXABI_H |