dbgexpr2.c

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

C
479
字号
/****************************************************************************
*
*                            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:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include "dbgdefn.h"
#include "dbglit.h"
#include "dbgstk.h"
#include "dbgerr.h"
#include "dbgmem.h"
#include "dbgtoggl.h"
#include "dbgitem.h"
#include "dbginfo.h"
#include "i64.h"


extern bool             ForceSym2Num(char *,unsigned int , unsigned_64 *);
extern sym_list         *Disambiguate( sym_list *, location_context * );
extern void             DoAPoints( stack_entry *, type_kind );
extern void             ExprSetAddrInfo( stack_entry *, bool );
extern void             FromItem( item_mach *, stack_entry * );
extern void             FreeSymHandle( sym_list * );
extern sym_list         *LookupSymList( symbol_source, void *, bool, lookup_item * );
extern dip_status       LocationAssign( location_list *, location_list *, unsigned long, bool );
extern void             LocationCreate( location_list *, location_type, void * );
extern void             CreateLC( stack_entry * );
extern address          DefAddrSpaceForAddr( address );
extern address          DefAddrSpaceForMod( mod_handle );
extern unsigned         DefaultSize( default_kind );
extern void             GetMADTypeDefaultAt( address, mad_type_kind, mad_type_info * );

extern unsigned         ExprAddrDepth;
extern address          NilAddr;

static bool DefaultTypeInfo( type_info *info )
{
    bool        real_type;

    real_type = TRUE;
    switch( info->kind ) {
    case TK_DATA:
    case TK_NONE:
        real_type = FALSE;
        info->kind = TK_INTEGER;
        /* fall through */
    case TK_INTEGER:
        if( info->modifier == TM_NONE ) {
            info->modifier = TM_UNSIGNED;
        }
        if( info->size == 0 ) {
            info->size = DefaultSize( DK_INT );
        }
        break;
    case TK_CODE:
    case TK_ADDRESS:
        real_type = FALSE;
        /* fall through */
    case TK_POINTER:
        if( info->modifier == TM_NONE ) {
            info->modifier = TM_FAR;
        }
        if( info->size == 0 ) {
            info->size = DefaultSize( DK_DATA_PTR );
            switch( info->modifier ) {
            case TM_FAR:
            case TM_HUGE:
                info->size += sizeof( addr_seg );
                break;
            }
        }
        break;
    case TK_STRING:
        if( info->modifier == TM_NONE ) {
            info->modifier = TM_ASCII;
        }
        break;
    }
    return( real_type );
}

bool ClassifyType( location_context *lc, type_handle *th, type_info *info )
{
    TypeInfo( th, lc, info );
    return( DefaultTypeInfo( info ) );
}

void ClassifyEntry( stack_entry *stk, type_info *info )
{
    if( stk->th == NULL ) {
        *info = stk->info;
        DefaultTypeInfo( info );
    } else if( !ClassifyType( stk->lc, stk->th, info ) ) {
        stk->th = NULL;
    }
}

static void GetTrueEntry( stack_entry *entry )
{
    addr_off            near_off;
    type_modifier       mod;

    for( ;; ) {
        mod = entry->info.modifier;
        if( !(mod & TM_FLAG_DEREF) ) break;
        DoAPoints( entry, TK_NONE );
        if( entry->info.kind == TK_VOID ) Error( ERR_NONE, LIT( ERR_VOID_BASE ) );
        switch( mod & TM_MOD_MASK ) {
        case TM_NEAR:
            if( entry->info.kind == TK_FUNCTION ) {
                near_off = entry->v.loc.e[0].u.addr.mach.offset;
                entry->v.loc.e[0].u.addr = Context.execution;
                entry->v.loc.e[0].u.addr.mach.offset = near_off;
            }
            break;
        }
    }
}

static void LocationToAddr( stack_entry *entry )
{
    entry->v.addr = entry->v.loc.e[0].u.addr;
    entry->flags &= ~SF_LOCATION;
    ExprSetAddrInfo( entry, FALSE );
}

sym_list *ExprGetSymList( stack_entry *entry, bool source_only )
{
    sym_list            *syms;
    void                *d;
    symbol_source       ss;

    CreateLC( entry );
    if( entry->lc->sh != NULL ) {
        ss = SS_SCOPESYM;
        d = entry->lc->sh;
        entry->lc->sh = NULL;
    } else if( entry->lc->th != NULL ) {
        ss = SS_TYPE;
        d = entry->lc->th;
        entry->lc->th = NULL;
        source_only = TRUE;
    } else {
        ss = SS_SCOPED;
        d = &entry->lc->execution;
    }
    syms = LookupSymList( ss, d, source_only, &entry->v.name );
    return( syms );
}

void ExprSymbol( stack_entry *entry, sym_handle *sh )
{
    SET_TH( entry );
    if( SymType( sh, entry->th ) != DS_OK ) entry->th = NULL;
    ClassifyEntry( entry, &entry->info );
    SET_SH( entry );
    HDLAssign( sym, entry->v.sh, sh );
    entry->flags |= SF_SYM;
}


bool NameResolve( stack_entry *entry, bool source_only )
{
    sym_list    *syms;

    if( entry->flags & SF_NAME ) {
        syms = ExprGetSymList( entry, source_only );
        if( syms == NULL ) return( FALSE );
        if( syms->next != NULL ) {
            syms = Disambiguate( syms, entry->lc );
        }
        entry->flags &= ~SF_NAME;
        ExprSymbol( entry, SL2SH( syms ) );
        FreeSymHandle( syms );
    }
    return( TRUE );
}


void SymResolve( stack_entry *entry )
{
    item_mach   tmp;
    sym_handle  *sh;

    if( entry->flags & SF_SYM ) {
        sh = entry->v.sh;
        entry->flags &= ~SF_FORM_MASK;
        if( SymLocation( sh, entry->lc, &entry->v.loc ) == DS_OK ) {
            entry->flags |= SF_LOCATION;
            if( entry->v.loc.e[0].type == LT_ADDR ) {
                entry->flags |= SF_IMP_ADDR;
            }
            GetTrueEntry( entry );
        } else {
            if( entry->info.kind == TK_STRING ) {
                _ChkAlloc( entry->v.string.allocated, entry->info.size,
                            LIT( ERR_NO_MEMORY_FOR_EXPR ) );
                LocationCreate( &entry->v.string.loc, LT_INTERNAL,
                            entry->v.string.allocated );
                if( SymValue( sh, entry->lc, entry->v.string.allocated ) != DS_OK ) {
                    Error( ERR_NONE, LIT( ERR_NO_ACCESS ) );
                }
            } else {
                if( SymValue( sh, entry->lc, &tmp ) != DS_OK ) {
                    Error( ERR_NONE, LIT( ERR_NO_ACCESS ) );
                }
                FromItem( &tmp, entry );
            }
        }
        switch( entry->info.kind ) {
        case TK_CODE:
        case TK_ADDRESS:
            if( !(entry->flags & SF_LOCATION) ) {
                ExprSetAddrInfo( entry, FALSE );

⌨️ 快捷键说明

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