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