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