OSDN Git Service

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