1152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant//===----------------------- private_typeinfo.cpp -------------------------===// 2152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant// 3152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant// The LLVM Compiler Infrastructure 4152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant// 5152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant// This file is dual licensed under the MIT and the University of Illinois Open 6152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant// Source Licenses. See LICENSE.TXT for details. 7152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant// 8152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant//===----------------------------------------------------------------------===// 9152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant 10152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant#include "private_typeinfo.h" 11152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant 12326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// The flag _LIBCXX_DYNAMIC_FALLBACK is used to make dynamic_cast more 13326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// forgiving when type_info's mistakenly have hidden visibility and thus 14326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// multiple type_infos can exist for a single type. 15326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// 16326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// When _LIBCXX_DYNAMIC_FALLBACK is defined, and only in the case where 17326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// there is a detected inconsistency in the type_info hierarchy during a 18326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// dynamic_cast, then the equality operation will fall back to using strcmp 196d00feffc82d4f8c0201242291a0e93b492e1dd4Howard Hinnant// on type_info names to determine type_info equality. 20326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// 21326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// This change happens *only* under dynamic_cast, and only when 22326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// dynamic_cast is faced with the choice: abort, or possibly give back the 23326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// wrong answer. If when the dynamic_cast is done with this fallback 24326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// algorithm and an inconsistency is still detected, dynamic_cast will call 256d00feffc82d4f8c0201242291a0e93b492e1dd4Howard Hinnant// abort with an appropriate message. 26326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// 27326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// The current implementation of _LIBCXX_DYNAMIC_FALLBACK requires a 28326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// printf-like function called syslog: 29326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// 3036fd93fd039ef14005d6ab51c2e9f2816d2b7063Yaron Keren// void syslog(int facility_priority, const char* format, ...); 31326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// 32326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// If you want this functionality but your platform doesn't have syslog, 33326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// just implement it in terms of fprintf(stderr, ...). 34326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// 35326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant// _LIBCXX_DYNAMIC_FALLBACK is currently off by default. 36326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant 3791fc04d667ef064c0750133aa75bd58886030f15Eric Fiselier 3891fc04d667ef064c0750133aa75bd58886030f15Eric Fiselier#include <string.h> 3991fc04d667ef064c0750133aa75bd58886030f15Eric Fiselier 4091fc04d667ef064c0750133aa75bd58886030f15Eric Fiselier 41a1fce46063c99e307594236c55004b4e5b62243fDan Albert#ifdef _LIBCXX_DYNAMIC_FALLBACK 42326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant#include "abort_message.h" 431a0d1bc64fa339249c28511fdd6a9780152c9980Howard Hinnant#include <sys/syslog.h> 441a0d1bc64fa339249c28511fdd6a9780152c9980Howard Hinnant#endif 451a0d1bc64fa339249c28511fdd6a9780152c9980Howard Hinnant 46d9eb5fc4502578e2d2a4df8c60c46970c36c4046Yaron Keren// On Windows, typeids are different between DLLs and EXEs, so comparing 47d9eb5fc4502578e2d2a4df8c60c46970c36c4046Yaron Keren// type_info* will work for typeids from the same compiled file but fail 48d9eb5fc4502578e2d2a4df8c60c46970c36c4046Yaron Keren// for typeids from a DLL and an executable. Among other things, exceptions 49d9eb5fc4502578e2d2a4df8c60c46970c36c4046Yaron Keren// are not caught by handlers since can_catch() returns false. 50d9eb5fc4502578e2d2a4df8c60c46970c36c4046Yaron Keren// 51d9eb5fc4502578e2d2a4df8c60c46970c36c4046Yaron Keren// Defining _LIBCXX_DYNAMIC_FALLBACK does not help since can_catch() calls 52d9eb5fc4502578e2d2a4df8c60c46970c36c4046Yaron Keren// is_equal() with use_strcmp=false so the string names are not compared. 53d9eb5fc4502578e2d2a4df8c60c46970c36c4046Yaron Keren 54d9eb5fc4502578e2d2a4df8c60c46970c36c4046Yaron Keren#ifdef _WIN32 55d9eb5fc4502578e2d2a4df8c60c46970c36c4046Yaron Keren#include <string.h> 56d9eb5fc4502578e2d2a4df8c60c46970c36c4046Yaron Keren#endif 57d9eb5fc4502578e2d2a4df8c60c46970c36c4046Yaron Keren 58152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnantnamespace __cxxabiv1 59152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant{ 60152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant 610240685ed6756ee0eed7c76e37eb2abdc01dcf82Howard Hinnant#pragma GCC visibility push(hidden) 62facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant 63326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnantinline 64326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnantbool 65326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnantis_equal(const std::type_info* x, const std::type_info* y, bool use_strcmp) 66326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant{ 6791fc04d667ef064c0750133aa75bd58886030f15Eric Fiselier#ifndef _WIN32 68326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant if (!use_strcmp) 69326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant return x == y; 70326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant return strcmp(x->name(), y->name()) == 0; 71d9eb5fc4502578e2d2a4df8c60c46970c36c4046Yaron Keren#else 72d9eb5fc4502578e2d2a4df8c60c46970c36c4046Yaron Keren return (x == y) || (strcmp(x->name(), y->name()) == 0); 7391fc04d667ef064c0750133aa75bd58886030f15Eric Fiselier#endif 74326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant} 75326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant 76326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant 77facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// __shim_type_info 78facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant 79facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant__shim_type_info::~__shim_type_info() 80facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant{ 81facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant} 82facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant 838f28628704f966409e860c74c46041e04c082720Howard Hinnantvoid __shim_type_info::noop1() const {} 848f28628704f966409e860c74c46041e04c082720Howard Hinnantvoid __shim_type_info::noop2() const {} 858f28628704f966409e860c74c46041e04c082720Howard Hinnant 86152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant// __fundamental_type_info 87152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant 8816650b58dfc7d1a2632b052843dc4e21ae949b07Howard Hinnant// This miraculously (compiler magic) emits the type_info's for: 8916650b58dfc7d1a2632b052843dc4e21ae949b07Howard Hinnant// 1. all of the fundamental types 9016650b58dfc7d1a2632b052843dc4e21ae949b07Howard Hinnant// 2. pointers to all of the fundamental types 9116650b58dfc7d1a2632b052843dc4e21ae949b07Howard Hinnant// 3. pointers to all of the const fundamental types 92152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant__fundamental_type_info::~__fundamental_type_info() 93152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant{ 94152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant} 95152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant 9635b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant// __array_type_info 9735b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant 9835b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant__array_type_info::~__array_type_info() 99facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant{ 100facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant} 101facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant 10235b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant// __function_type_info 103152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant 10435b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant__function_type_info::~__function_type_info() 105152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant{ 106152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant} 107152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant 10835b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant// __enum_type_info 10935b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant 11035b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant__enum_type_info::~__enum_type_info() 111facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant{ 112facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant} 113facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant 11435b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant// __class_type_info 115152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant 11635b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant__class_type_info::~__class_type_info() 117152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant{ 118152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant} 119152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant 12035b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant// __si_class_type_info 12135b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant 12235b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant__si_class_type_info::~__si_class_type_info() 123facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant{ 124facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant} 125facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant 12635b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant// __vmi_class_type_info 127152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant 12835b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant__vmi_class_type_info::~__vmi_class_type_info() 129152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant{ 130152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant} 131152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant 13235b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant// __pbase_type_info 13335b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant 13435b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant__pbase_type_info::~__pbase_type_info() 135facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant{ 136facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant} 137facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant 13835b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant// __pointer_type_info 139152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant 14035b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant__pointer_type_info::~__pointer_type_info() 14135b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant{ 14235b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant} 14335b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant 14435b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant// __pointer_to_member_type_info 14535b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant 14635b2c2af6b2720a3f624ad556b1a3c75394350d7Howard Hinnant__pointer_to_member_type_info::~__pointer_to_member_type_info() 147152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant{ 148152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant} 149152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant 150c30bfdc7ff4f0ab46e614fb8891be0785ae9a753Howard Hinnant// can_catch 151c30bfdc7ff4f0ab46e614fb8891be0785ae9a753Howard Hinnant 152c30bfdc7ff4f0ab46e614fb8891be0785ae9a753Howard Hinnant// A handler is a match for an exception object of type E if 153a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant// 1. The handler is of type cv T or cv T& and E and T are the same type 154a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant// (ignoring the top-level cv-qualifiers), or 155a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant// 2. the handler is of type cv T or cv T& and T is an unambiguous public 156a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant// base class of E, or 157a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant// 3. the handler is of type cv1 T* cv2 and E is a pointer type that can be 158a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant// converted to the type of the handler by either or both of 159a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant// A. a standard pointer conversion (4.10) not involving conversions to 160a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant// pointers to private or protected or ambiguous classes 161a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant// B. a qualification conversion 162a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant// 4. the handler is a pointer or pointer to member type and E is 163a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant// std::nullptr_t. 164c30bfdc7ff4f0ab46e614fb8891be0785ae9a753Howard Hinnant 165c30bfdc7ff4f0ab46e614fb8891be0785ae9a753Howard Hinnant// adjustedPtr: 166c30bfdc7ff4f0ab46e614fb8891be0785ae9a753Howard Hinnant// 167c30bfdc7ff4f0ab46e614fb8891be0785ae9a753Howard Hinnant// catch (A& a) : adjustedPtr == &a 168c30bfdc7ff4f0ab46e614fb8891be0785ae9a753Howard Hinnant// catch (A* a) : adjustedPtr == a 169c30bfdc7ff4f0ab46e614fb8891be0785ae9a753Howard Hinnant// catch (A** a) : adjustedPtr == a 170c30bfdc7ff4f0ab46e614fb8891be0785ae9a753Howard Hinnant// 171c30bfdc7ff4f0ab46e614fb8891be0785ae9a753Howard Hinnant// catch (D2& d2) : adjustedPtr == &d2 (d2 is base class of thrown object) 172c30bfdc7ff4f0ab46e614fb8891be0785ae9a753Howard Hinnant// catch (D2* d2) : adjustedPtr == d2 173c30bfdc7ff4f0ab46e614fb8891be0785ae9a753Howard Hinnant// catch (D2*& d2) : adjustedPtr == d2 174081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith// 175c30bfdc7ff4f0ab46e614fb8891be0785ae9a753Howard Hinnant// catch (...) : adjustedPtr == & of the exception 176081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith// 177081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith// If the thrown type is nullptr_t and the caught type is a pointer to 178081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith// member type, adjustedPtr points to a statically-allocated null pointer 179081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith// representation of that type. 180c30bfdc7ff4f0ab46e614fb8891be0785ae9a753Howard Hinnant 181a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant// Handles bullet 1 182a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnantbool 183a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant__fundamental_type_info::can_catch(const __shim_type_info* thrown_type, 184a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant void*&) const 185a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant{ 18606bbbdde3c601994cd92206c6afe26fbc67812baHoward Hinnant return is_equal(this, thrown_type, false); 187a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant} 188a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant 189a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnantbool 19096f01710bc5b9c37765f60b9a2e12327d2463d65Howard Hinnant__array_type_info::can_catch(const __shim_type_info*, void*&) const 191a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant{ 192aafd08aa288da66805f97231e8c64020bc9d50c6Howard Hinnant // We can get here if someone tries to catch an array by reference. 193aafd08aa288da66805f97231e8c64020bc9d50c6Howard Hinnant // However if someone tries to throw an array, it immediately gets 194aafd08aa288da66805f97231e8c64020bc9d50c6Howard Hinnant // converted to a pointer, which will not convert back to an array 195aafd08aa288da66805f97231e8c64020bc9d50c6Howard Hinnant // at the catch clause. So this can never catch anything. 196a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant return false; 197a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant} 198a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant 199a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnantbool 20096f01710bc5b9c37765f60b9a2e12327d2463d65Howard Hinnant__function_type_info::can_catch(const __shim_type_info*, void*&) const 201a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant{ 2024b3cb1cb82c0479bc9c675b79a2250ea4c85aae8Howard Hinnant // We can get here if someone tries to catch a function by reference. 2034b3cb1cb82c0479bc9c675b79a2250ea4c85aae8Howard Hinnant // However if someone tries to throw a function, it immediately gets 2044b3cb1cb82c0479bc9c675b79a2250ea4c85aae8Howard Hinnant // converted to a pointer, which will not convert back to a function 2054b3cb1cb82c0479bc9c675b79a2250ea4c85aae8Howard Hinnant // at the catch clause. So this can never catch anything. 206a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant return false; 207a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant} 208a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant 209a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant// Handles bullet 1 210a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnantbool 211a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant__enum_type_info::can_catch(const __shim_type_info* thrown_type, 212a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant void*&) const 213a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant{ 21406bbbdde3c601994cd92206c6afe26fbc67812baHoward Hinnant return is_equal(this, thrown_type, false); 215a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant} 216a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant 217faf34fbbbbb5956d6da2661a00f5c6b5aefcfe55Nick Lewycky#ifdef __clang__ 21891f198a4c8f43b40f23e8c51641e62fe5e13115aHoward Hinnant#pragma clang diagnostic push 21991f198a4c8f43b40f23e8c51641e62fe5e13115aHoward Hinnant#pragma clang diagnostic ignored "-Wmissing-field-initializers" 220faf34fbbbbb5956d6da2661a00f5c6b5aefcfe55Nick Lewycky#endif 22191f198a4c8f43b40f23e8c51641e62fe5e13115aHoward Hinnant 222a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant// Handles bullets 1 and 2 223a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnantbool 224a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant__class_type_info::can_catch(const __shim_type_info* thrown_type, 225a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant void*& adjustedPtr) const 226a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant{ 227a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant // bullet 1 22806bbbdde3c601994cd92206c6afe26fbc67812baHoward Hinnant if (is_equal(this, thrown_type, false)) 229a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant return true; 230a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant const __class_type_info* thrown_class_type = 231a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant dynamic_cast<const __class_type_info*>(thrown_type); 232a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant if (thrown_class_type == 0) 233a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant return false; 234a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant // bullet 2 235a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant __dynamic_cast_info info = {thrown_class_type, 0, this, -1, 0}; 236a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant info.number_of_dst_type = 1; 237a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, public_path); 238a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant if (info.path_dst_ptr_to_static_ptr == public_path) 239a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant { 240a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr); 241a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant return true; 242a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant } 243a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant return false; 244a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant} 245a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant 246faf34fbbbbb5956d6da2661a00f5c6b5aefcfe55Nick Lewycky#ifdef __clang__ 24791f198a4c8f43b40f23e8c51641e62fe5e13115aHoward Hinnant#pragma clang diagnostic pop 248faf34fbbbbb5956d6da2661a00f5c6b5aefcfe55Nick Lewycky#endif 24991f198a4c8f43b40f23e8c51641e62fe5e13115aHoward Hinnant 250a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnantvoid 251a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant__class_type_info::process_found_base_class(__dynamic_cast_info* info, 252a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant void* adjustedPtr, 253a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant int path_below) const 254a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant{ 255a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant if (info->dst_ptr_leading_to_static_ptr == 0) 256a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant { 257a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant // First time here 258a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant info->dst_ptr_leading_to_static_ptr = adjustedPtr; 259a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant info->path_dst_ptr_to_static_ptr = path_below; 260a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant info->number_to_static_ptr = 1; 261a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant } 262a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant else if (info->dst_ptr_leading_to_static_ptr == adjustedPtr) 263a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant { 264a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant // We've been here before. Update path to "most public" 265a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant if (info->path_dst_ptr_to_static_ptr == not_public_path) 266a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant info->path_dst_ptr_to_static_ptr = path_below; 267a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant } 268a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant else 269a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant { 270a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant // We've detected an ambiguous cast from (thrown_class_type, adjustedPtr) 271a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant // to a static_type 272a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant info->number_to_static_ptr += 1; 273a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant info->path_dst_ptr_to_static_ptr = not_public_path; 274a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant info->search_done = true; 275a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant } 276a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant} 277a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant 278a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnantvoid 279a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant__class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, 280a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant void* adjustedPtr, 281a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant int path_below) const 282a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant{ 28306bbbdde3c601994cd92206c6afe26fbc67812baHoward Hinnant if (is_equal(this, info->static_type, false)) 284a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant process_found_base_class(info, adjustedPtr, path_below); 285a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant} 286a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant 287a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnantvoid 288a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant__si_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, 289a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant void* adjustedPtr, 290a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant int path_below) const 291a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant{ 29206bbbdde3c601994cd92206c6afe26fbc67812baHoward Hinnant if (is_equal(this, info->static_type, false)) 293a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant process_found_base_class(info, adjustedPtr, path_below); 294a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant else 295a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant __base_type->has_unambiguous_public_base(info, adjustedPtr, path_below); 296a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant} 297a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant 298a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnantvoid 299a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant__base_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, 300a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant void* adjustedPtr, 301a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant int path_below) const 302a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant{ 30398bbf28c5eac8ed3356909563e4d80529507995fMarshall Clow ptrdiff_t offset_to_base = 0; 30498bbf28c5eac8ed3356909563e4d80529507995fMarshall Clow if (adjustedPtr != nullptr) 305a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant { 30698bbf28c5eac8ed3356909563e4d80529507995fMarshall Clow offset_to_base = __offset_flags >> __offset_shift; 30798bbf28c5eac8ed3356909563e4d80529507995fMarshall Clow if (__offset_flags & __virtual_mask) 30898bbf28c5eac8ed3356909563e4d80529507995fMarshall Clow { 30998bbf28c5eac8ed3356909563e4d80529507995fMarshall Clow const char* vtable = *static_cast<const char*const*>(adjustedPtr); 31098bbf28c5eac8ed3356909563e4d80529507995fMarshall Clow offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base); 31198bbf28c5eac8ed3356909563e4d80529507995fMarshall Clow } 312a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant } 31398bbf28c5eac8ed3356909563e4d80529507995fMarshall Clow __base_type->has_unambiguous_public_base( 31498bbf28c5eac8ed3356909563e4d80529507995fMarshall Clow info, 31598bbf28c5eac8ed3356909563e4d80529507995fMarshall Clow static_cast<char*>(adjustedPtr) + offset_to_base, 31698bbf28c5eac8ed3356909563e4d80529507995fMarshall Clow (__offset_flags & __public_mask) ? path_below : not_public_path); 317a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant} 318a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant 319a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnantvoid 320a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant__vmi_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, 321a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant void* adjustedPtr, 322a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant int path_below) const 323a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant{ 32406bbbdde3c601994cd92206c6afe26fbc67812baHoward Hinnant if (is_equal(this, info->static_type, false)) 325a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant process_found_base_class(info, adjustedPtr, path_below); 326a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant else 327a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant { 328a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant typedef const __base_class_type_info* Iter; 329a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant const Iter e = __base_info + __base_count; 330a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant Iter p = __base_info; 331a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant p->has_unambiguous_public_base(info, adjustedPtr, path_below); 332a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant if (++p < e) 333a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant { 334a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant do 335a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant { 336a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant p->has_unambiguous_public_base(info, adjustedPtr, path_below); 337a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant if (info->search_done) 338a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant break; 339a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant } while (++p < e); 340a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant } 341a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant } 342a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant} 343a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant 344081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith// Handles bullet 1 for both pointers and member pointers 345a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnantbool 346a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant__pbase_type_info::can_catch(const __shim_type_info* thrown_type, 347a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant void*&) const 348a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant{ 34991fc04d667ef064c0750133aa75bd58886030f15Eric Fiselier bool use_strcmp = this->__flags & (__incomplete_class_mask | 35091fc04d667ef064c0750133aa75bd58886030f15Eric Fiselier __incomplete_mask); 35191fc04d667ef064c0750133aa75bd58886030f15Eric Fiselier if (!use_strcmp) { 35291fc04d667ef064c0750133aa75bd58886030f15Eric Fiselier const __pbase_type_info* thrown_pbase = dynamic_cast<const __pbase_type_info*>( 35391fc04d667ef064c0750133aa75bd58886030f15Eric Fiselier thrown_type); 35491fc04d667ef064c0750133aa75bd58886030f15Eric Fiselier if (!thrown_pbase) return false; 35591fc04d667ef064c0750133aa75bd58886030f15Eric Fiselier use_strcmp = thrown_pbase->__flags & (__incomplete_class_mask | 35691fc04d667ef064c0750133aa75bd58886030f15Eric Fiselier __incomplete_mask); 35791fc04d667ef064c0750133aa75bd58886030f15Eric Fiselier } 35891fc04d667ef064c0750133aa75bd58886030f15Eric Fiselier return is_equal(this, thrown_type, use_strcmp); 359a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant} 360a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant 361faf34fbbbbb5956d6da2661a00f5c6b5aefcfe55Nick Lewycky#ifdef __clang__ 36291f198a4c8f43b40f23e8c51641e62fe5e13115aHoward Hinnant#pragma clang diagnostic push 36391f198a4c8f43b40f23e8c51641e62fe5e13115aHoward Hinnant#pragma clang diagnostic ignored "-Wmissing-field-initializers" 364faf34fbbbbb5956d6da2661a00f5c6b5aefcfe55Nick Lewycky#endif 36591f198a4c8f43b40f23e8c51641e62fe5e13115aHoward Hinnant 366a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant// Handles bullets 1, 3 and 4 3671b4ddb114e91d196cf3a652124e70560edf3816cEric Fiselier// NOTE: It might not be safe to adjust the pointer if it is not not a pointer 3681b4ddb114e91d196cf3a652124e70560edf3816cEric Fiselier// type. Only adjust the pointer after we know it is safe to do so. 369a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnantbool 370a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant__pointer_type_info::can_catch(const __shim_type_info* thrown_type, 371a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant void*& adjustedPtr) const 372a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant{ 373081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith // bullet 4 374081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith if (is_equal(thrown_type, &typeid(std::nullptr_t), false)) { 375081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith adjustedPtr = nullptr; 376081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith return true; 377081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith } 378081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith 379081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith // bullet 1 3801b4ddb114e91d196cf3a652124e70560edf3816cEric Fiselier if (__pbase_type_info::can_catch(thrown_type, adjustedPtr)) { 3811b4ddb114e91d196cf3a652124e70560edf3816cEric Fiselier if (adjustedPtr != NULL) 3821b4ddb114e91d196cf3a652124e70560edf3816cEric Fiselier adjustedPtr = *static_cast<void**>(adjustedPtr); 383a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant return true; 3841b4ddb114e91d196cf3a652124e70560edf3816cEric Fiselier } 385a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant // bullet 3 386a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant const __pointer_type_info* thrown_pointer_type = 387a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant dynamic_cast<const __pointer_type_info*>(thrown_type); 388a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant if (thrown_pointer_type == 0) 389a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant return false; 3901b4ddb114e91d196cf3a652124e70560edf3816cEric Fiselier // Do the dereference adjustment 3911b4ddb114e91d196cf3a652124e70560edf3816cEric Fiselier if (adjustedPtr != NULL) 3921b4ddb114e91d196cf3a652124e70560edf3816cEric Fiselier adjustedPtr = *static_cast<void**>(adjustedPtr); 393f1636207ad8e142a11f80860ea27ea92fcc8c776Richard Smith // bullet 3B and 3C 394f1636207ad8e142a11f80860ea27ea92fcc8c776Richard Smith if (thrown_pointer_type->__flags & ~__flags & __no_remove_flags_mask) 395f1636207ad8e142a11f80860ea27ea92fcc8c776Richard Smith return false; 396f1636207ad8e142a11f80860ea27ea92fcc8c776Richard Smith if (__flags & ~thrown_pointer_type->__flags & __no_add_flags_mask) 397a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant return false; 39806bbbdde3c601994cd92206c6afe26fbc67812baHoward Hinnant if (is_equal(__pointee, thrown_pointer_type->__pointee, false)) 399a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant return true; 400a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant // bullet 3A 401b979db159a515fe12b54f793690618313e017259Eric Fiselier if (is_equal(__pointee, &typeid(void), false)) { 402b979db159a515fe12b54f793690618313e017259Eric Fiselier // pointers to functions cannot be converted to void*. 403b979db159a515fe12b54f793690618313e017259Eric Fiselier // pointers to member functions are not handled here. 404b979db159a515fe12b54f793690618313e017259Eric Fiselier const __function_type_info* thrown_function = 405b979db159a515fe12b54f793690618313e017259Eric Fiselier dynamic_cast<const __function_type_info*>(thrown_pointer_type->__pointee); 406b979db159a515fe12b54f793690618313e017259Eric Fiselier return (thrown_function == nullptr); 407b979db159a515fe12b54f793690618313e017259Eric Fiselier } 4080cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier // Handle pointer to pointer 4090cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier const __pointer_type_info* nested_pointer_type = 4100cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier dynamic_cast<const __pointer_type_info*>(__pointee); 4110cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier if (nested_pointer_type) { 4120cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier if (~__flags & __const_mask) return false; 4130cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return nested_pointer_type->can_catch_nested(thrown_pointer_type->__pointee); 4140cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier } 4150cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier 4160cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier // Handle pointer to pointer to member 4170cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier const __pointer_to_member_type_info* member_ptr_type = 4180cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier dynamic_cast<const __pointer_to_member_type_info*>(__pointee); 4190cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier if (member_ptr_type) { 4200cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier if (~__flags & __const_mask) return false; 4210cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return member_ptr_type->can_catch_nested(thrown_pointer_type->__pointee); 4220cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier } 4230cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier 4240cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier // Handle pointer to class type 425a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant const __class_type_info* catch_class_type = 426a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant dynamic_cast<const __class_type_info*>(__pointee); 427a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant if (catch_class_type == 0) 428a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant return false; 429a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant const __class_type_info* thrown_class_type = 430a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant dynamic_cast<const __class_type_info*>(thrown_pointer_type->__pointee); 431a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant if (thrown_class_type == 0) 432a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant return false; 433a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant __dynamic_cast_info info = {thrown_class_type, 0, catch_class_type, -1, 0}; 434a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant info.number_of_dst_type = 1; 435a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, public_path); 436a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant if (info.path_dst_ptr_to_static_ptr == public_path) 437a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant { 438288859d0a1684e0899702f50353ccdbc1bdab8b7Marshall Clow if (adjustedPtr != NULL) 439288859d0a1684e0899702f50353ccdbc1bdab8b7Marshall Clow adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr); 440a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant return true; 441a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant } 442a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant return false; 443a1919d2ee24b06c833493cf06335afa307028bf7Howard Hinnant} 444c30bfdc7ff4f0ab46e614fb8891be0785ae9a753Howard Hinnant 4450cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselierbool __pointer_type_info::can_catch_nested( 4460cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier const __shim_type_info* thrown_type) const 4470cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier{ 4480cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier const __pointer_type_info* thrown_pointer_type = 4490cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier dynamic_cast<const __pointer_type_info*>(thrown_type); 4500cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier if (thrown_pointer_type == 0) 4510cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return false; 4520cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier // bullet 3B 4530cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier if (thrown_pointer_type->__flags & ~__flags) 4540cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return false; 4550cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier if (is_equal(__pointee, thrown_pointer_type->__pointee, false)) 4560cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return true; 4570cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier // If the pointed to types differ then the catch type must be const 4580cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier // qualified. 4590cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier if (~__flags & __const_mask) 4600cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return false; 4610cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier 4620cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier // Handle pointer to pointer 4630cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier const __pointer_type_info* nested_pointer_type = 4640cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier dynamic_cast<const __pointer_type_info*>(__pointee); 4650cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier if (nested_pointer_type) { 4660cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return nested_pointer_type->can_catch_nested( 4670cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier thrown_pointer_type->__pointee); 4680cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier } 4690cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier 4700cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier // Handle pointer to pointer to member 4710cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier const __pointer_to_member_type_info* member_ptr_type = 4720cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier dynamic_cast<const __pointer_to_member_type_info*>(__pointee); 4730cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier if (member_ptr_type) { 4740cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return member_ptr_type->can_catch_nested(thrown_pointer_type->__pointee); 4750cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier } 4760cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier 4770cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return false; 4780cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier} 4790cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier 4800cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselierbool __pointer_to_member_type_info::can_catch( 4810cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier const __shim_type_info* thrown_type, void*& adjustedPtr) const { 482081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith // bullet 4 483081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith if (is_equal(thrown_type, &typeid(std::nullptr_t), false)) { 484081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith // We assume that the pointer to member representation is the same for 485081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith // all pointers to data members and for all pointers to member functions. 486081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith struct X {}; 487081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith if (dynamic_cast<const __function_type_info*>(__pointee)) { 488081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith static int (X::*const null_ptr_rep)() = nullptr; 489081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith adjustedPtr = const_cast<int (X::**)()>(&null_ptr_rep); 490081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith } else { 491081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith static int X::*const null_ptr_rep = nullptr; 492081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith adjustedPtr = const_cast<int X::**>(&null_ptr_rep); 493081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith } 494081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith return true; 495081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith } 496081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith 497081ea86d80df60bcbb5517868ec5f1afab6bf973Richard Smith // bullet 1 4980cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier if (__pbase_type_info::can_catch(thrown_type, adjustedPtr)) 4990cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return true; 5000cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier 5010cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier const __pointer_to_member_type_info* thrown_pointer_type = 5020cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier dynamic_cast<const __pointer_to_member_type_info*>(thrown_type); 5030cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier if (thrown_pointer_type == 0) 5040cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return false; 505f1636207ad8e142a11f80860ea27ea92fcc8c776Richard Smith if (thrown_pointer_type->__flags & ~__flags & __no_remove_flags_mask) 506f1636207ad8e142a11f80860ea27ea92fcc8c776Richard Smith return false; 507f1636207ad8e142a11f80860ea27ea92fcc8c776Richard Smith if (__flags & ~thrown_pointer_type->__flags & __no_add_flags_mask) 5080cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return false; 509f1636207ad8e142a11f80860ea27ea92fcc8c776Richard Smith if (!is_equal(__pointee, thrown_pointer_type->__pointee, false)) 5100cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return false; 5110cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier if (is_equal(__context, thrown_pointer_type->__context, false)) 5120cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return true; 5130cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier 514554d59ab0b989830273c9183f7bdfd12108cad7aEric Fiselier // [except.handle] does not allow the pointer-to-member conversions mentioned 515554d59ab0b989830273c9183f7bdfd12108cad7aEric Fiselier // in [mem.conv] to take place. For this reason we don't check Derived->Base 516554d59ab0b989830273c9183f7bdfd12108cad7aEric Fiselier // for Derived->Base conversions. 5170cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier 5180cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return false; 5190cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier} 5200cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier 5210cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselierbool __pointer_to_member_type_info::can_catch_nested( 5220cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier const __shim_type_info* thrown_type) const 5230cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier{ 5240cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier const __pointer_to_member_type_info* thrown_member_ptr_type = 5250cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier dynamic_cast<const __pointer_to_member_type_info*>(thrown_type); 5260cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier if (thrown_member_ptr_type == 0) 5270cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return false; 5280cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier if (~__flags & thrown_member_ptr_type->__flags) 5290cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return false; 5300cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier if (!is_equal(__pointee, thrown_member_ptr_type->__pointee, false)) 5310cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return false; 5320cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier if (!is_equal(__context, thrown_member_ptr_type->__context, false)) 5330cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return false; 5340cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier return true; 5350cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier} 5360cb62d1b51f3d9ab65e0ba7b6541dda0663fe50dEric Fiselier 537faf34fbbbbb5956d6da2661a00f5c6b5aefcfe55Nick Lewycky#ifdef __clang__ 53891f198a4c8f43b40f23e8c51641e62fe5e13115aHoward Hinnant#pragma clang diagnostic pop 539faf34fbbbbb5956d6da2661a00f5c6b5aefcfe55Nick Lewycky#endif 54091f198a4c8f43b40f23e8c51641e62fe5e13115aHoward Hinnant 5410240685ed6756ee0eed7c76e37eb2abdc01dcf82Howard Hinnant#pragma GCC visibility pop 542facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant#pragma GCC visibility push(default) 543facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant 544faf34fbbbbb5956d6da2661a00f5c6b5aefcfe55Nick Lewycky#ifdef __clang__ 54591f198a4c8f43b40f23e8c51641e62fe5e13115aHoward Hinnant#pragma clang diagnostic push 54691f198a4c8f43b40f23e8c51641e62fe5e13115aHoward Hinnant#pragma clang diagnostic ignored "-Wmissing-field-initializers" 547faf34fbbbbb5956d6da2661a00f5c6b5aefcfe55Nick Lewycky#endif 54891f198a4c8f43b40f23e8c51641e62fe5e13115aHoward Hinnant 5491309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// __dynamic_cast 5501309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant 551cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// static_ptr: pointer to an object of type static_type; nonnull, and since the 552cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// object is polymorphic, *(void**)static_ptr is a virtual table pointer. 553cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// static_ptr is &v in the expression dynamic_cast<T>(v). 554cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// static_type: static type of the object pointed to by static_ptr. 555cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// dst_type: destination type of the cast (the "T" in "dynamic_cast<T>(v)"). 5561309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// src2dst_offset: a static hint about the location of the 5571309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// source subobject with respect to the complete object; 5581309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// special negative values are: 5591309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// -1: no hint 5601309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// -2: static_type is not a public base of dst_type 5611309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// -3: static_type is a multiple public base type but never a 5621309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// virtual base type 5631309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// otherwise, the static_type type is a unique public nonvirtual 5641309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// base type of dst_type at offset src2dst_offset from the 5651309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// origin of dst_type. 5661309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// 567cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// (dynamic_ptr, dynamic_type) are the run time type of the complete object 568cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// referred to by static_ptr and a pointer to it. These can be found from 569cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// static_ptr for polymorphic types. 5701309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// static_type is guaranteed to be a polymorphic type. 5711309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// 572cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// (dynamic_ptr, dynamic_type) is the root of a DAG that grows upward. Each 573cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// node of the tree represents a base class/object of its parent (or parents) below. 574cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// Each node is uniquely represented by a pointer to the object, and a pointer 575cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// to a type_info - its type. Different nodes may have the same pointer and 576cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// different nodes may have the same type. But only one node has a specific 577cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// (pointer-value, type) pair. In C++ two objects of the same type can not 578cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// share the same address. 579cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// 580cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// There are two flavors of nodes which have the type dst_type: 581cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// 1. Those that are derived from (below) (static_ptr, static_type). 582cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// 2. Those that are not derived from (below) (static_ptr, static_type). 583cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// 584cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// Invariants of the DAG: 585cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// 586cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// There is at least one path from the root (dynamic_ptr, dynamic_type) to 587cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// the node (static_ptr, static_type). This path may or may not be public. 588cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// There may be more than one such path (some public some not). Such a path may 589cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// or may not go through a node having type dst_type. 590cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// 591cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// No node of type T appears above a node of the same type. That means that 592cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// there is only one node with dynamic_type. And if dynamic_type == dst_type, 593cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// then there is only one dst_type in the DAG. 594cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// 595cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// No node of type dst_type appears above a node of type static_type. Such 596cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// DAG's are possible in C++, but the compiler computes those dynamic_casts at 597cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// compile time, and only calls __dynamic_cast when dst_type lies below 598cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// static_type in the DAG. 599cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// 600cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// dst_type != static_type: The compiler computes the dynamic_cast in this case too. 601facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// dynamic_type != static_type: The compiler computes the dynamic_cast in this case too. 602cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// 603cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// Returns: 604cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// 605cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// If there is exactly one dst_type of flavor 1, and 6061309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// If there is a public path from that dst_type to (static_ptr, static_type), or 607cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// If there are 0 dst_types of flavor 2, and there is a public path from 6081309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// (dynamic_ptr, dynamic_type) to (static_ptr, static_type) and a public 6091309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// path from (dynamic_ptr, dynamic_type) to the one dst_type, then return 6101309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// a pointer to that dst_type. 611cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// Else if there are 0 dst_types of flavor 1 and exactly 1 dst_type of flavor 2, and 612facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// if there is a public path from (dynamic_ptr, dynamic_type) to 6131309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// (static_ptr, static_type) and a public path from (dynamic_ptr, dynamic_type) 6141309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// to the one dst_type, then return a pointer to that one dst_type. 6151309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// Else return nullptr. 6161309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// 6171309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// If dynamic_type == dst_type, then the above algorithm collapses to the 6181309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// following cheaper algorithm: 6191309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// 6201309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// If there is a public path from (dynamic_ptr, dynamic_type) to 6211309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// (static_ptr, static_type), then return dynamic_ptr. 6221309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// Else return nullptr. 62346eb39a561ce4e4952abcb05378e38f01fd3fac6Saleem Abdulrasool 62446eb39a561ce4e4952abcb05378e38f01fd3fac6Saleem Abdulrasoolextern "C" _LIBCXXABI_FUNC_VIS void * 62546eb39a561ce4e4952abcb05378e38f01fd3fac6Saleem Abdulrasool__dynamic_cast(const void *static_ptr, const __class_type_info *static_type, 62646eb39a561ce4e4952abcb05378e38f01fd3fac6Saleem Abdulrasool const __class_type_info *dst_type, 62746eb39a561ce4e4952abcb05378e38f01fd3fac6Saleem Abdulrasool std::ptrdiff_t src2dst_offset) { 6280550d57ec1c783ff5f56ff15f933e01d81574105Howard Hinnant // Possible future optimization: Take advantage of src2dst_offset 6290550d57ec1c783ff5f56ff15f933e01d81574105Howard Hinnant // Currently clang always sets src2dst_offset to -1 (no hint). 630cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant 631cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant // Get (dynamic_ptr, dynamic_type) from static_ptr 6320f111c296c143eb179af0313d5d4108f346b3fbaSaleem Abdulrasool void **vtable = *static_cast<void ** const *>(static_ptr); 633cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant ptrdiff_t offset_to_derived = reinterpret_cast<ptrdiff_t>(vtable[-2]); 634cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant const void* dynamic_ptr = static_cast<const char*>(static_ptr) + offset_to_derived; 635cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant const __class_type_info* dynamic_type = static_cast<const __class_type_info*>(vtable[-1]); 636cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant 637cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant // Initialize answer to nullptr. This will be changed from the search 638cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant // results if a non-null answer is found. Regardless, this is what will 639cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant // be returned. 6401309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant const void* dst_ptr = 0; 641cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant // Initialize info struct for this search. 6421309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant __dynamic_cast_info info = {dst_type, static_ptr, static_type, src2dst_offset, 0}; 643cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant 644cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant // Find out if we can use a giant short cut in the search 64506bbbdde3c601994cd92206c6afe26fbc67812baHoward Hinnant if (is_equal(dynamic_type, dst_type, false)) 646f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant { 647cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant // Using giant short cut. Add that information to info. 6481309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info.number_of_dst_type = 1; 649cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant // Do the search 650326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, false); 651a1fce46063c99e307594236c55004b4e5b62243fDan Albert#ifdef _LIBCXX_DYNAMIC_FALLBACK 6521a0d1bc64fa339249c28511fdd6a9780152c9980Howard Hinnant // The following if should always be false because we should definitely 6531a0d1bc64fa339249c28511fdd6a9780152c9980Howard Hinnant // find (static_ptr, static_type), either on a public or private path 6541a0d1bc64fa339249c28511fdd6a9780152c9980Howard Hinnant if (info.path_dst_ptr_to_static_ptr == unknown) 6551a0d1bc64fa339249c28511fdd6a9780152c9980Howard Hinnant { 6561a0d1bc64fa339249c28511fdd6a9780152c9980Howard Hinnant // We get here only if there is some kind of visibility problem 6571a0d1bc64fa339249c28511fdd6a9780152c9980Howard Hinnant // in client code. 658552b14000a3063cfa561fd3f9fd3c26259e7ca31Howard Hinnant syslog(LOG_ERR, "dynamic_cast error 1: Both of the following type_info's " 6596c33e768c1b37af3e5d5f9f0e2a72fcf1dc51382Howard Hinnant "should have public visibility. At least one of them is hidden. %s" 660552b14000a3063cfa561fd3f9fd3c26259e7ca31Howard Hinnant ", %s.\n", static_type->name(), dynamic_type->name()); 661326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant // Redo the search comparing type_info's using strcmp 662326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant info = {dst_type, static_ptr, static_type, src2dst_offset, 0}; 663326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant info.number_of_dst_type = 1; 664326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, true); 6651a0d1bc64fa339249c28511fdd6a9780152c9980Howard Hinnant } 666326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant#endif // _LIBCXX_DYNAMIC_FALLBACK 667cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant // Query the search. 6681309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (info.path_dst_ptr_to_static_ptr == public_path) 6691309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant dst_ptr = dynamic_ptr; 6701309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant } 6711309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant else 6721309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant { 673cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant // Not using giant short cut. Do the search 674326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, false); 675a1fce46063c99e307594236c55004b4e5b62243fDan Albert #ifdef _LIBCXX_DYNAMIC_FALLBACK 6761a0d1bc64fa339249c28511fdd6a9780152c9980Howard Hinnant // The following if should always be false because we should definitely 6771a0d1bc64fa339249c28511fdd6a9780152c9980Howard Hinnant // find (static_ptr, static_type), either on a public or private path 678326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant if (info.path_dst_ptr_to_static_ptr == unknown && 6791a0d1bc64fa339249c28511fdd6a9780152c9980Howard Hinnant info.path_dynamic_ptr_to_static_ptr == unknown) 6801a0d1bc64fa339249c28511fdd6a9780152c9980Howard Hinnant { 681552b14000a3063cfa561fd3f9fd3c26259e7ca31Howard Hinnant syslog(LOG_ERR, "dynamic_cast error 2: One or more of the following type_info's " 682552b14000a3063cfa561fd3f9fd3c26259e7ca31Howard Hinnant " has hidden visibility. They should all have public visibility. " 683552b14000a3063cfa561fd3f9fd3c26259e7ca31Howard Hinnant " %s, %s, %s.\n", static_type->name(), dynamic_type->name(), 6841a0d1bc64fa339249c28511fdd6a9780152c9980Howard Hinnant dst_type->name()); 685326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant // Redo the search comparing type_info's using strcmp 686326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant info = {dst_type, static_ptr, static_type, src2dst_offset, 0}; 687326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, true); 6881a0d1bc64fa339249c28511fdd6a9780152c9980Howard Hinnant } 689326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant#endif // _LIBCXX_DYNAMIC_FALLBACK 690cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant // Query the search. 6911309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant switch (info.number_to_static_ptr) 692f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant { 6931309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant case 0: 6941309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (info.number_to_dst_ptr == 1 && 6951309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info.path_dynamic_ptr_to_static_ptr == public_path && 6961309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info.path_dynamic_ptr_to_dst_ptr == public_path) 6971309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant dst_ptr = info.dst_ptr_not_leading_to_static_ptr; 6981309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant break; 6991309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant case 1: 7001309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (info.path_dst_ptr_to_static_ptr == public_path || 7011309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant ( 7021309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info.number_to_dst_ptr == 0 && 7031309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info.path_dynamic_ptr_to_static_ptr == public_path && 7041309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info.path_dynamic_ptr_to_dst_ptr == public_path 7051309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant ) 7061309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant ) 7071309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant dst_ptr = info.dst_ptr_leading_to_static_ptr; 7081309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant break; 709f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant } 710f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant } 7111309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant return const_cast<void*>(dst_ptr); 712f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant} 713f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant 714faf34fbbbbb5956d6da2661a00f5c6b5aefcfe55Nick Lewycky#ifdef __clang__ 71591f198a4c8f43b40f23e8c51641e62fe5e13115aHoward Hinnant#pragma clang diagnostic pop 716faf34fbbbbb5956d6da2661a00f5c6b5aefcfe55Nick Lewycky#endif 71791f198a4c8f43b40f23e8c51641e62fe5e13115aHoward Hinnant 718facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant#pragma GCC visibility pop 719facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant#pragma GCC visibility push(hidden) 720facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant 7211309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// Call this function when you hit a static_type which is a base (above) a dst_type. 7221309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// Let caller know you hit a static_type. But only start recording details if 7231309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// this is (static_ptr, static_type) -- the node we are casting from. 7241309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// If this is (static_ptr, static_type) 7251309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// Record the path (public or not) from the dst_type to here. There may be 7261309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// multiple paths from the same dst_type to here, record the "most public" one. 7271309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// Record the dst_ptr as pointing to (static_ptr, static_type). 7281309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// If more than one (dst_ptr, dst_type) points to (static_ptr, static_type), 7291309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// then mark this dyanmic_cast as ambiguous and stop the search. 7301309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnantvoid 7311309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant__class_type_info::process_static_type_above_dst(__dynamic_cast_info* info, 7321309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant const void* dst_ptr, 7331309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant const void* current_ptr, 7341309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant int path_below) const 735f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant{ 7361309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // Record that we found a static_type 7371309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->found_any_static_type = true; 7381309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (current_ptr == info->static_ptr) 739271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant { 7401309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // Record that we found (static_ptr, static_type) 7411309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->found_our_static_ptr = true; 7421309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (info->dst_ptr_leading_to_static_ptr == 0) 743271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant { 7441309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // First time here 7451309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->dst_ptr_leading_to_static_ptr = dst_ptr; 7461309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->path_dst_ptr_to_static_ptr = path_below; 7471309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->number_to_static_ptr = 1; 7481309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // If there is only one dst_type in the entire tree and the path from 7491309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // there to here is public then we are done! 7501309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (info->number_of_dst_type == 1 && info->path_dst_ptr_to_static_ptr == public_path) 7511309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->search_done = true; 752271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant } 7531309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant else if (info->dst_ptr_leading_to_static_ptr == dst_ptr) 754f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant { 7551309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // We've been here before. Update path to "most public" 7561309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (info->path_dst_ptr_to_static_ptr == not_public_path) 7571309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->path_dst_ptr_to_static_ptr = path_below; 7581309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // If there is only one dst_type in the entire tree and the path from 7591309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // there to here is public then we are done! 7601309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (info->number_of_dst_type == 1 && info->path_dst_ptr_to_static_ptr == public_path) 7611309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->search_done = true; 762f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant } 763f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant else 764f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant { 7651309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // We've detected an ambiguous cast from (static_ptr, static_type) 7661309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // to a dst_type 7671309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->number_to_static_ptr += 1; 7681309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->search_done = true; 769f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant } 770f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant } 771f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant} 772f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant 7731309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// Call this function when you hit a static_type which is not a base (above) a dst_type. 7741309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// If this is (static_ptr, static_type) 7751309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// Record the path (public or not) from (dynamic_ptr, dynamic_type) to here. There may be 7761309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// multiple paths from (dynamic_ptr, dynamic_type) to here, record the "most public" one. 77716650b58dfc7d1a2632b052843dc4e21ae949b07Howard Hinnantvoid 7781309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant__class_type_info::process_static_type_below_dst(__dynamic_cast_info* info, 7791309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant const void* current_ptr, 7801309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant int path_below) const 781152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant{ 7821309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (current_ptr == info->static_ptr) 7831309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant { 7841309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // Record the most public path from (dynamic_ptr, dynamic_type) to 7851309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // (static_ptr, static_type) 7861309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (info->path_dynamic_ptr_to_static_ptr != public_path) 7871309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->path_dynamic_ptr_to_static_ptr = path_below; 7881309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant } 789152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant} 790152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant 7911309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// Call this function when searching below a dst_type node. This function searches 7921309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// for a path to (static_ptr, static_type) and for paths to one or more dst_type nodes. 7931309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// If it finds a static_type node, there is no need to further search base classes 7941309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// above. 7951309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// If it finds a dst_type node it should search base classes using search_above_dst 7961309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// to find out if this dst_type points to (static_ptr, static_type) or not. 797cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant// Either way, the dst_type is recorded as one of two "flavors": one that does 7981309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// or does not point to (static_ptr, static_type). 7991309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// If this is neither a static_type nor a dst_type node, continue searching 8001309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// base classes above. 8011309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// All the hoopla surrounding the search code is doing nothing but looking for 802facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// excuses to stop the search prematurely (break out of the for-loop). That is, 803facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// the algorithm below is simply an optimization of this: 804facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// void 805facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, 806facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// const void* current_ptr, 807facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// int path_below) const 808facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// { 809facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// typedef const __base_class_type_info* Iter; 810facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// if (this == info->static_type) 811facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// process_static_type_below_dst(info, current_ptr, path_below); 812facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// else if (this == info->dst_type) 813facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// { 814facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// // Record the most public access path that got us here 815facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// if (info->path_dynamic_ptr_to_dst_ptr != public_path) 816facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// info->path_dynamic_ptr_to_dst_ptr = path_below; 817facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// bool does_dst_type_point_to_our_static_type = false; 818facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// for (Iter p = __base_info, e= __base_info + __base_count; p < e; ++p) 819facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// { 820facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// p->search_above_dst(info, current_ptr, current_ptr, public_path); 821facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// if (info->found_our_static_ptr) 822facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// does_dst_type_point_to_our_static_type = true; 823facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// // break out early here if you can detect it doesn't matter if you do 824facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// } 825facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// if (!does_dst_type_point_to_our_static_type) 826facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// { 827facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// // We found a dst_type that doesn't point to (static_ptr, static_type) 828facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// // So record the address of this dst_ptr and increment the 829facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// // count of the number of such dst_types found in the tree. 830facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// info->dst_ptr_not_leading_to_static_ptr = current_ptr; 831facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// info->number_to_dst_ptr += 1; 832facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// } 833facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// } 834facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// else 835facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// { 836facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// // This is not a static_type and not a dst_type. 837facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// for (Iter p = __base_info, e = __base_info + __base_count; p < e; ++p) 838facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// { 839facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// p->search_below_dst(info, current_ptr, public_path); 840facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// // break out early here if you can detect it doesn't matter if you do 841facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// } 842facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// } 843facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// } 8441309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnantvoid 8451309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant__vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, 8461309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant const void* current_ptr, 847326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant int path_below, 848326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant bool use_strcmp) const 849f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant{ 850f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant typedef const __base_class_type_info* Iter; 851326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant if (is_equal(this, info->static_type, use_strcmp)) 8521309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant process_static_type_below_dst(info, current_ptr, path_below); 853326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant else if (is_equal(this, info->dst_type, use_strcmp)) 854f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant { 8551309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // We've been here before if we've recorded current_ptr in one of these 8561309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // two places: 8571309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (current_ptr == info->dst_ptr_leading_to_static_ptr || 8581309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant current_ptr == info->dst_ptr_not_leading_to_static_ptr) 859f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant { 8601309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // We've seen this node before, and therefore have already searched 8611309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // its base classes above. 8621309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // Update path to here that is "most public". 8631309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (path_below == public_path) 8641309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->path_dynamic_ptr_to_dst_ptr = public_path; 8651309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant } 8661309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant else // We have haven't been here before 8671309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant { 8681309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // Record the access path that got us here 8691309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // If there is more than one dst_type this path doesn't matter. 8701309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->path_dynamic_ptr_to_dst_ptr = path_below; 8711309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // Only search above here if dst_type derives from static_type, or 8721309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // if it is unknown if dst_type derives from static_type. 8731309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (info->is_dst_type_derived_from_static_type != no) 8741309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant { 8751309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // Set up flags to record results from all base classes 8761309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant bool is_dst_type_derived_from_static_type = false; 8771309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant bool does_dst_type_point_to_our_static_type = false; 8781309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // We've found a dst_type with a potentially public path to here. 8791309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // We have to assume the path is public because it may become 8801309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // public later (if we get back to here with a public path). 8811309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // We can stop looking above if: 8821309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // 1. We've found a public path to (static_ptr, static_type). 8831309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // 2. We've found an ambiguous cast from (static_ptr, static_type) to a dst_type. 8841309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // This is detected at the (static_ptr, static_type). 8851309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // 3. We can prove that there is no public path to (static_ptr, static_type) 8861309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // above here. 8871309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant const Iter e = __base_info + __base_count; 8881309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant for (Iter p = __base_info; p < e; ++p) 8891309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant { 8901309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // Zero out found flags 8911309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->found_our_static_ptr = false; 8921309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->found_any_static_type = false; 893326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant p->search_above_dst(info, current_ptr, current_ptr, public_path, use_strcmp); 894cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant if (info->search_done) 8951309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant break; 8961309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (info->found_any_static_type) 8971309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant { 8981309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant is_dst_type_derived_from_static_type = true; 8991309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (info->found_our_static_ptr) 9001309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant { 9011309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant does_dst_type_point_to_our_static_type = true; 9021309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // If we found what we're looking for, stop looking above. 9031309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (info->path_dst_ptr_to_static_ptr == public_path) 9041309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant break; 9051309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // We found a private path to (static_ptr, static_type) 9061309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // If there is no diamond then there is only one path 9071309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // to (static_ptr, static_type) and we just found it. 9081309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (!(__flags & __diamond_shaped_mask)) 9091309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant break; 9101309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant } 9111309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant else 9121309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant { 9131309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // If we found a static_type that isn't the one we're looking 9141309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // for, and if there are no repeated types above here, 9151309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // then stop looking. 9161309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (!(__flags & __non_diamond_repeat_mask)) 9171309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant break; 9181309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant } 9191309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant } 9201309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant } 9211309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (!does_dst_type_point_to_our_static_type) 9221309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant { 9231309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // We found a dst_type that doesn't point to (static_ptr, static_type) 9241309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // So record the address of this dst_ptr and increment the 9251309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // count of the number of such dst_types found in the tree. 9261309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->dst_ptr_not_leading_to_static_ptr = current_ptr; 9271309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->number_to_dst_ptr += 1; 9281309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // If there exists another dst with a private path to 9291309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // (static_ptr, static_type), then the cast from 9301309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // (dynamic_ptr, dynamic_type) to dst_type is now ambiguous, 9311309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // so stop search. 9321309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (info->number_to_static_ptr == 1 && 9331309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->path_dst_ptr_to_static_ptr == not_public_path) 9341309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->search_done = true; 9351309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant } 9361309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // If we found no static_type,s then dst_type doesn't derive 9371309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // from static_type, else it does. Record this result so that 9381309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // next time we hit a dst_type we will know not to search above 9391309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // it if it doesn't derive from static_type. 9401309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (is_dst_type_derived_from_static_type) 9411309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->is_dst_type_derived_from_static_type = yes; 9421309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant else 9431309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->is_dst_type_derived_from_static_type = no; 9441309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant } 945f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant } 946f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant } 9471309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant else 948271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant { 9491309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // This is not a static_type and not a dst_type. 9501309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant const Iter e = __base_info + __base_count; 95165255631de793131622f701df9075dfd78abfc50Howard Hinnant Iter p = __base_info; 952326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant p->search_below_dst(info, current_ptr, path_below, use_strcmp); 95365255631de793131622f701df9075dfd78abfc50Howard Hinnant if (++p < e) 9541309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant { 95565255631de793131622f701df9075dfd78abfc50Howard Hinnant if ((__flags & __diamond_shaped_mask) || info->number_to_static_ptr == 1) 9561309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant { 95765255631de793131622f701df9075dfd78abfc50Howard Hinnant // If there are multiple paths to a base above from here, or if 95865255631de793131622f701df9075dfd78abfc50Howard Hinnant // a dst_type pointing to (static_ptr, static_type) has been found, 95965255631de793131622f701df9075dfd78abfc50Howard Hinnant // then there is no way to break out of this loop early unless 96065255631de793131622f701df9075dfd78abfc50Howard Hinnant // something below detects the search is done. 96165255631de793131622f701df9075dfd78abfc50Howard Hinnant do 96265255631de793131622f701df9075dfd78abfc50Howard Hinnant { 96365255631de793131622f701df9075dfd78abfc50Howard Hinnant if (info->search_done) 96465255631de793131622f701df9075dfd78abfc50Howard Hinnant break; 965326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant p->search_below_dst(info, current_ptr, path_below, use_strcmp); 96665255631de793131622f701df9075dfd78abfc50Howard Hinnant } while (++p < e); 9671309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant } 96865255631de793131622f701df9075dfd78abfc50Howard Hinnant else if (__flags & __non_diamond_repeat_mask) 969271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant { 97065255631de793131622f701df9075dfd78abfc50Howard Hinnant // There are not multiple paths to any base class from here and a 97165255631de793131622f701df9075dfd78abfc50Howard Hinnant // dst_type pointing to (static_ptr, static_type) has not yet been 97265255631de793131622f701df9075dfd78abfc50Howard Hinnant // found. 97365255631de793131622f701df9075dfd78abfc50Howard Hinnant do 97465255631de793131622f701df9075dfd78abfc50Howard Hinnant { 97565255631de793131622f701df9075dfd78abfc50Howard Hinnant if (info->search_done) 97665255631de793131622f701df9075dfd78abfc50Howard Hinnant break; 97765255631de793131622f701df9075dfd78abfc50Howard Hinnant // If we just found a dst_type with a public path to (static_ptr, static_type), 97865255631de793131622f701df9075dfd78abfc50Howard Hinnant // then the only reason to continue the search is to make sure 97965255631de793131622f701df9075dfd78abfc50Howard Hinnant // no other dst_type points to (static_ptr, static_type). 98065255631de793131622f701df9075dfd78abfc50Howard Hinnant // If !diamond, then we don't need to search here. 98165255631de793131622f701df9075dfd78abfc50Howard Hinnant if (info->number_to_static_ptr == 1 && 98265255631de793131622f701df9075dfd78abfc50Howard Hinnant info->path_dst_ptr_to_static_ptr == public_path) 98365255631de793131622f701df9075dfd78abfc50Howard Hinnant break; 984326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant p->search_below_dst(info, current_ptr, path_below, use_strcmp); 98565255631de793131622f701df9075dfd78abfc50Howard Hinnant } while (++p < e); 986271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant } 98765255631de793131622f701df9075dfd78abfc50Howard Hinnant else 988271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant { 98965255631de793131622f701df9075dfd78abfc50Howard Hinnant // There are no repeated types above this node. 99065255631de793131622f701df9075dfd78abfc50Howard Hinnant // There are no nodes with multiple parents above this node. 99165255631de793131622f701df9075dfd78abfc50Howard Hinnant // no dst_type has been found to (static_ptr, static_type) 99265255631de793131622f701df9075dfd78abfc50Howard Hinnant do 99365255631de793131622f701df9075dfd78abfc50Howard Hinnant { 99465255631de793131622f701df9075dfd78abfc50Howard Hinnant if (info->search_done) 99565255631de793131622f701df9075dfd78abfc50Howard Hinnant break; 99665255631de793131622f701df9075dfd78abfc50Howard Hinnant // If we just found a dst_type with a public path to (static_ptr, static_type), 99765255631de793131622f701df9075dfd78abfc50Howard Hinnant // then the only reason to continue the search is to make sure sure 99865255631de793131622f701df9075dfd78abfc50Howard Hinnant // no other dst_type points to (static_ptr, static_type). 99965255631de793131622f701df9075dfd78abfc50Howard Hinnant // If !diamond, then we don't need to search here. 100065255631de793131622f701df9075dfd78abfc50Howard Hinnant // if we just found a dst_type with a private path to (static_ptr, static_type), 100165255631de793131622f701df9075dfd78abfc50Howard Hinnant // then we're only looking for a public path to (static_ptr, static_type) 100265255631de793131622f701df9075dfd78abfc50Howard Hinnant // and to check for other dst_types. 100365255631de793131622f701df9075dfd78abfc50Howard Hinnant // If !diamond & !repeat, then there is not a pointer to (static_ptr, static_type) 100465255631de793131622f701df9075dfd78abfc50Howard Hinnant // and not a dst_type under here. 100565255631de793131622f701df9075dfd78abfc50Howard Hinnant if (info->number_to_static_ptr == 1) 100665255631de793131622f701df9075dfd78abfc50Howard Hinnant break; 1007326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant p->search_below_dst(info, current_ptr, path_below, use_strcmp); 100865255631de793131622f701df9075dfd78abfc50Howard Hinnant } while (++p < e); 1009271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant } 1010271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant } 1011271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant } 10121309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant} 10131309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant 10141309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// This is the same algorithm as __vmi_class_type_info::search_below_dst but 10151309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// simplified to the case that there is only a single base class. 10161309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnantvoid 10171309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant__si_class_type_info::search_below_dst(__dynamic_cast_info* info, 10181309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant const void* current_ptr, 1019326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant int path_below, 1020326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant bool use_strcmp) const 10211309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant{ 1022326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant if (is_equal(this, info->static_type, use_strcmp)) 10231309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant process_static_type_below_dst(info, current_ptr, path_below); 1024326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant else if (is_equal(this, info->dst_type, use_strcmp)) 1025f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant { 10261309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // We've been here before if we've recorded current_ptr in one of these 10271309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // two places: 10281309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (current_ptr == info->dst_ptr_leading_to_static_ptr || 10291309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant current_ptr == info->dst_ptr_not_leading_to_static_ptr) 1030f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant { 10311309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // We've seen this node before, and therefore have already searched 10321309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // its base classes above. 10331309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // Update path to here that is "most public". 1034f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant if (path_below == public_path) 1035f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant info->path_dynamic_ptr_to_dst_ptr = public_path; 1036f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant } 1037271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant else // We have haven't been here before 1038f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant { 1039271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant // Record the access path that got us here 10401309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // If there is more than one dst_type this path doesn't matter. 1041f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant info->path_dynamic_ptr_to_dst_ptr = path_below; 10421309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // Only search above here if dst_type derives from static_type, or 10431309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // if it is unknown if dst_type derives from static_type. 10441309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (info->is_dst_type_derived_from_static_type != no) 1045f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant { 10461309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // Set up flags to record results from all base classes 10471309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant bool is_dst_type_derived_from_static_type = false; 10481309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant bool does_dst_type_point_to_our_static_type = false; 10491309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // Zero out found flags 10501309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->found_our_static_ptr = false; 10511309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->found_any_static_type = false; 1052326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant __base_type->search_above_dst(info, current_ptr, current_ptr, public_path, use_strcmp); 10531309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (info->found_any_static_type) 1054f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant { 10551309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant is_dst_type_derived_from_static_type = true; 10561309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (info->found_our_static_ptr) 10571309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant does_dst_type_point_to_our_static_type = true; 1058f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant } 10591309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (!does_dst_type_point_to_our_static_type) 1060f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant { 10611309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // We found a dst_type that doesn't point to (static_ptr, static_type) 10621309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // So record the address of this dst_ptr and increment the 10631309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // count of the number of such dst_types found in the tree. 10641309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->dst_ptr_not_leading_to_static_ptr = current_ptr; 1065f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant info->number_to_dst_ptr += 1; 1066271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant // If there exists another dst with a private path to 1067271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant // (static_ptr, static_type), then the cast from 1068271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant // (dynamic_ptr, dynamic_type) to dst_type is now ambiguous. 1069271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant if (info->number_to_static_ptr == 1 && 10701309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->path_dst_ptr_to_static_ptr == not_public_path) 10711309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->search_done = true; 1072f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant } 10731309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // If we found no static_type,s then dst_type doesn't derive 10741309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // from static_type, else it does. Record this result so that 10751309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // next time we hit a dst_type we will know not to search above 10761309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // it if it doesn't derive from static_type. 10771309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (is_dst_type_derived_from_static_type) 10781309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->is_dst_type_derived_from_static_type = yes; 10791309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant else 10801309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->is_dst_type_derived_from_static_type = no; 1081f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant } 1082f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant } 1083f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant } 10841309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant else 1085f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant { 10861309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // This is not a static_type and not a dst_type 1087326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant __base_type->search_below_dst(info, current_ptr, path_below, use_strcmp); 1088f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant } 10891309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant} 10901309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant 10911309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// This is the same algorithm as __vmi_class_type_info::search_below_dst but 10921309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// simplified to the case that there is no base class. 10931309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnantvoid 10941309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant__class_type_info::search_below_dst(__dynamic_cast_info* info, 10951309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant const void* current_ptr, 1096326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant int path_below, 1097326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant bool use_strcmp) const 10981309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant{ 1099326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant if (is_equal(this, info->static_type, use_strcmp)) 11001309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant process_static_type_below_dst(info, current_ptr, path_below); 1101326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant else if (is_equal(this, info->dst_type, use_strcmp)) 1102f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant { 11031309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // We've been here before if we've recorded current_ptr in one of these 11041309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // two places: 11051309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (current_ptr == info->dst_ptr_leading_to_static_ptr || 11061309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant current_ptr == info->dst_ptr_not_leading_to_static_ptr) 11071309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant { 11081309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // We've seen this node before, and therefore have already searched 11091309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // its base classes above. 11101309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // Update path to here that is "most public". 11111309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (path_below == public_path) 11121309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->path_dynamic_ptr_to_dst_ptr = public_path; 11131309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant } 11141309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant else // We have haven't been here before 1115271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant { 11161309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // Record the access path that got us here 11171309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // If there is more than one dst_type this path doesn't matter. 11181309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->path_dynamic_ptr_to_dst_ptr = path_below; 11191309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // We found a dst_type that doesn't point to (static_ptr, static_type) 11201309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // So record the address of this dst_ptr and increment the 11211309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // count of the number of such dst_types found in the tree. 11221309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->dst_ptr_not_leading_to_static_ptr = current_ptr; 11231309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->number_to_dst_ptr += 1; 11241309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // If there exists another dst with a private path to 11251309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // (static_ptr, static_type), then the cast from 11261309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // (dynamic_ptr, dynamic_type) to dst_type is now ambiguous. 1127271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant if (info->number_to_static_ptr == 1 && 11281309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->path_dst_ptr_to_static_ptr == not_public_path) 11291309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->search_done = true; 11301309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // We found that dst_type does not derive from static_type 11311309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->is_dst_type_derived_from_static_type = no; 1132271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant } 1133271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant } 11341309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant} 11351309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant 11361309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// Call this function when searching above a dst_type node. This function searches 11371309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// for a public path to (static_ptr, static_type). 11381309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// This function is guaranteed not to find a node of type dst_type. 11391309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// Theoretically this is a very simple function which just stops if it finds a 1140facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// static_type node: All the hoopla surrounding the search code is doing 1141facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// nothing but looking for excuses to stop the search prematurely (break out of 1142facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// the for-loop). That is, the algorithm below is simply an optimization of this: 1143facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// void 1144facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// __vmi_class_type_info::search_above_dst(__dynamic_cast_info* info, 1145facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// const void* dst_ptr, 1146facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// const void* current_ptr, 1147facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// int path_below) const 1148facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// { 1149facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// if (this == info->static_type) 1150facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); 1151facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// else 1152facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// { 1153facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// typedef const __base_class_type_info* Iter; 1154facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// // This is not a static_type and not a dst_type 1155facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// for (Iter p = __base_info, e = __base_info + __base_count; p < e; ++p) 1156facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// { 1157facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// p->search_above_dst(info, dst_ptr, current_ptr, public_path); 1158facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// // break out early here if you can detect it doesn't matter if you do 1159facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// } 1160facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// } 1161facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant// } 11621309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnantvoid 11631309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant__vmi_class_type_info::search_above_dst(__dynamic_cast_info* info, 11641309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant const void* dst_ptr, 11651309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant const void* current_ptr, 1166326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant int path_below, 1167326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant bool use_strcmp) const 11681309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant{ 1169326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant if (is_equal(this, info->static_type, use_strcmp)) 11701309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); 1171271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant else 1172271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant { 11731309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant typedef const __base_class_type_info* Iter; 11741309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // This is not a static_type and not a dst_type 11751309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // Save flags so they can be restored when returning to nodes below. 11761309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant bool found_our_static_ptr = info->found_our_static_ptr; 11771309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant bool found_any_static_type = info->found_any_static_type; 11781309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // We've found a dst_type below with a path to here. If the path 11791309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // to here is not public, there may be another path to here that 11801309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // is public. So we have to assume that the path to here is public. 11811309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // We can stop looking above if: 11821309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // 1. We've found a public path to (static_ptr, static_type). 11831309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // 2. We've found an ambiguous cast from (static_ptr, static_type) to a dst_type. 11841309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // This is detected at the (static_ptr, static_type). 11851309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // 3. We can prove that there is no public path to (static_ptr, static_type) 11861309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // above here. 11871309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant const Iter e = __base_info + __base_count; 118865255631de793131622f701df9075dfd78abfc50Howard Hinnant Iter p = __base_info; 118965255631de793131622f701df9075dfd78abfc50Howard Hinnant // Zero out found flags 119065255631de793131622f701df9075dfd78abfc50Howard Hinnant info->found_our_static_ptr = false; 119165255631de793131622f701df9075dfd78abfc50Howard Hinnant info->found_any_static_type = false; 1192326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant p->search_above_dst(info, dst_ptr, current_ptr, path_below, use_strcmp); 119365255631de793131622f701df9075dfd78abfc50Howard Hinnant if (++p < e) 1194271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant { 119565255631de793131622f701df9075dfd78abfc50Howard Hinnant do 11961309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant { 119765255631de793131622f701df9075dfd78abfc50Howard Hinnant if (info->search_done) 11981309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant break; 119965255631de793131622f701df9075dfd78abfc50Howard Hinnant if (info->found_our_static_ptr) 120065255631de793131622f701df9075dfd78abfc50Howard Hinnant { 120165255631de793131622f701df9075dfd78abfc50Howard Hinnant // If we found what we're looking for, stop looking above. 120265255631de793131622f701df9075dfd78abfc50Howard Hinnant if (info->path_dst_ptr_to_static_ptr == public_path) 120365255631de793131622f701df9075dfd78abfc50Howard Hinnant break; 120465255631de793131622f701df9075dfd78abfc50Howard Hinnant // We found a private path to (static_ptr, static_type) 120565255631de793131622f701df9075dfd78abfc50Howard Hinnant // If there is no diamond then there is only one path 120665255631de793131622f701df9075dfd78abfc50Howard Hinnant // to (static_ptr, static_type) from here and we just found it. 120765255631de793131622f701df9075dfd78abfc50Howard Hinnant if (!(__flags & __diamond_shaped_mask)) 120865255631de793131622f701df9075dfd78abfc50Howard Hinnant break; 120965255631de793131622f701df9075dfd78abfc50Howard Hinnant } 121065255631de793131622f701df9075dfd78abfc50Howard Hinnant else if (info->found_any_static_type) 121165255631de793131622f701df9075dfd78abfc50Howard Hinnant { 121265255631de793131622f701df9075dfd78abfc50Howard Hinnant // If we found a static_type that isn't the one we're looking 121365255631de793131622f701df9075dfd78abfc50Howard Hinnant // for, and if there are no repeated types above here, 121465255631de793131622f701df9075dfd78abfc50Howard Hinnant // then stop looking. 121565255631de793131622f701df9075dfd78abfc50Howard Hinnant if (!(__flags & __non_diamond_repeat_mask)) 121665255631de793131622f701df9075dfd78abfc50Howard Hinnant break; 121765255631de793131622f701df9075dfd78abfc50Howard Hinnant } 121865255631de793131622f701df9075dfd78abfc50Howard Hinnant // Zero out found flags 121965255631de793131622f701df9075dfd78abfc50Howard Hinnant info->found_our_static_ptr = false; 122065255631de793131622f701df9075dfd78abfc50Howard Hinnant info->found_any_static_type = false; 1221326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant p->search_above_dst(info, dst_ptr, current_ptr, path_below, use_strcmp); 122265255631de793131622f701df9075dfd78abfc50Howard Hinnant } while (++p < e); 1223271f1ac649aac4c80df7534270b19f3fbdce9c5dHoward Hinnant } 12241309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant // Restore flags 12251309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->found_our_static_ptr = found_our_static_ptr; 12261309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant info->found_any_static_type = found_any_static_type; 1227f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant } 1228185dc7d61ff4e58909f043f3a0c0d7d1d87ba7daHoward Hinnant} 1229185dc7d61ff4e58909f043f3a0c0d7d1d87ba7daHoward Hinnant 12301309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// This is the same algorithm as __vmi_class_type_info::search_above_dst but 12311309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// simplified to the case that there is only a single base class. 12321309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnantvoid 12331309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant__si_class_type_info::search_above_dst(__dynamic_cast_info* info, 12341309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant const void* dst_ptr, 12351309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant const void* current_ptr, 1236326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant int path_below, 1237326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant bool use_strcmp) const 1238f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant{ 1239326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant if (is_equal(this, info->static_type, use_strcmp)) 12401309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); 12411309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant else 1242326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant __base_type->search_above_dst(info, dst_ptr, current_ptr, path_below, use_strcmp); 1243f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant} 1244f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant 12451309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// This is the same algorithm as __vmi_class_type_info::search_above_dst but 12461309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// simplified to the case that there is no base class. 124716650b58dfc7d1a2632b052843dc4e21ae949b07Howard Hinnantvoid 12481309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant__class_type_info::search_above_dst(__dynamic_cast_info* info, 12491309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant const void* dst_ptr, 12501309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant const void* current_ptr, 1251326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant int path_below, 1252326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant bool use_strcmp) const 125316650b58dfc7d1a2632b052843dc4e21ae949b07Howard Hinnant{ 1254326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant if (is_equal(this, info->static_type, use_strcmp)) 12551309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); 125616650b58dfc7d1a2632b052843dc4e21ae949b07Howard Hinnant} 125716650b58dfc7d1a2632b052843dc4e21ae949b07Howard Hinnant 12581309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// The search functions for __base_class_type_info are simply convenience 12591309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// functions for adjusting the current_ptr and path_below as the search is 12601309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant// passed up to the base class node. 12611309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant 126216650b58dfc7d1a2632b052843dc4e21ae949b07Howard Hinnantvoid 12631309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant__base_class_type_info::search_above_dst(__dynamic_cast_info* info, 12641309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant const void* dst_ptr, 12651309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant const void* current_ptr, 1266326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant int path_below, 1267326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant bool use_strcmp) const 126816650b58dfc7d1a2632b052843dc4e21ae949b07Howard Hinnant{ 126916650b58dfc7d1a2632b052843dc4e21ae949b07Howard Hinnant ptrdiff_t offset_to_base = __offset_flags >> __offset_shift; 127016650b58dfc7d1a2632b052843dc4e21ae949b07Howard Hinnant if (__offset_flags & __virtual_mask) 127116650b58dfc7d1a2632b052843dc4e21ae949b07Howard Hinnant { 1272cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant const char* vtable = *static_cast<const char*const*>(current_ptr); 1273cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base); 127416650b58dfc7d1a2632b052843dc4e21ae949b07Howard Hinnant } 12751309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant __base_type->search_above_dst(info, dst_ptr, 1276cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant static_cast<const char*>(current_ptr) + offset_to_base, 12771309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant (__offset_flags & __public_mask) ? 12781309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant path_below : 1279326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant not_public_path, 1280326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant use_strcmp); 1281152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant} 1282152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant 12831309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnantvoid 12841309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant__base_class_type_info::search_below_dst(__dynamic_cast_info* info, 12851309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant const void* current_ptr, 1286326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant int path_below, 1287326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant bool use_strcmp) const 128816650b58dfc7d1a2632b052843dc4e21ae949b07Howard Hinnant{ 12891309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant ptrdiff_t offset_to_base = __offset_flags >> __offset_shift; 12901309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant if (__offset_flags & __virtual_mask) 1291f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant { 1292cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant const char* vtable = *static_cast<const char*const*>(current_ptr); 1293cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base); 1294f877d21f16d5ecb32570a89148e614ff68d632beHoward Hinnant } 12951309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant __base_type->search_below_dst(info, 1296cc614df38c199d9781a6dea123e714970e82711fHoward Hinnant static_cast<const char*>(current_ptr) + offset_to_base, 12971309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant (__offset_flags & __public_mask) ? 12981309366d3676ca5a34bea0388ad2d2dd5701dc9bHoward Hinnant path_below : 1299326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant not_public_path, 1300326aca3713db53b9fb0dbfedc17d2e72aaca8a74Howard Hinnant use_strcmp); 130116650b58dfc7d1a2632b052843dc4e21ae949b07Howard Hinnant} 130216650b58dfc7d1a2632b052843dc4e21ae949b07Howard Hinnant 1303facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant#pragma GCC visibility pop 1304facfc46ef3ecde55e675fa19d93d9a25b169c49fHoward Hinnant 1305152beb7a421a05155ae339434c2b48e2151111cdHoward Hinnant} // __cxxabiv1 1306