1 //===----------------------- private_typeinfo.cpp -------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "private_typeinfo.h"
11 
12 #ifdef DEBUG
13 #include <iostream>
14 #endif
15 
16 namespace __cxxabiv1
17 {
18 
19 //#pragma GCC visibility push(hidden)
20 
21 // __shim_type_info
22 
23 __shim_type_info::~__shim_type_info()
24 {
25 }
26 
27 // __fundamental_type_info
28 
29 // This miraculously (compiler magic) emits the type_info's for:
30 //   1. all of the fundamental types
31 //   2. pointers to all of the fundamental types
32 //   3. pointers to all of the const fundamental types
33 __fundamental_type_info::~__fundamental_type_info()
34 {
35 }
36 
37 // __array_type_info
38 
39 __array_type_info::~__array_type_info()
40 {
41 }
42 
43 // __function_type_info
44 
45 __function_type_info::~__function_type_info()
46 {
47 }
48 
49 // __enum_type_info
50 
51 __enum_type_info::~__enum_type_info()
52 {
53 }
54 
55 // __class_type_info
56 
57 __class_type_info::~__class_type_info()
58 {
59 }
60 
61 // __si_class_type_info
62 
63 __si_class_type_info::~__si_class_type_info()
64 {
65 }
66 
67 // __vmi_class_type_info
68 
69 __vmi_class_type_info::~__vmi_class_type_info()
70 {
71 }
72 
73 // __pbase_type_info
74 
75 __pbase_type_info::~__pbase_type_info()
76 {
77 }
78 
79 // __pointer_type_info
80 
81 __pointer_type_info::~__pointer_type_info()
82 {
83 }
84 
85 // __pointer_to_member_type_info
86 
87 __pointer_to_member_type_info::~__pointer_to_member_type_info()
88 {
89 }
90 
91 #pragma GCC visibility push(hidden)
92 
93 #ifdef DEBUG
94 
95 void
96 __fundamental_type_info::display() const
97 {
98     std::cout << "__fundamental_type_info " << __type_name << '\n';
99 }
100 
101 void
102 __array_type_info::display() const
103 {
104     std::cout << "__array_type_info " << __type_name << '\n';
105 }
106 
107 void
108 __function_type_info::display() const
109 {
110     std::cout << "__function_type_info " << __type_name << '\n';
111 }
112 
113 void
114 __enum_type_info::display() const
115 {
116     std::cout << "__enum_type_info " << __type_name << '\n';
117 }
118 
119 void
120 __class_type_info::display() const
121 {
122     std::cout << "__class_type_info " << __type_name << '\n';
123 }
124 
125 void
126 __si_class_type_info::display() const
127 {
128     std::cout << "__si_class_type_info " << __type_name << '\n';
129     std::cout << "derived from ";
130     __base_type->display();
131 }
132 
133 void
134 __vmi_class_type_info::display() const
135 {
136     std::cout << "__vmi_class_type_info " << __type_name << '\n';
137     if (__flags & __non_diamond_repeat_mask)
138         std::cout << "__non_diamond_repeat_mask\n";
139     if (__flags & __diamond_shaped_mask)
140         std::cout << "__diamond_shaped_mask\n";
141     std::cout << "derived from\n";
142     for (const __base_class_type_info* p = __base_info; p < __base_info + __base_count; ++p)
143         p->display();
144 }
145 
146 void
147 __base_class_type_info::display() const
148 {
149     if (__offset_flags & __public_mask)
150         std::cout << "public ";
151     __base_type->display();
152 }
153 
154 void
155 __pointer_type_info::display() const
156 {
157     std::cout << "__pointer_type_info " << __type_name << '\n';
158     if (__flags & __const_mask)
159         std::cout << "const ";
160     if (__flags & __volatile_mask)
161         std::cout << "volatile ";
162     if (__flags & __restrict_mask)
163         std::cout << "restrict ";
164     if (__flags & __incomplete_mask)
165         std::cout << "__incomplete_mask ";
166     if (__flags & __incomplete_class_mask)
167         std::cout << "__incomplete_class_mask ";
168     std::cout << "pointer to ";
169     __pointee->display();
170 }
171 
172 void
173 __pointer_to_member_type_info::display() const
174 {
175     std::cout << "__pointer_to_member_type_info " << __type_name << '\n';
176     if (__flags & __const_mask)
177         std::cout << "const ";
178     if (__flags & __volatile_mask)
179         std::cout << "volatile ";
180     if (__flags & __restrict_mask)
181         std::cout << "restrict ";
182     if (__flags & __incomplete_mask)
183         std::cout << "__incomplete_mask ";
184     if (__flags & __incomplete_class_mask)
185         std::cout << "__incomplete_class_mask ";
186     std::cout << "member pointer to class ";
187     __context->display();
188     std::cout << "and type ";
189     __pointee->display();
190 }
191 
192 #endif
193 
194 // can_catch
195 
196 // A handler is a match for an exception object of type E if
197 //   1. The handler is of type cv T or cv T& and E and T are the same type
198 //      (ignoring the top-level cv-qualifiers), or
199 //   2. the handler is of type cv T or cv T& and T is an unambiguous public
200 //       base class of E, or
201 //   3. the handler is of type cv1 T* cv2 and E is a pointer type that can be
202 //      converted to the type of the handler by either or both of
203 //      A. a standard pointer conversion (4.10) not involving conversions to
204 //         pointers to private or protected or ambiguous classes
205 //      B. a qualification conversion
206 //   4. the handler is a pointer or pointer to member type and E is
207 //      std::nullptr_t.
208 
209 // adjustedPtr:
210 //
211 // catch (A& a) : adjustedPtr == &a
212 // catch (A* a) : adjustedPtr == a
213 // catch (A** a) : adjustedPtr == a
214 //
215 // catch (D2& d2) : adjustedPtr == &d2  (d2 is base class of thrown object)
216 // catch (D2* d2) : adjustedPtr == d2
217 // catch (D2*& d2) : adjustedPtr == d2
218 //
219 // catch (...) : adjustedPtr == & of the exception
220 
221 // TODO:  can_catch looks similar to search_above_dst.  Reuse?
222 
223 bool
224 __shim_type_info::can_catch(const __shim_type_info* thrown_type,
225                             void*&) const
226 {
227     return this == thrown_type;
228 }
229 
230 // Handles bullet 1
231 // TODO:  Let __shim_type_info handle it?
232 bool
233 __fundamental_type_info::can_catch(const __shim_type_info* thrown_type,
234                                    void*&) const
235 {
236     return this == thrown_type;
237 }
238 
239 bool
240 __array_type_info::can_catch(const __shim_type_info* thrown_type,
241                              void*&) const
242 {
243     // TODO:  Can this be called?
244     return false;
245 }
246 
247 bool
248 __function_type_info::can_catch(const __shim_type_info* thrown_type,
249                                 void*&) const
250 {
251     // TODO:  Can this be called?
252     return false;
253 }
254 
255 // Handles bullet 1
256 // TODO:  Let __shim_type_info handle it?
257 bool
258 __enum_type_info::can_catch(const __shim_type_info* thrown_type,
259                             void*&) const
260 {
261     return this == thrown_type;
262 }
263 
264 // Handles bullets 1 and 2
265 bool
266 __class_type_info::can_catch(const __shim_type_info* thrown_type,
267                              void*& adjustedPtr) const
268 {
269     // bullet 1
270     if (this == thrown_type)
271         return true;
272     const __class_type_info* thrown_class_type =
273         dynamic_cast<const __class_type_info*>(thrown_type);
274     if (thrown_class_type == 0)
275         return false;
276     // bullet 2
277     __dynamic_cast_info info = {thrown_class_type, 0, this, -1, 0};
278     info.number_of_dst_type = 1;
279     thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, public_path);
280     if (info.path_dst_ptr_to_static_ptr == public_path)
281     {
282         adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr);
283         return true;
284     }
285     return false;
286 }
287 
288 void
289 __class_type_info::process_found_base_class(__dynamic_cast_info* info,
290                                                void* adjustedPtr,
291                                                int path_below) const
292 {
293     if (info->dst_ptr_leading_to_static_ptr == 0)
294     {
295         // First time here
296         info->dst_ptr_leading_to_static_ptr = adjustedPtr;
297         info->path_dst_ptr_to_static_ptr = path_below;
298         info->number_to_static_ptr = 1;
299     }
300     else if (info->dst_ptr_leading_to_static_ptr == adjustedPtr)
301     {
302         // We've been here before.  Update path to "most public"
303         if (info->path_dst_ptr_to_static_ptr == not_public_path)
304             info->path_dst_ptr_to_static_ptr = path_below;
305     }
306     else
307     {
308         // We've detected an ambiguous cast from (thrown_class_type, adjustedPtr)
309         //   to a static_type
310         info->number_to_static_ptr += 1;
311         info->path_dst_ptr_to_static_ptr = not_public_path;
312         info->search_done = true;
313     }
314 }
315 
316 void
317 __class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
318                                                void* adjustedPtr,
319                                                int path_below) const
320 {
321     if (this == info->static_type)
322         process_found_base_class(info, adjustedPtr, path_below);
323 }
324 
325 void
326 __si_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
327                                                   void* adjustedPtr,
328                                                   int path_below) const
329 {
330     if (this == info->static_type)
331         process_found_base_class(info, adjustedPtr, path_below);
332     else
333         __base_type->has_unambiguous_public_base(info, adjustedPtr, path_below);
334 }
335 
336 void
337 __base_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
338                                                     void* adjustedPtr,
339                                                     int path_below) const
340 {
341     ptrdiff_t offset_to_base = __offset_flags >> __offset_shift;
342     if (__offset_flags & __virtual_mask)
343     {
344         const char* vtable = *static_cast<const char*const*>(adjustedPtr);
345         offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
346     }
347     __base_type->has_unambiguous_public_base(info,
348                                              static_cast<char*>(adjustedPtr) + offset_to_base,
349                                              (__offset_flags & __public_mask) ?
350                                                  path_below :
351                                                  not_public_path);
352 }
353 
354 void
355 __vmi_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
356                                                    void* adjustedPtr,
357                                                    int path_below) const
358 {
359     if (this == info->static_type)
360         process_found_base_class(info, adjustedPtr, path_below);
361     else
362     {
363         typedef const __base_class_type_info* Iter;
364         const Iter e = __base_info + __base_count;
365         Iter p = __base_info;
366         p->has_unambiguous_public_base(info, adjustedPtr, path_below);
367         if (++p < e)
368         {
369             do
370             {
371                 p->has_unambiguous_public_base(info, adjustedPtr, path_below);
372                 if (info->search_done)
373                     break;
374             } while (++p < e);
375         }
376     }
377 }
378 
379 // Handles bullets 1 and 4
380 // TODO:  Are we good to go here for __pointer_to_member_type_info?
381 bool
382 __pbase_type_info::can_catch(const __shim_type_info* thrown_type,
383                              void*&) const
384 {
385     if (this == thrown_type)
386         return true;
387     return thrown_type == &typeid(std::nullptr_t);
388 }
389 
390 // Handles bullets 1, 3 and 4
391 bool
392 __pointer_type_info::can_catch(const __shim_type_info* thrown_type,
393                                void*& adjustedPtr) const
394 {
395     // Do the dereference adjustment
396     adjustedPtr = *static_cast<void**>(adjustedPtr);
397     // bullets 1 and 4
398     if (__pbase_type_info::can_catch(thrown_type, adjustedPtr))
399         return true;
400     // bullet 3
401     const __pointer_type_info* thrown_pointer_type =
402         dynamic_cast<const __pointer_type_info*>(thrown_type);
403     if (thrown_pointer_type == 0)
404         return false;
405     // bullet 3B
406     if (thrown_pointer_type->__flags & ~__flags)
407         return false;
408     if (__pointee == thrown_pointer_type->__pointee)
409         return true;
410     // bullet 3A
411     if (__pointee == &typeid(void))
412         return true;
413     const __class_type_info* catch_class_type =
414         dynamic_cast<const __class_type_info*>(__pointee);
415     if (catch_class_type == 0)
416         return false;
417     const __class_type_info* thrown_class_type =
418         dynamic_cast<const __class_type_info*>(thrown_pointer_type->__pointee);
419     if (thrown_class_type == 0)
420         return false;
421     __dynamic_cast_info info = {thrown_class_type, 0, catch_class_type, -1, 0};
422     info.number_of_dst_type = 1;
423     thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, public_path);
424     if (info.path_dst_ptr_to_static_ptr == public_path)
425     {
426         adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr);
427         return true;
428     }
429     return false;
430 }
431 
432 //#pragma GCC visibility pop
433 #pragma GCC visibility push(default)
434 
435 // __dynamic_cast
436 
437 // static_ptr: pointer to an object of type static_type; nonnull, and since the
438 //   object is polymorphic, *(void**)static_ptr is a virtual table pointer.
439 //   static_ptr is &v in the expression dynamic_cast<T>(v).
440 // static_type: static type of the object pointed to by static_ptr.
441 // dst_type: destination type of the cast (the "T" in "dynamic_cast<T>(v)").
442 // src2dst_offset: a static hint about the location of the
443 //                 source subobject with respect to the complete object;
444 //                 special negative values are:
445 //                     -1: no hint
446 //                     -2: static_type is not a public base of dst_type
447 //                     -3: static_type is a multiple public base type but never a
448 //                         virtual base type
449 //                 otherwise, the static_type type is a unique public nonvirtual
450 //                 base type of dst_type at offset src2dst_offset from the
451 //                 origin of dst_type.
452 //
453 // (dynamic_ptr, dynamic_type) are the run time type of the complete object
454 // referred to by static_ptr and a pointer to it.  These can be found from
455 // static_ptr for polymorphic types.
456 // static_type is guaranteed to be a polymorphic type.
457 //
458 // (dynamic_ptr, dynamic_type) is the root of a DAG that grows upward.  Each
459 // node of the tree represents a base class/object of its parent (or parents) below.
460 // Each node is uniquely represented by a pointer to the object, and a pointer
461 // to a type_info - its type.  Different nodes may have the same pointer and
462 // different nodes may have the same type.  But only one node has a specific
463 // (pointer-value, type) pair.  In C++ two objects of the same type can not
464 // share the same address.
465 //
466 // There are two flavors of nodes which have the type dst_type:
467 //    1.  Those that are derived from (below) (static_ptr, static_type).
468 //    2.  Those that are not derived from (below) (static_ptr, static_type).
469 //
470 // Invariants of the DAG:
471 //
472 // There is at least one path from the root (dynamic_ptr, dynamic_type) to
473 // the node (static_ptr, static_type).  This path may or may not be public.
474 // There may be more than one such path (some public some not).  Such a path may
475 // or may not go through a node having type dst_type.
476 //
477 // No node of type T appears above a node of the same type.  That means that
478 // there is only one node with dynamic_type.  And if dynamic_type == dst_type,
479 // then there is only one dst_type in the DAG.
480 //
481 // No node of type dst_type appears above a node of type static_type.  Such
482 // DAG's are possible in C++, but the compiler computes those dynamic_casts at
483 // compile time, and only calls __dynamic_cast when dst_type lies below
484 // static_type in the DAG.
485 //
486 // dst_type != static_type:  The compiler computes the dynamic_cast in this case too.
487 // dynamic_type != static_type:  The compiler computes the dynamic_cast in this case too.
488 //
489 // Returns:
490 //
491 // If there is exactly one dst_type of flavor 1, and
492 //    If there is a public path from that dst_type to (static_ptr, static_type), or
493 //    If there are 0 dst_types of flavor 2, and there is a public path from
494 //        (dynamic_ptr, dynamic_type) to (static_ptr, static_type) and a public
495 //        path from (dynamic_ptr, dynamic_type) to the one dst_type, then return
496 //        a pointer to that dst_type.
497 // Else if there are 0 dst_types of flavor 1 and exactly 1 dst_type of flavor 2, and
498 //    if there is a public path from (dynamic_ptr, dynamic_type) to
499 //    (static_ptr, static_type) and a public path from (dynamic_ptr, dynamic_type)
500 //    to the one dst_type, then return a pointer to that one dst_type.
501 // Else return nullptr.
502 //
503 // If dynamic_type == dst_type, then the above algorithm collapses to the
504 // following cheaper algorithm:
505 //
506 // If there is a public path from (dynamic_ptr, dynamic_type) to
507 //    (static_ptr, static_type), then return dynamic_ptr.
508 // Else return nullptr.
509 extern "C"
510 void*
511 __dynamic_cast(const void* static_ptr,
512 			   const __class_type_info* static_type,
513 			   const __class_type_info* dst_type,
514 			   std::ptrdiff_t src2dst_offset)
515 {
516     // TODO:  Take advantage of src2dst_offset
517 
518     // Get (dynamic_ptr, dynamic_type) from static_ptr
519     void** vtable = *(void***)static_ptr;
520     ptrdiff_t offset_to_derived = reinterpret_cast<ptrdiff_t>(vtable[-2]);
521     const void* dynamic_ptr = static_cast<const char*>(static_ptr) + offset_to_derived;
522     const __class_type_info* dynamic_type = static_cast<const __class_type_info*>(vtable[-1]);
523 
524     // Initialize answer to nullptr.  This will be changed from the search
525     //    results if a non-null answer is found.  Regardless, this is what will
526     //    be returned.
527     const void* dst_ptr = 0;
528     // Initialize info struct for this search.
529     __dynamic_cast_info info = {dst_type, static_ptr, static_type, src2dst_offset, 0};
530 
531     // Find out if we can use a giant short cut in the search
532     if (dynamic_type == dst_type)
533     {
534         // Using giant short cut.  Add that information to info.
535         info.number_of_dst_type = 1;
536         // Do the  search
537         dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path);
538         // Query the search.
539         if (info.path_dst_ptr_to_static_ptr == public_path)
540             dst_ptr = dynamic_ptr;
541     }
542     else
543     {
544         // Not using giant short cut.  Do the search
545         dynamic_type->search_below_dst(&info, dynamic_ptr, public_path);
546         // Query the search.
547         switch (info.number_to_static_ptr)
548         {
549         case 0:
550             if (info.number_to_dst_ptr == 1 &&
551                     info.path_dynamic_ptr_to_static_ptr == public_path &&
552                     info.path_dynamic_ptr_to_dst_ptr == public_path)
553                 dst_ptr = info.dst_ptr_not_leading_to_static_ptr;
554             break;
555         case 1:
556             if (info.path_dst_ptr_to_static_ptr == public_path ||
557                    (
558                        info.number_to_dst_ptr == 0 &&
559                        info.path_dynamic_ptr_to_static_ptr == public_path &&
560                        info.path_dynamic_ptr_to_dst_ptr == public_path
561                    )
562                )
563                 dst_ptr = info.dst_ptr_leading_to_static_ptr;
564             break;
565         }
566     }
567     return const_cast<void*>(dst_ptr);
568 }
569 
570 #pragma GCC visibility pop
571 #pragma GCC visibility push(hidden)
572 
573 // Call this function when you hit a static_type which is a base (above) a dst_type.
574 // Let caller know you hit a static_type.  But only start recording details if
575 // this is (static_ptr, static_type) -- the node we are casting from.
576 // If this is (static_ptr, static_type)
577 //   Record the path (public or not) from the dst_type to here.  There may be
578 //   multiple paths from the same dst_type to here, record the "most public" one.
579 //   Record the dst_ptr as pointing to (static_ptr, static_type).
580 //   If more than one (dst_ptr, dst_type) points to (static_ptr, static_type),
581 //   then mark this dyanmic_cast as ambiguous and stop the search.
582 void
583 __class_type_info::process_static_type_above_dst(__dynamic_cast_info* info,
584                                                  const void* dst_ptr,
585                                                  const void* current_ptr,
586                                                  int path_below) const
587 {
588     // Record that we found a static_type
589     info->found_any_static_type = true;
590     if (current_ptr == info->static_ptr)
591     {
592         // Record that we found (static_ptr, static_type)
593         info->found_our_static_ptr = true;
594         if (info->dst_ptr_leading_to_static_ptr == 0)
595         {
596             // First time here
597             info->dst_ptr_leading_to_static_ptr = dst_ptr;
598             info->path_dst_ptr_to_static_ptr = path_below;
599             info->number_to_static_ptr = 1;
600             // If there is only one dst_type in the entire tree and the path from
601             //    there to here is public then we are done!
602             if (info->number_of_dst_type == 1 && info->path_dst_ptr_to_static_ptr == public_path)
603                 info->search_done = true;
604         }
605         else if (info->dst_ptr_leading_to_static_ptr == dst_ptr)
606         {
607             // We've been here before.  Update path to "most public"
608             if (info->path_dst_ptr_to_static_ptr == not_public_path)
609                 info->path_dst_ptr_to_static_ptr = path_below;
610             // If there is only one dst_type in the entire tree and the path from
611             //    there to here is public then we are done!
612             if (info->number_of_dst_type == 1 && info->path_dst_ptr_to_static_ptr == public_path)
613                 info->search_done = true;
614         }
615         else
616         {
617             // We've detected an ambiguous cast from (static_ptr, static_type)
618             //   to a dst_type
619             info->number_to_static_ptr += 1;
620             info->search_done = true;
621         }
622     }
623 }
624 
625 // Call this function when you hit a static_type which is not a base (above) a dst_type.
626 // If this is (static_ptr, static_type)
627 //   Record the path (public or not) from (dynamic_ptr, dynamic_type) to here.  There may be
628 //   multiple paths from (dynamic_ptr, dynamic_type) to here, record the "most public" one.
629 void
630 __class_type_info::process_static_type_below_dst(__dynamic_cast_info* info,
631                                                  const void* current_ptr,
632                                                  int path_below) const
633 {
634     if (current_ptr == info->static_ptr)
635     {
636         // Record the most public path from (dynamic_ptr, dynamic_type) to
637         //                                  (static_ptr, static_type)
638         if (info->path_dynamic_ptr_to_static_ptr != public_path)
639             info->path_dynamic_ptr_to_static_ptr = path_below;
640     }
641 }
642 
643 // Call this function when searching below a dst_type node.  This function searches
644 // for a path to (static_ptr, static_type) and for paths to one or more dst_type nodes.
645 // If it finds a static_type node, there is no need to further search base classes
646 // above.
647 // If it finds a dst_type node it should search base classes using search_above_dst
648 // to find out if this dst_type points to (static_ptr, static_type) or not.
649 // Either way, the dst_type is recorded as one of two "flavors":  one that does
650 // or does not point to (static_ptr, static_type).
651 // If this is neither a static_type nor a dst_type node, continue searching
652 // base classes above.
653 // All the hoopla surrounding the search code is doing nothing but looking for
654 // excuses to stop the search prematurely (break out of the for-loop).  That is,
655 // the algorithm below is simply an optimization of this:
656 // void
657 // __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info,
658 //                                         const void* current_ptr,
659 //                                         int path_below) const
660 // {
661 //     typedef const __base_class_type_info* Iter;
662 //     if (this == info->static_type)
663 //         process_static_type_below_dst(info, current_ptr, path_below);
664 //     else if (this == info->dst_type)
665 //     {
666 //         // Record the most public access path that got us here
667 //         if (info->path_dynamic_ptr_to_dst_ptr != public_path)
668 //             info->path_dynamic_ptr_to_dst_ptr = path_below;
669 //         bool does_dst_type_point_to_our_static_type = false;
670 //         for (Iter p = __base_info, e= __base_info + __base_count; p < e; ++p)
671 //         {
672 //             p->search_above_dst(info, current_ptr, current_ptr, public_path);
673 //             if (info->found_our_static_ptr)
674 //                 does_dst_type_point_to_our_static_type = true;
675 //             // break out early here if you can detect it doesn't matter if you do
676 //         }
677 //         if (!does_dst_type_point_to_our_static_type)
678 //         {
679 //             // We found a dst_type that doesn't point to (static_ptr, static_type)
680 //             // So record the address of this dst_ptr and increment the
681 //             // count of the number of such dst_types found in the tree.
682 //             info->dst_ptr_not_leading_to_static_ptr = current_ptr;
683 //             info->number_to_dst_ptr += 1;
684 //         }
685 //     }
686 //     else
687 //     {
688 //         // This is not a static_type and not a dst_type.
689 //         for (Iter p = __base_info, e = __base_info + __base_count; p < e; ++p)
690 //         {
691 //             p->search_below_dst(info, current_ptr, public_path);
692 //             // break out early here if you can detect it doesn't matter if you do
693 //         }
694 //     }
695 // }
696 void
697 __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info,
698                                         const void* current_ptr,
699                                         int path_below) const
700 {
701     typedef const __base_class_type_info* Iter;
702     if (this == info->static_type)
703         process_static_type_below_dst(info, current_ptr, path_below);
704     else if (this == info->dst_type)
705     {
706         // We've been here before if we've recorded current_ptr in one of these
707         //   two places:
708         if (current_ptr == info->dst_ptr_leading_to_static_ptr ||
709             current_ptr == info->dst_ptr_not_leading_to_static_ptr)
710         {
711             // We've seen this node before, and therefore have already searched
712             // its base classes above.
713             //  Update path to here that is "most public".
714             if (path_below == public_path)
715                 info->path_dynamic_ptr_to_dst_ptr = public_path;
716         }
717         else  // We have haven't been here before
718         {
719             // Record the access path that got us here
720             //   If there is more than one dst_type this path doesn't matter.
721             info->path_dynamic_ptr_to_dst_ptr = path_below;
722             // Only search above here if dst_type derives from static_type, or
723             //    if it is unknown if dst_type derives from static_type.
724             if (info->is_dst_type_derived_from_static_type != no)
725             {
726                 // Set up flags to record results from all base classes
727                 bool is_dst_type_derived_from_static_type = false;
728                 bool does_dst_type_point_to_our_static_type = false;
729                 // We've found a dst_type with a potentially public path to here.
730                 // We have to assume the path is public because it may become
731                 //   public later (if we get back to here with a public path).
732                 // We can stop looking above if:
733                 //    1.  We've found a public path to (static_ptr, static_type).
734                 //    2.  We've found an ambiguous cast from (static_ptr, static_type) to a dst_type.
735                 //        This is detected at the (static_ptr, static_type).
736                 //    3.  We can prove that there is no public path to (static_ptr, static_type)
737                 //        above here.
738                 const Iter e = __base_info + __base_count;
739                 for (Iter p = __base_info; p < e; ++p)
740                 {
741                     // Zero out found flags
742                     info->found_our_static_ptr = false;
743                     info->found_any_static_type = false;
744                     p->search_above_dst(info, current_ptr, current_ptr, public_path);
745                     if (info->search_done)
746                         break;
747                     if (info->found_any_static_type)
748                     {
749                         is_dst_type_derived_from_static_type = true;
750                         if (info->found_our_static_ptr)
751                         {
752                             does_dst_type_point_to_our_static_type = true;
753                             // If we found what we're looking for, stop looking above.
754                             if (info->path_dst_ptr_to_static_ptr == public_path)
755                                 break;
756                             // We found a private path to (static_ptr, static_type)
757                             //   If there is no diamond then there is only one path
758                             //   to (static_ptr, static_type) and we just found it.
759                             if (!(__flags & __diamond_shaped_mask))
760                                 break;
761                         }
762                         else
763                         {
764                             // If we found a static_type that isn't the one we're looking
765                             //    for, and if there are no repeated types above here,
766                             //    then stop looking.
767                             if (!(__flags & __non_diamond_repeat_mask))
768                                 break;
769                         }
770                     }
771                 }
772                 if (!does_dst_type_point_to_our_static_type)
773                 {
774                     // We found a dst_type that doesn't point to (static_ptr, static_type)
775                     // So record the address of this dst_ptr and increment the
776                     // count of the number of such dst_types found in the tree.
777                     info->dst_ptr_not_leading_to_static_ptr = current_ptr;
778                     info->number_to_dst_ptr += 1;
779                     // If there exists another dst with a private path to
780                     //    (static_ptr, static_type), then the cast from
781                     //     (dynamic_ptr, dynamic_type) to dst_type is now ambiguous,
782                     //      so stop search.
783                     if (info->number_to_static_ptr == 1 &&
784                             info->path_dst_ptr_to_static_ptr == not_public_path)
785                         info->search_done = true;
786                 }
787                 // If we found no static_type,s then dst_type doesn't derive
788                 //   from static_type, else it does.  Record this result so that
789                 //   next time we hit a dst_type we will know not to search above
790                 //   it if it doesn't derive from static_type.
791                 if (is_dst_type_derived_from_static_type)
792                     info->is_dst_type_derived_from_static_type = yes;
793                 else
794                     info->is_dst_type_derived_from_static_type = no;
795             }
796         }
797     }
798     else
799     {
800         // This is not a static_type and not a dst_type.
801         const Iter e = __base_info + __base_count;
802         Iter p = __base_info;
803         p->search_below_dst(info, current_ptr, path_below);
804         if (++p < e)
805         {
806             if ((__flags & __diamond_shaped_mask) || info->number_to_static_ptr == 1)
807             {
808                 // If there are multiple paths to a base above from here, or if
809                 //    a dst_type pointing to (static_ptr, static_type) has been found,
810                 //    then there is no way to break out of this loop early unless
811                 //    something below detects the search is done.
812                 do
813                 {
814                     if (info->search_done)
815                         break;
816                     p->search_below_dst(info, current_ptr, path_below);
817                 } while (++p < e);
818             }
819             else if (__flags & __non_diamond_repeat_mask)
820             {
821                 // There are not multiple paths to any base class from here and a
822                 //   dst_type pointing to (static_ptr, static_type) has not yet been
823                 //   found.
824                 do
825                 {
826                     if (info->search_done)
827                         break;
828                     // If we just found a dst_type with a public path to (static_ptr, static_type),
829                     //    then the only reason to continue the search is to make sure
830                     //    no other dst_type points to (static_ptr, static_type).
831                     //    If !diamond, then we don't need to search here.
832                     if (info->number_to_static_ptr == 1 &&
833                               info->path_dst_ptr_to_static_ptr == public_path)
834                         break;
835                     p->search_below_dst(info, current_ptr, path_below);
836                 } while (++p < e);
837             }
838             else
839             {
840                 // There are no repeated types above this node.
841                 // There are no nodes with multiple parents above this node.
842                 // no dst_type has been found to (static_ptr, static_type)
843                 do
844                 {
845                     if (info->search_done)
846                         break;
847                     // If we just found a dst_type with a public path to (static_ptr, static_type),
848                     //    then the only reason to continue the search is to make sure sure
849                     //    no other dst_type points to (static_ptr, static_type).
850                     //    If !diamond, then we don't need to search here.
851                     // if we just found a dst_type with a private path to (static_ptr, static_type),
852                     //    then we're only looking for a public path to (static_ptr, static_type)
853                     //    and to check for other dst_types.
854                     //    If !diamond & !repeat, then there is not a pointer to (static_ptr, static_type)
855                     //    and not a dst_type under here.
856                     if (info->number_to_static_ptr == 1)
857                         break;
858                     p->search_below_dst(info, current_ptr, path_below);
859                 } while (++p < e);
860             }
861         }
862     }
863 }
864 
865 // This is the same algorithm as __vmi_class_type_info::search_below_dst but
866 //   simplified to the case that there is only a single base class.
867 void
868 __si_class_type_info::search_below_dst(__dynamic_cast_info* info,
869                                        const void* current_ptr,
870                                        int path_below) const
871 {
872     if (this == info->static_type)
873         process_static_type_below_dst(info, current_ptr, path_below);
874     else if (this == info->dst_type)
875     {
876         // We've been here before if we've recorded current_ptr in one of these
877         //   two places:
878         if (current_ptr == info->dst_ptr_leading_to_static_ptr ||
879             current_ptr == info->dst_ptr_not_leading_to_static_ptr)
880         {
881             // We've seen this node before, and therefore have already searched
882             // its base classes above.
883             //  Update path to here that is "most public".
884             if (path_below == public_path)
885                 info->path_dynamic_ptr_to_dst_ptr = public_path;
886         }
887         else  // We have haven't been here before
888         {
889             // Record the access path that got us here
890             //   If there is more than one dst_type this path doesn't matter.
891             info->path_dynamic_ptr_to_dst_ptr = path_below;
892             // Only search above here if dst_type derives from static_type, or
893             //    if it is unknown if dst_type derives from static_type.
894             if (info->is_dst_type_derived_from_static_type != no)
895             {
896                 // Set up flags to record results from all base classes
897                 bool is_dst_type_derived_from_static_type = false;
898                 bool does_dst_type_point_to_our_static_type = false;
899                 // Zero out found flags
900                 info->found_our_static_ptr = false;
901                 info->found_any_static_type = false;
902                 __base_type->search_above_dst(info, current_ptr, current_ptr, public_path);
903                 if (info->found_any_static_type)
904                 {
905                     is_dst_type_derived_from_static_type = true;
906                     if (info->found_our_static_ptr)
907                         does_dst_type_point_to_our_static_type = true;
908                 }
909                 if (!does_dst_type_point_to_our_static_type)
910                 {
911                     // We found a dst_type that doesn't point to (static_ptr, static_type)
912                     // So record the address of this dst_ptr and increment the
913                     // count of the number of such dst_types found in the tree.
914                     info->dst_ptr_not_leading_to_static_ptr = current_ptr;
915                     info->number_to_dst_ptr += 1;
916                     // If there exists another dst with a private path to
917                     //    (static_ptr, static_type), then the cast from
918                     //     (dynamic_ptr, dynamic_type) to dst_type is now ambiguous.
919                     if (info->number_to_static_ptr == 1 &&
920                             info->path_dst_ptr_to_static_ptr == not_public_path)
921                         info->search_done = true;
922                 }
923                 // If we found no static_type,s then dst_type doesn't derive
924                 //   from static_type, else it does.  Record this result so that
925                 //   next time we hit a dst_type we will know not to search above
926                 //   it if it doesn't derive from static_type.
927                 if (is_dst_type_derived_from_static_type)
928                     info->is_dst_type_derived_from_static_type = yes;
929                 else
930                     info->is_dst_type_derived_from_static_type = no;
931             }
932         }
933     }
934     else
935     {
936         // This is not a static_type and not a dst_type
937         __base_type->search_below_dst(info, current_ptr, path_below);
938     }
939 }
940 
941 // This is the same algorithm as __vmi_class_type_info::search_below_dst but
942 //   simplified to the case that there is no base class.
943 void
944 __class_type_info::search_below_dst(__dynamic_cast_info* info,
945                                     const void* current_ptr,
946                                     int path_below) const
947 {
948     typedef const __base_class_type_info* Iter;
949     if (this == info->static_type)
950         process_static_type_below_dst(info, current_ptr, path_below);
951     else if (this == info->dst_type)
952     {
953         // We've been here before if we've recorded current_ptr in one of these
954         //   two places:
955         if (current_ptr == info->dst_ptr_leading_to_static_ptr ||
956             current_ptr == info->dst_ptr_not_leading_to_static_ptr)
957         {
958             // We've seen this node before, and therefore have already searched
959             // its base classes above.
960             //  Update path to here that is "most public".
961             if (path_below == public_path)
962                 info->path_dynamic_ptr_to_dst_ptr = public_path;
963         }
964         else  // We have haven't been here before
965         {
966             // Record the access path that got us here
967             //   If there is more than one dst_type this path doesn't matter.
968             info->path_dynamic_ptr_to_dst_ptr = path_below;
969             // We found a dst_type that doesn't point to (static_ptr, static_type)
970             // So record the address of this dst_ptr and increment the
971             // count of the number of such dst_types found in the tree.
972             info->dst_ptr_not_leading_to_static_ptr = current_ptr;
973             info->number_to_dst_ptr += 1;
974             // If there exists another dst with a private path to
975             //    (static_ptr, static_type), then the cast from
976             //     (dynamic_ptr, dynamic_type) to dst_type is now ambiguous.
977             if (info->number_to_static_ptr == 1 &&
978                     info->path_dst_ptr_to_static_ptr == not_public_path)
979                 info->search_done = true;
980             // We found that dst_type does not derive from static_type
981             info->is_dst_type_derived_from_static_type = no;
982         }
983     }
984 }
985 
986 // Call this function when searching above a dst_type node.  This function searches
987 // for a public path to (static_ptr, static_type).
988 // This function is guaranteed not to find a node of type dst_type.
989 // Theoretically this is a very simple function which just stops if it finds a
990 // static_type node:  All the hoopla surrounding the search code is doing
991 // nothing but looking for excuses to stop the search prematurely (break out of
992 // the for-loop).  That is, the algorithm below is simply an optimization of this:
993 // void
994 // __vmi_class_type_info::search_above_dst(__dynamic_cast_info* info,
995 //                                         const void* dst_ptr,
996 //                                         const void* current_ptr,
997 //                                         int path_below) const
998 // {
999 //     if (this == info->static_type)
1000 //         process_static_type_above_dst(info, dst_ptr, current_ptr, path_below);
1001 //     else
1002 //     {
1003 //         typedef const __base_class_type_info* Iter;
1004 //         // This is not a static_type and not a dst_type
1005 //         for (Iter p = __base_info, e = __base_info + __base_count; p < e; ++p)
1006 //         {
1007 //             p->search_above_dst(info, dst_ptr, current_ptr, public_path);
1008 //             // break out early here if you can detect it doesn't matter if you do
1009 //         }
1010 //     }
1011 // }
1012 void
1013 __vmi_class_type_info::search_above_dst(__dynamic_cast_info* info,
1014                                         const void* dst_ptr,
1015                                         const void* current_ptr,
1016                                         int path_below) const
1017 {
1018     if (this == info->static_type)
1019         process_static_type_above_dst(info, dst_ptr, current_ptr, path_below);
1020     else
1021     {
1022         typedef const __base_class_type_info* Iter;
1023         // This is not a static_type and not a dst_type
1024         // Save flags so they can be restored when returning to nodes below.
1025         bool found_our_static_ptr = info->found_our_static_ptr;
1026         bool found_any_static_type = info->found_any_static_type;
1027         // We've found a dst_type below with a path to here.  If the path
1028         //    to here is not public, there may be another path to here that
1029         //    is public.  So we have to assume that the path to here is public.
1030         //  We can stop looking above if:
1031         //    1.  We've found a public path to (static_ptr, static_type).
1032         //    2.  We've found an ambiguous cast from (static_ptr, static_type) to a dst_type.
1033         //        This is detected at the (static_ptr, static_type).
1034         //    3.  We can prove that there is no public path to (static_ptr, static_type)
1035         //        above here.
1036         const Iter e = __base_info + __base_count;
1037         Iter p = __base_info;
1038         // Zero out found flags
1039         info->found_our_static_ptr = false;
1040         info->found_any_static_type = false;
1041         p->search_above_dst(info, dst_ptr, current_ptr, path_below);
1042         if (++p < e)
1043         {
1044             do
1045             {
1046                 if (info->search_done)
1047                     break;
1048                 if (info->found_our_static_ptr)
1049                 {
1050                     // If we found what we're looking for, stop looking above.
1051                     if (info->path_dst_ptr_to_static_ptr == public_path)
1052                         break;
1053                     // We found a private path to (static_ptr, static_type)
1054                     //   If there is no diamond then there is only one path
1055                     //   to (static_ptr, static_type) from here and we just found it.
1056                     if (!(__flags & __diamond_shaped_mask))
1057                         break;
1058                 }
1059                 else if (info->found_any_static_type)
1060                 {
1061                     // If we found a static_type that isn't the one we're looking
1062                     //    for, and if there are no repeated types above here,
1063                     //    then stop looking.
1064                     if (!(__flags & __non_diamond_repeat_mask))
1065                         break;
1066                 }
1067                 // Zero out found flags
1068                 info->found_our_static_ptr = false;
1069                 info->found_any_static_type = false;
1070                 p->search_above_dst(info, dst_ptr, current_ptr, path_below);
1071             } while (++p < e);
1072         }
1073         // Restore flags
1074         info->found_our_static_ptr = found_our_static_ptr;
1075         info->found_any_static_type = found_any_static_type;
1076     }
1077 }
1078 
1079 // This is the same algorithm as __vmi_class_type_info::search_above_dst but
1080 //   simplified to the case that there is only a single base class.
1081 void
1082 __si_class_type_info::search_above_dst(__dynamic_cast_info* info,
1083                                        const void* dst_ptr,
1084                                        const void* current_ptr,
1085                                        int path_below) const
1086 {
1087     if (this == info->static_type)
1088         process_static_type_above_dst(info, dst_ptr, current_ptr, path_below);
1089     else
1090         __base_type->search_above_dst(info, dst_ptr, current_ptr, path_below);
1091 }
1092 
1093 // This is the same algorithm as __vmi_class_type_info::search_above_dst but
1094 //   simplified to the case that there is no base class.
1095 void
1096 __class_type_info::search_above_dst(__dynamic_cast_info* info,
1097                                     const void* dst_ptr,
1098                                     const void* current_ptr,
1099                                     int path_below) const
1100 {
1101     if (this == info->static_type)
1102         process_static_type_above_dst(info, dst_ptr, current_ptr, path_below);
1103 }
1104 
1105 // The search functions for __base_class_type_info are simply convenience
1106 //   functions for adjusting the current_ptr and path_below as the search is
1107 //   passed up to the base class node.
1108 
1109 void
1110 __base_class_type_info::search_above_dst(__dynamic_cast_info* info,
1111                                          const void* dst_ptr,
1112                                          const void* current_ptr,
1113                                          int path_below) const
1114 {
1115     ptrdiff_t offset_to_base = __offset_flags >> __offset_shift;
1116     if (__offset_flags & __virtual_mask)
1117     {
1118         const char* vtable = *static_cast<const char*const*>(current_ptr);
1119         offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
1120     }
1121     __base_type->search_above_dst(info, dst_ptr,
1122                                   static_cast<const char*>(current_ptr) + offset_to_base,
1123                                   (__offset_flags & __public_mask) ?
1124                                       path_below :
1125                                       not_public_path);
1126 }
1127 
1128 void
1129 __base_class_type_info::search_below_dst(__dynamic_cast_info* info,
1130                                          const void* current_ptr,
1131                                          int path_below) const
1132 {
1133     ptrdiff_t offset_to_base = __offset_flags >> __offset_shift;
1134     if (__offset_flags & __virtual_mask)
1135     {
1136         const char* vtable = *static_cast<const char*const*>(current_ptr);
1137         offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
1138     }
1139     __base_type->search_below_dst(info,
1140                                   static_cast<const char*>(current_ptr) + offset_to_base,
1141                                   (__offset_flags & __public_mask) ?
1142                                       path_below :
1143                                       not_public_path);
1144 }
1145 
1146 #pragma GCC visibility pop
1147 
1148 }  // __cxxabiv1
1149