dftypes.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 794 行 · 第 1/2 页

C
794
字号
/******************************************************/
    dbg_type    ret;
    uint        class;

    if( st->is_struct ){
        class = DW_ST_STRUCT;
    }else{
        class = DW_ST_UNION;
    }
    ret = DWStruct( Client, class );
    st->me = ret;
}


typedef struct {
    dw_loc_id       locid;
    bool            addr_seg:1;
    bool            seg     :1;
    bool            offset  :1;
}loc_state;

static  dw_loc_id   DoLocCnv( dbg_loc loc, loc_state *state ) {
/****************************************/

    type_length     offset;
    dw_loc_id       locid;
    uint            dref_op;
    uint            size;
    dw_sym_handle   sym;

    if( loc->next != NULL ) {
        locid = DoLocCnv( loc->next, state );
    }else{
        locid = state->locid;
    }
    switch( loc->class & 0xf0 ) {
    case LOC_CONSTANT:
        if( loc->class == LOC_MEMORY ) {
            sym = (dw_sym_handle)loc->u.fe_sym;
            if( state->seg == TRUE ){
                DWLocSegment( Client, locid, sym );
            }
            if( state->offset == TRUE ){
                DWLocStatic( Client, locid, sym );
                if( state->seg ){
                    state->addr_seg = TRUE;
                }
            }
        } else {
            offset = loc->u.val;
            DWLocConstS( Client, locid, offset );
        }
        break;
    case LOC_BP_OFFSET:
        offset = NewBase( loc->u.be_sym );
        DWLocOp( Client, locid, DW_LOC_fbreg, offset );
        break;
    case LOC_REG:
        DFOutReg( locid, loc->u.be_sym );
        break;
    case LOC_IND_REG:
        if( HW_CEqual( loc->u.be_sym->r.reg, HW_EMPTY ) ) {
            //NYI: structured return value on the stack. Have to do something
            //       suitable. For now, output a no location.
            DWLocOp( Client,locid,DW_LOC_breg, 0, 0 );
        } else {
            DFOutRegInd( locid, loc->u.be_sym );
        }
        break;
    case LOC_OPER:
        switch( loc->class & 0x0f ) {
        case LOP_IND_2:
        case LOP_IND_4:
            if( state->addr_seg ){
                dref_op =  DW_LOC_xderef_size;
            }else{
                dref_op =  DW_LOC_deref_size;
            }
            if( (loc->class & 0x0f) == LOP_IND_2 ){
                size = 2;
            }else{
                size = 4;
            }
            DWLocOp( Client, locid, dref_op, size );
            state->addr_seg = FALSE;  /* ate offset seg */
            break;
        case LOP_IND_ADDR286:
        case LOP_IND_ADDR386:
            if( (loc->class & 0x0f) == LOP_IND_ADDR286 ){
                size = 2;
            }else{
                size = 4;
            }
            if( state->addr_seg ){
                dref_op =  DW_LOC_xderef_size;
                DWLocOp0( Client, locid, DW_LOC_pick );  /* dup seg */
                DWLocOp0( Client, locid, DW_LOC_pick );  /* dup offset */
                DWLocOp( Client, locid, DW_LOC_plus_uconst, size ); /* seg offset*/
                DWLocOp( Client, locid, dref_op, 2 );  /* push seg */
                DWLocOp0( Client, locid, DW_LOC_rot );  /* seg at bottom */
                DWLocOp( Client, locid, dref_op, size ); /* push offset */
                /* now have offset seg on stack */
            }else{
                dref_op =  DW_LOC_deref_size;
                DWLocOp0( Client, locid, DW_LOC_dup );    /* dup offset */
                DWLocOp( Client, locid, DW_LOC_plus_uconst, size ); /* seg offset*/
                DWLocOp( Client, locid, dref_op, 2 );  /* push seg */
                DWLocOp0( Client, locid, DW_LOC_swap ); /* get dup offset */
                DWLocOp( Client, locid, dref_op, size ); /* push offset */
                /* now have offset seg on stack */
            }
            state->addr_seg = TRUE; /* we have offset seg on stack */
            break;
        case LOP_ZEB:
            DWLocConstU( Client, locid, 0xff );
            DWLocOp0( Client, locid, DW_LOC_and );
            break;
        case LOP_ZEW:
            DWLocConstU( Client, locid, 0xffff );
            DWLocOp0( Client, locid, DW_LOC_and );
            break;
        case LOP_MK_FP:
            state->addr_seg = TRUE;
            break;
        case LOP_POP:
            DWLocOp0( Client, locid, DW_LOC_drop );
            break;
        case LOP_XCHG:
            DWLocOp0( Client, locid, DW_LOC_swap );
            break;
        case LOP_ADD:
            DWLocOp0( Client, locid, DW_LOC_plus );
            break;
        case LOP_DUP:
            DWLocOp0( Client, locid, DW_LOC_dup );
            break;
        case LOP_NOP:
            DWLocOp0( Client, locid, DW_LOC_not );
            break;
        }
        break;
    default:
        break;
    }
    return( locid );
}

static  dbg_loc   SkipMkFP( dbg_loc loc ) {
/****************************************/
//skip a MkFP and operand

    if( (loc->class & 0xf0) == LOC_OPER ) {
        if( (loc->class & 0x0f) == LOP_MK_FP  ){
            loc = loc->next;  /* skip MK_FP */
            loc = loc->next;   /* skip operand */
        }
    }
    return( loc );
}

extern dw_loc_id DBGLoc2DFCont( dbg_loc loc, dw_loc_id df_locid ){
/*****************************************/
/* Convert Brian to a dwarf              */
/* in a continious fasion                */
/*****************************************/
    loc_state       state;

    state.seg = FALSE;
    state.offset = TRUE;
    state.addr_seg = FALSE;
    state.locid = df_locid;
    if( loc != NULL ){
        df_locid = DoLocCnv( loc, &state );
    }
    return( df_locid );

}
extern dw_loc_handle DBGLoc2DF( dbg_loc loc ){
/*****************************************/
/* Convert Brian to a dwarf                */
/*****************************************/
    dw_loc_id       df_locid;
    dw_loc_handle   df_loc;
    loc_state       state;

    state.seg = FALSE;
    state.offset = TRUE;
    state.addr_seg = FALSE;
    state.locid = DWLocInit( Client );
    if( loc != NULL ){
        df_locid = DoLocCnv( loc, &state );
        df_loc = DWLocFini( Client, df_locid );
    }else{
        df_locid = state.locid;
        df_loc = DWLocFini( Client, df_locid );
    }
    return( df_loc );

}

extern dw_loc_handle DBGLocBase2DF( dbg_loc loc_seg ){
/*****************************************/
/* Convert Brian to a dwarf                */
/*****************************************/
    dw_loc_id       df_locid;
    dw_loc_handle   df_loc;
    loc_state       state;

    state.seg = TRUE;
    state.offset = TRUE;
    state.addr_seg = FALSE;
    state.locid = DWLocInit( Client );
    loc_seg = SkipMkFP( loc_seg );
    if( loc_seg != NULL ){
        df_locid = DoLocCnv( loc_seg, &state );
        df_loc = DWLocFini( Client, df_locid );
    }else{
        df_locid = state.locid;
        df_loc = DWLocFini( Client, df_locid );
    }
    return( df_loc );

}
extern  dbg_type        DFBasedPtr( cg_type ptr_type, dbg_type base,
                                        dbg_loc loc_segment ) {
/****************************************************************/
/* need support to get segment value */
    dbg_type        ret;
    uint            flags;
    dw_loc_handle   dw_segloc;

    dw_segloc = DBGLocBase2DF( loc_segment );
    flags = DFPtrClass( ptr_type );
    ret = DWBasedPointer( Client, base, dw_segloc, flags );
    if( dw_segloc != NULL ){
        DWLocTrash( Client, dw_segloc );
    }
    return( ret );
}

static int WVDFAccess( uint attr ){
    int ret;

    if( attr & FIELD_INTERNAL ){
        attr &= ~FIELD_INTERNAL;
        ret = DW_FLAG_ARTIFICIAL;
    }else{
        ret = 0;
    }
    switch( attr ){
    case FIELD_PUBLIC:
        ret |= DW_FLAG_PRIVATE;
        break;
    case FIELD_PROTECTED:
        ret |= DW_FLAG_PROTECTED;
        break;
    case FIELD_PRIVATE:
        ret |= DW_FLAG_PRIVATE;
        break;
    }
    return( ret );
}

extern  dbg_type        DFEndStruct( struct_list  *st ) {
/*******************************************************/

    field_any      *field;
    dbg_type        ret;
    dw_loc_id       locid;
    dw_loc_handle   loc;
    char           *name;
    uint            flags;

    ret = st->me;
    if( st->name[0] != '\0' ){
        name = st->name;
    }else{
        name = NULL;
    }
    DWBeginStruct( Client, ret, st->size, name, 0, 0 );
    for(;;) {
        field = st->list;
        if( field == NULL ) break;
        switch( field->entry.field_type ) {
        case FIELD_INHERIT:
            flags = WVDFAccess(field->bclass.attr );
            loc = DBGLoc2DF( field->bclass.u.adjustor );
            DBLocFini( field->bclass.u.adjustor );
            if( field->bclass.kind == INHERIT_VBASE ){
                flags |= DW_FLAG_VIRTUAL;
            }
            DWAddInheritance( Client, field->bclass.base, loc, flags );
            DWLocTrash( Client, loc );
            break;
        case FIELD_METHOD:
            DBLocFini( field->method.u.loc );
            break;
        case FIELD_NESTED:
            break;
        case FIELD_LOC:
        case FIELD_OFFSET:
            /* some loc thing */
            flags = WVDFAccess(field->member.attr );
            if( field->entry.field_type == FIELD_LOC ){
                loc = DBGLoc2DF( field->member.u.loc );
                 DBLocFini( field->member.u.loc );
            }else{
                locid = DWLocInit( Client );
                DWLocConstU( Client, locid, field->member.u.off );
                DWLocOp0( Client, locid, DW_LOC_plus );
                loc = DWLocFini( Client, locid );
            }
            if( field->member.b_strt == 0 && field->member.b_len == 0 ){
                DWAddField( Client, field->member.base, loc,
                    field->member.name, flags );
            }else{
                int bit_start;

                bit_start = 4*8-( field->member.b_strt+field->member.b_len);
                DWAddBitField( Client, field->member.base, loc, 4,
                               bit_start, field->member.b_len,
                               field->member.name, flags );
            }
            DWLocTrash( Client, loc );
            break;
        case FIELD_STFIELD:
            /* some loc thing */
            flags = WVDFAccess( field->stfield.attr );
            loc = DBGLoc2DF( field->stfield.loc );
            DBLocFini( field->stfield.loc );
            DWAddField( Client, field->stfield.base, loc,
                         field->stfield.name, flags | DW_FLAG_STATIC );
            DWLocTrash( Client, loc );
            break;
        }
        st->list = field->entry.next;
        _Free( field, sizeof( field_entry ) );
    }
    DWEndStruct( Client );
    return( ret );
}


extern  dbg_type        DFEndEnum( enum_list *en ) {
/**************************************************/
    dbg_type    ret;
    type_def    *tipe_addr;
    const_entry *cons;
    signed_64   val;

    tipe_addr = TypeAddress( en->tipe );
    ret = DWBeginEnumeration( Client, tipe_addr->length, NULL, 0, 0 );
    for(;;) {
        cons = en->list;
        if( cons == NULL ) break;
        val = cons->val;
        if( val.u._32[I64HI32] == 0 || val.u._32[I64HI32] == -1 ){
            DWAddConstant( Client, val.u._32[I64LO32], cons->name );
        }else{
            DWAddConstant( Client, val.u._32[I64LO32], cons->name );
        }
        en->list = cons->next;
        _Free( cons, sizeof( const_entry ) + cons->len );
    }
    DWEndEnumeration( Client );
    return( ret );
}


extern  dbg_type        DFEndProc( proc_list  *pr ) {
/***************************************************/

    parm_entry  *parm;
    dbg_type    proc_type;
    uint        flags;


//  flags = DFPtrClass( pr->call );
    flags = DW_FLAG_PROTOTYPED | DW_FLAG_DECLARATION;
    proc_type = DWBeginSubroutineType( Client, pr->ret, NULL, 0, flags );
    parm = pr->list;
    if( parm == NULL ){
        DWAddEllipsisToSubroutineType( Client );
    }
    for(;;) {
        if( parm == NULL ) break;
        DWAddParmToSubroutineType( Client, parm->tipe, NULL, NULL, NULL );
        pr->list = parm->next;
        _Free( parm, sizeof( parm_entry ) );
        parm = pr->list;
    }
    DWEndSubroutineType( Client );
    return( proc_type );
}


⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?