2001-02-15 Benjamin Kosnik <bkoz@redhat.com>
[official-gcc.git] / libstdc++-v3 / libsupc++ / tinfo.cc
blobdbb164b2380a62bfe9fbd8a3ad4832e3aac61520
1 // Methods for type_info for -*- C++ -*- Run Time Type Identification.
3 // Copyright (C) 1994, 1996, 1998, 1999, 2000 Free Software Foundation
4 //
5 // This file is part of GNU CC.
6 //
7 // GNU CC is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2, or (at your option)
10 // any later version.
12 // GNU CC 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.
17 // You should have received a copy of the GNU General Public License
18 // along with GNU CC; see the file COPYING. If not, write to
19 // the Free Software Foundation, 59 Temple Place - Suite 330,
20 // Boston, MA 02111-1307, USA.
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction. Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License. This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
31 #pragma implementation "typeinfo"
33 #include <cstddef>
34 #include "tinfo.h"
35 #include "new" // for placement new
37 // This file contains the minimal working set necessary to link with code
38 // that uses virtual functions and -frtti but does not actually use RTTI
39 // functionality.
41 std::type_info::
42 ~type_info ()
43 { }
45 #if !__GXX_MERGED_TYPEINFO_NAMES
47 // We can't rely on common symbols being shared between shared objects.
48 bool std::type_info::
49 operator== (const std::type_info& arg) const
51 return (&arg == this) || (__builtin_strcmp (name (), arg.name ()) == 0);
54 #endif
56 #if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
57 // original (old) abi
59 namespace
61 // ADDR is a pointer to an object. Convert it to a pointer to a base,
62 // using OFFSET.
63 inline void*
64 convert_to_base (void *addr, bool is_virtual, myint32 offset)
66 if (!addr)
67 return NULL;
69 if (!is_virtual)
70 return (char *) addr + offset;
72 // Under the old ABI, the offset gives us the address of a pointer
73 // to the virtual base.
74 return *((void **) ((char *) addr + offset));
79 extern "C" void
80 __rtti_class (void *addr, const char *name,
81 const __class_type_info::base_info *bl, std::size_t bn)
82 { new (addr) __class_type_info (name, bl, bn); }
84 extern "C" void
85 __rtti_si (void *addr, const char *n, const std::type_info *ti)
87 new (addr) __si_type_info
88 (n, static_cast <const __user_type_info &> (*ti));
91 extern "C" void
92 __rtti_user (void *addr, const char *name)
93 { new (addr) __user_type_info (name); }
95 // Upcast for catch checking. OBJPTR points to the thrown object and might be
96 // NULL. Return 0 on failure, non-zero on success. Set *ADJPTR to adjusted
97 // object pointer.
98 int __user_type_info::
99 upcast (const type_info &target, void *objptr,
100 void **adjptr) const
102 upcast_result result;
104 if (do_upcast (contained_public, target, objptr, result))
105 return 0;
106 *adjptr = result.target_obj;
107 return contained_public_p (result.whole2target);
110 // Down or cross cast for dynamic_cast. OBJPTR points to the most derrived
111 // object, SUBPTR points to the static base object. Both must not be NULL.
112 // TARGET specifies the desired target type, SUBTYPE specifies the static
113 // type. Both must be defined. Returns adjusted object pointer on success,
114 // NULL on failure. [expr.dynamic.cast]/8 says 'unambiguous public base'. This
115 // itself is an ambiguous statement. We choose it to mean the base must be
116 // separately unambiguous and public, rather than unambiguous considering only
117 // public bases.
118 void *__user_type_info::
119 dyncast (int boff,
120 const type_info &target, void *objptr,
121 const type_info &subtype, void *subptr) const
123 dyncast_result result;
125 do_dyncast (boff, contained_public,
126 target, objptr, subtype, subptr, result);
127 if (!result.target_obj)
128 return NULL;
129 if (contained_public_p (result.target2sub))
130 return result.target_obj;
131 if (contained_public_p (sub_kind (result.whole2sub & result.whole2target)))
132 // Found a valid cross cast
133 return result.target_obj;
134 if (contained_nonvirtual_p (result.whole2sub))
135 // Found an invalid cross cast, which cannot also be a down cast
136 return NULL;
137 if (result.target2sub == unknown)
138 result.target2sub = static_cast <const __user_type_info &> (target)
139 .find_public_subobj (boff, subtype,
140 result.target_obj, subptr);
141 if (contained_public_p (result.target2sub))
142 // Found a valid down cast
143 return result.target_obj;
144 // Must be an invalid down cast, or the cross cast wasn't bettered
145 return NULL;
148 // Catch cast helper. ACCESS_PATH is the access from the complete thrown
149 // object to this base. TARGET is the desired type we want to catch. OBJPTR
150 // points to this base within the throw object, it might be NULL. Fill in
151 // RESULT with what we find. Return true, should we determine catch must fail.
152 bool __user_type_info::
153 do_upcast (sub_kind access_path,
154 const type_info &target, void *objptr,
155 upcast_result &__restrict result) const
157 if (*this == target)
159 result.target_obj = objptr;
160 result.base_type = nonvirtual_base_type;
161 result.whole2target = access_path;
162 return contained_nonpublic_p (access_path);
164 return false;
167 // dynamic cast helper. ACCESS_PATH gives the access from the most derived
168 // object to this base. TARGET indicates the desired type we want. OBJPTR
169 // points to this base within the object. SUBTYPE indicates the static type
170 // started from and SUBPTR points to that base within the most derived object.
171 // Fill in RESULT with what we find. Return true if we have located an
172 // ambiguous match.
173 bool __user_type_info::
174 do_dyncast (int, sub_kind access_path,
175 const type_info &target, void *objptr,
176 const type_info &subtype, void *subptr,
177 dyncast_result &__restrict result) const
179 if (objptr == subptr && *this == subtype)
181 // The subobject we started from. Indicate how we are accessible from
182 // the most derived object.
183 result.whole2sub = access_path;
184 return false;
186 if (*this == target)
188 result.target_obj = objptr;
189 result.whole2target = access_path;
190 result.target2sub = not_contained;
191 return false;
193 return false;
196 // find_public_subobj helper. Return contained_public if we are the desired
197 // subtype. OBJPTR points to this base type, SUBPTR points to the desired base
198 // object.
199 __user_type_info::sub_kind __user_type_info::
200 do_find_public_subobj (int, const type_info &, void *objptr, void *subptr) const
202 if (subptr == objptr)
203 // Must be our type, as the pointers match.
204 return contained_public;
205 return not_contained;
208 // catch helper for single public inheritance types. See
209 // __user_type_info::do_upcast for semantics.
210 bool __si_type_info::
211 do_upcast (sub_kind access_path,
212 const type_info &target, void *objptr,
213 upcast_result &__restrict result) const
215 if (*this == target)
217 result.target_obj = objptr;
218 result.base_type = nonvirtual_base_type;
219 result.whole2target = access_path;
220 return contained_nonpublic_p (access_path);
222 return base.do_upcast (access_path, target, objptr, result);
225 // dynamic cast helper for single public inheritance types. See
226 // __user_type_info::do_dyncast for semantics. BOFF indicates how SUBTYPE
227 // types are inherited by TARGET types.
228 bool __si_type_info::
229 do_dyncast (int boff, sub_kind access_path,
230 const type_info &target, void *objptr,
231 const type_info &subtype, void *subptr,
232 dyncast_result &__restrict result) const
234 if (objptr == subptr && *this == subtype)
236 // The subobject we started from. Indicate how we are accessible from
237 // the most derived object.
238 result.whole2sub = access_path;
239 return false;
241 if (*this == target)
243 result.target_obj = objptr;
244 result.whole2target = access_path;
245 if (boff >= 0)
246 result.target2sub = ((char *)subptr - (char *)objptr) == boff
247 ? contained_public : not_contained;
248 else if (boff == -2)
249 result.target2sub = not_contained;
250 return false;
252 return base.do_dyncast (boff, access_path,
253 target, objptr, subtype, subptr, result);
256 // find_public_subobj helper. See __user_type_info::do_find_public_subobj or
257 // semantics. BOFF indicates how SUBTYPE types are inherited by the original
258 // target object.
259 __user_type_info::sub_kind __si_type_info::
260 do_find_public_subobj (int boff, const type_info &subtype, void *objptr, void *subptr) const
262 if (subptr == objptr && subtype == *this)
263 return contained_public;
264 return base.do_find_public_subobj (boff, subtype, objptr, subptr);
267 // catch helper for multiple or non-public inheritance types. See
268 // __user_type_info::do_upcast for semantics.
269 bool __class_type_info::
270 do_upcast (sub_kind access_path,
271 const type_info &target, void *objptr,
272 upcast_result &__restrict result) const
274 if (*this == target)
276 result.target_obj = objptr;
277 result.base_type = nonvirtual_base_type;
278 result.whole2target = access_path;
279 return contained_nonpublic_p (access_path);
282 for (std::size_t i = n_bases; i--;)
284 upcast_result result2;
285 void *p = objptr;
286 sub_kind sub_access = access_path;
287 p = convert_to_base (p,
288 base_list[i].is_virtual,
289 base_list[i].offset);
290 if (base_list[i].is_virtual)
291 sub_access = sub_kind (sub_access | contained_virtual_mask);
292 if (base_list[i].access != PUBLIC)
293 sub_access = sub_kind (sub_access & ~contained_public_mask);
294 if (base_list[i].base->do_upcast (sub_access, target, p, result2)
295 && !contained_virtual_p (result2.whole2target))
296 return true; // must fail
297 if (result2.base_type)
299 if (result2.base_type == nonvirtual_base_type
300 && base_list[i].is_virtual)
301 result2.base_type = base_list[i].base;
302 if (!result.base_type)
303 result = result2;
304 else if (result.target_obj != result2.target_obj)
306 // Found an ambiguity.
307 result.target_obj = NULL;
308 result.whole2target = contained_ambig;
309 return true;
311 else if (result.target_obj)
313 // Ok, found real object via a virtual path.
314 result.whole2target
315 = sub_kind (result.whole2target | result2.whole2target);
317 else
319 // Dealing with a null pointer, need to check vbase
320 // containing each of the two choices.
321 if (result2.base_type == nonvirtual_base_type
322 || result.base_type == nonvirtual_base_type
323 || !(*result2.base_type == *result.base_type))
325 // Already ambiguous, not virtual or via different virtuals.
326 // Cannot match.
327 result.whole2target = contained_ambig;
328 return true;
330 result.whole2target
331 = sub_kind (result.whole2target | result2.whole2target);
335 return false;
338 // dynamic cast helper for non-public or multiple inheritance types. See
339 // __user_type_info::do_dyncast for overall semantics.
340 // This is a big hairy function. Although the run-time behaviour of
341 // dynamic_cast is simple to describe, it gives rise to some non-obvious
342 // behaviour. We also desire to determine as early as possible any definite
343 // answer we can get. Because it is unknown what the run-time ratio of
344 // succeeding to failing dynamic casts is, we do not know in which direction
345 // to bias any optimizations. To that end we make no particular effort towards
346 // early fail answers or early success answers. Instead we try to minimize
347 // work by filling in things lazily (when we know we need the information),
348 // and opportunisticly take early success or failure results.
349 bool __class_type_info::
350 do_dyncast (int boff, sub_kind access_path,
351 const type_info &target, void *objptr,
352 const type_info &subtype, void *subptr,
353 dyncast_result &__restrict result) const
355 if (objptr == subptr && *this == subtype)
357 // The subobject we started from. Indicate how we are accessible from
358 // the most derived object.
359 result.whole2sub = access_path;
360 return false;
362 if (*this == target)
364 result.target_obj = objptr;
365 result.whole2target = access_path;
366 if (boff >= 0)
367 result.target2sub = ((char *)subptr - (char *)objptr) == boff
368 ? contained_public : not_contained;
369 else if (boff == -2)
370 result.target2sub = not_contained;
371 return false;
373 bool result_ambig = false;
374 for (std::size_t i = n_bases; i--;)
376 dyncast_result result2;
377 void *p;
378 sub_kind sub_access = access_path;
379 p = convert_to_base (objptr,
380 base_list[i].is_virtual,
381 base_list[i].offset);
382 if (base_list[i].is_virtual)
383 sub_access = sub_kind (sub_access | contained_virtual_mask);
384 if (base_list[i].access != PUBLIC)
385 sub_access = sub_kind (sub_access & ~contained_public_mask);
387 bool result2_ambig
388 = base_list[i].base->do_dyncast (boff, sub_access,
389 target, p, subtype, subptr, result2);
390 result.whole2sub = sub_kind (result.whole2sub | result2.whole2sub);
391 if (result2.target2sub == contained_public
392 || result2.target2sub == contained_ambig)
394 result.target_obj = result2.target_obj;
395 result.whole2target = result2.whole2target;
396 result.target2sub = result2.target2sub;
397 // Found a downcast which can't be bettered or an ambiguous downcast
398 // which can't be disambiguated
399 return result2_ambig;
402 if (!result_ambig && !result.target_obj)
404 // Not found anything yet.
405 result.target_obj = result2.target_obj;
406 result.whole2target = result2.whole2target;
407 result_ambig = result2_ambig;
409 else if (result.target_obj && result.target_obj == result2.target_obj)
411 // Found at same address, must be via virtual. Pick the most
412 // accessible path.
413 result.whole2target =
414 sub_kind (result.whole2target | result2.whole2target);
416 else if ((result.target_obj && result2.target_obj)
417 || (result_ambig && result2.target_obj)
418 || (result2_ambig && result.target_obj))
420 // Found two different TARGET bases, or a valid one and a set of
421 // ambiguous ones, must disambiguate. See whether SUBOBJ is
422 // contained publicly within one of the non-ambiguous choices.
423 // If it is in only one, then that's the choice. If it is in
424 // both, then we're ambiguous and fail. If it is in neither,
425 // we're ambiguous, but don't yet fail as we might later find a
426 // third base which does contain SUBPTR.
428 sub_kind new_sub_kind = result2.target2sub;
429 sub_kind old_sub_kind = result.target2sub;
431 if (contained_nonvirtual_p (result.whole2sub))
433 // We already found SUBOBJ as a non-virtual base of most
434 // derived. Therefore if it is in either choice, it can only be
435 // in one of them, and we will already know.
436 if (old_sub_kind == unknown)
437 old_sub_kind = not_contained;
438 if (new_sub_kind == unknown)
439 new_sub_kind = not_contained;
441 else
443 const __user_type_info &t =
444 static_cast <const __user_type_info &> (target);
446 if (old_sub_kind >= not_contained)
447 ;// already calculated
448 else if (contained_nonvirtual_p (new_sub_kind))
449 // Already found non-virtually inside the other choice,
450 // cannot be in this.
451 old_sub_kind = not_contained;
452 else
453 old_sub_kind = t.find_public_subobj (boff, subtype,
454 result.target_obj, subptr);
456 if (new_sub_kind >= not_contained)
457 ;// already calculated
458 else if (contained_nonvirtual_p (old_sub_kind))
459 // Already found non-virtually inside the other choice,
460 // cannot be in this.
461 new_sub_kind = not_contained;
462 else
463 new_sub_kind = t.find_public_subobj (boff, subtype,
464 result2.target_obj, subptr);
467 // Neither sub_kind can be contained_ambig -- we bail out early
468 // when we find those.
469 if (contained_p (sub_kind (new_sub_kind ^ old_sub_kind)))
471 // Only on one choice, not ambiguous.
472 if (contained_p (new_sub_kind))
474 // Only in new.
475 result.target_obj = result2.target_obj;
476 result.whole2target = result2.whole2target;
477 result_ambig = false;
478 old_sub_kind = new_sub_kind;
480 result.target2sub = old_sub_kind;
481 if (result.target2sub == contained_public)
482 return false; // Can't be an ambiguating downcast for later discovery.
484 else if (contained_p (sub_kind (new_sub_kind & old_sub_kind)))
486 // In both.
487 result.target_obj = NULL;
488 result.target2sub = contained_ambig;
489 return true; // Fail.
491 else
493 // In neither publicly, ambiguous for the moment, but keep
494 // looking. It is possible that it was private in one or
495 // both and therefore we should fail, but that's just tough.
496 result.target_obj = NULL;
497 result.target2sub = not_contained;
498 result_ambig = true;
502 if (result.whole2sub == contained_private)
503 // We found SUBOBJ as a private non-virtual base, therefore all
504 // cross casts will fail. We have already found a down cast, if
505 // there is one.
506 return result_ambig;
509 return result_ambig;
512 // find_public_subobj helper for non-public or multiple inheritance types. See
513 // __user_type_info::do_find_public_subobj for semantics. We make use of BOFF
514 // to prune the base class walk.
515 __user_type_info::sub_kind __class_type_info::
516 do_find_public_subobj (int boff, const type_info &subtype, void *objptr, void *subptr) const
518 if (objptr == subptr && subtype == *this)
519 return contained_public;
521 for (std::size_t i = n_bases; i--;)
523 if (base_list[i].access != PUBLIC)
524 continue; // Not public, can't be here.
525 void *p;
527 if (base_list[i].is_virtual && boff == -3)
528 // Not a virtual base, so can't be here.
529 continue;
531 p = convert_to_base (objptr,
532 base_list[i].is_virtual,
533 base_list[i].offset);
535 sub_kind base_kind = base_list[i].base->do_find_public_subobj
536 (boff, subtype, p, subptr);
537 if (contained_p (base_kind))
539 if (base_list[i].is_virtual)
540 base_kind = sub_kind (base_kind | contained_virtual_mask);
541 return base_kind;
545 return not_contained;
547 #else
548 // new abi
550 namespace std {
552 // return true if this is a type_info for a pointer type
553 bool type_info::
554 __is_pointer_p () const
556 return false;
559 // return true if this is a type_info for a function type
560 bool type_info::
561 __is_function_p () const
563 return false;
566 // try and catch a thrown object.
567 bool type_info::
568 __do_catch (const type_info *thr_type, void **, unsigned) const
570 return *this == *thr_type;
573 // upcast from this type to the target. __class_type_info will override
574 bool type_info::
575 __do_upcast (const abi::__class_type_info *, void **) const
577 return false;
582 namespace {
584 using namespace std;
585 using namespace abi;
587 // initial part of a vtable, this structure is used with offsetof, so we don't
588 // have to keep alignments consistent manually.
589 struct vtable_prefix {
590 ptrdiff_t whole_object; // offset to most derived object
591 const __class_type_info *whole_type; // pointer to most derived type_info
592 const void *origin; // what a class's vptr points to
595 template <typename T>
596 inline const T *
597 adjust_pointer (const void *base, ptrdiff_t offset)
599 return reinterpret_cast <const T *>
600 (reinterpret_cast <const char *> (base) + offset);
603 // ADDR is a pointer to an object. Convert it to a pointer to a base,
604 // using OFFSET. IS_VIRTUAL is true, if we are getting a virtual base.
605 inline void const *
606 convert_to_base (void const *addr, bool is_virtual, ptrdiff_t offset)
608 if (is_virtual)
610 const void *vtable = *static_cast <const void *const *> (addr);
612 offset = *adjust_pointer<ptrdiff_t> (vtable, offset);
615 return adjust_pointer<void> (addr, offset);
618 // some predicate functions for __class_type_info::__sub_kind
619 inline bool contained_p (__class_type_info::__sub_kind access_path)
621 return access_path >= __class_type_info::__contained_mask;
623 inline bool public_p (__class_type_info::__sub_kind access_path)
625 return access_path & __class_type_info::__contained_public_mask;
627 inline bool virtual_p (__class_type_info::__sub_kind access_path)
629 return (access_path & __class_type_info::__contained_virtual_mask);
631 inline bool contained_public_p (__class_type_info::__sub_kind access_path)
633 return ((access_path & __class_type_info::__contained_public)
634 == __class_type_info::__contained_public);
636 inline bool contained_nonpublic_p (__class_type_info::__sub_kind access_path)
638 return ((access_path & __class_type_info::__contained_public)
639 == __class_type_info::__contained_mask);
641 inline bool contained_nonvirtual_p (__class_type_info::__sub_kind access_path)
643 return ((access_path & (__class_type_info::__contained_mask
644 | __class_type_info::__contained_virtual_mask))
645 == __class_type_info::__contained_mask);
648 static const __class_type_info *const nonvirtual_base_type =
649 static_cast <const __class_type_info *> (0) + 1;
651 }; // namespace
653 namespace __cxxabiv1
656 __class_type_info::
657 ~__class_type_info ()
660 __si_class_type_info::
661 ~__si_class_type_info ()
664 __vmi_class_type_info::
665 ~__vmi_class_type_info ()
668 // __upcast_result is used to hold information during traversal of a class
669 // heirarchy when catch matching.
670 struct __class_type_info::__upcast_result
672 const void *dst_ptr; // pointer to caught object
673 __sub_kind part2dst; // path from current base to target
674 int src_details; // hints about the source type heirarchy
675 const __class_type_info *base_type; // where we found the target,
676 // if in vbase the __class_type_info of vbase
677 // if a non-virtual base then 1
678 // else NULL
679 public:
680 __upcast_result (int d)
681 :dst_ptr (NULL), part2dst (__unknown), src_details (d), base_type (NULL)
685 // __dyncast_result is used to hold information during traversal of a class
686 // heirarchy when dynamic casting.
687 struct __class_type_info::__dyncast_result
689 const void *dst_ptr; // pointer to target object or NULL
690 __sub_kind whole2dst; // path from most derived object to target
691 __sub_kind whole2src; // path from most derived object to sub object
692 __sub_kind dst2src; // path from target to sub object
693 int whole_details; // details of the whole class heirarchy
695 public:
696 __dyncast_result (int details_ = __vmi_class_type_info::__flags_unknown_mask)
697 :dst_ptr (NULL), whole2dst (__unknown),
698 whole2src (__unknown), dst2src (__unknown),
699 whole_details (details_)
703 bool __class_type_info::
704 __do_catch (const type_info *thr_type,
705 void **thr_obj,
706 unsigned outer) const
708 if (*this == *thr_type)
709 return true;
710 if (outer >= 4)
711 // Neither `A' nor `A *'.
712 return false;
713 return thr_type->__do_upcast (this, thr_obj);
716 bool __class_type_info::
717 __do_upcast (const __class_type_info *dst_type,
718 void **obj_ptr) const
720 __upcast_result result (__vmi_class_type_info::__flags_unknown_mask);
722 __do_upcast (dst_type, *obj_ptr, result);
723 if (!contained_public_p (result.part2dst))
724 return false;
725 *obj_ptr = const_cast <void *> (result.dst_ptr);
726 return true;
729 inline __class_type_info::__sub_kind __class_type_info::
730 __find_public_src (ptrdiff_t src2dst,
731 const void *obj_ptr,
732 const __class_type_info *src_type,
733 const void *src_ptr) const
735 if (src2dst >= 0)
736 return adjust_pointer <void> (obj_ptr, src2dst) == src_ptr
737 ? __contained_public : __not_contained;
738 if (src2dst == -2)
739 return __not_contained;
740 return __do_find_public_src (src2dst, obj_ptr, src_type, src_ptr);
743 __class_type_info::__sub_kind __class_type_info::
744 __do_find_public_src (ptrdiff_t,
745 const void *obj_ptr,
746 const __class_type_info *,
747 const void *src_ptr) const
749 if (src_ptr == obj_ptr)
750 // Must be our type, as the pointers match.
751 return __contained_public;
752 return __not_contained;
755 __class_type_info::__sub_kind __si_class_type_info::
756 __do_find_public_src (ptrdiff_t src2dst,
757 const void *obj_ptr,
758 const __class_type_info *src_type,
759 const void *src_ptr) const
761 if (src_ptr == obj_ptr && *this == *src_type)
762 return __contained_public;
763 return __base_type->__do_find_public_src (src2dst, obj_ptr, src_type, src_ptr);
766 __class_type_info::__sub_kind __vmi_class_type_info::
767 __do_find_public_src (ptrdiff_t src2dst,
768 const void *obj_ptr,
769 const __class_type_info *src_type,
770 const void *src_ptr) const
772 if (obj_ptr == src_ptr && *this == *src_type)
773 return __contained_public;
775 for (std::size_t i = __base_count; i--;)
777 if (!__base_info[i].__is_public_p ())
778 continue; // Not public, can't be here.
780 const void *base = obj_ptr;
781 ptrdiff_t offset = __base_info[i].__offset ();
782 bool is_virtual = __base_info[i].__is_virtual_p ();
784 if (is_virtual)
786 if (src2dst == -3)
787 continue; // Not a virtual base, so can't be here.
789 base = convert_to_base (base, is_virtual, offset);
791 __sub_kind base_kind = __base_info[i].__base->__do_find_public_src
792 (src2dst, base, src_type, src_ptr);
793 if (contained_p (base_kind))
795 if (is_virtual)
796 base_kind = __sub_kind (base_kind | __contained_virtual_mask);
797 return base_kind;
801 return __not_contained;
804 bool __class_type_info::
805 __do_dyncast (ptrdiff_t,
806 __sub_kind access_path,
807 const __class_type_info *dst_type,
808 const void *obj_ptr,
809 const __class_type_info *src_type,
810 const void *src_ptr,
811 __dyncast_result &__restrict result) const
813 if (obj_ptr == src_ptr && *this == *src_type)
815 // The src object we started from. Indicate how we are accessible from
816 // the most derived object.
817 result.whole2src = access_path;
818 return false;
820 if (*this == *dst_type)
822 result.dst_ptr = obj_ptr;
823 result.whole2dst = access_path;
824 result.dst2src = __not_contained;
825 return false;
827 return false;
830 bool __si_class_type_info::
831 __do_dyncast (ptrdiff_t src2dst,
832 __sub_kind access_path,
833 const __class_type_info *dst_type,
834 const void *obj_ptr,
835 const __class_type_info *src_type,
836 const void *src_ptr,
837 __dyncast_result &__restrict result) const
839 if (*this == *dst_type)
841 result.dst_ptr = obj_ptr;
842 result.whole2dst = access_path;
843 if (src2dst >= 0)
844 result.dst2src = adjust_pointer <void> (obj_ptr, src2dst) == src_ptr
845 ? __contained_public : __not_contained;
846 else if (src2dst == -2)
847 result.dst2src = __not_contained;
848 return false;
850 if (obj_ptr == src_ptr && *this == *src_type)
852 // The src object we started from. Indicate how we are accessible from
853 // the most derived object.
854 result.whole2src = access_path;
855 return false;
857 return __base_type->__do_dyncast (src2dst, access_path, dst_type, obj_ptr,
858 src_type, src_ptr, result);
861 // This is a big hairy function. Although the run-time behaviour of
862 // dynamic_cast is simple to describe, it gives rise to some non-obvious
863 // behaviour. We also desire to determine as early as possible any definite
864 // answer we can get. Because it is unknown what the run-time ratio of
865 // succeeding to failing dynamic casts is, we do not know in which direction
866 // to bias any optimizations. To that end we make no particular effort towards
867 // early fail answers or early success answers. Instead we try to minimize
868 // work by filling in things lazily (when we know we need the information),
869 // and opportunisticly take early success or failure results.
870 bool __vmi_class_type_info::
871 __do_dyncast (ptrdiff_t src2dst,
872 __sub_kind access_path,
873 const __class_type_info *dst_type,
874 const void *obj_ptr,
875 const __class_type_info *src_type,
876 const void *src_ptr,
877 __dyncast_result &__restrict result) const
879 if (result.whole_details & __flags_unknown_mask)
880 result.whole_details = __flags;
882 if (obj_ptr == src_ptr && *this == *src_type)
884 // The src object we started from. Indicate how we are accessible from
885 // the most derived object.
886 result.whole2src = access_path;
887 return false;
889 if (*this == *dst_type)
891 result.dst_ptr = obj_ptr;
892 result.whole2dst = access_path;
893 if (src2dst >= 0)
894 result.dst2src = adjust_pointer <void> (obj_ptr, src2dst) == src_ptr
895 ? __contained_public : __not_contained;
896 else if (src2dst == -2)
897 result.dst2src = __not_contained;
898 return false;
901 bool result_ambig = false;
902 for (std::size_t i = __base_count; i--;)
904 __dyncast_result result2 (result.whole_details);
905 void const *base = obj_ptr;
906 __sub_kind base_access = access_path;
907 ptrdiff_t offset = __base_info[i].__offset ();
908 bool is_virtual = __base_info[i].__is_virtual_p ();
910 if (is_virtual)
911 base_access = __sub_kind (base_access | __contained_virtual_mask);
912 base = convert_to_base (base, is_virtual, offset);
914 if (!__base_info[i].__is_public_p ())
916 if (src2dst == -2 &&
917 !(result.whole_details
918 & (__non_diamond_repeat_mask | __diamond_shaped_mask)))
919 // The hierarchy has no duplicate bases (which might ambiguate
920 // things) and where we started is not a public base of what we
921 // want (so it cannot be a downcast). There is nothing of interest
922 // hiding in a non-public base.
923 continue;
924 base_access = __sub_kind (base_access & ~__contained_public_mask);
927 bool result2_ambig
928 = __base_info[i].__base->__do_dyncast (src2dst, base_access,
929 dst_type, base,
930 src_type, src_ptr, result2);
931 result.whole2src = __sub_kind (result.whole2src | result2.whole2src);
932 if (result2.dst2src == __contained_public
933 || result2.dst2src == __contained_ambig)
935 result.dst_ptr = result2.dst_ptr;
936 result.whole2dst = result2.whole2dst;
937 result.dst2src = result2.dst2src;
938 // Found a downcast which can't be bettered or an ambiguous downcast
939 // which can't be disambiguated
940 return result2_ambig;
943 if (!result_ambig && !result.dst_ptr)
945 // Not found anything yet.
946 result.dst_ptr = result2.dst_ptr;
947 result.whole2dst = result2.whole2dst;
948 result_ambig = result2_ambig;
949 if (result.dst_ptr && result.whole2src != __unknown
950 && !(__flags & __non_diamond_repeat_mask))
951 // Found dst and src and we don't have repeated bases.
952 return result_ambig;
954 else if (result.dst_ptr && result.dst_ptr == result2.dst_ptr)
956 // Found at same address, must be via virtual. Pick the most
957 // accessible path.
958 result.whole2dst =
959 __sub_kind (result.whole2dst | result2.whole2dst);
961 else if ((result.dst_ptr != 0 | result_ambig)
962 && (result2.dst_ptr != 0 | result2_ambig))
964 // Found two different DST_TYPE bases, or a valid one and a set of
965 // ambiguous ones, must disambiguate. See whether SRC_PTR is
966 // contained publicly within one of the non-ambiguous choices. If it
967 // is in only one, then that's the choice. If it is in both, then
968 // we're ambiguous and fail. If it is in neither, we're ambiguous,
969 // but don't yet fail as we might later find a third base which does
970 // contain SRC_PTR.
972 __sub_kind new_sub_kind = result2.dst2src;
973 __sub_kind old_sub_kind = result.dst2src;
975 if (contained_p (result.whole2src)
976 && (!virtual_p (result.whole2src)
977 || !(result.whole_details & __diamond_shaped_mask)))
979 // We already found SRC_PTR as a base of most derived, and
980 // either it was non-virtual, or the whole heirarchy is
981 // not-diamond shaped. Therefore if it is in either choice, it
982 // can only be in one of them, and we will already know.
983 if (old_sub_kind == __unknown)
984 old_sub_kind = __not_contained;
985 if (new_sub_kind == __unknown)
986 new_sub_kind = __not_contained;
988 else
990 if (old_sub_kind >= __not_contained)
991 ;// already calculated
992 else if (contained_p (new_sub_kind)
993 && (!virtual_p (new_sub_kind)
994 || !(__flags & __diamond_shaped_mask)))
995 // Already found inside the other choice, and it was
996 // non-virtual or we are not diamond shaped.
997 old_sub_kind = __not_contained;
998 else
999 old_sub_kind = dst_type->__find_public_src
1000 (src2dst, result.dst_ptr, src_type, src_ptr);
1002 if (new_sub_kind >= __not_contained)
1003 ;// already calculated
1004 else if (contained_p (old_sub_kind)
1005 && (!virtual_p (old_sub_kind)
1006 || !(__flags & __diamond_shaped_mask)))
1007 // Already found inside the other choice, and it was
1008 // non-virtual or we are not diamond shaped.
1009 new_sub_kind = __not_contained;
1010 else
1011 new_sub_kind = dst_type->__find_public_src
1012 (src2dst, result2.dst_ptr, src_type, src_ptr);
1015 // Neither sub_kind can be contained_ambig -- we bail out early
1016 // when we find those.
1017 if (contained_p (__sub_kind (new_sub_kind ^ old_sub_kind)))
1019 // Only on one choice, not ambiguous.
1020 if (contained_p (new_sub_kind))
1022 // Only in new.
1023 result.dst_ptr = result2.dst_ptr;
1024 result.whole2dst = result2.whole2dst;
1025 result_ambig = false;
1026 old_sub_kind = new_sub_kind;
1028 result.dst2src = old_sub_kind;
1029 if (public_p (result.dst2src))
1030 return false; // Can't be an ambiguating downcast for later discovery.
1031 if (!virtual_p (result.dst2src))
1032 return false; // Found non-virtually can't be bettered
1034 else if (contained_p (__sub_kind (new_sub_kind & old_sub_kind)))
1036 // In both.
1037 result.dst_ptr = NULL;
1038 result.dst2src = __contained_ambig;
1039 return true; // Fail.
1041 else
1043 // In neither publicly, ambiguous for the moment, but keep
1044 // looking. It is possible that it was private in one or
1045 // both and therefore we should fail, but that's just tough.
1046 result.dst_ptr = NULL;
1047 result.dst2src = __not_contained;
1048 result_ambig = true;
1052 if (result.whole2src == __contained_private)
1053 // We found SRC_PTR as a private non-virtual base, therefore all
1054 // cross casts will fail. We have already found a down cast, if
1055 // there is one.
1056 return result_ambig;
1059 return result_ambig;
1062 bool __class_type_info::
1063 __do_upcast (const __class_type_info *dst, const void *obj,
1064 __upcast_result &__restrict result) const
1066 if (*this == *dst)
1068 result.dst_ptr = obj;
1069 result.base_type = nonvirtual_base_type;
1070 result.part2dst = __contained_public;
1071 return true;
1073 return false;
1076 bool __si_class_type_info::
1077 __do_upcast (const __class_type_info *dst, const void *obj_ptr,
1078 __upcast_result &__restrict result) const
1080 if (__class_type_info::__do_upcast (dst, obj_ptr, result))
1081 return true;
1083 return __base_type->__do_upcast (dst, obj_ptr, result);
1086 bool __vmi_class_type_info::
1087 __do_upcast (const __class_type_info *dst, const void *obj_ptr,
1088 __upcast_result &__restrict result) const
1090 if (__class_type_info::__do_upcast (dst, obj_ptr, result))
1091 return true;
1093 int src_details = result.src_details;
1094 if (src_details & __flags_unknown_mask)
1095 src_details = __flags;
1097 for (std::size_t i = __base_count; i--;)
1099 __upcast_result result2 (src_details);
1100 const void *base = obj_ptr;
1101 ptrdiff_t offset = __base_info[i].__offset ();
1102 bool is_virtual = __base_info[i].__is_virtual_p ();
1103 bool is_public = __base_info[i].__is_public_p ();
1105 if (!is_public && !(src_details & __non_diamond_repeat_mask))
1106 // original cannot have an ambiguous base, so skip private bases
1107 continue;
1109 if (base)
1110 base = convert_to_base (base, is_virtual, offset);
1112 if (__base_info[i].__base->__do_upcast (dst, base, result2))
1114 if (result2.base_type == nonvirtual_base_type && is_virtual)
1115 result2.base_type = __base_info[i].__base;
1116 if (contained_p (result2.part2dst) && !is_public)
1117 result2.part2dst = __sub_kind (result2.part2dst & ~__contained_public_mask);
1119 if (!result.base_type)
1121 result = result2;
1122 if (!contained_p (result.part2dst))
1123 return true; // found ambiguously
1125 if (result.part2dst & __contained_public_mask)
1127 if (!(__flags & __non_diamond_repeat_mask))
1128 return true; // cannot have an ambiguous other base
1130 else
1132 if (!virtual_p (result.part2dst))
1133 return true; // cannot have another path
1134 if (!(__flags & __diamond_shaped_mask))
1135 return true; // cannot have a more accessible path
1138 else if (result.dst_ptr != result2.dst_ptr)
1140 // Found an ambiguity.
1141 result.dst_ptr = NULL;
1142 result.part2dst = __contained_ambig;
1143 return true;
1145 else if (result.dst_ptr)
1147 // Ok, found real object via a virtual path.
1148 result.part2dst
1149 = __sub_kind (result.part2dst | result2.part2dst);
1151 else
1153 // Dealing with a null pointer, need to check vbase
1154 // containing each of the two choices.
1155 if (result2.base_type == nonvirtual_base_type
1156 || result.base_type == nonvirtual_base_type
1157 || !(*result2.base_type == *result.base_type))
1159 // Already ambiguous, not virtual or via different virtuals.
1160 // Cannot match.
1161 result.part2dst = __contained_ambig;
1162 return true;
1164 result.part2dst
1165 = __sub_kind (result.part2dst | result2.part2dst);
1169 return result.part2dst != __unknown;
1172 // this is the external interface to the dynamic cast machinery
1173 extern "C" void *
1174 __dynamic_cast (const void *src_ptr, // object started from
1175 const __class_type_info *src_type, // type of the starting object
1176 const __class_type_info *dst_type, // desired target type
1177 ptrdiff_t src2dst) // how src and dst are related
1179 const void *vtable = *static_cast <const void *const *> (src_ptr);
1180 const vtable_prefix *prefix =
1181 adjust_pointer <vtable_prefix> (vtable,
1182 -offsetof (vtable_prefix, origin));
1183 const void *whole_ptr =
1184 adjust_pointer <void> (src_ptr, prefix->whole_object);
1185 const __class_type_info *whole_type = prefix->whole_type;
1186 __class_type_info::__dyncast_result result;
1188 whole_type->__do_dyncast (src2dst, __class_type_info::__contained_public,
1189 dst_type, whole_ptr, src_type, src_ptr, result);
1190 if (!result.dst_ptr)
1191 return NULL;
1192 if (contained_public_p (result.dst2src))
1193 // Src is known to be a public base of dst.
1194 return const_cast <void *> (result.dst_ptr);
1195 if (contained_public_p (__class_type_info::__sub_kind (result.whole2src & result.whole2dst)))
1196 // Both src and dst are known to be public bases of whole. Found a valid
1197 // cross cast.
1198 return const_cast <void *> (result.dst_ptr);
1199 if (contained_nonvirtual_p (result.whole2src))
1200 // Src is known to be a non-public nonvirtual base of whole, and not a
1201 // base of dst. Found an invalid cross cast, which cannot also be a down
1202 // cast
1203 return NULL;
1204 if (result.dst2src == __class_type_info::__unknown)
1205 result.dst2src = dst_type->__find_public_src (src2dst, result.dst_ptr,
1206 src_type, src_ptr);
1207 if (contained_public_p (result.dst2src))
1208 // Found a valid down cast
1209 return const_cast <void *> (result.dst_ptr);
1210 // Must be an invalid down cast, or the cross cast wasn't bettered
1211 return NULL;
1214 }; // namespace __cxxabiv1
1215 #endif