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