dbgexpr.c

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

C
806
字号
                ~0UL >> (sizeof(addr48_off)*8-(mti.b.bits-mti.a.seg.bits));
    }
}

/*
 * PushAddr -- push an address on the stack
 */

void PushAddr( address addr )
{
    CreateEntry();
    ExprSP->v.addr = addr;
    AddrFix( &ExprSP->v.addr );
    ExprSetAddrInfo( ExprSP, FALSE );
}

void PushLocation( location_list *ll, type_info *ti )
{
    CreateEntry();
    if( ti != NULL ) ExprSP->info = *ti;
    ExprSP->v.loc = *ll;
    ExprSP->flags |= SF_LOCATION;
}


/*
 * CombinEntries -- combine the SF_CONST bits of the left and optional right
 *            entries into the dest entry. Be careful of aliases.
 */

void CombineEntries( stack_entry *dest, stack_entry *l, stack_entry *r )
{
    stack_flags         f;
    stack_entry         *lc_src;

    f = l->flags;
    lc_src = l;
    if( r != NULL ) {
        f &= r->flags;
        if( r->lc != NULL ) lc_src = r;
    }
    MoveLC( lc_src, dest );
    dest->flags &= ~SF_CONST;
    dest->flags |= f & SF_CONST;
    if( l != dest ) DeleteEntry( l );
    if( r != dest ) DeleteEntry( r );
}


/*
 * MoveTH - move a type handle from one stack entry to another
 */

void MoveTH( stack_entry *old, stack_entry *new )
{
    if( old->th != NULL ) {
        SET_TH( new );
        HDLAssign( type, new->th, old->th );
    }
}


/*
 * PushType -- push a type on the stack
 */

void PushType( type_handle *th )
{
    CreateEntry();
    ExprSP->flags = SF_LOCATION;
    SET_TH( ExprSP );
    HDLAssign( type, ExprSP->th, th );
    ClassifyEntry( ExprSP, &ExprSP->info );
}

/*
 * PushInt - push an integer constant on the stack
 */

void PushInt( int val )
{
    CreateEntry();
    I32ToI64( val, &ExprSP->v.sint );
    ExprSP->info.kind = TK_INTEGER;
    ExprSP->info.modifier = TM_SIGNED;
    ExprSP->info.size = sizeof( ExprSP->v.sint );
}


static void PushBool( int val )
{
    CreateEntry();
    I32ToI64( val, &ExprSP->v.sint );
    ExprSP->info.kind = TK_BOOL;
    ExprSP->info.modifier = TM_NONE;
    ExprSP->info.size = 1;
}


/*
 * PushString - push the created string onto the stack
 */

void PushString( void )
{
    //NYI: This interface sucks. Hidden static variables. :-(
    CreateEntry();
    ExprSP->info.kind = TK_STRING;
    ExprSP->info.size = StringLength;
    ExprSP->v.string.allocated = StringStart;
    LocationCreate( &ExprSP->v.string.loc, LT_INTERNAL, StringStart );
    StringStart = NULL;
    StringLength = 0;
}


/*
 * PopEntry - pop a stack entry
 */

void PopEntry( void )
{
    if( ExprSP == &ExprBOS ) Error( ERR_LOC+ERR_INTERNAL, LIT( ERR_STK_UNDERFL ) );
    DeleteEntry( ExprSP );
}


/*
 * FStrCmp -- compare two strings, padding shorter one with spaces aka FORTRAN
 */
static int FStrCmp( char *str1, unsigned len1, char *str2, unsigned len2 )
{
    unsigned long   max, count;
    char            c1, c2;

    max = (len1 > len2)  ?  len1  :  len2;
    for( count = 0; count < max; ++count ) {
        c1 = (count < len1)  ?  *str1++  :  ' ';
        c2 = (count < len2)  ?  *str2++  :  ' ';
        if( c1 != c2 ) return(  c1 - c2 );
    }
    return( 0 );
}



/*
 * TstEQ - test for equality
 */


unsigned TstEQ( unsigned true_value )
{
    stack_entry *left, *rite;
    int temp;

    left = StkEntry( 1 );
    rite = ExprSP;
    BinOp( left, rite );
    switch( left->info.kind ) {
    case TK_BOOL:
    case TK_ENUM:
    case TK_CHAR:
    case TK_INTEGER:
        temp = (U64Cmp( &left->v.uint, &rite->v.uint ) == 0);
        break;
    case TK_ADDRESS:
    case TK_POINTER:
        temp = (AddrComp(left->v.addr,rite->v.addr) == 0);
        break;
    case TK_REAL:
        temp = (LDCmp( &left->v.real, &rite->v.real ) == 0);
        break;
    case TK_COMPLEX:
        temp = (LDCmp( &left->v.cmplx.re, &rite->v.cmplx.re ) == 0) &&
               (LDCmp( &left->v.cmplx.im, &rite->v.cmplx.im ) == 0);
        break;
    case TK_STRING:
        temp = FStrCmp( left->v.string.loc.e[0].u.p, left->info.size,
                        rite->v.string.loc.e[0].u.p, rite->info.size )
               == 0;
        break;
    default:
        Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
        break;
    }
    PushBool( temp ? true_value : 0 );
    CombineEntries( ExprSP, left, rite );
    return( I32FetchTrunc( ExprSP->v.sint ) );
}


/*
 * TstLT - test for less than
 */

unsigned TstLT( unsigned true_value )
{
    stack_entry *left, *rite;
    int temp;

    left = StkEntry( 1 );
    rite = ExprSP;
    BinOp( left, rite );
    switch( left->info.kind ) {
    case TK_BOOL:
    case TK_ENUM:
    case TK_CHAR:
    case TK_INTEGER:
        if( (left->info.modifier & TM_MOD_MASK) == TM_UNSIGNED ) {
            temp = ( U64Cmp( &left->v.uint, &rite->v.uint ) < 0 );
        } else {
            temp = ( I64Cmp( &left->v.sint, &rite->v.sint ) < 0 );
        }
        break;
    case TK_ADDRESS:
    case TK_POINTER:
        temp = (AddrComp(left->v.addr,rite->v.addr) < 0);
        break;
    case TK_REAL:
        temp = (LDCmp( &left->v.real, &rite->v.real ) < 0);
        break;
    case TK_STRING:
        temp = FStrCmp( left->v.string.loc.e[0].u.p, left->info.size,
                        rite->v.string.loc.e[0].u.p, rite->info.size )
               < 0;
        break;
    default:
        Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
        break;
    }
    PushBool( temp ? true_value : 0 );
    CombineEntries( ExprSP, left, rite );
    return( I32FetchTrunc( ExprSP->v.sint ) );
}


/*
 * TstTrue - set to FALSE or TRUE and return result
 */

unsigned TstTrue( unsigned true_value )
{
    PushInt( 0 );
    TstEQ( true_value );
    PushInt( true_value );
    DoXor();
    return( U32FetchTrunc( ExprSP->v.uint ) );
}


/*
 * TstExist - test if a variable exists or not
 */

unsigned TstExist( unsigned true_value )
{
    bool        tst;
    sym_list    *syms;

    if( ExprSP->flags & SF_NAME ) {
        syms = ExprGetSymList( ExprSP, FALSE );
        if( syms != NULL ) {
            PurgeSymHandles();
            tst = TRUE;
        } else {
            tst = FALSE;
        }
    } else {
        tst = TRUE;
    }
    PopEntry();
    PushBool( tst ? true_value : 0 );
    return( U32FetchTrunc( ExprSP->v.uint ) );
}


/*
 * MakeAddr - convert two stack entries into a segment/offset address
 */

void MakeAddr( void )
{
    stack_entry *left;
    addr48_off  offset;

    left = StkEntry( 1 );
    RValue( left );
    ConvertTo( left, TK_INTEGER, TM_UNSIGNED, sizeof( word ) );
    RValue( ExprSP );
    ConvertTo( ExprSP, TK_INTEGER, TM_UNSIGNED, sizeof( addr48_off ) );
    //NYI: 64 bit offsets
    offset = U32FetchTrunc( ExprSP->v.uint );
    /* NYI: address abstraction lost */
    ExprSP->v.addr = NilAddr;
    ExprSP->v.addr.mach.offset = offset;
    ExprSP->v.addr.mach.segment = U32FetchTrunc( left->v.uint );
    AddrFloat( &ExprSP->v.addr );
    ExprSetAddrInfo( ExprSP, TRUE );
    CombineEntries( ExprSP, left, ExprSP );
}



void FreePgmStack( bool freeall )
{
    unsigned    count, newlevel;
    addr_ptr    stk;

    count = ( freeall  ?  NestedCallLevel + 1  :  1 );
    newlevel = ( freeall  ?  0  :
                    ( (NestedCallLevel > 0)  ?  NestedCallLevel - 1  :  0 ) );
    MADRegSpecialGet( MSR_SP, &DbgRegs->mr, &stk );
    for( ; count > 0; --count ) {
        stk.offset += PgmStackUsage[ NestedCallLevel ];
        PgmStackUsage[ NestedCallLevel ] = 0;
        --NestedCallLevel;
    }
    MADRegSpecialSet( MSR_SP, &DbgRegs->mr, &stk );
    NestedCallLevel = newlevel;
}



/*
 * ExprPurge - clean up expression stack
 */

void ExprPurge( void )
{
    stack_entry *stk_ptr, *next_ptr;

    stk_ptr = ExprSP;
    while( stk_ptr->dn != NULL ) {
        stk_ptr = stk_ptr->dn;
    }
    while( !(stk_ptr->flags & SF_END_PURGE) ) {
        next_ptr = stk_ptr->up;
        FreeEntry( stk_ptr );
        stk_ptr = next_ptr;
    }
    stk_ptr->dn = NULL;
    ExprSP = stk_ptr;
    if( StringStart != NULL ) _Free( StringStart );
    FreePgmStack( TRUE );
}

void MarkArrayOrder( bool column_major )
{
    if( column_major ) {
        _SwitchOn( SW_COL_MAJ_ARRAYS );
    } else {
        _SwitchOff( SW_COL_MAJ_ARRAYS );
    }
}

void StartSubscript( void )
{
    LValue( ExprSP );
}

void AddSubscript( void )
{
    stack_entry *array;
    array_info  ai;
    type_info   ti;
    stack_flags save_imp;
    DIPHDL( type, th );

    array = StkEntry( 1 );
    save_imp = array->flags & SF_IMP_ADDR;
    switch( array->info.kind ) {
    case TK_ARRAY:
        TypeArrayInfo( array->th, array->lc, &ai, th );
        PushType( th );
        SwapStack( 1 );
        DoConvert();
        break;
    case TK_POINTER:
        save_imp = 0;
        TypeBase( array->th, th, NULL, NULL );
        TypeInfo( th, array->lc, &ti );
        ai.stride = ti.size;
        ai.low_bound = 0;
        RValue( ExprSP );
        ConvertTo( ExprSP, TK_INTEGER, TM_SIGNED, sizeof( ExprSP->v.sint ) );
        break;
    default:
        Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
    }
    PushNum( ai.low_bound );
    DoMinus();
    PushNum( ai.stride );
    DoMul();
    DoPlus();
    DoPoints( TK_NONE );
    ExprSP->flags |= save_imp;
}

void EndSubscript( void )
{
}

⌨️ 快捷键说明

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