symdbg.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,175 行 · 第 1/3 页
C
1,175 行
/****************************************************************************
*
* 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 <assert.h>
#include "errdefns.h"
#include "cgfront.h"
#include "cgback.h"
#include "codegen.h"
#include "pragdefn.h"
#include "cginfo.h"
#include "carve.h"
#include "ppops.h"
#include "ring.h"
#include "vfun.h"
#include "symdbg.h"
#include "dbgsupp.h"
typedef struct fwd_info FWD_INFO;
struct fwd_info {
FWD_INFO *next;
TYPE type;
dbg_name dn;
dbg_type dt;
dbg_name comp_dn;
};
// carve storage for fwd_info structures
#define BLOCK_FWD_INFO 16
static carve_t carveFWD_INFO;
static FWD_INFO *prevFwdInfo;
static dbg_type scopeEnum;
static dbg_type scopeUnion;
static dbg_type scopeStruct;
static dbg_type scopeClass;
static TYPE vf_FieldType;
static TYPE pvf_FieldType;
static unsigned vf_FieldTypeSize;
static TYPE vb_FieldType;
static TYPE pvb_FieldType;
static unsigned vb_FieldTypeSize;
// prototypes
static dbg_loc symbolicDebugSetSegment( dbg_loc dl, SYMBOL sym );
static dbg_loc symbolicDebugSetCodeSegment( dbg_loc dl );
static dbg_type symbolicDebugClassType( TYPE type );
static void doSymbolicDebugFundamentalType( TYPE type, void *data );
static void symbolicDebugFundamentalType( void );
static void doSymbolicDebugNamedType( TYPE type, void *data );
static void symbolicDebugNamedType( void );
static void symbolicDebugSymbol( void );
void SymbolicDebugInit( void )
/****************************/
{
assert( sizeof( vf_FieldType->dbg.handle ) == sizeof( dbg_type ) );
if( GenSwitches & DBG_TYPES ) {
scopeEnum = DBScope( "enum" );
scopeUnion = DBScope( "union" );
scopeStruct = DBScope( "struct" );
scopeClass = DBScope( "class" );
DbgSuppInit( DSI_NULL );
}
if( GenSwitches & DBG_LOCALS ) {
pvf_FieldType = MakeVFTableFieldType( TRUE );
vf_FieldType = PointerTypeEquivalent( pvf_FieldType )->of;
vf_FieldTypeSize = CgTypeSize( vf_FieldType );
pvb_FieldType = MakeVBTableFieldType( TRUE );
vb_FieldType = PointerTypeEquivalent( pvb_FieldType )->of;
vb_FieldTypeSize = CgTypeSize( vb_FieldType );
}
carveFWD_INFO = CarveCreate( sizeof( FWD_INFO ), BLOCK_FWD_INFO );
}
void SymbolicDebugFini( void )
/****************************/
{
#ifndef NDEBUG
CarveVerifyAllGone( carveFWD_INFO, "FWD_INFO" );
#endif
CarveDestroy( carveFWD_INFO );
}
static cg_sym_handle symbolicDebugSymAlias( SYMBOL sym )
/******************************************************/
{
SYMBOL check;
sym = SymDeAlias( sym );
check = SymIsAnonymous( sym );
if( check != NULL ) {
sym = check;
}
return( (cg_sym_handle)sym );
}
static dbg_loc symbolicDebugSetSegment( dbg_loc dl, SYMBOL sym )
/**************************************************************/
{
dl = DBLocSym( dl, symbolicDebugSymAlias( sym ) );
dl = DBLocOp( dl, DB_OP_XCHG, 1 );
dl = DBLocOp( dl, DB_OP_MK_FP, 0 );
return( dl );
}
static dbg_loc symbolicDebugSetCodeSegment( dbg_loc dl )
/******************************************************/
{
if( !IsBigCode() ) {
dl = symbolicDebugSetSegment( dl, DefaultCodeSymbol );
DbgAddrTaken( DefaultCodeSymbol );
}
return( dl );
}
dbg_loc SymbolicDebugSetDataSegment( dbg_loc dl )
/***********************************************/
{
if( !IsBigData() ) {
dl = symbolicDebugSetSegment( dl, DefaultDataSymbol );
DefaultDataSymbol->flag |= SF_REFERENCED;
}
return( dl );
}
static dbg_loc symbolicDebugSymAddr( dbg_loc dl, SYMBOL sym )
/***********************************************************/
{
#ifdef DISABLE_CGRF
if( SymIsReferenced( sym ) ) {
DbgAddrTaken( sym );
dl = DBLocSym( dl, symbolicDebugSymAlias( sym ) );
if( SymIsInitialized( sym ) ) {
cgfile = CgioLocateFile( sym );
if( cgfile != NULL ) {
cgfile->refed = TRUE;
}
}
}
#else
DbgAddrTaken( sym );
dl = DBLocSym( dl, symbolicDebugSymAlias( sym ) );
#endif
return( dl );
}
static dbg_type symWVDebugClassType( TYPE type )
/*************************************************/
{ // Dump WV class
dbg_type dt;
dbg_struct ds;
dbg_loc dl;
SYMBOL stop, curr;
BASE_CLASS *base;
CLASSINFO *info;
CLASSINFO *base_info;
TYPE root = TypedefModifierRemoveOnly( type );
ds = DBBegStruct( CgTypeOutput( type ), !(root->flag & TF1_UNION) );
dt = DBStructForward( ds );
info = root->u.c.info;
if( dt != DBG_NIL_TYPE ){
info->dbg_no_vbases = dt;
type->dbg.handle = dt;
}
// define all the members
// first data members
stop = ScopeOrderedStart( root->u.c.scope );
curr = ScopeOrderedNext( stop, NULL );
while( curr != NULL ) {
if( SymIsClassMember( curr ) &&
SymIsData( curr ) &&
!SymIsEnumeration( curr ) &&
IsCppNameInterestingDebug( curr ) ) {
uint attribute;
byte offset = 0;
byte length = 0;
if( curr->flag & SF_PRIVATE ) {
attribute = FIELD_ATTR_PRIVATE;
} else if( curr->flag & SF_PROTECTED ) {
attribute = FIELD_ATTR_PROTECTED;
} else {
attribute = FIELD_ATTR_PUBLIC;
}
if( curr->sym_type->id == TYP_BITFIELD ) {
offset = curr->sym_type->u.b.field_start;
length = curr->sym_type->u.b.field_width;
}
dl = DBLocInit();
if( SymIsStaticDataMember( curr ) ) {
DbgAddrTaken( curr );
dl = DBLocSym( dl, symbolicDebugSymAlias( curr ) );
} else if( SymIsThisDataMember( curr ) ){
TYPE pt;
if( curr->u.offset != 0 ) {
dl = DBLocConst( dl, curr->u.offset );
dl = DBLocOp( dl, DB_OP_ADD, 0 );
}
pt = PointerTypeEquivalent( curr->sym_type );
if( pt
&& pt->id == TYP_POINTER
&& (pt->flag & TF1_REFERENCE) ) {
dl = DBLocOp( dl, DB_OP_POINTS,
CgTypeOutput( curr->sym_type ) );
dl = SymbolicDebugSetDataSegment( dl );
}
} else {
CFatal( "symdbg: illegal data member symbol" );
}
DBAddLocField( ds,
dl,
attribute,
offset,
length,
CppNameDebug( curr ),
SymbolicDebugType( curr->sym_type, SD_DEFAULT ) );
DBLocFini( dl );
}
curr = ScopeOrderedNext( stop, curr );
}
if( info->has_vbptr ) {
dl = DBLocInit();
if( info->vb_offset != 0 ) {
dl = DBLocConst( dl, info->vb_offset );
dl = DBLocOp( dl, DB_OP_ADD, 0 );
}
DBAddLocField( ds, dl, FIELD_ATTR_INTERNAL, 0, 0, "__vbptr",
SymbolicDebugType( pvb_FieldType, SD_DEFAULT ) );
DBLocFini( dl );
}
if( info->has_vfptr ) {
dl = DBLocInit();
if( info->vf_offset != 0 ) {
dl = DBLocConst( dl, info->vf_offset );
dl = DBLocOp( dl, DB_OP_ADD, 0 );
}
DBAddLocField( ds, dl, FIELD_ATTR_INTERNAL, 0, 0, "__vfptr",
SymbolicDebugType( pvf_FieldType, SD_DEFAULT ) );
DBLocFini( dl );
}
// now function members
stop = ScopeOrderedStart( root->u.c.scope );
curr = ScopeOrderedNext( stop, NULL );
while( curr != NULL ) {
if( SymIsClassMember( curr ) &&
!SymIsData( curr ) &&
IsCppNameInterestingDebug( curr ) ) {
if( SymIsEnumeration( curr ) ) {
SymbolicDebugType( curr->sym_type, SD_DEFAULT );
} else {
uint attribute;
if( curr->flag & SF_PRIVATE ) {
attribute = FIELD_ATTR_PRIVATE;
} else if( curr->flag & SF_PROTECTED ) {
attribute = FIELD_ATTR_PROTECTED;
} else {
attribute = FIELD_ATTR_PUBLIC;
}
dl = DBLocInit();
if( SymIsStaticFuncMember( curr ) ) {
dl = symbolicDebugSymAddr( dl, curr );
} else if( SymIsThisFuncMember( curr ) ) {
if( SymIsVirtual( curr ) ) {
if( info->vf_offset != 0 ) {
dl = DBLocConst( dl, info->vf_offset );
dl = DBLocOp( dl, DB_OP_ADD, 0 );
}
dl = DBLocOp( dl, DB_OP_POINTS,
CgTypeOutput( pvf_FieldType ) );
dl = DBLocConst( dl, ( curr->u.offset - VFUN_BASE ) *
vf_FieldTypeSize );
dl = DBLocOp( dl, DB_OP_ADD, 0 );
dl = DBLocOp( dl, DB_OP_POINTS,
CgTypeOutput( vf_FieldType ) );
dl = symbolicDebugSetCodeSegment( dl );
} else {
dl = symbolicDebugSymAddr( dl, curr );
}
} else {
CFatal( "symdbg: illegal function member symbol" );
}
DBAddLocField( ds,
dl,
attribute,
0,
0,
CppNameDebug( curr ),
SymbolicDebugType( curr->sym_type, SD_DEFAULT ) );
DBLocFini( dl );
}
}
curr = ScopeOrderedNext( stop, curr );
}
// define all the direct non-virtual bases
RingIterBeg( ScopeInherits( root->u.c.scope ), base ) {
if( _IsDirectNonVirtualBase( base ) ) {
dl = DBLocInit();
dl = DBLocConst( dl, base->delta );
SymbolicDebugType( base->type, SD_DEFAULT );
base_info = StructType( base->type )->u.c.info;
DBAddInheritance( ds, base_info->dbg_no_vbases,
FIELD_ATTR_PUBLIC, INHERIT_DBASE, dl );
DBLocFini( dl );
}
} RingIterEnd( base )
dt = DBEndStruct( ds );
info->dbg_no_vbases= dt;
if( ScopeHasVirtualBases( root->u.c.scope ) ) {
ds = DBBegStruct( CgTypeOutput( type ), !(root->flag & TF1_UNION) );
// define own component
dl = DBLocInit();
dl = DBLocConst( dl, 0 );
DBAddInheritance( ds, info->dbg_no_vbases,
FIELD_ATTR_PUBLIC, INHERIT_DBASE, dl );
DBLocFini( dl );
// define all the direct+indirect virtual bases
RingIterBeg( ScopeInherits( root->u.c.scope ), base ) {
if( _IsVirtualBase( base ) ) {
dl = DBLocInit();
if( info->vb_offset != 0 ) {
dl = DBLocConst( dl, info->vb_offset );
dl = DBLocOp( dl, DB_OP_ADD, 0 );
}
dl = DBLocOp( dl, DB_OP_POINTS, CgTypeOutput( pvb_FieldType ) );
dl = DBLocConst( dl, base->vb_index * vb_FieldTypeSize );
dl = DBLocOp( dl, DB_OP_ADD, 0 );
dl = DBLocOp( dl, DB_OP_POINTS, CgTypeOutput( vb_FieldType ) );
if( info->vb_offset != 0 ) {
dl = DBLocConst( dl, info->vb_offset );
dl = DBLocOp( dl, DB_OP_ADD, 0 );
}
SymbolicDebugType( base->type, SD_DEFAULT );
base_info = StructType( base->type )->u.c.info;
DBAddInheritance( ds, base_info->dbg_no_vbases,
FIELD_ATTR_PUBLIC, INHERIT_IVBASE, dl );
DBLocFini( dl );
}
} RingIterEnd( base )
dt = DBEndStruct( ds );
}
root->dbgflag |= TF2_SYMDBG;
root->dbg.handle = dt;
type->dbg.handle = dt;
return( dt );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?