symdbg.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,175 行 · 第 1/3 页
C
1,175 行
static dbg_type symbolicMethodType( SYMBOL curr, TYPE cls ){
/*************************************************************/
dbg_proc dp;
arg_list *alist;
int i;
TYPE base;
TYPE type;
TYPE this_type;
dbg_type this_dbg;
dbg_type ret;
dbg_type dc;
type = curr->sym_type;
base = TypedefModifierRemoveOnly( type );
if( type->dbgflag & TF2_NON_SYMDBG ) {
type->dbgflag &= ~TF2_NON_SYMDBG;
type->dbg.handle = DBG_NIL_TYPE;
}
dp = DBBegProc( CgTypeOutput( type ),
SymbolicDebugType( base->of,
SD_DEFAULT ^SD_DEREF ) );//XOR
dc = SymbolicDebugType( cls, SD_DEFAULT );
this_type = TypeThisSymbol( curr, FALSE );
if( this_type != NULL ){
this_dbg = SymbolicDebugType( this_type,
SD_DEFAULT ^SD_DEREF );//XOR
}else{
this_dbg = DBG_NIL_TYPE;
}
DBAddMethParms( dp, dc, this_dbg );
alist = TypeArgList( base );
for( i = 0 ; i < alist->num_args ; i++ ) {
if( alist->type_list[i]->id == TYP_DOT_DOT_DOT ) break;
DBAddParm( dp,
SymbolicDebugType( alist->type_list[i],
SD_DEFAULT^SD_DEREF ) );//XOR
}
ret = DBEndProc( dp );
type->dbgflag |= TF2_SYMDBG;
type->dbg.handle = ret;
return( ret );
}
static dbg_type symCVDebugClassType( TYPE type )
/*************************************************/
{ // Dump Codeview class
dbg_type dt;
dbg_type dmt;
dbg_struct ds;
dbg_loc dl;
SYMBOL stop, curr;
BASE_CLASS *base;
CLASSINFO *info;
CLASSINFO *base_info;
TYPE root = TypedefModifierRemoveOnly( type );
info = root->u.c.info;
if( info->unnamed ){
ds = DBBegStruct( CgTypeOutput( type ), !(root->flag & TF1_UNION) );
}else{
ds = DBBegNameStruct( info->name, CgTypeOutput( type ), !(root->flag & TF1_UNION) );
}
DBNested( FALSE );
dt = DBStructForward( ds );
if( dt != DBG_NIL_TYPE ){
info->dbg_no_vbases = dt;
type->dbg.handle = dt;
}
// 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 )
if( ScopeHasVirtualBases( root->u.c.scope ) ) {
// Dump virtual bases
dbg_type dvbt;
// define all the direct+indirect virtual bases
dvbt = SymbolicDebugType( vb_FieldType, SD_DEFAULT );
DBAddBaseInfo( ds, info->vb_offset,vb_FieldTypeSize, dvbt, CgTypeOutput( pvb_FieldType ) );
RingIterBeg( ScopeInherits( root->u.c.scope ), base ) {
if( _IsDirectVirtualBase( base ) ) { /* cv specific could be adapted */
dl = DBLocInit();
dl = DBLocConst( dl, base->vb_index );
SymbolicDebugType( base->type, SD_DEFAULT );
base_info = StructType( base->type )->u.c.info;
DBAddInheritance( ds, base_info->dbg_no_vbases,
FIELD_ATTR_PUBLIC, INHERIT_VBASE, dl );
DBLocFini( dl );
}
} RingIterEnd( base )
// Dump Indirect virtual bases
RingIterBeg( ScopeInherits( root->u.c.scope ), base ) {
if( _IsIndirectVirtualBase( base ) ) {
dl = DBLocInit();
dl = DBLocConst( dl, base->vb_index );
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 )
}
// first data members
stop = ScopeOrderedStart( root->u.c.scope );
curr = ScopeOrderedNext( stop, NULL );
while( curr != NULL ) {
if( SymIsClassDefinition( curr )||SymIsEnumDefinition( curr ) ) {
DBNested( TRUE );
DBAddNestedType( ds,
CppNameDebug( curr ),
SymbolicDebugType( curr->sym_type, SD_DEFAULT ) );
DBNested( FALSE );
} else if( SymIsEnumeration( curr ) ) {
} else if( SymIsInjectedTypedef( curr ) ) {
} else if( SymIsTypedef( curr ) ) {
} else if( SymIsStaticDataMember( curr ) ) {
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;
}
DbgAddrTaken( curr );
dl = DBLocInit();
dl = DBLocSym( dl, symbolicDebugSymAlias( curr ) );
DBAddStField( ds, dl,
CppNameDebug( curr ),
attribute,
SymbolicDebugType( curr->sym_type, SD_DEFAULT ) );
if( SymIsInitialized( curr ) ){
if( GenSwitches & DBG_LOCALS ) {
DBGenStMem( (cg_sym_handle)curr, dl );
}
}
DBLocFini( dl );
} else 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( SymIsThisDataMember( curr ) ){
if( curr->u.offset != 0 ) {
dl = DBLocConst( dl, curr->u.offset );
dl = DBLocOp( dl, DB_OP_ADD, 0 );
}
} 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_vfptr ) {
DBAddVFuncInfo(ds, info->vf_offset, info->last_vfn, CgTypeOutput( pvf_FieldType ) );
}
// 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;
uint kind;
kind = METHOD_VANILLA;
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 ) ) {
kind = METHOD_STATIC;
dl = symbolicDebugSymAddr( dl, curr );
} else if( SymIsThisFuncMember( curr ) ) {
if( SymIsVirtual( curr ) ) {
kind = METHOD_VIRTUAL;
dl = DBLocConst( dl, ( curr->u.offset - VFUN_BASE ) *
vf_FieldTypeSize );
} else {
dl = symbolicDebugSymAddr( dl, curr );
}
} else {
CFatal( "symdbg: illegal function member symbol" );
}
dmt = symbolicMethodType( curr, type );
DBAddMethod( ds,
dl,
attribute,
kind,
CppNameDebug( curr ),
dmt );
DBLocFini( dl );
}
}
curr = ScopeOrderedNext( stop, curr );
}
dt = DBEndStruct( ds );
info->dbg_no_vbases = dt;
root->dbgflag |= TF2_SYMDBG;
root->dbg.handle = dt;
type->dbg.handle = dt;
return( dt );
}
static dbg_type symbolicDebugClassType( TYPE type )
/*************************************************/
{
dbg_type ret;
if( GenSwitches & DBG_CV ) {
ret = symCVDebugClassType( type );
}else{
ret = symWVDebugClassType( type );
}
return( ret );
}
static dbg_type basedPointerType( TYPE type,
TYPE base,
SD_CONTROL control ){
/*****************************************************/
TYPE btype;
dbg_loc dl;
dbg_type dt;
btype = BasedType( base->of );
dl = DBLocInit();
switch( btype->flag & TF1_BASED ) {
//a caution if you change these expressions
//codeview and dwarf might not be able to translate them
case TF1_BASED_STRING:
dl = DBLocConst( dl, 0 );
if( SegmentFindBased( btype ) == SEG_CODE ) {
dl = symbolicDebugSetCodeSegment( dl );
} else {
// fixme: this should handle segments that aren't
// in DGROUP by defining a symbol in that segment and
// using it. For now all such pointers just go to
// DGROUP. Note that defining a symbol in that segment
// may require defining that segment.
dl = SymbolicDebugSetDataSegment( dl );
}
break;
case TF1_BASED_SELF:
dl = DBLocConst( dl, 0 );
dl = DBLocOp( dl, DB_OP_MK_FP, 0 );
break;
case TF1_BASED_VOID:
dl = DBLocConst( dl, 0 );
dl = DBLocConst( dl, 0 );
dl = DBLocOp( dl, DB_OP_MK_FP, 0 );
break;
case TF1_BASED_FETCH:
dl = DBLocSym( dl, symbolicDebugSymAlias( btype->u.m.base ) );
dl = DBLocOp( dl, DB_OP_POINTS,
CgTypeOutput( GetBasicType( TYP_USHORT ) ) );
dl = DBLocConst( dl, 0 );
dl = DBLocOp( dl, DB_OP_MK_FP, 0 );
break;
case TF1_BASED_ADD:
{ SYMBOL sym;
TYPE bptr;
TYPE ptr;
type_flag flags;
sym = (SYMBOL)btype->u.m.base;
dl = DBLocSym( dl, symbolicDebugSymAlias( sym ) );
bptr = TypedefModifierRemove( sym->sym_type );
bptr = TypeModFlagsEC( bptr->of, &flags );
ptr = GetBasicType( TYP_VOID );
if( flags & TF1_NEAR ) {
ptr = MakePointerTo( ptr );
dl = DBLocOp( dl, DB_OP_POINTS, CgTypeOutput( ptr ) );
if( bptr->id == TYP_FUNCTION ) {
dl = symbolicDebugSetCodeSegment( dl );
} else {
dl = SymbolicDebugSetDataSegment( dl );
}
} else {
ptr = MakeModifiedType( ptr, TF1_FAR );
ptr = MakePointerTo( ptr );
dl = DBLocOp( dl, DB_OP_POINTS, CgTypeOutput( ptr ) );
}
} break;
}
dt = DBBasedPtr( CgTypeOutput( type ),
SymbolicDebugType( base->of, control ),
dl );
DBLocFini( dl );
return( dt );
}
dbg_type SymbolicDebugType( TYPE type, SD_CONTROL control )
/*********************************************************/
{
FWD_INFO *fwd_info;
TYPE base;
dbg_type dt = DBG_NIL_TYPE;
if( type->dbgflag & TF2_NON_SYMDBG ) {
type->dbg.handle = DBG_NIL_TYPE;
}
type->dbgflag = (type->dbgflag & ~TF2_NON_SYMDBG);
// mark current location to allow breaking of cycles in type structure
if( type->dbg.handle == DBG_FWD_TYPE ) {
FWD_INFO *fip;
fip = prevFwdInfo;
while( fip->type != type ) {
fip = fip->next;
}
if( fip->dn == NULL ) {
fip->dn = DBBegName( "", fip->dt );
}
type->dbgflag |= TF2_SYMDBG;
type->dbg.handle = DBForward( fip->dn );
if( type->id == TYP_CLASS ) {
if( ScopeHasVirtualBases( type->u.c.scope ) ) {
fip->comp_dn = DBBegName( "", DBG_NIL_TYPE );
type->u.c.info->dbg_no_vbases = DBForward( fip->comp_dn );
} else {
fip->comp_dn = fip->dn;
type->u.c.info->dbg_no_vbases = type->dbg.handle;
}
}
}
// if we have already done this one, just return it
if( type->dbg.handle != DBG_NIL_TYPE ) {
return( type->dbg.handle );
}
// chain the cycle breaking list
fwd_info = CarveAlloc( carveFWD_INFO );
fwd_info->next = prevFwdInfo;
fwd_info->type = type;
fwd_info->dn = NULL;
fwd_info->dt = DBG_NIL_TYPE;
fwd_info->comp_dn = NULL;
// typedefs require special handling
// normally we ignore typedefs, but we want the names to come out
if( type->id == TYP_TYPEDEF ) {
if( ScopeType( type->u.t.scope, SCOPE_TEMPLATE_DECL ) ) return( dt );
if( !ScopeType( type->u.t.scope, SCOPE_TEMPLATE_PARM )
&& !ScopeType( type->u.t.scope, SCOPE_TEMPLATE_PARM ) ) {
if( !CompFlags.no_debug_type_names ) {
if( !ScopeType( type->u.t.scope, SCOPE_TEMPLATE_INST ) ) {
fwd_info->dn = DBBegName( SimpleTypeName( type ),
DBG_NIL_TYPE );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?