can2ms1.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 960 行 · 第 1/2 页
C
960 行
}
STATIC int typePass1( void *_type, void *parm ) {
cantype *type = _type;
/**/myassert( type != NULL );
parm = parm;
switch( type->class ) {
case CANT_INTEGER: typ1Integer( type ); break;
case CANT_REAL: typ1Real( type ); break;
case CANT_VOID: typ1Void( type ); break;
case CANT_COMPLEX: typ1Complex( type ); break;
default:
type->extra = 0; /* initialize to 0 */
}
return( 0 );
}
/*
Functions for type pass 2. This pass does most of the work of converting
cantypes to ms types.
*/
FORWARD STATIC int typePass2( void *type, void *force );
STATIC idx_t resolveType( type_handle hdl ) {
cantype *type;
type = CanTFind( hdl );
/**/myassert( type != NULL );
if( type->extra == 0 ) {
int force;
#ifndef USE_NEWTYPE
while( type->class == CANT_TYPEDEF &&
type->d.typdef.scope == CANT_SCOPE_NULL ) {
type = CanTFind( type->d.typdef.type );
}
#endif
force = 1;
typePass2( type, &force );
}
/**/myassert( type->extra != 0 );
return( type->extra );
}
STATIC void doStruct( cantype *type, name_handle name_hdl, type_rec *tr ) {
/*
Assumes that caller has done tr = newType( MS_SL_STRUCTURE ), but has not
written any type info into the new type yet. Does an endType( tr );
*/
type_rec *tlist;
type_rec *nlist;
struct_field *field;
struct_field *field_stop;
cantype *field_type;
/**/myassert( type != NULL && type->class == CANT_STRUCT );
/* write the structure info */
putUnsigned( tr, type->size ); /* length of structure */
putUnsigned( tr, type->d.strct.num_fields ); /* number of fields */
tlist = newType( MS_SL_LIST );
putIndex( tr, tlist->idx );
nlist = newType( MS_SL_LIST );
putIndex( tr, nlist->idx );
putName( tr, name_hdl );
put8( tr, MS_OL_PACKED );
endType( tr );
/* write the field types and name/offset lists */
field = type->d.strct.fields;
if( field != NULL ) {
field_stop = field + type->d.strct.num_fields;
while( field < field_stop ) {
if( field->bitfield ) {
field_type = CanTFind( field->type );
tr = newType( MS_SL_BITFIELD );
field_type->extra = tr->idx;
putUnsigned( tr, field_type->size );
put8( tr, ( field_type->sgned ) ?
MS_BTL_SIGNED_INT : MS_BTL_UNSIGNED_INT );
put8( tr, field->bit_offset & 0x07 );
endType( tr );
putIndex( tlist, tr->idx );
} else {
putIndex( tlist, resolveType( field->type ) );
}
putName( nlist, field->name );
putUnsigned( nlist, field->bit_offset >> 3 );
++field;
}
}
endType( tlist );
endType( nlist );
}
STATIC void doEnum( cantype *type, name_handle name_hdl, type_rec *tr ) {
/*
Assumes that tr = newType( MS_SL_SCALAR );. Does an endType( tr );
*/
type_rec *elist;
enum_const *enum_c;
enum_const *enum_cstop;
int is_signed;
int_32 slo, shi;
uint_32 ulo, uhi;
/**/myassert( type != NULL && type->class == CANT_ENUM );
putUnsigned( tr, type->size ); /* length of enum type */
if( type->sgned ) {
is_signed = 1;
put8( tr, MS_BTL_SIGNED_INT );
} else {
is_signed = 0;
put8( tr, MS_BTL_UNSIGNED_INT );
}
putName( tr, name_hdl );
elist = newType( MS_SL_LIST );
putIndex( tr, elist->idx );
/* walk through constants */
enum_c = type->d.enumr.consts;
if( enum_c != NULL ) {
if( is_signed ) {
slo = enum_c->value;
shi = enum_c->value;
} else {
ulo = enum_c->value;
uhi = enum_c->value;
}
enum_cstop = enum_c + type->d.enumr.num_consts;
while( enum_c < enum_cstop ) {
putName( elist, enum_c->name );
if( is_signed ) {
if( (int_32)enum_c->value < slo ) {
slo = enum_c->value;
} else if( (int_32)enum_c->value > shi ) {
shi = enum_c->value;
}
putSigned( elist, (int_32)enum_c->value );
} else {
if( (uint_32)enum_c->value < ulo ) {
ulo = enum_c->value;
} else if( (uint_32)enum_c->value > uhi ) {
uhi = enum_c->value;
}
putUnsigned( elist, enum_c->value );
}
++enum_c;
}
if( is_signed ) {
putSigned( tr, slo );
putSigned( tr, shi );
} else {
putUnsigned( tr, ulo );
putUnsigned( tr, uhi );
}
} else {
putUnsigned( tr, 0 );
putUnsigned( tr, 1 );
}
endType( elist );
endType( tr );
}
STATIC void typ2Integer( cantype *type ) {
/*
We delay creating non-standard integer sizes until the second pass so that
they may possibly be created by doStruct... KLUDGE! FIXME - we might
still generate an extraneous type...
*/
type_rec *tr;
/**/myassert( type != NULL && type->class == CANT_INTEGER );
tr = newType( MS_SL_BITFIELD );
type->extra = tr->idx;
putUnsigned( tr, type->size );
put8( tr, ( type->sgned ) ? MS_BTL_SIGNED_INT : MS_BTL_UNSIGNED_INT );
put8( tr, 0 );
endType( tr );
}
STATIC void typ2TypeDef( cantype *type ) {
type_rec *tr;
cantype *base_type;
/**/myassert( type != NULL && type->class == CANT_TYPEDEF );
if( type->d.typdef.scope == CANT_SCOPE_NULL ) {
#ifdef USE_NEWTYPE
tr = newType( MS_SL_NEWTYPE );
type->extra = tr->idx;
putIndex( tr, resolveType( type->d.typdef.type ) );
putName( tr, type->d.typdef.name );
endType( tr );
#else
/* this is safe because of the special case loop in resolveType */
type->extra = resolveType( type->d.typdef.type );
#endif
return;
}
base_type = CanTFind( type->d.typdef.type );
/**/myassert( base_type != NULL );
switch( type->d.typdef.scope ) {
case CANT_SCOPE_STRUCT:
/**/ myassert( base_type->class == CANT_STRUCT );
tr = newType( MS_SL_STRUCTURE );
base_type->extra = type->extra = tr->idx;
doStruct( base_type, type->d.typdef.name, tr );
break;
case CANT_SCOPE_UNION:
/**/ myassert( base_type->class == CANT_STRUCT );
tr = newType( MS_SL_STRUCTURE );
base_type->extra = type->extra = tr->idx;
doStruct( base_type, type->d.typdef.name, tr );
break;
case CANT_SCOPE_ENUM:
/**/ myassert( base_type->class == CANT_ENUM );
tr = newType( MS_SL_SCALAR );
base_type->extra = type->extra = tr->idx;
doEnum( base_type, type->d.typdef.name, tr );
break;
default:
/**/ never_reach();
}
}
STATIC void typ2SubRange( cantype *type ) {
type_rec *tr;
int is_signed;
/**/myassert( type != NULL && type->class == CANT_SUBRANGE );
tr = newType( MS_SL_SCALAR );
type->extra = tr->idx;
put8( tr, type->size );
if( type->sgned ) {
is_signed = 1;
put8( tr, MS_BTL_SIGNED_INT );
} else {
is_signed = 0;
put8( tr, MS_BTL_UNSIGNED_INT );
}
putName( tr, NAME_NULL );
put8( tr, MS_BCL_NIL );
if( is_signed ) {
putSigned( tr, (int_32)type->d.subrng.low );
putSigned( tr, (int_32)type->d.subrng.high );
} else {
putUnsigned( tr, type->d.subrng.low );
putUnsigned( tr, type->d.subrng.high );
}
endType( tr );
}
STATIC void typ2Array( cantype *type ) {
type_rec *tr;
/**/myassert( type != NULL && ( type->class == CANT_ARRAY ||
type->class == CANT_ARRAY_ZERO ) );
tr = newType( MS_SL_ARRAY );
type->extra = tr->idx;
putUnsigned( tr, type->size ); /* size of array */
putIndex( tr, resolveType( type->d.array.base_type ) );
if( type->class == CANT_ARRAY ) {
putIndex( tr, resolveType( type->d.array.index_type ) );
}
/* we don't emit the optional array name */
endType( tr );
}
STATIC void typ2ArrayD( cantype *type ) {
/**/myassert( type != NULL && type->class == CANT_ARRAY_DESC );
PrtMsg( WRN|MSG_UNS_ARRAY_DESC );
type->extra = voidIdx;
}
STATIC uint_8 ptrClass( uint_8 class ) {
if( class & CANT_PTR_HUGE ) {
return( MS_RT_I_FIELD | MS_RT_MD_HUGE_PTR );
} else if( class & CANT_PTR_FAR ) {
return( MS_RT_I_FIELD | MS_RT_MD_FAR_PTR );
}
return( MS_RT_I_FIELD | MS_RT_MD_NEAR_PTR );
}
STATIC void typ2Pointer( cantype *type ) {
type_rec *tr;
cantype *base_type;
idx_t base_idx;
/**/myassert( type != NULL && type->class == CANT_POINTER &&
type->extra == 0 );
/*
We ignore the CANT_PTR_386 bit because Microsoft has no specific 386
pointer type. dumb. We'll also ignore the DEREF bit since there is
no support for it.
*/
base_type = CanTElimTypeDef( type->d.pointr.base_type );
switch( base_type->class ) {
case CANT_INTEGER:
case CANT_REAL:
case CANT_COMPLEX:
/* we'll try to use the reserved types here */
base_idx = resolveType( base_type->hdl );
if( base_idx < 256 && base_idx > 127 ) {
type->extra = ptrClass( type->d.pointr.class ) |
base_idx;
return;
}
/* otherwise we have to create a pointer for it */
break;
case CANT_VOID:
/* another Microsoft booboo... no "void *" type */
type->extra = ptrClass( type->d.pointr.class ) |
MS_RT_TYP_SIGNED | MS_SZ_8BIT;
return;
}
/* if we get to here then create a pointer type */
tr = newType( MS_SL_POINTER );
type->extra = tr->idx;
if( type->d.pointr.class & CANT_PTR_HUGE ) {
put8( tr, MS_OL_HUGE );
} else if( type->d.pointr.class & CANT_PTR_FAR ) {
put8( tr, MS_OL_PLM_FAR );
} else {
put8( tr, MS_OL_PLM_NEAR );
}
putIndex( tr, resolveType( type->d.pointr.base_type ) );
endType( tr );
}
STATIC void typ2Enum( cantype *type, int force ) {
type_rec *tr;
/**/myassert( type != NULL && type->class == CANT_ENUM );
if( force ) {
tr = newType( MS_SL_SCALAR );
type->extra = tr->idx;
doEnum( type, NAME_NULL, tr );
}
}
STATIC void typ2Struct( cantype *type, int force ) {
type_rec *tr;
/**/myassert( type != NULL && type->class == CANT_STRUCT && type->extra == 0 );
if( force ) {
tr = newType( MS_SL_STRUCTURE );
type->extra = tr->idx;
doStruct( type, NAME_NULL, tr );
}
}
STATIC void typ2Procedure( cantype *type ) {
type_rec *tr;
type_rec *list;
proc_parm *parm;
proc_parm *parm_stop;
/**/myassert( type != NULL && type->class == CANT_PROCEDURE &&
type->extra == 0 );
/*
We ignore the CANT_PROC_386 bit because Microsoft does not have any 386
specific procedure type.
*/
tr = newType( MS_SL_PROCEDURE );
type->extra = tr->idx;
put8( tr, MS_BCL_NIL );
putIndex( tr, resolveType( type->d.proc.ret_type ) );
if( type->d.proc.class & CANT_PROC_FAR ) {
put8( tr, MS_OL_C_FAR ); /* FIXME support other styles */
} else {
put8( tr, MS_OL_C_NEAR );
}
putUnsigned( tr, type->d.proc.num_parms );
if( type->d.proc.num_parms == 0 ) {
putIndex( tr, voidIdx ); /* nil leaf for no parms */
} else {
list = newType( MS_SL_LIST );
/* output parm types */
parm = type->d.proc.parms;
parm_stop = parm + type->d.proc.num_parms;
while( parm < parm_stop ) {
putIndex( list, resolveType( parm->type ) );
++parm;
}
putIndex( tr, list->idx );
endType( list );
}
endType( tr );
}
STATIC void typ2CharBlock( cantype *type ) {
type_rec *tr;
/**/myassert( type != NULL && type->class == CANT_CHARBLOCK );
tr = newType( MS_SL_FSTRING );
type->extra = tr->idx;
put8( tr, 0 );
putUnsigned( tr, type->d.charb.length );
endType( tr );
}
STATIC void typ2CharBlockI( cantype *type ) {
/**/myassert( type != NULL && type->class == CANT_CHARBLOCK_IND );
PrtMsg( WRN|MSG_UNS_CHARBLOCK_IND );
type->extra = voidIdx;
}
STATIC int typePass2( void *_type, void *_force ) {
cantype *type = _type;
int *force = _force;
/**/myassert( type != NULL );
if( type->extra != 0 ) { /* already processed */
return( 0 );
}
switch( type->class ) {
case CANT_RESERVED: break;
case CANT_INTEGER: typ2Integer( type ); break;
case CANT_TYPEDEF: typ2TypeDef( type ); break;
case CANT_SUBRANGE: typ2SubRange( type ); break;
case CANT_ARRAY: /* FALL THROUGH */
case CANT_ARRAY_ZERO: typ2Array( type ); break;
case CANT_ARRAY_DESC: typ2ArrayD( type ); break;
case CANT_POINTER: typ2Pointer( type ); break;
case CANT_ENUM: typ2Enum( type, *force ); break;
case CANT_STRUCT: typ2Struct( type, *force ); break;
case CANT_PROCEDURE: typ2Procedure( type ); break;
case CANT_CHARBLOCK: typ2CharBlock( type ); break;
case CANT_CHARBLOCK_IND:typ2CharBlockI( type ); break;
}
return( 0 );
}
STATIC void makeVoid( void ) {
type_rec *tr;
tr = newType( MS_BCL_NIL );
voidIdx = tr->idx;
endType( tr );
}
void Can2MsT( void ) {
/******************/
int force;
if( CanMisc.types_present ) {
setupObjIO();
makeVoid();
CanTWalk( NULL, typePass1 );
/**/ myassert( waitingRecs == NULL );
force = 0; /* don't force definition of everything */
CanTWalk( &force, typePass2 );
/**/ myassert( waitingRecs == NULL );
force = 1;
CanTWalk( &force, typePass2 );
/**/ myassert( waitingRecs == NULL );
finishObjIO();
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?