1 // Methods for type_info for -*- C++ -*- Run Time Type Identification.
2 // Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000 Free Software Foundation
4 // This file is part of GNU CC.
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)
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.
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.
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.
30 #include "new" // for placement new
34 #if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
36 type_info::before (const type_info &arg) const
38 return __builtin_strcmp (name (), arg.name ()) < 0;
41 // type info for pointer type.
43 struct __pointer_type_info : public type_info {
44 const type_info& type;
46 __pointer_type_info (const char *n, const type_info& ti)
47 : type_info (n), type (ti) {}
50 // type info for attributes
52 struct __attr_type_info : public type_info {
53 enum cv { NONE = 0, CONST = 1, VOLATILE = 2, CONSTVOL = 1 | 2 };
55 const type_info& type;
58 __attr_type_info (const char *n, cv a, const type_info& t)
59 : type_info (n), type (t), attr (a) {}
62 // type_info for builtin type
64 struct __builtin_type_info : public type_info {
65 __builtin_type_info (const char *n): type_info (n) {}
68 // type info for function.
70 struct __func_type_info : public type_info {
71 __func_type_info (const char *n) : type_info (n) {}
74 // type info for pointer to member function.
76 struct __ptmf_type_info : public type_info {
77 __ptmf_type_info (const char *n) : type_info (n) {}
80 // type info for pointer to data member.
82 struct __ptmd_type_info : public type_info {
83 __ptmd_type_info (const char *n): type_info (n) {}
86 // type info for array.
88 struct __array_type_info : public type_info {
89 __array_type_info (const char *n): type_info (n) {}
97 #if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
98 namespace __cxxabiv1 {
102 // This has special meaning to the compiler, and will cause it
103 // to emit the type_info structures for the fundamental types which are
104 // mandated to exist in the runtime.
105 __fundamental_type_info::
106 ~__fundamental_type_info ()
109 __pointer_type_info::
110 ~__pointer_type_info ()
114 ~__array_type_info ()
117 __function_type_info::
118 ~__function_type_info ()
125 __pointer_to_member_type_info::
126 ~__pointer_to_member_type_info ()
129 bool __pointer_type_info::
130 __is_pointer_p () const
135 bool __function_type_info::
136 __is_function_p () const
141 bool __pointer_to_member_type_info::
142 __is_pointer_p () const
148 bool __pointer_type_info::
149 __do_catch (const type_info *thr_type,
151 unsigned outer) const
153 if (*this == *thr_type)
154 return true; // same type
155 if (typeid (*this) != typeid (*thr_type))
156 return false; // not both same kind of pointers
159 // We're not the same and our outer pointers are not all const qualified
160 // Therefore there must at least be a qualification conversion involved
161 // But for that to be valid, our outer pointers must be const qualified.
164 const __pointer_type_info *thrown_type =
165 static_cast <const __pointer_type_info *> (thr_type);
167 if (thrown_type->quals & ~quals)
168 // We're less qualified.
171 if (!(quals & const_mask))
174 return __pointer_catch (thrown_type, thr_obj, outer);
177 bool __pointer_type_info::
178 __pointer_catch (const __pointer_type_info *thrown_type,
180 unsigned outer) const
182 if (outer < 2 && *type == typeid (void))
184 // conversion to void
185 return !thrown_type->type->__is_function_p ();
188 return type->__do_catch (thrown_type->type, thr_obj, outer + 2);
191 bool __pointer_to_member_type_info::
192 __pointer_catch (const __pointer_type_info *thr_type,
194 unsigned outer) const
196 // This static cast is always valid, as our caller will have determined that
197 // thr_type is really a __pointer_to_member_type_info.
198 const __pointer_to_member_type_info *thrown_type =
199 static_cast <const __pointer_to_member_type_info *> (thr_type);
201 if (*klass != *thrown_type->klass)
202 return false; // not pointers to member of same class
204 return type->__do_catch (thrown_type->type, thr_obj, outer + 2);
210 // Entry points for the compiler.
212 /* Low level match routine used by compiler to match types of catch
213 variables and thrown objects. */
216 __throw_type_match_rtti_2 (const void *catch_type_r, const void *throw_type_r,
217 void *objptr, void **valp)
219 const type_info &catch_type = *(const type_info *)catch_type_r;
220 const type_info &throw_type = *(const type_info *)throw_type_r;
224 #if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
226 if (catch_type == throw_type)
229 if (const __user_type_info *p
230 = dynamic_cast <const __user_type_info *> (&throw_type))
232 return p->upcast (catch_type, objptr, valp);
234 else if (const __pointer_type_info *fr =
235 dynamic_cast <const __pointer_type_info *> (&throw_type))
237 const __pointer_type_info *to =
238 dynamic_cast <const __pointer_type_info *> (&catch_type);
243 const type_info *subfr = &fr->type, *subto = &to->type;
244 __attr_type_info::cv cvfrom, cvto;
246 if (const __attr_type_info *at
247 = dynamic_cast <const __attr_type_info *> (subfr))
253 cvfrom = __attr_type_info::NONE;
255 if (const __attr_type_info *at
256 = dynamic_cast <const __attr_type_info *> (subto))
262 cvto = __attr_type_info::NONE;
264 if (((cvfrom & __attr_type_info::CONST)
265 > (cvto & __attr_type_info::CONST))
266 || ((cvfrom & __attr_type_info::VOLATILE)
267 > (cvto & __attr_type_info::VOLATILE)))
270 if (*subto == *subfr)
272 else if (*subto == typeid (void)
273 && dynamic_cast <const __func_type_info *> (subfr) == 0)
275 else if (const __user_type_info *p
276 = dynamic_cast <const __user_type_info *> (subfr))
277 return p->upcast (*subto, objptr, valp);
278 else if (const __pointer_type_info *pfr
279 = dynamic_cast <const __pointer_type_info *> (subfr))
281 // Multi-level pointer conversion.
283 const __pointer_type_info *pto
284 = dynamic_cast <const __pointer_type_info *> (subto);
289 bool constp = (cvto & __attr_type_info::CONST);
290 for (subto = &pto->type, subfr = &pfr->type; ;
291 subto = &pto->type, subfr = &pfr->type)
293 if (const __attr_type_info *at
294 = dynamic_cast <const __attr_type_info *> (subfr))
300 cvfrom = __attr_type_info::NONE;
302 if (const __attr_type_info *at
303 = dynamic_cast <const __attr_type_info *> (subto))
309 cvto = __attr_type_info::NONE;
311 if (((cvfrom & __attr_type_info::CONST)
312 > (cvto & __attr_type_info::CONST))
313 || ((cvfrom & __attr_type_info::VOLATILE)
314 > (cvto & __attr_type_info::VOLATILE)))
318 && (((cvfrom & __attr_type_info::CONST)
319 < (cvto & __attr_type_info::CONST))
320 || ((cvfrom & __attr_type_info::VOLATILE)
321 < (cvto & __attr_type_info::VOLATILE))))
324 if (*subto == *subfr)
327 pto = dynamic_cast <const __pointer_type_info *> (subto);
328 pfr = dynamic_cast <const __pointer_type_info *> (subfr);
332 if (! (cvto & __attr_type_info::CONST))
340 return catch_type.__do_catch (&throw_type, valp, 1);
345 #if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
346 /* Backward compatibility wrapper. */
349 __throw_type_match_rtti (const void *catch_type_r, const void *throw_type_r,
353 if (__throw_type_match_rtti_2 (catch_type_r, throw_type_r, objptr, &ret))
359 /* Called from __cp_pop_exception. Is P the type_info node for a pointer
363 __is_pointer (void *p)
365 const type_info *t = reinterpret_cast <const type_info *>(p);
366 #if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
368 const __pointer_type_info *pt =
369 dynamic_cast <const __pointer_type_info *> (t);
373 return t->__is_pointer_p ();
377 #if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
381 __rtti_ptr (void *addr, const char *n, const type_info *ti)
382 { new (addr) __pointer_type_info (n, *ti); }
385 __rtti_attr (void *addr, const char *n, int attrval, const type_info *ti)
387 new (addr) __attr_type_info
388 (n, static_cast <__attr_type_info::cv> (attrval), *ti);
392 __rtti_func (void *addr, const char *name)
393 { new (addr) __func_type_info (name); }
396 __rtti_ptmf (void *addr, const char *name)
397 { new (addr) __ptmf_type_info (name); }
400 __rtti_ptmd (void *addr, const char *name)
401 { new (addr) __ptmd_type_info (name); }
404 __rtti_array (void *addr, const char *name)
405 { new (addr) __array_type_info (name); }
408 __dynamic_cast (const type_info& (*from)(void), const type_info& (*to)(void),
409 int require_public, void *address, const type_info & (*sub)(void), void *subptr)
411 if (!require_public) abort();
412 return static_cast <__user_type_info const &> (from ()).dyncast
413 (/*boff=*/-1, to (), address, sub (), subptr);
417 __dynamic_cast_2 (const type_info& (*from)(void), const type_info& (*to)(void),
419 void *address, const type_info & (*sub)(void), void *subptr)
421 return static_cast <__user_type_info const &> (from ()).dyncast
422 (boff, to (), address, sub (), subptr);
425 // type_info nodes and functions for the builtin types. The mangling here
426 // must match the mangling in gcc/cp/rtti.c.
428 #define BUILTIN(mangled) \
429 unsigned char __ti##mangled [sizeof (__builtin_type_info)] \
430 __attribute__ ((aligned (__alignof__ (void *)))); \
431 extern "C" const type_info &__tf##mangled (void) { \
432 if ((*(void **) __ti##mangled) == 0) \
433 new (__ti##mangled) __builtin_type_info (#mangled); \
434 return *(type_info *)__ti##mangled; \
437 BUILTIN (v); BUILTIN (x); BUILTIN (l); BUILTIN (i); BUILTIN (s); BUILTIN (b);
438 BUILTIN (c); BUILTIN (w); BUILTIN (r); BUILTIN (d); BUILTIN (f);
439 BUILTIN (Ui); BUILTIN (Ul); BUILTIN (Ux); BUILTIN (Us); BUILTIN (Uc);