dbgexpr3.c

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

C
884
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Debugger expression handling, Part III (Type conversion).
*
****************************************************************************/


#include <string.h>
#include "dbgdefn.h"
#include "dbgstk.h"
#include "dbgerr.h"
#include "dbgtoggl.h"
#include "dbgitem.h"
#include "dbgmem.h"
#include "dbglit.h"
#include "ldsupp.h"
#include "mad.h"
#include "i64.h"

extern void             RValue(stack_entry *);
extern void             MoveTH( stack_entry *, stack_entry * );
extern bool             AllocatedString( stack_entry * );
extern void             LocationCreate( location_list *, location_type, void * );
extern address          DefAddrSpaceForAddr( address );
extern unsigned         DefaultSize( default_kind );

extern address          NilAddr;
extern stack_entry      *ExprSP;

typedef enum {
    I1,
    U1,
    I2,
    U2,
    I4,
    U4,
    I8,
    U8,
    F4,
    F8,
    F10,
    C8,
    C16,
    C20,
    STR,
    NP2,
    NP4,
    FP4,
    FP6,
    HP4,
    ERR,
    NUM_CLASSES
} conv_class;


conv_class ConvIdx( type_info *info )
{
    unsigned    size;

    if( info->kind == TK_STRING ) return( STR );
    if( info->size > sizeof( item_mach ) ) return( ERR );
    size = info->size;
    switch( info->kind ) {
    case TK_BOOL:
    case TK_ENUM:
    case TK_CHAR:
    case TK_INTEGER:
        if( (info->modifier & TM_MOD_MASK) == TM_SIGNED ) {
            switch( size ) {
            case 1:
                return( I1 );
            case 2:
                return( I2 );
            case 4:
                return( I4 );
            case 8:
                return( I8 );
            }
        } else {
            switch( size ) {
            case 1:
                return( U1 );
            case 2:
                return( U2 );
            case 4:
                return( U4 );
            case 8:
                return( U8 );
            }
        }
        break;
    case TK_REAL:
        switch( size ) {
        case 4:
            return( F4 );
        case 8:
            return( F8 );
        case 10:
            return( F10 );
        }
        break;
    case TK_COMPLEX:
        switch( size ) {
        case 8:
            return( C8 );
        case 16:
            return( C16 );
        case 20:
            return( C20 );
        }
        break;
    case TK_POINTER:
    case TK_ADDRESS:
        switch( info->modifier & TM_MOD_MASK ) {
        case TM_NEAR:
            switch( size ) {
            case 2:
                return( NP2 );
            case 4:
                return( NP4 );
            }
            break;
        case TM_FAR:
            switch( size ) {
            case 4:
                return( FP4 );
            case 6:
                return( FP6 );
            }
            break;
        case TM_HUGE:
            switch( size ) {
            case 4:
                return( HP4 );
            }
        }
        break;
    }
    return( ERR );
}

void FromItem( item_mach *tmp, stack_entry *entry )
{
    unsigned            size;
    mad_type_info       src_type;
    mad_type_info       dst_type;
    type_info           ti;

    if( entry->info.size > sizeof( *tmp ) ) {
        Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) );
    }
    size = entry->info.size;
    switch( entry->info.kind ) {
    case TK_BOOL:
    case TK_ENUM:
    case TK_CHAR:
    case TK_INTEGER:
        MADTypeInfo( MADTypeForDIPType( &entry->info ), &src_type );
        if( (entry->info.modifier & TM_MOD_MASK) == TM_SIGNED ) {
            MADTypeInfoForHost( MTK_INTEGER, -sizeof( entry->v.sint ), &dst_type );
        } else {
            MADTypeInfoForHost( MTK_INTEGER, sizeof( entry->v.sint ), &dst_type );
        }
        MADTypeConvert( &src_type, tmp, &dst_type, &entry->v.uint, 0 );
        return;
    case TK_REAL:
        MADTypeInfo( MADTypeForDIPType( &entry->info ), &src_type );
        MADTypeInfoForHost( MTK_FLOAT, sizeof( entry->v.real ), &dst_type );
        MADTypeConvert( &src_type, tmp, &dst_type, &entry->v.real, 0 );
        return;
    case TK_COMPLEX:
        ti.kind = TK_REAL;
        ti.size = entry->info.size / 2;
        ti.modifier = entry->info.modifier;
        MADTypeInfo( MADTypeForDIPType( &ti ), &src_type );
        MADTypeInfoForHost( MTK_FLOAT, sizeof( entry->v.cmplx.re ), &dst_type );
        MADTypeConvert( &src_type, tmp, &dst_type, &entry->v.cmplx.re, 0 );
        MADTypeConvert( &src_type, (unsigned_8 *)tmp + ti.size, &dst_type, &entry->v.cmplx.im, 0 );
        return;
    case TK_POINTER:
    case TK_ADDRESS:
        //NYI: use MAD conversion routines....
        switch( entry->info.modifier & TM_MOD_MASK ) {
        case TM_NEAR:
            switch( size ) {
            case 2:
                entry->v.addr.mach.offset = tmp->so;
                return;
            case 8:
                //NYI: 64 bit offsets
                entry->info.size = 4;
            case 4:
                entry->v.addr.mach.offset = tmp->lo;
                return;
            }
            break;
        case TM_FAR:
        case TM_HUGE:
            switch( size ) {
            case 4:
                entry->v.addr.sect_id = 0;
                entry->v.addr.indirect = FALSE;
                ConvAddr32ToAddr48( tmp->sa, entry->v.addr.mach );
                return;
            case 6:
                entry->v.addr.sect_id = 0;
                entry->v.addr.indirect = FALSE;
                entry->v.addr.mach = tmp->la;
                return;
            case sizeof( address ):
                /* it's an internal address symbol */
                entry->v.addr = tmp->xa;
                entry->info.size = 6;
                return;
            }
            break;
        }
        break;
    }
    Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) );
}


void ToItem( stack_entry *entry, item_mach *tmp )
{
    unsigned            size;
    mad_type_info       src_type;
    mad_type_info       dst_type;

    if( entry->info.size > sizeof( *tmp ) ) {
        Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) );
    }
    //NYI: use MAD routines for all conversions
    size = entry->info.size;
    switch( entry->info.kind ) {
    case TK_BOOL:
    case TK_ENUM:
    case TK_CHAR:
    case TK_INTEGER:
        MADTypeInfo( MADTypeForDIPType( &entry->info ), &dst_type );
        if( (entry->info.modifier & TM_MOD_MASK) == TM_SIGNED ) {
            MADTypeInfoForHost( MTK_INTEGER, -sizeof( entry->v.sint ), &src_type );
        } else {
            MADTypeInfoForHost( MTK_INTEGER, sizeof( entry->v.sint ), &src_type );
        }
        MADTypeConvert( &src_type, &entry->v.uint, &dst_type, tmp, 0 );
        return;
    case TK_REAL:
        MADTypeInfo( MADTypeForDIPType( &entry->info ), &dst_type );
        MADTypeInfoForHost( MTK_FLOAT, sizeof( entry->v.real ), &src_type );
        MADTypeConvert( &src_type, &entry->v.real, &dst_type, tmp, 0 );
        return;
    case TK_COMPLEX:
        switch( size ) {
        case 8:
            tmp->sc.re = LDToD( &entry->v.cmplx.re );
            tmp->sc.im = LDToD( &entry->v.cmplx.im );
            return;
        case 16:
            tmp->lc.re = LDToD( &entry->v.cmplx.re );
            tmp->lc.im = LDToD( &entry->v.cmplx.im );
            return;
        case 20:
            tmp->xc = entry->v.cmplx;
            return;
        }
        break;
    case TK_POINTER:
    case TK_ADDRESS:
        switch( entry->info.modifier & TM_MOD_MASK ) {
        case TM_NEAR:
            switch( size ) {
            case 2:
                tmp->so = entry->v.addr.mach.offset;
                return;
            case 4:
                tmp->lo = entry->v.addr.mach.offset;
                return;
            case 8:
                tmp->qo.u._32[I64LO32] = entry->v.addr.mach.offset;
                tmp->qo.u._32[I64HI32] = 0;
            }
            break;
        case TM_FAR:
        case TM_HUGE:
            switch( size ) {
            case 4:
                ConvAddr48ToAddr32( entry->v.addr.mach, tmp->sa );
                return;
            case 6:
                tmp->la = entry->v.addr.mach;
                return;
            }
            break;
        }
        break;
    }
    Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) );
}


OVL_EXTERN bool ConvU8( stack_entry *entry, conv_class from )
{
    unsigned_64  tmp;

    switch( from ) {
    case U1:
    case U2:
    case U4:
    case U8:
        tmp = entry->v.uint;
        break;
    case I1:
    case I2:
    case I4:
    case I8:
        tmp = entry->v.sint;
        break;
    case F4:
    case F8:
    case F10:
        //NYI: 64-bit support
        I32ToI64( LDToD( &entry->v.real ), &tmp );
        break;
    case C8:
    case C16:
    case C20:
        I32ToI64( LDToD( &entry->v.cmplx.re ), &tmp );
        break;
    case NP2:
    case NP4:
        //NYI: 64-bit offsets
        U32ToU64( entry->v.addr.mach.offset, &tmp );
        break;
    case FP4:
    case HP4:
        U32ToU64( entry->v.addr.mach.offset +
                ((long) entry->v.addr.mach.segment << 16), &tmp );
        break;
    case FP6:
        U32ToU64( entry->v.addr.mach.offset, &tmp );
        break;
    default:
        return( FALSE );
    }
    entry->v.uint = tmp;
    return( TRUE );
}

OVL_EXTERN bool ConvU1( stack_entry *entry, conv_class from )
{
    if( !ConvU8( entry, from ) ) return( FALSE );
    U32ToU64( (unsigned_8)U32FetchTrunc( entry->v.uint ), &entry->v.uint );
    return( TRUE );
}

OVL_EXTERN bool ConvU2( stack_entry *entry, conv_class from )
{
    if( !ConvU8( entry, from ) ) return( FALSE );
    U32ToU64( (unsigned_16)U32FetchTrunc( entry->v.uint ), &entry->v.uint );
    return( TRUE );
}

OVL_EXTERN bool ConvU4( stack_entry *entry, conv_class from )
{
    if( !ConvU8( entry, from ) ) return( FALSE );
    U32ToU64( (unsigned_32)U32FetchTrunc( entry->v.uint ), &entry->v.uint );
    return( TRUE );
}

OVL_EXTERN bool ConvI1( stack_entry *entry, conv_class from )
{
    if( !ConvU8( entry, from ) ) return( FALSE );
    I32ToI64( (signed_8)U32FetchTrunc( entry->v.uint ), &entry->v.sint );
    return( TRUE );
}

OVL_EXTERN bool ConvI2( stack_entry *entry, conv_class from )
{
    if( !ConvU8( entry, from ) ) return( FALSE );
    I32ToI64( (signed_16)U32FetchTrunc( entry->v.uint ), &entry->v.sint );
    return( TRUE );
}

OVL_EXTERN bool ConvI4( stack_entry *entry, conv_class from )
{
    if( !ConvU8( entry, from ) ) return( FALSE );
    I32ToI64( (signed_32)U32FetchTrunc( entry->v.uint ), &entry->v.sint );
    return( TRUE );
}

OVL_EXTERN bool ConvI8( stack_entry *entry, conv_class from )
{
    return( ConvU8( entry, from ) );
}

OVL_EXTERN bool ConvR10( stack_entry *entry, conv_class from )
{
    xreal       tmp;

    switch( from ) {
    case U1:
    case U2:
    case U4:
    case U8:
        //NYI: 64 bit support
        DToLD( U32FetchTrunc( entry->v.uint ), &tmp );
        break;
    case I1:
    case I2:
    case I4:
    case I8:
        //NYI: 64 bit support
        DToLD( I32FetchTrunc( entry->v.sint ), &tmp );
        break;
    case F4:
    case F8:
    case F10:

⌨️ 快捷键说明

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