1*404b540aSrobert // Methods for type_info for -*- C++ -*- Run Time Type Identification.
2*404b540aSrobert
3*404b540aSrobert // Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002
4*404b540aSrobert // Free Software Foundation
5*404b540aSrobert //
6*404b540aSrobert // This file is part of GCC.
7*404b540aSrobert //
8*404b540aSrobert // GCC is free software; you can redistribute it and/or modify
9*404b540aSrobert // it under the terms of the GNU General Public License as published by
10*404b540aSrobert // the Free Software Foundation; either version 2, or (at your option)
11*404b540aSrobert // any later version.
12*404b540aSrobert
13*404b540aSrobert // GCC is distributed in the hope that it will be useful,
14*404b540aSrobert // but WITHOUT ANY WARRANTY; without even the implied warranty of
15*404b540aSrobert // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16*404b540aSrobert // GNU General Public License for more details.
17*404b540aSrobert
18*404b540aSrobert // You should have received a copy of the GNU General Public License
19*404b540aSrobert // along with GCC; see the file COPYING. If not, write to
20*404b540aSrobert // the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21*404b540aSrobert // Boston, MA 02110-1301, USA.
22*404b540aSrobert
23*404b540aSrobert // As a special exception, you may use this file as part of a free software
24*404b540aSrobert // library without restriction. Specifically, if other files instantiate
25*404b540aSrobert // templates or use macros or inline functions from this file, or you compile
26*404b540aSrobert // this file and link it with other files to produce an executable, this
27*404b540aSrobert // file does not by itself cause the resulting executable to be covered by
28*404b540aSrobert // the GNU General Public License. This exception does not however
29*404b540aSrobert // invalidate any other reasons why the executable file might be covered by
30*404b540aSrobert // the GNU General Public License.
31*404b540aSrobert
32*404b540aSrobert #include <cstddef>
33*404b540aSrobert #include "tinfo.h"
34*404b540aSrobert #include "new" // for placement new
35*404b540aSrobert
36*404b540aSrobert // We can't rely on having stdlib.h if we're freestanding.
37*404b540aSrobert extern "C" void abort ();
38*404b540aSrobert
39*404b540aSrobert using std::type_info;
40*404b540aSrobert
41*404b540aSrobert #if !__GXX_MERGED_TYPEINFO_NAMES
42*404b540aSrobert
43*404b540aSrobert bool
before(const type_info & arg) const44*404b540aSrobert type_info::before (const type_info &arg) const
45*404b540aSrobert {
46*404b540aSrobert return __builtin_strcmp (name (), arg.name ()) < 0;
47*404b540aSrobert }
48*404b540aSrobert
49*404b540aSrobert #endif
50*404b540aSrobert
51*404b540aSrobert #include <cxxabi.h>
52*404b540aSrobert
53*404b540aSrobert namespace __cxxabiv1 {
54*404b540aSrobert
55*404b540aSrobert using namespace std;
56*404b540aSrobert
57*404b540aSrobert // This has special meaning to the compiler, and will cause it
58*404b540aSrobert // to emit the type_info structures for the fundamental types which are
59*404b540aSrobert // mandated to exist in the runtime.
60*404b540aSrobert __fundamental_type_info::
~__fundamental_type_info()61*404b540aSrobert ~__fundamental_type_info ()
62*404b540aSrobert {}
63*404b540aSrobert
64*404b540aSrobert __array_type_info::
~__array_type_info()65*404b540aSrobert ~__array_type_info ()
66*404b540aSrobert {}
67*404b540aSrobert
68*404b540aSrobert __function_type_info::
~__function_type_info()69*404b540aSrobert ~__function_type_info ()
70*404b540aSrobert {}
71*404b540aSrobert
72*404b540aSrobert __enum_type_info::
~__enum_type_info()73*404b540aSrobert ~__enum_type_info ()
74*404b540aSrobert {}
75*404b540aSrobert
76*404b540aSrobert __pbase_type_info::
~__pbase_type_info()77*404b540aSrobert ~__pbase_type_info ()
78*404b540aSrobert {}
79*404b540aSrobert
80*404b540aSrobert __pointer_type_info::
~__pointer_type_info()81*404b540aSrobert ~__pointer_type_info ()
82*404b540aSrobert {}
83*404b540aSrobert
84*404b540aSrobert __pointer_to_member_type_info::
~__pointer_to_member_type_info()85*404b540aSrobert ~__pointer_to_member_type_info ()
86*404b540aSrobert {}
87*404b540aSrobert
88*404b540aSrobert bool __pointer_type_info::
__is_pointer_p() const89*404b540aSrobert __is_pointer_p () const
90*404b540aSrobert {
91*404b540aSrobert return true;
92*404b540aSrobert }
93*404b540aSrobert
94*404b540aSrobert bool __function_type_info::
__is_function_p() const95*404b540aSrobert __is_function_p () const
96*404b540aSrobert {
97*404b540aSrobert return true;
98*404b540aSrobert }
99*404b540aSrobert
100*404b540aSrobert bool __pbase_type_info::
__do_catch(const type_info * thr_type,void ** thr_obj,unsigned outer) const101*404b540aSrobert __do_catch (const type_info *thr_type,
102*404b540aSrobert void **thr_obj,
103*404b540aSrobert unsigned outer) const
104*404b540aSrobert {
105*404b540aSrobert if (*this == *thr_type)
106*404b540aSrobert return true; // same type
107*404b540aSrobert if (typeid (*this) != typeid (*thr_type))
108*404b540aSrobert return false; // not both same kind of pointers
109*404b540aSrobert
110*404b540aSrobert if (!(outer & 1))
111*404b540aSrobert // We're not the same and our outer pointers are not all const qualified
112*404b540aSrobert // Therefore there must at least be a qualification conversion involved
113*404b540aSrobert // But for that to be valid, our outer pointers must be const qualified.
114*404b540aSrobert return false;
115*404b540aSrobert
116*404b540aSrobert const __pbase_type_info *thrown_type =
117*404b540aSrobert static_cast <const __pbase_type_info *> (thr_type);
118*404b540aSrobert
119*404b540aSrobert if (thrown_type->__flags & ~__flags)
120*404b540aSrobert // We're less qualified.
121*404b540aSrobert return false;
122*404b540aSrobert
123*404b540aSrobert if (!(__flags & __const_mask))
124*404b540aSrobert outer &= ~1;
125*404b540aSrobert
126*404b540aSrobert return __pointer_catch (thrown_type, thr_obj, outer);
127*404b540aSrobert }
128*404b540aSrobert
129*404b540aSrobert inline bool __pbase_type_info::
__pointer_catch(const __pbase_type_info * thrown_type,void ** thr_obj,unsigned outer) const130*404b540aSrobert __pointer_catch (const __pbase_type_info *thrown_type,
131*404b540aSrobert void **thr_obj,
132*404b540aSrobert unsigned outer) const
133*404b540aSrobert {
134*404b540aSrobert return __pointee->__do_catch (thrown_type->__pointee, thr_obj, outer + 2);
135*404b540aSrobert }
136*404b540aSrobert
137*404b540aSrobert bool __pointer_type_info::
__pointer_catch(const __pbase_type_info * thrown_type,void ** thr_obj,unsigned outer) const138*404b540aSrobert __pointer_catch (const __pbase_type_info *thrown_type,
139*404b540aSrobert void **thr_obj,
140*404b540aSrobert unsigned outer) const
141*404b540aSrobert {
142*404b540aSrobert if (outer < 2 && *__pointee == typeid (void))
143*404b540aSrobert {
144*404b540aSrobert // conversion to void
145*404b540aSrobert return !thrown_type->__pointee->__is_function_p ();
146*404b540aSrobert }
147*404b540aSrobert
148*404b540aSrobert return __pbase_type_info::__pointer_catch (thrown_type, thr_obj, outer);
149*404b540aSrobert }
150*404b540aSrobert
151*404b540aSrobert bool __pointer_to_member_type_info::
__pointer_catch(const __pbase_type_info * thr_type,void ** thr_obj,unsigned outer) const152*404b540aSrobert __pointer_catch (const __pbase_type_info *thr_type,
153*404b540aSrobert void **thr_obj,
154*404b540aSrobert unsigned outer) const
155*404b540aSrobert {
156*404b540aSrobert // This static cast is always valid, as our caller will have determined that
157*404b540aSrobert // thr_type is really a __pointer_to_member_type_info.
158*404b540aSrobert const __pointer_to_member_type_info *thrown_type =
159*404b540aSrobert static_cast <const __pointer_to_member_type_info *> (thr_type);
160*404b540aSrobert
161*404b540aSrobert if (*__context != *thrown_type->__context)
162*404b540aSrobert return false; // not pointers to member of same class
163*404b540aSrobert
164*404b540aSrobert return __pbase_type_info::__pointer_catch (thrown_type, thr_obj, outer);
165*404b540aSrobert }
166*404b540aSrobert
167*404b540aSrobert } // namespace std
168