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