1// -*- C++ -*- 2//===--------------------------- __debug ----------------------------------===// 3// 4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5// See https://llvm.org/LICENSE.txt for license information. 6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef _LIBCPP_DEBUG_H 11#define _LIBCPP_DEBUG_H 12 13#include <__config> 14 15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 16#pragma GCC system_header 17#endif 18 19#if defined(_LIBCPP_HAS_NO_NULLPTR) 20# include <cstddef> 21#endif 22 23#if _LIBCPP_DEBUG_LEVEL >= 1 || defined(_LIBCPP_BUILDING_LIBRARY) 24# include <cstdlib> 25# include <cstdio> 26# include <cstddef> 27# include <exception> 28#endif 29 30#if _LIBCPP_DEBUG_LEVEL >= 1 && !defined(_LIBCPP_ASSERT) 31# define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : \ 32 _VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, #x, m))) 33#endif 34 35#if _LIBCPP_DEBUG_LEVEL >= 2 36#ifndef _LIBCPP_DEBUG_ASSERT 37#define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(x, m) 38#endif 39#define _LIBCPP_DEBUG_MODE(...) __VA_ARGS__ 40#endif 41 42#ifndef _LIBCPP_ASSERT 43# define _LIBCPP_ASSERT(x, m) ((void)0) 44#endif 45#ifndef _LIBCPP_DEBUG_ASSERT 46# define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0) 47#endif 48#ifndef _LIBCPP_DEBUG_MODE 49#define _LIBCPP_DEBUG_MODE(...) ((void)0) 50#endif 51 52#if _LIBCPP_DEBUG_LEVEL < 1 53class _LIBCPP_EXCEPTION_ABI __libcpp_debug_exception; 54#endif 55 56_LIBCPP_BEGIN_NAMESPACE_STD 57 58struct _LIBCPP_TEMPLATE_VIS __libcpp_debug_info { 59 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 60 __libcpp_debug_info() 61 : __file_(nullptr), __line_(-1), __pred_(nullptr), __msg_(nullptr) {} 62 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 63 __libcpp_debug_info(const char* __f, int __l, const char* __p, const char* __m) 64 : __file_(__f), __line_(__l), __pred_(__p), __msg_(__m) {} 65 const char* __file_; 66 int __line_; 67 const char* __pred_; 68 const char* __msg_; 69}; 70 71/// __libcpp_debug_function_type - The type of the assertion failure handler. 72typedef void(*__libcpp_debug_function_type)(__libcpp_debug_info const&); 73 74/// __libcpp_debug_function - The handler function called when a _LIBCPP_ASSERT 75/// fails. 76extern _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_function_type __libcpp_debug_function; 77 78/// __libcpp_abort_debug_function - A debug handler that aborts when called. 79_LIBCPP_NORETURN _LIBCPP_FUNC_VIS 80void __libcpp_abort_debug_function(__libcpp_debug_info const&); 81 82/// __libcpp_throw_debug_function - A debug handler that throws 83/// an instance of __libcpp_debug_exception when called. 84 _LIBCPP_NORETURN _LIBCPP_FUNC_VIS 85void __libcpp_throw_debug_function(__libcpp_debug_info const&); 86 87/// __libcpp_set_debug_function - Set the debug handler to the specified 88/// function. 89_LIBCPP_FUNC_VIS 90bool __libcpp_set_debug_function(__libcpp_debug_function_type __func); 91 92// Setup the throwing debug handler during dynamic initialization. 93#if _LIBCPP_DEBUG_LEVEL >= 1 && defined(_LIBCPP_DEBUG_USE_EXCEPTIONS) 94# if defined(_LIBCPP_NO_EXCEPTIONS) 95# error _LIBCPP_DEBUG_USE_EXCEPTIONS cannot be used when exceptions are disabled. 96# endif 97static bool __init_dummy = __libcpp_set_debug_function(__libcpp_throw_debug_function); 98#endif 99 100#if _LIBCPP_DEBUG_LEVEL >= 1 || defined(_LIBCPP_BUILDING_LIBRARY) 101class _LIBCPP_EXCEPTION_ABI __libcpp_debug_exception : public exception { 102public: 103 __libcpp_debug_exception() _NOEXCEPT; 104 explicit __libcpp_debug_exception(__libcpp_debug_info const& __i); 105 __libcpp_debug_exception(__libcpp_debug_exception const&); 106 ~__libcpp_debug_exception() _NOEXCEPT; 107 const char* what() const _NOEXCEPT; 108private: 109 struct __libcpp_debug_exception_imp; 110 __libcpp_debug_exception_imp *__imp_; 111}; 112#endif 113 114#if _LIBCPP_DEBUG_LEVEL >= 2 || defined(_LIBCPP_BUILDING_LIBRARY) 115 116struct _LIBCPP_TYPE_VIS __c_node; 117 118struct _LIBCPP_TYPE_VIS __i_node 119{ 120 void* __i_; 121 __i_node* __next_; 122 __c_node* __c_; 123 124#ifndef _LIBCPP_CXX03_LANG 125 __i_node(const __i_node&) = delete; 126 __i_node& operator=(const __i_node&) = delete; 127#else 128private: 129 __i_node(const __i_node&); 130 __i_node& operator=(const __i_node&); 131public: 132#endif 133 _LIBCPP_INLINE_VISIBILITY 134 __i_node(void* __i, __i_node* __next, __c_node* __c) 135 : __i_(__i), __next_(__next), __c_(__c) {} 136 ~__i_node(); 137}; 138 139struct _LIBCPP_TYPE_VIS __c_node 140{ 141 void* __c_; 142 __c_node* __next_; 143 __i_node** beg_; 144 __i_node** end_; 145 __i_node** cap_; 146 147#ifndef _LIBCPP_CXX03_LANG 148 __c_node(const __c_node&) = delete; 149 __c_node& operator=(const __c_node&) = delete; 150#else 151private: 152 __c_node(const __c_node&); 153 __c_node& operator=(const __c_node&); 154public: 155#endif 156 _LIBCPP_INLINE_VISIBILITY 157 __c_node(void* __c, __c_node* __next) 158 : __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {} 159 virtual ~__c_node(); 160 161 virtual bool __dereferenceable(const void*) const = 0; 162 virtual bool __decrementable(const void*) const = 0; 163 virtual bool __addable(const void*, ptrdiff_t) const = 0; 164 virtual bool __subscriptable(const void*, ptrdiff_t) const = 0; 165 166 void __add(__i_node* __i); 167 _LIBCPP_HIDDEN void __remove(__i_node* __i); 168}; 169 170template <class _Cont> 171struct _C_node 172 : public __c_node 173{ 174 _C_node(void* __c, __c_node* __n) 175 : __c_node(__c, __n) {} 176 177 virtual bool __dereferenceable(const void*) const; 178 virtual bool __decrementable(const void*) const; 179 virtual bool __addable(const void*, ptrdiff_t) const; 180 virtual bool __subscriptable(const void*, ptrdiff_t) const; 181}; 182 183template <class _Cont> 184inline bool 185_C_node<_Cont>::__dereferenceable(const void* __i) const 186{ 187 typedef typename _Cont::const_iterator iterator; 188 const iterator* __j = static_cast<const iterator*>(__i); 189 _Cont* _Cp = static_cast<_Cont*>(__c_); 190 return _Cp->__dereferenceable(__j); 191} 192 193template <class _Cont> 194inline bool 195_C_node<_Cont>::__decrementable(const void* __i) const 196{ 197 typedef typename _Cont::const_iterator iterator; 198 const iterator* __j = static_cast<const iterator*>(__i); 199 _Cont* _Cp = static_cast<_Cont*>(__c_); 200 return _Cp->__decrementable(__j); 201} 202 203template <class _Cont> 204inline bool 205_C_node<_Cont>::__addable(const void* __i, ptrdiff_t __n) const 206{ 207 typedef typename _Cont::const_iterator iterator; 208 const iterator* __j = static_cast<const iterator*>(__i); 209 _Cont* _Cp = static_cast<_Cont*>(__c_); 210 return _Cp->__addable(__j, __n); 211} 212 213template <class _Cont> 214inline bool 215_C_node<_Cont>::__subscriptable(const void* __i, ptrdiff_t __n) const 216{ 217 typedef typename _Cont::const_iterator iterator; 218 const iterator* __j = static_cast<const iterator*>(__i); 219 _Cont* _Cp = static_cast<_Cont*>(__c_); 220 return _Cp->__subscriptable(__j, __n); 221} 222 223class _LIBCPP_TYPE_VIS __libcpp_db 224{ 225 __c_node** __cbeg_; 226 __c_node** __cend_; 227 size_t __csz_; 228 __i_node** __ibeg_; 229 __i_node** __iend_; 230 size_t __isz_; 231 232 __libcpp_db(); 233public: 234#ifndef _LIBCPP_CXX03_LANG 235 __libcpp_db(const __libcpp_db&) = delete; 236 __libcpp_db& operator=(const __libcpp_db&) = delete; 237#else 238private: 239 __libcpp_db(const __libcpp_db&); 240 __libcpp_db& operator=(const __libcpp_db&); 241public: 242#endif 243 ~__libcpp_db(); 244 245 class __db_c_iterator; 246 class __db_c_const_iterator; 247 class __db_i_iterator; 248 class __db_i_const_iterator; 249 250 __db_c_const_iterator __c_end() const; 251 __db_i_const_iterator __i_end() const; 252 253 typedef __c_node*(_InsertConstruct)(void*, void*, __c_node*); 254 255 template <class _Cont> 256 _LIBCPP_INLINE_VISIBILITY static __c_node* __create_C_node(void *__mem, void *__c, __c_node *__next) { 257 return ::new(__mem) _C_node<_Cont>(__c, __next); 258 } 259 260 template <class _Cont> 261 _LIBCPP_INLINE_VISIBILITY 262 void __insert_c(_Cont* __c) 263 { 264 __insert_c(static_cast<void*>(__c), &__create_C_node<_Cont>); 265 } 266 267 void __insert_i(void* __i); 268 void __insert_c(void* __c, _InsertConstruct* __fn); 269 void __erase_c(void* __c); 270 271 void __insert_ic(void* __i, const void* __c); 272 void __iterator_copy(void* __i, const void* __i0); 273 void __erase_i(void* __i); 274 275 void* __find_c_from_i(void* __i) const; 276 void __invalidate_all(void* __c); 277 __c_node* __find_c_and_lock(void* __c) const; 278 __c_node* __find_c(void* __c) const; 279 void unlock() const; 280 281 void swap(void* __c1, void* __c2); 282 283 284 bool __dereferenceable(const void* __i) const; 285 bool __decrementable(const void* __i) const; 286 bool __addable(const void* __i, ptrdiff_t __n) const; 287 bool __subscriptable(const void* __i, ptrdiff_t __n) const; 288 bool __less_than_comparable(const void* __i, const void* __j) const; 289private: 290 _LIBCPP_HIDDEN 291 __i_node* __insert_iterator(void* __i); 292 _LIBCPP_HIDDEN 293 __i_node* __find_iterator(const void* __i) const; 294 295 friend _LIBCPP_FUNC_VIS __libcpp_db* __get_db(); 296}; 297 298_LIBCPP_FUNC_VIS __libcpp_db* __get_db(); 299_LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db(); 300 301 302#endif // _LIBCPP_DEBUG_LEVEL >= 2 || defined(_LIBCPP_BUILDING_LIBRARY) 303 304_LIBCPP_END_NAMESPACE_STD 305 306#endif // _LIBCPP_DEBUG_H 307 308