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