]>
Commit | Line | Data |
---|---|---|
06bd10fb | 1 | // RTTI support internals for -*- C++ -*- |
748086b7 | 2 | // Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2004, 2009 |
aefb3380 BK |
3 | // Free Software Foundation |
4 | ||
ce120bb2 MK |
5 | // This file is part of GCC. |
6 | // | |
7 | // GCC is free software; you can redistribute it and/or modify | |
8 | // it under the terms of the GNU General Public License as published by | |
748086b7 | 9 | // the Free Software Foundation; either version 3, or (at your option) |
ce120bb2 MK |
10 | // any later version. |
11 | ||
12 | // GCC is distributed in the hope that it will be useful, | |
13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | // GNU General Public License for more details. | |
16 | ||
748086b7 JJ |
17 | // Under Section 7 of GPL version 3, you are granted additional |
18 | // permissions described in the GCC Runtime Library Exception, version | |
19 | // 3.1, as published by the Free Software Foundation. | |
ce120bb2 | 20 | |
748086b7 JJ |
21 | // You should have received a copy of the GNU General Public License and |
22 | // a copy of the GCC Runtime Library Exception along with this program; | |
23 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
24 | // <http://www.gnu.org/licenses/>. | |
ce120bb2 | 25 | |
06bd10fb | 26 | #include "typeinfo" |
6b76f569 | 27 | #include <cstddef> |
06bd10fb BK |
28 | |
29 | // Class declarations shared between the typeinfo implementation files. | |
30 | ||
06bd10fb | 31 | #include <cxxabi.h> |
bd994a48 MM |
32 | |
33 | namespace __cxxabiv1 { | |
34 | ||
35 | inline bool __pbase_type_info:: | |
36 | __pointer_catch (const __pbase_type_info *thrown_type, | |
37 | void **thr_obj, | |
38 | unsigned outer) const | |
39 | { | |
40 | return __pointee->__do_catch (thrown_type->__pointee, thr_obj, outer + 2); | |
41 | } | |
42 | ||
43 | namespace { | |
44 | ||
45 | using namespace std; | |
46 | using namespace abi; | |
47 | ||
48 | // Initial part of a vtable, this structure is used with offsetof, so we don't | |
49 | // have to keep alignments consistent manually. | |
50 | struct vtable_prefix | |
51 | { | |
52 | // Offset to most derived object. | |
53 | ptrdiff_t whole_object; | |
54 | ||
55 | // Additional padding if necessary. | |
56 | #ifdef _GLIBCXX_VTABLE_PADDING | |
57 | ptrdiff_t padding1; | |
58 | #endif | |
59 | ||
60 | // Pointer to most derived type_info. | |
61 | const __class_type_info *whole_type; | |
62 | ||
63 | // Additional padding if necessary. | |
64 | #ifdef _GLIBCXX_VTABLE_PADDING | |
65 | ptrdiff_t padding2; | |
66 | #endif | |
67 | ||
68 | // What a class's vptr points to. | |
69 | const void *origin; | |
70 | }; | |
71 | ||
72 | template <typename T> | |
73 | inline const T * | |
74 | adjust_pointer (const void *base, ptrdiff_t offset) | |
75 | { | |
76 | return reinterpret_cast <const T *> | |
77 | (reinterpret_cast <const char *> (base) + offset); | |
78 | } | |
79 | ||
80 | // ADDR is a pointer to an object. Convert it to a pointer to a base, | |
81 | // using OFFSET. IS_VIRTUAL is true, if we are getting a virtual base. | |
82 | inline void const * | |
83 | convert_to_base (void const *addr, bool is_virtual, ptrdiff_t offset) | |
84 | { | |
85 | if (is_virtual) | |
86 | { | |
87 | const void *vtable = *static_cast <const void *const *> (addr); | |
88 | ||
89 | offset = *adjust_pointer<ptrdiff_t> (vtable, offset); | |
90 | } | |
91 | ||
92 | return adjust_pointer<void> (addr, offset); | |
93 | } | |
94 | ||
95 | // some predicate functions for __class_type_info::__sub_kind | |
96 | inline bool contained_p (__class_type_info::__sub_kind access_path) | |
97 | { | |
98 | return access_path >= __class_type_info::__contained_mask; | |
99 | } | |
100 | inline bool public_p (__class_type_info::__sub_kind access_path) | |
101 | { | |
102 | return access_path & __class_type_info::__contained_public_mask; | |
103 | } | |
104 | inline bool virtual_p (__class_type_info::__sub_kind access_path) | |
105 | { | |
106 | return (access_path & __class_type_info::__contained_virtual_mask); | |
107 | } | |
108 | inline bool contained_public_p (__class_type_info::__sub_kind access_path) | |
109 | { | |
110 | return ((access_path & __class_type_info::__contained_public) | |
111 | == __class_type_info::__contained_public); | |
112 | } | |
113 | inline bool contained_nonpublic_p (__class_type_info::__sub_kind access_path) | |
114 | { | |
115 | return ((access_path & __class_type_info::__contained_public) | |
116 | == __class_type_info::__contained_mask); | |
117 | } | |
118 | inline bool contained_nonvirtual_p (__class_type_info::__sub_kind access_path) | |
119 | { | |
120 | return ((access_path & (__class_type_info::__contained_mask | |
121 | | __class_type_info::__contained_virtual_mask)) | |
122 | == __class_type_info::__contained_mask); | |
123 | } | |
124 | ||
125 | static const __class_type_info *const nonvirtual_base_type = | |
126 | static_cast <const __class_type_info *> (0) + 1; | |
127 | ||
128 | } // namespace | |
129 | ||
130 | // __upcast_result is used to hold information during traversal of a class | |
131 | // hierarchy when catch matching. | |
132 | struct __class_type_info::__upcast_result | |
133 | { | |
134 | const void *dst_ptr; // pointer to caught object | |
135 | __sub_kind part2dst; // path from current base to target | |
136 | int src_details; // hints about the source type hierarchy | |
137 | const __class_type_info *base_type; // where we found the target, | |
138 | // if in vbase the __class_type_info of vbase | |
139 | // if a non-virtual base then 1 | |
140 | // else NULL | |
141 | __upcast_result (int d) | |
142 | :dst_ptr (NULL), part2dst (__unknown), src_details (d), base_type (NULL) | |
143 | {} | |
144 | }; | |
145 | ||
146 | // __dyncast_result is used to hold information during traversal of a class | |
147 | // hierarchy when dynamic casting. | |
148 | struct __class_type_info::__dyncast_result | |
149 | { | |
150 | const void *dst_ptr; // pointer to target object or NULL | |
151 | __sub_kind whole2dst; // path from most derived object to target | |
152 | __sub_kind whole2src; // path from most derived object to sub object | |
153 | __sub_kind dst2src; // path from target to sub object | |
154 | int whole_details; // details of the whole class hierarchy | |
155 | ||
156 | __dyncast_result (int details_ = __vmi_class_type_info::__flags_unknown_mask) | |
157 | :dst_ptr (NULL), whole2dst (__unknown), | |
158 | whole2src (__unknown), dst2src (__unknown), | |
159 | whole_details (details_) | |
160 | {} | |
161 | ||
162 | protected: | |
163 | __dyncast_result(const __dyncast_result&); | |
164 | ||
165 | __dyncast_result& | |
166 | operator=(const __dyncast_result&); | |
167 | }; | |
168 | ||
169 | inline __class_type_info::__sub_kind __class_type_info:: | |
170 | __find_public_src (ptrdiff_t src2dst, | |
171 | const void *obj_ptr, | |
172 | const __class_type_info *src_type, | |
173 | const void *src_ptr) const | |
174 | { | |
175 | if (src2dst >= 0) | |
176 | return adjust_pointer <void> (obj_ptr, src2dst) == src_ptr | |
177 | ? __contained_public : __not_contained; | |
178 | if (src2dst == -2) | |
179 | return __not_contained; | |
180 | return __do_find_public_src (src2dst, obj_ptr, src_type, src_ptr); | |
181 | } | |
182 | ||
183 | } |