(root)/
gcc-13.2.0/
libstdc++-v3/
libsupc++/
tinfo.h
       1  // RTTI support internals for -*- C++ -*-
       2  // Copyright (C) 1994-2023 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  }