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