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. 37extern "C" void abort (); 38 39using std::type_info; 40 41#if !__GXX_MERGED_TYPEINFO_NAMES 42 43bool 44type_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 53namespace __cxxabiv1 { 54 55using 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 88bool __pointer_type_info:: 89__is_pointer_p () const 90{ 91 return true; 92} 93 94bool __function_type_info:: 95__is_function_p () const 96{ 97 return true; 98} 99 100bool __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 129inline 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 137bool __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 151bool __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