@@ -645,70 +645,27 @@ bool Cppyy::IsTypedefed(TCppScope_t handle)
645645 return Cpp::IsTypedefed (handle);
646646}
647647
648- // namespace {
649- // class AutoCastRTTI {
650- // public:
651- // virtual ~AutoCastRTTI() {}
652- // };
653- // }
654- //
655- // Cppyy::TCppType_t Cppyy::GetActualClass(TCppType_t klass, TCppObject_t obj)
656- // {
657- // TClassRef& cr = type_from_handle(klass);
658- // if (!cr.GetClass() || !obj) return klass;
659- //
660- // if (!(cr->ClassProperty() & kClassHasVirtual))
661- // return klass; // not polymorphic: no RTTI info available
662- //
663- // #ifdef _WIN64
664- // // Cling does not provide a consistent ImageBase address for calculating relative addresses
665- // // as used in Windows 64b RTTI. So, check for our own RTTI extension instead. If that fails,
666- // // see whether the unmangled raw_name is available (e.g. if this is an MSVC compiled rather
667- // // than JITed class) and pass on if it is.
668- // volatile const char* raw = nullptr; // to prevent too aggressive reordering
669- // try {
670- // // this will filter those objects that do not have RTTI to begin with (throws)
671- // AutoCastRTTI* pcst = (AutoCastRTTI*)obj;
672- // raw = typeid(*pcst).raw_name();
673- //
674- // // check the signature id (0 == absolute, 1 == relative, 2 == ours)
675- // void* vfptr = *(void**)((intptr_t)obj);
676- // void* meta = (void*)((intptr_t)*((void**)((intptr_t)vfptr-sizeof(void*))));
677- // if (*(intptr_t*)meta == 2) {
678- // // access the extra data item which is an absolute pointer to the RTTI
679- // void* ptdescr = (void*)((intptr_t)meta + 4*sizeof(unsigned long)+sizeof(void*));
680- // if (ptdescr && *(void**)ptdescr) {
681- // auto rtti = *(std::type_info**)ptdescr;
682- // raw = rtti->raw_name();
683- // if (raw && raw[0] != '\0') // likely unnecessary
684- // return (TCppType_t)GetScope(rtti->name());
685- // }
686- //
687- // return klass; // do not fall through if no RTTI info available
688- // }
689- //
690- // // if the raw name is the empty string (no guarantees that this is so as truly, the
691- // // address is corrupt, but it is common to be empty), then there is no accessible RTTI
692- // // and getting the unmangled name will crash ...
693- //
694- // // a common case are the i/o stream objects b/c these are pulled in from libCling
695- // if (!raw || (strstr(cr->GetName(), "std::basic_") && strstr(cr->GetName(), "stream")) || raw[0] == '\0')
696- // return klass;
697- // } catch (std::bad_typeid) {
698- // return klass; // can't risk passing to ROOT/meta as it may do RTTI
699- // }
700- // #endif
701- //
702- // TClass* clActual = cr->GetActualClass((void*)obj);
703- // if (clActual && clActual != cr.GetClass()) {
704- // auto itt = g_name2classrefidx.find(clActual->GetName());
705- // if (itt != g_name2classrefidx.end())
706- // return (TCppType_t)itt->second;
707- // return (TCppType_t)GetScope(clActual->GetName());
708- // }
709- //
710- // return klass;
711- // }
648+ namespace {
649+ class AutoCastRTTI {
650+ public:
651+ virtual ~AutoCastRTTI () {}
652+ };
653+ } // namespace
654+
655+ Cppyy::TCppScope_t Cppyy::GetActualClass (TCppScope_t klass, TCppObject_t obj) {
656+ if (!Cpp::IsClassPolymorphic (klass))
657+ return klass;
658+
659+ const std::type_info *typ = &typeid (*(AutoCastRTTI *)obj);
660+
661+ std::string mangled_name = typ->name ();
662+ std::string demangled_name = Cpp::Demangle (mangled_name);
663+
664+ if (TCppScope_t scope = Cppyy::GetScope (demangled_name))
665+ return scope;
666+
667+ return klass;
668+ }
712669
713670size_t Cppyy::SizeOf (TCppScope_t klass)
714671{
0 commit comments