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 
18 namespace __cxxabiv1 {
19 
20 class _LIBCXXABI_TYPE_VIS __shim_type_info : public std::type_info {
21 public:
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 
30 class _LIBCXXABI_TYPE_VIS __fundamental_type_info : public __shim_type_info {
31 public:
32   _LIBCXXABI_HIDDEN virtual ~__fundamental_type_info();
33   _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
34                                            void *&) const;
35 };
36 
37 class _LIBCXXABI_TYPE_VIS __array_type_info : public __shim_type_info {
38 public:
39   _LIBCXXABI_HIDDEN virtual ~__array_type_info();
40   _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
41                                            void *&) const;
42 };
43 
44 class _LIBCXXABI_TYPE_VIS __function_type_info : public __shim_type_info {
45 public:
46   _LIBCXXABI_HIDDEN virtual ~__function_type_info();
47   _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
48                                            void *&) const;
49 };
50 
51 class _LIBCXXABI_TYPE_VIS __enum_type_info : public __shim_type_info {
52 public:
53   _LIBCXXABI_HIDDEN virtual ~__enum_type_info();
54   _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *,
55                                            void *&) const;
56 };
57 
58 enum
59 {
60     unknown = 0,
61     public_path,
62     not_public_path,
63     yes,
64     no
65 };
66 
67 class _LIBCXXABI_TYPE_VIS __class_type_info;
68 
69 struct _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
117 class _LIBCXXABI_TYPE_VIS __class_type_info : public __shim_type_info {
118 public:
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
140 class _LIBCXXABI_TYPE_VIS __si_class_type_info : public __class_type_info {
141 public:
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 
155 struct _LIBCXXABI_HIDDEN __base_class_type_info
156 {
157 public:
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
174 class _LIBCXXABI_TYPE_VIS __vmi_class_type_info : public __class_type_info {
175 public:
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 
198 class _LIBCXXABI_TYPE_VIS __pbase_type_info : public __shim_type_info {
199 public:
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 
231 class _LIBCXXABI_TYPE_VIS __pointer_type_info : public __pbase_type_info {
232 public:
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 
239 class _LIBCXXABI_TYPE_VIS __pointer_to_member_type_info
240     : public __pbase_type_info {
241 public:
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