wattype.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,874 行 · 第 1/4 页
C
1,874 行
}
dip_status DIPENTRY DIPImpTypeBase(imp_image_handle *ii, imp_type_handle *it,
imp_type_handle *base,
location_context *lc, location_list *ll )
{
unsigned index;
byte *p;
dip_status ret;
typeinfo typeld;
PushLoad( &typeld );
*base = *it;
ret = LoadType( ii, it->im, it->t.entry );
if( ret != DS_OK ) {
PopLoad();
return( ret );
}
p = it->t.offset + Type->start;
if( base->f.s.col_major ) {
if( base->f.s.array_ss > 1 ) {
base->f.s.array_ss--;
} else {
base->f.s.col_major = 0;
do {
p = BaseTypePtr( p );
GetIndex( p, &index );
FindRawTypeHandle( ii, base->im, index, base );
p = base->t.offset + Type->start;
} while( (p[1] & CLASS_MASK) == ARRAY_TYPE );
}
PopLoad();
} else if( p[1] == ENUM_TYPE+ENUM_LIST ) {
base->t.offset = *(unsigned_8 *)(p+4);
base->f.s.sclr = 1;
PopLoad();
} else {
p = BaseTypePtr( p );
if( p == NULL ) return( DS_FAIL );
GetIndex( p, &index );
PopLoad();
FindTypeHandle( ii, it->im, index, base );
}
return( DS_OK );
}
dip_status DIPENTRY DIPImpTypeArrayInfo(imp_image_handle *ii, imp_type_handle *it,
location_context *lc, array_info *ai, imp_type_handle *index )
{
byte *p;
unsigned index_idx;
unsigned scalar;
imp_type_handle tmp;
address addr;
byte is_32;
long hi;
type_info info;
unsigned count;
dip_status ret;
typeinfo typeld;
if( it->f.s.col_major ) {
tmp = *it;
tmp.f.s.col_major = 0;
for( count = tmp.f.s.array_ss-1; count != 0; --count ) {
ImpInterface.type_base( ii, &tmp, &tmp, NULL, NULL );
}
ImpInterface.type_array_info( ii, &tmp, lc, ai, index );
ai->num_dims = tmp.f.s.array_ss - ai->num_dims + 1;
ai->column_major = 1;
return( DS_OK );
}
PushLoad( &typeld );
ret = LoadType( ii, it->im, it->t.entry );
if( ret != DS_OK ) {
PopLoad();
return( ret );
}
is_32 = 1;
index_idx = 0;
scalar = SCLR_UNSIGNED | 3;
p = it->t.offset + Type->start;
switch( p[1] ) {
case ARRAY_TYPE+ARRAY_BYTE_INDEX:
ai->num_elts = *(unsigned_8 *)(p+2) + 1;
ai->low_bound = 0;
break;
case ARRAY_TYPE+ARRAY_WORD_INDEX:
ai->num_elts = *(unsigned_16 *)(p+2) + 1;
ai->low_bound = 0;
break;
case ARRAY_TYPE+ARRAY_LONG_INDEX:
ai->num_elts = *(unsigned_32 *)(p+2) + 1;
ai->low_bound = 0;
break;
case ARRAY_TYPE+ARRAY_TYPE_INDEX:
GetIndex( p + 2, &index_idx );
ret = FindTypeHandle( ii, it->im, index_idx, &tmp );
if( ret != DS_OK ) {
PopLoad();
return( ret );
}
ret = LoadType( ii, tmp.im, tmp.t.entry );
if( ret != DS_OK ) {
PopLoad();
return( ret );
}
p = tmp.t.offset + Type->start;
switch( p[1] ) {
case SUBRANGE_TYPE+SUBRANGE_BYTE:
ai->low_bound = *(signed_8 *)(p+2);
hi = *(signed_8 *)(p+3);
break;
case SUBRANGE_TYPE+SUBRANGE_WORD:
ai->low_bound = *(signed_16 *)(p+2);
hi = *(signed_16 *)(p+4);
break;
case SUBRANGE_TYPE+SUBRANGE_LONG:
ai->low_bound = *(signed_32 *)(p+2);
hi = *(signed_32 *)(p+6);
break;
}
ai->num_elts = (hi - ai->low_bound) + 1;
break;
case ARRAY_TYPE+ARRAY_DESC_INDEX:
is_32 = 0;
/* fall through */
case ARRAY_TYPE+ARRAY_DESC386_INDEX:
GetAddress( ii, p + 4, &addr, is_32 );
scalar = *(unsigned_8 *)(p+2);
ai->low_bound = GetScalar( addr, scalar );
addr.mach.offset += (scalar & SCLR_LEN_MASK) + 1;
ai->num_elts = GetScalar( addr, *(unsigned_8 *)(p+3) );
break;
}
PopLoad();
ImpInterface.type_base( ii, it, &tmp, NULL, NULL );
ai->num_dims = 1;
ret = GetTypeInfo( ii, &tmp, lc, &info, &ai->num_dims );
if( ret != DS_OK ) return( ret );
ai->stride = info.size;
ai->column_major = 0;
if( index != NULL ) {
if( index_idx != 0 ) {
FindTypeHandle( ii, it->im, index_idx, index );
} else {
index->im = it->im;
index->f.all = 0;
index->f.s.sclr = 1;
index->t.offset = scalar;
}
}
return( DS_OK );
}
dip_status DIPENTRY DIPImpTypeProcInfo(imp_image_handle *ii, imp_type_handle *it,
imp_type_handle *parm, unsigned num )
{
byte *p;
byte *end;
unsigned index;
dip_status ret;
typeinfo typeld;
PushLoad( &typeld );
ret = LoadType( ii, it->im, it->t.entry );
if( ret != DS_OK ) {
PopLoad();
return( ret );
}
p = Type->start + it->t.offset;
end = NEXT_TYPE( p );
p = GetIndex( p + 2, &index );
if( num == 0 ) {
/* nothing to do */
} else if( num <= *p ) {
++p;
for( ;; ) {
if( p == end ) {
/* handle EXT_PARMS record */
p += 2;
end = NEXT_TYPE( p );
}
p = GetIndex( p, &index );
--num;
if( num == 0 ) break;
}
} else {
PopLoad();
return( DS_NO_PARM );
}
PopLoad();
return( FindTypeHandle( ii, it->im, index, parm ) );
}
dip_status DIPENTRY DIPImpTypePtrAddrSpace( imp_image_handle *ii,
imp_type_handle *it, location_context *lc, address *addr )
{
byte *p;
byte *end;
dip_status ret;
location_list ll;
unsigned dummy;
typeinfo typeld;
PushLoad( &typeld );
ret = LoadType( ii, it->im, it->t.entry );
if( ret != DS_OK ) {
PopLoad();
return( ret );
}
p = Type->start + it->t.offset;
end = NEXT_TYPE( p );
p = GetIndex( p + 2, &dummy );
if( p >= end ) {
PopLoad();
return( DS_FAIL );
}
LocationCreate( &ll, LT_ADDR, addr );
PushBaseLocation( &ll );
ret = EvalLocation( ii, lc, p, &ll );
PopLoad();
if( ret != DS_OK ) return( ret );
if( ll.num != 1 || ll.e[0].type != LT_ADDR ) {
return( DS_ERR|DS_BAD_LOCATION );
}
*addr = ll.e[0].u.addr;
return( DS_OK );
}
unsigned SymHdl2CstName( imp_image_handle *ii, imp_sym_handle *is,
char *name, unsigned max )
{
byte *p;
unsigned len;
typeinfo typeld;
PushLoad( &typeld );
if( LoadType( ii, is->im, is->u.typ.t.entry ) != DS_OK ) {
PopLoad();
return( 0 );
}
p = Type->start + is->u.typ.t.offset;
len = *p - is->name_off;
if( max > 0 ) {
--max;
if( max > len ) max = len;
memcpy( name, p + is->name_off, max );
name[max] = '\0';
}
PopLoad();
return( len );
}
unsigned SymHdl2TypName( imp_image_handle *ii, imp_sym_handle *is,
char *name, unsigned max )
{
return( SymHdl2CstName( ii, is, name, max ) );
}
unsigned SymHdl2MbrName( imp_image_handle *ii, imp_sym_handle *is,
char *name, unsigned max )
{
return( SymHdl2CstName( ii, is, name, max ) );
}
dip_status SymHdl2CstValue( imp_image_handle *ii, imp_sym_handle *is, void *d )
{
byte *p;
byte *e;
unsigned_64 val;
dip_status ret;
typeinfo typeld;
PushLoad( &typeld );
ret = LoadType( ii, is->im, is->u.typ.t.entry );
if( ret != DS_OK ) {
PopLoad();
return( ret );
}
memset( &val, 0, sizeof( val ) );
p = Type->start + is->u.typ.t.offset;
switch( p[1] ) {
case ENUM_TYPE+ENUM_CONST_BYTE:
val.u._32[0] = *(signed_8 *)(p+2);
break;
case ENUM_TYPE+ENUM_CONST_WORD:
val.u._32[0] = *(signed_16 *)(p+2);
break;
case ENUM_TYPE+ENUM_CONST_LONG:
val.u._32[0] = *(signed_32 *)(p+2);
break;
case ENUM_TYPE+ENUM_CONST_I64:
memcpy( &val, p + 2, sizeof( val ) );
break;
}
e = Type->start + is->u.typ.h.offset;
memcpy( d, &val, (*(e+4) & SCLR_LEN_MASK) + 1 );
PopLoad();
return( DS_OK );
}
dip_status SymHdl2CstType( imp_image_handle *ii, imp_sym_handle *is,
imp_type_handle *it )
{
ii = ii;
it->im = is->im;
it->t = is->u.typ.h;
it->f.all = 0;
return( DS_OK );
}
dip_status SymHdl2TypType( imp_image_handle *ii, imp_sym_handle *is,
imp_type_handle *it )
{
ii = ii;
it->im = is->im;
it->t = is->u.typ.t;
it->f.all = 0;
return( DS_OK );
}
dip_status SymHdl2MbrType( imp_image_handle *ii, imp_sym_handle *is,
imp_type_handle *it )
{
byte *p;
unsigned index;
dip_status ret;
typeinfo typeld;
PushLoad( &typeld );
ret = LoadType( ii, is->im, is->u.typ.t.entry );
if( ret != DS_OK ) {
PopLoad();
return( ret );
}
p = Type->start + is->u.typ.t.offset;
p = BaseTypePtr( p );
GetIndex( p, &index );
PopLoad();
return( FindTypeHandle( ii, is->im, index, it ) );
}
struct pending_entry {
struct pending_entry *prev;
unsigned short off;
};
struct anc_graph {
struct anc_graph *prev;
union {
struct pending_entry *todo;
struct {
unsigned short off;
unsigned short count;
} s;
} u;
unsigned short entry;
};
dip_status SymHdl2MbrLoc( imp_image_handle *ii, imp_sym_handle *is,
location_context *lc, location_list *ll )
{
byte *p;
unsigned count;
struct anc_graph *pending, *new, *tmp;
imp_type_handle new_it;
unsigned index;
dip_status ok;
location_list adj;
addr_off offset;
unsigned bit_start;
unsigned bit_len;
location_info info;
typeinfo typeld;
PushLoad( &typeld );
ok = LoadType( ii, is->im, is->u.typ.t.entry );
if( ok != DS_OK ) {
PopLoad();
return( ok );
}
p = Type->start + is->u.typ.t.offset;
switch( p[1] ) {
case STRUCT_TYPE+ST_FIELD_LOC:
case STRUCT_TYPE+ST_BIT_LOC:
info = InfoLocation( p + 3 );
break;
default:
info = NEED_BASE;
break;
}
if( info & (NEED_BASE|EMPTY_EXPR) ) {
ok = LoadType( ii, is->im, is->u.typ.h.entry );
if( ok != DS_OK ) {
PopLoad();
return( ok );
}
p = Type->start + is->u.typ.h.offset;
pending = NULL;
count = *(unsigned_16 *)(p+2);
for( ;; ) {
if( count == 0 ) {
if( pending == NULL ) return( DS_FAIL );
ok = LoadType( ii, is->im, pending->entry );
if( ok != DS_OK ) {
PopLoad();
return( ok );
}
count = pending->u.s.count;
p = Type->start + pending->u.s.off;
pending = pending->prev;
}
--count;
p = NEXT_TYPE( p );
if( p[1] == STRUCT_TYPE+ST_INHERIT ) {
new = __alloca( sizeof( *new ) );
new->entry = Type->entry;
new->u.s.off = p - Type->start;
new->u.s.count = count;
new->prev = pending;
pending = new;
p = SkipLocation( p + 2 );
GetIndex( p, &index );
ok = DoFindTypeHandle( ii, is->im, index, &new_it );
if( ok != DS_OK ) {
PopLoad();
return( ok );
}
p = Type->start + new_it.t.offset;
count = *(unsigned_16 *)(p+2);
} else {
if( is->u.typ.t.entry == Type->entry
&& is->u.typ.t.offset == (p - Type->start) ) break;
}
}
FreeLoad();
/* reverse the inheritance list */
new = NULL;
while( pending != NULL ) {
tmp = pending;
pending = tmp->prev;
tmp->prev = new;
new = tmp;
}
/* do the adjustors at each level */
ok = DCItemLocation( lc, CI_OBJECT, ll );
if( ok != DS_OK ) {
PopLoad();
DCStatus( ok );
return( ok );
}
while( new != NULL ) {
ok = LoadType( ii, is->im, new->entry );
if( ok != DS_OK ) {
PopLoad();
return( ok );
}
PushBaseLocation( ll );
p = new->u.s.off + Type->start;
ok = EvalLocation( ii, lc, p + 2, &adj );
if( ok != DS_OK ) {
PopLoad();
return( ok );
}
if( adj.num != 1 || adj.e[0].type != LT_ADDR ) {
PopLoad();
DCStatus( DS_ERR|DS_BAD_LOCATION );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?