dmpobjmd.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 439 行
C
439 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include "plusplus.h"
#include "errdefns.h"
#include "pragdefn.h"
#include "vbuf.h"
#include "vstk.h"
typedef enum dump_struct_control {
DS_BASE = 0x0001,
DS_NULL = 0x0000,
} ds_control;
typedef struct // DUMP INFORMATION
{ target_size_t offset; // - offset of current structure
VSTK_CTL stack; // - parentage stack
VBUF buffer; // - buffer for printing
TYPE original; // - original type
} DUMP_INFO;
static DUMP_INFO* bufferNull( // INITIALIZE BUFFER
DUMP_INFO* di ) // - dump information
{
VStrNull( &di->buffer );
return di;
}
static DUMP_INFO* bufferChr( // CONCATENATE CHAR TO BUFFER
DUMP_INFO* di, // - dump information
char chr ) // - to be concatenated
{
VStrConcChr( &di->buffer, chr );
return di;
}
static DUMP_INFO* bufferStr( // CONCATENATE STRING TO BUFFER
DUMP_INFO* di, // - dump information
char* str ) // - to be concatenated
{
VStrConcStr( &di->buffer, str );
return di;
}
static DUMP_INFO* bufferNmb( // CONCATENATE NUMBER TO BUFFER
DUMP_INFO* di, // - dump information
unsigned numb ) // - to be concatenated
{
char buf[16]; // - buffer
VStrConcDecimal( &di->buffer, numb );
if( numb >= 10 ) {
itoa( numb, buf, 16 );
di = bufferStr( di, "/0x" );
di = bufferStr( di, buf );
}
return di;
}
static DUMP_INFO* bufferInit( // INITIALIZE BUFFER (NON-TITLE LINE)
DUMP_INFO* di ) // - dump information
{
di = bufferNull( di );
di = bufferStr( di, " " );
return di;
}
static void vbufWrite( // WRITE A VBUFFER
VBUF* vbuf ) // - the VBUF to be written
{
MsgDisplayLine( vbuf->buf );
}
static DUMP_INFO* bufferWrite( // WRITE A BUFFER
DUMP_INFO* di ) // - dump information
{
vbufWrite( &di->buffer );
return di;
}
static void dumpDirect( BASE_CLASS*, void * );
static void dumpVirtual( BASE_CLASS*, void * );
static DUMP_INFO* dumpTitle( // DUMP A TITLE LINE
DUMP_INFO* di, // - dump information
char* title, // - title line
char* class_name ) // - name of class
{
di = bufferNull( di );
di = bufferChr( di, '\n' );
di = bufferStr( di, title );
di = bufferChr( di, ' ' );
di = bufferStr( di, class_name );
di = bufferWrite( di );
return di;
}
static DUMP_INFO* dumpOffset( // DUMP OFFSET LINE
DUMP_INFO* di ) // - dump information
{
di = bufferInit( di );
di = bufferStr( di, "offset of class: " );
di = bufferNmb( di, di->offset );
di = bufferWrite( di );
return di;
}
static DUMP_INFO* dumpParentage( // DUMP PARENTAGE
DUMP_INFO* di ) // - dump information
{
char**daughter; // - daughter class
for( daughter = VstkTop( &di->stack ); ; ) {
daughter = VstkNext( &di->stack, daughter );
if( daughter == NULL ) break;
di = bufferInit( di );
di = bufferStr( di, "base of: " );
di = bufferStr( di, *daughter );
di = bufferWrite( di );
}
return di;
}
static DUMP_INFO* dumpBitMemb( // DUMP A BITFIELD MEMBER
DUMP_INFO* di, // - dump information
char* kind, // - kind of field
char* name, // - field name
target_offset_t offset, // - field offset
target_size_t start, // - field start
target_size_t size ) // - field size
{
di = bufferInit( di );
di = bufferStr( di, kind );
di = bufferChr( di, ' ' );
di = bufferStr( di, name );
di = bufferStr( di, ", offset = " );
di = bufferNmb( di, offset );
di = bufferStr( di, ", bit offset =" );
di = bufferNmb( di, start );
di = bufferStr( di, ", bit width =" );
di = bufferNmb( di, size );
di = bufferWrite( di );
return di;
}
static DUMP_INFO* dumpDataMemb( // DUMP A DATA MEMBER
DUMP_INFO* di, // - dump information
char* kind, // - kind of field
char* name, // - field name
target_offset_t offset, // - field offset
target_size_t size ) // - field size
{
di = bufferInit( di );
di = bufferStr( di, kind );
di = bufferChr( di, ' ' );
di = bufferStr( di, name );
di = bufferStr( di, ", offset = " );
di = bufferNmb( di, offset );
di = bufferStr( di, ", size = " );
di = bufferNmb( di, size );
di = bufferWrite( di );
return di;
}
static void dumpMember( // DUMP A MEMBER
SYMBOL memb, // - member
void *_di ) // - dump information
{
DUMP_INFO* di = _di;
target_offset_t offset; // - offset of symbol
TYPE type; // - type of symbol
char* name; // - symbol's name
offset = di->offset + memb->u.offset;
name = memb->name->name;
type = TypedefModifierRemove( memb->sym_type );
if( type->id == TYP_BITFIELD ) {
di = dumpBitMemb( di
, "bit member:"
, name
, offset
, type->u.b.field_start
, type->u.b.field_width );
} else {
di = dumpDataMemb( di
, "member:"
, name
, offset
, CgMemorySize( type ) );
}
}
static DUMP_INFO* dumpStruct( // DUMP A STRUCTURE
TYPE type, // - structure type
DUMP_INFO* di, // - dump information
char* title, // - title for dump
ds_control control ) // - control word
{
CLASSINFO* info; // - class information
char** parent; // - where parent ptr is stored
type = StructType( type );
info = type->u.c.info;
parent = VstkPush( &di->stack );
*parent = info->name;
di = dumpTitle( di, title, info->name );
if( type != di->original ) {
di = bufferInit( di );
di = bufferStr( di, "embedded size: " );
di = bufferNmb( di, info->vsize );
di = bufferWrite( di );
di = dumpOffset( di );
di = dumpParentage( di );
} else {
di = bufferInit( di );
di = bufferStr( di, "size: " );
di = bufferNmb( di, info->size );
di = bufferWrite( di );
}
if( info->has_vbptr ) {
di = dumpDataMemb( di
, "[virtual"
, "base pointer]"
, info->vb_offset + di->offset
, CgMemorySize( TypePtrToVoid() ) );
}
if( info->has_vfptr ) {
di = dumpDataMemb( di
, "[virtual"
, "functions pointer]"
, info->vf_offset + di->offset
, CgMemorySize( TypePtrToVoid() ) );
}
ScopeWalkDataMembers( type->u.c.scope, dumpMember, di );
if( type == di->original ) {
ScopeWalkVirtualBases( type->u.c.scope, dumpVirtual, di );
}
ScopeWalkDirectBases( type->u.c.scope, dumpDirect, di );
VstkPop( &di->stack );
return di;
}
static void dumpBase( // DUMP BASE
BASE_CLASS* base, // - base information
DUMP_INFO* di, // - dump information
char* title ) // - title
{
di->offset += base->delta;
di = dumpStruct( base->type, di, title, DS_BASE );
di->offset -= base->delta;
}
static void dumpVirtual( // DUMP VIRTUAL BASE
BASE_CLASS* vbase, // - virtual base
void * _di ) // - dump information
{
DUMP_INFO* di = _di;
dumpBase( vbase, di, "Virtual Base:" );
}
static void dumpDirect( // DUMP DIRECT BASE
BASE_CLASS* dbase, // - direct base
void * _di ) // - dump information
{
DUMP_INFO* di = _di;
dumpBase( dbase, di, "Direct Base:" );
}
void DumpObjectModelClass( // DUMP OBJECT MODEL: CLASS
TYPE type ) // - structure type
{
DUMP_INFO di; // - dump information
if( ! type->u.c.info->corrupted ) {
CompFlags.log_note_msgs = TRUE;
di.original = type;
di.offset = 0;
VbufInit( &di.buffer );
VstkOpen( &di.stack, sizeof( char* ), 16 );
dumpStruct( type, &di, "Object Model for:", DS_NULL );
VbufFree( &di.buffer );
VstkClose( &di.stack );
CompFlags.log_note_msgs = FALSE;
}
}
void DumpObjectModelEnum( // DUMP OBJECT MODEL: ENUM
TYPE type ) // - enum type
{
SYMBOL sym; // - current symbol
TYPE base; // - base type
VBUF buffer; // - printing buffer
char buf[16]; // - buffer
long numb; // - a numeric value
char *name; // - name to be printed
boolean sign; // - TRUE ==> signed enum
unsigned long mask; // - used to mask to true size
unsigned long val; // - value as unsigned
CompFlags.log_note_msgs = TRUE;
VbufInit( &buffer );
base = TypedefModifierRemoveOnly( type );
sym = base->u.t.sym;
VStrNull( &buffer );
VStrConcStr( &buffer, "Object Model for: " );
name = sym->name->name;
if( NULL == name
|| name[0] == '.' ) {
name = "anonymous enum type";
}
VStrConcStr( &buffer, name );
switch( TypedefModifierRemove( base->of ) -> id ) {
case TYP_CHAR :
case TYP_UCHAR :
name = "unsigned char";
sign = FALSE;
break;
case TYP_SCHAR :
name = "signed char";
sign = TRUE;
break;
case TYP_SSHORT :
name = "signed short";
sign = TRUE;
break;
case TYP_USHORT :
name = "unsigned short";
sign = FALSE;
break;
case TYP_SINT :
name = "signed int";
sign = TRUE;
break;
case TYP_UINT :
name = "unsigned int";
sign = FALSE;
break;
case TYP_SLONG :
name = "signed long";
sign = TRUE;
break;
case TYP_ULONG :
name = "unsigned long";
sign = FALSE;
break;
case TYP_SLONG64 :
name = "__int64";
sign = TRUE;
break;
case TYP_ULONG64 :
name = "unsigned __int64";
sign = FALSE;
break;
DbgDefault( "DumpObjectModelEnum -- bad underlying type" );
}
VStrConcStr( &buffer, ", base type is " );
VStrConcStr( &buffer, name );
vbufWrite( &buffer );
mask = CgMemorySize( base );
if( mask == sizeof( unsigned long ) ) {
mask = -1;
} else {
mask = ( 1 << ( mask * 8 ) ) - 1;
}
for( ; ; ) {
sym = sym->thread;
if( ! SymIsEnumeration( sym ) ) break;
VStrNull( &buffer );
VStrConcStr( &buffer, " " );
VStrConcStr( &buffer, sym->name->name );
VStrConcStr( &buffer, " = " );
numb = sym->u.sval;
if( sign && numb < 0 ) {
VStrConcChr( &buffer, '-' );
VStrConcDecimal( &buffer, -numb );
} else {
VStrConcDecimal( &buffer, numb );
}
val = mask & numb;
if( val > 10 ) {
itoa( val, buf, 16 );
VStrConcStr( &buffer, " /0x" );
VStrConcStr( &buffer, buf );
}
vbufWrite( &buffer );
}
VbufFree( &buffer );
CompFlags.log_note_msgs = FALSE;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?