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 + -
显示快捷键?