wattype.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,874 行 · 第 1/4 页
C
1,874 行
}
dip_status FindTypeHandle( imp_image_handle *ii, imp_mod_handle im,
unsigned index, imp_type_handle *it )
{
typeinfo typeld;
dip_status ret;
PushLoad( &typeld );
ret = DoFindTypeHandle( ii, im, index, it );
PopLoad();
return( ret );
}
typedef enum { ET_ENUM = 1, ET_TYPE = 2 } type_or_enum;
enum { STRUCT_IDX, CLASS_IDX, UNION_IDX, ENUM_IDX, NUM_IDX };
static const char *Scopes[] = { "struct", "class", "union", "enum", NULL };
struct name_state {
unsigned scope_idx[NUM_IDX];
unsigned curr_idx;
unsigned hit_eof : 1;
byte *header;
};
static void InitNameState( struct name_state *state )
{
memset( state, 0, sizeof( *state ) );
}
static byte *FindAName( struct name_state *state, byte *p,
type_or_enum which, lookup_item *li )
{
byte *name;
unsigned len;
int (*comp)();
unsigned index;
unsigned i;
unsigned type;
if( li->case_sensitive ) {
comp = memcmp;
} else {
comp = memicmp;
}
for( ; p < Type->end; p = NEXT_TYPE( p ) ) {
state->curr_idx++;
switch( p[1] & CLASS_MASK ) {
case ENUM_TYPE:
if( p[1] == ENUM_TYPE+ENUM_LIST ) {
state->header = p;
} else {
state->curr_idx--;
}
if( (which & ET_ENUM) == 0 ) continue;
break;
case NAME_TYPE:
if( ( p[1] & SUBCLASS_MASK ) == TYPE_EOF ) {
state->hit_eof = 1;
return( NULL );
}
if( (which & ET_TYPE) == 0 ) continue;
switch( p[1] & SUBCLASS_MASK ) {
case TYPE_SCALAR:
type = ST_TYPE;
break;
case TYPE_SCOPE:
name = NamePtr( p );
len = *p - (name-p);
for( i = 0; i < NUM_IDX; ++i ) {
if( memcmp( name, Scopes[i], len ) == 0 ) {
state->scope_idx[i] = state->curr_idx;
break;
}
}
continue;
case TYPE_NAME:
GetIndex( p + 2, &index );
if( index == 0 ) {
type = ST_TYPE;
} else {
for( i = 0; i < NUM_IDX; ++i ) {
if( state->scope_idx[i] == index ) break;
}
type = ST_STRUCT_TAG+i;
}
break;
default:
continue;
}
if( type == ST_TYPE && li->type == ST_NONE ) break;
if( type == li->type ) break;
continue;
case STRUCT_TYPE:
if( p[1] == STRUCT_TYPE+STRUCT_LIST ) {
state->header = p;
} else {
state->curr_idx--;
}
continue;
default:
continue;
}
name = NamePtr( p );
len = *p - (name-p);
if( len != li->name.len ) continue;
if( comp( name, li->name.start, len ) != 0 ) continue;
return( p );
}
return( NULL );
}
search_result LookupTypeName( imp_image_handle *ii, imp_mod_handle im,
lookup_item *li, imp_type_handle *it )
{
unsigned entry;
struct name_state state;
byte *p;
typeinfo typeld;
search_result sr;
PushLoad( &typeld );
InitNameState( &state );
sr = SR_NONE;
entry = 0;
for( ;; ) {
if( LoadType( ii, im, entry ) != DS_OK ) break;
p = FindAName( &state, Type->start, ET_TYPE, li );
if( p != NULL ) {
it->im = im;
it->f.all = 0;
it->t.entry = entry;
it->t.offset = p - Type->start;
sr = SR_EXACT;
break;
}
if( state.hit_eof ) break;
++entry;
}
PopLoad();
return( sr );
}
static search_result SearchEnumTypeName( imp_image_handle *ii, imp_mod_handle im,
lookup_item *li, void *d, type_or_enum which )
{
unsigned entry;
struct name_state state;
search_result sr;
imp_sym_handle *is;
byte *p;
typeinfo typeld;
PushLoad( &typeld );
sr = SR_NONE;
InitNameState( &state );
entry = 0;
for( ;; ) {
if( LoadType( ii, im, entry ) != DS_OK ) break;
p = Type->start;
for( ;; ) {
p = FindAName( &state, p, which, li );
if( p == NULL ) break;
is = DCSymCreate( ii, d );
is->im = im;
is->name_off = NamePtr( p ) - p;
is->u.typ.t.entry = entry;
is->u.typ.t.offset = p - Type->start;
if( (p[1] & CLASS_MASK) == ENUM_TYPE ) {
is->type = SH_CST;
is->u.typ.h.offset = state.header - Type->start;
is->u.typ.h.entry = entry;
} else {
is->type = SH_TYP;
}
sr = SR_EXACT;
/* we really should continue searching for more names that
match, but we're going to early out because I know that
the symbolic info format is too weak to have more than
one type name or enum const that will match */
PopLoad();
return( sr );
}
if( state.hit_eof ) break;
++entry;
}
PopLoad();
return( sr );
}
search_result SearchEnumName( imp_image_handle *ii, imp_mod_handle im,
lookup_item *li, void *d )
{
return( SearchEnumTypeName( ii, im, li, d, ET_ENUM ) );
}
search_result SearchTypeName( imp_image_handle *ii, imp_mod_handle im,
lookup_item *li, void *d )
{
return( SearchEnumTypeName( ii, im, li, d, ET_TYPE ) );
}
walk_result DIPENTRY DIPImpWalkTypeList( imp_image_handle *ii, imp_mod_handle im,
IMP_TYPE_WKR *wk, imp_type_handle *it, void *d )
{
byte *p;
byte kind;
typeinfo typeld;
walk_result wr;
PushLoad( &typeld );
it->im = im;
it->f.all = 0;
it->t.entry = 0;
for( ;; ) {
if( LoadType( ii, im, it->t.entry ) != DS_OK ) break;
for( p = Type->start; p < Type->end; p = NEXT_TYPE( p ) ) {
kind = p[1];
switch( kind & CLASS_MASK ) {
case NAME_TYPE:
switch( kind & SUBCLASS_MASK ) {
case TYPE_SCOPE:
case TYPE_CUE_TABLE:
continue;
case TYPE_EOF:
goto done;
}
break;
case ENUM_TYPE :
if( (kind & SUBCLASS_MASK) != ENUM_LIST ) {
continue;
}
break;
case STRUCT_TYPE :
if( (kind & SUBCLASS_MASK) != STRUCT_LIST ) {
continue;
}
break;
case PROC_TYPE:
if( (kind & SUBCLASS_MASK) == PROC_EXT_PARMS ) {
continue;
}
break;
}
it->t.offset = p - Type->start;
wr = wk( ii, it, d );
if( wr != WR_CONTINUE ) {
PopLoad();
return( wr );
}
}
it->t.entry++;
}
done:
PopLoad();
return( WR_CONTINUE );
}
static void ScalarInfo( unsigned info, type_info *ti )
{
ti->size = (info & SCLR_LEN_MASK) + 1;
switch( info & SCLR_CLASS_MASK ) {
case SCLR_INTEGER:
ti->modifier = TM_SIGNED;
ti->kind = TK_INTEGER;
break;
case SCLR_UNSIGNED:
ti->modifier = TM_UNSIGNED;
ti->kind = TK_INTEGER;
break;
case SCLR_FLOAT:
ti->kind = TK_REAL;
break;
case SCLR_VOID:
ti->kind = TK_VOID;
break;
case SCLR_COMPLEX:
ti->kind = TK_COMPLEX;
break;
}
}
static dip_status GetTypeInfo(imp_image_handle *ii, imp_type_handle *it,
location_context *lc, type_info *ti, unsigned *ndims )
{
byte *p;
byte subkind;
imp_type_handle tmp;
address addr;
array_info info;
byte is_char;
byte save_major;
dip_status ret;
unsigned index;
unsigned count;
unsigned long max;
addr_off offset;
unsigned skip;
typeinfo typeld;
location_list ll;
PushLoad( &typeld );
ti->kind = TK_NONE;
ti->modifier = TM_NONE;
ti->size = 0;
if( it->f.s.gbl ) {
ti->kind = GblTypeClassify( it->t.offset );
} else if( it->f.s.sclr ) {
ScalarInfo( it->t.offset, ti );
} else {
is_char = it->f.s.chr;
ret = LoadType( ii, it->im, it->t.entry );
if( ret != DS_OK ) {
PopLoad();
return( ret );
}
if( !GetRealTypeHandle( ii, it ) ) {
PopLoad();
return( DS_FAIL );
}
p = it->t.offset + Type->start;
subkind = p[1] & SUBCLASS_MASK;
switch( p[1] & CLASS_MASK ) {
case NAME_TYPE:
if( subkind == TYPE_SCALAR ) {
ScalarInfo( p[2], ti );
if( is_char && ti->kind == TK_INTEGER && ti->size == 1 ) {
ti->kind = TK_CHAR;
}
}
break;
case ARRAY_TYPE:
FreeLoad();
save_major = it->f.s.col_major;
it->f.s.col_major = 0;
ImpInterface.type_array_info( ii, it, lc, &info, NULL );
ImpInterface.type_base( ii, it, &tmp, NULL, NULL );
GetTypeInfo( ii, &tmp, lc, ti, ndims );
it->f.s.col_major = save_major;
if( ndims != NULL ) ++*ndims;
ti->size *= info.num_elts;
ti->modifier = TM_NONE;
ti->kind = TK_ARRAY;
Type->start = NULL;
break;
case SUBRANGE_TYPE:
ImpInterface.type_base( ii, it, &tmp, NULL, NULL );
ImpInterface.tipe_info( ii, &tmp, lc, ti );
break;
case POINTER_TYPE:
{
static const char PSize[] = {2,4,4,2,4,4,4,6,4,6};
#define N TM_NEAR
#define F TM_FAR
#define H TM_HUGE
#define D TM_FLAG_DEREF
static const char PMods[] = {N,F,H,N|D,F|D,H|D,N,F,N|D,F|D};
ti->size = PSize[subkind];
ti->modifier = PMods[subkind];
ti->kind = TK_POINTER;
}
break;
case ENUM_TYPE:
ScalarInfo( p[4], ti );
ti->kind = TK_ENUM;
break;
case STRUCT_TYPE:
if( *p > 4 ) {
ti->size = *(unsigned_32 *)(p+4);
} else {
max = 0;
count = *(unsigned_16 *)(p+2);
while( count != 0 ) {
skip = 2;
p = NEXT_TYPE( p );
switch( p[1] ) {
case STRUCT_TYPE+ST_BIT_BYTE:
skip += 2;
/* fall through */
case STRUCT_TYPE+ST_FIELD_BYTE:
skip += 1;
offset = *(unsigned_8 *)(p+2);
break;
case STRUCT_TYPE+ST_BIT_WORD:
skip += 2;
/* fall through */
case STRUCT_TYPE+ST_FIELD_WORD:
skip += 2;
offset = *(unsigned_16 *)(p+2);
break;
case STRUCT_TYPE+ST_BIT_LONG:
skip += 2;
/* fall through */
case STRUCT_TYPE+ST_FIELD_LONG:
skip += 4;
offset = *(unsigned_32 *)(p+2);
break;
case STRUCT_TYPE+ST_FIELD_LOC:
case STRUCT_TYPE+ST_BIT_LOC:
case STRUCT_TYPE+ST_INHERIT:
skip = 0;
break;
}
if( skip > 0 ) {
GetIndex( p + skip, &index );
/* Pulling a trick. We know that the size
field will only be absent in older objects,
and thus will only have one type section per
module. */
FindTypeHandle( ii, it->im, index, &tmp );
GetTypeInfo( ii, &tmp, lc, ti, NULL );
offset += ti->size;
if( offset > max ) max = offset;
}
--count;
}
ti->size = max;
}
ti->kind = TK_STRUCT;
break;
case PROC_TYPE:
{
static const char FMods[] = {
TM_NEAR,TM_FAR,TM_NEAR,TM_FAR
};
ti->modifier = FMods[subkind];
ti->kind = TK_FUNCTION;
}
break;
case CHAR_TYPE:
switch( subkind ) {
case CHAR_BYTE_LEN:
ti->size = *(unsigned_8 *)(p+2);
break;
case CHAR_WORD_LEN:
ti->size = *(unsigned_16 *)(p+2);
break;
case CHAR_LONG_LEN:
ti->size = *(unsigned_32 *)(p+2);
break;
case CHAR_DESC_LEN:
GetAddress( ii, p + 3, &addr, 0 );
ti->size = GetScalar( addr, p[2] );
break;
case CHAR_DESC386_LEN:
GetAddress( ii, p + 3, &addr, 1 );
ti->size = GetScalar( addr, p[2] );
break;
case CHAR_DESC_LOC:
EvalLocation( ii, lc, p + 3, &ll );
ti->size = GetScalar( ll.e[0].u.addr, p[2] );
break;
}
ti->kind = TK_STRING;
}
}
PopLoad();
return( DS_OK );
}
dip_status DIPENTRY DIPImpTypeInfo(imp_image_handle *ii, imp_type_handle *it,
location_context *lc, type_info *ti )
{
return( GetTypeInfo( ii, it, lc, ti, NULL ) );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?