/*
This file is part of Fennix Kernel.
Fennix Kernel 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 of
the License, or (at your option) any later version.
Fennix Kernel 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.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see .
*/
#ifndef __FENNIX_KERNEL_TYPEINFO_H__
#define __FENNIX_KERNEL_TYPEINFO_H__
#include
#include
namespace __cxxabiv1
{
class __class_type_info;
class __si_class_type_info;
}
namespace std
{
class type_info
{
protected:
const char *Name;
explicit type_info(const char *n) : Name(n) {}
public:
type_info() = delete;
type_info(const type_info &) = delete;
virtual ~type_info();
type_info &operator=(const type_info &) = delete;
type_info &operator=(type_info &&) = delete;
constexpr bool operator==(const type_info &rhs) const noexcept
{
return this == &rhs;
}
bool before(const type_info &rhs) const noexcept
{
return (Name[0] == '*' && rhs.Name[0] == '*')
? Name < rhs.Name
: __builtin_strcmp(Name, rhs.Name) < 0;
}
std::size_t hash_code() const noexcept
{
return reinterpret_cast(this);
}
const char *name() const noexcept
{
return Name[0] == '*' ? Name + 1 : Name;
}
virtual bool __is_pointer_p() const
{
return Name[0] == '*';
}
virtual bool __is_function_p() const
{
return Name[0] == '(';
}
virtual bool __do_catch(const type_info *ThrowType, void **ThrowObject, unsigned Outer) const;
virtual bool __do_upcast(const __cxxabiv1::__class_type_info *Target, void **ObjectPointer) const;
};
class bad_cast : public exception
{
public:
bad_cast() noexcept {}
virtual ~bad_cast() noexcept;
virtual const char *what() const noexcept;
};
class bad_typeid : public exception
{
public:
bad_typeid() noexcept {}
virtual ~bad_typeid() noexcept;
virtual const char *what() const noexcept;
};
}
namespace __cxxabiv1
{
class __pbase_type_info : public std::type_info
{
public:
unsigned int Flags;
const std::type_info *Pointee;
explicit __pbase_type_info(const char *n, int Qualifiers, const std::type_info *Type)
: std::type_info(n),
Flags(Qualifiers),
Pointee(Type)
{
}
virtual ~__pbase_type_info();
enum __masks
{
__const_mask = 0x1,
__volatile_mask = 0x2,
__restrict_mask = 0x4,
__incomplete_mask = 0x8,
__incomplete_class_mask = 0x10,
__transaction_safe_mask = 0x20,
__noexcept_mask = 0x40
};
protected:
__pbase_type_info(const __pbase_type_info &);
__pbase_type_info &operator=(const __pbase_type_info &);
virtual bool __do_catch(const std::type_info *ThrowType,
void **ThrowObject,
unsigned int Outer) const;
inline bool __pointer_catch(const __pbase_type_info *ThrownType,
void **ThrowObject,
unsigned Outer) const
{
return Pointee->__do_catch(ThrownType->Pointee, ThrowObject, Outer + 2);
}
};
class __pointer_type_info : public __pbase_type_info
{
public:
explicit __pointer_type_info(const char *n,
int Qualifiers,
const std::type_info *Type)
: __pbase_type_info(n, Qualifiers, Type) {}
virtual ~__pointer_type_info();
protected:
virtual bool __is_pointer_p() const;
virtual bool __pointer_catch(const __pbase_type_info *ThrowType,
void **ThrowObject,
unsigned Outer) const;
};
/* FIXME: stub */
class __pointer_to_member_type_info : public __pbase_type_info
{
};
class __fundamental_type_info : public std::type_info
{
public:
explicit __fundamental_type_info(const char *n) : std::type_info(n) {}
virtual ~__fundamental_type_info();
};
class __base_class_type_info
{
public:
const __class_type_info *BaseType;
#ifdef __LP64__
long long OffsetFlags;
#else
long OffsetFlags;
#endif
enum __offset_flags_masks
{
__virtual_mask = 0x1,
__public_mask = 0x2,
__hwm_bit = 0x2,
__offset_shift = 0x8
};
bool __is_virtual_p() const
{
return OffsetFlags & __virtual_mask;
}
bool __is_public_p() const
{
return OffsetFlags & __public_mask;
}
ptrdiff_t __offset() const
{
return static_cast(OffsetFlags) >> __offset_shift;
}
};
class __class_type_info : public std::type_info
{
public:
explicit __class_type_info(const char *n)
: std::type_info(n) {}
virtual ~__class_type_info();
enum __sub_kind
{
__unknown = 0,
__not_contained,
__contained_ambig,
__contained_virtual_mask = __base_class_type_info::__virtual_mask,
__contained_public_mask = __base_class_type_info::__public_mask,
__contained_mask = 1 << __base_class_type_info::__hwm_bit,
__contained_private = __contained_mask,
__contained_public = __contained_mask | __contained_public_mask
};
struct __upcast_result
{
const void *dst_ptr;
__sub_kind part2dst;
int src_details;
const __class_type_info *base_type;
__upcast_result(int d)
: dst_ptr(NULL),
part2dst(__unknown),
src_details(d),
base_type(NULL) {}
};
struct __dyncast_result
{
const void *dst_ptr;
__sub_kind whole2dst;
__sub_kind whole2src;
__sub_kind dst2src;
int whole_details;
__dyncast_result(int details_ = 0x10 /*__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 &);
};
virtual __sub_kind __do_find_public_src(ptrdiff_t SourceToDestination,
const void *ObjectPointer,
const __class_type_info *SourceType,
const void *SubroutinePointer) const;
virtual bool __do_upcast(const __class_type_info *Destination,
const void *Object,
__upcast_result &__restrict Result) const;
virtual bool __do_dyncast(ptrdiff_t SourceToDestination,
__sub_kind AccessPath,
const __class_type_info *DestinationType,
const void *ObjectPointer,
const __class_type_info *SourceType,
const void *SourcePointer,
__dyncast_result &Result) const;
protected:
virtual bool __do_upcast(const __class_type_info *DestinationType,
void **ObjectPointer) const;
virtual bool __do_catch(const type_info *ThrowType,
void **ThrowObject,
unsigned Outer) const;
};
class __vmi_class_type_info : public __class_type_info
{
public:
enum __flags_masks
{
__non_diamond_repeat_mask = 0x1,
__diamond_shaped_mask = 0x2,
__flags_unknown_mask = 0x10
};
virtual ~__vmi_class_type_info();
virtual bool __do_upcast(const __class_type_info *target, void **thrown_object) const;
virtual void *cast_to(void *obj, const struct __class_type_info *other) const;
};
class __si_class_type_info : public __class_type_info
{
public:
const __class_type_info *BaseType;
explicit __si_class_type_info(const char *n,
const __class_type_info *Base)
: __class_type_info(n),
BaseType(Base) {}
virtual ~__si_class_type_info();
protected:
__si_class_type_info(const __si_class_type_info &);
__si_class_type_info &operator=(const __si_class_type_info &);
virtual bool __do_dyncast(ptrdiff_t SourceToDestination, __sub_kind AccessPath,
const __class_type_info *DestinationType, const void *ObjectPointer,
const __class_type_info *SourceType, const void *SourcePointer,
__dyncast_result &Result) const;
virtual __sub_kind __do_find_public_src(ptrdiff_t SourceToDestination,
const void *ObjectPointer,
const __class_type_info *SourceType,
const void *SubroutinePointer) const;
virtual bool __do_upcast(const __class_type_info *Destination,
const void *Object,
__upcast_result &__restrict Result) const;
};
static const __class_type_info *const nonvirtual_base_type = static_cast(0) + 1;
}
#endif // !__FENNIX_KERNEL_TYPEINFO_H__