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 + -
显示快捷键?