home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / libg++-2.7.1-base.tgz / libg++-2.7.1-src.tar / fsf / libg++ / libstdc++ / typeinfoi.cc < prev    next >
C/C++ Source or Header  |  1995-09-12  |  5KB  |  130 lines

  1. // Methods for type_info for the -*- C++ -*- Run Time Type Identification.
  2. // Copyright (C) 1994 Free Software Foundation
  3.  
  4. // This file is part of the GNU ANSI C++ Library.  This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 2, or (at your option)
  8. // any later version.
  9.  
  10. // This library is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14.  
  15. // You should have received a copy of the GNU General Public License
  16. // along with this library; see the file COPYING.  If not, write to the Free
  17. // Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. // As a special exception, if you link this library with files
  20. // compiled with a GNU compiler to produce an executable, this does not cause
  21. // the resulting executable to be covered by the GNU General Public License.
  22. // This exception does not however invalidate any other reasons why
  23. // the executable file might be covered by the GNU General Public License.
  24.  
  25. // Written by Kung Hsu based upon the specification in the 20 September 1994
  26. // C++ working paper, ANSI document X3J16/94-0158.
  27.  
  28. #ifdef __GNUG__
  29. #pragma implementation "std/typeinfo.h"
  30. #endif
  31.  
  32. #include <std/cstdlib.h>
  33. #include <std/typeinfo.h>
  34.  
  35. // Offset functions for the class type.
  36.  
  37. // 0 is returned if the cast is invalid, otherwise the converted
  38. // object pointer that points to the sub-object that is matched is
  39. // returned.
  40.  
  41. void* __class_type_info::__rtti_match(const type_info& desired, int is_public,
  42.                       void *objptr) const
  43. {
  44.   if (__rtti_compare(desired) == 0)
  45.     return objptr;
  46.  
  47.   void *match_found = 0;
  48.   for (int i = 0; i < n_bases; i++) {
  49.     if (is_public && access_list[i] != _RTTI_ACCESS_PUBLIC)
  50.       continue;
  51.     void *p = (char *)objptr + offset_list[i];
  52.     if (is_virtual_list[i])
  53.       p = *(void **)p;
  54.  
  55.     if ((p=base_list[i]->__rtti_match(desired, is_public, p))
  56.     != 0)
  57.       if (match_found == 0)
  58.     match_found = p;
  59.       else if (match_found != p) {
  60.     // base found at two different pointers,
  61.     // conversion is not unique
  62.     return 0;
  63.       }
  64.   }
  65.  
  66.   return match_found;
  67. }
  68.  
  69. void* __pointer_type_info::__rtti_match(const type_info& catch_type, int,
  70.                     void *objptr) const
  71. {
  72.   if (catch_type.__rtti_get_node_type () == __rtti_get_node_type())
  73.     {
  74.       type_info &sub_catch_type = ((__pointer_type_info&)catch_type).type;
  75.       type_info &sub_throw_type = ((__pointer_type_info*)this)->type;
  76.       if (sub_catch_type.__rtti_get_node_type () == _RTTI_BUILTIN_TYPE
  77.       && ((__builtin_type_info&)sub_catch_type).b_type == __builtin_type_info::_RTTI_BI_VOID)
  78.     {
  79.       return objptr;
  80.     }
  81.       if (sub_catch_type.__rtti_get_node_type () == _RTTI_ATTR_TYPE
  82.       && ((__attr_type_info&)sub_catch_type).attr == __attr_type_info::_RTTI_ATTR_CONST)
  83.     {
  84.       /* We have to allow a catch of const int* on a int * throw. */
  85.       type_info &sub_sub_catch_type = ((__attr_type_info&)sub_catch_type).type;
  86.       return __throw_type_match_rtti (&sub_sub_catch_type, &sub_throw_type, objptr);
  87.     }
  88.       return __throw_type_match_rtti (&sub_catch_type, &sub_throw_type, objptr);
  89.     }
  90.   return 0;
  91. }
  92.  
  93. /* Low level match routine used by compiler to match types of catch variables and thrown
  94.    objects.  */
  95. extern "C"
  96. void*
  97. __throw_type_match_rtti (void *catch_type_r, void *throw_type_r, void *objptr)
  98. {
  99.   type_info &catch_type = *(type_info*)catch_type_r;
  100.   type_info &throw_type = *(type_info*)throw_type_r;
  101.   void *new_objptr;
  102.  
  103.   if (catch_type == throw_type)
  104.     return objptr;
  105.  
  106.   /* Ensure we can call __rtti_match.  */
  107.   if ((throw_type.__rtti_get_node_type () != type_info::_RTTI_CLASS_TYPE
  108.        && throw_type.__rtti_get_node_type () != type_info::_RTTI_USER_TYPE
  109.        && throw_type.__rtti_get_node_type () != type_info::_RTTI_POINTER_TYPE)
  110.       || ((catch_type.__rtti_get_node_type () != type_info::_RTTI_CLASS_TYPE
  111.        && catch_type.__rtti_get_node_type () != type_info::_RTTI_USER_TYPE
  112.        && catch_type.__rtti_get_node_type () != type_info::_RTTI_POINTER_TYPE)))
  113.     return 0;
  114.  
  115. #if 0
  116.   printf("We want to match a %s against a %s!\n",
  117.      throw_type.name(), catch_type.name());
  118. #endif
  119.  
  120.   /* The 1 skips conversions to private bases. */
  121.   new_objptr = throw_type.__rtti_match (catch_type, 1, objptr);
  122. #if 0
  123.   if (new_objptr)
  124.     printf("It converts, delta is %d\n", new_objptr-objptr);
  125. #endif
  126.   return new_objptr;
  127. }
  128.  
  129. bad_cast __bad_cast_object ("bad_cast");
  130.