dftype.c

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

C
1,391
字号
        }else if( !DRIsSymDefined( var ) ){
            is->sclass = SYM_MEMF;    // memfunc decl
        }else{
           is->sclass = SYM_MEMVAR;   // inlined defn treat like a var
        }
        break;
    }
    saved = DRGetDebug();
    d->wr = d->wk( d->com.ii, SWI_SYMBOL, is, d->com.d );
    DRSetDebug( saved );
    if( d->wr != WR_CONTINUE ){
        cont = FALSE;
    }
    return( cont );
}

static int AInherit( dr_handle inh, int index, void *_d ) {
/*************************************************/
//TODO: Need to track virtual base as not to visit same place twice
    type_wlk_wlk *d = _d;
    int         cont;
    dr_handle   btype;
    dr_handle   old_inh;
    imp_sym_handle  *is;
    dr_dbg_handle  saved;
    walk_result wr;

    index = index;
    cont = TRUE;

    btype = DRGetTypeAT( inh );
    btype =  DRSkipTypeChain( btype ); /* skip modifiers and typedefs */
    if(  DRGetVirtuality( inh ) == DR_VIRTUALITY_VIRTUAL  ){
        if( !AddBase( btype, &d->com.vbase ) ){
            return( cont );
        }
    }
    is = d->is;
    SetSymHandle( (type_wlk *)d, is );
    is->sym = inh;
    is->sclass = SYM_MEM;     //  treat inherit like a var
    saved = DRGetDebug();
    wr = d->wk( d->com.ii, SWI_INHERIT_START, is, d->com.d );
    DRSetDebug( saved );
    if( wr == WR_CONTINUE ) {
        old_inh = d->com.inh;
        d->com.inh = inh;
        DRWalkStruct( btype, StrucWlk, d );
        d->com.inh = old_inh;
        saved = DRGetDebug();
        d->wk( d->com.ii, SWI_INHERIT_END, NULL, d->com.d );
        DRSetDebug( saved );
        if( d->wr != WR_CONTINUE ){
            cont = FALSE;
        }
    }
    return( cont );
}


static int AMemLookup( dr_handle var, int index, void *d );
static int AInheritLookup( dr_handle inh, int index, void *d );
static DRWLKBLK StrucWlkLookup[DR_WLKBLK_STRUCT] = {
    AMemLookup,
    AInheritLookup,
    AMemLookup,
    AMemLookup,
    NULL
};

static int AMemLookup( dr_handle var, int index, void *_d ){
/*************************************************/
    type_wlk_lookup  *d = _d;
    imp_sym_handle   *is;
    char   *name;
    int    len;

    name =  DRGetName( var );
    if( name == NULL ){
        DCStatus( DS_FAIL );
        return( FALSE );
    }
    len = strlen( name );
    if( len == d->li->name.len && d->comp(name, d->li->name.start,len)==0 ) {
        is = DCSymCreate( d->com.ii, d->com.d );
        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
            }else if( !DRIsSymDefined( var ) ){
                is->sclass = SYM_MEMF;    // memfunc decl
            }else{
               is->sclass = SYM_MEMVAR;   // inlined defn treat like a var
            }
            break;
        }
        d->sr = SR_EXACT;
    }
    DCFree( name );
    return( TRUE );
}

static int AInheritLookup( dr_handle inh, int index, void *_d ){
/*************************************************/
//Push inherit handle and search
    type_wlk_lookup *d = _d;
    dr_handle btype;
    dr_handle old_inh;

    index = index;
    btype = DRGetTypeAT( inh );
    btype =  DRSkipTypeChain( btype ); /* skip modifiers and typedefs */
    if(  DRGetVirtuality( inh ) == DR_VIRTUALITY_VIRTUAL ){
        if( !AddBase( btype, &d->com.vbase ) ){
            return( TRUE );
        }
    }
    old_inh = d->com.inh;
    d->com.inh = inh;
    DRWalkStruct( btype, StrucWlkLookup, d );
    d->com.inh = old_inh;
    return( TRUE );
}

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

    index = index;
    cont = TRUE;
    is = d->is;
    SetSymHandle( (type_wlk *)d, is );
    is->sym = var;
    saved = DRGetDebug();
    d->wr = d->wk( d->com.ii, SWI_SYMBOL, is, d->com.d );
    DRSetDebug( saved );
    if( d->wr != WR_CONTINUE ){
        cont = FALSE;
    }
    return( cont );
}

static int AEnumMemLookup( dr_handle var, int index, void *_d ) {
/***************************************************************/
    type_wlk_lookup  *d = _d;
    imp_sym_handle   *is;
    char   *name;
    int    len;

    index = index;
    name =  DRGetName( var );
    if( name == NULL ){
        DCStatus( DS_FAIL );
        return( FALSE );
    }
    len = strlen( name );
    if( len == d->li->name.len && d->comp(name, d->li->name.start,len)==0 ) {
        is = DCSymCreate( d->com.ii, d->com.d );
        SetSymHandle( (type_wlk *)d, is );
        is->sym = var;
        d->sr = SR_EXACT;
    }
    DCFree( name );
    return( TRUE );
}

extern walk_result WalkTypeSymList( imp_image_handle *ii, imp_type_handle *it,
                 IMP_SYM_WKR *wk, imp_sym_handle *is, void *d ){
    dr_handle       btype;
    type_wlk_wlk    df;
    df_cleaner      cleanup;

    DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
    if( it->state == DF_NOT ){
        if(  DRGetTypeInfo( it->type, &it->typeinfo ) ){
            it->state = DF_SET;
        }
    }
    if( it->state == DF_NOT ){
        return( WR_STOP );
    }
    df.com.imx = it->imx;
    df.com.ii = ii;
    df.com.d = d;
    df.com.root = it->type;
    df.com.inh = NULL;
    df.com.vbase = NULL;
    cleanup.rtn = FreeBases;   //push cleanup
    cleanup.d = &df.com.vbase;
    cleanup.prev = Cleaners;
    Cleaners = &cleanup;
    btype = DRSkipTypeChain( it->type );
    df.is = is;
    df.wk = wk;
    df.wr = WR_CONTINUE;
    switch( it->typeinfo.kind ){
    case DR_TYPEK_ENUM:
        df.com.sclass = SYM_ENUM;
        df.com.einfo.size = it->typeinfo.size;
        df.com.einfo.sign = it->typeinfo.modifier.sign;
        DRWalkEnum( btype, AEnumMem, &df );
        break;
    case DR_TYPEK_STRUCT:
    case DR_TYPEK_UNION:
    case DR_TYPEK_CLASS:
        df.com.sclass = SYM_MEM;
        DRWalkStruct( btype, StrucWlk, &df );
        break;
    default:
        DCStatus( DS_ERR | DS_BAD_PARM );
        df.wr = WR_STOP;
    }
    FreeBases( &df.com.vbase ); // free virtual base list
    Cleaners = cleanup.prev; // pop cleanup
    return( df.wr );
}

extern search_result SearchMbr( imp_image_handle *ii, imp_type_handle *it,
                 lookup_item *li, void *d ){
//Search for matching lookup item
    dr_handle       btype;
    type_wlk_lookup df;
    df_cleaner      cleanup;


    DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
    if( it->state == DF_NOT ){
        if(  DRGetTypeInfo( it->type, &it->typeinfo ) ){
            it->state = DF_SET;
        }
    }
    if( it->state == DF_NOT ){
        return( SR_NONE );
    }
    df.com.imx = it->imx;
    df.com.ii = ii;
    df.com.d = d;
    df.com.root = it->type;
    df.com.inh = NULL;
    df.com.vbase = NULL;
    cleanup.rtn = FreeBases;   //push cleanup
    cleanup.d = &df.com.vbase;
    cleanup.prev = Cleaners;
    Cleaners = &cleanup;
    btype = DRSkipTypeChain( it->type );
    if( li->case_sensitive ) {
        df.comp = memcmp;
    } else {
        df.comp = memicmp;
    }
    df.li = li;
    df.sr = SR_NONE;
    switch( it->typeinfo.kind ){
    case DR_TYPEK_ENUM:
        df.com.sclass = SYM_ENUM;
        df.com.einfo.size = it->typeinfo.size;
        df.com.einfo.sign = it->typeinfo.modifier.sign;
        DRWalkEnum( btype, AEnumMemLookup, &df );
        break;
    case DR_TYPEK_STRUCT:
    case DR_TYPEK_UNION:
    case DR_TYPEK_CLASS:
        df.com.sclass = SYM_MEM;
        DRWalkStruct( btype, StrucWlkLookup, &df );
        break;
    default:
        DCStatus( DS_ERR | DS_BAD_PARM );
        df.sr = SR_FAIL;
    }
    FreeBases( &df.com.vbase ); // free virtual base list
    Cleaners = cleanup.prev; // pop cleanup
    return( df.sr );
}
/*********************************************/
/*  Search for a derived type then eval loc  */
/*********************************************/
typedef struct inh_path {
    struct inh_path *next;
    dr_handle        inh;
}inh_path;

typedef struct type_wlk_inherit {
    imp_image_handle *ii;
    dr_handle         dr_derived;
    location_context *lc;
    address          *addr;
    inh_path         *head;
    inh_path         **lnk;
    dip_status       wr;
    bool             cont;
}type_wlk_inherit;

static int AInhFind( dr_handle inh, int index, void *df );
static DRWLKBLK InheritWlk[DR_WLKBLK_STRUCT] = {
    NULL,
    AInhFind,
    NULL,
    NULL,
    NULL,
};


static int AInhFind( dr_handle inh, int index, void *_df ){
/*************************************************/
//Push inherit handle and search
    type_wlk_inherit *df = _df;
    dr_handle       dr_derived;
    inh_path        head, *curr, **old_lnk;

    index = index;
    head.inh = inh;
    head.next = NULL;
    old_lnk = df->lnk;
    *df->lnk  = &head;
    df->lnk = &head.next;
    dr_derived = DRGetTypeAT( inh );        /* get base type */
    if( dr_derived == df->dr_derived ){
        curr = df->head;
        while( curr != NULL ){
            df->wr = EvalLocAdj( df->ii, df->lc, curr->inh, df->addr );
            if( df->wr != DS_OK )break;
            curr = curr->next;
        }
        df->cont = FALSE;
    }else{
        dr_derived =  DRSkipTypeChain( dr_derived); /* skip modifiers and typedefs */
        DRWalkStruct( dr_derived, InheritWlk, df ); /* walk struct looking for inheritance */
    }
    df->lnk = old_lnk;
    return( df->cont );
}

extern dip_status  DFBaseAdjust( imp_image_handle *ii,
                                dr_handle base, dr_handle derived,
                                location_context *lc, address *addr ){
    type_wlk_inherit df;
    dr_handle        dr_base;

    df.ii = ii;
    df.dr_derived = derived;
    df.lc =  lc;
    df.addr = addr;
    df.head = NULL;
    df.lnk  = &df.head;
    df.wr = DS_FAIL;
    df.cont = TRUE;
    dr_base =  DRSkipTypeChain( base );   /* skip modifiers and typedefs */
    DRWalkStruct( dr_base, InheritWlk, &df ); /* walk struct looking for inheritance */
    return( df.wr );
}

dip_status      DIPENTRY DIPImpTypeThunkAdjust( imp_image_handle *ii,
                        imp_type_handle *base, imp_type_handle *derived,
                        location_context *lc, address *addr )
{
    /*
        When you convert a pointer to a C++ class to a pointer at one
        of its derived classes you have to adjust the pointer so that
        it points at the start of the derived class. The 'derived' type
        may not actually be a derived type of 'base'. In that case, return
        DS_FAIL and nothing to 'addr'. If it is a derived type, let 'disp'
        be the displacement between the 'base' type and the 'derived' type.
        You need to do the following. "addr->mach.offset += disp;".
    */
    return( DFBaseAdjust( ii, base->type, derived->type, lc, addr ) );
}

unsigned DIPENTRY DIPImpTypeName( imp_image_handle *ii, imp_type_handle *it,
                unsigned num, symbol_type *tag, char *buff, unsigned max )
{
    /*
        Given the imp_type_handle, copy the name of the type into 'buff'.
        Do not copy more than 'max' - 1 characters into the buffer and
        append a trailing '\0' character. Return the real length
        of the type name (not including the trailing '\0' character) even
        if you had to truncate it to fit it into the buffer. If something
        went wrong and you can't get the type name, call DCStatus and
        return zero. NOTE: the client might pass in zero for 'max'. In that
        case, just return the length of the module name and do not attempt
        to put anything into the buffer.

        Since there can be a "string" of typedef names associated with
        a type_handle, the 'num' parm indicates which one of the names
        the client wants returned. Zero is the first type name, one is
        the second, etc. Fill in '*tag' with ST_ENUM_TAG, ST_UNION_TAG,
        ST_STRUCT_TAG, ST_CLASS_TAG if the name is a enum, union, struct,
        or class tag name respectively. If not, set '*tag' to ST_NONE.

        If the type does not have a name, return zero.
    */
    char        *name;
    dr_handle   dr_type;
    dr_typeinfo typeinfo;
    unsigned    len;

    DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
    ++num;
    len = 0;
    dr_type = it->type;
    while( dr_type != NULL ){
        name =  DRGetName( dr_type );
        if( name != NULL ){
            if(  --num == 0 )break;
            DCFree( name );
        }
        dr_type = DRGetTypeAT( dr_type );
    }
    if( num == 0 ){
        DRGetTypeInfo( dr_type, &typeinfo );
        switch( typeinfo.kind ){
        case DR_TYPEK_ENUM:
            *tag = ST_ENUM_TAG;
            break;
        case DR_TYPEK_STRUCT:
            *tag = ST_STRUCT_TAG;
            break;
        case DR_TYPEK_UNION:
            *tag = ST_UNION_TAG;
            break;
        case DR_TYPEK_CLASS:
            *tag = ST_CLASS_TAG;
            break;
        default:
            *tag = ST_NONE;
            break;
        }
        len = NameCopy( buff, name, max );
        DCFree( name );
    }
    return( len );
}

dip_status DIPENTRY DIPImpTypeAddRef( imp_image_handle *ii, imp_type_handle *it )
{
    ii=ii;
    it=it;
    return(DS_OK);
}

dip_status DIPENTRY DIPImpTypeRelease( imp_image_handle *ii, imp_type_handle *it )
{
    ii=ii;
    it=it;
    return(DS_OK);
}

dip_status DIPENTRY DIPImpTypeFreeAll( imp_image_handle *ii )
{
    ii=ii;
    return(DS_OK);
}

⌨️ 快捷键说明

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