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