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, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
32 #include "new" // for placement new
34 // We can't rely on having stdlib.h if we're freestanding.
35 extern "C" void abort ();
39 #if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
41 type_info::before (const type_info
&arg
) const
43 return __builtin_strcmp (name (), arg
.name ()) < 0;
46 // type info for pointer type.
48 struct __pointer_type_info
: public type_info
{
49 const type_info
& type
;
51 __pointer_type_info (const char *n
, const type_info
& ti
)
52 : type_info (n
), type (ti
) {}
55 // type info for attributes
57 struct __attr_type_info
: public type_info
{
58 enum cv
{ NONE
= 0, CONST
= 1, VOLATILE
= 2, CONSTVOL
= 1 | 2 };
60 const type_info
& type
;
63 __attr_type_info (const char *n
, cv a
, const type_info
& t
)
64 : type_info (n
), type (t
), attr (a
) {}
67 // type_info for builtin type
69 struct __builtin_type_info
: public type_info
{
70 __builtin_type_info (const char *n
): type_info (n
) {}
73 // type info for function.
75 struct __func_type_info
: public type_info
{
76 __func_type_info (const char *n
) : type_info (n
) {}
79 // type info for pointer to member function.
81 struct __ptmf_type_info
: public type_info
{
82 __ptmf_type_info (const char *n
) : type_info (n
) {}
85 // type info for pointer to data member.
87 struct __ptmd_type_info
: public type_info
{
88 __ptmd_type_info (const char *n
): type_info (n
) {}
91 // type info for array.
93 struct __array_type_info
: public type_info
{
94 __array_type_info (const char *n
): type_info (n
) {}
102 #if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
103 namespace __cxxabiv1
{
107 // This has special meaning to the compiler, and will cause it
108 // to emit the type_info structures for the fundamental types which are
109 // mandated to exist in the runtime.
110 __fundamental_type_info::
111 ~__fundamental_type_info ()
115 ~__array_type_info ()
118 __function_type_info::
119 ~__function_type_info ()
127 ~__pbase_type_info ()
130 __pointer_type_info::
131 ~__pointer_type_info ()
134 __pointer_to_member_type_info::
135 ~__pointer_to_member_type_info ()
138 bool __pointer_type_info::
139 __is_pointer_p () const
144 bool __function_type_info::
145 __is_function_p () const
150 bool __pbase_type_info::
151 __do_catch (const type_info
*thr_type
,
153 unsigned outer
) const
155 if (*this == *thr_type
)
156 return true; // same type
157 if (typeid (*this) != typeid (*thr_type
))
158 return false; // not both same kind of pointers
161 // We're not the same and our outer pointers are not all const qualified
162 // Therefore there must at least be a qualification conversion involved
163 // But for that to be valid, our outer pointers must be const qualified.
166 const __pbase_type_info
*thrown_type
=
167 static_cast <const __pbase_type_info
*> (thr_type
);
169 if (thrown_type
->__qualifier_flags
& ~__qualifier_flags
)
170 // We're less qualified.
173 if (!(__qualifier_flags
& __const_mask
))
176 return __pointer_catch (thrown_type
, thr_obj
, outer
);
179 inline bool __pbase_type_info::
180 __pointer_catch (const __pbase_type_info
*thrown_type
,
182 unsigned outer
) const
184 return __pointee
->__do_catch (thrown_type
->__pointee
, thr_obj
, outer
+ 2);
187 bool __pointer_type_info::
188 __pointer_catch (const __pbase_type_info
*thrown_type
,
190 unsigned outer
) const
192 if (outer
< 2 && *__pointee
== typeid (void))
194 // conversion to void
195 return !thrown_type
->__pointee
->__is_function_p ();
198 return __pbase_type_info::__pointer_catch (thrown_type
, thr_obj
, outer
);
201 bool __pointer_to_member_type_info::
202 __pointer_catch (const __pbase_type_info
*thr_type
,
204 unsigned outer
) const
206 // This static cast is always valid, as our caller will have determined that
207 // thr_type is really a __pointer_to_member_type_info.
208 const __pointer_to_member_type_info
*thrown_type
=
209 static_cast <const __pointer_to_member_type_info
*> (thr_type
);
211 if (*__context_class
!= *thrown_type
->__context_class
)
212 return false; // not pointers to member of same class
214 return __pbase_type_info::__pointer_catch (thrown_type
, thr_obj
, outer
);
220 // Entry points for the compiler.
222 /* Low level match routine used by compiler to match types of catch
223 variables and thrown objects. */
226 __throw_type_match_rtti_2 (const void *catch_type_r
, const void *throw_type_r
,
227 void *objptr
, void **valp
)
229 const type_info
&catch_type
= *(const type_info
*)catch_type_r
;
230 const type_info
&throw_type
= *(const type_info
*)throw_type_r
;
234 #if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
236 if (catch_type
== throw_type
)
239 if (const __user_type_info
*p
240 = dynamic_cast <const __user_type_info
*> (&throw_type
))
242 return p
->upcast (catch_type
, objptr
, valp
);
244 else if (const __pointer_type_info
*fr
=
245 dynamic_cast <const __pointer_type_info
*> (&throw_type
))
247 const __pointer_type_info
*to
=
248 dynamic_cast <const __pointer_type_info
*> (&catch_type
);
253 const type_info
*subfr
= &fr
->type
, *subto
= &to
->type
;
254 __attr_type_info::cv cvfrom
, cvto
;
256 if (const __attr_type_info
*at
257 = dynamic_cast <const __attr_type_info
*> (subfr
))
263 cvfrom
= __attr_type_info::NONE
;
265 if (const __attr_type_info
*at
266 = dynamic_cast <const __attr_type_info
*> (subto
))
272 cvto
= __attr_type_info::NONE
;
274 if (((cvfrom
& __attr_type_info::CONST
)
275 > (cvto
& __attr_type_info::CONST
))
276 || ((cvfrom
& __attr_type_info::VOLATILE
)
277 > (cvto
& __attr_type_info::VOLATILE
)))
280 if (*subto
== *subfr
)
282 else if (*subto
== typeid (void)
283 && dynamic_cast <const __func_type_info
*> (subfr
) == 0)
285 else if (const __user_type_info
*p
286 = dynamic_cast <const __user_type_info
*> (subfr
))
287 return p
->upcast (*subto
, objptr
, valp
);
288 else if (const __pointer_type_info
*pfr
289 = dynamic_cast <const __pointer_type_info
*> (subfr
))
291 // Multi-level pointer conversion.
293 const __pointer_type_info
*pto
294 = dynamic_cast <const __pointer_type_info
*> (subto
);
299 bool constp
= (cvto
& __attr_type_info::CONST
);
300 for (subto
= &pto
->type
, subfr
= &pfr
->type
; ;
301 subto
= &pto
->type
, subfr
= &pfr
->type
)
303 if (const __attr_type_info
*at
304 = dynamic_cast <const __attr_type_info
*> (subfr
))
310 cvfrom
= __attr_type_info::NONE
;
312 if (const __attr_type_info
*at
313 = dynamic_cast <const __attr_type_info
*> (subto
))
319 cvto
= __attr_type_info::NONE
;
321 if (((cvfrom
& __attr_type_info::CONST
)
322 > (cvto
& __attr_type_info::CONST
))
323 || ((cvfrom
& __attr_type_info::VOLATILE
)
324 > (cvto
& __attr_type_info::VOLATILE
)))
328 && (((cvfrom
& __attr_type_info::CONST
)
329 < (cvto
& __attr_type_info::CONST
))
330 || ((cvfrom
& __attr_type_info::VOLATILE
)
331 < (cvto
& __attr_type_info::VOLATILE
))))
334 if (*subto
== *subfr
)
337 pto
= dynamic_cast <const __pointer_type_info
*> (subto
);
338 pfr
= dynamic_cast <const __pointer_type_info
*> (subfr
);
342 if (! (cvto
& __attr_type_info::CONST
))
350 return catch_type
.__do_catch (&throw_type
, valp
, 1);
355 #if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
356 /* Backward compatibility wrapper. */
359 __throw_type_match_rtti (const void *catch_type_r
, const void *throw_type_r
,
363 if (__throw_type_match_rtti_2 (catch_type_r
, throw_type_r
, objptr
, &ret
))
369 /* Called from __cp_pop_exception. Is P the type_info node for a pointer
373 __is_pointer (void *p
)
375 const type_info
*t
= reinterpret_cast <const type_info
*>(p
);
376 #if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
378 const __pointer_type_info
*pt
=
379 dynamic_cast <const __pointer_type_info
*> (t
);
383 return t
->__is_pointer_p ();
387 #if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
391 __rtti_ptr (void *addr
, const char *n
, const type_info
*ti
)
392 { new (addr
) __pointer_type_info (n
, *ti
); }
395 __rtti_attr (void *addr
, const char *n
, int attrval
, const type_info
*ti
)
397 new (addr
) __attr_type_info
398 (n
, static_cast <__attr_type_info::cv
> (attrval
), *ti
);
402 __rtti_func (void *addr
, const char *name
)
403 { new (addr
) __func_type_info (name
); }
406 __rtti_ptmf (void *addr
, const char *name
)
407 { new (addr
) __ptmf_type_info (name
); }
410 __rtti_ptmd (void *addr
, const char *name
)
411 { new (addr
) __ptmd_type_info (name
); }
414 __rtti_array (void *addr
, const char *name
)
415 { new (addr
) __array_type_info (name
); }
418 __dynamic_cast (const type_info
& (*from
)(void), const type_info
& (*to
)(void),
419 int require_public
, void *address
, const type_info
& (*sub
)(void), void *subptr
)
421 if (!require_public
) abort();
422 return static_cast <__user_type_info
const &> (from ()).dyncast
423 (/*boff=*/-1, to (), address
, sub (), subptr
);
427 __dynamic_cast_2 (const type_info
& (*from
)(void), const type_info
& (*to
)(void),
429 void *address
, const type_info
& (*sub
)(void), void *subptr
)
431 return static_cast <__user_type_info
const &> (from ()).dyncast
432 (boff
, to (), address
, sub (), subptr
);
435 // type_info nodes and functions for the builtin types. The mangling here
436 // must match the mangling in gcc/cp/rtti.c.
438 #define BUILTIN(mangled) \
439 unsigned char __ti##mangled [sizeof (__builtin_type_info)] \
440 __attribute__ ((aligned (__alignof__ (void *)))); \
441 extern "C" const type_info &__tf##mangled (void) { \
442 if ((*(void **) __ti##mangled) == 0) \
443 new (__ti##mangled) __builtin_type_info (#mangled); \
444 return *(type_info *)__ti##mangled; \
447 BUILTIN (v
); BUILTIN (x
); BUILTIN (l
); BUILTIN (i
); BUILTIN (s
); BUILTIN (b
);
448 BUILTIN (c
); BUILTIN (w
); BUILTIN (r
); BUILTIN (d
); BUILTIN (f
);
449 BUILTIN (Ui
); BUILTIN (Ul
); BUILTIN (Ux
); BUILTIN (Us
); BUILTIN (Uc
);