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