1 // Methods for type_info for -*- C++ -*- Run Time Type Identification.
2 // Copyright (C) 1994, 1996, 1998, 1999, 2000 Free Software Foundation
4 // This file is part of GNU CC.
6 // GNU CC 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 // GNU CC 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 GNU CC; see the file COPYING. If not, write to
18 // the Free Software Foundation, 59 Temple Place - Suite 330,
19 // Boston, MA 02111-1307, 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 functions 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.
30 #pragma implementation "typeinfo"
34 #include "new" // for placement new
36 // This file contains the minimal working set necessary to link with code
37 // that uses virtual functions and -frtti but does not actually use RTTI
44 #if !__GXX_MERGED_TYPEINFO_NAMES
46 // We can't rely on common symbols being shared between shared objects.
48 operator== (const std::type_info
& arg
) const
50 return (&arg
== this) || (__builtin_strcmp (name (), arg
.name ()) == 0);
55 #if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
60 // ADDR is a pointer to an object. Convert it to a pointer to a base,
63 convert_to_base (void *addr
, bool is_virtual
, myint32 offset
)
69 return (char *) addr
+ offset
;
71 // Under the old ABI, the offset gives us the address of a pointer
72 // to the virtual base.
73 return *((void **) ((char *) addr
+ offset
));
79 __rtti_class (void *addr
, const char *name
,
80 const __class_type_info::base_info
*bl
, std::size_t bn
)
81 { new (addr
) __class_type_info (name
, bl
, bn
); }
84 __rtti_si (void *addr
, const char *n
, const std::type_info
*ti
)
86 new (addr
) __si_type_info
87 (n
, static_cast <const __user_type_info
&> (*ti
));
91 __rtti_user (void *addr
, const char *name
)
92 { new (addr
) __user_type_info (name
); }
94 // Upcast for catch checking. OBJPTR points to the thrown object and might be
95 // NULL. Return 0 on failure, non-zero on success. Set *ADJPTR to adjusted
97 int __user_type_info::
98 upcast (const type_info
&target
, void *objptr
,
101 upcast_result result
;
103 if (do_upcast (contained_public
, target
, objptr
, result
))
105 *adjptr
= result
.target_obj
;
106 return contained_public_p (result
.whole2target
);
109 // Down or cross cast for dynamic_cast. OBJPTR points to the most derrived
110 // object, SUBPTR points to the static base object. Both must not be NULL.
111 // TARGET specifies the desired target type, SUBTYPE specifies the static
112 // type. Both must be defined. Returns adjusted object pointer on success,
113 // NULL on failure. [expr.dynamic.cast]/8 says 'unambiguous public base'. This
114 // itself is an ambiguous statement. We choose it to mean the base must be
115 // separately unambiguous and public, rather than unambiguous considering only
117 void *__user_type_info::
119 const type_info
&target
, void *objptr
,
120 const type_info
&subtype
, void *subptr
) const
122 dyncast_result result
;
124 do_dyncast (boff
, contained_public
,
125 target
, objptr
, subtype
, subptr
, result
);
126 if (!result
.target_obj
)
128 if (contained_public_p (result
.target2sub
))
129 return result
.target_obj
;
130 if (contained_public_p (sub_kind (result
.whole2sub
& result
.whole2target
)))
131 // Found a valid cross cast
132 return result
.target_obj
;
133 if (contained_nonvirtual_p (result
.whole2sub
))
134 // Found an invalid cross cast, which cannot also be a down cast
136 if (result
.target2sub
== unknown
)
137 result
.target2sub
= static_cast <const __user_type_info
&> (target
)
138 .find_public_subobj (boff
, subtype
,
139 result
.target_obj
, subptr
);
140 if (contained_public_p (result
.target2sub
))
141 // Found a valid down cast
142 return result
.target_obj
;
143 // Must be an invalid down cast, or the cross cast wasn't bettered
147 // Catch cast helper. ACCESS_PATH is the access from the complete thrown
148 // object to this base. TARGET is the desired type we want to catch. OBJPTR
149 // points to this base within the throw object, it might be NULL. Fill in
150 // RESULT with what we find. Return true, should we determine catch must fail.
151 bool __user_type_info::
152 do_upcast (sub_kind access_path
,
153 const type_info
&target
, void *objptr
,
154 upcast_result
&__restrict result
) const
158 result
.target_obj
= objptr
;
159 result
.base_type
= nonvirtual_base_type
;
160 result
.whole2target
= access_path
;
161 return contained_nonpublic_p (access_path
);
166 // dynamic cast helper. ACCESS_PATH gives the access from the most derived
167 // object to this base. TARGET indicates the desired type we want. OBJPTR
168 // points to this base within the object. SUBTYPE indicates the static type
169 // started from and SUBPTR points to that base within the most derived object.
170 // Fill in RESULT with what we find. Return true if we have located an
172 bool __user_type_info::
173 do_dyncast (int, sub_kind access_path
,
174 const type_info
&target
, void *objptr
,
175 const type_info
&subtype
, void *subptr
,
176 dyncast_result
&__restrict result
) const
178 if (objptr
== subptr
&& *this == subtype
)
180 // The subobject we started from. Indicate how we are accessible from
181 // the most derived object.
182 result
.whole2sub
= access_path
;
187 result
.target_obj
= objptr
;
188 result
.whole2target
= access_path
;
189 result
.target2sub
= not_contained
;
195 // find_public_subobj helper. Return contained_public if we are the desired
196 // subtype. OBJPTR points to this base type, SUBPTR points to the desired base
198 __user_type_info::sub_kind
__user_type_info::
199 do_find_public_subobj (int, const type_info
&, void *objptr
, void *subptr
) const
201 if (subptr
== objptr
)
202 // Must be our type, as the pointers match.
203 return contained_public
;
204 return not_contained
;
207 // catch helper for single public inheritance types. See
208 // __user_type_info::do_upcast for semantics.
209 bool __si_type_info::
210 do_upcast (sub_kind access_path
,
211 const type_info
&target
, void *objptr
,
212 upcast_result
&__restrict result
) const
216 result
.target_obj
= objptr
;
217 result
.base_type
= nonvirtual_base_type
;
218 result
.whole2target
= access_path
;
219 return contained_nonpublic_p (access_path
);
221 return base
.do_upcast (access_path
, target
, objptr
, result
);
224 // dynamic cast helper for single public inheritance types. See
225 // __user_type_info::do_dyncast for semantics. BOFF indicates how SUBTYPE
226 // types are inherited by TARGET types.
227 bool __si_type_info::
228 do_dyncast (int boff
, sub_kind access_path
,
229 const type_info
&target
, void *objptr
,
230 const type_info
&subtype
, void *subptr
,
231 dyncast_result
&__restrict result
) const
233 if (objptr
== subptr
&& *this == subtype
)
235 // The subobject we started from. Indicate how we are accessible from
236 // the most derived object.
237 result
.whole2sub
= access_path
;
242 result
.target_obj
= objptr
;
243 result
.whole2target
= access_path
;
245 result
.target2sub
= ((char *)subptr
- (char *)objptr
) == boff
246 ? contained_public
: not_contained
;
248 result
.target2sub
= not_contained
;
251 return base
.do_dyncast (boff
, access_path
,
252 target
, objptr
, subtype
, subptr
, result
);
255 // find_public_subobj helper. See __user_type_info::do_find_public_subobj or
256 // semantics. BOFF indicates how SUBTYPE types are inherited by the original
258 __user_type_info::sub_kind
__si_type_info::
259 do_find_public_subobj (int boff
, const type_info
&subtype
, void *objptr
, void *subptr
) const
261 if (subptr
== objptr
&& subtype
== *this)
262 return contained_public
;
263 return base
.do_find_public_subobj (boff
, subtype
, objptr
, subptr
);
266 // catch helper for multiple or non-public inheritance types. See
267 // __user_type_info::do_upcast for semantics.
268 bool __class_type_info::
269 do_upcast (sub_kind access_path
,
270 const type_info
&target
, void *objptr
,
271 upcast_result
&__restrict result
) const
275 result
.target_obj
= objptr
;
276 result
.base_type
= nonvirtual_base_type
;
277 result
.whole2target
= access_path
;
278 return contained_nonpublic_p (access_path
);
281 for (std::size_t i
= n_bases
; i
--;)
283 upcast_result result2
;
285 sub_kind sub_access
= access_path
;
286 p
= convert_to_base (p
,
287 base_list
[i
].is_virtual
,
288 base_list
[i
].offset
);
289 if (base_list
[i
].is_virtual
)
290 sub_access
= sub_kind (sub_access
| contained_virtual_mask
);
291 if (base_list
[i
].access
!= PUBLIC
)
292 sub_access
= sub_kind (sub_access
& ~contained_public_mask
);
293 if (base_list
[i
].base
->do_upcast (sub_access
, target
, p
, result2
)
294 && !contained_virtual_p (result2
.whole2target
))
295 return true; // must fail
296 if (result2
.base_type
)
298 if (result2
.base_type
== nonvirtual_base_type
299 && base_list
[i
].is_virtual
)
300 result2
.base_type
= base_list
[i
].base
;
301 if (!result
.base_type
)
303 else if (result
.target_obj
!= result2
.target_obj
)
305 // Found an ambiguity.
306 result
.target_obj
= NULL
;
307 result
.whole2target
= contained_ambig
;
310 else if (result
.target_obj
)
312 // Ok, found real object via a virtual path.
314 = sub_kind (result
.whole2target
| result2
.whole2target
);
318 // Dealing with a null pointer, need to check vbase
319 // containing each of the two choices.
320 if (result2
.base_type
== nonvirtual_base_type
321 || result
.base_type
== nonvirtual_base_type
322 || !(*result2
.base_type
== *result
.base_type
))
324 // Already ambiguous, not virtual or via different virtuals.
326 result
.whole2target
= contained_ambig
;
330 = sub_kind (result
.whole2target
| result2
.whole2target
);
337 // dynamic cast helper for non-public or multiple inheritance types. See
338 // __user_type_info::do_dyncast for overall semantics.
339 // This is a big hairy function. Although the run-time behaviour of
340 // dynamic_cast is simple to describe, it gives rise to some non-obvious
341 // behaviour. We also desire to determine as early as possible any definite
342 // answer we can get. Because it is unknown what the run-time ratio of
343 // succeeding to failing dynamic casts is, we do not know in which direction
344 // to bias any optimizations. To that end we make no particular effort towards
345 // early fail answers or early success answers. Instead we try to minimize
346 // work by filling in things lazily (when we know we need the information),
347 // and opportunisticly take early success or failure results.
348 bool __class_type_info::
349 do_dyncast (int boff
, sub_kind access_path
,
350 const type_info
&target
, void *objptr
,
351 const type_info
&subtype
, void *subptr
,
352 dyncast_result
&__restrict result
) const
354 if (objptr
== subptr
&& *this == subtype
)
356 // The subobject we started from. Indicate how we are accessible from
357 // the most derived object.
358 result
.whole2sub
= access_path
;
363 result
.target_obj
= objptr
;
364 result
.whole2target
= access_path
;
366 result
.target2sub
= ((char *)subptr
- (char *)objptr
) == boff
367 ? contained_public
: not_contained
;
369 result
.target2sub
= not_contained
;
372 bool result_ambig
= false;
373 for (std::size_t i
= n_bases
; i
--;)
375 dyncast_result result2
;
377 sub_kind sub_access
= access_path
;
378 p
= convert_to_base (objptr
,
379 base_list
[i
].is_virtual
,
380 base_list
[i
].offset
);
381 if (base_list
[i
].is_virtual
)
382 sub_access
= sub_kind (sub_access
| contained_virtual_mask
);
383 if (base_list
[i
].access
!= PUBLIC
)
384 sub_access
= sub_kind (sub_access
& ~contained_public_mask
);
387 = base_list
[i
].base
->do_dyncast (boff
, sub_access
,
388 target
, p
, subtype
, subptr
, result2
);
389 result
.whole2sub
= sub_kind (result
.whole2sub
| result2
.whole2sub
);
390 if (result2
.target2sub
== contained_public
391 || result2
.target2sub
== contained_ambig
)
393 result
.target_obj
= result2
.target_obj
;
394 result
.whole2target
= result2
.whole2target
;
395 result
.target2sub
= result2
.target2sub
;
396 // Found a downcast which can't be bettered or an ambiguous downcast
397 // which can't be disambiguated
398 return result2_ambig
;
401 if (!result_ambig
&& !result
.target_obj
)
403 // Not found anything yet.
404 result
.target_obj
= result2
.target_obj
;
405 result
.whole2target
= result2
.whole2target
;
406 result_ambig
= result2_ambig
;
408 else if (result
.target_obj
&& result
.target_obj
== result2
.target_obj
)
410 // Found at same address, must be via virtual. Pick the most
412 result
.whole2target
=
413 sub_kind (result
.whole2target
| result2
.whole2target
);
415 else if ((result
.target_obj
&& result2
.target_obj
)
416 || (result_ambig
&& result2
.target_obj
)
417 || (result2_ambig
&& result
.target_obj
))
419 // Found two different TARGET bases, or a valid one and a set of
420 // ambiguous ones, must disambiguate. See whether SUBOBJ is
421 // contained publicly within one of the non-ambiguous choices.
422 // If it is in only one, then that's the choice. If it is in
423 // both, then we're ambiguous and fail. If it is in neither,
424 // we're ambiguous, but don't yet fail as we might later find a
425 // third base which does contain SUBPTR.
427 sub_kind new_sub_kind
= result2
.target2sub
;
428 sub_kind old_sub_kind
= result
.target2sub
;
430 if (contained_nonvirtual_p (result
.whole2sub
))
432 // We already found SUBOBJ as a non-virtual base of most
433 // derived. Therefore if it is in either choice, it can only be
434 // in one of them, and we will already know.
435 if (old_sub_kind
== unknown
)
436 old_sub_kind
= not_contained
;
437 if (new_sub_kind
== unknown
)
438 new_sub_kind
= not_contained
;
442 const __user_type_info
&t
=
443 static_cast <const __user_type_info
&> (target
);
445 if (old_sub_kind
>= not_contained
)
446 ;// already calculated
447 else if (contained_nonvirtual_p (new_sub_kind
))
448 // Already found non-virtually inside the other choice,
449 // cannot be in this.
450 old_sub_kind
= not_contained
;
452 old_sub_kind
= t
.find_public_subobj (boff
, subtype
,
453 result
.target_obj
, subptr
);
455 if (new_sub_kind
>= not_contained
)
456 ;// already calculated
457 else if (contained_nonvirtual_p (old_sub_kind
))
458 // Already found non-virtually inside the other choice,
459 // cannot be in this.
460 new_sub_kind
= not_contained
;
462 new_sub_kind
= t
.find_public_subobj (boff
, subtype
,
463 result2
.target_obj
, subptr
);
466 // Neither sub_kind can be contained_ambig -- we bail out early
467 // when we find those.
468 if (contained_p (sub_kind (new_sub_kind
^ old_sub_kind
)))
470 // Only on one choice, not ambiguous.
471 if (contained_p (new_sub_kind
))
474 result
.target_obj
= result2
.target_obj
;
475 result
.whole2target
= result2
.whole2target
;
476 result_ambig
= false;
477 old_sub_kind
= new_sub_kind
;
479 result
.target2sub
= old_sub_kind
;
480 if (result
.target2sub
== contained_public
)
481 return false; // Can't be an ambiguating downcast for later discovery.
483 else if (contained_p (sub_kind (new_sub_kind
& old_sub_kind
)))
486 result
.target_obj
= NULL
;
487 result
.target2sub
= contained_ambig
;
488 return true; // Fail.
492 // In neither publicly, ambiguous for the moment, but keep
493 // looking. It is possible that it was private in one or
494 // both and therefore we should fail, but that's just tough.
495 result
.target_obj
= NULL
;
496 result
.target2sub
= not_contained
;
501 if (result
.whole2sub
== contained_private
)
502 // We found SUBOBJ as a private non-virtual base, therefore all
503 // cross casts will fail. We have already found a down cast, if
511 // find_public_subobj helper for non-public or multiple inheritance types. See
512 // __user_type_info::do_find_public_subobj for semantics. We make use of BOFF
513 // to prune the base class walk.
514 __user_type_info::sub_kind
__class_type_info::
515 do_find_public_subobj (int boff
, const type_info
&subtype
, void *objptr
, void *subptr
) const
517 if (objptr
== subptr
&& subtype
== *this)
518 return contained_public
;
520 for (std::size_t i
= n_bases
; i
--;)
522 if (base_list
[i
].access
!= PUBLIC
)
523 continue; // Not public, can't be here.
526 if (base_list
[i
].is_virtual
&& boff
== -3)
527 // Not a virtual base, so can't be here.
530 p
= convert_to_base (objptr
,
531 base_list
[i
].is_virtual
,
532 base_list
[i
].offset
);
534 sub_kind base_kind
= base_list
[i
].base
->do_find_public_subobj
535 (boff
, subtype
, p
, subptr
);
536 if (contained_p (base_kind
))
538 if (base_list
[i
].is_virtual
)
539 base_kind
= sub_kind (base_kind
| contained_virtual_mask
);
544 return not_contained
;
551 // return true if this is a type_info for a pointer type
553 __is_pointer_p () const
558 // return true if this is a type_info for a function type
560 __is_function_p () const
565 // try and catch a thrown object.
567 __do_catch (const type_info
*thr_type
, void **, unsigned) const
569 return *this == *thr_type
;
572 // upcast from this type to the target. __class_type_info will override
574 __do_upcast (const abi::__class_type_info
*, void **) const
586 // initial part of a vtable, this structure is used with offsetof, so we don't
587 // have to keep alignments consistent manually.
588 struct vtable_prefix
{
589 ptrdiff_t whole_object
; // offset to most derived object
590 const __class_type_info
*whole_type
; // pointer to most derived type_info
591 const void *origin
; // what a class's vptr points to
594 template <typename T
>
596 adjust_pointer (const void *base
, ptrdiff_t offset
)
598 return reinterpret_cast <const T
*>
599 (reinterpret_cast <const char *> (base
) + offset
);
602 // ADDR is a pointer to an object. Convert it to a pointer to a base,
603 // using OFFSET. IS_VIRTUAL is true, if we are getting a virtual base.
605 convert_to_base (void const *addr
, bool is_virtual
, ptrdiff_t offset
)
609 const void *vtable
= *static_cast <const void *const *> (addr
);
611 offset
= *adjust_pointer
<ptrdiff_t> (vtable
, offset
);
614 return adjust_pointer
<void> (addr
, offset
);
617 // some predicate functions for __class_type_info::__sub_kind
618 inline bool contained_p (__class_type_info::__sub_kind access_path
)
620 return access_path
>= __class_type_info::__contained_mask
;
622 inline bool public_p (__class_type_info::__sub_kind access_path
)
624 return access_path
& __class_type_info::__contained_public_mask
;
626 inline bool virtual_p (__class_type_info::__sub_kind access_path
)
628 return (access_path
& __class_type_info::__contained_virtual_mask
);
630 inline bool contained_public_p (__class_type_info::__sub_kind access_path
)
632 return ((access_path
& __class_type_info::__contained_public
)
633 == __class_type_info::__contained_public
);
635 inline bool contained_nonpublic_p (__class_type_info::__sub_kind access_path
)
637 return ((access_path
& __class_type_info::__contained_public
)
638 == __class_type_info::__contained_mask
);
640 inline bool contained_nonvirtual_p (__class_type_info::__sub_kind access_path
)
642 return ((access_path
& (__class_type_info::__contained_mask
643 | __class_type_info::__contained_virtual_mask
))
644 == __class_type_info::__contained_mask
);
647 static const __class_type_info
*const nonvirtual_base_type
=
648 static_cast <const __class_type_info
*> (0) + 1;
656 ~__class_type_info ()
659 __si_class_type_info::
660 ~__si_class_type_info ()
663 __vmi_class_type_info::
664 ~__vmi_class_type_info ()
667 // __upcast_result is used to hold information during traversal of a class
668 // heirarchy when catch matching.
669 struct __class_type_info::__upcast_result
671 const void *dst_ptr
; // pointer to caught object
672 __sub_kind part2dst
; // path from current base to target
673 int src_details
; // hints about the source type heirarchy
674 const __class_type_info
*base_type
; // where we found the target,
675 // if in vbase the __class_type_info of vbase
676 // if a non-virtual base then 1
679 __upcast_result (int d
)
680 :dst_ptr (NULL
), part2dst (__unknown
), src_details (d
), base_type (NULL
)
684 // __dyncast_result is used to hold information during traversal of a class
685 // heirarchy when dynamic casting.
686 struct __class_type_info::__dyncast_result
688 const void *dst_ptr
; // pointer to target object or NULL
689 __sub_kind whole2dst
; // path from most derived object to target
690 __sub_kind whole2src
; // path from most derived object to sub object
691 __sub_kind dst2src
; // path from target to sub object
692 int whole_details
; // details of the whole class heirarchy
695 __dyncast_result (int details_
= __vmi_class_type_info::__flags_unknown_mask
)
696 :dst_ptr (NULL
), whole2dst (__unknown
),
697 whole2src (__unknown
), dst2src (__unknown
),
698 whole_details (details_
)
702 bool __class_type_info::
703 __do_catch (const type_info
*thr_type
,
705 unsigned outer
) const
707 if (*this == *thr_type
)
710 // Neither `A' nor `A *'.
712 return thr_type
->__do_upcast (this, thr_obj
);
715 bool __class_type_info::
716 __do_upcast (const __class_type_info
*dst_type
,
717 void **obj_ptr
) const
719 __upcast_result
result (__vmi_class_type_info::__flags_unknown_mask
);
721 __do_upcast (dst_type
, *obj_ptr
, result
);
722 if (!contained_public_p (result
.part2dst
))
724 *obj_ptr
= const_cast <void *> (result
.dst_ptr
);
728 inline __class_type_info::__sub_kind
__class_type_info::
729 __find_public_src (ptrdiff_t src2dst
,
731 const __class_type_info
*src_type
,
732 const void *src_ptr
) const
735 return adjust_pointer
<void> (obj_ptr
, src2dst
) == src_ptr
736 ? __contained_public
: __not_contained
;
738 return __not_contained
;
739 return __do_find_public_src (src2dst
, obj_ptr
, src_type
, src_ptr
);
742 __class_type_info::__sub_kind
__class_type_info::
743 __do_find_public_src (ptrdiff_t,
745 const __class_type_info
*,
746 const void *src_ptr
) const
748 if (src_ptr
== obj_ptr
)
749 // Must be our type, as the pointers match.
750 return __contained_public
;
751 return __not_contained
;
754 __class_type_info::__sub_kind
__si_class_type_info::
755 __do_find_public_src (ptrdiff_t src2dst
,
757 const __class_type_info
*src_type
,
758 const void *src_ptr
) const
760 if (src_ptr
== obj_ptr
&& *this == *src_type
)
761 return __contained_public
;
762 return __base_type
->__do_find_public_src (src2dst
, obj_ptr
, src_type
, src_ptr
);
765 __class_type_info::__sub_kind
__vmi_class_type_info::
766 __do_find_public_src (ptrdiff_t src2dst
,
768 const __class_type_info
*src_type
,
769 const void *src_ptr
) const
771 if (obj_ptr
== src_ptr
&& *this == *src_type
)
772 return __contained_public
;
774 for (std::size_t i
= __base_count
; i
--;)
776 if (!__base_info
[i
].__is_public_p ())
777 continue; // Not public, can't be here.
779 const void *base
= obj_ptr
;
780 ptrdiff_t offset
= __base_info
[i
].__offset ();
781 bool is_virtual
= __base_info
[i
].__is_virtual_p ();
786 continue; // Not a virtual base, so can't be here.
788 base
= convert_to_base (base
, is_virtual
, offset
);
790 __sub_kind base_kind
= __base_info
[i
].__base
->__do_find_public_src
791 (src2dst
, base
, src_type
, src_ptr
);
792 if (contained_p (base_kind
))
795 base_kind
= __sub_kind (base_kind
| __contained_virtual_mask
);
800 return __not_contained
;
803 bool __class_type_info::
804 __do_dyncast (ptrdiff_t,
805 __sub_kind access_path
,
806 const __class_type_info
*dst_type
,
808 const __class_type_info
*src_type
,
810 __dyncast_result
&__restrict result
) const
812 if (obj_ptr
== src_ptr
&& *this == *src_type
)
814 // The src object we started from. Indicate how we are accessible from
815 // the most derived object.
816 result
.whole2src
= access_path
;
819 if (*this == *dst_type
)
821 result
.dst_ptr
= obj_ptr
;
822 result
.whole2dst
= access_path
;
823 result
.dst2src
= __not_contained
;
829 bool __si_class_type_info::
830 __do_dyncast (ptrdiff_t src2dst
,
831 __sub_kind access_path
,
832 const __class_type_info
*dst_type
,
834 const __class_type_info
*src_type
,
836 __dyncast_result
&__restrict result
) const
838 if (*this == *dst_type
)
840 result
.dst_ptr
= obj_ptr
;
841 result
.whole2dst
= access_path
;
843 result
.dst2src
= adjust_pointer
<void> (obj_ptr
, src2dst
) == src_ptr
844 ? __contained_public
: __not_contained
;
845 else if (src2dst
== -2)
846 result
.dst2src
= __not_contained
;
849 if (obj_ptr
== src_ptr
&& *this == *src_type
)
851 // The src object we started from. Indicate how we are accessible from
852 // the most derived object.
853 result
.whole2src
= access_path
;
856 return __base_type
->__do_dyncast (src2dst
, access_path
, dst_type
, obj_ptr
,
857 src_type
, src_ptr
, result
);
860 // This is a big hairy function. Although the run-time behaviour of
861 // dynamic_cast is simple to describe, it gives rise to some non-obvious
862 // behaviour. We also desire to determine as early as possible any definite
863 // answer we can get. Because it is unknown what the run-time ratio of
864 // succeeding to failing dynamic casts is, we do not know in which direction
865 // to bias any optimizations. To that end we make no particular effort towards
866 // early fail answers or early success answers. Instead we try to minimize
867 // work by filling in things lazily (when we know we need the information),
868 // and opportunisticly take early success or failure results.
869 bool __vmi_class_type_info::
870 __do_dyncast (ptrdiff_t src2dst
,
871 __sub_kind access_path
,
872 const __class_type_info
*dst_type
,
874 const __class_type_info
*src_type
,
876 __dyncast_result
&__restrict result
) const
878 if (result
.whole_details
& __flags_unknown_mask
)
879 result
.whole_details
= __flags
;
881 if (obj_ptr
== src_ptr
&& *this == *src_type
)
883 // The src object we started from. Indicate how we are accessible from
884 // the most derived object.
885 result
.whole2src
= access_path
;
888 if (*this == *dst_type
)
890 result
.dst_ptr
= obj_ptr
;
891 result
.whole2dst
= access_path
;
893 result
.dst2src
= adjust_pointer
<void> (obj_ptr
, src2dst
) == src_ptr
894 ? __contained_public
: __not_contained
;
895 else if (src2dst
== -2)
896 result
.dst2src
= __not_contained
;
900 bool result_ambig
= false;
901 for (std::size_t i
= __base_count
; i
--;)
903 __dyncast_result
result2 (result
.whole_details
);
904 void const *base
= obj_ptr
;
905 __sub_kind base_access
= access_path
;
906 ptrdiff_t offset
= __base_info
[i
].__offset ();
907 bool is_virtual
= __base_info
[i
].__is_virtual_p ();
910 base_access
= __sub_kind (base_access
| __contained_virtual_mask
);
911 base
= convert_to_base (base
, is_virtual
, offset
);
913 if (!__base_info
[i
].__is_public_p ())
916 !(result
.whole_details
917 & (__non_diamond_repeat_mask
| __diamond_shaped_mask
)))
918 // The hierarchy has no duplicate bases (which might ambiguate
919 // things) and where we started is not a public base of what we
920 // want (so it cannot be a downcast). There is nothing of interest
921 // hiding in a non-public base.
923 base_access
= __sub_kind (base_access
& ~__contained_public_mask
);
927 = __base_info
[i
].__base
->__do_dyncast (src2dst
, base_access
,
929 src_type
, src_ptr
, result2
);
930 result
.whole2src
= __sub_kind (result
.whole2src
| result2
.whole2src
);
931 if (result2
.dst2src
== __contained_public
932 || result2
.dst2src
== __contained_ambig
)
934 result
.dst_ptr
= result2
.dst_ptr
;
935 result
.whole2dst
= result2
.whole2dst
;
936 result
.dst2src
= result2
.dst2src
;
937 // Found a downcast which can't be bettered or an ambiguous downcast
938 // which can't be disambiguated
939 return result2_ambig
;
942 if (!result_ambig
&& !result
.dst_ptr
)
944 // Not found anything yet.
945 result
.dst_ptr
= result2
.dst_ptr
;
946 result
.whole2dst
= result2
.whole2dst
;
947 result_ambig
= result2_ambig
;
948 if (result
.dst_ptr
&& result
.whole2src
!= __unknown
949 && !(__flags
& __non_diamond_repeat_mask
))
950 // Found dst and src and we don't have repeated bases.
953 else if (result
.dst_ptr
&& result
.dst_ptr
== result2
.dst_ptr
)
955 // Found at same address, must be via virtual. Pick the most
958 __sub_kind (result
.whole2dst
| result2
.whole2dst
);
960 else if ((result
.dst_ptr
!= 0 | result_ambig
)
961 && (result2
.dst_ptr
!= 0 | result2_ambig
))
963 // Found two different DST_TYPE bases, or a valid one and a set of
964 // ambiguous ones, must disambiguate. See whether SRC_PTR is
965 // contained publicly within one of the non-ambiguous choices. If it
966 // is in only one, then that's the choice. If it is in both, then
967 // we're ambiguous and fail. If it is in neither, we're ambiguous,
968 // but don't yet fail as we might later find a third base which does
971 __sub_kind new_sub_kind
= result2
.dst2src
;
972 __sub_kind old_sub_kind
= result
.dst2src
;
974 if (contained_p (result
.whole2src
)
975 && (!virtual_p (result
.whole2src
)
976 || !(result
.whole_details
& __diamond_shaped_mask
)))
978 // We already found SRC_PTR as a base of most derived, and
979 // either it was non-virtual, or the whole heirarchy is
980 // not-diamond shaped. Therefore if it is in either choice, it
981 // can only be in one of them, and we will already know.
982 if (old_sub_kind
== __unknown
)
983 old_sub_kind
= __not_contained
;
984 if (new_sub_kind
== __unknown
)
985 new_sub_kind
= __not_contained
;
989 if (old_sub_kind
>= __not_contained
)
990 ;// already calculated
991 else if (contained_p (new_sub_kind
)
992 && (!virtual_p (new_sub_kind
)
993 || !(__flags
& __diamond_shaped_mask
)))
994 // Already found inside the other choice, and it was
995 // non-virtual or we are not diamond shaped.
996 old_sub_kind
= __not_contained
;
998 old_sub_kind
= dst_type
->__find_public_src
999 (src2dst
, result
.dst_ptr
, src_type
, src_ptr
);
1001 if (new_sub_kind
>= __not_contained
)
1002 ;// already calculated
1003 else if (contained_p (old_sub_kind
)
1004 && (!virtual_p (old_sub_kind
)
1005 || !(__flags
& __diamond_shaped_mask
)))
1006 // Already found inside the other choice, and it was
1007 // non-virtual or we are not diamond shaped.
1008 new_sub_kind
= __not_contained
;
1010 new_sub_kind
= dst_type
->__find_public_src
1011 (src2dst
, result2
.dst_ptr
, src_type
, src_ptr
);
1014 // Neither sub_kind can be contained_ambig -- we bail out early
1015 // when we find those.
1016 if (contained_p (__sub_kind (new_sub_kind
^ old_sub_kind
)))
1018 // Only on one choice, not ambiguous.
1019 if (contained_p (new_sub_kind
))
1022 result
.dst_ptr
= result2
.dst_ptr
;
1023 result
.whole2dst
= result2
.whole2dst
;
1024 result_ambig
= false;
1025 old_sub_kind
= new_sub_kind
;
1027 result
.dst2src
= old_sub_kind
;
1028 if (public_p (result
.dst2src
))
1029 return false; // Can't be an ambiguating downcast for later discovery.
1030 if (!virtual_p (result
.dst2src
))
1031 return false; // Found non-virtually can't be bettered
1033 else if (contained_p (__sub_kind (new_sub_kind
& old_sub_kind
)))
1036 result
.dst_ptr
= NULL
;
1037 result
.dst2src
= __contained_ambig
;
1038 return true; // Fail.
1042 // In neither publicly, ambiguous for the moment, but keep
1043 // looking. It is possible that it was private in one or
1044 // both and therefore we should fail, but that's just tough.
1045 result
.dst_ptr
= NULL
;
1046 result
.dst2src
= __not_contained
;
1047 result_ambig
= true;
1051 if (result
.whole2src
== __contained_private
)
1052 // We found SRC_PTR as a private non-virtual base, therefore all
1053 // cross casts will fail. We have already found a down cast, if
1055 return result_ambig
;
1058 return result_ambig
;
1061 bool __class_type_info::
1062 __do_upcast (const __class_type_info
*dst
, const void *obj
,
1063 __upcast_result
&__restrict result
) const
1067 result
.dst_ptr
= obj
;
1068 result
.base_type
= nonvirtual_base_type
;
1069 result
.part2dst
= __contained_public
;
1075 bool __si_class_type_info::
1076 __do_upcast (const __class_type_info
*dst
, const void *obj_ptr
,
1077 __upcast_result
&__restrict result
) const
1079 if (__class_type_info::__do_upcast (dst
, obj_ptr
, result
))
1082 return __base_type
->__do_upcast (dst
, obj_ptr
, result
);
1085 bool __vmi_class_type_info::
1086 __do_upcast (const __class_type_info
*dst
, const void *obj_ptr
,
1087 __upcast_result
&__restrict result
) const
1089 if (__class_type_info::__do_upcast (dst
, obj_ptr
, result
))
1092 int src_details
= result
.src_details
;
1093 if (src_details
& __flags_unknown_mask
)
1094 src_details
= __flags
;
1096 for (std::size_t i
= __base_count
; i
--;)
1098 __upcast_result
result2 (src_details
);
1099 const void *base
= obj_ptr
;
1100 ptrdiff_t offset
= __base_info
[i
].__offset ();
1101 bool is_virtual
= __base_info
[i
].__is_virtual_p ();
1102 bool is_public
= __base_info
[i
].__is_public_p ();
1104 if (!is_public
&& !(src_details
& __non_diamond_repeat_mask
))
1105 // original cannot have an ambiguous base, so skip private bases
1109 base
= convert_to_base (base
, is_virtual
, offset
);
1111 if (__base_info
[i
].__base
->__do_upcast (dst
, base
, result2
))
1113 if (result2
.base_type
== nonvirtual_base_type
&& is_virtual
)
1114 result2
.base_type
= __base_info
[i
].__base
;
1115 if (contained_p (result2
.part2dst
) && !is_public
)
1116 result2
.part2dst
= __sub_kind (result2
.part2dst
& ~__contained_public_mask
);
1118 if (!result
.base_type
)
1121 if (!contained_p (result
.part2dst
))
1122 return true; // found ambiguously
1124 if (result
.part2dst
& __contained_public_mask
)
1126 if (!(__flags
& __non_diamond_repeat_mask
))
1127 return true; // cannot have an ambiguous other base
1131 if (!virtual_p (result
.part2dst
))
1132 return true; // cannot have another path
1133 if (!(__flags
& __diamond_shaped_mask
))
1134 return true; // cannot have a more accessible path
1137 else if (result
.dst_ptr
!= result2
.dst_ptr
)
1139 // Found an ambiguity.
1140 result
.dst_ptr
= NULL
;
1141 result
.part2dst
= __contained_ambig
;
1144 else if (result
.dst_ptr
)
1146 // Ok, found real object via a virtual path.
1148 = __sub_kind (result
.part2dst
| result2
.part2dst
);
1152 // Dealing with a null pointer, need to check vbase
1153 // containing each of the two choices.
1154 if (result2
.base_type
== nonvirtual_base_type
1155 || result
.base_type
== nonvirtual_base_type
1156 || !(*result2
.base_type
== *result
.base_type
))
1158 // Already ambiguous, not virtual or via different virtuals.
1160 result
.part2dst
= __contained_ambig
;
1164 = __sub_kind (result
.part2dst
| result2
.part2dst
);
1168 return result
.part2dst
!= __unknown
;
1171 // this is the external interface to the dynamic cast machinery
1173 __dynamic_cast (const void *src_ptr
, // object started from
1174 const __class_type_info
*src_type
, // type of the starting object
1175 const __class_type_info
*dst_type
, // desired target type
1176 ptrdiff_t src2dst
) // how src and dst are related
1178 const void *vtable
= *static_cast <const void *const *> (src_ptr
);
1179 const vtable_prefix
*prefix
=
1180 adjust_pointer
<vtable_prefix
> (vtable
,
1181 -offsetof (vtable_prefix
, origin
));
1182 const void *whole_ptr
=
1183 adjust_pointer
<void> (src_ptr
, prefix
->whole_object
);
1184 const __class_type_info
*whole_type
= prefix
->whole_type
;
1185 __class_type_info::__dyncast_result result
;
1187 whole_type
->__do_dyncast (src2dst
, __class_type_info::__contained_public
,
1188 dst_type
, whole_ptr
, src_type
, src_ptr
, result
);
1189 if (!result
.dst_ptr
)
1191 if (contained_public_p (result
.dst2src
))
1192 // Src is known to be a public base of dst.
1193 return const_cast <void *> (result
.dst_ptr
);
1194 if (contained_public_p (__class_type_info::__sub_kind (result
.whole2src
& result
.whole2dst
)))
1195 // Both src and dst are known to be public bases of whole. Found a valid
1197 return const_cast <void *> (result
.dst_ptr
);
1198 if (contained_nonvirtual_p (result
.whole2src
))
1199 // Src is known to be a non-public nonvirtual base of whole, and not a
1200 // base of dst. Found an invalid cross cast, which cannot also be a down
1203 if (result
.dst2src
== __class_type_info::__unknown
)
1204 result
.dst2src
= dst_type
->__find_public_src (src2dst
, result
.dst_ptr
,
1206 if (contained_public_p (result
.dst2src
))
1207 // Found a valid down cast
1208 return const_cast <void *> (result
.dst_ptr
);
1209 // Must be an invalid down cast, or the cross cast wasn't bettered
1213 }; // namespace __cxxabiv1