1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
// RTTI support internals for -*- C++ -*-
// Copyright (C) 1994-2015 Free Software Foundation, Inc.
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#include "typeinfo"
#include <cstddef>
// Class declarations shared between the typeinfo implementation files.
#include <cxxabi.h>
namespace __cxxabiv1 {
namespace {
using namespace std;
using namespace abi;
// Initial part of a vtable, this structure is used with offsetof, so we don't
// have to keep alignments consistent manually.
struct vtable_prefix
{
// Offset to most derived object.
ptrdiff_t whole_object;
// Additional padding if necessary.
#ifdef _GLIBCXX_VTABLE_PADDING
ptrdiff_t padding1;
#endif
// Pointer to most derived type_info.
const __class_type_info *whole_type;
// Additional padding if necessary.
#ifdef _GLIBCXX_VTABLE_PADDING
ptrdiff_t padding2;
#endif
// What a class's vptr points to.
const void *origin;
};
template <typename T>
inline const T *
adjust_pointer (const void *base, ptrdiff_t offset)
{
return reinterpret_cast <const T *>
(reinterpret_cast <const char *> (base) + offset);
}
// ADDR is a pointer to an object. Convert it to a pointer to a base,
// using OFFSET. IS_VIRTUAL is true, if we are getting a virtual base.
inline void const *
convert_to_base (void const *addr, bool is_virtual, ptrdiff_t offset)
{
if (is_virtual)
{
const void *vtable = *static_cast <const void *const *> (addr);
offset = *adjust_pointer<ptrdiff_t> (vtable, offset);
}
return adjust_pointer<void> (addr, offset);
}
// some predicate functions for __class_type_info::__sub_kind
inline bool contained_p (__class_type_info::__sub_kind access_path)
{
return access_path >= __class_type_info::__contained_mask;
}
inline bool public_p (__class_type_info::__sub_kind access_path)
{
return access_path & __class_type_info::__contained_public_mask;
}
inline bool virtual_p (__class_type_info::__sub_kind access_path)
{
return (access_path & __class_type_info::__contained_virtual_mask);
}
inline bool contained_public_p (__class_type_info::__sub_kind access_path)
{
return ((access_path & __class_type_info::__contained_public)
== __class_type_info::__contained_public);
}
inline bool contained_nonpublic_p (__class_type_info::__sub_kind access_path)
{
return ((access_path & __class_type_info::__contained_public)
== __class_type_info::__contained_mask);
}
inline bool contained_nonvirtual_p (__class_type_info::__sub_kind access_path)
{
return ((access_path & (__class_type_info::__contained_mask
| __class_type_info::__contained_virtual_mask))
== __class_type_info::__contained_mask);
}
static const __class_type_info *const nonvirtual_base_type =
static_cast <const __class_type_info *> (0) + 1;
} // namespace
// __upcast_result is used to hold information during traversal of a class
// hierarchy when catch matching.
struct __class_type_info::__upcast_result
{
const void *dst_ptr; // pointer to caught object
__sub_kind part2dst; // path from current base to target
int src_details; // hints about the source type hierarchy
const __class_type_info *base_type; // where we found the target,
// if in vbase the __class_type_info of vbase
// if a non-virtual base then 1
// else NULL
__upcast_result (int d)
:dst_ptr (NULL), part2dst (__unknown), src_details (d), base_type (NULL)
{}
};
// __dyncast_result is used to hold information during traversal of a class
// hierarchy when dynamic casting.
struct __class_type_info::__dyncast_result
{
const void *dst_ptr; // pointer to target object or NULL
__sub_kind whole2dst; // path from most derived object to target
__sub_kind whole2src; // path from most derived object to sub object
__sub_kind dst2src; // path from target to sub object
int whole_details; // details of the whole class hierarchy
__dyncast_result (int details_ = __vmi_class_type_info::__flags_unknown_mask)
:dst_ptr (NULL), whole2dst (__unknown),
whole2src (__unknown), dst2src (__unknown),
whole_details (details_)
{}
protected:
__dyncast_result(const __dyncast_result&);
__dyncast_result&
operator=(const __dyncast_result&);
};
inline __class_type_info::__sub_kind __class_type_info::
__find_public_src (ptrdiff_t src2dst,
const void *obj_ptr,
const __class_type_info *src_type,
const void *src_ptr) const
{
if (src2dst >= 0)
return adjust_pointer <void> (obj_ptr, src2dst) == src_ptr
? __contained_public : __not_contained;
if (src2dst == -2)
return __not_contained;
return __do_find_public_src (src2dst, obj_ptr, src_type, src_ptr);
}
}
|