1// Methods for type_info for -*- C++ -*- Run Time Type Identification. 2// Copyright (C) 1994, 1996, 1998 Free Software Foundation 3 4// This file is part of GNU CC. 5 6// GNU CC is free software; you can redistribute it and/or modify 7// it under the terms of the GNU General Public License as published by 8// the Free Software Foundation; either version 2, or (at your option) 9// any later version. 10 11// GNU CC is distributed in the hope that it will be useful, 12// but WITHOUT ANY WARRANTY; without even the implied warranty of 13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14// GNU General Public License for more details. 15 16// You should have received a copy of the GNU General Public License 17// along with GNU CC; see the file COPYING. If not, write to 18// the Free Software Foundation, 59 Temple Place - Suite 330, 19// Boston, MA 02111-1307, USA. 20 21// As a special exception, if you link this library with other files, 22// some of which are compiled with GCC, to produce an executable, 23// this library does not by itself cause the resulting executable 24// to be covered by the GNU General Public License. 25// This exception does not however invalidate any other reasons why 26// the executable file might be covered by the GNU General Public License. 27 28#pragma implementation "typeinfo" 29 30#include <stddef.h> 31#include "tinfo.h" 32#include "new" // for placement new 33 34// This file contains the minimal working set necessary to link with code 35// that uses virtual functions and -frtti but does not actually use RTTI 36// functionality. 37 38std::type_info:: 39~type_info () 40{ } 41 42// We can't rely on common symbols being shared between shared objects. 43bool std::type_info:: 44operator== (const std::type_info& arg) const 45{ 46 return (&arg == this) || (strcmp (name (), arg.name ()) == 0); 47} 48 49extern "C" void 50__rtti_class (void *addr, const char *name, 51 const __class_type_info::base_info *bl, size_t bn) 52{ new (addr) __class_type_info (name, bl, bn); } 53 54extern "C" void 55__rtti_si (void *addr, const char *n, const std::type_info *ti) 56{ 57 new (addr) __si_type_info 58 (n, static_cast <const __user_type_info &> (*ti)); 59} 60 61extern "C" void 62__rtti_user (void *addr, const char *name) 63{ new (addr) __user_type_info (name); } 64 65// dynamic_cast helper methods. 66// Returns a pointer to the desired sub-object or 0. 67 68void * __user_type_info:: 69dcast (const type_info& to, int, void *addr, const type_info *, void *) const 70{ return (*this == to) ? addr : 0; } 71 72void * __si_type_info:: 73dcast (const type_info& to, int require_public, void *addr, 74 const type_info *sub, void *subptr) const 75{ 76 if (*this == to) 77 return addr; 78 return base.dcast (to, require_public, addr, sub, subptr); 79} 80 81void* __class_type_info:: 82dcast (const type_info& desired, int is_public, void *objptr, 83 const type_info *sub, void *subptr) const 84{ 85 if (*this == desired) 86 return objptr; 87 88 void *match_found = 0; 89 for (size_t i = 0; i < n_bases; i++) 90 { 91 if (is_public && base_list[i].access != PUBLIC) 92 continue; 93 94 void *p = (char *)objptr + base_list[i].offset; 95 if (base_list[i].is_virtual) 96 p = *(void **)p; 97 p = base_list[i].base->dcast (desired, is_public, p, sub, subptr); 98 if (p) 99 { 100 if (match_found == 0) 101 match_found = p; 102 else if (match_found != p) 103 { 104 if (sub) 105 { 106 // Perhaps we're downcasting from *sub to desired; see if 107 // subptr is a subobject of exactly one of {match_found,p}. 108 109 const __user_type_info &d = 110 static_cast <const __user_type_info &> (desired); 111 112 void *os = d.dcast (*sub, 1, match_found); 113 void *ns = d.dcast (*sub, 1, p); 114 115 if (os == ns) 116 /* ambiguous -- subptr is a virtual base */; 117 else if (os == subptr) 118 continue; 119 else if (ns == subptr) 120 { 121 match_found = p; 122 continue; 123 } 124 } 125 126 // base found at two different pointers, 127 // conversion is not unique 128 return 0; 129 } 130 } 131 } 132 133 return match_found; 134} 135