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, if you link this library with other files,
22 // some of which are compiled with GCC, to produce an executable,
23 // this library does not by itself cause the resulting executable
24 // to be covered by the GNU General Public License.
25 // This exception does not however invalidate any other reasons why
26 // the executable file might be covered by the GNU General Public License.
28 #pragma implementation "typeinfo"
32 #include "new" // for placement new
34 // This file contains the minimal working set necessary to link with code
35 // that uses virtual functions and -frtti but does not actually use RTTI
42 #if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
47 // ADDR is a pointer to an object. Convert it to a pointer to a base,
50 convert_to_base (void *addr, bool is_virtual, myint32 offset)
56 return (char *) addr + offset;
58 // Under the old ABI, the offset gives us the address of a pointer
59 // to the virtual base.
60 return *((void **) ((char *) addr + offset));
65 // We can't rely on common symbols being shared between shared objects.
67 operator== (const std::type_info& arg) const
69 return (&arg == this) || (strcmp (name (), arg.name ()) == 0);
73 __rtti_class (void *addr, const char *name,
74 const __class_type_info::base_info *bl, size_t bn)
75 { new (addr) __class_type_info (name, bl, bn); }
78 __rtti_si (void *addr, const char *n, const std::type_info *ti)
80 new (addr) __si_type_info
81 (n, static_cast <const __user_type_info &> (*ti));
85 __rtti_user (void *addr, const char *name)
86 { new (addr) __user_type_info (name); }
88 // Upcast for catch checking. OBJPTR points to the thrown object and might be
89 // NULL. Return 0 on failure, non-zero on success. Set *ADJPTR to adjusted
91 int __user_type_info::
92 upcast (const type_info &target, void *objptr,
97 if (do_upcast (contained_public, target, objptr, result))
99 *adjptr = result.target_obj;
100 return contained_public_p (result.whole2target);
103 // Down or cross cast for dynamic_cast. OBJPTR points to the most derrived
104 // object, SUBPTR points to the static base object. Both must not be NULL.
105 // TARGET specifies the desired target type, SUBTYPE specifies the static
106 // type. Both must be defined. Returns adjusted object pointer on success,
107 // NULL on failure. [expr.dynamic.cast]/8 says 'unambiguous public base'. This
108 // itself is an ambiguous statement. We choose it to mean the base must be
109 // separately unambiguous and public, rather than unambiguous considering only
111 void *__user_type_info::
113 const type_info &target, void *objptr,
114 const type_info &subtype, void *subptr) const
116 dyncast_result result;
118 do_dyncast (boff, contained_public,
119 target, objptr, subtype, subptr, result);
120 if (!result.target_obj)
122 if (contained_public_p (result.target2sub))
123 return result.target_obj;
124 if (contained_public_p (sub_kind (result.whole2sub & result.whole2target)))
125 // Found a valid cross cast
126 return result.target_obj;
127 if (contained_nonvirtual_p (result.whole2sub))
128 // Found an invalid cross cast, which cannot also be a down cast
130 if (result.target2sub == unknown)
131 result.target2sub = static_cast <const __user_type_info &> (target)
132 .find_public_subobj (boff, subtype,
133 result.target_obj, subptr);
134 if (contained_public_p (result.target2sub))
135 // Found a valid down cast
136 return result.target_obj;
137 // Must be an invalid down cast, or the cross cast wasn't bettered
141 // Catch cast helper. ACCESS_PATH is the access from the complete thrown
142 // object to this base. TARGET is the desired type we want to catch. OBJPTR
143 // points to this base within the throw object, it might be NULL. Fill in
144 // RESULT with what we find. Return true, should we determine catch must fail.
145 bool __user_type_info::
146 do_upcast (sub_kind access_path,
147 const type_info &target, void *objptr,
148 upcast_result &__restrict result) const
152 result.target_obj = objptr;
153 result.base_type = nonvirtual_base_type;
154 result.whole2target = access_path;
155 return contained_nonpublic_p (access_path);
160 // dynamic cast helper. ACCESS_PATH gives the access from the most derived
161 // object to this base. TARGET indicates the desired type we want. OBJPTR
162 // points to this base within the object. SUBTYPE indicates the static type
163 // started from and SUBPTR points to that base within the most derived object.
164 // Fill in RESULT with what we find. Return true if we have located an
166 bool __user_type_info::
167 do_dyncast (int, sub_kind access_path,
168 const type_info &target, void *objptr,
169 const type_info &subtype, void *subptr,
170 dyncast_result &__restrict result) const
172 if (objptr == subptr && *this == subtype)
174 // The subobject we started from. Indicate how we are accessible from
175 // the most derived object.
176 result.whole2sub = access_path;
181 result.target_obj = objptr;
182 result.whole2target = access_path;
183 result.target2sub = not_contained;
189 // find_public_subobj helper. Return contained_public if we are the desired
190 // subtype. OBJPTR points to this base type, SUBPTR points to the desired base
192 __user_type_info::sub_kind __user_type_info::
193 do_find_public_subobj (int, const type_info &, void *objptr, void *subptr) const
195 if (subptr == objptr)
196 // Must be our type, as the pointers match.
197 return contained_public;
198 return not_contained;
201 // catch helper for single public inheritance types. See
202 // __user_type_info::do_upcast for semantics.
203 bool __si_type_info::
204 do_upcast (sub_kind access_path,
205 const type_info &target, void *objptr,
206 upcast_result &__restrict result) const
210 result.target_obj = objptr;
211 result.base_type = nonvirtual_base_type;
212 result.whole2target = access_path;
213 return contained_nonpublic_p (access_path);
215 return base.do_upcast (access_path, target, objptr, result);
218 // dynamic cast helper for single public inheritance types. See
219 // __user_type_info::do_dyncast for semantics. BOFF indicates how SUBTYPE
220 // types are inherited by TARGET types.
221 bool __si_type_info::
222 do_dyncast (int boff, sub_kind access_path,
223 const type_info &target, void *objptr,
224 const type_info &subtype, void *subptr,
225 dyncast_result &__restrict result) const
227 if (objptr == subptr && *this == subtype)
229 // The subobject we started from. Indicate how we are accessible from
230 // the most derived object.
231 result.whole2sub = access_path;
236 result.target_obj = objptr;
237 result.whole2target = access_path;
239 result.target2sub = ((char *)subptr - (char *)objptr) == boff
240 ? contained_public : not_contained;
242 result.target2sub = not_contained;
245 return base.do_dyncast (boff, access_path,
246 target, objptr, subtype, subptr, result);
249 // find_public_subobj helper. See __user_type_info::do_find_public_subobj or
250 // semantics. BOFF indicates how SUBTYPE types are inherited by the original
252 __user_type_info::sub_kind __si_type_info::
253 do_find_public_subobj (int boff, const type_info &subtype, void *objptr, void *subptr) const
255 if (subptr == objptr && subtype == *this)
256 return contained_public;
257 return base.do_find_public_subobj (boff, subtype, objptr, subptr);
260 // catch helper for multiple or non-public inheritance types. See
261 // __user_type_info::do_upcast for semantics.
262 bool __class_type_info::
263 do_upcast (sub_kind access_path,
264 const type_info &target, void *objptr,
265 upcast_result &__restrict result) const
269 result.target_obj = objptr;
270 result.base_type = nonvirtual_base_type;
271 result.whole2target = access_path;
272 return contained_nonpublic_p (access_path);
275 for (size_t i = n_bases; i--;)
277 upcast_result result2;
279 sub_kind sub_access = access_path;
280 p = convert_to_base (p,
281 base_list[i].is_virtual,
282 base_list[i].offset);
283 if (base_list[i].is_virtual)
284 sub_access = sub_kind (sub_access | contained_virtual_mask);
285 if (base_list[i].access != PUBLIC)
286 sub_access = sub_kind (sub_access & ~contained_public_mask);
287 if (base_list[i].base->do_upcast (sub_access, target, p, result2))
288 return true; // must fail
289 if (result2.base_type)
291 if (result2.base_type == nonvirtual_base_type
292 && base_list[i].is_virtual)
293 result2.base_type = base_list[i].base;
294 if (!result.base_type)
296 else if (result.target_obj != result2.target_obj)
298 // Found an ambiguity.
299 result.target_obj = NULL;
300 result.whole2target = contained_ambig;
303 else if (result.target_obj)
305 // Ok, found real object via a virtual path.
307 = sub_kind (result.whole2target | result2.whole2target);
311 // Dealing with a null pointer, need to check vbase
312 // containing each of the two choices.
313 if (result2.base_type == nonvirtual_base_type
314 || result.base_type == nonvirtual_base_type
315 || !(*result2.base_type == *result.base_type))
317 // Already ambiguous, not virtual or via different virtuals.
319 result.whole2target = contained_ambig;
328 // dynamic cast helper for non-public or multiple inheritance types. See
329 // __user_type_info::do_dyncast for overall semantics.
330 // This is a big hairy function. Although the run-time behaviour of
331 // dynamic_cast is simple to describe, it gives rise to some non-obvious
332 // behaviour. We also desire to determine as early as possible any definite
333 // answer we can get. Because it is unknown what the run-time ratio of
334 // succeeding to failing dynamic casts is, we do not know in which direction
335 // to bias any optimizations. To that end we make no particular effort towards
336 // early fail answers or early success answers. Instead we try to minimize
337 // work by filling in things lazily (when we know we need the information),
338 // and opportunisticly take early success or failure results.
339 bool __class_type_info::
340 do_dyncast (int boff, sub_kind access_path,
341 const type_info &target, void *objptr,
342 const type_info &subtype, void *subptr,
343 dyncast_result &__restrict result) const
345 if (objptr == subptr && *this == subtype)
347 // The subobject we started from. Indicate how we are accessible from
348 // the most derived object.
349 result.whole2sub = access_path;
354 result.target_obj = objptr;
355 result.whole2target = access_path;
357 result.target2sub = ((char *)subptr - (char *)objptr) == boff
358 ? contained_public : not_contained;
360 result.target2sub = not_contained;
363 bool result_ambig = false;
364 for (size_t i = n_bases; i--;)
366 dyncast_result result2;
368 sub_kind sub_access = access_path;
369 p = convert_to_base (objptr,
370 base_list[i].is_virtual,
371 base_list[i].offset);
372 if (base_list[i].is_virtual)
373 sub_access = sub_kind (sub_access | contained_virtual_mask);
374 if (base_list[i].access != PUBLIC)
375 sub_access = sub_kind (sub_access & ~contained_public_mask);
378 = base_list[i].base->do_dyncast (boff, sub_access,
379 target, p, subtype, subptr, result2);
380 result.whole2sub = sub_kind (result.whole2sub | result2.whole2sub);
381 if (result2.target2sub == contained_public
382 || result2.target2sub == contained_ambig)
384 result.target_obj = result2.target_obj;
385 result.whole2target = result2.whole2target;
386 result.target2sub = result2.target2sub;
387 // Found a downcast which can't be bettered or an ambiguous downcast
388 // which can't be disambiguated
389 return result2_ambig;
392 if (!result_ambig && !result.target_obj)
394 // Not found anything yet.
395 result.target_obj = result2.target_obj;
396 result.whole2target = result2.whole2target;
397 result_ambig = result2_ambig;
399 else if (result.target_obj && result.target_obj == result2.target_obj)
401 // Found at same address, must be via virtual. Pick the most
403 result.whole2target =
404 sub_kind (result.whole2target | result2.whole2target);
406 else if ((result.target_obj && result2.target_obj)
407 || (result_ambig && result2.target_obj)
408 || (result2_ambig && result.target_obj))
410 // Found two different TARGET bases, or a valid one and a set of
411 // ambiguous ones, must disambiguate. See whether SUBOBJ is
412 // contained publicly within one of the non-ambiguous choices.
413 // If it is in only one, then that's the choice. If it is in
414 // both, then we're ambiguous and fail. If it is in neither,
415 // we're ambiguous, but don't yet fail as we might later find a
416 // third base which does contain SUBPTR.
418 sub_kind new_sub_kind = result2.target2sub;
419 sub_kind old_sub_kind = result.target2sub;
421 if (contained_nonvirtual_p (result.whole2sub))
423 // We already found SUBOBJ as a non-virtual base of most
424 // derived. Therefore if it is in either choice, it can only be
425 // in one of them, and we will already know.
426 if (old_sub_kind == unknown)
427 old_sub_kind = not_contained;
428 if (new_sub_kind == unknown)
429 new_sub_kind = not_contained;
433 const __user_type_info &t =
434 static_cast <const __user_type_info &> (target);
436 if (old_sub_kind >= not_contained)
437 ;// already calculated
438 else if (contained_nonvirtual_p (new_sub_kind))
439 // Already found non-virtually inside the other choice,
440 // cannot be in this.
441 old_sub_kind = not_contained;
443 old_sub_kind = t.find_public_subobj (boff, subtype,
444 result.target_obj, subptr);
446 if (new_sub_kind >= not_contained)
447 ;// already calculated
448 else if (contained_nonvirtual_p (old_sub_kind))
449 // Already found non-virtually inside the other choice,
450 // cannot be in this.
451 new_sub_kind = not_contained;
453 new_sub_kind = t.find_public_subobj (boff, subtype,
454 result2.target_obj, subptr);
457 // Neither sub_kind can be contained_ambig -- we bail out early
458 // when we find those.
459 if (contained_p (sub_kind (new_sub_kind ^ old_sub_kind)))
461 // Only on one choice, not ambiguous.
462 if (contained_p (new_sub_kind))
465 result.target_obj = result2.target_obj;
466 result.whole2target = result2.whole2target;
467 result_ambig = false;
468 old_sub_kind = new_sub_kind;
470 result.target2sub = old_sub_kind;
471 if (result.target2sub == contained_public)
472 return false; // Can't be an ambiguating downcast for later discovery.
474 else if (contained_p (sub_kind (new_sub_kind & old_sub_kind)))
477 result.target_obj = NULL;
478 result.target2sub = contained_ambig;
479 return true; // Fail.
483 // In neither publicly, ambiguous for the moment, but keep
484 // looking. It is possible that it was private in one or
485 // both and therefore we should fail, but that's just tough.
486 result.target_obj = NULL;
487 result.target2sub = not_contained;
492 if (result.whole2sub == contained_private)
493 // We found SUBOBJ as a private non-virtual base, therefore all
494 // cross casts will fail. We have already found a down cast, if
502 // find_public_subobj helper for non-public or multiple inheritance types. See
503 // __user_type_info::do_find_public_subobj for semantics. We make use of BOFF
504 // to prune the base class walk.
505 __user_type_info::sub_kind __class_type_info::
506 do_find_public_subobj (int boff, const type_info &subtype, void *objptr, void *subptr) const
508 if (objptr == subptr && subtype == *this)
509 return contained_public;
511 for (size_t i = n_bases; i--;)
513 if (base_list[i].access != PUBLIC)
514 continue; // Not public, can't be here.
517 if (base_list[i].is_virtual && boff == -3)
518 // Not a virtual base, so can't be here.
521 p = convert_to_base (objptr,
522 base_list[i].is_virtual,
523 base_list[i].offset);
525 sub_kind base_kind = base_list[i].base->do_find_public_subobj
526 (boff, subtype, p, subptr);
527 if (contained_p (base_kind))
529 if (base_list[i].is_virtual)
530 base_kind = sub_kind (base_kind | contained_virtual_mask);
535 return not_contained;
542 // return true if this is a type_info for a pointer type
544 is_pointer_p () const
549 // return true if this is a type_info for a function type
551 is_function_p () const
556 // try and catch a thrown object.
558 do_catch (const type_info *thr_type, void **, unsigned) const
560 return *this == *thr_type;
563 // upcast from this type to the target. __class_type_info will override
565 do_upcast (const abi::__class_type_info *, void **) const
577 // initial part of a vtable, this structure is used with offsetof, so we don't
578 // have to keep alignments consistent manually.
579 struct vtable_prefix {
580 ptrdiff_t whole_object; // offset to most derived object
581 const __class_type_info *whole_type; // pointer to most derived type_info
582 const void *origin; // what a class's vptr points to
585 template <typename T>
587 adjust_pointer (const void *base, ptrdiff_t offset)
589 return reinterpret_cast <const T *>
590 (reinterpret_cast <const char *> (base) + offset);
593 // some predicate functions for __class_type_info::sub_kind
594 inline bool contained_p (__class_type_info::sub_kind access_path)
596 return access_path >= __class_type_info::contained_mask;
598 inline bool public_p (__class_type_info::sub_kind access_path)
600 return access_path & __class_type_info::contained_public_mask;
602 inline bool virtual_p (__class_type_info::sub_kind access_path)
604 return (access_path & __class_type_info::contained_virtual_mask);
606 inline bool contained_public_p (__class_type_info::sub_kind access_path)
608 return (access_path & __class_type_info::contained_public) == __class_type_info::contained_public;
610 inline bool contained_nonpublic_p (__class_type_info::sub_kind access_path)
612 return (access_path & __class_type_info::contained_public) == __class_type_info::contained_mask;
614 inline bool contained_nonvirtual_p (__class_type_info::sub_kind access_path)
616 return (access_path & (__class_type_info::contained_mask | __class_type_info::contained_virtual_mask))
617 == __class_type_info::contained_mask;
620 static const __class_type_info *const nonvirtual_base_type =
621 static_cast <const __class_type_info *> (0) + 1;
629 ~__class_type_info ()
632 __si_class_type_info::
633 ~__si_class_type_info ()
636 __vmi_class_type_info::
637 ~__vmi_class_type_info ()
640 bool __class_type_info::
641 do_catch (const type_info *thr_type, void **thr_obj,
642 unsigned outer) const
644 if (*this == *thr_type)
647 // Neither `A' nor `A *'.
649 return thr_type->do_upcast (this, thr_obj);
652 bool __class_type_info::
653 do_upcast (const __class_type_info *dst_type, void **obj_ptr) const
655 upcast_result result (__vmi_class_type_info::details_unknown_mask);
657 if (do_upcast (contained_public, dst_type, *obj_ptr, result))
659 *obj_ptr = const_cast <void *> (result.dst_ptr);
660 return contained_public_p (result.whole2dst);
663 inline __class_type_info::sub_kind __class_type_info::
664 find_public_src (ptrdiff_t src2dst,
666 const __class_type_info *src_type,
667 const void *src_ptr) const
670 return adjust_pointer <void> (obj_ptr, src2dst) == src_ptr
671 ? contained_public : not_contained;
673 return not_contained;
674 return do_find_public_src (src2dst, obj_ptr, src_type, src_ptr);
677 __class_type_info::sub_kind __class_type_info::
678 do_find_public_src (ptrdiff_t,
680 const __class_type_info *,
681 const void *src_ptr) const
683 if (src_ptr == obj_ptr)
684 // Must be our type, as the pointers match.
685 return contained_public;
686 return not_contained;
689 __class_type_info::sub_kind __si_class_type_info::
690 do_find_public_src (ptrdiff_t src2dst,
692 const __class_type_info *src_type,
693 const void *src_ptr) const
695 if (src_ptr == obj_ptr && *this == *src_type)
696 return contained_public;
697 return base->do_find_public_src (src2dst, obj_ptr, src_type, src_ptr);
700 __class_type_info::sub_kind __vmi_class_type_info::
701 do_find_public_src (ptrdiff_t src2dst,
703 const __class_type_info *src_type,
704 const void *src_ptr) const
706 if (obj_ptr == src_ptr && *this == *src_type)
707 return contained_public;
709 for (size_t i = n_bases; i--;)
711 if (!base_list[i].is_public_p ())
712 continue; // Not public, can't be here.
714 const void *base = obj_ptr;
715 ptrdiff_t offset = base_list[i].offset ();
717 if (base_list[i].is_virtual_p ())
720 continue; // Not a virtual base, so can't be here.
721 const ptrdiff_t *vtable = *static_cast <const ptrdiff_t *const *> (base);
723 offset = vtable[offset];
725 base = adjust_pointer <void> (base, offset);
727 sub_kind base_kind = base_list[i].base->do_find_public_src
728 (src2dst, base, src_type, src_ptr);
729 if (contained_p (base_kind))
731 if (base_list[i].is_virtual_p ())
732 base_kind = sub_kind (base_kind | contained_virtual_mask);
737 return not_contained;
740 bool __class_type_info::
741 do_dyncast (ptrdiff_t,
742 sub_kind access_path,
743 const __class_type_info *dst_type,
745 const __class_type_info *src_type,
747 dyncast_result &__restrict result) const
749 if (obj_ptr == src_ptr && *this == *src_type)
751 // The src object we started from. Indicate how we are accessible from
752 // the most derived object.
753 result.whole2src = access_path;
756 if (*this == *dst_type)
758 result.dst_ptr = obj_ptr;
759 result.whole2dst = access_path;
760 result.dst2src = not_contained;
766 bool __si_class_type_info::
767 do_dyncast (ptrdiff_t src2dst,
768 sub_kind access_path,
769 const __class_type_info *dst_type,
771 const __class_type_info *src_type,
773 dyncast_result &__restrict result) const
775 if (*this == *dst_type)
777 result.dst_ptr = obj_ptr;
778 result.whole2dst = access_path;
780 result.dst2src = adjust_pointer <void> (obj_ptr, src2dst) == src_ptr
781 ? contained_public : not_contained;
782 else if (src2dst == -2)
783 result.dst2src = not_contained;
786 if (obj_ptr == src_ptr && *this == *src_type)
788 // The src object we started from. Indicate how we are accessible from
789 // the most derived object.
790 result.whole2src = access_path;
793 return base->do_dyncast (src2dst, access_path, dst_type, obj_ptr,
794 src_type, src_ptr, result);
797 // This is a big hairy function. Although the run-time behaviour of
798 // dynamic_cast is simple to describe, it gives rise to some non-obvious
799 // behaviour. We also desire to determine as early as possible any definite
800 // answer we can get. Because it is unknown what the run-time ratio of
801 // succeeding to failing dynamic casts is, we do not know in which direction
802 // to bias any optimizations. To that end we make no particular effort towards
803 // early fail answers or early success answers. Instead we try to minimize
804 // work by filling in things lazily (when we know we need the information),
805 // and opportunisticly take early success or failure results.
806 bool __vmi_class_type_info::
807 do_dyncast (ptrdiff_t src2dst,
808 sub_kind access_path,
809 const __class_type_info *dst_type,
811 const __class_type_info *src_type,
813 dyncast_result &__restrict result) const
815 if (obj_ptr == src_ptr && *this == *src_type)
817 // The src object we started from. Indicate how we are accessible from
818 // the most derived object.
819 result.whole2src = access_path;
822 if (*this == *dst_type)
824 result.dst_ptr = obj_ptr;
825 result.whole2dst = access_path;
827 result.dst2src = adjust_pointer <void> (obj_ptr, src2dst) == src_ptr
828 ? contained_public : not_contained;
829 else if (src2dst == -2)
830 result.dst2src = not_contained;
833 bool result_ambig = false;
834 for (size_t i = n_bases; i--;)
836 dyncast_result result2;
837 void const *base = obj_ptr;
838 sub_kind base_access = access_path;
839 ptrdiff_t offset = base_list[i].offset ();
841 if (base_list[i].is_virtual_p ())
843 base_access = sub_kind (base_access | contained_virtual_mask);
844 const ptrdiff_t *vtable = *static_cast <const ptrdiff_t *const *> (base);
846 offset = vtable[offset];
848 base = adjust_pointer <void> (base, offset);
850 if (!base_list[i].is_public_p ())
851 base_access = sub_kind (base_access & ~contained_public_mask);
854 = base_list[i].base->do_dyncast (src2dst, base_access,
856 src_type, src_ptr, result2);
857 result.whole2src = sub_kind (result.whole2src | result2.whole2src);
858 if (result2.dst2src == contained_public
859 || result2.dst2src == contained_ambig)
861 result.dst_ptr = result2.dst_ptr;
862 result.whole2dst = result2.whole2dst;
863 result.dst2src = result2.dst2src;
864 // Found a downcast which can't be bettered or an ambiguous downcast
865 // which can't be disambiguated
866 return result2_ambig;
869 if (!result_ambig && !result.dst_ptr)
871 // Not found anything yet.
872 result.dst_ptr = result2.dst_ptr;
873 result.whole2dst = result2.whole2dst;
874 result_ambig = result2_ambig;
876 else if (result.dst_ptr && result.dst_ptr == result2.dst_ptr)
878 // Found at same address, must be via virtual. Pick the most
881 sub_kind (result.whole2dst | result2.whole2dst);
883 else if ((result.dst_ptr && result2.dst_ptr)
884 || (result_ambig && result2.dst_ptr)
885 || (result2_ambig && result.dst_ptr))
887 // Found two different DST_TYPE bases, or a valid one and a set of
888 // ambiguous ones, must disambiguate. See whether SRC_PTR is
889 // contained publicly within one of the non-ambiguous choices. If it
890 // is in only one, then that's the choice. If it is in both, then
891 // we're ambiguous and fail. If it is in neither, we're ambiguous,
892 // but don't yet fail as we might later find a third base which does
895 sub_kind new_sub_kind = result2.dst2src;
896 sub_kind old_sub_kind = result.dst2src;
898 if (contained_nonvirtual_p (result.whole2src))
900 // We already found SRC_PTR as a non-virtual base of most
901 // derived. Therefore if it is in either choice, it can only be
902 // in one of them, and we will already know.
903 if (old_sub_kind == unknown)
904 old_sub_kind = not_contained;
905 if (new_sub_kind == unknown)
906 new_sub_kind = not_contained;
910 if (old_sub_kind >= not_contained)
911 ;// already calculated
912 else if (contained_nonvirtual_p (new_sub_kind))
913 // Already found non-virtually inside the other choice,
914 // cannot be in this.
915 old_sub_kind = not_contained;
917 old_sub_kind = dst_type->find_public_src
918 (src2dst, result.dst_ptr, src_type, src_ptr);
920 if (new_sub_kind >= not_contained)
921 ;// already calculated
922 else if (contained_nonvirtual_p (old_sub_kind))
923 // Already found non-virtually inside the other choice,
924 // cannot be in this.
925 new_sub_kind = not_contained;
927 new_sub_kind = dst_type->find_public_src
928 (src2dst, result2.dst_ptr, src_type, src_ptr);
931 // Neither sub_kind can be contained_ambig -- we bail out early
932 // when we find those.
933 if (contained_p (sub_kind (new_sub_kind ^ old_sub_kind)))
935 // Only on one choice, not ambiguous.
936 if (contained_p (new_sub_kind))
939 result.dst_ptr = result2.dst_ptr;
940 result.whole2dst = result2.whole2dst;
941 result_ambig = false;
942 old_sub_kind = new_sub_kind;
944 result.dst2src = old_sub_kind;
945 if (public_p (result.dst2src))
946 return false; // Can't be an ambiguating downcast for later discovery.
947 if (!virtual_p (result.dst2src))
948 return false; // Found non-virtually can't be bettered
950 else if (contained_p (sub_kind (new_sub_kind & old_sub_kind)))
953 result.dst_ptr = NULL;
954 result.dst2src = contained_ambig;
955 return true; // Fail.
959 // In neither publicly, ambiguous for the moment, but keep
960 // looking. It is possible that it was private in one or
961 // both and therefore we should fail, but that's just tough.
962 result.dst_ptr = NULL;
963 result.dst2src = not_contained;
968 if (result.whole2src == contained_private)
969 // We found SRC_PTR as a private non-virtual base, therefore all
970 // cross casts will fail. We have already found a down cast, if
978 bool __class_type_info::
979 do_upcast (sub_kind access_path,
980 const __class_type_info *dst, const void *obj,
981 upcast_result &__restrict result) const
985 result.dst_ptr = obj;
986 result.base_type = nonvirtual_base_type;
987 result.whole2dst = access_path;
988 return contained_nonpublic_p (access_path);
993 bool __si_class_type_info::
994 do_upcast (sub_kind access_path,
995 const __class_type_info *dst, const void *obj_ptr,
996 upcast_result &__restrict result) const
1000 result.dst_ptr = obj_ptr;
1001 result.base_type = nonvirtual_base_type;
1002 result.whole2dst = access_path;
1003 return contained_nonpublic_p (access_path);
1005 return base->do_upcast (access_path, dst, obj_ptr, result);
1008 bool __vmi_class_type_info::
1009 do_upcast (sub_kind access_path,
1010 const __class_type_info *dst, const void *obj_ptr,
1011 upcast_result &__restrict result) const
1015 result.dst_ptr = obj_ptr;
1016 result.base_type = nonvirtual_base_type;
1017 result.whole2dst = access_path;
1018 return contained_nonpublic_p (access_path);
1021 int src_details = result.src_details;
1022 if (src_details & details_unknown_mask)
1023 src_details = details;
1025 for (size_t i = n_bases; i--;)
1027 upcast_result result2 (src_details);
1028 const void *base = obj_ptr;
1029 sub_kind sub_access = access_path;
1030 ptrdiff_t offset = base_list[i].offset ();
1032 if (!base_list[i].is_public_p ())
1034 if (!(src_details & non_diamond_repeat_mask))
1035 // original cannot have an ambiguous base
1037 sub_access = sub_kind (sub_access & ~contained_public_mask);
1039 if (base_list[i].is_virtual_p ())
1041 sub_access = sub_kind (sub_access | contained_virtual_mask);
1045 const ptrdiff_t *vtable = *static_cast <const ptrdiff_t *const *> (base);
1046 offset = vtable[offset];
1050 base = adjust_pointer <void> (base, offset);
1052 if (base_list[i].base->do_upcast (sub_access, dst, base, result2))
1053 return true; // must fail
1054 if (result2.base_type)
1056 if (result2.base_type == nonvirtual_base_type
1057 && base_list[i].is_virtual_p ())
1058 result2.base_type = base_list[i].base;
1059 if (!result.base_type)
1062 if (!(details & non_diamond_repeat_mask))
1063 // cannot have an ambiguous other base
1066 else if (result.dst_ptr != result2.dst_ptr)
1068 // Found an ambiguity.
1069 result.dst_ptr = NULL;
1070 result.whole2dst = contained_ambig;
1073 else if (result.dst_ptr)
1075 // Ok, found real object via a virtual path.
1077 = sub_kind (result.whole2dst | result2.whole2dst);
1081 // Dealing with a null pointer, need to check vbase
1082 // containing each of the two choices.
1083 if (result2.base_type == nonvirtual_base_type
1084 || result.base_type == nonvirtual_base_type
1085 || !(*result2.base_type == *result.base_type))
1087 // Already ambiguous, not virtual or via different virtuals.
1089 result.whole2dst = contained_ambig;
1098 // this is the external interface to the dynamic cast machinery
1100 __dynamic_cast (const void *src_ptr, // object started from
1101 const __class_type_info *src_type, // type of the starting object
1102 const __class_type_info *dst_type, // desired target type
1103 ptrdiff_t src2dst) // how src and dst are related
1105 const void *vtable = *static_cast <const void *const *> (src_ptr);
1106 const vtable_prefix *prefix =
1107 adjust_pointer <vtable_prefix> (vtable,
1108 -offsetof (vtable_prefix, origin));
1109 const void *whole_ptr =
1110 adjust_pointer <void> (src_ptr, prefix->whole_object);
1111 const __class_type_info *whole_type = prefix->whole_type;
1112 __class_type_info::dyncast_result result;
1114 whole_type->do_dyncast (src2dst, __class_type_info::contained_public,
1115 dst_type, whole_ptr, src_type, src_ptr, result);
1116 if (!result.dst_ptr)
1118 if (contained_public_p (result.dst2src))
1119 return const_cast <void *> (result.dst_ptr);
1120 if (contained_public_p (__class_type_info::sub_kind (result.whole2src & result.whole2dst)))
1121 // Found a valid cross cast
1122 return const_cast <void *> (result.dst_ptr);
1123 if (contained_nonvirtual_p (result.whole2src))
1124 // Found an invalid cross cast, which cannot also be a down cast
1126 #if 0 // FIXME: we need to discover this lazily
1127 if (!(whole_type->details & __class_type_info::private_base_mask))
1128 // whole type has no private bases
1129 return const_cast <void *> (result.dst_ptr);
1131 if (result.dst2src == __class_type_info::unknown)
1132 result.dst2src = dst_type->find_public_src (src2dst, result.dst_ptr,
1134 if (contained_public_p (result.dst2src))
1135 // Found a valid down cast
1136 return const_cast <void *> (result.dst_ptr);
1137 // Must be an invalid down cast, or the cross cast wasn't bettered
1141 }; // namespace __cxxabiv1