OSDN Git Service

* cp-tree.h (flag_new_abi): Move.
[pf3gnuchains/gcc-fork.git] / gcc / cp / tinfo.cc
1 // Methods for type_info for -*- C++ -*- Run Time Type Identification.
2 // Copyright (C) 1994, 1996, 1998, 1999, 2000 Free Software Foundation
3
4 // This file is part of GNU CC.
5
6 // GNU CC 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 2, or (at your option)
9 // any later version.
10
11 // GNU CC 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 // You should have received a copy of the GNU General Public License
17 // along with GNU CC; see the file COPYING.  If not, write to
18 // the Free Software Foundation, 59 Temple Place - Suite 330,
19 // Boston, MA 02111-1307, USA. 
20
21 // As a special exception, if you link this library with other files,
22 // some of which are compiled with GCC, to produce an executable,
23 // this library does not by itself cause the resulting executable
24 // to be covered by the GNU General Public License.
25 // This exception does not however invalidate any other reasons why
26 // the executable file might be covered by the GNU General Public License.
27
28 #pragma implementation "typeinfo"
29
30 #include <stddef.h>
31 #include "tinfo.h"
32 #include "new"                  // for placement new
33
34 namespace
35 {
36 // ADDR is a pointer to an object.  Convert it to a pointer to a base,
37 // using OFFSET.
38 inline void*
39 convert_to_base (void *addr, bool is_virtual, USItype offset)
40 {
41   if (!addr)
42     return NULL;
43
44   if (!is_virtual)
45     return (char *) addr + offset;
46
47 #ifdef __GXX_ABI_VERSION
48   // Under the new ABI, the offset gives us an index into the vtable,
49   // which contains an offset to the virtual base.  The vptr is always
50   // the first thing in the object.
51   std::ptrdiff_t *vtable = *((std::ptrdiff_t **) addr);
52   return ((char *) addr) + vtable[offset];
53 #else
54   // Under the old ABI, the offset gives us the address of a pointer
55   // to the virtual base.
56   return *((void **) ((char *) addr + offset));
57 #endif
58 }
59
60 }
61
62 // This file contains the minimal working set necessary to link with code
63 // that uses virtual functions and -frtti but does not actually use RTTI
64 // functionality.
65
66 std::type_info::
67 ~type_info ()
68 { }
69
70 // We can't rely on common symbols being shared between shared objects.
71 bool std::type_info::
72 operator== (const std::type_info& arg) const
73 {
74   return (&arg == this) || (strcmp (name (), arg.name ()) == 0);
75 }
76
77 extern "C" void
78 __rtti_class (void *addr, const char *name,
79               const __class_type_info::base_info *bl, size_t bn)
80 { new (addr) __class_type_info (name, bl, bn); }
81
82 extern "C" void
83 __rtti_si (void *addr, const char *n, const std::type_info *ti)
84 {
85   new (addr) __si_type_info
86     (n, static_cast <const __user_type_info &> (*ti));
87 }
88
89 extern "C" void
90 __rtti_user (void *addr, const char *name)
91 { new (addr) __user_type_info (name); }
92
93 // Upcast for catch checking. OBJPTR points to the thrown object and might be
94 // NULL. Return 0 on failure, non-zero on success. Set *ADJPTR to adjusted
95 // object pointer.
96 int __user_type_info::
97 upcast (const type_info &target, void *objptr,
98         void **adjptr) const
99 {
100   upcast_result result;
101   
102   if (do_upcast (contained_public, target, objptr, result))
103     return 0;
104   *adjptr = result.target_obj;
105   return contained_public_p (result.whole2target);
106 }
107
108 // Down or cross cast for dynamic_cast. OBJPTR points to the most derrived
109 // object, SUBPTR points to the static base object. Both must not be NULL.
110 // TARGET specifies the desired target type, SUBTYPE specifies the static
111 // type. Both must be defined. Returns adjusted object pointer on success,
112 // NULL on failure. [expr.dynamic.cast]/8 says 'unambiguous public base'. This
113 // itself is an ambiguous statement. We choose it to mean the base must be
114 // separately unambiguous and public, rather than unambiguous considering only
115 // public bases.
116 void *__user_type_info::
117 dyncast (int boff,
118          const type_info &target, void *objptr,
119          const type_info &subtype, void *subptr) const
120 {
121   dyncast_result result;
122   
123   do_dyncast (boff, contained_public,
124               target, objptr, subtype, subptr, result);
125   if (!result.target_obj)
126     return NULL;
127   if (contained_public_p (result.target2sub))
128     return result.target_obj;
129   if (contained_public_p (sub_kind (result.whole2sub & result.whole2target)))
130     // Found a valid cross cast
131     return result.target_obj;
132   if (contained_nonvirtual_p (result.whole2sub))
133     // Found an invalid cross cast, which cannot also be a down cast
134     return NULL;
135   if (result.target2sub == unknown)
136     result.target2sub = static_cast <const __user_type_info &> (target)
137                         .find_public_subobj (boff, subtype,
138                                              result.target_obj, subptr);
139   if (contained_public_p (result.target2sub))
140     // Found a valid down cast
141     return result.target_obj;
142   // Must be an invalid down cast, or the cross cast wasn't bettered
143   return NULL;
144 }
145
146 // Catch cast helper. ACCESS_PATH is the access from the complete thrown
147 // object to this base. TARGET is the desired type we want to catch. OBJPTR
148 // points to this base within the throw object, it might be NULL. Fill in
149 // RESULT with what we find. Return true, should we determine catch must fail.
150 bool __user_type_info::
151 do_upcast (sub_kind access_path,
152            const type_info &target, void *objptr,
153            upcast_result &__restrict result) const
154 {
155   if (*this == target)
156     {
157       result.target_obj = objptr;
158       result.base_type = nonvirtual_base_type;
159       result.whole2target = access_path;
160       return contained_nonpublic_p (access_path);
161     }
162   return false;
163 }
164
165 // dynamic cast helper. ACCESS_PATH gives the access from the most derived
166 // object to this base. TARGET indicates the desired type we want. OBJPTR
167 // points to this base within the object. SUBTYPE indicates the static type
168 // started from and SUBPTR points to that base within the most derived object.
169 // Fill in RESULT with what we find. Return true if we have located an
170 // ambiguous match.
171 bool __user_type_info::
172 do_dyncast (int, sub_kind access_path,
173             const type_info &target, void *objptr,
174             const type_info &subtype, void *subptr,
175             dyncast_result &__restrict result) const
176 {
177   if (objptr == subptr && *this == subtype)
178     {
179       // The subobject we started from. Indicate how we are accessible from
180       // the most derived object.
181       result.whole2sub = access_path;
182       return false;
183     }
184   if (*this == target)
185     {
186       result.target_obj = objptr;
187       result.whole2target = access_path;
188       result.target2sub = not_contained;
189       return false;
190     }
191   return false;
192 }
193
194 // find_public_subobj helper. Return contained_public if we are the desired
195 // subtype. OBJPTR points to this base type, SUBPTR points to the desired base
196 // object.
197 __user_type_info::sub_kind __user_type_info::
198 do_find_public_subobj (int, const type_info &, void *objptr, void *subptr) const
199 {
200   if (subptr == objptr)
201     // Must be our type, as the pointers match.
202     return contained_public;
203   return not_contained;
204 }
205
206 // catch helper for single public inheritance types. See
207 // __user_type_info::do_upcast for semantics.
208 bool __si_type_info::
209 do_upcast (sub_kind access_path,
210            const type_info &target, void *objptr,
211            upcast_result &__restrict result) const
212 {
213   if (*this == target)
214     {
215       result.target_obj = objptr;
216       result.base_type = nonvirtual_base_type;
217       result.whole2target = access_path;
218       return contained_nonpublic_p (access_path);
219     }
220   return base.do_upcast (access_path, target, objptr, result);
221 }
222
223 // dynamic cast helper for single public inheritance types. See
224 // __user_type_info::do_dyncast for semantics. BOFF indicates how SUBTYPE
225 // types are inherited by TARGET types.
226 bool __si_type_info::
227 do_dyncast (int boff, sub_kind access_path,
228             const type_info &target, void *objptr,
229             const type_info &subtype, void *subptr,
230             dyncast_result &__restrict result) const
231 {
232   if (objptr == subptr && *this == subtype)
233     {
234       // The subobject we started from. Indicate how we are accessible from
235       // the most derived object.
236       result.whole2sub = access_path;
237       return false;
238     }
239   if (*this == target)
240     {
241       result.target_obj = objptr;
242       result.whole2target = access_path;
243       if (boff >= 0)
244         result.target2sub = ((char *)subptr - (char *)objptr) == boff
245               ? contained_public : not_contained;
246       else if (boff == -3)
247         result.target2sub = not_contained;
248       return false;
249     }
250   return base.do_dyncast (boff, access_path,
251                           target, objptr, subtype, subptr, result);
252 }
253
254 // find_public_subobj helper. See __user_type_info::do_find_public_subobj or
255 // semantics. BOFF indicates how SUBTYPE types are inherited by the original
256 // target object.
257 __user_type_info::sub_kind __si_type_info::
258 do_find_public_subobj (int boff, const type_info &subtype, void *objptr, void *subptr) const
259 {
260   if (subptr == objptr && subtype == *this)
261     return contained_public;
262   return base.do_find_public_subobj (boff, subtype, objptr, subptr);
263 }
264
265 // catch helper for multiple or non-public inheritance types. See
266 // __user_type_info::do_upcast for semantics.
267 bool __class_type_info::
268 do_upcast (sub_kind access_path,
269            const type_info &target, void *objptr,
270            upcast_result &__restrict result) const
271 {
272   if (*this == target)
273     {
274       result.target_obj = objptr;
275       result.base_type = nonvirtual_base_type;
276       result.whole2target = access_path;
277       return contained_nonpublic_p (access_path);
278     }
279   
280   for (size_t i = n_bases; i--;)
281     {
282       upcast_result result2;
283       void *p = objptr;
284       sub_kind sub_access = access_path;
285       p = convert_to_base (p, 
286                            base_list[i].is_virtual,
287                            base_list[i].offset);
288       if (base_list[i].is_virtual)
289         sub_access = sub_kind (sub_access | contained_virtual_mask);
290       if (base_list[i].access != PUBLIC)
291         sub_access = sub_kind (sub_access & ~contained_public_mask);
292       if (base_list[i].base->do_upcast (sub_access, target, p, result2))
293         return true; // must fail
294       if (result2.base_type)
295         {
296           if (result2.base_type == nonvirtual_base_type
297               && base_list[i].is_virtual)
298             result2.base_type = base_list[i].base;
299           if (!result.base_type)
300             result = result2;
301           else if (result.target_obj != result2.target_obj)
302             {
303               // Found an ambiguity.
304               result.target_obj = NULL;
305               result.whole2target = contained_ambig;
306               return true;
307             }
308           else if (result.target_obj)
309             {
310               // Ok, found real object via a virtual path.
311               result.whole2target
312                   = sub_kind (result.whole2target | result2.whole2target);
313             }
314           else
315             {
316               // Dealing with a null pointer, need to check vbase
317               // containing each of the two choices.
318               if (result2.base_type == nonvirtual_base_type
319                   || result.base_type == nonvirtual_base_type
320                   || !(*result2.base_type == *result.base_type))
321                 {
322                   // Already ambiguous, not virtual or via different virtuals.
323                   // Cannot match.
324                   result.whole2target = contained_ambig;
325                   return true;
326                 }
327             }
328         }
329     }
330   return false;
331 }
332
333 // dynamic cast helper for non-public or multiple inheritance types. See
334 // __user_type_info::do_dyncast for overall semantics.
335 // This is a big hairy function. Although the run-time behaviour of
336 // dynamic_cast is simple to describe, it gives rise to some non-obvious
337 // behaviour. We also desire to determine as early as possible any definite
338 // answer we can get. Because it is unknown what the run-time ratio of
339 // succeeding to failing dynamic casts is, we do not know in which direction
340 // to bias any optimizations. To that end we make no particular effort towards
341 // early fail answers or early success answers. Instead we try to minimize
342 // work by filling in things lazily (when we know we need the information),
343 // and opportunisticly take early success or failure results.
344 bool __class_type_info::
345 do_dyncast (int boff, sub_kind access_path,
346             const type_info &target, void *objptr,
347             const type_info &subtype, void *subptr,
348             dyncast_result &__restrict result) const
349 {
350   if (objptr == subptr && *this == subtype)
351     {
352       // The subobject we started from. Indicate how we are accessible from
353       // the most derived object.
354       result.whole2sub = access_path;
355       return false;
356     }
357   if (*this == target)
358     {
359       result.target_obj = objptr;
360       result.whole2target = access_path;
361       if (boff >= 0)
362         result.target2sub = ((char *)subptr - (char *)objptr) == boff
363               ? contained_public : not_contained;
364       else if (boff == -3)
365         result.target2sub = not_contained;
366       return false;
367     }
368   bool result_ambig = false;
369   for (size_t i = n_bases; i--;)
370     {
371       dyncast_result result2;
372       void *p;
373       sub_kind sub_access = access_path;
374       p = convert_to_base (objptr, 
375                            base_list[i].is_virtual,
376                            base_list[i].offset);
377       if (base_list[i].is_virtual)
378         sub_access = sub_kind (sub_access | contained_virtual_mask);
379       if (base_list[i].access != PUBLIC)
380         sub_access = sub_kind (sub_access & ~contained_public_mask);
381       
382       bool result2_ambig
383           = base_list[i].base->do_dyncast (boff, sub_access,
384                                            target, p, subtype, subptr, result2);
385       result.whole2sub = sub_kind (result.whole2sub | result2.whole2sub);
386       if (result2.target2sub == contained_public
387           || result2.target2sub == contained_ambig)
388         {
389           result.target_obj = result2.target_obj;
390           result.whole2target = result2.whole2target;
391           result.target2sub = result2.target2sub;
392           // Found a downcast which can't be bettered or an ambiguous downcast
393           // which can't be disambiguated
394           return result2_ambig;
395         }
396       
397       if (!result_ambig && !result.target_obj)
398         {
399           // Not found anything yet.
400           result.target_obj = result2.target_obj;
401           result.whole2target = result2.whole2target;
402           result_ambig = result2_ambig;
403         }
404       else if (result.target_obj && result.target_obj == result2.target_obj)
405         {
406           // Found at same address, must be via virtual.  Pick the most
407           // accessible path.
408           result.whole2target =
409               sub_kind (result.whole2target | result2.whole2target);
410         }
411       else if ((result.target_obj && result2.target_obj)
412                || (result_ambig && result2.target_obj)
413                || (result2_ambig && result.target_obj))
414         {
415           // Found two different TARGET bases, or a valid one and a set of
416           // ambiguous ones, must disambiguate. See whether SUBOBJ is
417           // contained publicly within one of the non-ambiguous choices.
418           // If it is in only one, then that's the choice. If it is in
419           // both, then we're ambiguous and fail. If it is in neither,
420           // we're ambiguous, but don't yet fail as we might later find a
421           // third base which does contain SUBPTR.
422         
423           sub_kind new_sub_kind = result2.target2sub;
424           sub_kind old_sub_kind = result.target2sub;
425           
426           if (contained_nonvirtual_p (result.whole2sub))
427             {
428               // We already found SUBOBJ as a non-virtual base of most
429               // derived. Therefore if it is in either choice, it can only be
430               // in one of them, and we will already know.
431               if (old_sub_kind == unknown)
432                 old_sub_kind = not_contained;
433               if (new_sub_kind == unknown)
434                 new_sub_kind = not_contained;
435             }
436           else
437             {
438               const __user_type_info &t =
439                   static_cast <const __user_type_info &> (target);
440               
441               if (old_sub_kind >= not_contained)
442                 ;// already calculated
443               else if (contained_nonvirtual_p (new_sub_kind))
444                 // Already found non-virtually inside the other choice,
445                 // cannot be in this.
446                 old_sub_kind = not_contained;
447               else
448                 old_sub_kind = t.find_public_subobj (boff, subtype,
449                                                      result.target_obj, subptr);
450           
451               if (new_sub_kind >= not_contained)
452                 ;// already calculated
453               else if (contained_nonvirtual_p (old_sub_kind))
454                 // Already found non-virtually inside the other choice,
455                 // cannot be in this.
456                 new_sub_kind = not_contained;
457               else
458                 new_sub_kind = t.find_public_subobj (boff, subtype,
459                                                      result2.target_obj, subptr);
460             }
461           
462           // Neither sub_kind can be contained_ambig -- we bail out early
463           // when we find those.
464           if (contained_p (sub_kind (new_sub_kind ^ old_sub_kind)))
465             {
466               // Only on one choice, not ambiguous.
467               if (contained_p (new_sub_kind))
468                 {
469                   // Only in new.
470                   result.target_obj = result2.target_obj;
471                   result.whole2target = result2.whole2target;
472                   result_ambig = false;
473                   old_sub_kind = new_sub_kind;
474                 }
475               result.target2sub = old_sub_kind;
476               if (result.target2sub == contained_public)
477                 return false; // Can't be an ambiguating downcast for later discovery.
478             }
479           else if (contained_p (sub_kind (new_sub_kind & old_sub_kind)))
480             {
481               // In both.
482               result.target_obj = NULL;
483               result.target2sub = contained_ambig;
484               return true;  // Fail.
485             }
486           else
487             {
488               // In neither publicly, ambiguous for the moment, but keep
489               // looking. It is possible that it was private in one or
490               // both and therefore we should fail, but that's just tough.
491               result.target_obj = NULL;
492               result.target2sub = not_contained;
493               result_ambig = true;
494             }
495         }
496       
497       if (result.whole2sub == contained_private)
498         // We found SUBOBJ as a private non-virtual base, therefore all
499         // cross casts will fail. We have already found a down cast, if
500         // there is one.
501         return result_ambig;
502     }
503
504   return result_ambig;
505 }
506
507 // find_public_subobj helper for non-public or multiple inheritance types. See
508 // __user_type_info::do_find_public_subobj for semantics. We make use of BOFF
509 // to prune the base class walk.
510 __user_type_info::sub_kind __class_type_info::
511 do_find_public_subobj (int boff, const type_info &subtype, void *objptr, void *subptr) const
512 {
513   if (objptr == subptr && subtype == *this)
514     return contained_public;
515   
516   for (size_t i = n_bases; i--;)
517     {
518       if (base_list[i].access != PUBLIC)
519         continue; // Not public, can't be here.
520       void *p;
521
522       if (base_list[i].is_virtual && boff == -1)
523         // Not a virtual base, so can't be here.
524         continue;
525       
526       p = convert_to_base (objptr, 
527                            base_list[i].is_virtual,
528                            base_list[i].offset);
529
530       sub_kind base_kind = base_list[i].base->do_find_public_subobj
531                               (boff, subtype, p, subptr);
532       if (contained_p (base_kind))
533         {
534           if (base_list[i].is_virtual)
535             base_kind = sub_kind (base_kind | contained_virtual_mask);
536           return base_kind;
537         }
538     }
539   
540   return not_contained;
541 }