tinfo2.cc revision 97403
197403Sobrien// Methods for type_info for -*- C++ -*- Run Time Type Identification. 297403Sobrien 397403Sobrien// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001 497403Sobrien// Free Software Foundation 597403Sobrien// 697403Sobrien// This file is part of GNU CC. 797403Sobrien// 897403Sobrien// GNU CC is free software; you can redistribute it and/or modify 997403Sobrien// it under the terms of the GNU General Public License as published by 1097403Sobrien// the Free Software Foundation; either version 2, or (at your option) 1197403Sobrien// any later version. 1297403Sobrien 1397403Sobrien// GNU CC is distributed in the hope that it will be useful, 1497403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1597403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1697403Sobrien// GNU General Public License for more details. 1797403Sobrien 1897403Sobrien// You should have received a copy of the GNU General Public License 1997403Sobrien// along with GNU CC; see the file COPYING. If not, write to 2097403Sobrien// the Free Software Foundation, 59 Temple Place - Suite 330, 2197403Sobrien// Boston, MA 02111-1307, USA. 2297403Sobrien 2397403Sobrien// As a special exception, you may use this file as part of a free software 2497403Sobrien// library without restriction. Specifically, if other files instantiate 2597403Sobrien// templates or use macros or inline functions from this file, or you compile 2697403Sobrien// this file and link it with other files to produce an executable, this 2797403Sobrien// file does not by itself cause the resulting executable to be covered by 2897403Sobrien// the GNU General Public License. This exception does not however 2997403Sobrien// invalidate any other reasons why the executable file might be covered by 3097403Sobrien// the GNU General Public License. 3197403Sobrien 3297403Sobrien#include <cstddef> 3397403Sobrien#include "tinfo.h" 3497403Sobrien#include "new" // for placement new 3597403Sobrien 3697403Sobrien// We can't rely on having stdlib.h if we're freestanding. 3797403Sobrienextern "C" void abort (); 3897403Sobrien 3997403Sobrienusing std::type_info; 4097403Sobrien 4197403Sobrien#if !__GXX_MERGED_TYPEINFO_NAMES 4297403Sobrien 4397403Sobrienbool 4497403Sobrientype_info::before (const type_info &arg) const 4597403Sobrien{ 4697403Sobrien return __builtin_strcmp (name (), arg.name ()) < 0; 4797403Sobrien} 4897403Sobrien 4997403Sobrien#endif 5097403Sobrien 5197403Sobrien#include <cxxabi.h> 5297403Sobrien 5397403Sobriennamespace __cxxabiv1 { 5497403Sobrien 5597403Sobrienusing namespace std; 5697403Sobrien 5797403Sobrien// This has special meaning to the compiler, and will cause it 5897403Sobrien// to emit the type_info structures for the fundamental types which are 5997403Sobrien// mandated to exist in the runtime. 6097403Sobrien__fundamental_type_info:: 6197403Sobrien~__fundamental_type_info () 6297403Sobrien{} 6397403Sobrien 6497403Sobrien__array_type_info:: 6597403Sobrien~__array_type_info () 6697403Sobrien{} 6797403Sobrien 6897403Sobrien__function_type_info:: 6997403Sobrien~__function_type_info () 7097403Sobrien{} 7197403Sobrien 7297403Sobrien__enum_type_info:: 7397403Sobrien~__enum_type_info () 7497403Sobrien{} 7597403Sobrien 7697403Sobrien__pbase_type_info:: 7797403Sobrien~__pbase_type_info () 7897403Sobrien{} 7997403Sobrien 8097403Sobrien__pointer_type_info:: 8197403Sobrien~__pointer_type_info () 8297403Sobrien{} 8397403Sobrien 8497403Sobrien__pointer_to_member_type_info:: 8597403Sobrien~__pointer_to_member_type_info () 8697403Sobrien{} 8797403Sobrien 8897403Sobrienbool __pointer_type_info:: 8997403Sobrien__is_pointer_p () const 9097403Sobrien{ 9197403Sobrien return true; 9297403Sobrien} 9397403Sobrien 9497403Sobrienbool __function_type_info:: 9597403Sobrien__is_function_p () const 9697403Sobrien{ 9797403Sobrien return true; 9897403Sobrien} 9997403Sobrien 10097403Sobrienbool __pbase_type_info:: 10197403Sobrien__do_catch (const type_info *thr_type, 10297403Sobrien void **thr_obj, 10397403Sobrien unsigned outer) const 10497403Sobrien{ 10597403Sobrien if (*this == *thr_type) 10697403Sobrien return true; // same type 10797403Sobrien if (typeid (*this) != typeid (*thr_type)) 10897403Sobrien return false; // not both same kind of pointers 10997403Sobrien 11097403Sobrien if (!(outer & 1)) 11197403Sobrien // We're not the same and our outer pointers are not all const qualified 11297403Sobrien // Therefore there must at least be a qualification conversion involved 11397403Sobrien // But for that to be valid, our outer pointers must be const qualified. 11497403Sobrien return false; 11597403Sobrien 11697403Sobrien const __pbase_type_info *thrown_type = 11797403Sobrien static_cast <const __pbase_type_info *> (thr_type); 11897403Sobrien 11997403Sobrien if (thrown_type->__qualifier_flags & ~__qualifier_flags) 12097403Sobrien // We're less qualified. 12197403Sobrien return false; 12297403Sobrien 12397403Sobrien if (!(__qualifier_flags & __const_mask)) 12497403Sobrien outer &= ~1; 12597403Sobrien 12697403Sobrien return __pointer_catch (thrown_type, thr_obj, outer); 12797403Sobrien} 12897403Sobrien 12997403Sobrieninline bool __pbase_type_info:: 13097403Sobrien__pointer_catch (const __pbase_type_info *thrown_type, 13197403Sobrien void **thr_obj, 13297403Sobrien unsigned outer) const 13397403Sobrien{ 13497403Sobrien return __pointee->__do_catch (thrown_type->__pointee, thr_obj, outer + 2); 13597403Sobrien} 13697403Sobrien 13797403Sobrienbool __pointer_type_info:: 13897403Sobrien__pointer_catch (const __pbase_type_info *thrown_type, 13997403Sobrien void **thr_obj, 14097403Sobrien unsigned outer) const 14197403Sobrien{ 14297403Sobrien if (outer < 2 && *__pointee == typeid (void)) 14397403Sobrien { 14497403Sobrien // conversion to void 14597403Sobrien return !thrown_type->__pointee->__is_function_p (); 14697403Sobrien } 14797403Sobrien 14897403Sobrien return __pbase_type_info::__pointer_catch (thrown_type, thr_obj, outer); 14997403Sobrien} 15097403Sobrien 15197403Sobrienbool __pointer_to_member_type_info:: 15297403Sobrien__pointer_catch (const __pbase_type_info *thr_type, 15397403Sobrien void **thr_obj, 15497403Sobrien unsigned outer) const 15597403Sobrien{ 15697403Sobrien // This static cast is always valid, as our caller will have determined that 15797403Sobrien // thr_type is really a __pointer_to_member_type_info. 15897403Sobrien const __pointer_to_member_type_info *thrown_type = 15997403Sobrien static_cast <const __pointer_to_member_type_info *> (thr_type); 16097403Sobrien 16197403Sobrien if (*__context_class != *thrown_type->__context_class) 16297403Sobrien return false; // not pointers to member of same class 16397403Sobrien 16497403Sobrien return __pbase_type_info::__pointer_catch (thrown_type, thr_obj, outer); 16597403Sobrien} 16697403Sobrien 16797403Sobrien} // namespace std 168