Only create gcc/configargs.h if gcc build directory is present
[official-gcc.git] / libstdc++ / tinfo2.cc
blob6e1c916f17720b1572adfc2d199333a5e97ecd4b
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)
9 // any later version.
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.
30 #include <stddef.h>
31 #include "tinfo.hP"
32 #include "new" // for placement new
34 // We can't rely on having stdlib.h if we're freestanding.
35 extern "C" void abort ();
37 using std::type_info;
39 #if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
40 bool
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;
61 cv attr;
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) {}
97 #else
99 #include <cxxabi.h>
100 #endif
102 #if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
103 namespace __cxxabiv1 {
105 using namespace std;
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 ()
114 __array_type_info::
115 ~__array_type_info ()
118 __function_type_info::
119 ~__function_type_info ()
122 __enum_type_info::
123 ~__enum_type_info ()
126 __pbase_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
141 return true;
144 bool __function_type_info::
145 __is_function_p () const
147 return true;
150 bool __pbase_type_info::
151 __do_catch (const type_info *thr_type,
152 void **thr_obj,
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
160 if (!(outer & 1))
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.
164 return false;
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.
171 return false;
173 if (!(__qualifier_flags & __const_mask))
174 outer &= ~1;
176 return __pointer_catch (thrown_type, thr_obj, outer);
179 inline bool __pbase_type_info::
180 __pointer_catch (const __pbase_type_info *thrown_type,
181 void **thr_obj,
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,
189 void **thr_obj,
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,
203 void **thr_obj,
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);
217 } // namespace std
218 #endif
220 // Entry points for the compiler.
222 /* Low level match routine used by compiler to match types of catch
223 variables and thrown objects. */
225 extern "C" int
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;
232 *valp = objptr;
234 #if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
235 // old abi
236 if (catch_type == throw_type)
237 return 1;
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);
250 if (! to)
251 return 0;
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))
259 cvfrom = at->attr;
260 subfr = &at->type;
262 else
263 cvfrom = __attr_type_info::NONE;
265 if (const __attr_type_info *at
266 = dynamic_cast <const __attr_type_info *> (subto))
268 cvto = at->attr;
269 subto = &at->type;
271 else
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)))
278 return 0;
280 if (*subto == *subfr)
281 return 1;
282 else if (*subto == typeid (void)
283 && dynamic_cast <const __func_type_info *> (subfr) == 0)
284 return 1;
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);
296 if (! pto)
297 return 0;
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))
306 cvfrom = at->attr;
307 subfr = &at->type;
309 else
310 cvfrom = __attr_type_info::NONE;
312 if (const __attr_type_info *at
313 = dynamic_cast <const __attr_type_info *> (subto))
315 cvto = at->attr;
316 subto = &at->type;
318 else
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)))
325 return 0;
327 if (! constp
328 && (((cvfrom & __attr_type_info::CONST)
329 < (cvto & __attr_type_info::CONST))
330 || ((cvfrom & __attr_type_info::VOLATILE)
331 < (cvto & __attr_type_info::VOLATILE))))
332 return 0;
334 if (*subto == *subfr)
335 return 1;
337 pto = dynamic_cast <const __pointer_type_info *> (subto);
338 pfr = dynamic_cast <const __pointer_type_info *> (subfr);
339 if (! pto || ! pfr)
340 return 0;
342 if (! (cvto & __attr_type_info::CONST))
343 constp = false;
347 #else
348 // new abi
350 return catch_type.__do_catch (&throw_type, valp, 1);
351 #endif
352 return 0;
355 #if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
356 /* Backward compatibility wrapper. */
358 extern "C" void*
359 __throw_type_match_rtti (const void *catch_type_r, const void *throw_type_r,
360 void *objptr)
362 void *ret;
363 if (__throw_type_match_rtti_2 (catch_type_r, throw_type_r, objptr, &ret))
364 return ret;
365 return NULL;
367 #endif
369 /* Called from __cp_pop_exception. Is P the type_info node for a pointer
370 of some kind? */
372 bool
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
377 // old abi
378 const __pointer_type_info *pt =
379 dynamic_cast <const __pointer_type_info *> (t);
380 return pt != 0;
381 #else
382 // new abi
383 return t->__is_pointer_p ();
384 #endif
387 #if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
388 // old abi
390 extern "C" void
391 __rtti_ptr (void *addr, const char *n, const type_info *ti)
392 { new (addr) __pointer_type_info (n, *ti); }
394 extern "C" void
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);
401 extern "C" void
402 __rtti_func (void *addr, const char *name)
403 { new (addr) __func_type_info (name); }
405 extern "C" void
406 __rtti_ptmf (void *addr, const char *name)
407 { new (addr) __ptmf_type_info (name); }
409 extern "C" void
410 __rtti_ptmd (void *addr, const char *name)
411 { new (addr) __ptmd_type_info (name); }
413 extern "C" void
414 __rtti_array (void *addr, const char *name)
415 { new (addr) __array_type_info (name); }
417 extern "C" void *
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);
426 extern "C" void *
427 __dynamic_cast_2 (const type_info& (*from)(void), const type_info& (*to)(void),
428 int boff,
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);
450 BUILTIN (Sc);
452 #endif