]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/libsupc++/tinfo.cc
typeinfo (__GXX_MERGED_TYPEINFO_NAMES): New macro.
[thirdparty/gcc.git] / libstdc++-v3 / libsupc++ / tinfo.cc
1 // Methods for type_info for -*- C++ -*- Run Time Type Identification.
2 // Copyright (C) 1994, 1996, 1998, 1999, 2000 Free Software Foundation
3
4 // This file is part of GNU CC.
5
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)
9 // any later version.
10
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.
15
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.
20
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.
29
30 #pragma implementation "typeinfo"
31
32 #include <cstddef>
33 #include "tinfo.h"
34 #include "new" // for placement new
35
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
38 // functionality.
39
40 std::type_info::
41 ~type_info ()
42 { }
43
44 #if !__GXX_MERGED_TYPEINFO_NAMES
45
46 // We can't rely on common symbols being shared between shared objects.
47 bool std::type_info::
48 operator== (const std::type_info& arg) const
49 {
50 return (&arg == this) || (__builtin_strcmp (name (), arg.name ()) == 0);
51 }
52
53 #endif
54
55 #if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
56 // original (old) abi
57
58 namespace
59 {
60 // ADDR is a pointer to an object. Convert it to a pointer to a base,
61 // using OFFSET.
62 inline void*
63 convert_to_base (void *addr, bool is_virtual, myint32 offset)
64 {
65 if (!addr)
66 return NULL;
67
68 if (!is_virtual)
69 return (char *) addr + offset;
70
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));
74 }
75
76 }
77
78 extern "C" void
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); }
82
83 extern "C" void
84 __rtti_si (void *addr, const char *n, const std::type_info *ti)
85 {
86 new (addr) __si_type_info
87 (n, static_cast <const __user_type_info &> (*ti));
88 }
89
90 extern "C" void
91 __rtti_user (void *addr, const char *name)
92 { new (addr) __user_type_info (name); }
93
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
96 // object pointer.
97 int __user_type_info::
98 upcast (const type_info &target, void *objptr,
99 void **adjptr) const
100 {
101 upcast_result result;
102
103 if (do_upcast (contained_public, target, objptr, result))
104 return 0;
105 *adjptr = result.target_obj;
106 return contained_public_p (result.whole2target);
107 }
108
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
116 // public bases.
117 void *__user_type_info::
118 dyncast (int boff,
119 const type_info &target, void *objptr,
120 const type_info &subtype, void *subptr) const
121 {
122 dyncast_result result;
123
124 do_dyncast (boff, contained_public,
125 target, objptr, subtype, subptr, result);
126 if (!result.target_obj)
127 return NULL;
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
135 return NULL;
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
144 return NULL;
145 }
146
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
155 {
156 if (*this == target)
157 {
158 result.target_obj = objptr;
159 result.base_type = nonvirtual_base_type;
160 result.whole2target = access_path;
161 return contained_nonpublic_p (access_path);
162 }
163 return false;
164 }
165
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
171 // ambiguous match.
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
177 {
178 if (objptr == subptr && *this == subtype)
179 {
180 // The subobject we started from. Indicate how we are accessible from
181 // the most derived object.
182 result.whole2sub = access_path;
183 return false;
184 }
185 if (*this == target)
186 {
187 result.target_obj = objptr;
188 result.whole2target = access_path;
189 result.target2sub = not_contained;
190 return false;
191 }
192 return false;
193 }
194
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
197 // object.
198 __user_type_info::sub_kind __user_type_info::
199 do_find_public_subobj (int, const type_info &, void *objptr, void *subptr) const
200 {
201 if (subptr == objptr)
202 // Must be our type, as the pointers match.
203 return contained_public;
204 return not_contained;
205 }
206
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
213 {
214 if (*this == target)
215 {
216 result.target_obj = objptr;
217 result.base_type = nonvirtual_base_type;
218 result.whole2target = access_path;
219 return contained_nonpublic_p (access_path);
220 }
221 return base.do_upcast (access_path, target, objptr, result);
222 }
223
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
232 {
233 if (objptr == subptr && *this == subtype)
234 {
235 // The subobject we started from. Indicate how we are accessible from
236 // the most derived object.
237 result.whole2sub = access_path;
238 return false;
239 }
240 if (*this == target)
241 {
242 result.target_obj = objptr;
243 result.whole2target = access_path;
244 if (boff >= 0)
245 result.target2sub = ((char *)subptr - (char *)objptr) == boff
246 ? contained_public : not_contained;
247 else if (boff == -2)
248 result.target2sub = not_contained;
249 return false;
250 }
251 return base.do_dyncast (boff, access_path,
252 target, objptr, subtype, subptr, result);
253 }
254
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
257 // target object.
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
260 {
261 if (subptr == objptr && subtype == *this)
262 return contained_public;
263 return base.do_find_public_subobj (boff, subtype, objptr, subptr);
264 }
265
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
272 {
273 if (*this == target)
274 {
275 result.target_obj = objptr;
276 result.base_type = nonvirtual_base_type;
277 result.whole2target = access_path;
278 return contained_nonpublic_p (access_path);
279 }
280
281 for (std::size_t i = n_bases; i--;)
282 {
283 upcast_result result2;
284 void *p = objptr;
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)
297 {
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)
302 result = result2;
303 else if (result.target_obj != result2.target_obj)
304 {
305 // Found an ambiguity.
306 result.target_obj = NULL;
307 result.whole2target = contained_ambig;
308 return true;
309 }
310 else if (result.target_obj)
311 {
312 // Ok, found real object via a virtual path.
313 result.whole2target
314 = sub_kind (result.whole2target | result2.whole2target);
315 }
316 else
317 {
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))
323 {
324 // Already ambiguous, not virtual or via different virtuals.
325 // Cannot match.
326 result.whole2target = contained_ambig;
327 return true;
328 }
329 result.whole2target
330 = sub_kind (result.whole2target | result2.whole2target);
331 }
332 }
333 }
334 return false;
335 }
336
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
353 {
354 if (objptr == subptr && *this == subtype)
355 {
356 // The subobject we started from. Indicate how we are accessible from
357 // the most derived object.
358 result.whole2sub = access_path;
359 return false;
360 }
361 if (*this == target)
362 {
363 result.target_obj = objptr;
364 result.whole2target = access_path;
365 if (boff >= 0)
366 result.target2sub = ((char *)subptr - (char *)objptr) == boff
367 ? contained_public : not_contained;
368 else if (boff == -2)
369 result.target2sub = not_contained;
370 return false;
371 }
372 bool result_ambig = false;
373 for (std::size_t i = n_bases; i--;)
374 {
375 dyncast_result result2;
376 void *p;
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);
385
386 bool result2_ambig
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)
392 {
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;
399 }
400
401 if (!result_ambig && !result.target_obj)
402 {
403 // Not found anything yet.
404 result.target_obj = result2.target_obj;
405 result.whole2target = result2.whole2target;
406 result_ambig = result2_ambig;
407 }
408 else if (result.target_obj && result.target_obj == result2.target_obj)
409 {
410 // Found at same address, must be via virtual. Pick the most
411 // accessible path.
412 result.whole2target =
413 sub_kind (result.whole2target | result2.whole2target);
414 }
415 else if ((result.target_obj && result2.target_obj)
416 || (result_ambig && result2.target_obj)
417 || (result2_ambig && result.target_obj))
418 {
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.
426
427 sub_kind new_sub_kind = result2.target2sub;
428 sub_kind old_sub_kind = result.target2sub;
429
430 if (contained_nonvirtual_p (result.whole2sub))
431 {
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;
439 }
440 else
441 {
442 const __user_type_info &t =
443 static_cast <const __user_type_info &> (target);
444
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;
451 else
452 old_sub_kind = t.find_public_subobj (boff, subtype,
453 result.target_obj, subptr);
454
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;
461 else
462 new_sub_kind = t.find_public_subobj (boff, subtype,
463 result2.target_obj, subptr);
464 }
465
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)))
469 {
470 // Only on one choice, not ambiguous.
471 if (contained_p (new_sub_kind))
472 {
473 // Only in new.
474 result.target_obj = result2.target_obj;
475 result.whole2target = result2.whole2target;
476 result_ambig = false;
477 old_sub_kind = new_sub_kind;
478 }
479 result.target2sub = old_sub_kind;
480 if (result.target2sub == contained_public)
481 return false; // Can't be an ambiguating downcast for later discovery.
482 }
483 else if (contained_p (sub_kind (new_sub_kind & old_sub_kind)))
484 {
485 // In both.
486 result.target_obj = NULL;
487 result.target2sub = contained_ambig;
488 return true; // Fail.
489 }
490 else
491 {
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;
497 result_ambig = true;
498 }
499 }
500
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
504 // there is one.
505 return result_ambig;
506 }
507
508 return result_ambig;
509 }
510
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
516 {
517 if (objptr == subptr && subtype == *this)
518 return contained_public;
519
520 for (std::size_t i = n_bases; i--;)
521 {
522 if (base_list[i].access != PUBLIC)
523 continue; // Not public, can't be here.
524 void *p;
525
526 if (base_list[i].is_virtual && boff == -3)
527 // Not a virtual base, so can't be here.
528 continue;
529
530 p = convert_to_base (objptr,
531 base_list[i].is_virtual,
532 base_list[i].offset);
533
534 sub_kind base_kind = base_list[i].base->do_find_public_subobj
535 (boff, subtype, p, subptr);
536 if (contained_p (base_kind))
537 {
538 if (base_list[i].is_virtual)
539 base_kind = sub_kind (base_kind | contained_virtual_mask);
540 return base_kind;
541 }
542 }
543
544 return not_contained;
545 }
546 #else
547 // new abi
548
549 namespace std {
550
551 // return true if this is a type_info for a pointer type
552 bool type_info::
553 __is_pointer_p () const
554 {
555 return false;
556 }
557
558 // return true if this is a type_info for a function type
559 bool type_info::
560 __is_function_p () const
561 {
562 return false;
563 }
564
565 // try and catch a thrown object.
566 bool type_info::
567 __do_catch (const type_info *thr_type, void **, unsigned) const
568 {
569 return *this == *thr_type;
570 }
571
572 // upcast from this type to the target. __class_type_info will override
573 bool type_info::
574 __do_upcast (const abi::__class_type_info *, void **) const
575 {
576 return false;
577 }
578
579 };
580
581 namespace {
582
583 using namespace std;
584 using namespace abi;
585
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
592 };
593
594 template <typename T>
595 inline const T *
596 adjust_pointer (const void *base, ptrdiff_t offset)
597 {
598 return reinterpret_cast <const T *>
599 (reinterpret_cast <const char *> (base) + offset);
600 }
601
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.
604 inline void const *
605 convert_to_base (void const *addr, bool is_virtual, ptrdiff_t offset)
606 {
607 if (is_virtual)
608 {
609 const void *vtable = *static_cast <const void *const *> (addr);
610
611 offset = *adjust_pointer<ptrdiff_t> (vtable, offset);
612 }
613
614 return adjust_pointer<void> (addr, offset);
615 }
616
617 // some predicate functions for __class_type_info::__sub_kind
618 inline bool contained_p (__class_type_info::__sub_kind access_path)
619 {
620 return access_path >= __class_type_info::__contained_mask;
621 }
622 inline bool public_p (__class_type_info::__sub_kind access_path)
623 {
624 return access_path & __class_type_info::__contained_public_mask;
625 }
626 inline bool virtual_p (__class_type_info::__sub_kind access_path)
627 {
628 return (access_path & __class_type_info::__contained_virtual_mask);
629 }
630 inline bool contained_public_p (__class_type_info::__sub_kind access_path)
631 {
632 return ((access_path & __class_type_info::__contained_public)
633 == __class_type_info::__contained_public);
634 }
635 inline bool contained_nonpublic_p (__class_type_info::__sub_kind access_path)
636 {
637 return ((access_path & __class_type_info::__contained_public)
638 == __class_type_info::__contained_mask);
639 }
640 inline bool contained_nonvirtual_p (__class_type_info::__sub_kind access_path)
641 {
642 return ((access_path & (__class_type_info::__contained_mask
643 | __class_type_info::__contained_virtual_mask))
644 == __class_type_info::__contained_mask);
645 }
646
647 static const __class_type_info *const nonvirtual_base_type =
648 static_cast <const __class_type_info *> (0) + 1;
649
650 }; // namespace
651
652 namespace __cxxabiv1
653 {
654
655 __class_type_info::
656 ~__class_type_info ()
657 {}
658
659 __si_class_type_info::
660 ~__si_class_type_info ()
661 {}
662
663 __vmi_class_type_info::
664 ~__vmi_class_type_info ()
665 {}
666
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
670 {
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
677 // else NULL
678 public:
679 __upcast_result (int d)
680 :dst_ptr (NULL), part2dst (__unknown), src_details (d), base_type (NULL)
681 {}
682 };
683
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
687 {
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
693
694 public:
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_)
699 {}
700 };
701
702 bool __class_type_info::
703 __do_catch (const type_info *thr_type,
704 void **thr_obj,
705 unsigned outer) const
706 {
707 if (*this == *thr_type)
708 return true;
709 if (outer >= 4)
710 // Neither `A' nor `A *'.
711 return false;
712 return thr_type->__do_upcast (this, thr_obj);
713 }
714
715 bool __class_type_info::
716 __do_upcast (const __class_type_info *dst_type,
717 void **obj_ptr) const
718 {
719 __upcast_result result (__vmi_class_type_info::__flags_unknown_mask);
720
721 __do_upcast (dst_type, *obj_ptr, result);
722 if (!contained_public_p (result.part2dst))
723 return false;
724 *obj_ptr = const_cast <void *> (result.dst_ptr);
725 return true;
726 }
727
728 inline __class_type_info::__sub_kind __class_type_info::
729 __find_public_src (ptrdiff_t src2dst,
730 const void *obj_ptr,
731 const __class_type_info *src_type,
732 const void *src_ptr) const
733 {
734 if (src2dst >= 0)
735 return adjust_pointer <void> (obj_ptr, src2dst) == src_ptr
736 ? __contained_public : __not_contained;
737 if (src2dst == -2)
738 return __not_contained;
739 return __do_find_public_src (src2dst, obj_ptr, src_type, src_ptr);
740 }
741
742 __class_type_info::__sub_kind __class_type_info::
743 __do_find_public_src (ptrdiff_t,
744 const void *obj_ptr,
745 const __class_type_info *,
746 const void *src_ptr) const
747 {
748 if (src_ptr == obj_ptr)
749 // Must be our type, as the pointers match.
750 return __contained_public;
751 return __not_contained;
752 }
753
754 __class_type_info::__sub_kind __si_class_type_info::
755 __do_find_public_src (ptrdiff_t src2dst,
756 const void *obj_ptr,
757 const __class_type_info *src_type,
758 const void *src_ptr) const
759 {
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);
763 }
764
765 __class_type_info::__sub_kind __vmi_class_type_info::
766 __do_find_public_src (ptrdiff_t src2dst,
767 const void *obj_ptr,
768 const __class_type_info *src_type,
769 const void *src_ptr) const
770 {
771 if (obj_ptr == src_ptr && *this == *src_type)
772 return __contained_public;
773
774 for (std::size_t i = __base_count; i--;)
775 {
776 if (!__base_info[i].__is_public_p ())
777 continue; // Not public, can't be here.
778
779 const void *base = obj_ptr;
780 ptrdiff_t offset = __base_info[i].__offset ();
781 bool is_virtual = __base_info[i].__is_virtual_p ();
782
783 if (is_virtual)
784 {
785 if (src2dst == -3)
786 continue; // Not a virtual base, so can't be here.
787 }
788 base = convert_to_base (base, is_virtual, offset);
789
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))
793 {
794 if (is_virtual)
795 base_kind = __sub_kind (base_kind | __contained_virtual_mask);
796 return base_kind;
797 }
798 }
799
800 return __not_contained;
801 }
802
803 bool __class_type_info::
804 __do_dyncast (ptrdiff_t,
805 __sub_kind access_path,
806 const __class_type_info *dst_type,
807 const void *obj_ptr,
808 const __class_type_info *src_type,
809 const void *src_ptr,
810 __dyncast_result &__restrict result) const
811 {
812 if (obj_ptr == src_ptr && *this == *src_type)
813 {
814 // The src object we started from. Indicate how we are accessible from
815 // the most derived object.
816 result.whole2src = access_path;
817 return false;
818 }
819 if (*this == *dst_type)
820 {
821 result.dst_ptr = obj_ptr;
822 result.whole2dst = access_path;
823 result.dst2src = __not_contained;
824 return false;
825 }
826 return false;
827 }
828
829 bool __si_class_type_info::
830 __do_dyncast (ptrdiff_t src2dst,
831 __sub_kind access_path,
832 const __class_type_info *dst_type,
833 const void *obj_ptr,
834 const __class_type_info *src_type,
835 const void *src_ptr,
836 __dyncast_result &__restrict result) const
837 {
838 if (*this == *dst_type)
839 {
840 result.dst_ptr = obj_ptr;
841 result.whole2dst = access_path;
842 if (src2dst >= 0)
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;
847 return false;
848 }
849 if (obj_ptr == src_ptr && *this == *src_type)
850 {
851 // The src object we started from. Indicate how we are accessible from
852 // the most derived object.
853 result.whole2src = access_path;
854 return false;
855 }
856 return __base_type->__do_dyncast (src2dst, access_path, dst_type, obj_ptr,
857 src_type, src_ptr, result);
858 }
859
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,
873 const void *obj_ptr,
874 const __class_type_info *src_type,
875 const void *src_ptr,
876 __dyncast_result &__restrict result) const
877 {
878 if (result.whole_details & __flags_unknown_mask)
879 result.whole_details = __flags;
880
881 if (obj_ptr == src_ptr && *this == *src_type)
882 {
883 // The src object we started from. Indicate how we are accessible from
884 // the most derived object.
885 result.whole2src = access_path;
886 return false;
887 }
888 if (*this == *dst_type)
889 {
890 result.dst_ptr = obj_ptr;
891 result.whole2dst = access_path;
892 if (src2dst >= 0)
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;
897 return false;
898 }
899
900 bool result_ambig = false;
901 for (std::size_t i = __base_count; i--;)
902 {
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 ();
908
909 if (is_virtual)
910 base_access = __sub_kind (base_access | __contained_virtual_mask);
911 base = convert_to_base (base, is_virtual, offset);
912
913 if (!__base_info[i].__is_public_p ())
914 {
915 if (src2dst == -2 &&
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.
922 continue;
923 base_access = __sub_kind (base_access & ~__contained_public_mask);
924 }
925
926 bool result2_ambig
927 = __base_info[i].__base->__do_dyncast (src2dst, base_access,
928 dst_type, base,
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)
933 {
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;
940 }
941
942 if (!result_ambig && !result.dst_ptr)
943 {
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.
951 return result_ambig;
952 }
953 else if (result.dst_ptr && result.dst_ptr == result2.dst_ptr)
954 {
955 // Found at same address, must be via virtual. Pick the most
956 // accessible path.
957 result.whole2dst =
958 __sub_kind (result.whole2dst | result2.whole2dst);
959 }
960 else if ((result.dst_ptr != 0 | result_ambig)
961 && (result2.dst_ptr != 0 | result2_ambig))
962 {
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
969 // contain SRC_PTR.
970
971 __sub_kind new_sub_kind = result2.dst2src;
972 __sub_kind old_sub_kind = result.dst2src;
973
974 if (contained_p (result.whole2src)
975 && (!virtual_p (result.whole2src)
976 || !(result.whole_details & __diamond_shaped_mask)))
977 {
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;
986 }
987 else
988 {
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;
997 else
998 old_sub_kind = dst_type->__find_public_src
999 (src2dst, result.dst_ptr, src_type, src_ptr);
1000
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;
1009 else
1010 new_sub_kind = dst_type->__find_public_src
1011 (src2dst, result2.dst_ptr, src_type, src_ptr);
1012 }
1013
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)))
1017 {
1018 // Only on one choice, not ambiguous.
1019 if (contained_p (new_sub_kind))
1020 {
1021 // Only in new.
1022 result.dst_ptr = result2.dst_ptr;
1023 result.whole2dst = result2.whole2dst;
1024 result_ambig = false;
1025 old_sub_kind = new_sub_kind;
1026 }
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
1032 }
1033 else if (contained_p (__sub_kind (new_sub_kind & old_sub_kind)))
1034 {
1035 // In both.
1036 result.dst_ptr = NULL;
1037 result.dst2src = __contained_ambig;
1038 return true; // Fail.
1039 }
1040 else
1041 {
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;
1048 }
1049 }
1050
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
1054 // there is one.
1055 return result_ambig;
1056 }
1057
1058 return result_ambig;
1059 }
1060
1061 bool __class_type_info::
1062 __do_upcast (const __class_type_info *dst, const void *obj,
1063 __upcast_result &__restrict result) const
1064 {
1065 if (*this == *dst)
1066 {
1067 result.dst_ptr = obj;
1068 result.base_type = nonvirtual_base_type;
1069 result.part2dst = __contained_public;
1070 return true;
1071 }
1072 return false;
1073 }
1074
1075 bool __si_class_type_info::
1076 __do_upcast (const __class_type_info *dst, const void *obj_ptr,
1077 __upcast_result &__restrict result) const
1078 {
1079 if (__class_type_info::__do_upcast (dst, obj_ptr, result))
1080 return true;
1081
1082 return __base_type->__do_upcast (dst, obj_ptr, result);
1083 }
1084
1085 bool __vmi_class_type_info::
1086 __do_upcast (const __class_type_info *dst, const void *obj_ptr,
1087 __upcast_result &__restrict result) const
1088 {
1089 if (__class_type_info::__do_upcast (dst, obj_ptr, result))
1090 return true;
1091
1092 int src_details = result.src_details;
1093 if (src_details & __flags_unknown_mask)
1094 src_details = __flags;
1095
1096 for (std::size_t i = __base_count; i--;)
1097 {
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 ();
1103
1104 if (!is_public && !(src_details & __non_diamond_repeat_mask))
1105 // original cannot have an ambiguous base, so skip private bases
1106 continue;
1107
1108 if (base)
1109 base = convert_to_base (base, is_virtual, offset);
1110
1111 if (__base_info[i].__base->__do_upcast (dst, base, result2))
1112 {
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);
1117
1118 if (!result.base_type)
1119 {
1120 result = result2;
1121 if (!contained_p (result.part2dst))
1122 return true; // found ambiguously
1123
1124 if (result.part2dst & __contained_public_mask)
1125 {
1126 if (!(__flags & __non_diamond_repeat_mask))
1127 return true; // cannot have an ambiguous other base
1128 }
1129 else
1130 {
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
1135 }
1136 }
1137 else if (result.dst_ptr != result2.dst_ptr)
1138 {
1139 // Found an ambiguity.
1140 result.dst_ptr = NULL;
1141 result.part2dst = __contained_ambig;
1142 return true;
1143 }
1144 else if (result.dst_ptr)
1145 {
1146 // Ok, found real object via a virtual path.
1147 result.part2dst
1148 = __sub_kind (result.part2dst | result2.part2dst);
1149 }
1150 else
1151 {
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))
1157 {
1158 // Already ambiguous, not virtual or via different virtuals.
1159 // Cannot match.
1160 result.part2dst = __contained_ambig;
1161 return true;
1162 }
1163 result.part2dst
1164 = __sub_kind (result.part2dst | result2.part2dst);
1165 }
1166 }
1167 }
1168 return result.part2dst != __unknown;
1169 }
1170
1171 // this is the external interface to the dynamic cast machinery
1172 extern "C" void *
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
1177 {
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;
1186
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)
1190 return NULL;
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
1196 // cross cast.
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
1201 // cast
1202 return NULL;
1203 if (result.dst2src == __class_type_info::__unknown)
1204 result.dst2src = dst_type->__find_public_src (src2dst, result.dst_ptr,
1205 src_type, src_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
1210 return NULL;
1211 }
1212
1213 }; // namespace __cxxabiv1
1214 #endif