5 #include "cetlib_except/demangle.h" 16 #ifdef _LIBCPPABI_VERSION 27 namespace __cxxabiv1 {
29 class __class_type_info :
public std::type_info {
31 explicit __class_type_info(
char const*
n) : type_info(n) {}
32 virtual ~__class_type_info()
override;
36 class __si_class_type_info :
public __class_type_info {
38 __class_type_info
const* __base_type;
39 explicit __si_class_type_info(
char const*
n, __class_type_info
const* base)
40 : __class_type_info(n), __base_type(base)
42 virtual ~__si_class_type_info()
override;
46 struct __base_class_type_info {
47 __class_type_info
const* __base_type;
48 #if defined _GLIBCXX_LLP64 49 long long __offset_flags;
53 enum __offset_flags_masks {
61 class __vmi_class_type_info :
public __class_type_info {
64 unsigned int __base_count;
65 __base_class_type_info __base_info[1];
68 __non_diamond_repeat_mask = 0x1,
69 __diamond_shaped_mask = 0x2,
70 __flags_unknown_mask = 0x10
73 explicit __vmi_class_type_info(
char const*
n,
int flags)
74 : __class_type_info(n), __flags(flags), __base_count(0)
76 virtual ~__vmi_class_type_info()
override;
79 #endif // _LIBCPPABI_VERSION 85 bool first_call =
true;
87 bool is_ambiguous =
false;
91 void print [[maybe_unused]] ()
const;
92 void reset [[maybe_unused]] ();
96 upcast_result::print()
const 98 cout <<
" found: " << found << endl;
99 cout <<
"is_ambiguous: " << is_ambiguous << endl;
100 cout <<
" offset: " << offset << endl;
104 upcast_result::reset()
108 is_ambiguous =
false;
113 visit_class_for_upcast(abi::__class_type_info
const* ci,
114 abi::__class_type_info
const* dest,
118 if (res.first_call) {
119 res.first_call =
false;
120 }
else if (ci == dest) {
126 res.is_ambiguous =
true;
130 if (
auto si = dynamic_cast<abi::__si_class_type_info const*>(ci)) {
132 visit_class_for_upcast(si->__base_type, dest, offset, res);
135 if (
auto vmi = dynamic_cast<abi::__vmi_class_type_info const*>(ci)) {
137 for (
auto i = 0U; i < vmi->__base_count; ++i) {
138 auto const& base = vmi->__base_info[i];
139 bool is_public =
false;
140 if (base.__offset_flags & abi::__base_class_type_info::__public_mask) {
144 (base.__offset_flags >> abi::__base_class_type_info::__offset_shift);
145 if (is_public && (boff > -1)) {
148 visit_class_for_upcast(base.__base_type, dest, offset + boff, res);
161 if (tid_from == tid_to) {
165 auto ci_from =
dynamic_cast<abi::__class_type_info const*
>(&tid_from);
166 auto ci_to =
dynamic_cast<abi::__class_type_info const*
>(&tid_to);
167 if (ci_from ==
nullptr) {
171 if (ci_to ==
nullptr) {
175 if (ci_from == ci_to) {
180 visit_class_for_upcast(ci_from, ci_to, 0L, res);
181 return res.found && !res.is_ambiguous;
186 type_info
const& tid_from,
187 type_info
const& tid_to)
189 if (tid_from == tid_to) {
193 auto ci_from =
dynamic_cast<abi::__class_type_info const*
>(&tid_from);
194 auto ci_to =
dynamic_cast<abi::__class_type_info const*
>(&tid_to);
195 if (ci_from ==
nullptr) {
199 if (ci_to ==
nullptr) {
203 if (ci_from == ci_to) {
208 visit_class_for_upcast(ci_from, ci_to, 0L, res);
211 <<
"maybeCastObj : unable to convert type: " 212 << cet::demangle_symbol(tid_from.name())
213 <<
"\nto: " << cet::demangle_symbol(tid_to.name()) <<
"\n" 214 <<
"No suitable base found.\n";
216 if (res.is_ambiguous) {
218 <<
"MaybeCastObj : unable to convert type: " 219 << cet::demangle_symbol(tid_from.name())
220 <<
"\nto: " << cet::demangle_symbol(tid_to.name()) <<
"\n" 221 <<
"Base class is ambiguous.\n";
223 return static_cast<char const*
>(ptr) + res.offset;
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
bool upcastAllowed(std::type_info const &tiFrom, std::type_info const &tiTo)
void const * maybeCastObj(void const *address, std::type_info const &tiFrom, std::type_info const &tiTo)