Changeset View
Changeset View
Standalone View
Standalone View
head/contrib/libcxxrt/dynamic_cast.cc
Show All 38 Lines | struct vtable_header | ||||
/** Type of the object. */ | /** Type of the object. */ | ||||
const __class_type_info *type; | const __class_type_info *type; | ||||
}; | }; | ||||
/** | /** | ||||
* Simple macro that does pointer arithmetic in bytes but returns a value of | * Simple macro that does pointer arithmetic in bytes but returns a value of | ||||
* the same type as the original. | * the same type as the original. | ||||
*/ | */ | ||||
#define ADD_TO_PTR(x, off) (__typeof__(x))(((char*)x) + off) | #define ADD_TO_PTR(x, off) reinterpret_cast<__typeof__(x)>(reinterpret_cast<char*>(x) + off) | ||||
bool std::type_info::__do_catch(std::type_info const *ex_type, | bool std::type_info::__do_catch(std::type_info const *ex_type, | ||||
void **exception_object, | void **exception_object, | ||||
unsigned int outer) const | unsigned int outer) const | ||||
{ | { | ||||
const type_info *type = this; | const type_info *type = this; | ||||
if (type == ex_type) | if (type == ex_type) | ||||
▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | for (unsigned int i=0 ; i<__base_count ; i++) | ||||
// base subobject. For a virtual base, this is the offset in the | // base subobject. For a virtual base, this is the offset in the | ||||
// virtual table of the virtual base offset for the virtual base | // virtual table of the virtual base offset for the virtual base | ||||
// referenced (negative).' | // referenced (negative).' | ||||
void *obj = *thrown_object; | void *obj = *thrown_object; | ||||
if (info->isVirtual()) | if (info->isVirtual()) | ||||
{ | { | ||||
// Object's vtable | // Object's vtable | ||||
ptrdiff_t *off = *(ptrdiff_t**)obj; | ptrdiff_t *off = *static_cast<ptrdiff_t**>(obj); | ||||
// Offset location in vtable | // Offset location in vtable | ||||
off = ADD_TO_PTR(off, offset); | off = ADD_TO_PTR(off, offset); | ||||
offset = *off; | offset = *off; | ||||
} | } | ||||
void *cast = ADD_TO_PTR(obj, offset); | void *cast = ADD_TO_PTR(obj, offset); | ||||
if (info->__base_type == target || | if (info->__base_type == target || | ||||
(info->__base_type->__do_upcast(target, &cast))) | (info->__base_type->__do_upcast(target, &cast))) | ||||
Show All 19 Lines | |||||
* that src is not a public base of dst, and -3 that src is a multiple public | * that src is not a public base of dst, and -3 that src is a multiple public | ||||
* base type but never a virtual base type | * base type but never a virtual base type | ||||
*/ | */ | ||||
extern "C" void* __dynamic_cast(const void *sub, | extern "C" void* __dynamic_cast(const void *sub, | ||||
const __class_type_info *src, | const __class_type_info *src, | ||||
const __class_type_info *dst, | const __class_type_info *dst, | ||||
ptrdiff_t src2dst_offset) | ptrdiff_t src2dst_offset) | ||||
{ | { | ||||
char *vtable_location = *(char**)sub; | const char *vtable_location = *static_cast<const char * const *>(sub); | ||||
const vtable_header *header = | const vtable_header *header = | ||||
(const vtable_header*)(vtable_location - sizeof(vtable_header)); | reinterpret_cast<const vtable_header*>(vtable_location - sizeof(vtable_header)); | ||||
void *leaf = ADD_TO_PTR((void*)sub, header->leaf_offset); | void *leaf = ADD_TO_PTR(const_cast<void *>(sub), header->leaf_offset); | ||||
return header->type->cast_to(leaf, dst); | return header->type->cast_to(leaf, dst); | ||||
} | } |