drdecnam.c

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

C
2,033
字号

    EndNode( &( decname->type_bas ), TRUE, loc->entry_st, symtype );
    ListConcat( &( decname->type_bas ), typename );
    EndNode( &( decname->type_bas ), FALSE, 0, DR_SYM_NOT_SYM );

    ListConcat( &( decname->type_bas ), Kwd );

    DWRFREE( typename.s );

    return( decname );
}

static int baseHook( dr_sym_type stype, dr_handle base, char *name,
                     dr_handle notused, void *info )
/*****************************************************************/
{
    BaseSearchInfo  *data;
    String          namestr;

    notused = notused;

    namestr.s = name;
    if( namestr.s == NULL ) {
        namestr.s = DWRALLOC( 1 );
        *namestr.s = '\0';
    }
    namestr.l = strlen( namestr.s );

    data = (BaseSearchInfo *) info;
    if( data->firstTime ) {
        data->firstTime = FALSE;
        ListConcat( &( data->decname->type_inh ), BaseKwd );
    } else {
        ListConcat( &( data->decname->type_inh ), BaseSepKwd );
    }
    EndNode( &( data->decname->type_inh ), TRUE, base, stype );
    ListConcat( &( data->decname->type_inh ), namestr );
    EndNode( &( data->decname->type_inh ), FALSE, 0, DR_SYM_NOT_SYM );

    DWRFREE( namestr.s );

    return( TRUE );
}

BrokenName_T *DecorateBases( BrokenName_T *decname, Loc_T *loc )
/**************************************************************/
{
    BaseSearchInfo  data;

    data.decname = decname;
    data.firstTime = TRUE;
    DRBaseSearch( loc->entry_st, &data, baseHook );
    return( decname );
}


BrokenName_T *DecoratePtrToMember( BrokenName_T *decname, Loc_T *loc )
/********************************************************************/
{
    dr_handle tmp_abbrev;
    dr_handle tmp_entry;
    dr_handle containing_entry;
    String    containing_name;

    tmp_abbrev = loc->abbrev_cr;
    tmp_entry = loc->entry_cr;

    ListConcat( &( decname->var_plg ), SpaceKwd );
    ListConcat( &( decname->var_plg ), PtrKwd );
    ListConcat( &( decname->var_plg ), MemberKwd );

    if( DWRScanForAttrib( &tmp_abbrev, &tmp_entry, DW_AT_containing_type )
        == DW_AT_containing_type ) {

        containing_entry = DWRReadReference( tmp_abbrev, tmp_entry );

        containing_name.s = DRGetName( containing_entry );
        if( containing_name.s == NULL ) {
            containing_name.s = DWRALLOC( 1 );
            *containing_name.s = '\0';
        }

        containing_name.s = strrev( containing_name.s );
        containing_name.l = strlen( containing_name.s );

        EndNode( &( decname->var_plg ), TRUE, containing_entry, DR_SYM_CLASS );
        ListConcat( &( decname->var_plg ), containing_name );
        EndNode( &( decname->var_plg ), FALSE, 0, DR_SYM_NOT_SYM );

        DWRFREE( containing_name.s );
    }

    return( decname );
}

static bool AddArrayIndex( dr_handle abbrev, dr_handle entry, void *data )
/************************************************************************/
// add an array index to the name
{
    unsigned_32 upper_bd;
    unsigned_32 *dataptr;

    if( DWRScanForAttrib( &abbrev, &entry, DW_AT_upper_bound )
        != DW_AT_upper_bound )
        return( FALSE );

    dataptr  = data;
    upper_bd = DWRReadConstant( abbrev, entry );
    *dataptr = upper_bd;
    return( TRUE );
}

static BrokenName_T *DecorateArray( BrokenName_T *decname, Loc_T *loc )
/*********************************************************************/
{
    dr_handle   abbrev;
    dr_handle   entry;
    dr_handle   type_entry;
    Loc_T       type_loc;
    String      tmpStr;
    unsigned_32 upper_bd;

    tmpStr.s = DWRALLOC( 1 );
    *tmpStr.s = '\0';
    tmpStr.l = 0;

    abbrev = loc->abbrev_cr;
    entry = loc->entry_cr;
    if( DWRScanForAttrib( &abbrev, &entry, DW_AT_type ) != DW_AT_type ) {
        DWREXCEPT( DREXCEP_BAD_DBG_INFO );
    }
    type_entry = DWRReadReference( abbrev, entry );
    type_entry =  SkipPCH( type_entry );
    FillLoc( &type_loc, type_entry );
    DecorateType( decname, &type_loc, DW_TAG_padding );

    abbrev = loc->abbrev_cr;
    entry = loc->entry_cr;
    if( DWRScanForAttrib( &abbrev, &entry, DW_AT_count ) == DW_AT_count ) {
        upper_bd = DWRReadConstant( abbrev, entry );
    } else {
        DWRSkipRest( abbrev, &entry );
        DWRAllChildren( entry, AddArrayIndex, &upper_bd );
    }
    if( upper_bd != 0 ) {
        String      bounds;
        char        buf[ 15 ];      /* "[ 2147483647 ]\0" */
        char        indx[ 12 ];     /* "2147483647" */

        buf[ 0 ] = '\0';
        strncat( buf, ArrayLeftKwd.s, ArrayLeftKwd.l );
        ltoa( upper_bd, indx, 10 );
        strcat( buf, indx );
        strncat( buf, ArrayRightKwd.s, ArrayRightKwd.l );

        bounds.s = buf;
        bounds.l = strlen( buf );
        tmpStr.l += bounds.l;
        ReallocStr( &tmpStr );
        strncat( tmpStr.s, bounds.s, bounds.l );
    }
    strrev( tmpStr.s );

    ListConcat( &(decname->var_elg), tmpStr );

    DWRFREE( tmpStr.s );

    return( decname );
}

static void FORDecVariable( BrokenName_T *decname, Loc_T *loc )
/*************************************************************/
{
    String      varname;
    dr_handle   tmp_entry;
    dr_handle   tmp_abbrev;
    bool        inParam;
    dr_handle   type_die;
    Loc_T       type_loc;

    inParam = loc->inParam;

    tmp_abbrev = loc->abbrev_cr;
    tmp_entry = loc->entry_cr;

    GrabName( tmp_abbrev, tmp_entry, &varname );

    EndNode( &( decname->var_bas ), TRUE, loc->entry_st, DR_SYM_VARIABLE );
    ListConcat( &( decname->var_bas ), varname );
    EndNode( &( decname->var_bas ), FALSE, 0, DR_SYM_NOT_SYM );

    DWRFREE( varname.s );

    /*
     *check to see if this is a member of a containing die
     */
    tmp_abbrev = loc->abbrev_cr;    /* reset to start of die / abbrev */
    tmp_entry = loc->entry_cr;

    if( DWRScanForAttrib( &tmp_abbrev, &tmp_entry, DW_AT_containing_type )
                           == DW_AT_containing_type  ){
        dr_handle containing_die;

        containing_die = DWRReadReference( tmp_abbrev, tmp_entry );
        if( containing_die != DW_TAG_padding ) {
            String    containing_name;

            tmp_entry = containing_die;
            tmp_abbrev = DWRGetAbbrev( &tmp_entry );

            GrabName( tmp_abbrev, tmp_entry, &containing_name );
            if( containing_name.s != NULL ) {

                ListConcat( &( decname->var_bas ), MemberKwd );

                EndNode( &( decname->var_bas ), TRUE, containing_die, DR_SYM_CLASS );
                ListConcat( &( decname->var_bas ), containing_name );
                EndNode( &( decname->var_bas ), FALSE, 0, DR_SYM_NOT_SYM );

                DWRFREE( containing_name.s );
            }
        }
    }

    /* check for type information */

    tmp_abbrev = loc->abbrev_cr;
    tmp_entry = loc->entry_cr;

    if( DWRScanForAttrib( &tmp_abbrev, &tmp_entry, DW_AT_type )
        == DW_AT_type ) {

        type_die = DWRReadReference( tmp_abbrev, tmp_entry );
        type_die =  SkipPCH( type_die );
        if( type_die != DW_TAG_padding ) {
            FillLoc( &type_loc, type_die );
            type_loc.inParam = inParam;

            FORDecType( decname, &type_loc );
        }

        FORAddConstVal( decname, loc, &type_loc );
    }
}

static void FORAddConstVal( BrokenName_T *decname, Loc_T *loc, Loc_T *type_loc )
/******************************************************************************/
/* if a variable is constant, decorate as a parameter */
{
    dr_handle   tmp_entry;
    dr_handle   tmp_abbrev;
    unsigned_8  *buf;
    unsigned    form;
    unsigned    len;
    char        *charBuf;
    char        numBuf1[ 32 ];  // hold text for number
    char        numBuf2[ 32 ];  // hold text for number
    String      value;
    unsigned_32 encoding;

    tmp_abbrev = loc->abbrev_cr;
    tmp_entry = loc->entry_cr;

    if( DWRScanForAttrib( &tmp_abbrev, &tmp_entry, DW_AT_const_value )
        == DW_AT_const_value ) {
        ListConcat( &( decname->type_plg ), FORParamKwd );

        form = DWRVMReadULEB128( &tmp_abbrev );
        if( form == DW_FORM_indirect ) {
            form = DWRVMReadULEB128( &tmp_entry );
        }

        switch( form ) {
        case DW_FORM_block1:
            len = DWRVMReadByte( tmp_entry );
            tmp_entry += sizeof(unsigned_8);
            ReadBlock( &buf, tmp_entry, len );
            break;
        case DW_FORM_block2:
            len = DWRVMReadWord( tmp_entry );
            tmp_entry += sizeof(unsigned_16);
            ReadBlock( &buf, tmp_entry, len );
            break;
        case DW_FORM_block4:
            len = DWRVMReadWord( tmp_entry );
            tmp_entry += sizeof(unsigned_32);
            ReadBlock( &buf, tmp_entry, len );
            break;
        case DW_FORM_block:
            len = DWRVMReadULEB128( &tmp_entry );
            ReadBlock( &buf, tmp_entry, len );
            break;
        default:
            DWREXCEPT( DREXCEP_BAD_DBG_INFO );
        }

        if( type_loc->tag == DW_TAG_string_type ) {
            charBuf = DWRALLOC( len + 3 );      // 2 * "'" + \0
            if( charBuf == NULL ) {
                DWREXCEPT( DREXCEP_OUT_OF_MMEM );
            }
            charBuf[ 0 ] = '\'';
            strncat( charBuf + 1, (char *)buf, len );
            strcat( charBuf, "'" );
        } else {
            charBuf = DWRALLOC( 64 );
            if( charBuf == NULL ) {
                DWREXCEPT( DREXCEP_OUT_OF_MMEM );
            }

            tmp_abbrev = type_loc->abbrev_cr;
            tmp_entry = type_loc->entry_cr;
            if( DWRScanForAttrib( &tmp_abbrev, &tmp_entry, DW_AT_encoding )
                == DW_AT_encoding ) {
                encoding = DWRReadConstant( tmp_abbrev, tmp_entry );
            } else {
                DWREXCEPT( DREXCEP_BAD_DBG_INFO );
            }

            switch( encoding ) {
            case DW_ATE_address:
                // NYI
                break;
            case DW_ATE_boolean:
                if( *buf ) {
                    strcpy( charBuf, ".TRUE." );
                } else {
                    strcpy( charBuf, ".FALSE." );
                }
                break;
            case DW_ATE_complex_float:
                switch( len ) {
                case (2 * sizeof(float)):
                    gcvt( *(float *)buf, 5, numBuf1 );
                    gcvt( *((float *)buf + 1), 5, numBuf2 );
                    break;
                case (2 * sizeof(double)):
                    gcvt( *(double *)buf, 5, numBuf1 );
                    gcvt( *((double *)buf + 1), 5, numBuf2 );
                    break;
                default:
                    DWREXCEPT( DREXCEP_BAD_DBG_INFO );
                }
                strcpy( charBuf, "(" );
                strcat( charBuf, numBuf1 );
                strcat( charBuf, "," );
                strcat( charBuf, numBuf2 );
                strcat( charBuf, ")" );
                break;
            case DW_ATE_float:
                switch( len ) {
                case sizeof(float):
                    gcvt( *(float *)buf, 5, charBuf );
                    break;
                case sizeof(double):
                    gcvt( *(double *)buf, 5, charBuf );
                    break;
                default:
                    DWREXCEPT( DREXCEP_BAD_DBG_INFO );
                }
                break;
            case DW_ATE_signed:
                switch( len ) {
                case sizeof(signed_32):
                    ltoa( *(signed_32 *)buf, charBuf, 10 );
                    break;
                case sizeof(signed_16):
                    ltoa( *(signed_16 *)buf, charBuf, 10 );
                    break;
                case sizeof(signed_8):
                    ltoa( *(signed_8 *)buf, charBuf, 10 );
                    break;
                default:
                    DWREXCEPT( DREXCEP_BAD_DBG_INFO );
                }
                break;
            case DW_ATE_unsigned:
                switch( len ) {
                case sizeof(unsigned_32):
                    ultoa( *(unsigned_32 *)buf, charBuf, 10 );
                    break;
                case sizeof(unsigned_16):
                    ultoa( *(unsigned_16 *)buf, charBuf, 10 );
                    break;
                case sizeof(unsigned_8):
                    ultoa( *(unsigned_8 *)buf, charBuf, 10 );
                    break;
                default:
                    DWREXCEPT( DREXCEP_BAD_DBG_INFO );
                }
                break;
            case DW_ATE_unsigned_char:
            case DW_ATE_signed_char:
                charBuf[ 0 ] = '\'';
                charBuf[ 1 ] = *(unsigned_8 *)buf;
                charBuf[ 2 ] = '\'';
                charBuf[ 3 ] = '\'';
                break;
            default:
                DWREXCEPT( DREXCEP_BAD_DBG_INFO );
            }
        }

        value.s = strrev( charBuf );
        value.l = strlen( charBuf );
        ListConcat( &(decname->var_elg), value );
        ListConcat( &(decname->var_elg), FOREqualKwd );

⌨️ 快捷键说明

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