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