dftype.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,391 行 · 第 1/3 页

C
1,391
字号
    /*
        Fill in the type information for the type handle. The location
        context is being passed in because it might be needed to calculate
        the size of the type (variable dimensioned arrays and the like).
    */

    InitTypeHandle( ii, it, lc );
    MapImpTypeInfo( &it->typeinfo, ti );
    if( ti->kind == TK_INTEGER ){  // this can be removed when 10.5 gets updated
        char *name;

        name =  DRGetName( it->type );
        if( name != NULL ){
            if( strcmp( name, "char" ) == 0
             || strcmp( name, "unsigned char" ) == 0 ){
                ti->kind = TK_CHAR;
            }
            DCFree( name );
        }

    }
    return( DS_OK );
}

dip_status      DIPENTRY DIPImpTypeBase( imp_image_handle *ii,
                        imp_type_handle *it, imp_type_handle *base,
                        location_context *lc, location_list *ll )
{
    dr_handle  btype;
    /*
        Given an implementation type handle, fill in 'base' with the
        base type of the handle.
     */
    if( base != it ){
        *base = *it;
    }
    DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
    if( base->state == DF_SET && base->sub_array  ){
        base->array.index = GetArrayDim( base->array.index, 1 );
        if( base->array.is_based ){
            base->array.is_set = FALSE;
        }
        base->array.is_based = TRUE;
        if( base->array.index != NULL ){
            return( DS_OK );
        }
    }
    btype =  DRSkipTypeChain( base->type ); /* skip modifiers and typedefs */
    base->type = DRGetTypeAT( btype );      /* get base type */
    if( base->type == NULL ) {
        base->type = DR_HANDLE_VOID;        /* no type means 'void' */
    }
    base->state = DF_NOT;
    return( DS_OK );
}

typedef struct {
    int_32 low;
    int_32 high;
}enum_range;

static int AEnum( dr_handle var, int index, void *_de ) {
    enum_range *de = _de;
    int_32  value;

    index = index;
    if( !DRConstValAT( var, (uint_32 *)&value ) ){
        return( FALSE );
    }
    if( value < de->low ){
        de->low = value;
    }else if( value > de->high ){
        de->high = value;
    }
    return( TRUE );
}

static int ArrayEnumType( dr_handle tenu, int index, void *_df ) {
/****************************************************************/
// Find low, high bounds of enum
//TODO:unsigned range
    array_wlk_wlk  *df = _df;
    enum_range     de;
    int_32         count;

    index = index;
    de.low  = LONG_MIN;
    de.high = LONG_MAX;
    if( !DRWalkEnum( tenu, AEnum, &de )){
        return( FALSE );
    }
    df->low = de.low;
    count = de.high-de.low+1;
    df->count *= count;

    df->dim++;
    return( df->cont );
}

static int  GetSymVal( imp_image_handle *ii,
                       dr_handle dr_sym, location_context *lc,
                        long *ret ){
//  Find value of scalar
    dr_handle       dr_type;
    dr_typeinfo     typeinfo[1];
    uint_32         seg;
    location_list   src;
    location_list   dst;
    im_idx          imx;

    dr_type =  DRGetTypeAT( dr_sym );
    if( dr_type == NULL ){
        return( FALSE );
    }
    DRGetTypeInfo( dr_type, typeinfo );
    if( typeinfo->size > sizeof( *ret ) ){
        return( FALSE );
    }
    imx = DwarfModIdx( ii, dr_sym );
    if( imx == INVALID_IMX ){
        return( FALSE );
    }
    if( ii->mod_map[imx].is_segment == FALSE ){
        seg = SEG_DATA; // if flat hoke segment
    }else{
        EvalSeg( ii, dr_sym, &seg );
    }
    if( EvalLocation( ii, lc, dr_sym, seg, &src ) != DS_OK ){
        return( FALSE );
    }
    LocationCreate( &dst, LT_INTERNAL, ret );
    if( DCAssignLocation( &dst, &src, typeinfo->size ) != DS_OK ){
        return( FALSE );
    }
    return( TRUE );
}

static int GetDrVal( array_wlk_wlk *df, dr_val32 *val,  int_32 *ret ){
/*******************************************/
// extract the value from val
    switch( val->val_class ){
    case DR_VAL_INT:
        *ret = val->val.s;
        return( TRUE );
    case DR_VAL_REF:
        if( DRConstValAT( val->val.ref, (uint_32*)ret ) ){
            return( TRUE );
        }else if( GetSymVal( df->ii, val->val.ref, df->lc, ret ) ){
            return( TRUE );
        }
    }
    return( FALSE );
}

static int ArraySubRange( dr_handle tsub, int index, void *_df ) {
/****************************************************************/
    array_wlk_wlk *df = _df;
    dr_subinfo info;
    int_32     low;
    int_32     high;
    int_32     count;

    index = index;
    DRGetSubrangeInfo( tsub, &info );
    /* DWARF 2.0 specifies lower bound defaults for C/C++ (0) and FORTRAN (1) */
    if( info.low.val_class == DR_VAL_NOT ) {
        if( df->ii->mod_map[df->it->imx].lang == DR_LANG_FORTRAN )
            low = 1;
        else
            low = 0;
    } else {
        GetDrVal( df, &info.low, &low );
    }
    if( info.count.val_class == DR_VAL_NOT ){
        if( info.high.val_class == DR_VAL_NOT ){
            return( FALSE );
        }
        GetDrVal( df, &info.high, &high );
        count = high - low +1;
    }else{
        GetDrVal( df, &info.count, &count );
    }
    df->low = low;
    df->count *= count;
    df->dim++;
    return( df->cont );
}

dip_status      DIPENTRY DIPImpTypeArrayInfo( imp_image_handle *ii,
                        imp_type_handle *array, location_context *lc,
                        array_info *ai, imp_type_handle *index )
{
    /*
        Given an implemenation type handle that represents an array type,
        get information about the array shape and index type. The location
        context is for variable dimensioned arrays again. The 'index'
        parameter is filled in with the type of variable used to subscript
        the array. It may be NULL, in which case no information is returned.
    */

    DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
    if( array->state == DF_NOT ){
        InitTypeHandle( ii, array, lc );
    }
    if( array->state == DF_NOT ){
        DCStatus( DS_ERR | DS_BAD_PARM );
        return( DS_ERR | DS_BAD_PARM  );
    }
    if( array->typeinfo.kind != DR_TYPEK_ARRAY ){
        DCStatus( DS_ERR | DS_BAD_PARM );
        return( DS_ERR | DS_BAD_PARM  );
    }
    ai->low_bound = array->array.low;
    ai->num_elts = array->array.num_elts;
    ai->num_dims = array->array.dims;
    ai->column_major = array->array.column_major;
    ai->stride = array->array.base_stride;
    if( index != NULL ){
        index->imx = array->imx;
        if( array->array.index == NULL ){  //Fake a type up
            index->state = DF_SET;
            index->type = NULL;
            index->typeinfo.size = 0;
            index->typeinfo.kind = DR_TYPEK_NONE;
            index->typeinfo.mclass = DR_MOD_NONE;
        }else{
            index->state = DF_NOT;
            index->type = array->array.index;
        }
    }
    return( DS_OK );
}

/*
    Given an implementation type handle that represents a procedure type,
    get information about the return and parameter types. If the 'n'
    parameter is zero, store the return type handle into the 'parm'
    variable. Otherwise store the handle for the n'th parameter in
    'parm'.
*/
typedef struct {
    int            count;
    int            last;
    dr_handle       var;
}parm_wlk;

static int AParm( dr_handle var, int index, void *_df ) {
/*******************************************************/
    parm_wlk *df = _df;

    index = index;
    ++df->count;
    if( df->count == df->last ){
        df->var = var;
        return( FALSE );
    }else{
        return( TRUE );
    }
}

extern dr_handle GetParmN(  imp_image_handle *ii,dr_handle proc, int count ){
/******************************************************/
// return handle of the n parm
    parm_wlk df;
    dr_handle ret;

    df.count = 0;
    df.last = count;
    DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
    if( DRWalkBlock( proc,  DR_SRCH_parm, AParm, &df ) ){
        ret = NULL;
    }else{
        ret = df.var;
    }
    return( ret );
}

extern int GetParmCount(  imp_image_handle *ii, dr_handle proc ){
/******************************************************/
// return handle of the n parm
    parm_wlk df;

    df.count = 0;
    df.last = 0;
    DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
    DRWalkBlock( proc,  DR_SRCH_parm, AParm, &df );
    return( df.count );
}

dip_status      DIPENTRY DIPImpTypeProcInfo( imp_image_handle *ii,
                imp_type_handle *proc, imp_type_handle *parm, unsigned n )
{
    dr_handle       btype;
    dr_handle       parm_type;
    dip_status      ret;

    DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
    btype =  DRSkipTypeChain( proc->type ); /* skip modifiers and typedefs */
    if( n > 0 ){
        btype = GetParmN( ii, btype, n );
    }// if n == 0 just fall through and get type of function
    if( btype != NULL ){
        parm_type = DRGetTypeAT( btype );    /* get type */
    }
    if( parm_type != NULL ){
        parm->state = DF_NOT;
        parm->type = parm_type;
        parm->imx = proc->imx;
        ret = DS_OK;
    }else{
       ret = DS_FAIL;
    }
    return( ret );
}

dip_status      DIPENTRY DIPImpTypePtrAddrSpace( imp_image_handle *ii,
                    imp_type_handle *it, location_context *lc, address *a )
{
    /*
        Given an implementation type handle that represents a pointer type,
        get information about any implied address space for that pointer
        (based pointer cruft). If there is an implied address space for
        the pointer, fill in *a with the information and return DS_OK.
        Otherwise return DS_FAIL.
    */
    dip_status ret;

    ret = EvalBasedPtr( ii, lc, it->type, a );
    return( ret );
}


int DIPENTRY DIPImpTypeCmp( imp_image_handle *ii, imp_type_handle *it1,
                                imp_type_handle *it2 )
{
    long diff;

    ii = ii;
    diff = it1->type - it2->type;
    return( diff );
}
/*****************************/
/* Structure Enum Walks      */
/*****************************/
typedef struct inh_vbase {
    struct inh_vbase *next;
    dr_handle        base;
}inh_vbase;

typedef struct{
    im_idx           imx;
    imp_image_handle *ii;
    sym_sclass        sclass;
    void             *d;
    dr_handle        root;
    dr_handle        inh;
    inh_vbase        *vbase;
    enum_einfo       einfo;
}type_wlk_com;


typedef struct {
    type_wlk_com     com;
    IMP_SYM_WKR      *wk;
    imp_sym_handle   *is;
    walk_result      wr;
}type_wlk_wlk;

typedef struct {
    type_wlk_com     com;
    int              (*comp)();
    lookup_item      *li;
    search_result     sr;
}type_wlk_lookup;

typedef union {
    type_wlk_com    com;
    type_wlk_wlk    sym;
    type_wlk_lookup lookup;
}type_wlk;


static int AddBase( dr_handle base, inh_vbase **lnk ){
/*****************************************************/
//if base not in list add return FALSE
    inh_vbase   *cur;

    while( (cur = *lnk) != NULL ){
        if( base <= cur->base ){
            if( base == cur->base ){
                return( FALSE);
            }
            break;
        }
        lnk = &cur->next;
    }
    cur = DCAlloc( sizeof( *cur ) );
    cur->base = base;
    cur->next = *lnk;
    *lnk = cur;
    return( TRUE );
}

static int FreeBases( void *_lnk ){
/***************************************/
//Free bases
    inh_vbase   **lnk = _lnk;
    inh_vbase   *cur;
    inh_vbase   *old;

    cur = *lnk;
    while( cur != NULL ){
        old = cur;
        cur = cur->next;
        DCFree( old );
    }
    *lnk = NULL;
    return 0;
}

static int AMem( dr_handle var, int index, void *d );
static int AInherit( dr_handle inh, int index, void *d );
static DRWLKBLK StrucWlk[DR_WLKBLK_STRUCT] = {
    AMem,
    AInherit,
    AMem,
    AMem,
    NULL
};

static void SetSymHandle( type_wlk *d, imp_sym_handle  *is ){
// Set is with info from com
    is->sclass = d->com.sclass;
    is->imx = d->com.imx;
    is->state = DF_NOT;
    if( d->com.sclass == SYM_ENUM ){
        is->f.einfo = d->com.einfo;
    }else{
        is->f.minfo.root = d->com.root;
        is->f.minfo.inh = d->com.inh;
    }
}

static int AMem( dr_handle var, int index, void *_d ) {
/*****************************************************/
    type_wlk_wlk   *d = _d;
    int            cont;
    imp_sym_handle  *is;
    dr_dbg_handle  saved;

    cont = TRUE;
    is = d->is;
    SetSymHandle( (type_wlk *)d, is );
    is->sym = var;
    switch( index ){
    case 0:
        is->sclass = SYM_MEM;
        break;
    case 2:
        is->sclass = SYM_MEMVAR;      // static member
        break;
    case 3:
        if( DRGetVirtuality( var ) == DR_VIRTUALITY_VIRTUAL  ){
            is->sclass = SYM_VIRTF;   // virtual func

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?