1 // Methods for type_info for -*- C++ -*- Run Time Type Identification. 2 3 // Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002 4 // Free Software Foundation 5 // 6 // This file is part of GCC. 7 // 8 // GCC is free software; you can redistribute it and/or modify 9 // it under the terms of the GNU General Public License as published by 10 // the Free Software Foundation; either version 2, or (at your option) 11 // any later version. 12 13 // GCC is distributed in the hope that it will be useful, 14 // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 // GNU General Public License for more details. 17 18 // You should have received a copy of the GNU General Public License 19 // along with GCC; see the file COPYING. If not, write to 20 // the Free Software Foundation, 51 Franklin Street, Fifth Floor, 21 // Boston, MA 02110-1301, USA. 22 23 // As a special exception, you may use this file as part of a free software 24 // library without restriction. Specifically, if other files instantiate 25 // templates or use macros or inline functions from this file, or you compile 26 // this file and link it with other files to produce an executable, this 27 // file does not by itself cause the resulting executable to be covered by 28 // the GNU General Public License. This exception does not however 29 // invalidate any other reasons why the executable file might be covered by 30 // the GNU General Public License. 31 32 #include <cstddef> 33 #include "tinfo.h" 34 #include "new" // for placement new 35 36 // We can't rely on having stdlib.h if we're freestanding. 37 extern "C" void abort (); 38 39 using std::type_info; 40 41 #if !__GXX_MERGED_TYPEINFO_NAMES 42 43 bool 44 type_info::before (const type_info &arg) const 45 { 46 return __builtin_strcmp (name (), arg.name ()) < 0; 47 } 48 49 #endif 50 51 #include <cxxabi.h> 52 53 namespace __cxxabiv1 { 54 55 using namespace std; 56 57 // This has special meaning to the compiler, and will cause it 58 // to emit the type_info structures for the fundamental types which are 59 // mandated to exist in the runtime. 60 __fundamental_type_info:: 61 ~__fundamental_type_info () 62 {} 63 64 __array_type_info:: 65 ~__array_type_info () 66 {} 67 68 __function_type_info:: 69 ~__function_type_info () 70 {} 71 72 __enum_type_info:: 73 ~__enum_type_info () 74 {} 75 76 __pbase_type_info:: 77 ~__pbase_type_info () 78 {} 79 80 __pointer_type_info:: 81 ~__pointer_type_info () 82 {} 83 84 __pointer_to_member_type_info:: 85 ~__pointer_to_member_type_info () 86 {} 87 88 bool __pointer_type_info:: 89 __is_pointer_p () const 90 { 91 return true; 92 } 93 94 bool __function_type_info:: 95 __is_function_p () const 96 { 97 return true; 98 } 99 100 bool __pbase_type_info:: 101 __do_catch (const type_info *thr_type, 102 void **thr_obj, 103 unsigned outer) const 104 { 105 if (*this == *thr_type) 106 return true; // same type 107 if (typeid (*this) != typeid (*thr_type)) 108 return false; // not both same kind of pointers 109 110 if (!(outer & 1)) 111 // We're not the same and our outer pointers are not all const qualified 112 // Therefore there must at least be a qualification conversion involved 113 // But for that to be valid, our outer pointers must be const qualified. 114 return false; 115 116 const __pbase_type_info *thrown_type = 117 static_cast <const __pbase_type_info *> (thr_type); 118 119 if (thrown_type->__flags & ~__flags) 120 // We're less qualified. 121 return false; 122 123 if (!(__flags & __const_mask)) 124 outer &= ~1; 125 126 return __pointer_catch (thrown_type, thr_obj, outer); 127 } 128 129 inline bool __pbase_type_info:: 130 __pointer_catch (const __pbase_type_info *thrown_type, 131 void **thr_obj, 132 unsigned outer) const 133 { 134 return __pointee->__do_catch (thrown_type->__pointee, thr_obj, outer + 2); 135 } 136 137 bool __pointer_type_info:: 138 __pointer_catch (const __pbase_type_info *thrown_type, 139 void **thr_obj, 140 unsigned outer) const 141 { 142 if (outer < 2 && *__pointee == typeid (void)) 143 { 144 // conversion to void 145 return !thrown_type->__pointee->__is_function_p (); 146 } 147 148 return __pbase_type_info::__pointer_catch (thrown_type, thr_obj, outer); 149 } 150 151 bool __pointer_to_member_type_info:: 152 __pointer_catch (const __pbase_type_info *thr_type, 153 void **thr_obj, 154 unsigned outer) const 155 { 156 // This static cast is always valid, as our caller will have determined that 157 // thr_type is really a __pointer_to_member_type_info. 158 const __pointer_to_member_type_info *thrown_type = 159 static_cast <const __pointer_to_member_type_info *> (thr_type); 160 161 if (*__context != *thrown_type->__context) 162 return false; // not pointers to member of same class 163 164 return __pbase_type_info::__pointer_catch (thrown_type, thr_obj, outer); 165 } 166 167 } // namespace std 168