summaryrefslogtreecommitdiff
path: root/src/private_typeinfo.h
blob: 3922ae6ef56ebb835db2e0c04c0415850dc46f9c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
//===------------------------ private_typeinfo.h --------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef __PRIVATE_TYPEINFO_H_
#define __PRIVATE_TYPEINFO_H_

#include "__cxxabi_config.h"

#include <typeinfo>
#include <cstddef>

namespace __cxxabiv1 {

class _LIBCXXABI_TYPE_VIS __shim_type_info : public std::type_info {
public:
  _LIBCXXABI_HIDDEN virtual ~__shim_type_info();

  _LIBCXXABI_HIDDEN virtual void noop1() const;
  _LIBCXXABI_HIDDEN virtual void noop2() const;
  _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *thrown_type,
                                           void *&adjustedPtr) const = 0;
};

class _LIBCXXABI_TYPE_VIS __fundamental_type_info : public __shim_type_info {
public:
  _LIBCXXABI_HIDDEN virtual ~__fundamental_type_info();
  _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
                                           void *&) const;
};

class _LIBCXXABI_TYPE_VIS __array_type_info : public __shim_type_info {
public:
  _LIBCXXABI_HIDDEN virtual ~__array_type_info();
  _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
                                           void *&) const;
};

class _LIBCXXABI_TYPE_VIS __function_type_info : public __shim_type_info {
public:
  _LIBCXXABI_HIDDEN virtual ~__function_type_info();
  _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
                                           void *&) const;
};

class _LIBCXXABI_TYPE_VIS __enum_type_info : public __shim_type_info {
public:
  _LIBCXXABI_HIDDEN virtual ~__enum_type_info();
  _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
                                           void *&) const;
};

enum
{
    unknown = 0,
    public_path,
    not_public_path,
    yes,
    no
};

class _LIBCXXABI_TYPE_VIS __class_type_info;

struct _LIBCXXABI_HIDDEN __dynamic_cast_info
{
// const data supplied to the search:

    const __class_type_info* dst_type;
    const void* static_ptr;
    const __class_type_info* static_type;
    std::ptrdiff_t src2dst_offset;

// Data that represents the answer:

    // pointer to a dst_type which has (static_ptr, static_type) above it
    const void* dst_ptr_leading_to_static_ptr;
    // pointer to a dst_type which does not have (static_ptr, static_type) above it
    const void* dst_ptr_not_leading_to_static_ptr;

    // The following three paths are either unknown, public_path or not_public_path.
    // access of path from dst_ptr_leading_to_static_ptr to (static_ptr, static_type)
    int path_dst_ptr_to_static_ptr;
    // access of path from (dynamic_ptr, dynamic_type) to (static_ptr, static_type)
    //    when there is no dst_type along the path
    int path_dynamic_ptr_to_static_ptr;
    // access of path from (dynamic_ptr, dynamic_type) to dst_type
    //    (not used if there is a (static_ptr, static_type) above a dst_type).
    int path_dynamic_ptr_to_dst_ptr;

    // Number of dst_types below (static_ptr, static_type)
    int number_to_static_ptr;
    // Number of dst_types not below (static_ptr, static_type)
    int number_to_dst_ptr;

// Data that helps stop the search before the entire tree is searched:

    // is_dst_type_derived_from_static_type is either unknown, yes or no.
    int is_dst_type_derived_from_static_type;
    // Number of dst_type in tree.  If 0, then that means unknown.
    int number_of_dst_type;
    // communicates to a dst_type node that (static_ptr, static_type) was found
    //    above it.
    bool found_our_static_ptr;
    // communicates to a dst_type node that a static_type was found
    //    above it, but it wasn't (static_ptr, static_type)
    bool found_any_static_type;
    // Set whenever a search can be stopped
    bool search_done;
};

// Has no base class
class _LIBCXXABI_TYPE_VIS __class_type_info : public __shim_type_info {
public:
  _LIBCXXABI_HIDDEN virtual ~__class_type_info();

  _LIBCXXABI_HIDDEN void process_static_type_above_dst(__dynamic_cast_info *,
                                                       const void *,
                                                       const void *, int) const;
  _LIBCXXABI_HIDDEN void process_static_type_below_dst(__dynamic_cast_info *,
                                                       const void *, int) const;
  _LIBCXXABI_HIDDEN void process_found_base_class(__dynamic_cast_info *, void *,
                                                  int) const;
  _LIBCXXABI_HIDDEN virtual void search_above_dst(__dynamic_cast_info *,
                                                  const void *, const void *,
                                                  int, bool) const;
  _LIBCXXABI_HIDDEN virtual void
  search_below_dst(__dynamic_cast_info *, const void *, int, bool) const;
  _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
                                           void *&) const;
  _LIBCXXABI_HIDDEN virtual void
  has_unambiguous_public_base(__dynamic_cast_info *, void *, int) const;
};

// Has one non-virtual public base class at offset zero
class _LIBCXXABI_TYPE_VIS __si_class_type_info : public __class_type_info {
public:
  const __class_type_info *__base_type;

  _LIBCXXABI_HIDDEN virtual ~__si_class_type_info();

  _LIBCXXABI_HIDDEN virtual void search_above_dst(__dynamic_cast_info *,
                                                  const void *, const void *,
                                                  int, bool) const;
  _LIBCXXABI_HIDDEN virtual void
  search_below_dst(__dynamic_cast_info *, const void *, int, bool) const;
  _LIBCXXABI_HIDDEN virtual void
  has_unambiguous_public_base(__dynamic_cast_info *, void *, int) const;
};

struct _LIBCXXABI_HIDDEN __base_class_type_info
{
public:
    const __class_type_info* __base_type;
    long __offset_flags;

    enum __offset_flags_masks
    {
        __virtual_mask = 0x1,
        __public_mask  = 0x2, // base is public
        __offset_shift = 8
    };

    void search_above_dst(__dynamic_cast_info*, const void*, const void*, int, bool) const;
    void search_below_dst(__dynamic_cast_info*, const void*, int, bool) const;
    void has_unambiguous_public_base(__dynamic_cast_info*, void*, int) const;
};

// Has one or more base classes
class _LIBCXXABI_TYPE_VIS __vmi_class_type_info : public __class_type_info {
public:
  unsigned int __flags;
  unsigned int __base_count;
  __base_class_type_info __base_info[1];

  enum __flags_masks {
    __non_diamond_repeat_mask = 0x1, // has two or more distinct base class
                                     //    objects of the same type
    __diamond_shaped_mask = 0x2      // has base class object with two or
                                     //    more derived objects
  };

  _LIBCXXABI_HIDDEN virtual ~__vmi_class_type_info();

  _LIBCXXABI_HIDDEN virtual void search_above_dst(__dynamic_cast_info *,
                                                  const void *, const void *,
                                                  int, bool) const;
  _LIBCXXABI_HIDDEN virtual void
  search_below_dst(__dynamic_cast_info *, const void *, int, bool) const;
  _LIBCXXABI_HIDDEN virtual void
  has_unambiguous_public_base(__dynamic_cast_info *, void *, int) const;
};

class _LIBCXXABI_TYPE_VIS __pbase_type_info : public __shim_type_info {
public:
  unsigned int __flags;
  const __shim_type_info *__pointee;

  enum __masks {
    __const_mask = 0x1,
    __volatile_mask = 0x2,
    __restrict_mask = 0x4,
    __incomplete_mask = 0x8,
    __incomplete_class_mask = 0x10,
    __transaction_safe_mask = 0x20,
    // This implements the following proposal from cxx-abi-dev (not yet part of
    // the ABI document):
    //
    //   http://sourcerytools.com/pipermail/cxx-abi-dev/2016-October/002986.html
    //
    // This is necessary for support of http://wg21.link/p0012, which permits
    // throwing noexcept function and member function pointers and catching
    // them as non-noexcept pointers.
    __noexcept_mask = 0x40,

    // Flags that cannot be removed by a standard conversion.
    __no_remove_flags_mask = __const_mask | __volatile_mask | __restrict_mask,
    // Flags that cannot be added by a standard conversion.
    __no_add_flags_mask = __transaction_safe_mask | __noexcept_mask
  };

  _LIBCXXABI_HIDDEN virtual ~__pbase_type_info();
  _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
                                           void *&) const;
};

class _LIBCXXABI_TYPE_VIS __pointer_type_info : public __pbase_type_info {
public:
  _LIBCXXABI_HIDDEN virtual ~__pointer_type_info();
  _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
                                           void *&) const;
  _LIBCXXABI_HIDDEN bool can_catch_nested(const __shim_type_info *) const;
};

class _LIBCXXABI_TYPE_VIS __pointer_to_member_type_info
    : public __pbase_type_info {
public:
  const __class_type_info *__context;

  _LIBCXXABI_HIDDEN virtual ~__pointer_to_member_type_info();
  _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
                                           void *&) const;
  _LIBCXXABI_HIDDEN bool can_catch_nested(const __shim_type_info *) const;
};

}  // __cxxabiv1

#endif  // __PRIVATE_TYPEINFO_H_