1 // Methods for type_info for -*- C++ -*- Run Time Type Identification.
2 // Copyright (C) 1994, 96-97, 1998, 1999 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
35 type_info::before (const type_info
&arg
) const
37 return strcmp (name (), arg
.name ()) < 0;
40 // type info for pointer type.
42 struct __pointer_type_info
: public type_info
{
43 const type_info
& type
;
45 __pointer_type_info (const char *n
, const type_info
& ti
)
46 : type_info (n
), type (ti
) {}
49 // type info for attributes
51 struct __attr_type_info
: public type_info
{
52 enum cv
{ NONE
= 0, CONST
= 1, VOLATILE
= 2, CONSTVOL
= 1 | 2 };
54 const type_info
& type
;
57 __attr_type_info (const char *n
, cv a
, const type_info
& t
)
58 : type_info (n
), type (t
), attr (a
) {}
61 // type_info for builtin type
63 struct __builtin_type_info
: public type_info
{
64 __builtin_type_info (const char *n
): type_info (n
) {}
67 // type info for function.
69 struct __func_type_info
: public type_info
{
70 __func_type_info (const char *n
) : type_info (n
) {}
73 // type info for pointer to member function.
75 struct __ptmf_type_info
: public type_info
{
76 __ptmf_type_info (const char *n
) : type_info (n
) {}
79 // type info for pointer to data member.
81 struct __ptmd_type_info
: public type_info
{
82 __ptmd_type_info (const char *n
): type_info (n
) {}
85 // type info for array.
87 struct __array_type_info
: public type_info
{
88 __array_type_info (const char *n
): type_info (n
) {}
91 // Entry points for the compiler.
93 /* Low level match routine used by compiler to match types of catch
94 variables and thrown objects. */
97 __throw_type_match_rtti_2 (const void *catch_type_r
, const void *throw_type_r
,
98 void *objptr
, void **valp
)
100 const type_info
&catch_type
= *(const type_info
*)catch_type_r
;
101 const type_info
&throw_type
= *(const type_info
*)throw_type_r
;
105 if (catch_type
== throw_type
)
108 if (const __user_type_info
*p
109 = dynamic_cast <const __user_type_info
*> (&throw_type
))
111 return p
->upcast (catch_type
, objptr
, valp
);
113 else if (const __pointer_type_info
*fr
=
114 dynamic_cast <const __pointer_type_info
*> (&throw_type
))
116 const __pointer_type_info
*to
=
117 dynamic_cast <const __pointer_type_info
*> (&catch_type
);
122 const type_info
*subfr
= &fr
->type
, *subto
= &to
->type
;
123 __attr_type_info::cv cvfrom
, cvto
;
125 if (const __attr_type_info
*at
126 = dynamic_cast <const __attr_type_info
*> (subfr
))
132 cvfrom
= __attr_type_info::NONE
;
134 if (const __attr_type_info
*at
135 = dynamic_cast <const __attr_type_info
*> (subto
))
141 cvto
= __attr_type_info::NONE
;
143 if (((cvfrom
& __attr_type_info::CONST
)
144 > (cvto
& __attr_type_info::CONST
))
145 || ((cvfrom
& __attr_type_info::VOLATILE
)
146 > (cvto
& __attr_type_info::VOLATILE
)))
149 if (*subto
== *subfr
)
151 else if (*subto
== typeid (void)
152 && dynamic_cast <const __func_type_info
*> (subfr
) == 0)
154 else if (const __user_type_info
*p
155 = dynamic_cast <const __user_type_info
*> (subfr
))
156 return p
->upcast (*subto
, objptr
, valp
);
157 else if (const __pointer_type_info
*pfr
158 = dynamic_cast <const __pointer_type_info
*> (subfr
))
160 // Multi-level pointer conversion.
162 const __pointer_type_info
*pto
163 = dynamic_cast <const __pointer_type_info
*> (subto
);
168 bool constp
= (cvto
& __attr_type_info::CONST
);
169 for (subto
= &pto
->type
, subfr
= &pfr
->type
; ;
170 subto
= &pto
->type
, subfr
= &pfr
->type
)
172 if (const __attr_type_info
*at
173 = dynamic_cast <const __attr_type_info
*> (subfr
))
179 cvfrom
= __attr_type_info::NONE
;
181 if (const __attr_type_info
*at
182 = dynamic_cast <const __attr_type_info
*> (subto
))
188 cvto
= __attr_type_info::NONE
;
190 if (((cvfrom
& __attr_type_info::CONST
)
191 > (cvto
& __attr_type_info::CONST
))
192 || ((cvfrom
& __attr_type_info::VOLATILE
)
193 > (cvto
& __attr_type_info::VOLATILE
)))
197 && (((cvfrom
& __attr_type_info::CONST
)
198 < (cvto
& __attr_type_info::CONST
))
199 || ((cvfrom
& __attr_type_info::VOLATILE
)
200 < (cvto
& __attr_type_info::VOLATILE
))))
203 if (*subto
== *subfr
)
206 pto
= dynamic_cast <const __pointer_type_info
*> (subto
);
207 pfr
= dynamic_cast <const __pointer_type_info
*> (subfr
);
211 if (! (cvto
& __attr_type_info::CONST
))
220 /* Backward compatibility wrapper. */
223 __throw_type_match_rtti (const void *catch_type_r
, const void *throw_type_r
,
227 if (__throw_type_match_rtti_2 (catch_type_r
, throw_type_r
, objptr
, &ret
))
232 /* Called from __cp_pop_exception. Is P the type_info node for a pointer
236 __is_pointer (void *p
)
238 const type_info
*t
= reinterpret_cast <const type_info
*>(p
);
239 const __pointer_type_info
*pt
=
240 dynamic_cast <const __pointer_type_info
*> (t
);
245 __rtti_ptr (void *addr
, const char *n
, const type_info
*ti
)
246 { new (addr
) __pointer_type_info (n
, *ti
); }
249 __rtti_attr (void *addr
, const char *n
, int attrval
, const type_info
*ti
)
251 new (addr
) __attr_type_info
252 (n
, static_cast <__attr_type_info::cv
> (attrval
), *ti
);
256 __rtti_func (void *addr
, const char *name
)
257 { new (addr
) __func_type_info (name
); }
260 __rtti_ptmf (void *addr
, const char *name
)
261 { new (addr
) __ptmf_type_info (name
); }
264 __rtti_ptmd (void *addr
, const char *name
)
265 { new (addr
) __ptmd_type_info (name
); }
268 __rtti_array (void *addr
, const char *name
)
269 { new (addr
) __array_type_info (name
); }
272 __dynamic_cast (const type_info
& (*from
)(void), const type_info
& (*to
)(void),
273 int require_public
, void *address
, const type_info
& (*sub
)(void), void *subptr
)
275 if (!require_public
) abort();
276 return static_cast <__user_type_info
const &> (from ()).dyncast
277 (/*boff=*/-2, to (), address
, sub (), subptr
);
281 __dynamic_cast_2 (const type_info
& (*from
)(void), const type_info
& (*to
)(void),
283 void *address
, const type_info
& (*sub
)(void), void *subptr
)
285 return static_cast <__user_type_info
const &> (from ()).dyncast
286 (boff
, to (), address
, sub (), subptr
);
289 // type_info nodes and functions for the builtin types. The mangling here
290 // must match the mangling in gcc/cp/rtti.c.
292 #define BUILTIN(mangled) \
293 unsigned char __ti##mangled [sizeof (__builtin_type_info)] \
294 __attribute__ ((aligned (__alignof__ (void *)))); \
295 extern "C" const type_info &__tf##mangled (void) { \
296 if ((*(void **) __ti##mangled) == 0) \
297 new (__ti##mangled) __builtin_type_info (#mangled); \
298 return *(type_info *)__ti##mangled; \
301 BUILTIN (v
); BUILTIN (x
); BUILTIN (l
); BUILTIN (i
); BUILTIN (s
); BUILTIN (b
);
302 BUILTIN (c
); BUILTIN (w
); BUILTIN (r
); BUILTIN (d
); BUILTIN (f
);
303 BUILTIN (Ui
); BUILTIN (Ul
); BUILTIN (Ux
); BUILTIN (Us
); BUILTIN (Uc
);