xref: /dflybsd-src/contrib/gcc-4.7/libstdc++-v3/libsupc++/tinfo.h (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino // RTTI support internals for -*- C++ -*-
2*e4b17023SJohn Marino // Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2004, 2009
3*e4b17023SJohn Marino // Free Software Foundation
4*e4b17023SJohn Marino 
5*e4b17023SJohn Marino // This file is part of GCC.
6*e4b17023SJohn Marino //
7*e4b17023SJohn Marino // GCC is free software; you can redistribute it and/or modify
8*e4b17023SJohn Marino // it under the terms of the GNU General Public License as published by
9*e4b17023SJohn Marino // the Free Software Foundation; either version 3, or (at your option)
10*e4b17023SJohn Marino // any later version.
11*e4b17023SJohn Marino 
12*e4b17023SJohn Marino // GCC is distributed in the hope that it will be useful,
13*e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of
14*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*e4b17023SJohn Marino // GNU General Public License for more details.
16*e4b17023SJohn Marino 
17*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional
18*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version
19*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation.
20*e4b17023SJohn Marino 
21*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and
22*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program;
23*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>.
25*e4b17023SJohn Marino 
26*e4b17023SJohn Marino #include "typeinfo"
27*e4b17023SJohn Marino #include <cstddef>
28*e4b17023SJohn Marino 
29*e4b17023SJohn Marino // Class declarations shared between the typeinfo implementation files.
30*e4b17023SJohn Marino 
31*e4b17023SJohn Marino #include <cxxabi.h>
32*e4b17023SJohn Marino 
33*e4b17023SJohn Marino namespace __cxxabiv1 {
34*e4b17023SJohn Marino 
35*e4b17023SJohn Marino inline bool __pbase_type_info::
__pointer_catch(const __pbase_type_info * thrown_type,void ** thr_obj,unsigned outer)36*e4b17023SJohn Marino __pointer_catch (const __pbase_type_info *thrown_type,
37*e4b17023SJohn Marino                  void **thr_obj,
38*e4b17023SJohn Marino                  unsigned outer) const
39*e4b17023SJohn Marino {
40*e4b17023SJohn Marino   return __pointee->__do_catch (thrown_type->__pointee, thr_obj, outer + 2);
41*e4b17023SJohn Marino }
42*e4b17023SJohn Marino 
43*e4b17023SJohn Marino namespace {
44*e4b17023SJohn Marino 
45*e4b17023SJohn Marino using namespace std;
46*e4b17023SJohn Marino using namespace abi;
47*e4b17023SJohn Marino 
48*e4b17023SJohn Marino // Initial part of a vtable, this structure is used with offsetof, so we don't
49*e4b17023SJohn Marino // have to keep alignments consistent manually.
50*e4b17023SJohn Marino struct vtable_prefix
51*e4b17023SJohn Marino {
52*e4b17023SJohn Marino   // Offset to most derived object.
53*e4b17023SJohn Marino   ptrdiff_t whole_object;
54*e4b17023SJohn Marino 
55*e4b17023SJohn Marino   // Additional padding if necessary.
56*e4b17023SJohn Marino #ifdef _GLIBCXX_VTABLE_PADDING
57*e4b17023SJohn Marino   ptrdiff_t padding1;
58*e4b17023SJohn Marino #endif
59*e4b17023SJohn Marino 
60*e4b17023SJohn Marino   // Pointer to most derived type_info.
61*e4b17023SJohn Marino   const __class_type_info *whole_type;
62*e4b17023SJohn Marino 
63*e4b17023SJohn Marino   // Additional padding if necessary.
64*e4b17023SJohn Marino #ifdef _GLIBCXX_VTABLE_PADDING
65*e4b17023SJohn Marino   ptrdiff_t padding2;
66*e4b17023SJohn Marino #endif
67*e4b17023SJohn Marino 
68*e4b17023SJohn Marino   // What a class's vptr points to.
69*e4b17023SJohn Marino   const void *origin;
70*e4b17023SJohn Marino };
71*e4b17023SJohn Marino 
72*e4b17023SJohn Marino template <typename T>
73*e4b17023SJohn Marino inline const T *
adjust_pointer(const void * base,ptrdiff_t offset)74*e4b17023SJohn Marino adjust_pointer (const void *base, ptrdiff_t offset)
75*e4b17023SJohn Marino {
76*e4b17023SJohn Marino   return reinterpret_cast <const T *>
77*e4b17023SJohn Marino     (reinterpret_cast <const char *> (base) + offset);
78*e4b17023SJohn Marino }
79*e4b17023SJohn Marino 
80*e4b17023SJohn Marino // ADDR is a pointer to an object.  Convert it to a pointer to a base,
81*e4b17023SJohn Marino // using OFFSET. IS_VIRTUAL is true, if we are getting a virtual base.
82*e4b17023SJohn Marino inline void const *
convert_to_base(void const * addr,bool is_virtual,ptrdiff_t offset)83*e4b17023SJohn Marino convert_to_base (void const *addr, bool is_virtual, ptrdiff_t offset)
84*e4b17023SJohn Marino {
85*e4b17023SJohn Marino   if (is_virtual)
86*e4b17023SJohn Marino     {
87*e4b17023SJohn Marino       const void *vtable = *static_cast <const void *const *> (addr);
88*e4b17023SJohn Marino 
89*e4b17023SJohn Marino       offset = *adjust_pointer<ptrdiff_t> (vtable, offset);
90*e4b17023SJohn Marino     }
91*e4b17023SJohn Marino 
92*e4b17023SJohn Marino   return adjust_pointer<void> (addr, offset);
93*e4b17023SJohn Marino }
94*e4b17023SJohn Marino 
95*e4b17023SJohn Marino // some predicate functions for __class_type_info::__sub_kind
contained_p(__class_type_info::__sub_kind access_path)96*e4b17023SJohn Marino inline bool contained_p (__class_type_info::__sub_kind access_path)
97*e4b17023SJohn Marino {
98*e4b17023SJohn Marino   return access_path >= __class_type_info::__contained_mask;
99*e4b17023SJohn Marino }
public_p(__class_type_info::__sub_kind access_path)100*e4b17023SJohn Marino inline bool public_p (__class_type_info::__sub_kind access_path)
101*e4b17023SJohn Marino {
102*e4b17023SJohn Marino   return access_path & __class_type_info::__contained_public_mask;
103*e4b17023SJohn Marino }
virtual_p(__class_type_info::__sub_kind access_path)104*e4b17023SJohn Marino inline bool virtual_p (__class_type_info::__sub_kind access_path)
105*e4b17023SJohn Marino {
106*e4b17023SJohn Marino   return (access_path & __class_type_info::__contained_virtual_mask);
107*e4b17023SJohn Marino }
contained_public_p(__class_type_info::__sub_kind access_path)108*e4b17023SJohn Marino inline bool contained_public_p (__class_type_info::__sub_kind access_path)
109*e4b17023SJohn Marino {
110*e4b17023SJohn Marino   return ((access_path & __class_type_info::__contained_public)
111*e4b17023SJohn Marino           == __class_type_info::__contained_public);
112*e4b17023SJohn Marino }
contained_nonpublic_p(__class_type_info::__sub_kind access_path)113*e4b17023SJohn Marino inline bool contained_nonpublic_p (__class_type_info::__sub_kind access_path)
114*e4b17023SJohn Marino {
115*e4b17023SJohn Marino   return ((access_path & __class_type_info::__contained_public)
116*e4b17023SJohn Marino           == __class_type_info::__contained_mask);
117*e4b17023SJohn Marino }
contained_nonvirtual_p(__class_type_info::__sub_kind access_path)118*e4b17023SJohn Marino inline bool contained_nonvirtual_p (__class_type_info::__sub_kind access_path)
119*e4b17023SJohn Marino {
120*e4b17023SJohn Marino   return ((access_path & (__class_type_info::__contained_mask
121*e4b17023SJohn Marino                           | __class_type_info::__contained_virtual_mask))
122*e4b17023SJohn Marino           == __class_type_info::__contained_mask);
123*e4b17023SJohn Marino }
124*e4b17023SJohn Marino 
125*e4b17023SJohn Marino static const __class_type_info *const nonvirtual_base_type =
126*e4b17023SJohn Marino     static_cast <const __class_type_info *> (0) + 1;
127*e4b17023SJohn Marino 
128*e4b17023SJohn Marino } // namespace
129*e4b17023SJohn Marino 
130*e4b17023SJohn Marino // __upcast_result is used to hold information during traversal of a class
131*e4b17023SJohn Marino // hierarchy when catch matching.
132*e4b17023SJohn Marino struct __class_type_info::__upcast_result
133*e4b17023SJohn Marino {
134*e4b17023SJohn Marino   const void *dst_ptr;        // pointer to caught object
135*e4b17023SJohn Marino   __sub_kind part2dst;        // path from current base to target
136*e4b17023SJohn Marino   int src_details;            // hints about the source type hierarchy
137*e4b17023SJohn Marino   const __class_type_info *base_type; // where we found the target,
138*e4b17023SJohn Marino                               // if in vbase the __class_type_info of vbase
139*e4b17023SJohn Marino                               // if a non-virtual base then 1
140*e4b17023SJohn Marino                               // else NULL
__upcast_result__upcast_result141*e4b17023SJohn Marino   __upcast_result (int d)
142*e4b17023SJohn Marino     :dst_ptr (NULL), part2dst (__unknown), src_details (d), base_type (NULL)
143*e4b17023SJohn Marino     {}
144*e4b17023SJohn Marino };
145*e4b17023SJohn Marino 
146*e4b17023SJohn Marino // __dyncast_result is used to hold information during traversal of a class
147*e4b17023SJohn Marino // hierarchy when dynamic casting.
148*e4b17023SJohn Marino struct __class_type_info::__dyncast_result
149*e4b17023SJohn Marino {
150*e4b17023SJohn Marino   const void *dst_ptr;        // pointer to target object or NULL
151*e4b17023SJohn Marino   __sub_kind whole2dst;       // path from most derived object to target
152*e4b17023SJohn Marino   __sub_kind whole2src;       // path from most derived object to sub object
153*e4b17023SJohn Marino   __sub_kind dst2src;         // path from target to sub object
154*e4b17023SJohn Marino   int whole_details;          // details of the whole class hierarchy
155*e4b17023SJohn Marino 
156*e4b17023SJohn Marino   __dyncast_result (int details_ = __vmi_class_type_info::__flags_unknown_mask)
dst_ptr__dyncast_result157*e4b17023SJohn Marino     :dst_ptr (NULL), whole2dst (__unknown),
158*e4b17023SJohn Marino      whole2src (__unknown), dst2src (__unknown),
159*e4b17023SJohn Marino      whole_details (details_)
160*e4b17023SJohn Marino     {}
161*e4b17023SJohn Marino 
162*e4b17023SJohn Marino protected:
163*e4b17023SJohn Marino   __dyncast_result(const __dyncast_result&);
164*e4b17023SJohn Marino 
165*e4b17023SJohn Marino   __dyncast_result&
166*e4b17023SJohn Marino   operator=(const __dyncast_result&);
167*e4b17023SJohn Marino };
168*e4b17023SJohn Marino 
169*e4b17023SJohn Marino inline __class_type_info::__sub_kind __class_type_info::
__find_public_src(ptrdiff_t src2dst,const void * obj_ptr,const __class_type_info * src_type,const void * src_ptr)170*e4b17023SJohn Marino __find_public_src (ptrdiff_t src2dst,
171*e4b17023SJohn Marino                    const void *obj_ptr,
172*e4b17023SJohn Marino                    const __class_type_info *src_type,
173*e4b17023SJohn Marino                    const void *src_ptr) const
174*e4b17023SJohn Marino {
175*e4b17023SJohn Marino   if (src2dst >= 0)
176*e4b17023SJohn Marino     return adjust_pointer <void> (obj_ptr, src2dst) == src_ptr
177*e4b17023SJohn Marino             ? __contained_public : __not_contained;
178*e4b17023SJohn Marino   if (src2dst == -2)
179*e4b17023SJohn Marino     return __not_contained;
180*e4b17023SJohn Marino   return __do_find_public_src (src2dst, obj_ptr, src_type, src_ptr);
181*e4b17023SJohn Marino }
182*e4b17023SJohn Marino 
183*e4b17023SJohn Marino }
184