198944Sobrien// Methods for type_info for -*- C++ -*- Run Time Type Identification. 298944Sobrien 3130803Smarcel// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002 4130803Smarcel// Free Software Foundation 598944Sobrien// 698944Sobrien// This file is part of GCC. 798944Sobrien// 898944Sobrien// GCC is free software; you can redistribute it and/or modify 998944Sobrien// it under the terms of the GNU General Public License as published by 1098944Sobrien// the Free Software Foundation; either version 2, or (at your option) 1198944Sobrien// any later version. 1298944Sobrien 1398944Sobrien// GCC is distributed in the hope that it will be useful, 1498944Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1598944Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1698944Sobrien// GNU General Public License for more details. 1798944Sobrien 1898944Sobrien// You should have received a copy of the GNU General Public License 1998944Sobrien// along with GCC; see the file COPYING. If not, write to 2098944Sobrien// the Free Software Foundation, 51 Franklin Street, Fifth Floor, 2198944Sobrien// Boston, MA 02110-1301, USA. 2298944Sobrien 2398944Sobrien// As a special exception, you may use this file as part of a free software 2498944Sobrien// library without restriction. Specifically, if other files instantiate 2598944Sobrien// templates or use macros or inline functions from this file, or you compile 2698944Sobrien// this file and link it with other files to produce an executable, this 2798944Sobrien// file does not by itself cause the resulting executable to be covered by 2898944Sobrien// the GNU General Public License. This exception does not however 2998944Sobrien// invalidate any other reasons why the executable file might be covered by 3098944Sobrien// the GNU General Public License. 3198944Sobrien 3298944Sobrien#include <cstddef> 3398944Sobrien#include "tinfo.h" 3498944Sobrien#include "new" // for placement new 3598944Sobrien 3698944Sobrien// We can't rely on having stdlib.h if we're freestanding. 3798944Sobrienextern "C" void abort (); 3898944Sobrien 3998944Sobrienusing std::type_info; 4098944Sobrien 4198944Sobrien#if !__GXX_MERGED_TYPEINFO_NAMES 4298944Sobrien 4398944Sobrienbool 4498944Sobrientype_info::before (const type_info &arg) const 4598944Sobrien{ 4698944Sobrien return __builtin_strcmp (name (), arg.name ()) < 0; 4798944Sobrien} 4898944Sobrien 4998944Sobrien#endif 5098944Sobrien 5198944Sobrien#include <cxxabi.h> 5298944Sobrien 5398944Sobriennamespace __cxxabiv1 { 5498944Sobrien 5598944Sobrienusing namespace std; 5698944Sobrien 5798944Sobrien// This has special meaning to the compiler, and will cause it 5898944Sobrien// to emit the type_info structures for the fundamental types which are 5998944Sobrien// mandated to exist in the runtime. 6098944Sobrien__fundamental_type_info:: 6198944Sobrien~__fundamental_type_info () 6298944Sobrien{} 6398944Sobrien 6498944Sobrien__array_type_info:: 6598944Sobrien~__array_type_info () 6698944Sobrien{} 6798944Sobrien 6898944Sobrien__function_type_info:: 6998944Sobrien~__function_type_info () 7098944Sobrien{} 7198944Sobrien 7298944Sobrien__enum_type_info:: 7398944Sobrien~__enum_type_info () 7498944Sobrien{} 7598944Sobrien 7698944Sobrien__pbase_type_info:: 7798944Sobrien~__pbase_type_info () 7898944Sobrien{} 7998944Sobrien 8098944Sobrien__pointer_type_info:: 8198944Sobrien~__pointer_type_info () 8298944Sobrien{} 8398944Sobrien 8498944Sobrien__pointer_to_member_type_info:: 8598944Sobrien~__pointer_to_member_type_info () 8698944Sobrien{} 8798944Sobrien 8898944Sobrienbool __pointer_type_info:: 8998944Sobrien__is_pointer_p () const 9098944Sobrien{ 9198944Sobrien return true; 9298944Sobrien} 9398944Sobrien 9498944Sobrienbool __function_type_info:: 9598944Sobrien__is_function_p () const 9698944Sobrien{ 9798944Sobrien return true; 9898944Sobrien} 9998944Sobrien 10098944Sobrienbool __pbase_type_info:: 10198944Sobrien__do_catch (const type_info *thr_type, 10298944Sobrien void **thr_obj, 10398944Sobrien unsigned outer) const 10498944Sobrien{ 10598944Sobrien if (*this == *thr_type) 10698944Sobrien return true; // same type 10798944Sobrien if (typeid (*this) != typeid (*thr_type)) 10898944Sobrien return false; // not both same kind of pointers 10998944Sobrien 11098944Sobrien if (!(outer & 1)) 11198944Sobrien // We're not the same and our outer pointers are not all const qualified 11298944Sobrien // Therefore there must at least be a qualification conversion involved 11398944Sobrien // But for that to be valid, our outer pointers must be const qualified. 11498944Sobrien return false; 11598944Sobrien 11698944Sobrien const __pbase_type_info *thrown_type = 11798944Sobrien static_cast <const __pbase_type_info *> (thr_type); 11898944Sobrien 11998944Sobrien if (thrown_type->__flags & ~__flags) 12098944Sobrien // We're less qualified. 12198944Sobrien return false; 122130803Smarcel 123130803Smarcel if (!(__flags & __const_mask)) 124130803Smarcel outer &= ~1; 125130803Smarcel 126130803Smarcel return __pointer_catch (thrown_type, thr_obj, outer); 127130803Smarcel} 128130803Smarcel 129130803Smarcelinline bool __pbase_type_info:: 130130803Smarcel__pointer_catch (const __pbase_type_info *thrown_type, 131130803Smarcel void **thr_obj, 132130803Smarcel unsigned outer) const 133130803Smarcel{ 134130803Smarcel return __pointee->__do_catch (thrown_type->__pointee, thr_obj, outer + 2); 135130803Smarcel} 136130803Smarcel 137130803Smarcelbool __pointer_type_info:: 138130803Smarcel__pointer_catch (const __pbase_type_info *thrown_type, 139130803Smarcel void **thr_obj, 140130803Smarcel unsigned outer) const 141130803Smarcel{ 142130803Smarcel if (outer < 2 && *__pointee == typeid (void)) 143130803Smarcel { 144130803Smarcel // conversion to void 145130803Smarcel return !thrown_type->__pointee->__is_function_p (); 146130803Smarcel } 147130803Smarcel 148130803Smarcel return __pbase_type_info::__pointer_catch (thrown_type, thr_obj, outer); 149130803Smarcel} 150130803Smarcel 151130803Smarcelbool __pointer_to_member_type_info:: 15298944Sobrien__pointer_catch (const __pbase_type_info *thr_type, 15398944Sobrien void **thr_obj, 15498944Sobrien unsigned outer) const 15598944Sobrien{ 15698944Sobrien // This static cast is always valid, as our caller will have determined that 15798944Sobrien // thr_type is really a __pointer_to_member_type_info. 15898944Sobrien const __pointer_to_member_type_info *thrown_type = 15998944Sobrien static_cast <const __pointer_to_member_type_info *> (thr_type); 16098944Sobrien 16198944Sobrien if (*__context != *thrown_type->__context) 16298944Sobrien return false; // not pointers to member of same class 16398944Sobrien 16498944Sobrien return __pbase_type_info::__pointer_catch (thrown_type, thr_obj, outer); 16598944Sobrien} 16698944Sobrien 167130803Smarcel} // namespace std 168130803Smarcel