17a984708SDavid Chisnall// -*- C++ -*- 27a984708SDavid Chisnall//===--------------------------- __debug ----------------------------------===// 37a984708SDavid Chisnall// 47a984708SDavid Chisnall// The LLVM Compiler Infrastructure 57a984708SDavid Chisnall// 67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open 77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details. 87a984708SDavid Chisnall// 97a984708SDavid Chisnall//===----------------------------------------------------------------------===// 107a984708SDavid Chisnall 117a984708SDavid Chisnall#ifndef _LIBCPP_DEBUG_H 127a984708SDavid Chisnall#define _LIBCPP_DEBUG_H 137a984708SDavid Chisnall 14d72607e9SDimitry Andric#include <__config> 15d72607e9SDimitry Andric 164f7ab58eSDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 174f7ab58eSDimitry Andric#pragma GCC system_header 184f7ab58eSDimitry Andric#endif 194f7ab58eSDimitry Andric 20aed8d94eSDimitry Andric#if defined(_LIBCPP_HAS_NO_NULLPTR) 21aed8d94eSDimitry Andric# include <cstddef> 22aed8d94eSDimitry Andric#endif 23aed8d94eSDimitry Andric 24aed8d94eSDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 1 || defined(_LIBCPP_BUILDING_LIBRARY) 257a984708SDavid Chisnall# include <cstdlib> 267a984708SDavid Chisnall# include <cstdio> 277a984708SDavid Chisnall# include <cstddef> 28aed8d94eSDimitry Andric# include <exception> 291bf9f7c1SDimitry Andric#endif 30aed8d94eSDimitry Andric 31aed8d94eSDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 1 && !defined(_LIBCPP_ASSERT) 32aed8d94eSDimitry Andric# define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : \ 33aed8d94eSDimitry Andric _VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, #x, m))) 34aed8d94eSDimitry Andric#endif 35aed8d94eSDimitry Andric 36aed8d94eSDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 2 37aed8d94eSDimitry Andric#ifndef _LIBCPP_DEBUG_ASSERT 38aed8d94eSDimitry Andric#define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(x, m) 39aed8d94eSDimitry Andric#endif 40aed8d94eSDimitry Andric#define _LIBCPP_DEBUG_MODE(...) __VA_ARGS__ 41d72607e9SDimitry Andric#endif 427a984708SDavid Chisnall 43d72607e9SDimitry Andric#ifndef _LIBCPP_ASSERT 44d72607e9SDimitry Andric# define _LIBCPP_ASSERT(x, m) ((void)0) 457a984708SDavid Chisnall#endif 46aed8d94eSDimitry Andric#ifndef _LIBCPP_DEBUG_ASSERT 47aed8d94eSDimitry Andric# define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0) 48aed8d94eSDimitry Andric#endif 49aed8d94eSDimitry Andric#ifndef _LIBCPP_DEBUG_MODE 50aed8d94eSDimitry Andric#define _LIBCPP_DEBUG_MODE(...) ((void)0) 51aed8d94eSDimitry Andric#endif 527a984708SDavid Chisnall 53aed8d94eSDimitry Andric#if _LIBCPP_DEBUG_LEVEL < 1 54aed8d94eSDimitry Andricclass _LIBCPP_EXCEPTION_ABI __libcpp_debug_exception; 55aed8d94eSDimitry Andric#endif 567a984708SDavid Chisnall 577a984708SDavid Chisnall_LIBCPP_BEGIN_NAMESPACE_STD 587a984708SDavid Chisnall 59aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS __libcpp_debug_info { 60aed8d94eSDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 61aed8d94eSDimitry Andric __libcpp_debug_info() 62aed8d94eSDimitry Andric : __file_(nullptr), __line_(-1), __pred_(nullptr), __msg_(nullptr) {} 63aed8d94eSDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 64aed8d94eSDimitry Andric __libcpp_debug_info(const char* __f, int __l, const char* __p, const char* __m) 65aed8d94eSDimitry Andric : __file_(__f), __line_(__l), __pred_(__p), __msg_(__m) {} 66aed8d94eSDimitry Andric const char* __file_; 67aed8d94eSDimitry Andric int __line_; 68aed8d94eSDimitry Andric const char* __pred_; 69aed8d94eSDimitry Andric const char* __msg_; 70aed8d94eSDimitry Andric}; 71aed8d94eSDimitry Andric 72aed8d94eSDimitry Andric/// __libcpp_debug_function_type - The type of the assertion failure handler. 73aed8d94eSDimitry Andrictypedef void(*__libcpp_debug_function_type)(__libcpp_debug_info const&); 74aed8d94eSDimitry Andric 75aed8d94eSDimitry Andric/// __libcpp_debug_function - The handler function called when a _LIBCPP_ASSERT 76aed8d94eSDimitry Andric/// fails. 77*b5893f02SDimitry Andricextern _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_function_type __libcpp_debug_function; 78aed8d94eSDimitry Andric 79aed8d94eSDimitry Andric/// __libcpp_abort_debug_function - A debug handler that aborts when called. 80aed8d94eSDimitry Andric_LIBCPP_NORETURN _LIBCPP_FUNC_VIS 81aed8d94eSDimitry Andricvoid __libcpp_abort_debug_function(__libcpp_debug_info const&); 82aed8d94eSDimitry Andric 83aed8d94eSDimitry Andric/// __libcpp_throw_debug_function - A debug handler that throws 84aed8d94eSDimitry Andric/// an instance of __libcpp_debug_exception when called. 85aed8d94eSDimitry Andric _LIBCPP_NORETURN _LIBCPP_FUNC_VIS 86aed8d94eSDimitry Andricvoid __libcpp_throw_debug_function(__libcpp_debug_info const&); 87aed8d94eSDimitry Andric 88aed8d94eSDimitry Andric/// __libcpp_set_debug_function - Set the debug handler to the specified 89aed8d94eSDimitry Andric/// function. 90aed8d94eSDimitry Andric_LIBCPP_FUNC_VIS 91aed8d94eSDimitry Andricbool __libcpp_set_debug_function(__libcpp_debug_function_type __func); 92aed8d94eSDimitry Andric 93aed8d94eSDimitry Andric// Setup the throwing debug handler during dynamic initialization. 94aed8d94eSDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 1 && defined(_LIBCPP_DEBUG_USE_EXCEPTIONS) 95aed8d94eSDimitry Andric# if defined(_LIBCPP_NO_EXCEPTIONS) 96aed8d94eSDimitry Andric# error _LIBCPP_DEBUG_USE_EXCEPTIONS cannot be used when exceptions are disabled. 97aed8d94eSDimitry Andric# endif 98aed8d94eSDimitry Andricstatic bool __init_dummy = __libcpp_set_debug_function(__libcpp_throw_debug_function); 99aed8d94eSDimitry Andric#endif 100aed8d94eSDimitry Andric 101aed8d94eSDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 1 || defined(_LIBCPP_BUILDING_LIBRARY) 102aed8d94eSDimitry Andricclass _LIBCPP_EXCEPTION_ABI __libcpp_debug_exception : public exception { 103aed8d94eSDimitry Andricpublic: 104aed8d94eSDimitry Andric __libcpp_debug_exception() _NOEXCEPT; 105aed8d94eSDimitry Andric explicit __libcpp_debug_exception(__libcpp_debug_info const& __i); 106aed8d94eSDimitry Andric __libcpp_debug_exception(__libcpp_debug_exception const&); 107aed8d94eSDimitry Andric ~__libcpp_debug_exception() _NOEXCEPT; 108aed8d94eSDimitry Andric const char* what() const _NOEXCEPT; 109aed8d94eSDimitry Andricprivate: 110aed8d94eSDimitry Andric struct __libcpp_debug_exception_imp; 111aed8d94eSDimitry Andric __libcpp_debug_exception_imp *__imp_; 112aed8d94eSDimitry Andric}; 113aed8d94eSDimitry Andric#endif 114aed8d94eSDimitry Andric 115aed8d94eSDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 2 || defined(_LIBCPP_BUILDING_LIBRARY) 116aed8d94eSDimitry Andric 1171bf9f7c1SDimitry Andricstruct _LIBCPP_TYPE_VIS __c_node; 1187a984708SDavid Chisnall 1191bf9f7c1SDimitry Andricstruct _LIBCPP_TYPE_VIS __i_node 1207a984708SDavid Chisnall{ 1217a984708SDavid Chisnall void* __i_; 1227a984708SDavid Chisnall __i_node* __next_; 1237a984708SDavid Chisnall __c_node* __c_; 1247a984708SDavid Chisnall 12580779b37SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1267a984708SDavid Chisnall __i_node(const __i_node&) = delete; 1277a984708SDavid Chisnall __i_node& operator=(const __i_node&) = delete; 1284f7ab58eSDimitry Andric#else 1294f7ab58eSDimitry Andricprivate: 1304f7ab58eSDimitry Andric __i_node(const __i_node&); 1314f7ab58eSDimitry Andric __i_node& operator=(const __i_node&); 1324f7ab58eSDimitry Andricpublic: 1334f7ab58eSDimitry Andric#endif 1347a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1357a984708SDavid Chisnall __i_node(void* __i, __i_node* __next, __c_node* __c) 1367a984708SDavid Chisnall : __i_(__i), __next_(__next), __c_(__c) {} 1377a984708SDavid Chisnall ~__i_node(); 1387a984708SDavid Chisnall}; 1397a984708SDavid Chisnall 1401bf9f7c1SDimitry Andricstruct _LIBCPP_TYPE_VIS __c_node 1417a984708SDavid Chisnall{ 1427a984708SDavid Chisnall void* __c_; 1437a984708SDavid Chisnall __c_node* __next_; 1447a984708SDavid Chisnall __i_node** beg_; 1457a984708SDavid Chisnall __i_node** end_; 1467a984708SDavid Chisnall __i_node** cap_; 1477a984708SDavid Chisnall 14880779b37SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1497a984708SDavid Chisnall __c_node(const __c_node&) = delete; 1507a984708SDavid Chisnall __c_node& operator=(const __c_node&) = delete; 1514f7ab58eSDimitry Andric#else 1524f7ab58eSDimitry Andricprivate: 1534f7ab58eSDimitry Andric __c_node(const __c_node&); 1544f7ab58eSDimitry Andric __c_node& operator=(const __c_node&); 1554f7ab58eSDimitry Andricpublic: 1564f7ab58eSDimitry Andric#endif 1577a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1587a984708SDavid Chisnall __c_node(void* __c, __c_node* __next) 1597a984708SDavid Chisnall : __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {} 1607a984708SDavid Chisnall virtual ~__c_node(); 1617a984708SDavid Chisnall 1627a984708SDavid Chisnall virtual bool __dereferenceable(const void*) const = 0; 1637a984708SDavid Chisnall virtual bool __decrementable(const void*) const = 0; 1647a984708SDavid Chisnall virtual bool __addable(const void*, ptrdiff_t) const = 0; 1657a984708SDavid Chisnall virtual bool __subscriptable(const void*, ptrdiff_t) const = 0; 1667a984708SDavid Chisnall 1677a984708SDavid Chisnall void __add(__i_node* __i); 1687a984708SDavid Chisnall _LIBCPP_HIDDEN void __remove(__i_node* __i); 1697a984708SDavid Chisnall}; 1707a984708SDavid Chisnall 1717a984708SDavid Chisnalltemplate <class _Cont> 1727a984708SDavid Chisnallstruct _C_node 1737a984708SDavid Chisnall : public __c_node 1747a984708SDavid Chisnall{ 1757a984708SDavid Chisnall _C_node(void* __c, __c_node* __n) 1767a984708SDavid Chisnall : __c_node(__c, __n) {} 1777a984708SDavid Chisnall 1787a984708SDavid Chisnall virtual bool __dereferenceable(const void*) const; 1797a984708SDavid Chisnall virtual bool __decrementable(const void*) const; 1807a984708SDavid Chisnall virtual bool __addable(const void*, ptrdiff_t) const; 1817a984708SDavid Chisnall virtual bool __subscriptable(const void*, ptrdiff_t) const; 1827a984708SDavid Chisnall}; 1837a984708SDavid Chisnall 1847a984708SDavid Chisnalltemplate <class _Cont> 185aed8d94eSDimitry Andricinline bool 1867a984708SDavid Chisnall_C_node<_Cont>::__dereferenceable(const void* __i) const 1877a984708SDavid Chisnall{ 1887a984708SDavid Chisnall typedef typename _Cont::const_iterator iterator; 1897a984708SDavid Chisnall const iterator* __j = static_cast<const iterator*>(__i); 19094e3ee44SDavid Chisnall _Cont* _Cp = static_cast<_Cont*>(__c_); 19194e3ee44SDavid Chisnall return _Cp->__dereferenceable(__j); 1927a984708SDavid Chisnall} 1937a984708SDavid Chisnall 1947a984708SDavid Chisnalltemplate <class _Cont> 195aed8d94eSDimitry Andricinline bool 1967a984708SDavid Chisnall_C_node<_Cont>::__decrementable(const void* __i) const 1977a984708SDavid Chisnall{ 1987a984708SDavid Chisnall typedef typename _Cont::const_iterator iterator; 1997a984708SDavid Chisnall const iterator* __j = static_cast<const iterator*>(__i); 20094e3ee44SDavid Chisnall _Cont* _Cp = static_cast<_Cont*>(__c_); 20194e3ee44SDavid Chisnall return _Cp->__decrementable(__j); 2027a984708SDavid Chisnall} 2037a984708SDavid Chisnall 2047a984708SDavid Chisnalltemplate <class _Cont> 205aed8d94eSDimitry Andricinline bool 2067a984708SDavid Chisnall_C_node<_Cont>::__addable(const void* __i, ptrdiff_t __n) const 2077a984708SDavid Chisnall{ 2087a984708SDavid Chisnall typedef typename _Cont::const_iterator iterator; 2097a984708SDavid Chisnall const iterator* __j = static_cast<const iterator*>(__i); 21094e3ee44SDavid Chisnall _Cont* _Cp = static_cast<_Cont*>(__c_); 21194e3ee44SDavid Chisnall return _Cp->__addable(__j, __n); 2127a984708SDavid Chisnall} 2137a984708SDavid Chisnall 2147a984708SDavid Chisnalltemplate <class _Cont> 215aed8d94eSDimitry Andricinline bool 2167a984708SDavid Chisnall_C_node<_Cont>::__subscriptable(const void* __i, ptrdiff_t __n) const 2177a984708SDavid Chisnall{ 2187a984708SDavid Chisnall typedef typename _Cont::const_iterator iterator; 2197a984708SDavid Chisnall const iterator* __j = static_cast<const iterator*>(__i); 22094e3ee44SDavid Chisnall _Cont* _Cp = static_cast<_Cont*>(__c_); 22194e3ee44SDavid Chisnall return _Cp->__subscriptable(__j, __n); 2227a984708SDavid Chisnall} 2237a984708SDavid Chisnall 2241bf9f7c1SDimitry Andricclass _LIBCPP_TYPE_VIS __libcpp_db 2257a984708SDavid Chisnall{ 2267a984708SDavid Chisnall __c_node** __cbeg_; 2277a984708SDavid Chisnall __c_node** __cend_; 2287a984708SDavid Chisnall size_t __csz_; 2297a984708SDavid Chisnall __i_node** __ibeg_; 2307a984708SDavid Chisnall __i_node** __iend_; 2317a984708SDavid Chisnall size_t __isz_; 2327a984708SDavid Chisnall 2337a984708SDavid Chisnall __libcpp_db(); 2347a984708SDavid Chisnallpublic: 23580779b37SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 2367a984708SDavid Chisnall __libcpp_db(const __libcpp_db&) = delete; 2377a984708SDavid Chisnall __libcpp_db& operator=(const __libcpp_db&) = delete; 2384f7ab58eSDimitry Andric#else 2394f7ab58eSDimitry Andricprivate: 2404f7ab58eSDimitry Andric __libcpp_db(const __libcpp_db&); 2414f7ab58eSDimitry Andric __libcpp_db& operator=(const __libcpp_db&); 2424f7ab58eSDimitry Andricpublic: 2434f7ab58eSDimitry Andric#endif 2447a984708SDavid Chisnall ~__libcpp_db(); 2457a984708SDavid Chisnall 2467a984708SDavid Chisnall class __db_c_iterator; 2477a984708SDavid Chisnall class __db_c_const_iterator; 2487a984708SDavid Chisnall class __db_i_iterator; 2497a984708SDavid Chisnall class __db_i_const_iterator; 2507a984708SDavid Chisnall 2517a984708SDavid Chisnall __db_c_const_iterator __c_end() const; 2527a984708SDavid Chisnall __db_i_const_iterator __i_end() const; 2537a984708SDavid Chisnall 2547a984708SDavid Chisnall template <class _Cont> 2557a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2567a984708SDavid Chisnall void __insert_c(_Cont* __c) 2577a984708SDavid Chisnall { 2587a984708SDavid Chisnall __c_node* __n = __insert_c(static_cast<void*>(__c)); 2597a984708SDavid Chisnall ::new(__n) _C_node<_Cont>(__n->__c_, __n->__next_); 2607a984708SDavid Chisnall } 2617a984708SDavid Chisnall 2627a984708SDavid Chisnall void __insert_i(void* __i); 2637a984708SDavid Chisnall __c_node* __insert_c(void* __c); 2647a984708SDavid Chisnall void __erase_c(void* __c); 2657a984708SDavid Chisnall 2667a984708SDavid Chisnall void __insert_ic(void* __i, const void* __c); 2677a984708SDavid Chisnall void __iterator_copy(void* __i, const void* __i0); 2687a984708SDavid Chisnall void __erase_i(void* __i); 2697a984708SDavid Chisnall 2707a984708SDavid Chisnall void* __find_c_from_i(void* __i) const; 2717a984708SDavid Chisnall void __invalidate_all(void* __c); 2727a984708SDavid Chisnall __c_node* __find_c_and_lock(void* __c) const; 2737a984708SDavid Chisnall __c_node* __find_c(void* __c) const; 2747a984708SDavid Chisnall void unlock() const; 2757a984708SDavid Chisnall 2767a984708SDavid Chisnall void swap(void* __c1, void* __c2); 2777a984708SDavid Chisnall 2787a984708SDavid Chisnall 2797a984708SDavid Chisnall bool __dereferenceable(const void* __i) const; 2807a984708SDavid Chisnall bool __decrementable(const void* __i) const; 2817a984708SDavid Chisnall bool __addable(const void* __i, ptrdiff_t __n) const; 2827a984708SDavid Chisnall bool __subscriptable(const void* __i, ptrdiff_t __n) const; 2834f7ab58eSDimitry Andric bool __less_than_comparable(const void* __i, const void* __j) const; 2847a984708SDavid Chisnallprivate: 2857a984708SDavid Chisnall _LIBCPP_HIDDEN 2867a984708SDavid Chisnall __i_node* __insert_iterator(void* __i); 2877a984708SDavid Chisnall _LIBCPP_HIDDEN 2887a984708SDavid Chisnall __i_node* __find_iterator(const void* __i) const; 2897a984708SDavid Chisnall 2901bf9f7c1SDimitry Andric friend _LIBCPP_FUNC_VIS __libcpp_db* __get_db(); 2917a984708SDavid Chisnall}; 2927a984708SDavid Chisnall 2931bf9f7c1SDimitry Andric_LIBCPP_FUNC_VIS __libcpp_db* __get_db(); 2941bf9f7c1SDimitry Andric_LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db(); 2957a984708SDavid Chisnall 2967a984708SDavid Chisnall 297aed8d94eSDimitry Andric#endif // _LIBCPP_DEBUG_LEVEL >= 2 || defined(_LIBCPP_BUILDING_LIBRARY) 2987a984708SDavid Chisnall 299aed8d94eSDimitry Andric_LIBCPP_END_NAMESPACE_STD 3007a984708SDavid Chisnall 3017a984708SDavid Chisnall#endif // _LIBCPP_DEBUG_H 3027a984708SDavid Chisnall 303