X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibc%2B%2B.so_src%2Ftypeinfo.cc;h=99bfedc5de1ce40e459ac1de54e064da592aa34d;hb=3d67e21210fbcad7cdcbfa9c348019a191ce1798;hp=b0a9b3e1b9020d2455e3337e380a4aaa5c16f4da;hpb=b7d9f86f7a1c23be18b50d5c647fd5d3c08369c3;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libc++.so_src/typeinfo.cc b/Usermode/Libraries/libc++.so_src/typeinfo.cc index b0a9b3e1..99bfedc5 100644 --- a/Usermode/Libraries/libc++.so_src/typeinfo.cc +++ b/Usermode/Libraries/libc++.so_src/typeinfo.cc @@ -6,6 +6,9 @@ * - typeid and dynamic_cast */ #include +#include +#include +#include namespace std { @@ -16,16 +19,19 @@ type_info::~type_info() bool type_info::operator==(const type_info& other) const { + //_SysDebug("type_info::operator== - '%s' == '%s'", this->__type_name, other.__type_name); return this->__type_name == other.__type_name; } bool type_info::operator!=(const type_info& other) const { + //_SysDebug("type_info::operator!= - '%s' != '%s'", this->__type_name, other.__type_name); return this->__type_name != other.__type_name; } bool type_info::before(const type_info& other) const { + //_SysDebug("type_info::before - '%s' < '%s'", this->__type_name, other.__type_name); return this->__type_name < other.__type_name; } @@ -41,10 +47,76 @@ type_info::type_info(const type_info& rhs): } type_info& type_info::operator=(const type_info& rhs) { + _SysDebug("type_info::operator=, was %s now %s", __type_name, rhs.__type_name); __type_name = rhs.__type_name; return *this; } +bool type_info::is_class() const +{ + if( typeid(*this) == typeid(::__cxxabiv1::__class_type_info) ) + return true; + if( is_subclass() ) + return true; + return false; +} -}; // namespace std +bool type_info::is_subclass() const +{ + if( typeid(*this) == typeid(::__cxxabiv1::__si_class_type_info) ) + return true; + if( typeid(*this) == typeid(::__cxxabiv1::__vmi_class_type_info) ) + return true; + return false; +} + +// Acess-defined +bool type_info::__is_child(const type_info &poss_child, size_t &offset) const +{ + _SysDebug("typeids = this:%s , poss_child:%s", typeid(*this).name(), typeid(poss_child).name()); + + // Check #1: Child is same type + if( poss_child == *this ) { + offset = 0; + return true; + } + + // Check #2: This type must be a class + if( !this->is_class() ) { + return false; + } + // Check #3: Child class must be a subclass + if( !poss_child.is_subclass() ) { + return false; + } + + if( typeid(poss_child) == typeid(::__cxxabiv1::__si_class_type_info) ) { + auto &si_poss_child = reinterpret_cast(poss_child); + // Single inheritance + _SysDebug("type_info::__is_child - Single inheritance"); + return __is_child( *si_poss_child.__base_type, offset ); + } + else if( typeid(poss_child) == typeid(::__cxxabiv1::__vmi_class_type_info) ) { + // Multiple inheritance + _SysDebug("TODO: type_info::__is_child - Multiple inheritance"); + abort(); + for(;;); + } + else { + // Oops! + _SysDebug("ERROR: type_info::__is_child - Reported subclass type, but not a subclass %s", + typeid(poss_child).name() + ); + abort(); + for(;;); + } +} + +// NOTE: Not defined by the C++ ABI, but is similar to one defined by GCC (__cxa_type_match +//bool __acess_type_match(std::typeinfo& possibly_derived, const std::typeinfo& base_type) +//{ +// return false; +//} + +}; // namespace std