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