dbgexpr4.c

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

C
1,355
字号
            U64ShiftL( &left->v.uint, shift, &left->v.uint );
        } else if( (left->info.modifier & TM_MOD_MASK) == TM_UNSIGNED ) {
            U64ShiftR( &left->v.uint, -shift, &left->v.uint );
        } else {
            I64ShiftR( &left->v.sint, -shift, &left->v.sint );
        }
        break;
    default:
        Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
        break;
    }
    CombineEntries( left, left, ExprSP );
}


/*
 * DoAddr - take the address of a stack entry
 */

void DoAddr( void )
{
    mad_type_info       mti;

    LValue( ExprSP );
    if( (ExprSP->flags & SF_LOCATION)
        && ExprSP->v.loc.num == 1
        && ExprSP->v.loc.e[0].type == LT_ADDR ) {
        ExprSP->v.addr = ExprSP->v.loc.e[0].u.addr;
        ExprSetAddrInfo( ExprSP, FALSE );
        if( ExprSP->th != NULL ) {
            GetMADTypeDefaultAt( ExprSP->v.addr, MTK_ADDRESS, &mti );
            TypePointer(ExprSP->th, TM_FAR, mti.b.bits / BITS_PER_BYTE, ExprSP->th);
            ExprSP->info.kind = TK_POINTER;
        } else {
            ExprSP->info.kind = TK_ADDRESS;
        }
        ExprSP->flags &= ~SF_FORM_MASK;
    } else {
        Error( ERR_NONE, LIT( ERR_NEED_ADDRESS ) );
    }
}


/*
 * DoPoints - do an indirection
 */

void DoAPoints( stack_entry *stk, type_kind def )
{
    stack_flags         was_imp_addr;
    addr_off            off;

    LRValue( stk );
    was_imp_addr = stk->flags & SF_IMP_ADDR;
    switch( stk->info.kind ) {
    case TK_BOOL:
    case TK_ENUM:
    case TK_CHAR:
    case TK_INTEGER:
        //NYI: 64 bit offsets
        off = U32FetchTrunc( stk->v.uint );
        stk->v.addr = DefAddrSpaceForAddr( Context.execution );
        stk->v.addr.mach.offset = off;
        stk->info.modifier = TM_NEAR;
        /* fall through */
    case TK_POINTER:
    case TK_ADDRESS:
        if( stk->th != NULL ) {
            LocationCreate( &stk->v.loc, LT_ADDR, &stk->v.addr );
            TypeBase( stk->th, stk->th, stk->lc, &stk->v.loc );
            ClassifyEntry( stk, &stk->info );
            if( stk->info.kind == TK_VOID ) Error( ERR_NONE, LIT( ERR_VOID_BASE ) );
        } else {
            if( def == TK_NONE ) def = TK_INTEGER;
            stk->info.kind = def;
            switch( def ) {
            case TK_INTEGER:
                stk->info.modifier = TM_UNSIGNED;
                stk->info.size = DefaultSize( DK_INT );
                break;
            case TK_ADDRESS:
                ExprSetAddrInfo( stk, FALSE );
                break;
            }
            LocationCreate( &stk->v.loc, LT_ADDR, &stk->v.addr );
        }
        stk->flags |= SF_LOCATION | was_imp_addr;
        break;
    default:
        Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
        break;
    }
    stk->flags &= ~SF_CONST;
}

void DoPoints( type_kind def )
{
    DoAPoints( ExprSP, def );
}

/*
 * ConvertGiven -- convert a stack entry to the type of another stack entry
 */

static void ConvertGiven( stack_entry *object, stack_entry *new )
{
    type_info           new_type;
    type_info           obj_type;
    DIPHDL( type, obj_th );
    DIPHDL( type, new_th );

    if( object->th != NULL ) HDLAssign( type, obj_th, object->th );
    ClassifyEntry( new, &new_type );
    new_type.modifier &= TM_MOD_MASK; /* turn off DEREF bit */
    ConvertTo( object, new_type.kind, new_type.modifier, new_type.size );
    if( object->th == NULL ) goto no_adjust;
    ClassifyEntry( object, &obj_type );
    if( obj_type.kind != TK_POINTER ) goto no_adjust;
    if( AddrComp( object->v.addr, NilAddr ) == 0 ) goto no_adjust;
    TypeBase( obj_th, obj_th, NULL, NULL );
    ClassifyType( object->lc, obj_th, &obj_type );
    if( obj_type.kind != TK_STRUCT ) goto no_adjust;
    ClassifyEntry( new, &new_type );
    if( new_type.kind != TK_POINTER ) goto no_adjust;
    TypeBase( new->th, new_th, NULL, NULL );
    ClassifyType( object->lc, new_th, &new_type );
    if( new_type.kind != TK_STRUCT ) goto no_adjust;
    /*
     * At this point we know both the old type and the new type were
     * pointers to structures (classes) and that the pointer is non-null.
     * Now we have to find out if the new type is a pointer to the base
     * type of the old. If it is, we have to adjust the pointer by the
     * correct amount.
     */
     TypeThunkAdjust( obj_th, new_th, object->lc, &object->v.addr );
     /*
        NYI: C++ actually allows us to go the other way (convert a base
        type to a derived type) if the thunk adjust does not have to go
        through a virtual base type. If the above function doesn't return
        TRUE we can do the following:
        save = object->v.addr.mach.offset;
        if( CalcThunkAdjust( &object->v.addr, new_th, obj_th ) ) {
            diff = object->v.addr.mach.offset - save;
            object->v.addr.mach.offset -= 2*diff;
        }
        But it's such a horky thing, we'll wait for a customer to report a
        problem before putting it in.
    */
no_adjust:
    MoveTH( new, object );
}


/*
 * DoConvert - convert a stack entry to a given type
 */

void DoConvert( void )
{
    stack_entry *left;

    left = StkEntry( 1 );
    RValue( ExprSP );
    ConvertGiven( ExprSP, left );
    CombineEntries( ExprSP, left, ExprSP );
}


/*
 * DoLConvert - convert an lvalue stack entry to a given type
 */

void DoLConvert( void )
{
    stack_entry *left;
    type_info   new;

    left = StkEntry( 1 );
    LValue( ExprSP );
    if( ExprSP->flags & SF_LOCATION ) {
        ClassifyEntry( left, &new );
        if( ExprSP->v.loc.e[ExprSP->v.loc.num-1].type != LT_ADDR ) {
            if( new.size > ExprSP->info.size ) {
                Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) );
            }
        }
        ExprSP->info = new;
        MoveTH( left, ExprSP );
    } else {
        Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) );
    }
    CombineEntries( ExprSP, left, ExprSP );
}


/*
 * DoMakeComplex - combine the top 2 stack entries into a complex number
 */

void DoMakeComplex( void )
{
    stack_entry *left;
    xreal       zero;

    left = StkEntry( 1 );
    RValue( ExprSP );
    RValue( left );
    DToLD( 0.0, &zero );
    if( ExprSP->info.kind == TK_COMPLEX ) {
        if( LDCmp( &ExprSP->v.cmplx.im, &zero ) != 0 ) {
            Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
        }
    }
    if( left->info.kind == TK_COMPLEX ) {
        if( LDCmp( &left->v.cmplx.im, &zero ) != 0 ) {
            Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
        }
    }
    ConvertTo( ExprSP, TK_REAL, TM_NONE, sizeof( ExprSP->v.real ) );
    ConvertTo( left, TK_COMPLEX, TM_NONE, sizeof( left->v.cmplx ) );
    left->v.cmplx.im = ExprSP->v.real;
    CombineEntries( left, left, ExprSP );
}


/*
 * DoStringConcat -- Concaternate two character strings
 */

void DoStringConcat( void )
{
    stack_entry         *left, *rite;

    left = StkEntry( 1 );
    rite = ExprSP;
    RValue( left );
    RValue( rite );
    BinOp( left, rite );
    if( left->info.kind != TK_STRING ) {
        Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
    }
    CreateEntry();
    ExprSP->info.kind = TK_STRING;
    ExprSP->info.modifier = TM_NONE;
    ExprSP->info.size = left->info.size + rite->info.size;
    _ChkAlloc( ExprSP->v.string.allocated, ExprSP->info.size, LIT( ERR_NO_MEMORY_FOR_EXPR ) );
    LocationCreate( &ExprSP->v.string.loc, LT_INTERNAL, ExprSP->v.string.allocated );
    LocationAssign( &ExprSP->v.string.loc, &left->v.string.loc, left->info.size, FALSE );
    ExprSP->v.string.loc.e[0].u.p = left->info.size +
                (byte *)ExprSP->v.string.loc.e[0].u.p;
    LocationAssign( &ExprSP->v.string.loc, &rite->v.string.loc, rite->info.size, FALSE );
    ExprSP->v.string.loc.e[0].u.p = ExprSP->v.string.allocated;
    CombineEntries( ExprSP, left, rite );
}


/*
 * DoGivenField - do a structure field selection, given the field pointer
 */

void DoGivenField( sym_handle *member )
{
    LValue( ExprSP );
    if( !(ExprSP->flags & SF_LOCATION) ) {
        Error( ERR_NONE, LIT( ERR_NEED_ADDRESS ) );
    }
    CreateLC( ExprSP );
    ExprSP->lc->object = ExprSP->v.loc;
    ExprSP->lc->have_object = TRUE;
    ExprSP->lc->maybe_have_object = FALSE;
    ExprSymbol( ExprSP, member );
    SymResolve( ExprSP );
}

typedef struct {
    address             proc_addr;
    location_context    *lc;
    bool                found;
} find_context;

OVL_EXTERN CALL_CHAIN_RTN FindContext;
OVL_EXTERN bool FindContext( call_chain_entry *entry, void *_info )
{
    find_context *info = _info;
    unsigned    save_use;

    if( AddrComp( entry->start, info->proc_addr ) != 0 ) return( TRUE );
    save_use = info->lc->use;
    *info->lc = entry->lc;
    info->lc->use = save_use;
    info->found = TRUE;
    return( FALSE );
}

/*
 * DoField - do a structure field selection
 */

void DoField( void )
{
    stack_entry         *object;
    find_context        find;
    location_list       ll;
    DIPHDL( sym, sh );

    if( !(ExprSP->flags & SF_NAME) ) {
        Error( ERR_LOC, LIT( ERR_WANT_NAME ) );
    }
    object = StkEntry( 1 );
    LValue( object );
    if( object->info.kind == TK_FUNCTION ) {
        RValue( object );
        if( DeAliasAddrSym( NO_MOD, object->v.addr, sh ) == SR_NONE ) {
            Error( ERR_NONE, LIT( ERR_NO_ROUTINE ), object->v.addr );
        }
        if( SymLocation( sh, object->lc, &ll ) != DS_OK
          || ll.num != 1 || ll.e[0].type != LT_ADDR ) {
            Error( ERR_NONE, LIT( ERR_NO_ROUTINE ), object->v.addr );
        }
        find.proc_addr = ll.e[0].u.addr;
        find.found = FALSE;
        CreateLC( ExprSP );
        find.lc = ExprSP->lc;
        WalkCallChain( FindContext, &find );
        if( !find.found ) {
            ExprSP->lc->execution = find.proc_addr;
            ExprSP->lc->regs = NULL;
            ExprSP->lc->th = NULL;
            ExprSP->lc->have_frame = FALSE;
            ExprSP->lc->have_stack = FALSE;
            ExprSP->lc->have_object = FALSE;
            ExprSP->lc->maybe_have_frame = FALSE;
            ExprSP->lc->maybe_have_object = FALSE;
        }
        object->flags |= SF_IMP_ADDR;
    } else {
        MoveLC( object, ExprSP );
        CreateLC( ExprSP );
        if( !(object->flags & SF_LOCATION) ) {
            Error( ERR_NONE, LIT( ERR_NEED_ADDRESS ) );
        }
        ExprSP->lc->object = object->v.loc;
        ExprSP->lc->have_object = TRUE;
        ExprSP->lc->maybe_have_object = FALSE;
        ExprSP->lc->th = object->th;
    }
    NameResolve( ExprSP, TRUE );
    ExprSP->flags &= ~SF_IMP_ADDR;
    ExprSP->flags |= (object->flags & SF_IMP_ADDR);
    DeleteEntry( object );
}

/*
 * DoScope - do a scoped symbol lookup
 */

static char ScopeBuff[TXT_LEN]; // nyi - this should be dynamic

void DoScope( void )
{
    stack_entry         *scope;
    char                *p;
    char                buff[TXT_LEN];

    if( !(ExprSP->flags & SF_NAME) ) {
        Error( ERR_LOC, LIT( ERR_WANT_NAME ) );
    }
    scope = StkEntry( 1 );
    if( !(scope->flags & SF_NAME) ) {
        Error( ERR_LOC, LIT( ERR_WANT_NAME ) );
    }
    p = buff;
    if( scope->flags & SF_SCOPE ) {
        memcpy( p, scope->v.name.scope.start, scope->v.name.scope.len );
        p += scope->v.name.scope.len;
    }
    memcpy( p, scope->v.name.name.start, scope->v.name.name.len );
    p += scope->v.name.name.len;
    *p++ = '\0';
    memcpy( ScopeBuff, buff, p - buff );
    ExprSP->v.name.scope.start = ScopeBuff;
    ExprSP->v.name.scope.len = p - buff;
    ExprSP->flags |= SF_SCOPE;
    NameResolve( scope, FALSE );
    if( (scope->flags & SF_SYM) ) {
        CreateLC( ExprSP );
        ExprSP->lc->sh = scope->v.sh;
        NameResolve( ExprSP, FALSE );
    }
    DeleteEntry( scope );
}


/*
 * DoAssign - do an assignment operation
 */

void DoAssign( void )
{
    stack_entry         *dest;
    item_mach           item;
    location_list       ll;
    location_list       src;
    unsigned long       copy;
    unsigned long       pad;

    dest = StkEntry( 1 );
    ExprResolve( ExprSP );
    LValue( ExprSP );
    if( (dest->flags & SF_NAME) && !NameResolve( dest, FALSE ) ) {
        if( !CreateSym( &dest->v.name, &ExprSP->info ) ) {
            Error( ERR_NONE, LIT( ERR_SYM_NOT_CREATED ), dest->v.name.name.start,
                        dest->v.name.name.len );
        }
    }
    LValue( dest );
    if( dest->flags & SF_LOCATION ) {
        if( dest->info.kind == TK_STRING ) {
            if( ExprSP->info.kind != TK_STRING ) {
                Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) );
            }
            copy = ExprSP->info.size;
            if( copy > dest->info.size ) copy = dest->info.size;
            if( LocationAssign( &dest->v.loc, &ExprSP->v.loc, copy, FALSE ) != DS_OK ) {
                Error( ERR_NONE, LIT( ERR_NO_ACCESS ) );
            }
            if( dest->info.size > copy ) {
                /* have to pad */
                #define PADDING "                     "
                #define PAD_LEN (sizeof(PADDING)-1)
                ll = dest->v.loc;
                pad = dest->info.size - ExprSP->info.size;
                do {
                    LocationAdd( &ll, copy * 8 );
                    copy = pad;
                    if( copy > PAD_LEN ) copy = PAD_LEN;
                    LocationCreate( &src, LT_INTERNAL, PADDING );
                    if( LocationAssign( &ll, &src, copy, FALSE ) != DS_OK ) {
                        Error( ERR_NONE, LIT( ERR_NO_ACCESS ) );
                    }
                    pad -= copy;
                } while( pad != 0 );
            }
        } else {
            RValue( ExprSP );
            ConvertGiven( ExprSP, dest );
            ToItem( ExprSP, &item );
            LocationCreate( &src, LT_INTERNAL, &item );
            if( LocationAssign( &dest->v.loc, &src, dest->info.size, FALSE ) != DS_OK ) {
                Error( ERR_NONE, LIT( ERR_NO_ACCESS ) );
            }
        }

⌨️ 快捷键说明

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