drdecnam.c

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

C
2,033
字号

        DWRFREE( buf );
        DWRFREE( charBuf );
    }
}

static void ReadBlock( unsigned_8 **buf, dr_handle entry, unsigned len )
/**********************************************************************/
{
    unsigned_8  *mbuf;

    *buf = DWRALLOC( len );
    if( *buf == NULL ) {
        DWREXCEPT( DREXCEP_OUT_OF_MMEM );
    }

    mbuf = *buf;
    DWRVMRead( entry, mbuf, len );
}

static void FORDecParam( BrokenName_T *decname, Loc_T *loc )
/**********************************************************/
{
    loc->inParam = TRUE;
    FORDecVariable( decname, loc );
}

static void FORDecMember( BrokenName_T *decname, Loc_T *loc )
/***********************************************************/
{
    String    tmp_str;

    FORDecVariable( decname, loc );

    ListConcat( &( decname->var_bas ), FORMemberKwd );
    tmp_str.s = DRGetName( loc->parent );
    if( tmp_str.s == NULL ) {
        tmp_str.s = DWRALLOC( 1 );
        *tmp_str.s = '\0';
    }
    tmp_str.s = strrev( tmp_str.s );
    tmp_str.l = strlen( tmp_str.s );
    EndNode( &( decname->var_bas ), TRUE, loc->parent, DR_SYM_CLASS );
    ListConcat( &( decname->var_bas ), tmp_str );
    EndNode( &( decname->var_bas ), FALSE, 0, DR_SYM_NOT_SYM );
    DWRFREE( tmp_str.s );
}

static int FORAddParam( dr_handle entry, int index, void *data )
/**************************************************************/
// add an array index to the name
{
    List_T      *list;
    List_T      add;
    Loc_T       loc;

    BrokenName_T  decstruct = Empty_Broken_Name;

    index = index;
    list = (List_T *)data;

    FillLoc( &loc, entry );

    FORDecParam( &decstruct, &loc );
    add = FormList( &decstruct );

    if( list->head == NULL ) {
        list->head = add.head;
        list->tail = add.tail;
    } else {
        EndNode( list, FALSE, 0, DR_SYM_NOT_SYM );
        ListConcat( list, FORParmSepKwd );
        list->tail->next = add.head;
        list->tail = add.tail;
    }

    return( TRUE );
}

static void FORDecSubprogram( BrokenName_T *decname, Loc_T *loc )
/***************************************************************/
{
    static unsigned_16 WalkTags[] = { DW_TAG_formal_parameter, 0 };
    static DRWLKBLK     WalkFns[] = { &FORAddParam, NULL };

    String      func_name;
    List_T      parms = { NULL, NULL, LIST_TAIL };
    dr_handle   tmp_abbrev;
    dr_handle   tmp_entry;
    Loc_T       type_loc;

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

    GrabName( tmp_abbrev, tmp_entry, &func_name );

    if( strcmp( func_name.s, FORMainProgMatch ) == 0 ) {
        EndNode( &( decname->var_bas ), TRUE, loc->entry_st, DR_SYM_FUNCTION );
        ListConcat( &( decname->var_bas ), func_name );
        EndNode( &( decname->var_bas ), FALSE, 0, DR_SYM_NOT_SYM );

        DWRFREE( func_name.s );

        return;
    }

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

    DWRFREE( func_name.s );

    tmp_abbrev = loc->abbrev_cr;
    tmp_entry = loc->entry_cr;
    if( DWRScanForAttrib( &tmp_abbrev, &tmp_entry, DW_AT_type ) == DW_AT_type ) {
        dr_handle type_entry = DWRReadReference( tmp_abbrev, tmp_entry );

        type_entry =  SkipPCH( type_entry );
        if( type_entry != DW_TAG_padding ) {
            FillLoc( &type_loc, type_entry );
            FORDecType( decname, &type_loc );
        }
        ListConcat( &decname->var_plg, FORFuncKwd );
    } else {
        ListConcat( &decname->var_plg, FORSubprogramKwd );
    }

    DWRWalkChildren( loc->entry_st, WalkTags, WalkFns, &parms );

    if( parms.head != NULL ) {
        ListConcat( &decname->func_plg, FORFuncStartKwd );
        ListConcat( &decname->func_elg, FORFuncEndKwd );
        decname->func_bas.head = parms.head;
        decname->func_bas.tail = parms.tail;
    }
}

static void FORDecEntryPoint( BrokenName_T *decname, Loc_T *loc )
/***************************************************************/
{
    String      func_name;
    List_T      parms = { NULL, NULL, LIST_TAIL };
    dr_handle   tmp_abbrev;
    dr_handle   tmp_entry;
    unsigned_16 WalkTags[] = { DW_TAG_formal_parameter, 0 };
    DRWLKBLK    WalkFns[] = { &FORAddParam, NULL };

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

    GrabName( tmp_abbrev, tmp_entry, &func_name );

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

    DWRFREE( func_name.s );

    ListConcat( &decname->var_plg, FOREntryPointKwd );

    DWRSkipRest( tmp_abbrev, &tmp_entry );
    DWRWalkChildren( loc->entry_st, WalkTags, WalkFns, &parms );

    if( parms.head != NULL ) {
        ListConcat( &decname->func_plg, FORFuncStartKwd );
        ListConcat( &decname->func_elg, FORFuncEndKwd );
        decname->func_bas.head = parms.head;
        decname->func_bas.tail = parms.tail;
    }
}

static void FORDecStructure( BrokenName_T *decname, Loc_T *loc )
/**************************************************************/
{
    String  strucName;

    GrabName( loc->abbrev_cr, loc->entry_cr, &strucName );

    ListConcat( &( decname->type_bas ), SpaceKwd );
    ListConcat( &( decname->type_bas ), FORSlashKwd );

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

    ListConcat( &( decname->type_bas ), FORSlashKwd );
    ListConcat( &( decname->type_bas ), FORStructKwd );

    DWRFREE( strucName.s);
}

static int FORAddNameListItem( dr_handle entry, int index, void *data )
/*********************************************************************/
{
    BrokenName_T    *decname = (BrokenName_T *)data;
    String          itemName;
    Loc_T           loc;
    dr_handle       mod = entry;
    dr_handle       abbrev;
    dr_handle       item;

    index = index;
    abbrev = DWRGetAbbrev( &mod );
    if( DWRScanForAttrib( &abbrev, &mod, DW_AT_namelist_item ) != DW_AT_namelist_item ) {
        DWREXCEPT( DREXCEP_BAD_DBG_INFO );
    }
    item = DWRReadReference( abbrev, mod );

    FillLoc( &loc, item );

    if( decname->type_elg.head != NULL ) {
        ListConcat( &( decname->type_elg ), FORSepKwd );
    }

    GrabName( loc.abbrev_cr, loc.entry_cr, &itemName );
    strrev( itemName.s );

    EndNode( &( decname->type_elg ), TRUE, loc.entry_st, DR_SYM_VARIABLE );
    ListConcat( &( decname->type_elg ), itemName );
    EndNode( &( decname->type_elg ), FALSE, 0, DR_SYM_NOT_SYM );

    DWRFREE( itemName.s );

    return( TRUE );
}

static void FORDecNameList( BrokenName_T *decname, Loc_T *loc )
/*************************************************************/
{
    static unsigned_16 WalkTags[] = { DW_TAG_namelist_item, 0 };
    static DRWLKBLK     WalkFns[] = { &FORAddNameListItem, NULL };

    String strucName;

    GrabName( loc->abbrev_cr, loc->entry_cr, &strucName );

    ListConcat( &( decname->type_bas ), SpaceKwd );
    ListConcat( &( decname->type_bas ), FORSlashKwd );

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

    ListConcat( &( decname->type_bas ), FORSlashKwd );
    ListConcat( &( decname->type_bas ), FORNameListKwd );

    DWRFREE( strucName.s);

    DWRWalkChildren( loc->entry_st, WalkTags, WalkFns, decname );
}

static void FORDecRecord( BrokenName_T *decname, Loc_T *loc )
/***********************************************************/
{
    String  strucName;

    GrabName( loc->abbrev_cr, loc->entry_cr, &strucName );

    ListConcat( &( decname->type_bas ), SpaceKwd );
    ListConcat( &( decname->type_bas ), FORSlashKwd );

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

    ListConcat( &( decname->type_bas ), FORSlashKwd );
    ListConcat( &( decname->type_bas ), FORRecordKwd );

    DWRFREE( strucName.s);
}

static void FORDecUnion( BrokenName_T *decname, Loc_T *loc )
/**********************************************************/
{
    ListConcat( &( decname->type_bas ), SpaceKwd );

    EndNode( &( decname->type_bas ), TRUE, loc->entry_st, DR_SYM_CLASS );
    ListConcat( &( decname->type_bas ), FORUnionKwd );
    EndNode( &( decname->type_bas ), FALSE, 0, DR_SYM_NOT_SYM );
}

typedef struct FORArrIndexInf_S {
    String  *bounds;
    bool    inParam;
} FORArrIndexInf;

static bool FORAddArrayIndex( dr_handle abbrev, dr_handle entry, void *data )
/***************************************************************************/
// add an array index to the name
{
    dr_handle       tmp_abbrev;
    dr_handle       tmp_entry;
    signed_32       upper_bd;
    signed_32       lower_bd;
    bool            inParam;
    String          *bounds;
    String const    *add;
    char            buf[ 64 ];      /* "-4294967295:4294967295\0" */

    bounds = ((FORArrIndexInf *)data)->bounds;
    inParam = ((FORArrIndexInf *)data)->inParam;

    tmp_abbrev = abbrev;
    tmp_entry = entry;
    if( DWRScanForAttrib( &tmp_abbrev, &tmp_entry, DW_AT_lower_bound )
                != DW_AT_lower_bound ) {
        lower_bd = 1;   // default for FORTRAN
    } else {
        lower_bd = (signed_32)DWRReadConstant( tmp_abbrev, tmp_entry );
    }

    tmp_abbrev = abbrev;
    tmp_entry = entry;
    if( DWRScanForAttrib( &tmp_abbrev, &tmp_entry, DW_AT_upper_bound )
                != DW_AT_upper_bound ) {
        return( TRUE ); // not a subrange type
    } else {
        upper_bd = (signed_32)DWRReadConstant( tmp_abbrev, tmp_entry );
    }

    /* if empty, add "(" */
    if( bounds->l == 0 ) {
        add = &FORArrayLeftKwd;
    } else {
        add = &FORSepKwd;
    }
    bounds->l += add->l;
    ReallocStr( bounds );
    strncat( bounds->s, add->s, add->l );

    buf[ 0 ] = '\0';

    if( upper_bd < lower_bd ) {
        if( inParam ) {
            add = &FORAssumeArrKwd;
        } else {
            add = &FORAllocArrKwd;
        }
        bounds->l += add->l;
        ReallocStr( bounds );
        strncat( bounds->s, add->s, add->l );
    } else {
        if( lower_bd != 1 ) {
            ltoa( lower_bd, buf, 10 );
            bounds->l += strlen( buf ) + 1;
            ReallocStr( bounds );
            strcat( bounds->s, buf );
            strcat( bounds->s, ":" );
        }
        ltoa( upper_bd, buf, 10 );
        bounds->l += strlen( buf );
        ReallocStr( bounds );
        strcat( bounds->s, buf );
    }

    return( TRUE );
}

static void FORDecArray( BrokenName_T *decname, Loc_T *loc )
/**********************************************************/
{
    dr_handle       abbrev;
    dr_handle       entry;
    dr_handle       type_entry;
    Loc_T           type_loc;
    String          tmpStr;
    FORArrIndexInf  data;

    data.bounds = &tmpStr;
    data.inParam = loc->inParam;

    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 );
    FORDecType( decname, &type_loc );

    DWRSkipRest( abbrev, &entry );
    DWRAllChildren( entry, FORAddArrayIndex, &data );

    tmpStr.l += FORArrayRightKwd.l;
    ReallocStr( &tmpStr );
    strncat( tmpStr.s, FORArrayRightKwd.s, FORArrayRightKwd.l );

    strrev( tmpStr.s );

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

    DWRFREE( tmpStr.s );
}

static void FORDecType( BrokenName_T *decname, Loc_T *loc )
/*********************************************************/
{
    dr_handle   tmp_entry;
    dr_handle   tmp_abbrev;
    dr_handle   next_die;

⌨️ 快捷键说明

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