197403Sobrien// new abi support -*- C++ -*- 297403Sobrien 3169691Skan// Copyright (C) 2000, 2002, 2003, 2004, 2006 Free Software Foundation, Inc. 497403Sobrien// 5132720Skan// This file is part of GCC. 697403Sobrien// 7132720Skan// GCC is free software; you can redistribute it and/or modify 897403Sobrien// it under the terms of the GNU General Public License as published by 997403Sobrien// the Free Software Foundation; either version 2, or (at your option) 1097403Sobrien// any later version. 1197403Sobrien// 12132720Skan// GCC is distributed in the hope that it will be useful, 1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1597403Sobrien// GNU General Public License for more details. 1697403Sobrien// 1797403Sobrien// You should have received a copy of the GNU General Public License 18132720Skan// along with GCC; see the file COPYING. If not, write to 19169691Skan// the Free Software Foundation, 51 Franklin Street, Fifth Floor, 20169691Skan// Boston, MA 02110-1301, USA. 2197403Sobrien 2297403Sobrien// As a special exception, you may use this file as part of a free software 2397403Sobrien// library without restriction. Specifically, if other files instantiate 2497403Sobrien// templates or use macros or inline functions from this file, or you compile 2597403Sobrien// this file and link it with other files to produce an executable, this 2697403Sobrien// file does not by itself cause the resulting executable to be covered by 2797403Sobrien// the GNU General Public License. This exception does not however 2897403Sobrien// invalidate any other reasons why the executable file might be covered by 2997403Sobrien// the GNU General Public License. 3097403Sobrien 3197403Sobrien// Written by Nathan Sidwell, Codesourcery LLC, <nathan@codesourcery.com> 3297403Sobrien 3397403Sobrien/* This file declares the new abi entry points into the runtime. It is not 3497403Sobrien normally necessary for user programs to include this header, or use the 3597403Sobrien entry points directly. However, this header is available should that be 3697403Sobrien needed. 3797403Sobrien 3897403Sobrien Some of the entry points are intended for both C and C++, thus this header 3997403Sobrien is includable from both C and C++. Though the C++ specific parts are not 4097403Sobrien available in C, naturally enough. */ 4197403Sobrien 42169691Skan/** @file cxxabi.h 43169691Skan * The header provides an interface to the C++ ABI. 44169691Skan */ 45169691Skan 46132720Skan#ifndef _CXXABI_H 47132720Skan#define _CXXABI_H 1 4897403Sobrien 49169691Skan#pragma GCC visibility push(default) 50169691Skan 51132720Skan#include <stddef.h> 52169691Skan#include <bits/cxxabi_tweaks.h> 53132720Skan 5497403Sobrien#ifdef __cplusplus 55132720Skannamespace __cxxabiv1 56132720Skan{ 57132720Skan extern "C" 58132720Skan { 59132720Skan#endif 6097403Sobrien 61169691Skan typedef __cxa_cdtor_return_type (*__cxa_cdtor_type)(void *); 62169691Skan 63132720Skan // Allocate array. 64132720Skan void* 65132720Skan __cxa_vec_new(size_t __element_count, size_t __element_size, 66169691Skan size_t __padding_size, __cxa_cdtor_type constructor, 67169691Skan __cxa_cdtor_type destructor); 6897403Sobrien 69132720Skan void* 70132720Skan __cxa_vec_new2(size_t __element_count, size_t __element_size, 71169691Skan size_t __padding_size, __cxa_cdtor_type constructor, 72169691Skan __cxa_cdtor_type destructor, void *(*__alloc) (size_t), 73132720Skan void (*__dealloc) (void*)); 7497403Sobrien 75132720Skan void* 76132720Skan __cxa_vec_new3(size_t __element_count, size_t __element_size, 77169691Skan size_t __padding_size, __cxa_cdtor_type constructor, 78169691Skan __cxa_cdtor_type destructor, void *(*__alloc) (size_t), 79132720Skan void (*__dealloc) (void*, size_t)); 8097403Sobrien 81132720Skan // Construct array. 82169691Skan __cxa_vec_ctor_return_type 83132720Skan __cxa_vec_ctor(void* __array_address, size_t __element_count, 84169691Skan size_t __element_size, __cxa_cdtor_type constructor, 85169691Skan __cxa_cdtor_type destructor); 8697403Sobrien 87169691Skan __cxa_vec_ctor_return_type 88132720Skan __cxa_vec_cctor(void* dest_array, void* src_array, size_t element_count, 89169691Skan size_t element_size, 90169691Skan __cxa_cdtor_return_type (*constructor) (void*, void*), 91169691Skan __cxa_cdtor_type destructor); 92132720Skan 93132720Skan // Destruct array. 94132720Skan void 95132720Skan __cxa_vec_dtor(void* __array_address, size_t __element_count, 96169691Skan size_t __element_size, __cxa_cdtor_type destructor); 9797403Sobrien 98132720Skan void 99132720Skan __cxa_vec_cleanup(void* __array_address, size_t __element_count, 100169691Skan size_t __element_size, __cxa_cdtor_type destructor); 101132720Skan 102132720Skan // Destruct and release array. 103132720Skan void 104132720Skan __cxa_vec_delete(void* __array_address, size_t __element_size, 105169691Skan size_t __padding_size, __cxa_cdtor_type destructor); 10697403Sobrien 107132720Skan void 108132720Skan __cxa_vec_delete2(void* __array_address, size_t __element_size, 109169691Skan size_t __padding_size, __cxa_cdtor_type destructor, 110132720Skan void (*__dealloc) (void*)); 111132720Skan 112132720Skan void 113132720Skan __cxa_vec_delete3(void* __array_address, size_t __element_size, 114169691Skan size_t __padding_size, __cxa_cdtor_type destructor, 115132720Skan void (*__dealloc) (void*, size_t)); 11697403Sobrien 117132720Skan int 118132720Skan __cxa_guard_acquire(__guard*); 11997403Sobrien 120132720Skan void 121132720Skan __cxa_guard_release(__guard*); 12297403Sobrien 123132720Skan void 124132720Skan __cxa_guard_abort(__guard*); 12597403Sobrien 126132720Skan // Pure virtual functions. 127132720Skan void 128132720Skan __cxa_pure_virtual(void); 12997403Sobrien 130132720Skan // Exception handling. 131132720Skan void 132132720Skan __cxa_bad_cast(); 13397403Sobrien 134132720Skan void 135132720Skan __cxa_bad_typeid(); 13697403Sobrien 137132720Skan // DSO destruction. 138132720Skan int 139132720Skan __cxa_atexit(void (*)(void*), void*, void*); 140122182Skan 141132720Skan int 142132720Skan __cxa_finalize(void*); 14397403Sobrien 144132720Skan // Demangling routines. 145132720Skan char* 146132720Skan __cxa_demangle(const char* __mangled_name, char* __output_buffer, 147132720Skan size_t* __length, int* __status); 148132720Skan#ifdef __cplusplus 149132720Skan } 150132720Skan} // namespace __cxxabiv1 151132720Skan#endif 15297403Sobrien 153132720Skan#ifdef __cplusplus 15497403Sobrien 155132720Skan#include <typeinfo> 156132720Skan 157132720Skannamespace __cxxabiv1 15897403Sobrien{ 159132720Skan // Type information for int, float etc. 160132720Skan class __fundamental_type_info : public std::type_info 161132720Skan { 162132720Skan public: 163132720Skan explicit 164132720Skan __fundamental_type_info(const char* __n) : std::type_info(__n) { } 16597403Sobrien 166132720Skan virtual 167132720Skan ~__fundamental_type_info(); 16897403Sobrien }; 16997403Sobrien 170132720Skan // Type information for array objects. 171132720Skan class __array_type_info : public std::type_info 172132720Skan { 173132720Skan public: 174132720Skan explicit 175132720Skan __array_type_info(const char* __n) : std::type_info(__n) { } 17697403Sobrien 177132720Skan virtual 178132720Skan ~__array_type_info(); 179132720Skan }; 180132720Skan 181132720Skan // Type information for functions (both member and non-member). 182132720Skan class __function_type_info : public std::type_info 18397403Sobrien { 184132720Skan public: 185132720Skan explicit 186132720Skan __function_type_info(const char* __n) : std::type_info(__n) { } 187132720Skan 188132720Skan virtual 189132720Skan ~__function_type_info(); 190132720Skan 191132720Skan protected: 192132720Skan // Implementation defined member function. 193132720Skan virtual bool 194132720Skan __is_function_p() const; 195132720Skan }; 196132720Skan 197132720Skan // Type information for enumerations. 198132720Skan class __enum_type_info : public std::type_info 199132720Skan { 200132720Skan public: 201132720Skan explicit 202132720Skan __enum_type_info(const char* __n) : std::type_info(__n) { } 203132720Skan 204132720Skan virtual 205132720Skan ~__enum_type_info(); 206132720Skan }; 207132720Skan 208132720Skan // Common type information for simple pointers and pointers to member. 209132720Skan class __pbase_type_info : public std::type_info 210132720Skan { 211132720Skan public: 212132720Skan unsigned int __flags; // Qualification of the target object. 213132720Skan const std::type_info* __pointee; // Type of pointed to object. 214132720Skan 215132720Skan explicit 216132720Skan __pbase_type_info(const char* __n, int __quals, 217132720Skan const std::type_info* __type) 218132720Skan : std::type_info(__n), __flags(__quals), __pointee(__type) 219132720Skan { } 22097403Sobrien 221132720Skan virtual 222132720Skan ~__pbase_type_info(); 223132720Skan 224132720Skan // Implementation defined type. 225132720Skan enum __masks 226132720Skan { 227132720Skan __const_mask = 0x1, 228132720Skan __volatile_mask = 0x2, 229132720Skan __restrict_mask = 0x4, 230132720Skan __incomplete_mask = 0x8, 231132720Skan __incomplete_class_mask = 0x10 232132720Skan }; 233132720Skan 234132720Skan protected: 235132720Skan __pbase_type_info(const __pbase_type_info&); 236132720Skan 237132720Skan __pbase_type_info& 238132720Skan operator=(const __pbase_type_info&); 239132720Skan 240132720Skan // Implementation defined member functions. 241132720Skan virtual bool 242132720Skan __do_catch(const std::type_info* __thr_type, void** __thr_obj, 243132720Skan unsigned int __outer) const; 244132720Skan 245132720Skan inline virtual bool 246132720Skan __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, 247132720Skan unsigned __outer) const; 24897403Sobrien }; 24997403Sobrien 250132720Skan // Type information for simple pointers. 251132720Skan class __pointer_type_info : public __pbase_type_info 252132720Skan { 253132720Skan public: 254132720Skan explicit 255132720Skan __pointer_type_info(const char* __n, int __quals, 256132720Skan const std::type_info* __type) 257132720Skan : __pbase_type_info (__n, __quals, __type) { } 25897403Sobrien 25997403Sobrien 260132720Skan virtual 261132720Skan ~__pointer_type_info(); 26297403Sobrien 263132720Skan protected: 264132720Skan // Implementation defined member functions. 265132720Skan virtual bool 266132720Skan __is_pointer_p() const; 26797403Sobrien 268132720Skan virtual bool 269132720Skan __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, 270132720Skan unsigned __outer) const; 271132720Skan }; 27297403Sobrien 273132720Skan class __class_type_info; 27497403Sobrien 275132720Skan // Type information for a pointer to member variable. 276132720Skan class __pointer_to_member_type_info : public __pbase_type_info 277132720Skan { 278132720Skan public: 279132720Skan __class_type_info* __context; // Class of the member. 28097403Sobrien 281132720Skan explicit 282132720Skan __pointer_to_member_type_info(const char* __n, int __quals, 283132720Skan const std::type_info* __type, 284132720Skan __class_type_info* __klass) 285132720Skan : __pbase_type_info(__n, __quals, __type), __context(__klass) { } 28697403Sobrien 287132720Skan virtual 288132720Skan ~__pointer_to_member_type_info(); 28997403Sobrien 290132720Skan protected: 291132720Skan __pointer_to_member_type_info(const __pointer_to_member_type_info&); 29297403Sobrien 293132720Skan __pointer_to_member_type_info& 294132720Skan operator=(const __pointer_to_member_type_info&); 29597403Sobrien 296132720Skan // Implementation defined member function. 297132720Skan virtual bool 298132720Skan __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, 299132720Skan unsigned __outer) const; 300132720Skan }; 30197403Sobrien 302132720Skan // Helper class for __vmi_class_type. 303132720Skan class __base_class_type_info 304132720Skan { 305132720Skan public: 306132720Skan const __class_type_info* __base_type; // Base class type. 307132720Skan long __offset_flags; // Offset and info. 308132720Skan 309132720Skan enum __offset_flags_masks 310132720Skan { 311132720Skan __virtual_mask = 0x1, 312132720Skan __public_mask = 0x2, 313132720Skan __hwm_bit = 2, 314132720Skan __offset_shift = 8 // Bits to shift offset. 315132720Skan }; 316132720Skan 317132720Skan // Implementation defined member functions. 318132720Skan bool 319132720Skan __is_virtual_p() const 320132720Skan { return __offset_flags & __virtual_mask; } 321132720Skan 322132720Skan bool 323132720Skan __is_public_p() const 324132720Skan { return __offset_flags & __public_mask; } 325132720Skan 326132720Skan ptrdiff_t 327132720Skan __offset() const 328132720Skan { 329132720Skan // This shift, being of a signed type, is implementation 330132720Skan // defined. GCC implements such shifts as arithmetic, which is 331132720Skan // what we want. 332132720Skan return static_cast<ptrdiff_t>(__offset_flags) >> __offset_shift; 333132720Skan } 33497403Sobrien }; 33597403Sobrien 336132720Skan // Type information for a class. 337132720Skan class __class_type_info : public std::type_info 338132720Skan { 339132720Skan public: 340132720Skan explicit 341132720Skan __class_type_info (const char *__n) : type_info(__n) { } 34297403Sobrien 343132720Skan virtual 344132720Skan ~__class_type_info (); 34597403Sobrien 346132720Skan // Implementation defined types. 347132720Skan // The type sub_kind tells us about how a base object is contained 348132720Skan // within a derived object. We often do this lazily, hence the 349132720Skan // UNKNOWN value. At other times we may use NOT_CONTAINED to mean 350132720Skan // not publicly contained. 351132720Skan enum __sub_kind 352132720Skan { 353132720Skan // We have no idea. 354132720Skan __unknown = 0, 35597403Sobrien 356132720Skan // Not contained within us (in some circumstances this might 357132720Skan // mean not contained publicly) 358132720Skan __not_contained, 35997403Sobrien 360132720Skan // Contained ambiguously. 361132720Skan __contained_ambig, 362132720Skan 363132720Skan // Via a virtual path. 364132720Skan __contained_virtual_mask = __base_class_type_info::__virtual_mask, 36597403Sobrien 366132720Skan // Via a public path. 367132720Skan __contained_public_mask = __base_class_type_info::__public_mask, 36897403Sobrien 369132720Skan // Contained within us. 370132720Skan __contained_mask = 1 << __base_class_type_info::__hwm_bit, 371132720Skan 372132720Skan __contained_private = __contained_mask, 373132720Skan __contained_public = __contained_mask | __contained_public_mask 374132720Skan }; 37597403Sobrien 376132720Skan struct __upcast_result; 377132720Skan struct __dyncast_result; 37897403Sobrien 379132720Skan protected: 380132720Skan // Implementation defined member functions. 381132720Skan virtual bool 382132720Skan __do_upcast(const __class_type_info* __dst_type, void**__obj_ptr) const; 38397403Sobrien 384132720Skan virtual bool 385132720Skan __do_catch(const type_info* __thr_type, void** __thr_obj, 386132720Skan unsigned __outer) const; 38797403Sobrien 388132720Skan public: 389132720Skan // Helper for upcast. See if DST is us, or one of our bases. 390132720Skan // Return false if not found, true if found. 391132720Skan virtual bool 392132720Skan __do_upcast(const __class_type_info* __dst, const void* __obj, 393132720Skan __upcast_result& __restrict __result) const; 39497403Sobrien 395132720Skan // Indicate whether SRC_PTR of type SRC_TYPE is contained publicly 396132720Skan // within OBJ_PTR. OBJ_PTR points to a base object of our type, 397132720Skan // which is the destination type. SRC2DST indicates how SRC 398132720Skan // objects might be contained within this type. If SRC_PTR is one 399132720Skan // of our SRC_TYPE bases, indicate the virtuality. Returns 400132720Skan // not_contained for non containment or private containment. 401132720Skan inline __sub_kind 402132720Skan __find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, 403132720Skan const __class_type_info* __src_type, 404132720Skan const void* __src_ptr) const; 405117397Skan 406132720Skan // Helper for dynamic cast. ACCESS_PATH gives the access from the 407132720Skan // most derived object to this base. DST_TYPE indicates the 408132720Skan // desired type we want. OBJ_PTR points to a base of our type 409132720Skan // within the complete object. SRC_TYPE indicates the static type 410132720Skan // started from and SRC_PTR points to that base within the most 411132720Skan // derived object. Fill in RESULT with what we find. Return true 412132720Skan // if we have located an ambiguous match. 413132720Skan virtual bool 414132720Skan __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, 415132720Skan const __class_type_info* __dst_type, const void* __obj_ptr, 416132720Skan const __class_type_info* __src_type, const void* __src_ptr, 417132720Skan __dyncast_result& __result) const; 418132720Skan 419132720Skan // Helper for find_public_subobj. SRC2DST indicates how SRC_TYPE 420132720Skan // bases are inherited by the type started from -- which is not 421132720Skan // necessarily the current type. The current type will be a base 422132720Skan // of the destination type. OBJ_PTR points to the current base. 423132720Skan virtual __sub_kind 424132720Skan __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, 425132720Skan const __class_type_info* __src_type, 426132720Skan const void* __src_ptr) const; 427132720Skan }; 428117397Skan 429132720Skan // Type information for a class with a single non-virtual base. 430132720Skan class __si_class_type_info : public __class_type_info 431132720Skan { 432132720Skan public: 433132720Skan const __class_type_info* __base_type; 434117397Skan 435132720Skan explicit 436132720Skan __si_class_type_info(const char *__n, const __class_type_info *__base) 437132720Skan : __class_type_info(__n), __base_type(__base) { } 438117397Skan 439132720Skan virtual 440132720Skan ~__si_class_type_info(); 441117397Skan 442132720Skan protected: 443132720Skan __si_class_type_info(const __si_class_type_info&); 444117397Skan 445132720Skan __si_class_type_info& 446132720Skan operator=(const __si_class_type_info&); 447117397Skan 448132720Skan // Implementation defined member functions. 449132720Skan virtual bool 450132720Skan __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, 451132720Skan const __class_type_info* __dst_type, const void* __obj_ptr, 452132720Skan const __class_type_info* __src_type, const void* __src_ptr, 453132720Skan __dyncast_result& __result) const; 454117397Skan 455132720Skan virtual __sub_kind 456132720Skan __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, 457132720Skan const __class_type_info* __src_type, 458132720Skan const void* __sub_ptr) const; 459117397Skan 460132720Skan virtual bool 461132720Skan __do_upcast(const __class_type_info*__dst, const void*__obj, 462132720Skan __upcast_result& __restrict __result) const; 463132720Skan }; 464117397Skan 465132720Skan // Type information for a class with multiple and/or virtual bases. 466132720Skan class __vmi_class_type_info : public __class_type_info 467132720Skan { 468132720Skan public: 469132720Skan unsigned int __flags; // Details about the class hierarchy. 470169691Skan unsigned int __base_count; // Number of direct bases. 471117397Skan 472132720Skan // The array of bases uses the trailing array struct hack so this 473132720Skan // class is not constructable with a normal constructor. It is 474132720Skan // internally generated by the compiler. 475132720Skan __base_class_type_info __base_info[1]; // Array of bases. 476117397Skan 477132720Skan explicit 478132720Skan __vmi_class_type_info(const char* __n, int ___flags) 479132720Skan : __class_type_info(__n), __flags(___flags), __base_count(0) { } 480117397Skan 481132720Skan virtual 482132720Skan ~__vmi_class_type_info(); 483117397Skan 484132720Skan // Implementation defined types. 485132720Skan enum __flags_masks 486132720Skan { 487132720Skan __non_diamond_repeat_mask = 0x1, // Distinct instance of repeated base. 488132720Skan __diamond_shaped_mask = 0x2, // Diamond shaped multiple inheritance. 489132720Skan __flags_unknown_mask = 0x10 490132720Skan }; 49197403Sobrien 492132720Skan protected: 493132720Skan // Implementation defined member functions. 494132720Skan virtual bool 495132720Skan __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, 496132720Skan const __class_type_info* __dst_type, const void* __obj_ptr, 497132720Skan const __class_type_info* __src_type, const void* __src_ptr, 498132720Skan __dyncast_result& __result) const; 49997403Sobrien 500132720Skan virtual __sub_kind 501132720Skan __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, 502132720Skan const __class_type_info* __src_type, 503132720Skan const void* __src_ptr) const; 504132720Skan 505132720Skan virtual bool 506132720Skan __do_upcast(const __class_type_info* __dst, const void* __obj, 507132720Skan __upcast_result& __restrict __result) const; 508132720Skan }; 50997403Sobrien 510132720Skan // Dynamic cast runtime. 511132720Skan // src2dst has the following possible values 512132720Skan // >-1: src_type is a unique public non-virtual base of dst_type 513132720Skan // dst_ptr + src2dst == src_ptr 514132720Skan // -1: unspecified relationship 515132720Skan // -2: src_type is not a public base of dst_type 516132720Skan // -3: src_type is a multiple public non-virtual base of dst_type 517132720Skan extern "C" void* 518132720Skan __dynamic_cast(const void* __src_ptr, // Starting object. 519132720Skan const __class_type_info* __src_type, // Static type of object. 520132720Skan const __class_type_info* __dst_type, // Desired target type. 521132720Skan ptrdiff_t __src2dst); // How src and dst are related. 52297403Sobrien 523132720Skan 524132720Skan // Returns the type_info for the currently handled exception [15.3/8], or 525132720Skan // null if there is none. 526132720Skan extern "C" std::type_info* 527132720Skan __cxa_current_exception_type(); 528132720Skan} // namespace __cxxabiv1 529132720Skan 530132720Skan// User programs should use the alias `abi'. 53197403Sobriennamespace abi = __cxxabiv1; 53297403Sobrien 533132720Skan#endif // __cplusplus 53497403Sobrien 535169691Skan#pragma GCC visibility pop 536169691Skan 537132720Skan#endif // __CXXABI_H 538