cantype.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 692 行 · 第 1/2 页
C
692 行
type_handle CanTArrayD( type_handle base_type, type_handle lo,
type_handle hi, addr_handle bounds ) {
/*************************************************************************/
cantype *type;
/**/myassert( validHdl( lo ) && isOrdinalType( lo ) &&
validHdl( hi ) && isOrdinalType( hi ) &&
validHdl( base_type ) );
type = newNode( CANT_ARRAY_DESC );
type->size = 0; /* FIXME can we do better than this? */
type->d.arrayd.lo_type = lo;
type->d.arrayd.hi_type = hi;
type->d.arrayd.bounds = bounds;
type->d.arrayd.base_type = base_type;
return( type->hdl );
}
type_handle CanTPointer( type_handle base_type, uint_8 class ) {
/************************************************************/
cantype *type;
/**/myassert( validHdl( base_type ) );
type = newNode( CANT_POINTER );
if( class & ( CANT_PTR_FAR | CANT_PTR_HUGE ) ) {
type->size = 4*8;
} else {
type->size = 2*8;
}
if( class & (CANT_PTR_386) ) {
type->size += 2*8;
}
type->d.pointr.base_type = base_type;
type->d.pointr.class = class;
return( type->hdl );
}
cantype *CanTEnum( type_handle base_type, uint_16 num_consts ) {
/************************************************************/
cantype *type;
cantype *base;
/**/myassert( validHdl( base_type ) && num_consts > 0 );
base = CanTFind( base_type );
/**/myassert( base->class == CANT_INTEGER || base->class == CANT_SUBRANGE );
type = newNode( CANT_ENUM );
type->size = base->size;
type->sgned = base->sgned;
type->d.enumr.base_type = base_type;
type->d.enumr.num_consts = num_consts;
if( num_consts > 0 ) {
type->d.enumr.consts = MemAlloc( num_consts * sizeof( enum_const ) );
} else {
type->d.enumr.consts = NULL;
}
return( type );
}
cantype *CanTStruct( uint_16 num_fields ) {
/***************************************/
cantype *type;
type = newNode( CANT_STRUCT );
/* type->size is determined later */
type->d.strct.num_fields = num_fields;
if( num_fields > 0 ) {
type->d.strct.fields = MemAlloc( num_fields * sizeof( struct_field ) );
} else {
type->d.strct.fields = NULL;
}
return( type );
}
cantype *CanTProcedure( type_handle ret_type, uint_8 class,
uint_8 num_parms ) {
/************************************************************/
cantype *type;
/**/myassert( validHdl( ret_type ) );
type = newNode( CANT_PROCEDURE );
type->size = 0;
type->d.proc.ret_type = ret_type;
type->d.proc.class = class;
type->d.proc.num_parms = num_parms;
if( num_parms > 0 ) {
type->d.proc.parms = MemAlloc( num_parms * sizeof( proc_parm ) );
} else {
type->d.proc.parms = NULL;
}
return( type );
}
STATIC int sortStructFields( const void *_f1, const void *_f2 ) {
const struct_field *f1 = _f1;
const struct_field *f2 = _f2;
cantype *t1;
cantype *t2;
/**/myassert( f1 != NULL && f2 != NULL );
if( f1->bit_offset > f2->bit_offset ) {
return( 1 );
} else if( f1->bit_offset < f2->bit_offset ) {
return( -1 );
}
t1 = CanTFind( f1->type );
t2 = CanTFind( f2->type );
if( t1->size > t2->size ) {
return( 1 );
} else if( t1->size < t2->size ) {
return( -1 );
}
return( 0 );
}
STATIC void graphStruct( cantype *type ) {
struct_field *field;
struct_field *field_stop;
uint_32 offset_size;
bitsize max_offset_size;
cantype *fieldptr;
/**/myassert( type != NULL && type->class == CANT_STRUCT );
/*
We look for the max_offset_size here... we can't just use the last entry
in the array because of unions.
*/
max_offset_size = 0;
field = type->d.strct.fields;
field_stop = field + type->d.strct.num_fields;
while( field < field_stop ) {
fieldptr = CanTFind( field->type );
offset_size = fieldptr->size;
offset_size += field->bit_offset;
if( offset_size > max_offset_size ) {
max_offset_size = offset_size;
}
++field;
}
type->size = max_offset_size;
qsort( type->d.strct.fields, type->d.strct.num_fields,
sizeof( struct_field ), sortStructFields );
}
STATIC int sortSignedEnum( const void *_c1, const void *_c2 ) {
const enum_const *c1 = _c1;
const enum_const *c2 = _c2;
if( (int_32)c1->value > (int_32)c2->value ) {
return( 1 );
} else if( (int_32)c1->value == (int_32)c2->value ) {
return( 0 );
}
return( -1 );
}
STATIC int sortUnsignedEnum( const void *_c1, const void *_c2 ) {
const enum_const *c1 = _c1;
const enum_const *c2 = _c2;
if( (uint_32)c1->value > (uint_32)c2->value ) {
return( 1 );
} else if( (uint_32)c1->value == (uint_32)c2->value ) {
return( 0 );
}
return( -1 );
}
STATIC void graphEnum( cantype *type ) {
enum_const *enum_c;
enum_const *enum_cstop;
uint_16 num_consts;
bitsize size;
/**/myassert( type != NULL && type->class == CANT_ENUM );
if( type->sgned ) {
enum_c = type->d.enumr.consts;
num_consts = type->d.enumr.num_consts;
enum_cstop = enum_c + num_consts;
size = type->size;
while( enum_c < enum_cstop ) {
enum_c->value = signExtend( size, enum_c->value );
++enum_c;
}
}
enum_c = type->d.enumr.consts;
num_consts = type->d.enumr.num_consts;
qsort( enum_c, num_consts, sizeof( enum_const ),
type->sgned ? sortSignedEnum : sortUnsignedEnum );
}
STATIC void graphProcedure( cantype *type ) {
proc_parm *parm;
proc_parm *parm_stop;
if( type->d.proc.num_parms > 0 ) {
parm = type->d.proc.parms;
parm_stop = parm + type->d.proc.num_parms;
while( parm < parm_stop ) {
++parm;
}
}
}
void CanTGraph( cantype *type ) {
/*****************************/
switch( type->class ) {
case CANT_STRUCT: graphStruct( type ); break;
case CANT_PROCEDURE: graphProcedure( type ); break;
case CANT_ENUM: graphEnum( type ); break;
default:
/**/ myassert( 0 );
}
}
type_handle CanTCharB( uint_32 length ) {
/*************************************/
cantype *type;
type = newNode( CANT_CHARBLOCK );
type->size = length * 8;
type->d.charb.length = length;
return( type->hdl );
}
type_handle CanTCharBI( type_handle length_type, addr_handle length ) {
/*******************************************************************/
cantype *type;
/**/myassert( validHdl( length_type ) );
type = newNode( CANT_CHARBLOCK_IND );
type->size = 0; /* FIXME can we do better than this? */
type->d.charbi.length_type = length_type;
type->d.charbi.length = length;
return( type->hdl );
}
type_handle CanTDupSize( type_handle type_hdl, bitsize newsize ) {
/**************************************************************/
cantype *type;
cantype *newtype;
/**/myassert( validHdl( type_hdl ) );
type = CanTFind( type_hdl );
/**/myassert( type != NULL );
if( type->size == newsize ) {
return( type_hdl );
}
newtype = newNode( type->class );
newtype->size = newsize;
newtype->busy = 0;
newtype->d = type->d;
return( newtype->hdl );
}
void CanTMunge( void ) {
/********************/
/* Currently we don't need to do much here... it is all handled while
building the graph. */
}
int CanTWalk( void *parm, int (*func)(void *type, void *parm ) ) {
/*****************************************************************/
return( ArrWalk( cantArr, parm, func ) );
}
#if 0
cantype *CanTElimTypes( type_handle start_hdl, uint_16 elim ) {
/***********************************************************/
/*
Chase a type handle as far back as we can eliminating certain types
along the way.
*/
type_handle walk;
cantype *type;
/**/myassert( validHdl( start_hdl ) );
if( start_hdl == CANT_NULL ) {
return( NULL );
}
walk = start_hdl;
for(;;) {
type = CanTFind( walk );
/**/ myassert( type != NULL );
switch( type->class ) {
case CANT_TYPEDEF:
if( elim & CANT_ELIM_TYPEDEF ) {
walk = type->d.typdef.type;
} else {
return( type );
}
break;
case CANT_SUBRANGE:
if( elim & CANT_ELIM_SUBRANGE ) {
walk = type->d.subrng.base_type;
} else {
return( type );
}
break;
case CANT_ENUM:
if( elim & CANT_ELIM_ENUM ) {
walk = type->d.enumr.base_type;
} else {
return( type );
}
break;
default:
return( type );
}
}
return( NULL );
}
#endif
cantype *CanTElimTypeDef( type_handle start_hdl ) {
/***********************************************/
/*
Chase a type handle as far back as we can eliminating typedefs
along the way.
*/
type_handle walk;
cantype *type;
/**/myassert( validHdl( start_hdl ) );
if( start_hdl == CANT_NULL ) {
return( NULL );
}
walk = start_hdl;
for(;;) {
type = CanTFind( walk );
if( type == NULL ) break;
if( type->class != CANT_TYPEDEF ) {
return( type );
}
walk = type->d.typdef.type;
}
return( NULL );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?