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