dwarf.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,009 行 · 第 1/5 页
C
2,009 行
while( p != NULL ){
if( p->id == TYP_TYPEDEF ){
SCOPE sc;
sc = p->u.t.scope;
if( sc->id == SCOPE_TEMPLATE_PARM ){
dwarfType( p, DC_DEFINE|DC_FAKE );
}
}
p = p->of;
}
}
}
}
#endif
static boolean dwarfClassInfoFriend( TYPE type, boolean addfriend )
/*****************************************************************/
{
dw_handle dh;
FRIEND *friend;
boolean check_friends;
check_friends = FALSE;
if( !InDebug ){ /* TODO: if debug need handle */
RingIterBeg( ScopeFriends( type->u.c.scope ), friend ) {
check_friends = TRUE;
if( addfriend ) {
dh = dwarfSymbol( friend->sym, DC_DEFAULT );
if( dh ) {
DWAddFriend( Client, dh );
}
} else {
dh = dwarfSymbol( friend->sym, DC_DEFINE );
}
} RingIterEnd( friend )
}
return( check_friends );
}
static boolean dwarfClassInfo( TYPE type )
/****************************************/
{
dw_handle dh;
SYMBOL stop, curr;
BASE_CLASS *base;
dw_loc_id locid;
dw_loc_handle dl;
CLASSINFO *info;
boolean check_friends;
// define any template typedefs
for(;;) {
SCOPE scope;
if( (type->flag & TF1_INSTANTIATION) == 0 ) break;
scope = type->u.c.scope->enclosing;
if( !ScopeType( scope, SCOPE_TEMPLATE_INST ) ) break;
scope = scope->enclosing;
if( !ScopeType( scope, SCOPE_TEMPLATE_PARM ) ) break;
stop = ScopeOrderedStart( scope );
curr = ScopeOrderedNext( stop, NULL );
while( curr != NULL ) {
if( SymIsTypedef( curr ) ) {
dwarfTypedef( curr->sym_type, DC_DEFINE|DC_FAKE );
}
curr = ScopeOrderedNext( stop, curr );
}
break;
}
// define all the bases
info = type->u.c.info;
RingIterBeg( ScopeInherits( type->u.c.scope ), base ) {
uint flags = 0;
switch( base->flag & IN_ACCESS_SPECIFIED ) {
case IN_PRIVATE:
flags |= DW_FLAG_PRIVATE;
break;
case IN_PROTECTED:
flags |= DW_FLAG_PROTECTED;
break;
case IN_PUBLIC:
flags |= DW_FLAG_PUBLIC;
break;
default:
if( type->flag & TF1_UNION || type->flag & TF1_STRUCT ) {
flags |= DW_FLAG_PUBLIC;
} else {
flags |= DW_FLAG_PRIVATE;
}
break;
}
if( _IsDirectVirtualBase( base ) ) {
flags |= DW_FLAG_VIRTUAL;
locid = DWLocInit( Client );
DWLocConstS( Client, locid, info->vb_offset );
DWLocOp0( Client, locid, DW_LOC_plus );
DWLocOp0( Client, locid, DW_LOC_dup );
DWLocOp0( Client, locid, DW_LOC_deref );
DWLocConstS( Client, locid, base->vb_index * vb_FieldTypeSize );
DWLocOp0( Client, locid, DW_LOC_plus );
DWLocOp0( Client, locid, DW_LOC_deref );
if( info->vb_offset != 0 ) {
DWLocConstS( Client, locid, info->vb_offset );
DWLocOp0( Client, locid, DW_LOC_plus );
}
DWLocOp0( Client, locid, DW_LOC_plus );
dl = DWLocFini( Client, locid );
DWAddInheritance( Client,
dwarfType( base->type, DC_DEFAULT ),
dl,
flags );
DWLocTrash( Client, dl );
} else if( _IsDirectNonVirtualBase( base ) ) {
locid = DWLocInit( Client );
DWLocConstS( Client, locid, base->delta );
DWLocOp0( Client, locid, DW_LOC_plus );
dl = DWLocFini( Client, locid );
DWAddInheritance( Client,
dwarfType( base->type, DC_DEFAULT ),
dl,
flags );
DWLocTrash( Client, dl );
}
} RingIterEnd( base )
// forward reference all the friends
check_friends = dwarfClassInfoFriend( type, TRUE );
// hidden data members
if( info->has_vbptr ) {
locid = DWLocInit( Client );
DWLocConstS( Client, locid, info->vb_offset );
DWLocOp0( Client, locid, DW_LOC_plus );
dl = DWLocFini( Client, locid );
dh = dwarfType( pvb_FieldType, DC_DEFAULT );/* CppName no reentrant */
dh = DWAddField( Client,
dh,
dl,
"__vbptr",
DW_FLAG_ARTIFICIAL );
DWLocTrash( Client, dl );
}
if( info->has_vfptr ) {
locid = DWLocInit( Client );
DWLocConstS( Client, locid, info->vf_offset );
DWLocOp0( Client, locid, DW_LOC_plus );
dl = DWLocFini( Client, locid );
dh = dwarfType( pvf_FieldType, DC_DEFAULT );/* CppName no reentrant */
dh = DWAddField( Client,
dh,
dl,
"__vfptr",
DW_FLAG_ARTIFICIAL );
DWLocTrash( Client, dl );
}
// define all the fields
stop = ScopeOrderedStart( type->u.c.scope );
curr = ScopeOrderedNext( stop, NULL );
while( curr != NULL ) {
sym_reset( curr );
if( !IsCppNameInterestingDebug( curr ) ) {
dh = 0;
}else if( !InDebug && (curr->flag2 & SF2_TOKEN_LOCN)==0 ) {
dh = 0;
} else if( SymIsClassDefinition( curr ) ) {
dh = dwarfSymbol( curr, DC_DEFINE );
} else if( SymIsEnumDefinition( curr ) ) {
dh = dwarfSymbol( curr, DC_DEFINE );
} else if( SymIsEnumeration( curr ) ) {
// do nothing, handled by SymIsEnumDefinition
dh = 0;
} else if( SymIsFunction( curr ) ) {
// dwarfPumpArgTypes( curr->sym_type );
if( InDebug ){ /* gen a short defn */
dh = dwarfDebugMemberFuncDef( info, curr );
dh = 0; // if debug we don't want to clash with cg_handle
}else{
dh = dwarfSymbol( curr, DC_DEFINE );
}
} else if( SymIsTypedef( curr ) ) {
dh = dwarfSymbol( curr, DC_DEFINE );
} else if( SymIsData( curr ) ) {
uint flags;
TYPE pt;
if( !InDebug ){
dwarfLocation( curr );
}
if( curr->flag & SF_PRIVATE ) {
flags = DW_FLAG_PRIVATE;
} else if( curr->flag & SF_PROTECTED ) {
flags = DW_FLAG_PROTECTED;
} else {
flags = DW_FLAG_PUBLIC;
}
if( SymIsStaticMember( curr ) ) {
dw_loc_handle dl_seg;
flags |= DW_FLAG_STATIC;
dl_seg = NULL;
if( InDebug ){
dl = dwarfDebugStaticLoc( curr );
#if _INTEL_CPU
if(!( TargetSwitches & FLAT_MODEL )) {
dl_seg = dwarfDebugStaticSeg( curr );
}
#endif
}else{ /* fake up loc for browser */
locid = DWLocInit( Client );
dl = DWLocFini( Client, locid );
}
dh = dwarfType( curr->sym_type, DC_DEFAULT );/* CppName no reentrant */
dh = DWVariable( Client,
dh,
dl,
NULL,
dl_seg,
CppNameDebug( curr ),
0,
flags );
if( dl_seg != NULL ){
DWLocTrash( Client, dl_seg );
}
if( InDebug ){
dh = 0; // if debug we don't want to clash with cg_handle
}
} else if( SymIsThisDataMember( curr ) ){
TYPE sym_type = curr->sym_type;
TYPE btf = TypedefModifierRemoveOnly( sym_type );
locid = DWLocInit( Client );
DWLocOp( Client, locid, DW_LOC_plus_uconst,
curr->u.offset );
pt = PointerTypeEquivalent( sym_type );
if( pt
&& pt->id == TYP_POINTER
&& (pt->flag & TF1_REFERENCE) ) {
DWLocOp0( Client, locid, DW_LOC_deref );
}
dl = DWLocFini( Client, locid );
if( btf->id == TYP_BITFIELD ) {
int strt;
int tsize;
tsize = CgTypeSize( btf->of );
strt = 8*tsize-(btf->u.b.field_start+btf->u.b.field_width);
dh = dwarfType( sym_type, DC_DEFAULT );/* CppName no reentrant */
dh = DWAddBitField( Client,
dh,
dl,
tsize,
strt,
btf->u.b.field_width,
CppNameDebug( curr ),
flags );
} else {
dh = dwarfType( sym_type, DC_DEFAULT );/* CppName no reentrant */
dh = DWAddField( Client,
dh,
dl,
CppNameDebug( curr ),
flags );
}
}
DWLocTrash( Client, dl );
} else if( curr->id == SC_ACCESS ) {
// fixme: access modifiers ignored for now
dh = 0;
} else {
dh = 0;
#ifndef NDEBUG
DumpSymbol( curr );
CFatal( "dwarf: illegal member" );
#endif
}
if( dh != 0 ) {
sym_reset( curr );
sym_update( curr, SF2_DW_HANDLE_DEF, dh );
}
curr = ScopeOrderedNext( stop, curr );
}
return( check_friends );
}
static dw_handle dwarfClass( TYPE type, DC_CONTROL control )
/**********************************************************/
{
dw_handle dh;
char *name;
boolean defined;
boolean check_friends;
type_reset( type );
if( type->dbgflag & TF2_DWARF ) {
dh = type->dbg.handle;
} else {
uint kind;
if( type->flag & TF1_UNION ) {
kind = DW_ST_UNION;
} else if( type->flag & TF1_STRUCT ) {
kind = DW_ST_STRUCT;
} else {
kind = DW_ST_CLASS;
}
dh = DWStruct( Client, kind );
type_update( type, TF2_DWARF_FWD, dh );
}
if( type->dbgflag & TF2_DWARF_DEF ) {
return( dh );
}
defined = (type->u.c.info->defined != 0);
if( !defined || type->u.c.info->unnamed
|| (control & DC_DEFINE) ) {
type_update( type, TF2_DWARF_DEF, dh );
if( (type->u.c.info->anonymous == 0)
&&(type->u.c.info->unnamed == 0) ) {
name = SimpleTypeName( type );
} else {
name = NULL;
}
DWBeginStruct( Client,
dh,
CgTypeSize( type ),
name,
0,
(defined ? 0 : DW_FLAG_DECLARATION ) );
check_friends = FALSE;
if( defined ) {
check_friends = dwarfClassInfo( type );
}
DWEndStruct( Client );
if( check_friends ) {
dwarfClassInfoFriend( type, FALSE );
}
}
return( dh );
}
static dw_handle dwarfEnum( TYPE type, DC_CONTROL control )
/*********************************************************/
{
dw_handle dh;
type_reset( type );
if( type->dbgflag & TF2_DWARF ) {
dh = type->dbg.handle;
} else {
dh = DWHandle( Client, DW_ST_NONE );
type_update( type, TF2_DWARF_FWD, dh );
}
if( type->dbgflag & TF2_DWARF_DEF ) {
return( dh );
}
if( (type->flag & TF1_UNNAMED) //check for enum{ }foo
|| ( control & DC_DEFINE ) ){
SYMBOL sym;
type_update( type, TF2_DWARF_DEF, dh );
DWHandleSet( Client, dh );
dh = DWBeginEnumeration( Client,
CgTypeSize( type->of ),
SimpleTypeName( type ),
0,
0 );
sym = type->u.t.sym->thread;
while( SymIsEnumeration( sym ) ) {
// fixme: enums need to be in reverse order
DWAddConstant( Client, sym->u.sval, sym->name->name );
sym = sym->thread;
}
DWEndEnumeration( Client );
}
return( dh );
}
static dw_handle dwarfTypedef( TYPE type, DC_CONTROL control )
/************************************************************/
{
dw_handle dh;
type_reset( type );
if( type->dbgflag & TF2_DWARF ) {
dh = type->dbg.handle;
} else {
dh = DWHandle( Client, DW_ST_NONE );
type_update( type, TF2_DWARF_FWD, dh );
}
if( type->dbgflag & TF2_DWARF_DEF ) {
return( dh );
}
if( control & DC_DEFINE ) {
dw_handle of_hdl;
TYPE of_type;
SYMBOL sym;
uint flags;
type_update( type, TF2_DWARF_DEF, dh );
sym = type->u.t.sym;
of_type = StructType( type->of );
if( (of_type == type->of)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?