📄 rtti.cpp
字号:
/* */
/******************************************************************************/
void *std::dyn_cast(void *objp,
const VTBL_ENTRY *vtbl_ptr,
const TYPE_INFO_IMPL *class_info,
void *srcp,
const TYPE_INFO_IMPL *source_info)
{
void *complete_objp;
const TYPE_INFO_IMPL *complete_class_info;
/*-------------------------------------------------------------------------*/
/* GET THE COMPLETE OBJECT. */
/*-------------------------------------------------------------------------*/
complete_objp = (void *)((char *)objp - vtbl_ptr->first.delta);
/*-------------------------------------------------------------------------*/
/* GET THE TYPE OF THE COMPLETE OBJECT. */
/*-------------------------------------------------------------------------*/
complete_class_info = (const TYPE_INFO_IMPL *)vtbl_ptr->first.class_info;
/*-------------------------------------------------------------------------*/
/* DO SOMETHING PREDICTABLE IF PARTS OF THE APPLICATION WERE COMPILED */
/* WITHOUT RTTI ENABLED. */
/*-------------------------------------------------------------------------*/
if (!complete_class_info) throw_bad_cast();
/*-------------------------------------------------------------------------*/
/* IF class_info IS NULL, THE OBJECT POINTER IS BEING CAST TO VOID *, SO */
/* RETURN A POINTER TO THE COMPLETE OBJECT. */
/*-------------------------------------------------------------------------*/
if (!class_info) return complete_objp;
else
{
bool access_okay = true;
/*-------------------------------------------------------------------------*/
/* MAKE SURE THE BASE CLASS POINTED TO BY THE srcp IS AN ACCESSIBLE BASE */
/* CLASS. find_base_class_at_addr WILL RETURN NULL IF THE BASE CLASS IS AN */
/* INDIRECT BASE CLASS OF A PRIVATE BASE CLASS. IT WILL RETURN A POINTER */
/* TO THE BASE CLASS ENTRY IF IT IS A BASE CLASS OF AN ACCESSIBLE */
/* BASE CLASS (OR IF IT IS A DIRECT BASE CLASS). CHECK THE RETURNED BASE */
/* CLASS ENTRY TO MAKE SURE THE BASE CLASS IS PUBLIC. THE CONVERSIONS */
/* THAT FOLLOW ARE DONE ONLY IF THE SOURCE CLASS IS A PUBLIC BASE CLASS */
/*-------------------------------------------------------------------------*/
if (class_info == source_info)
access_okay = true;
else
{
const std::BASE_CLASS_SPEC *bcsp;
bcsp = find_base_class_at_addr (complete_objp, srcp,
complete_class_info, source_info);
access_okay = (bcsp != NULL) && ((bcsp->flags & BCS_PUBLIC) != 0);
}
if (access_okay)
{
/*-------------------------------------------------------------------------*/
/* ELSE IF THE OBJECT POINTER IS BEING CAST TO THE TYPE OF THE COMPLETE */
/* OBJECT, RETURN A POINTER TO THE COMPLETE OBJECT. */
/*-------------------------------------------------------------------------*/
if (matching_type_info(complete_class_info, class_info))
return complete_objp;
/*-------------------------------------------------------------------------*/
/* ELSE THE OBJECT POINTER IS BEING CAST TO THE TYPE OF A SUB-OBJECT OF */
/* THE OBJECT'S DYNAMIC TYPE. IF THE TYPE IS ACCESSIBLE AND UNAMBIGUOUS, */
/* THEN RETURN A POINTER TO THE SUB-OBJECT OF THAT TYPE. */
/*-------------------------------------------------------------------------*/
else
{
void *new_objp = NULL;
int found = d_to_b_conversion(&complete_objp, &new_objp,
complete_class_info, class_info);
return found ? new_objp : NULL;
}
}
}
return NULL;
}
/******************************************************************************/
/* DYN_CAST_REF - Interface to dyn_cast() for reference type casts. */
/* */
/* An exception is thrown if the cast fails. */
/* */
/******************************************************************************/
void *std::dyn_cast_ref(void *objp,
const VTBL_ENTRY *vtbl_ptr,
const TYPE_INFO_IMPL *class_info,
void *srcp,
const TYPE_INFO_IMPL *source_info)
{
void *result = dyn_cast(objp, vtbl_ptr, class_info, srcp, source_info);
if (!result) throw_bad_cast();
return result;
}
/******************************************************************************/
/* GET_TYPEID - Returns the type_info object for a given polymorphic type. */
/* */
/******************************************************************************/
void *std::get_typeid(const VTBL_ENTRY *vtbl_ptr)
{
const TYPE_INFO_IMPL *class_info;
if (!vtbl_ptr) throw_bad_typeid();
class_info = (const TYPE_INFO_IMPL *)vtbl_ptr->first.class_info;
/*-------------------------------------------------------------------------*/
/* DO SOMETHING PREDICTABLE IF PARTS OF THE APPLICATION WERE COMPILED */
/* WITHOUT RTTI ENABLED. */
/*-------------------------------------------------------------------------*/
if (!class_info) throw_bad_typeid();
return (void*)&class_info->user_type_info;
}
/******************************************************************************/
/* THROW_BAD_CAST - Throws a bad cast exception. */
/******************************************************************************/
void std::throw_bad_cast(void)
{
// throw bad_cast();
abort(); // For now, just call abort
}
/******************************************************************************/
/* THROW_BAD_TYPEID - Throws a bad typeid exception. */
/******************************************************************************/
void std::throw_bad_typeid(void)
{
// throw bad_typeid();
abort(); // For now, just call abort
}
#include <cstdio>
/******************************************************************************/
/* DUMP_TYPE_INFO - Dumps debug info about the given type representation. */
/******************************************************************************/
void std::dump_type_info(const type_info& info)
{
/*-------------------------------------------------------------------------*/
/* GET THE INTERNAL REPRESENTATION OF THE TYPE. WE DEPEND UPON THE FACT */
/* THAT THE USER VISIBLE TYPE_INFO IS THE FIRST MEMBER OF THIS STRUCTURE. */
/*-------------------------------------------------------------------------*/
const TYPE_INFO_IMPL *class_info = (const TYPE_INFO_IMPL *)&info;
/*-------------------------------------------------------------------------*/
/* NOW OUTPUT LOTS OF USEFUL INFORMATION. START WITH THE TYPE ITSELF. */
/*-------------------------------------------------------------------------*/
fprintf(stderr, "\n*********************************************\n");
fprintf(stderr, "Type information for: %s\n",
class_info->name ? class_info->name : "<NULL>");
fprintf(stderr, " flags :");
if (class_info->flags & TIF_LOCAL) fprintf(stderr, " local");
fprintf(stderr, "\n");
/*-------------------------------------------------------------------------*/
/* AND THEN INFO ABOUT ITS BASE CLASSES, IF THERE ARE ANY. */
/*-------------------------------------------------------------------------*/
if (class_info->bcs_entries)
{
const BASE_CLASS_SPEC *bcsp;
bool last;
/*----------------------------------------------------------------------*/
/* OUTPUT INFO ABOUT THE TYPE'S INHERITANCE. */
/*----------------------------------------------------------------------*/
fprintf(stderr, " base classes:\n");
for (bcsp = class_info->bcs_entries, last = false;
!last;
last = bcsp->flags & BCS_LAST, bcsp++)
{
char *name = bcsp->type_info->name;
fprintf(stderr, " name=%s\n", name ? name : "<NULL>");
fprintf(stderr, " offset=%0ld\n", (long)bcsp->offset);
fprintf(stderr, " flags:");
if (bcsp->flags & BCS_VIRTUAL) fprintf(stderr, " virtual");
if (bcsp->flags & BCS_LAST) fprintf(stderr, " last");
if (bcsp->flags & BCS_PUBLIC) fprintf(stderr, " public");
if (bcsp->flags & BCS_AMBIGUOUS) fprintf(stderr, " ambiguous");
if (bcsp->flags & BCS_DIRECT) fprintf(stderr, " direct");
fprintf(stderr, "\n");
}
/*----------------------------------------------------------------------*/
/* OUTPUT INFO ABOUT THE TYPE'S DIRECT BASE CLASSES. */
/*----------------------------------------------------------------------*/
for (bcsp = class_info->bcs_entries, last = false;
!last;
last = bcsp->flags & BCS_LAST, bcsp++)
if (bcsp->flags & BCS_DIRECT)
dump_type_info(bcsp->type_info->user_type_info);
}
fprintf(stderr, "*********************************************\n");
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -