1 // Methods for type_info for -*- C++ -*- Run Time Type Identification.
2 // Copyright (C) 1994, 1996, 1998, 1999, 2000 Free Software Foundation
4 // This file is part of GNU CC.
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)
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.
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.
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.
28 #pragma implementation "typeinfo"
32 #include "new" // for placement new
36 // ADDR is a pointer to an object. Convert it to a pointer to a base,
39 convert_to_base (void *addr, bool is_virtual, USItype offset)
45 return (char *) addr + offset;
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];
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));
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
70 // We can't rely on common symbols being shared between shared objects.
72 operator== (const std::type_info& arg) const
74 return (&arg == this) || (strcmp (name (), arg.name ()) == 0);
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); }
83 __rtti_si (void *addr, const char *n, const std::type_info *ti)
85 new (addr) __si_type_info
86 (n, static_cast <const __user_type_info &> (*ti));
90 __rtti_user (void *addr, const char *name)
91 { new (addr) __user_type_info (name); }
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
96 int __user_type_info::
97 upcast (const type_info &target, void *objptr,
100 upcast_result result;
102 if (do_upcast (contained_public, target, objptr, result))
104 *adjptr = result.target_obj;
105 return contained_public_p (result.whole2target);
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
116 void *__user_type_info::
118 const type_info &target, void *objptr,
119 const type_info &subtype, void *subptr) const
121 dyncast_result result;
123 do_dyncast (boff, contained_public,
124 target, objptr, subtype, subptr, result);
125 if (!result.target_obj)
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
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
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
157 result.target_obj = objptr;
158 result.base_type = nonvirtual_base_type;
159 result.whole2target = access_path;
160 return contained_nonpublic_p (access_path);
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
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
177 if (objptr == subptr && *this == subtype)
179 // The subobject we started from. Indicate how we are accessible from
180 // the most derived object.
181 result.whole2sub = access_path;
186 result.target_obj = objptr;
187 result.whole2target = access_path;
188 result.target2sub = not_contained;
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
197 __user_type_info::sub_kind __user_type_info::
198 do_find_public_subobj (int, const type_info &, void *objptr, void *subptr) const
200 if (subptr == objptr)
201 // Must be our type, as the pointers match.
202 return contained_public;
203 return not_contained;
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
215 result.target_obj = objptr;
216 result.base_type = nonvirtual_base_type;
217 result.whole2target = access_path;
218 return contained_nonpublic_p (access_path);
220 return base.do_upcast (access_path, target, objptr, result);
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
232 if (objptr == subptr && *this == subtype)
234 // The subobject we started from. Indicate how we are accessible from
235 // the most derived object.
236 result.whole2sub = access_path;
241 result.target_obj = objptr;
242 result.whole2target = access_path;
244 result.target2sub = ((char *)subptr - (char *)objptr) == boff
245 ? contained_public : not_contained;
247 result.target2sub = not_contained;
250 return base.do_dyncast (boff, access_path,
251 target, objptr, subtype, subptr, result);
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
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
260 if (subptr == objptr && subtype == *this)
261 return contained_public;
262 return base.do_find_public_subobj (boff, subtype, objptr, subptr);
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
274 result.target_obj = objptr;
275 result.base_type = nonvirtual_base_type;
276 result.whole2target = access_path;
277 return contained_nonpublic_p (access_path);
280 for (size_t i = n_bases; i--;)
282 upcast_result result2;
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)
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)
301 else if (result.target_obj != result2.target_obj)
303 // Found an ambiguity.
304 result.target_obj = NULL;
305 result.whole2target = contained_ambig;
308 else if (result.target_obj)
310 // Ok, found real object via a virtual path.
312 = sub_kind (result.whole2target | result2.whole2target);
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))
322 // Already ambiguous, not virtual or via different virtuals.
324 result.whole2target = contained_ambig;
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
350 if (objptr == subptr && *this == subtype)
352 // The subobject we started from. Indicate how we are accessible from
353 // the most derived object.
354 result.whole2sub = access_path;
359 result.target_obj = objptr;
360 result.whole2target = access_path;
362 result.target2sub = ((char *)subptr - (char *)objptr) == boff
363 ? contained_public : not_contained;
365 result.target2sub = not_contained;
368 bool result_ambig = false;
369 for (size_t i = n_bases; i--;)
371 dyncast_result result2;
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);
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)
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;
397 if (!result_ambig && !result.target_obj)
399 // Not found anything yet.
400 result.target_obj = result2.target_obj;
401 result.whole2target = result2.whole2target;
402 result_ambig = result2_ambig;
404 else if (result.target_obj && result.target_obj == result2.target_obj)
406 // Found at same address, must be via virtual. Pick the most
408 result.whole2target =
409 sub_kind (result.whole2target | result2.whole2target);
411 else if ((result.target_obj && result2.target_obj)
412 || (result_ambig && result2.target_obj)
413 || (result2_ambig && result.target_obj))
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.
423 sub_kind new_sub_kind = result2.target2sub;
424 sub_kind old_sub_kind = result.target2sub;
426 if (contained_nonvirtual_p (result.whole2sub))
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;
438 const __user_type_info &t =
439 static_cast <const __user_type_info &> (target);
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;
448 old_sub_kind = t.find_public_subobj (boff, subtype,
449 result.target_obj, subptr);
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;
458 new_sub_kind = t.find_public_subobj (boff, subtype,
459 result2.target_obj, subptr);
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)))
466 // Only on one choice, not ambiguous.
467 if (contained_p (new_sub_kind))
470 result.target_obj = result2.target_obj;
471 result.whole2target = result2.whole2target;
472 result_ambig = false;
473 old_sub_kind = new_sub_kind;
475 result.target2sub = old_sub_kind;
476 if (result.target2sub == contained_public)
477 return false; // Can't be an ambiguating downcast for later discovery.
479 else if (contained_p (sub_kind (new_sub_kind & old_sub_kind)))
482 result.target_obj = NULL;
483 result.target2sub = contained_ambig;
484 return true; // Fail.
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;
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
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
513 if (objptr == subptr && subtype == *this)
514 return contained_public;
516 for (size_t i = n_bases; i--;)
518 if (base_list[i].access != PUBLIC)
519 continue; // Not public, can't be here.
522 if (base_list[i].is_virtual && boff == -1)
523 // Not a virtual base, so can't be here.
526 p = convert_to_base (objptr,
527 base_list[i].is_virtual,
528 base_list[i].offset);
530 sub_kind base_kind = base_list[i].base->do_find_public_subobj
531 (boff, subtype, p, subptr);
532 if (contained_p (base_kind))
534 if (base_list[i].is_virtual)
535 base_kind = sub_kind (base_kind | contained_virtual_mask);
540 return not_contained;