OSDN Git Service

2014-04-04 Richard Biener <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / libsupc++ / vmi_class_type_info.cc
1 // Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007, 2009
2 // Free Software Foundation
3 //
4 // This file is part of GCC.
5 //
6 // GCC 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 3, or (at your option)
9 // any later version.
10
11 // GCC 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.
15
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
24
25 #include "tinfo.h"
26
27 namespace __cxxabiv1 {
28
29 __vmi_class_type_info::
30 ~__vmi_class_type_info ()
31 {}
32
33 __class_type_info::__sub_kind __vmi_class_type_info::
34 __do_find_public_src (ptrdiff_t src2dst,
35                       const void *obj_ptr,
36                       const __class_type_info *src_type,
37                       const void *src_ptr) const
38 {
39   if (obj_ptr == src_ptr && *this == *src_type)
40     return __contained_public;
41   
42   for (std::size_t i = __base_count; i--;)
43     {
44       if (!__base_info[i].__is_public_p ())
45         continue; // Not public, can't be here.
46       
47       const void *base = obj_ptr;
48       ptrdiff_t offset = __base_info[i].__offset ();
49       bool is_virtual = __base_info[i].__is_virtual_p ();
50       
51       if (is_virtual)
52         {
53           if (src2dst == -3)
54             continue; // Not a virtual base, so can't be here.
55         }
56       base = convert_to_base (base, is_virtual, offset);
57       
58       __sub_kind base_kind = __base_info[i].__base_type->__do_find_public_src
59                               (src2dst, base, src_type, src_ptr);
60       if (contained_p (base_kind))
61         {
62           if (is_virtual)
63             base_kind = __sub_kind (base_kind | __contained_virtual_mask);
64           return base_kind;
65         }
66     }
67   
68   return __not_contained;
69 }
70
71 // This is a big hairy function. Although the run-time behaviour of
72 // dynamic_cast is simple to describe, it gives rise to some non-obvious
73 // behaviour. We also desire to determine as early as possible any definite
74 // answer we can get. Because it is unknown what the run-time ratio of
75 // succeeding to failing dynamic casts is, we do not know in which direction
76 // to bias any optimizations. To that end we make no particular effort towards
77 // early fail answers or early success answers. Instead we try to minimize
78 // work by filling in things lazily (when we know we need the information),
79 // and opportunisticly take early success or failure results.
80 bool __vmi_class_type_info::
81 __do_dyncast (ptrdiff_t src2dst,
82               __sub_kind access_path,
83               const __class_type_info *dst_type,
84               const void *obj_ptr,
85               const __class_type_info *src_type,
86               const void *src_ptr,
87               __dyncast_result &__restrict result) const
88 {
89   if (result.whole_details & __flags_unknown_mask)
90     result.whole_details = __flags;
91   
92   if (obj_ptr == src_ptr && *this == *src_type)
93     {
94       // The src object we started from. Indicate how we are accessible from
95       // the most derived object.
96       result.whole2src = access_path;
97       return false;
98     }
99   if (*this == *dst_type)
100     {
101       result.dst_ptr = obj_ptr;
102       result.whole2dst = access_path;
103       if (src2dst >= 0)
104         result.dst2src = adjust_pointer <void> (obj_ptr, src2dst) == src_ptr
105               ? __contained_public : __not_contained;
106       else if (src2dst == -2)
107         result.dst2src = __not_contained;
108       return false;
109     }
110
111   // If src_type is a unique non-virtual base of dst_type, we have a good
112   // guess at the address we want, so in the first pass try skipping any
113   // bases which don't contain that address.
114   const void *dst_cand = NULL;
115   if (src2dst >= 0)
116     dst_cand = adjust_pointer<void>(src_ptr, -src2dst);
117   bool first_pass = true;
118   bool skipped = false;
119
120   bool result_ambig = false;
121  again:
122   for (std::size_t i = __base_count; i--;)
123     {
124       __dyncast_result result2 (result.whole_details);
125       void const *base = obj_ptr;
126       __sub_kind base_access = access_path;
127       ptrdiff_t offset = __base_info[i].__offset ();
128       bool is_virtual = __base_info[i].__is_virtual_p ();
129       
130       if (is_virtual)
131         base_access = __sub_kind (base_access | __contained_virtual_mask);
132       base = convert_to_base (base, is_virtual, offset);
133
134       if (dst_cand)
135         {
136           bool skip_on_first_pass = base > dst_cand;
137           if (skip_on_first_pass == first_pass)
138             {
139               // We aren't interested in this base on this pass: either
140               // we're on the first pass and this base doesn't contain the
141               // likely address, or we're on the second pass and we checked
142               // this base on the first pass.
143               skipped = true;
144               continue;
145             }
146         }
147
148       if (!__base_info[i].__is_public_p ())
149         {
150           if (src2dst == -2 &&
151               !(result.whole_details
152                 & (__non_diamond_repeat_mask | __diamond_shaped_mask)))
153             // The hierarchy has no duplicate bases (which might ambiguate
154             // things) and where we started is not a public base of what we
155             // want (so it cannot be a downcast). There is nothing of interest
156             // hiding in a non-public base.
157             continue;
158           base_access = __sub_kind (base_access & ~__contained_public_mask);
159         }
160       
161       bool result2_ambig
162           = __base_info[i].__base_type->__do_dyncast (src2dst, base_access,
163                                              dst_type, base,
164                                              src_type, src_ptr, result2);
165       result.whole2src = __sub_kind (result.whole2src | result2.whole2src);
166       if (result2.dst2src == __contained_public
167           || result2.dst2src == __contained_ambig)
168         {
169           result.dst_ptr = result2.dst_ptr;
170           result.whole2dst = result2.whole2dst;
171           result.dst2src = result2.dst2src;
172           // Found a downcast which can't be bettered or an ambiguous downcast
173           // which can't be disambiguated
174           return result2_ambig;
175         }
176       
177       if (!result_ambig && !result.dst_ptr)
178         {
179           // Not found anything yet.
180           result.dst_ptr = result2.dst_ptr;
181           result.whole2dst = result2.whole2dst;
182           result_ambig = result2_ambig;
183           if (result.dst_ptr && result.whole2src != __unknown
184               && !(__flags & __non_diamond_repeat_mask))
185             // Found dst and src and we don't have repeated bases.
186             return result_ambig;
187         }
188       else if (result.dst_ptr && result.dst_ptr == result2.dst_ptr)
189         {
190           // Found at same address, must be via virtual.  Pick the most
191           // accessible path.
192           result.whole2dst =
193               __sub_kind (result.whole2dst | result2.whole2dst);
194         }
195       else if ((result.dst_ptr != 0 && result2.dst_ptr != 0)
196                || (result.dst_ptr != 0 && result2_ambig)
197                || (result2.dst_ptr != 0 && result_ambig))
198         {
199           // Found two different DST_TYPE bases, or a valid one and a set of
200           // ambiguous ones, must disambiguate. See whether SRC_PTR is
201           // contained publicly within one of the non-ambiguous choices. If it
202           // is in only one, then that's the choice. If it is in both, then
203           // we're ambiguous and fail. If it is in neither, we're ambiguous,
204           // but don't yet fail as we might later find a third base which does
205           // contain SRC_PTR.
206         
207           __sub_kind new_sub_kind = result2.dst2src;
208           __sub_kind old_sub_kind = result.dst2src;
209           
210           if (contained_p (result.whole2src)
211               && (!virtual_p (result.whole2src)
212                   || !(result.whole_details & __diamond_shaped_mask)))
213             {
214               // We already found SRC_PTR as a base of most derived, and
215               // either it was non-virtual, or the whole hierarchy is
216               // not-diamond shaped. Therefore if it is in either choice, it
217               // can only be in one of them, and we will already know.
218               if (old_sub_kind == __unknown)
219                 old_sub_kind = __not_contained;
220               if (new_sub_kind == __unknown)
221                 new_sub_kind = __not_contained;
222             }
223           else
224             {
225               if (old_sub_kind >= __not_contained)
226                 ;// already calculated
227               else if (contained_p (new_sub_kind)
228                        && (!virtual_p (new_sub_kind)
229                            || !(__flags & __diamond_shaped_mask)))
230                 // Already found inside the other choice, and it was
231                 // non-virtual or we are not diamond shaped.
232                 old_sub_kind = __not_contained;
233               else
234                 old_sub_kind = dst_type->__find_public_src
235                                 (src2dst, result.dst_ptr, src_type, src_ptr);
236           
237               if (new_sub_kind >= __not_contained)
238                 ;// already calculated
239               else if (contained_p (old_sub_kind)
240                        && (!virtual_p (old_sub_kind)
241                            || !(__flags & __diamond_shaped_mask)))
242                 // Already found inside the other choice, and it was
243                 // non-virtual or we are not diamond shaped.
244                 new_sub_kind = __not_contained;
245               else
246                 new_sub_kind = dst_type->__find_public_src
247                                 (src2dst, result2.dst_ptr, src_type, src_ptr);
248             }
249           
250           // Neither sub_kind can be contained_ambig -- we bail out early
251           // when we find those.
252           if (contained_p (__sub_kind (new_sub_kind ^ old_sub_kind)))
253             {
254               // Only on one choice, not ambiguous.
255               if (contained_p (new_sub_kind))
256                 {
257                   // Only in new.
258                   result.dst_ptr = result2.dst_ptr;
259                   result.whole2dst = result2.whole2dst;
260                   result_ambig = false;
261                   old_sub_kind = new_sub_kind;
262                 }
263               result.dst2src = old_sub_kind;
264               if (public_p (result.dst2src))
265                 return false; // Can't be an ambiguating downcast for later discovery.
266               if (!virtual_p (result.dst2src))
267                 return false; // Found non-virtually can't be bettered
268             }
269           else if (contained_p (__sub_kind (new_sub_kind & old_sub_kind)))
270             {
271               // In both.
272               result.dst_ptr = NULL;
273               result.dst2src = __contained_ambig;
274               return true;  // Fail.
275             }
276           else
277             {
278               // In neither publicly, ambiguous for the moment, but keep
279               // looking. It is possible that it was private in one or
280               // both and therefore we should fail, but that's just tough.
281               result.dst_ptr = NULL;
282               result.dst2src = __not_contained;
283               result_ambig = true;
284             }
285         }
286       
287       if (result.whole2src == __contained_private)
288         // We found SRC_PTR as a private non-virtual base, therefore all
289         // cross casts will fail. We have already found a down cast, if
290         // there is one.
291         return result_ambig;
292     }
293
294   if (skipped && first_pass)
295     {
296       // We didn't find dst where we expected it, so let's go back and try
297       // the bases we skipped (if any).
298       first_pass = false;
299       goto again;
300     }
301
302   return result_ambig;
303 }
304
305 bool __vmi_class_type_info::
306 __do_upcast (const __class_type_info *dst, const void *obj_ptr,
307              __upcast_result &__restrict result) const
308 {
309   if (__class_type_info::__do_upcast (dst, obj_ptr, result))
310     return true;
311   
312   int src_details = result.src_details;
313   if (src_details & __flags_unknown_mask)
314     src_details = __flags;
315   
316   for (std::size_t i = __base_count; i--;)
317     {
318       __upcast_result result2 (src_details);
319       const void *base = obj_ptr;
320       ptrdiff_t offset = __base_info[i].__offset ();
321       bool is_virtual = __base_info[i].__is_virtual_p ();
322       bool is_public = __base_info[i].__is_public_p ();
323       
324       if (!is_public && !(src_details & __non_diamond_repeat_mask))
325         // original cannot have an ambiguous base, so skip private bases
326         continue;
327
328       if (base)
329         base = convert_to_base (base, is_virtual, offset);
330       
331       if (__base_info[i].__base_type->__do_upcast (dst, base, result2))
332         {
333           if (result2.base_type == nonvirtual_base_type && is_virtual)
334             result2.base_type = __base_info[i].__base_type;
335           if (contained_p (result2.part2dst) && !is_public)
336             result2.part2dst = __sub_kind (result2.part2dst & ~__contained_public_mask);
337           
338           if (!result.base_type)
339             {
340               result = result2;
341               if (!contained_p (result.part2dst))
342                 return true; // found ambiguously
343               
344               if (result.part2dst & __contained_public_mask)
345                 {
346                   if (!(__flags & __non_diamond_repeat_mask))
347                     return true;  // cannot have an ambiguous other base
348                 }
349               else
350                 {
351                   if (!virtual_p (result.part2dst))
352                     return true; // cannot have another path
353                   if (!(__flags & __diamond_shaped_mask))
354                     return true; // cannot have a more accessible path
355                 }
356             }
357           else if (result.dst_ptr != result2.dst_ptr)
358             {
359               // Found an ambiguity.
360               result.dst_ptr = NULL;
361               result.part2dst = __contained_ambig;
362               return true;
363             }
364           else if (result.dst_ptr)
365             {
366               // Ok, found real object via a virtual path.
367               result.part2dst
368                   = __sub_kind (result.part2dst | result2.part2dst);
369             }
370           else
371             {
372               // Dealing with a null pointer, need to check vbase
373               // containing each of the two choices.
374               if (result2.base_type == nonvirtual_base_type
375                   || result.base_type == nonvirtual_base_type
376                   || !(*result2.base_type == *result.base_type))
377                 {
378                   // Already ambiguous, not virtual or via different virtuals.
379                   // Cannot match.
380                   result.part2dst = __contained_ambig;
381                   return true;
382                 }
383               result.part2dst
384                   = __sub_kind (result.part2dst | result2.part2dst);
385             }
386         }
387     }
388   return result.part2dst != __unknown;
389 }
390
391 }