gcc50/csu: Skip depends step to avoid possible race
[dragonfly.git] / contrib / gcc-4.4 / 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   bool result_ambig = false;
112   for (std::size_t i = __base_count; i--;)
113     {
114       __dyncast_result result2 (result.whole_details);
115       void const *base = obj_ptr;
116       __sub_kind base_access = access_path;
117       ptrdiff_t offset = __base_info[i].__offset ();
118       bool is_virtual = __base_info[i].__is_virtual_p ();
119       
120       if (is_virtual)
121         base_access = __sub_kind (base_access | __contained_virtual_mask);
122       base = convert_to_base (base, is_virtual, offset);
123
124       if (!__base_info[i].__is_public_p ())
125         {
126           if (src2dst == -2 &&
127               !(result.whole_details
128                 & (__non_diamond_repeat_mask | __diamond_shaped_mask)))
129             // The hierarchy has no duplicate bases (which might ambiguate
130             // things) and where we started is not a public base of what we
131             // want (so it cannot be a downcast). There is nothing of interest
132             // hiding in a non-public base.
133             continue;
134           base_access = __sub_kind (base_access & ~__contained_public_mask);
135         }
136       
137       bool result2_ambig
138           = __base_info[i].__base_type->__do_dyncast (src2dst, base_access,
139                                              dst_type, base,
140                                              src_type, src_ptr, result2);
141       result.whole2src = __sub_kind (result.whole2src | result2.whole2src);
142       if (result2.dst2src == __contained_public
143           || result2.dst2src == __contained_ambig)
144         {
145           result.dst_ptr = result2.dst_ptr;
146           result.whole2dst = result2.whole2dst;
147           result.dst2src = result2.dst2src;
148           // Found a downcast which can't be bettered or an ambiguous downcast
149           // which can't be disambiguated
150           return result2_ambig;
151         }
152       
153       if (!result_ambig && !result.dst_ptr)
154         {
155           // Not found anything yet.
156           result.dst_ptr = result2.dst_ptr;
157           result.whole2dst = result2.whole2dst;
158           result_ambig = result2_ambig;
159           if (result.dst_ptr && result.whole2src != __unknown
160               && !(__flags & __non_diamond_repeat_mask))
161             // Found dst and src and we don't have repeated bases.
162             return result_ambig;
163         }
164       else if (result.dst_ptr && result.dst_ptr == result2.dst_ptr)
165         {
166           // Found at same address, must be via virtual.  Pick the most
167           // accessible path.
168           result.whole2dst =
169               __sub_kind (result.whole2dst | result2.whole2dst);
170         }
171       else if ((result.dst_ptr != 0 && result2.dst_ptr != 0)
172                || (result.dst_ptr != 0 && result2_ambig)
173                || (result2.dst_ptr != 0 && result_ambig))
174         {
175           // Found two different DST_TYPE bases, or a valid one and a set of
176           // ambiguous ones, must disambiguate. See whether SRC_PTR is
177           // contained publicly within one of the non-ambiguous choices. If it
178           // is in only one, then that's the choice. If it is in both, then
179           // we're ambiguous and fail. If it is in neither, we're ambiguous,
180           // but don't yet fail as we might later find a third base which does
181           // contain SRC_PTR.
182         
183           __sub_kind new_sub_kind = result2.dst2src;
184           __sub_kind old_sub_kind = result.dst2src;
185           
186           if (contained_p (result.whole2src)
187               && (!virtual_p (result.whole2src)
188                   || !(result.whole_details & __diamond_shaped_mask)))
189             {
190               // We already found SRC_PTR as a base of most derived, and
191               // either it was non-virtual, or the whole hierarchy is
192               // not-diamond shaped. Therefore if it is in either choice, it
193               // can only be in one of them, and we will already know.
194               if (old_sub_kind == __unknown)
195                 old_sub_kind = __not_contained;
196               if (new_sub_kind == __unknown)
197                 new_sub_kind = __not_contained;
198             }
199           else
200             {
201               if (old_sub_kind >= __not_contained)
202                 ;// already calculated
203               else if (contained_p (new_sub_kind)
204                        && (!virtual_p (new_sub_kind)
205                            || !(__flags & __diamond_shaped_mask)))
206                 // Already found inside the other choice, and it was
207                 // non-virtual or we are not diamond shaped.
208                 old_sub_kind = __not_contained;
209               else
210                 old_sub_kind = dst_type->__find_public_src
211                                 (src2dst, result.dst_ptr, src_type, src_ptr);
212           
213               if (new_sub_kind >= __not_contained)
214                 ;// already calculated
215               else if (contained_p (old_sub_kind)
216                        && (!virtual_p (old_sub_kind)
217                            || !(__flags & __diamond_shaped_mask)))
218                 // Already found inside the other choice, and it was
219                 // non-virtual or we are not diamond shaped.
220                 new_sub_kind = __not_contained;
221               else
222                 new_sub_kind = dst_type->__find_public_src
223                                 (src2dst, result2.dst_ptr, src_type, src_ptr);
224             }
225           
226           // Neither sub_kind can be contained_ambig -- we bail out early
227           // when we find those.
228           if (contained_p (__sub_kind (new_sub_kind ^ old_sub_kind)))
229             {
230               // Only on one choice, not ambiguous.
231               if (contained_p (new_sub_kind))
232                 {
233                   // Only in new.
234                   result.dst_ptr = result2.dst_ptr;
235                   result.whole2dst = result2.whole2dst;
236                   result_ambig = false;
237                   old_sub_kind = new_sub_kind;
238                 }
239               result.dst2src = old_sub_kind;
240               if (public_p (result.dst2src))
241                 return false; // Can't be an ambiguating downcast for later discovery.
242               if (!virtual_p (result.dst2src))
243                 return false; // Found non-virtually can't be bettered
244             }
245           else if (contained_p (__sub_kind (new_sub_kind & old_sub_kind)))
246             {
247               // In both.
248               result.dst_ptr = NULL;
249               result.dst2src = __contained_ambig;
250               return true;  // Fail.
251             }
252           else
253             {
254               // In neither publicly, ambiguous for the moment, but keep
255               // looking. It is possible that it was private in one or
256               // both and therefore we should fail, but that's just tough.
257               result.dst_ptr = NULL;
258               result.dst2src = __not_contained;
259               result_ambig = true;
260             }
261         }
262       
263       if (result.whole2src == __contained_private)
264         // We found SRC_PTR as a private non-virtual base, therefore all
265         // cross casts will fail. We have already found a down cast, if
266         // there is one.
267         return result_ambig;
268     }
269
270   return result_ambig;
271 }
272
273 bool __vmi_class_type_info::
274 __do_upcast (const __class_type_info *dst, const void *obj_ptr,
275              __upcast_result &__restrict result) const
276 {
277   if (__class_type_info::__do_upcast (dst, obj_ptr, result))
278     return true;
279   
280   int src_details = result.src_details;
281   if (src_details & __flags_unknown_mask)
282     src_details = __flags;
283   
284   for (std::size_t i = __base_count; i--;)
285     {
286       __upcast_result result2 (src_details);
287       const void *base = obj_ptr;
288       ptrdiff_t offset = __base_info[i].__offset ();
289       bool is_virtual = __base_info[i].__is_virtual_p ();
290       bool is_public = __base_info[i].__is_public_p ();
291       
292       if (!is_public && !(src_details & __non_diamond_repeat_mask))
293         // original cannot have an ambiguous base, so skip private bases
294         continue;
295
296       if (base)
297         base = convert_to_base (base, is_virtual, offset);
298       
299       if (__base_info[i].__base_type->__do_upcast (dst, base, result2))
300         {
301           if (result2.base_type == nonvirtual_base_type && is_virtual)
302             result2.base_type = __base_info[i].__base_type;
303           if (contained_p (result2.part2dst) && !is_public)
304             result2.part2dst = __sub_kind (result2.part2dst & ~__contained_public_mask);
305           
306           if (!result.base_type)
307             {
308               result = result2;
309               if (!contained_p (result.part2dst))
310                 return true; // found ambiguously
311               
312               if (result.part2dst & __contained_public_mask)
313                 {
314                   if (!(__flags & __non_diamond_repeat_mask))
315                     return true;  // cannot have an ambiguous other base
316                 }
317               else
318                 {
319                   if (!virtual_p (result.part2dst))
320                     return true; // cannot have another path
321                   if (!(__flags & __diamond_shaped_mask))
322                     return true; // cannot have a more accessible path
323                 }
324             }
325           else if (result.dst_ptr != result2.dst_ptr)
326             {
327               // Found an ambiguity.
328               result.dst_ptr = NULL;
329               result.part2dst = __contained_ambig;
330               return true;
331             }
332           else if (result.dst_ptr)
333             {
334               // Ok, found real object via a virtual path.
335               result.part2dst
336                   = __sub_kind (result.part2dst | result2.part2dst);
337             }
338           else
339             {
340               // Dealing with a null pointer, need to check vbase
341               // containing each of the two choices.
342               if (result2.base_type == nonvirtual_base_type
343                   || result.base_type == nonvirtual_base_type
344                   || !(*result2.base_type == *result.base_type))
345                 {
346                   // Already ambiguous, not virtual or via different virtuals.
347                   // Cannot match.
348                   result.part2dst = __contained_ambig;
349                   return true;
350                 }
351               result.part2dst
352                   = __sub_kind (result.part2dst | result2.part2dst);
353             }
354         }
355     }
356   return result.part2dst != __unknown;
357 }
358
359 }