1 // Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007
2 // Free Software Foundation
4 // This file is part of GCC.
6 // GCC is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2, or (at your option)
11 // GCC is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with GCC; see the file COPYING. If not, write to
18 // the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19 // Boston, MA 02110-1301, USA.
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline enums from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
32 namespace __cxxabiv1
{
34 __vmi_class_type_info::
35 ~__vmi_class_type_info ()
38 __class_type_info::__sub_kind
__vmi_class_type_info::
39 __do_find_public_src (ptrdiff_t src2dst
,
41 const __class_type_info
*src_type
,
42 const void *src_ptr
) const
44 if (obj_ptr
== src_ptr
&& *this == *src_type
)
45 return __contained_public
;
47 for (std::size_t i
= __base_count
; i
--;)
49 if (!__base_info
[i
].__is_public_p ())
50 continue; // Not public, can't be here.
52 const void *base
= obj_ptr
;
53 ptrdiff_t offset
= __base_info
[i
].__offset ();
54 bool is_virtual
= __base_info
[i
].__is_virtual_p ();
59 continue; // Not a virtual base, so can't be here.
61 base
= convert_to_base (base
, is_virtual
, offset
);
63 __sub_kind base_kind
= __base_info
[i
].__base_type
->__do_find_public_src
64 (src2dst
, base
, src_type
, src_ptr
);
65 if (contained_p (base_kind
))
68 base_kind
= __sub_kind (base_kind
| __contained_virtual_mask
);
73 return __not_contained
;
76 // This is a big hairy function. Although the run-time behaviour of
77 // dynamic_cast is simple to describe, it gives rise to some non-obvious
78 // behaviour. We also desire to determine as early as possible any definite
79 // answer we can get. Because it is unknown what the run-time ratio of
80 // succeeding to failing dynamic casts is, we do not know in which direction
81 // to bias any optimizations. To that end we make no particular effort towards
82 // early fail answers or early success answers. Instead we try to minimize
83 // work by filling in things lazily (when we know we need the information),
84 // and opportunisticly take early success or failure results.
85 bool __vmi_class_type_info::
86 __do_dyncast (ptrdiff_t src2dst
,
87 __sub_kind access_path
,
88 const __class_type_info
*dst_type
,
90 const __class_type_info
*src_type
,
92 __dyncast_result
&__restrict result
) const
94 if (result
.whole_details
& __flags_unknown_mask
)
95 result
.whole_details
= __flags
;
97 if (obj_ptr
== src_ptr
&& *this == *src_type
)
99 // The src object we started from. Indicate how we are accessible from
100 // the most derived object.
101 result
.whole2src
= access_path
;
104 if (*this == *dst_type
)
106 result
.dst_ptr
= obj_ptr
;
107 result
.whole2dst
= access_path
;
109 result
.dst2src
= adjust_pointer
<void> (obj_ptr
, src2dst
) == src_ptr
110 ? __contained_public
: __not_contained
;
111 else if (src2dst
== -2)
112 result
.dst2src
= __not_contained
;
116 bool result_ambig
= false;
117 for (std::size_t i
= __base_count
; i
--;)
119 __dyncast_result
result2 (result
.whole_details
);
120 void const *base
= obj_ptr
;
121 __sub_kind base_access
= access_path
;
122 ptrdiff_t offset
= __base_info
[i
].__offset ();
123 bool is_virtual
= __base_info
[i
].__is_virtual_p ();
126 base_access
= __sub_kind (base_access
| __contained_virtual_mask
);
127 base
= convert_to_base (base
, is_virtual
, offset
);
129 if (!__base_info
[i
].__is_public_p ())
132 !(result
.whole_details
133 & (__non_diamond_repeat_mask
| __diamond_shaped_mask
)))
134 // The hierarchy has no duplicate bases (which might ambiguate
135 // things) and where we started is not a public base of what we
136 // want (so it cannot be a downcast). There is nothing of interest
137 // hiding in a non-public base.
139 base_access
= __sub_kind (base_access
& ~__contained_public_mask
);
143 = __base_info
[i
].__base_type
->__do_dyncast (src2dst
, base_access
,
145 src_type
, src_ptr
, result2
);
146 result
.whole2src
= __sub_kind (result
.whole2src
| result2
.whole2src
);
147 if (result2
.dst2src
== __contained_public
148 || result2
.dst2src
== __contained_ambig
)
150 result
.dst_ptr
= result2
.dst_ptr
;
151 result
.whole2dst
= result2
.whole2dst
;
152 result
.dst2src
= result2
.dst2src
;
153 // Found a downcast which can't be bettered or an ambiguous downcast
154 // which can't be disambiguated
155 return result2_ambig
;
158 if (!result_ambig
&& !result
.dst_ptr
)
160 // Not found anything yet.
161 result
.dst_ptr
= result2
.dst_ptr
;
162 result
.whole2dst
= result2
.whole2dst
;
163 result_ambig
= result2_ambig
;
164 if (result
.dst_ptr
&& result
.whole2src
!= __unknown
165 && !(__flags
& __non_diamond_repeat_mask
))
166 // Found dst and src and we don't have repeated bases.
169 else if (result
.dst_ptr
&& result
.dst_ptr
== result2
.dst_ptr
)
171 // Found at same address, must be via virtual. Pick the most
174 __sub_kind (result
.whole2dst
| result2
.whole2dst
);
176 else if ((result
.dst_ptr
!= 0 && result2
.dst_ptr
!= 0)
177 || (result
.dst_ptr
!= 0 && result2_ambig
)
178 || (result2
.dst_ptr
!= 0 && result_ambig
))
180 // Found two different DST_TYPE bases, or a valid one and a set of
181 // ambiguous ones, must disambiguate. See whether SRC_PTR is
182 // contained publicly within one of the non-ambiguous choices. If it
183 // is in only one, then that's the choice. If it is in both, then
184 // we're ambiguous and fail. If it is in neither, we're ambiguous,
185 // but don't yet fail as we might later find a third base which does
188 __sub_kind new_sub_kind
= result2
.dst2src
;
189 __sub_kind old_sub_kind
= result
.dst2src
;
191 if (contained_p (result
.whole2src
)
192 && (!virtual_p (result
.whole2src
)
193 || !(result
.whole_details
& __diamond_shaped_mask
)))
195 // We already found SRC_PTR as a base of most derived, and
196 // either it was non-virtual, or the whole hierarchy is
197 // not-diamond shaped. Therefore if it is in either choice, it
198 // can only be in one of them, and we will already know.
199 if (old_sub_kind
== __unknown
)
200 old_sub_kind
= __not_contained
;
201 if (new_sub_kind
== __unknown
)
202 new_sub_kind
= __not_contained
;
206 if (old_sub_kind
>= __not_contained
)
207 ;// already calculated
208 else if (contained_p (new_sub_kind
)
209 && (!virtual_p (new_sub_kind
)
210 || !(__flags
& __diamond_shaped_mask
)))
211 // Already found inside the other choice, and it was
212 // non-virtual or we are not diamond shaped.
213 old_sub_kind
= __not_contained
;
215 old_sub_kind
= dst_type
->__find_public_src
216 (src2dst
, result
.dst_ptr
, src_type
, src_ptr
);
218 if (new_sub_kind
>= __not_contained
)
219 ;// already calculated
220 else if (contained_p (old_sub_kind
)
221 && (!virtual_p (old_sub_kind
)
222 || !(__flags
& __diamond_shaped_mask
)))
223 // Already found inside the other choice, and it was
224 // non-virtual or we are not diamond shaped.
225 new_sub_kind
= __not_contained
;
227 new_sub_kind
= dst_type
->__find_public_src
228 (src2dst
, result2
.dst_ptr
, src_type
, src_ptr
);
231 // Neither sub_kind can be contained_ambig -- we bail out early
232 // when we find those.
233 if (contained_p (__sub_kind (new_sub_kind
^ old_sub_kind
)))
235 // Only on one choice, not ambiguous.
236 if (contained_p (new_sub_kind
))
239 result
.dst_ptr
= result2
.dst_ptr
;
240 result
.whole2dst
= result2
.whole2dst
;
241 result_ambig
= false;
242 old_sub_kind
= new_sub_kind
;
244 result
.dst2src
= old_sub_kind
;
245 if (public_p (result
.dst2src
))
246 return false; // Can't be an ambiguating downcast for later discovery.
247 if (!virtual_p (result
.dst2src
))
248 return false; // Found non-virtually can't be bettered
250 else if (contained_p (__sub_kind (new_sub_kind
& old_sub_kind
)))
253 result
.dst_ptr
= NULL
;
254 result
.dst2src
= __contained_ambig
;
255 return true; // Fail.
259 // In neither publicly, ambiguous for the moment, but keep
260 // looking. It is possible that it was private in one or
261 // both and therefore we should fail, but that's just tough.
262 result
.dst_ptr
= NULL
;
263 result
.dst2src
= __not_contained
;
268 if (result
.whole2src
== __contained_private
)
269 // We found SRC_PTR as a private non-virtual base, therefore all
270 // cross casts will fail. We have already found a down cast, if
278 bool __vmi_class_type_info::
279 __do_upcast (const __class_type_info
*dst
, const void *obj_ptr
,
280 __upcast_result
&__restrict result
) const
282 if (__class_type_info::__do_upcast (dst
, obj_ptr
, result
))
285 int src_details
= result
.src_details
;
286 if (src_details
& __flags_unknown_mask
)
287 src_details
= __flags
;
289 for (std::size_t i
= __base_count
; i
--;)
291 __upcast_result
result2 (src_details
);
292 const void *base
= obj_ptr
;
293 ptrdiff_t offset
= __base_info
[i
].__offset ();
294 bool is_virtual
= __base_info
[i
].__is_virtual_p ();
295 bool is_public
= __base_info
[i
].__is_public_p ();
297 if (!is_public
&& !(src_details
& __non_diamond_repeat_mask
))
298 // original cannot have an ambiguous base, so skip private bases
302 base
= convert_to_base (base
, is_virtual
, offset
);
304 if (__base_info
[i
].__base_type
->__do_upcast (dst
, base
, result2
))
306 if (result2
.base_type
== nonvirtual_base_type
&& is_virtual
)
307 result2
.base_type
= __base_info
[i
].__base_type
;
308 if (contained_p (result2
.part2dst
) && !is_public
)
309 result2
.part2dst
= __sub_kind (result2
.part2dst
& ~__contained_public_mask
);
311 if (!result
.base_type
)
314 if (!contained_p (result
.part2dst
))
315 return true; // found ambiguously
317 if (result
.part2dst
& __contained_public_mask
)
319 if (!(__flags
& __non_diamond_repeat_mask
))
320 return true; // cannot have an ambiguous other base
324 if (!virtual_p (result
.part2dst
))
325 return true; // cannot have another path
326 if (!(__flags
& __diamond_shaped_mask
))
327 return true; // cannot have a more accessible path
330 else if (result
.dst_ptr
!= result2
.dst_ptr
)
332 // Found an ambiguity.
333 result
.dst_ptr
= NULL
;
334 result
.part2dst
= __contained_ambig
;
337 else if (result
.dst_ptr
)
339 // Ok, found real object via a virtual path.
341 = __sub_kind (result
.part2dst
| result2
.part2dst
);
345 // Dealing with a null pointer, need to check vbase
346 // containing each of the two choices.
347 if (result2
.base_type
== nonvirtual_base_type
348 || result
.base_type
== nonvirtual_base_type
349 || !(*result2
.base_type
== *result
.base_type
))
351 // Already ambiguous, not virtual or via different virtuals.
353 result
.part2dst
= __contained_ambig
;
357 = __sub_kind (result
.part2dst
| result2
.part2dst
);
361 return result
.part2dst
!= __unknown
;