1 // Methods for type_info for -*- C++ -*- Run Time Type Identification.
2 // Copyright (C) 1994, 1996 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
32 // service function for comparing types by name.
35 fast_compare (const char *n1
, const char *n2
) {
37 if (n1
== n2
) return 0;
38 if (n1
== 0) return *n2
;
39 else if (n2
== 0) return *n1
;
41 c
= (int)*n1
++ - (int)*n2
++;
42 return c
== 0 ? strcmp (n1
, n2
) : c
;
46 type_info::before (const type_info
&arg
) const
48 return fast_compare (name (), arg
.name ()) < 0;
53 operator== (const type_info
& arg
) const
55 return fast_compare (name (), arg
.name ()) == 0;
59 operator!= (const type_info
& arg
) const
61 return fast_compare (name (), arg
.name ()) != 0;
65 // type info for pointer type.
67 struct __pointer_type_info
: public type_info
{
68 const type_info
& type
;
70 __pointer_type_info (const char *n
, const type_info
& ti
)
71 : type_info (n
), type (ti
) {}
74 // type info for attributes
76 struct __attr_type_info
: public type_info
{
77 enum cv
{ NONE
= 0, CONST
= 1, VOLATILE
= 2, CONSTVOL
= 1 | 2 };
79 const type_info
& type
;
82 __attr_type_info (const char *n
, cv a
, const type_info
& t
)
83 : type_info (n
), type (t
), attr (a
) {}
86 // type_info for builtin type
88 struct __builtin_type_info
: public type_info
{
89 __builtin_type_info (const char *n
): type_info (n
) {}
92 // type info for function.
94 struct __func_type_info
: public type_info
{
95 __func_type_info (const char *n
) : type_info (n
) {}
98 // type info for pointer to member function.
100 struct __ptmf_type_info
: public type_info
{
101 __ptmf_type_info (const char *n
) : type_info (n
) {}
104 // type info for pointer to data member.
106 struct __ptmd_type_info
: public type_info
{
107 __ptmd_type_info (const char *n
): type_info (n
) {}
110 // type info for array.
112 struct __array_type_info
: public type_info
{
113 __array_type_info (const char *n
): type_info (n
) {}
116 // Entry points for the compiler.
118 /* Low level match routine used by compiler to match types of catch
119 variables and thrown objects. */
122 __throw_type_match_rtti (const void *catch_type_r
, const void *throw_type_r
,
125 const type_info
&catch_type
= *(const type_info
*)catch_type_r
;
126 const type_info
&throw_type
= *(const type_info
*)throw_type_r
;
128 if (catch_type
== throw_type
)
132 printf ("We want to match a %s against a %s!\n",
133 throw_type
.name (), catch_type
.name ());
136 void *new_objptr
= 0;
138 if (const __user_type_info
*p
139 = dynamic_cast <const __user_type_info
*> (&throw_type
))
141 /* The 1 skips conversions to private bases. */
142 new_objptr
= p
->dcast (catch_type
, 1, objptr
);
144 else if (const __pointer_type_info
*fr
=
145 dynamic_cast <const __pointer_type_info
*> (&throw_type
))
147 const __pointer_type_info
*to
=
148 dynamic_cast <const __pointer_type_info
*> (&catch_type
);
153 const type_info
*subfr
= &fr
->type
, *subto
= &to
->type
;
154 __attr_type_info::cv cvfrom
, cvto
;
156 if (const __attr_type_info
*at
157 = dynamic_cast <const __attr_type_info
*> (subfr
))
163 cvfrom
= __attr_type_info::NONE
;
165 if (const __attr_type_info
*at
166 = dynamic_cast <const __attr_type_info
*> (subto
))
172 cvto
= __attr_type_info::NONE
;
174 if (((cvfrom
& __attr_type_info::CONST
)
175 > (cvto
& __attr_type_info::CONST
))
176 || ((cvfrom
& __attr_type_info::VOLATILE
)
177 > (cvto
& __attr_type_info::VOLATILE
)))
180 if (*subto
== *subfr
)
182 else if (*subto
== typeid (void)
183 && dynamic_cast <const __func_type_info
*> (subfr
) == 0)
185 else if (const __user_type_info
*p
186 = dynamic_cast <const __user_type_info
*> (subfr
))
188 /* The 1 skips conversions to private bases. */
189 new_objptr
= p
->dcast (*subto
, 1, objptr
);
191 else if (const __pointer_type_info
*pfr
192 = dynamic_cast <const __pointer_type_info
*> (subfr
))
194 // Multi-level pointer conversion.
196 const __pointer_type_info
*pto
197 = dynamic_cast <const __pointer_type_info
*> (subto
);
202 bool constp
= (cvto
& __attr_type_info::CONST
);
203 for (subto
= &pto
->type
, subfr
= &pfr
->type
; ;
204 subto
= &pto
->type
, subfr
= &pfr
->type
)
206 if (const __attr_type_info
*at
207 = dynamic_cast <const __attr_type_info
*> (subfr
))
213 cvfrom
= __attr_type_info::NONE
;
215 if (const __attr_type_info
*at
216 = dynamic_cast <const __attr_type_info
*> (subto
))
222 cvto
= __attr_type_info::NONE
;
224 if (((cvfrom
& __attr_type_info::CONST
)
225 > (cvto
& __attr_type_info::CONST
))
226 || ((cvfrom
& __attr_type_info::VOLATILE
)
227 > (cvto
& __attr_type_info::VOLATILE
)))
231 && (((cvfrom
& __attr_type_info::CONST
)
232 < (cvto
& __attr_type_info::CONST
))
233 || ((cvfrom
& __attr_type_info::VOLATILE
)
234 < (cvto
& __attr_type_info::VOLATILE
))))
237 if (*subto
== *subfr
)
243 pto
= dynamic_cast <const __pointer_type_info
*> (subto
);
244 pfr
= dynamic_cast <const __pointer_type_info
*> (subfr
);
248 if (! (cvto
& __attr_type_info::CONST
))
257 printf ("It converts, delta is %d\n", new_objptr
-objptr
);
262 /* Called from __cp_pop_exception. Is P the type_info node for a pointer
266 __is_pointer (void *p
)
268 const type_info
*t
= reinterpret_cast <const type_info
*>(p
);
269 const __pointer_type_info
*pt
=
270 dynamic_cast <const __pointer_type_info
*> (t
);
275 __rtti_ptr (void *addr
, const char *n
, const type_info
*ti
)
276 { new (addr
) __pointer_type_info (n
, *ti
); }
279 __rtti_attr (void *addr
, const char *n
, int attrval
, const type_info
*ti
)
281 new (addr
) __attr_type_info
282 (n
, static_cast <__attr_type_info::cv
> (attrval
), *ti
);
286 __rtti_func (void *addr
, const char *name
)
287 { new (addr
) __func_type_info (name
); }
290 __rtti_ptmf (void *addr
, const char *name
)
291 { new (addr
) __ptmf_type_info (name
); }
294 __rtti_ptmd (void *addr
, const char *name
)
295 { new (addr
) __ptmd_type_info (name
); }
298 __rtti_array (void *addr
, const char *name
)
299 { new (addr
) __array_type_info (name
); }
302 __dynamic_cast (const type_info
& (*from
)(void), const type_info
& (*to
)(void),
303 int require_public
, void *address
,
304 const type_info
& (*sub
)(void), void *subptr
)
306 return static_cast <const __user_type_info
&> (from ()).dcast
307 (to (), require_public
, address
, &(sub ()), subptr
);
310 // type_info nodes and functions for the builtin types. The mangling here
311 // must match the mangling in gcc/cp/rtti.c.
313 #define BUILTIN(mangled) \
314 unsigned char __ti##mangled [sizeof (__builtin_type_info)] \
315 __attribute__ ((aligned (__alignof__ (void *)))); \
316 extern "C" const type_info &__tf##mangled (void) { \
317 if ((*(void **) __ti##mangled) == 0) \
318 new (__ti##mangled) __builtin_type_info (#mangled); \
319 return *(type_info *)__ti##mangled; \
322 BUILTIN (v
); BUILTIN (x
); BUILTIN (l
); BUILTIN (i
); BUILTIN (s
); BUILTIN (b
);
323 BUILTIN (c
); BUILTIN (w
); BUILTIN (r
); BUILTIN (d
); BUILTIN (f
);
324 BUILTIN (Ui
); BUILTIN (Ul
); BUILTIN (Ux
); BUILTIN (Us
); BUILTIN (Uc
);