5 #include "cetlib_except/demangle.h" 9 #ifdef _LIBCPPABI_VERSION 11 #include "TClassRef.h" 21 #ifdef _LIBCPPABI_VERSION 26 if (tid_from == tid_to) {
29 auto const clFrom = TClass::GetClass(tid_from);
33 auto const clTo = TClass::GetClass(tid_to);
37 return clFrom->InheritsFrom(clTo);
42 std::type_info
const& tiFrom,
43 std::type_info
const& tiTo)
49 auto const clFrom = TClass::GetClass(tiFrom);
50 auto const clTo = TClass::GetClass(tiTo);
52 void const* castAddr(
nullptr);
53 if (clFrom->InheritsFrom(clTo)) {
55 castAddr = clFrom->DynamicCast(clTo, const_cast<void*>(address),
true);
56 }
else if (clTo->InheritsFrom(clFrom)) {
59 <<
"art::Wrapper<> : unable to convert type " 60 << cet::demangle_symbol(tiFrom.name()) <<
" to " 61 << cet::demangle_symbol(tiTo.name()) <<
", which is a subclass.\n";
63 if (castAddr !=
nullptr) {
71 <<
"art::Wrapper<> : unable to convert type " 72 << cet::demangle_symbol(tiFrom.name()) <<
" to " 73 << cet::demangle_symbol(tiTo.name()) <<
"\n";
76 #else // _LIBCPPABI_VERSION 82 bool first_call =
true;
84 bool is_ambiguous =
false;
88 void print[[gnu::unused]]()
const;
89 void reset[[gnu::unused]]();
93 upcast_result::print()
const 95 cout <<
" found: " << found << endl;
96 cout <<
"is_ambiguous: " << is_ambiguous << endl;
97 cout <<
" offset: " << offset << endl;
101 upcast_result::reset()
105 is_ambiguous =
false;
110 visit_class_for_upcast(abi::__class_type_info
const* ci,
111 abi::__class_type_info
const* dest,
115 if (res.first_call) {
116 res.first_call =
false;
117 }
else if (ci == dest) {
123 res.is_ambiguous =
true;
127 if (
auto si = dynamic_cast<abi::__si_class_type_info const*>(ci)) {
129 visit_class_for_upcast(si->__base_type, dest, offset, res);
132 if (
auto vmi = dynamic_cast<abi::__vmi_class_type_info const*>(ci)) {
134 for (
auto i = 0U; i < vmi->__base_count; ++i) {
135 auto const& base = vmi->__base_info[i];
136 bool is_public =
false;
137 if (base.__offset_flags & abi::__base_class_type_info::__public_mask) {
141 (base.__offset_flags >> abi::__base_class_type_info::__offset_shift);
142 if (is_public && (boff > -1)) {
145 visit_class_for_upcast(base.__base_type, dest, offset + boff, res);
158 if (tid_from == tid_to) {
162 auto ci_from =
dynamic_cast<abi::__class_type_info const*
>(&tid_from);
163 auto ci_to =
dynamic_cast<abi::__class_type_info const*
>(&tid_to);
164 if (ci_from ==
nullptr) {
168 if (ci_to ==
nullptr) {
172 if (ci_from == ci_to) {
177 visit_class_for_upcast(ci_from, ci_to, 0L, res);
178 return res.found && !res.is_ambiguous;
183 type_info
const& tid_from,
184 type_info
const& tid_to)
186 if (tid_from == tid_to) {
190 auto ci_from =
dynamic_cast<abi::__class_type_info const*
>(&tid_from);
191 auto ci_to =
dynamic_cast<abi::__class_type_info const*
>(&tid_to);
192 if (ci_from ==
nullptr) {
196 if (ci_to ==
nullptr) {
200 if (ci_from == ci_to) {
205 visit_class_for_upcast(ci_from, ci_to, 0L, res);
208 <<
"maybeCastObj : unable to convert type: " 209 << cet::demangle_symbol(tid_from.name())
210 <<
"\nto: " << cet::demangle_symbol(tid_to.name()) <<
"\n" 211 <<
"No suitable base found.\n";
213 if (res.is_ambiguous) {
215 <<
"MaybeCastObj : unable to convert type: " 216 << cet::demangle_symbol(tid_from.name())
217 <<
"\nto: " << cet::demangle_symbol(tid_to.name()) <<
"\n" 218 <<
"Base class is ambiguous.\n";
220 return static_cast<char const*
>(ptr) + res.offset;
223 #endif // _LIBCPPABI_VERSION void const * maybeCastObj(element_type const *address, std::type_info const &tiTo)
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
bool upcastAllowed(std::type_info const &tiFrom, std::type_info const &tiTo)