Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // RTTI support internals for -*- C++ -*-
  2. // Copyright (C) 1994-2015 Free Software Foundation, Inc.
  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 "typeinfo"
  26. #include <cstddef>
  27.  
  28. // Class declarations shared between the typeinfo implementation files.
  29.  
  30. #include <cxxabi.h>
  31.  
  32. namespace __cxxabiv1 {
  33.  
  34. namespace {
  35.  
  36. using namespace std;
  37. using namespace abi;
  38.  
  39. // Initial part of a vtable, this structure is used with offsetof, so we don't
  40. // have to keep alignments consistent manually.
  41. struct vtable_prefix
  42. {
  43.   // Offset to most derived object.
  44.   ptrdiff_t whole_object;
  45.  
  46.   // Additional padding if necessary.
  47. #ifdef _GLIBCXX_VTABLE_PADDING
  48.   ptrdiff_t padding1;              
  49. #endif
  50.  
  51.   // Pointer to most derived type_info.
  52.   const __class_type_info *whole_type;  
  53.  
  54.   // Additional padding if necessary.
  55. #ifdef _GLIBCXX_VTABLE_PADDING
  56.   ptrdiff_t padding2;              
  57. #endif
  58.  
  59.   // What a class's vptr points to.
  60.   const void *origin;              
  61. };
  62.  
  63. template <typename T>
  64. inline const T *
  65. adjust_pointer (const void *base, ptrdiff_t offset)
  66. {
  67.   return reinterpret_cast <const T *>
  68.     (reinterpret_cast <const char *> (base) + offset);
  69. }
  70.  
  71. // ADDR is a pointer to an object.  Convert it to a pointer to a base,
  72. // using OFFSET. IS_VIRTUAL is true, if we are getting a virtual base.
  73. inline void const *
  74. convert_to_base (void const *addr, bool is_virtual, ptrdiff_t offset)
  75. {
  76.   if (is_virtual)
  77.     {
  78.       const void *vtable = *static_cast <const void *const *> (addr);
  79.      
  80.       offset = *adjust_pointer<ptrdiff_t> (vtable, offset);
  81.     }
  82.  
  83.   return adjust_pointer<void> (addr, offset);
  84. }
  85.  
  86. // some predicate functions for __class_type_info::__sub_kind
  87. inline bool contained_p (__class_type_info::__sub_kind access_path)
  88. {
  89.   return access_path >= __class_type_info::__contained_mask;
  90. }
  91. inline bool public_p (__class_type_info::__sub_kind access_path)
  92. {
  93.   return access_path & __class_type_info::__contained_public_mask;
  94. }
  95. inline bool virtual_p (__class_type_info::__sub_kind access_path)
  96. {
  97.   return (access_path & __class_type_info::__contained_virtual_mask);
  98. }
  99. inline bool contained_public_p (__class_type_info::__sub_kind access_path)
  100. {
  101.   return ((access_path & __class_type_info::__contained_public)
  102.           == __class_type_info::__contained_public);
  103. }
  104. inline bool contained_nonpublic_p (__class_type_info::__sub_kind access_path)
  105. {
  106.   return ((access_path & __class_type_info::__contained_public)
  107.           == __class_type_info::__contained_mask);
  108. }
  109. inline bool contained_nonvirtual_p (__class_type_info::__sub_kind access_path)
  110. {
  111.   return ((access_path & (__class_type_info::__contained_mask
  112.                           | __class_type_info::__contained_virtual_mask))
  113.           == __class_type_info::__contained_mask);
  114. }
  115.  
  116. static const __class_type_info *const nonvirtual_base_type =
  117.     static_cast <const __class_type_info *> (0) + 1;
  118.  
  119. } // namespace
  120.  
  121. // __upcast_result is used to hold information during traversal of a class
  122. // hierarchy when catch matching.
  123. struct __class_type_info::__upcast_result
  124. {
  125.   const void *dst_ptr;        // pointer to caught object
  126.   __sub_kind part2dst;        // path from current base to target
  127.   int src_details;            // hints about the source type hierarchy
  128.   const __class_type_info *base_type; // where we found the target,
  129.                               // if in vbase the __class_type_info of vbase
  130.                               // if a non-virtual base then 1
  131.                               // else NULL
  132.   __upcast_result (int d)
  133.     :dst_ptr (NULL), part2dst (__unknown), src_details (d), base_type (NULL)
  134.     {}
  135. };
  136.  
  137. // __dyncast_result is used to hold information during traversal of a class
  138. // hierarchy when dynamic casting.
  139. struct __class_type_info::__dyncast_result
  140. {
  141.   const void *dst_ptr;        // pointer to target object or NULL
  142.   __sub_kind whole2dst;       // path from most derived object to target
  143.   __sub_kind whole2src;       // path from most derived object to sub object
  144.   __sub_kind dst2src;         // path from target to sub object
  145.   int whole_details;          // details of the whole class hierarchy
  146.  
  147.   __dyncast_result (int details_ = __vmi_class_type_info::__flags_unknown_mask)
  148.     :dst_ptr (NULL), whole2dst (__unknown),
  149.      whole2src (__unknown), dst2src (__unknown),
  150.      whole_details (details_)
  151.     {}
  152.  
  153. protected:
  154.   __dyncast_result(const __dyncast_result&);
  155.  
  156.   __dyncast_result&
  157.   operator=(const __dyncast_result&);
  158. };
  159.  
  160. inline __class_type_info::__sub_kind __class_type_info::
  161. __find_public_src (ptrdiff_t src2dst,
  162.                    const void *obj_ptr,
  163.                    const __class_type_info *src_type,
  164.                    const void *src_ptr) const
  165. {
  166.   if (src2dst >= 0)
  167.     return adjust_pointer <void> (obj_ptr, src2dst) == src_ptr
  168.             ? __contained_public : __not_contained;
  169.   if (src2dst == -2)
  170.     return __not_contained;
  171.   return __do_find_public_src (src2dst, obj_ptr, src_type, src_ptr);
  172. }
  173.  
  174. }
  175.