1//===------------------------ private_typeinfo.h --------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef __PRIVATE_TYPEINFO_H_
11#define __PRIVATE_TYPEINFO_H_
12
13#include "__cxxabi_config.h"
14
15#include <typeinfo>
16#include <cstddef>
17
18namespace __cxxabiv1 {
19
20class _LIBCXXABI_TYPE_VIS __shim_type_info : public std::type_info {
21public:
22  _LIBCXXABI_HIDDEN virtual ~__shim_type_info();
23
24  _LIBCXXABI_HIDDEN virtual void noop1() const;
25  _LIBCXXABI_HIDDEN virtual void noop2() const;
26  _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *thrown_type,
27                                           void *&adjustedPtr) const = 0;
28};
29
30class _LIBCXXABI_TYPE_VIS __fundamental_type_info : public __shim_type_info {
31public:
32  _LIBCXXABI_HIDDEN virtual ~__fundamental_type_info();
33  _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
34                                           void *&) const;
35};
36
37class _LIBCXXABI_TYPE_VIS __array_type_info : public __shim_type_info {
38public:
39  _LIBCXXABI_HIDDEN virtual ~__array_type_info();
40  _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
41                                           void *&) const;
42};
43
44class _LIBCXXABI_TYPE_VIS __function_type_info : public __shim_type_info {
45public:
46  _LIBCXXABI_HIDDEN virtual ~__function_type_info();
47  _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
48                                           void *&) const;
49};
50
51class _LIBCXXABI_TYPE_VIS __enum_type_info : public __shim_type_info {
52public:
53  _LIBCXXABI_HIDDEN virtual ~__enum_type_info();
54  _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
55                                           void *&) const;
56};
57
58enum
59{
60    unknown = 0,
61    public_path,
62    not_public_path,
63    yes,
64    no
65};
66
67class _LIBCXXABI_TYPE_VIS __class_type_info;
68
69struct _LIBCXXABI_HIDDEN __dynamic_cast_info
70{
71// const data supplied to the search:
72
73    const __class_type_info* dst_type;
74    const void* static_ptr;
75    const __class_type_info* static_type;
76    std::ptrdiff_t src2dst_offset;
77
78// Data that represents the answer:
79
80    // pointer to a dst_type which has (static_ptr, static_type) above it
81    const void* dst_ptr_leading_to_static_ptr;
82    // pointer to a dst_type which does not have (static_ptr, static_type) above it
83    const void* dst_ptr_not_leading_to_static_ptr;
84
85    // The following three paths are either unknown, public_path or not_public_path.
86    // access of path from dst_ptr_leading_to_static_ptr to (static_ptr, static_type)
87    int path_dst_ptr_to_static_ptr;
88    // access of path from (dynamic_ptr, dynamic_type) to (static_ptr, static_type)
89    //    when there is no dst_type along the path
90    int path_dynamic_ptr_to_static_ptr;
91    // access of path from (dynamic_ptr, dynamic_type) to dst_type
92    //    (not used if there is a (static_ptr, static_type) above a dst_type).
93    int path_dynamic_ptr_to_dst_ptr;
94
95    // Number of dst_types below (static_ptr, static_type)
96    int number_to_static_ptr;
97    // Number of dst_types not below (static_ptr, static_type)
98    int number_to_dst_ptr;
99
100// Data that helps stop the search before the entire tree is searched:
101
102    // is_dst_type_derived_from_static_type is either unknown, yes or no.
103    int is_dst_type_derived_from_static_type;
104    // Number of dst_type in tree.  If 0, then that means unknown.
105    int number_of_dst_type;
106    // communicates to a dst_type node that (static_ptr, static_type) was found
107    //    above it.
108    bool found_our_static_ptr;
109    // communicates to a dst_type node that a static_type was found
110    //    above it, but it wasn't (static_ptr, static_type)
111    bool found_any_static_type;
112    // Set whenever a search can be stopped
113    bool search_done;
114};
115
116// Has no base class
117class _LIBCXXABI_TYPE_VIS __class_type_info : public __shim_type_info {
118public:
119  _LIBCXXABI_HIDDEN virtual ~__class_type_info();
120
121  _LIBCXXABI_HIDDEN void process_static_type_above_dst(__dynamic_cast_info *,
122                                                       const void *,
123                                                       const void *, int) const;
124  _LIBCXXABI_HIDDEN void process_static_type_below_dst(__dynamic_cast_info *,
125                                                       const void *, int) const;
126  _LIBCXXABI_HIDDEN void process_found_base_class(__dynamic_cast_info *, void *,
127                                                  int) const;
128  _LIBCXXABI_HIDDEN virtual void search_above_dst(__dynamic_cast_info *,
129                                                  const void *, const void *,
130                                                  int, bool) const;
131  _LIBCXXABI_HIDDEN virtual void
132  search_below_dst(__dynamic_cast_info *, const void *, int, bool) const;
133  _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
134                                           void *&) const;
135  _LIBCXXABI_HIDDEN virtual void
136  has_unambiguous_public_base(__dynamic_cast_info *, void *, int) const;
137};
138
139// Has one non-virtual public base class at offset zero
140class _LIBCXXABI_TYPE_VIS __si_class_type_info : public __class_type_info {
141public:
142  const __class_type_info *__base_type;
143
144  _LIBCXXABI_HIDDEN virtual ~__si_class_type_info();
145
146  _LIBCXXABI_HIDDEN virtual void search_above_dst(__dynamic_cast_info *,
147                                                  const void *, const void *,
148                                                  int, bool) const;
149  _LIBCXXABI_HIDDEN virtual void
150  search_below_dst(__dynamic_cast_info *, const void *, int, bool) const;
151  _LIBCXXABI_HIDDEN virtual void
152  has_unambiguous_public_base(__dynamic_cast_info *, void *, int) const;
153};
154
155struct _LIBCXXABI_HIDDEN __base_class_type_info
156{
157public:
158    const __class_type_info* __base_type;
159    long __offset_flags;
160
161    enum __offset_flags_masks
162    {
163        __virtual_mask = 0x1,
164        __public_mask  = 0x2, // base is public
165        __offset_shift = 8
166    };
167
168    void search_above_dst(__dynamic_cast_info*, const void*, const void*, int, bool) const;
169    void search_below_dst(__dynamic_cast_info*, const void*, int, bool) const;
170    void has_unambiguous_public_base(__dynamic_cast_info*, void*, int) const;
171};
172
173// Has one or more base classes
174class _LIBCXXABI_TYPE_VIS __vmi_class_type_info : public __class_type_info {
175public:
176  unsigned int __flags;
177  unsigned int __base_count;
178  __base_class_type_info __base_info[1];
179
180  enum __flags_masks {
181    __non_diamond_repeat_mask = 0x1, // has two or more distinct base class
182                                     //    objects of the same type
183    __diamond_shaped_mask = 0x2      // has base class object with two or
184                                     //    more derived objects
185  };
186
187  _LIBCXXABI_HIDDEN virtual ~__vmi_class_type_info();
188
189  _LIBCXXABI_HIDDEN virtual void search_above_dst(__dynamic_cast_info *,
190                                                  const void *, const void *,
191                                                  int, bool) const;
192  _LIBCXXABI_HIDDEN virtual void
193  search_below_dst(__dynamic_cast_info *, const void *, int, bool) const;
194  _LIBCXXABI_HIDDEN virtual void
195  has_unambiguous_public_base(__dynamic_cast_info *, void *, int) const;
196};
197
198class _LIBCXXABI_TYPE_VIS __pbase_type_info : public __shim_type_info {
199public:
200  unsigned int __flags;
201  const __shim_type_info *__pointee;
202
203  enum __masks {
204    __const_mask = 0x1,
205    __volatile_mask = 0x2,
206    __restrict_mask = 0x4,
207    __incomplete_mask = 0x8,
208    __incomplete_class_mask = 0x10,
209    __transaction_safe_mask = 0x20,
210    // This implements the following proposal from cxx-abi-dev (not yet part of
211    // the ABI document):
212    //
213    //   http://sourcerytools.com/pipermail/cxx-abi-dev/2016-October/002986.html
214    //
215    // This is necessary for support of http://wg21.link/p0012, which permits
216    // throwing noexcept function and member function pointers and catching
217    // them as non-noexcept pointers.
218    __noexcept_mask = 0x40,
219
220    // Flags that cannot be removed by a standard conversion.
221    __no_remove_flags_mask = __const_mask | __volatile_mask | __restrict_mask,
222    // Flags that cannot be added by a standard conversion.
223    __no_add_flags_mask = __transaction_safe_mask | __noexcept_mask
224  };
225
226  _LIBCXXABI_HIDDEN virtual ~__pbase_type_info();
227  _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
228                                           void *&) const;
229};
230
231class _LIBCXXABI_TYPE_VIS __pointer_type_info : public __pbase_type_info {
232public:
233  _LIBCXXABI_HIDDEN virtual ~__pointer_type_info();
234  _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
235                                           void *&) const;
236  _LIBCXXABI_HIDDEN bool can_catch_nested(const __shim_type_info *) const;
237};
238
239class _LIBCXXABI_TYPE_VIS __pointer_to_member_type_info
240    : public __pbase_type_info {
241public:
242  const __class_type_info *__context;
243
244  _LIBCXXABI_HIDDEN virtual ~__pointer_to_member_type_info();
245  _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
246                                           void *&) const;
247  _LIBCXXABI_HIDDEN bool can_catch_nested(const __shim_type_info *) const;
248};
249
250}  // __cxxabiv1
251
252#endif  // __PRIVATE_TYPEINFO_H_
253