drdecnam.c

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

C
2,033
字号
    switch( loc->tag ) {
    case DW_TAG_formal_parameter:
        FORDecParam( decname, loc );
        break;

    case DW_TAG_variable:
        FORDecVariable( decname, loc );
        break;

    case DW_TAG_member:
        if( loc->parent != NULL ) {
            FORDecMember( decname, loc );
        } else {
            FORDecVariable( decname, loc );
        }
        break;

    case DW_TAG_subprogram:
        FORDecSubprogram( decname, loc );
        break;

    case DW_TAG_entry_point:
        FORDecEntryPoint( decname, loc );
        break;

    case DW_TAG_structure_type:
        FORDecStructure( decname, loc );
        break;

    case DW_TAG_namelist:
        FORDecNameList( decname, loc );
        break;

    case DW_TAG_union_type:
        FORDecUnion( decname, loc );
        break;

    case DW_TAG_common_block:
        FORDecCommon( decname, loc );
        break;

    default:
        DWREXCEPT( DREXCEP_DWARF_LIB_FAIL );
    }
}

static void BuildCList( BrokenName_T *decname, Loc_T *loc )
/*********************************************************/
{
    switch( loc->tag ) {
    case DW_TAG_formal_parameter:
    case DW_TAG_variable:
        DecorateVariable( decname, loc );
        break;

    case DW_TAG_member:
        if( loc->parent != NULL ) {
            DecorateMember( decname, loc );
        } else {
            DecorateVariable( decname, loc );
        }
        break;

    case DW_TAG_typedef:
        DecorateTypedef( decname, loc );
        break;

    case DW_TAG_label:
        DecorateLabel( decname, loc );
        break;

    case DW_TAG_subprogram:
        DecorateFunction( decname, loc );
        break;

    case DW_TAG_enumeration_type:
        DecorateCompoundType( decname, loc, EnumKwd, DR_SYM_ENUM );
        break;

    case DW_TAG_class_type:
        DecorateCompoundType( decname, loc, ClassKwd, DR_SYM_CLASS );
        DecorateBases( decname, loc );
        break;

    case DW_TAG_structure_type:
        DecorateCompoundType( decname, loc, StructKwd, DR_SYM_CLASS );
        DecorateBases( decname, loc );
        break;

    case DW_TAG_union_type:
        DecorateCompoundType( decname, loc, UnionKwd, DR_SYM_CLASS );
        break;

    case DW_TAG_WATCOM_namespace:
        DecorateNameSpace( decname, loc );
        break;
    default:
        DWREXCEPT( DREXCEP_DWARF_LIB_FAIL );
    }
}

static void GrabName( dr_handle abbrev, dr_handle entry, String *name )
/*********************************************************************/
// read a name, setting length and reversing
{
    name->s = DWRGetName( abbrev, entry );
    if( name->s == NULL ) {
        name->s = DWRALLOC( 1 );
        *name->s = '\0';
    }
    name->l = strlen( name->s );
    strrev( name->s );
}

static void GetClassName( dr_handle   entry,
                          String      *containing_name )
/******************************************************/
{  //try and skip PCH
    dr_handle   abbrev;
    dr_handle   tmp_entry;
    dw_tagnum   tag;
    char        *name;

    name = NULL;
    while( entry != NULL ){
        tmp_entry = entry;
        abbrev = DWRVMReadULEB128( &tmp_entry );
        abbrev = DWRLookupAbbrev( tmp_entry, abbrev );
        tag = DWRVMReadULEB128( &abbrev );
        abbrev++;           // skip the child pointer.
        name = DWRGetName( abbrev, tmp_entry );
        if( name != NULL ) break;
        if( tag != DW_TAG_typedef ) break;
        entry = DRGetTypeAT( entry );
    }
    if( name == NULL ) {
        name = DWRALLOC( 1 );
        *name = '\0';
    }
    strrev( name );
    containing_name->s = name;
    containing_name->l = strlen( name );
}

static dr_handle SkipPCH( dr_handle entry )
/*****************************************/
{  //try and skip PCH
    dr_handle   abbrev;
    dr_handle   tmp_entry;
    dw_tagnum   tag;
    dw_atnum    attrib;

    while( entry != NULL ) {
        tmp_entry = entry;
        abbrev = DWRVMReadULEB128( &tmp_entry );
        abbrev = DWRLookupAbbrev( tmp_entry, abbrev );
        tag = DWRVMReadULEB128( &abbrev );
        if( tag != DW_TAG_typedef ) break;
        abbrev++;           // skip the child pointer.
        for( ;; ) {
            attrib = DWRVMReadULEB128( &abbrev );
            if( attrib == DW_AT_name ) break;
            if( attrib == 0 ) break;
        }
        if( attrib != 0 ) break;
        entry = DRGetTypeAT( entry );
    }
    return( entry );
}

/*
 * decorate the name of a DW_TAG_variable die.
 */

static BrokenName_T *DecorateVariable( BrokenName_T *decname, Loc_T *loc )
/************************************************************************/
{
    String      varname;
    dr_handle   tmp_entry;
    dr_handle   tmp_abbrev;

    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 if external */
    if( DWRScanForAttrib( &tmp_abbrev, &tmp_entry, DW_AT_external )
        == DW_AT_external ) {
        if( DWRReadConstant( tmp_abbrev, tmp_entry ) ) {
            ListConcat( &( decname->dec_plg ), ExternKwd );
        }
    }

    /*
     *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;

            GetClassName( containing_die, &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 ) {
        dr_handle type_die;

        type_die = DWRReadReference( tmp_abbrev, tmp_entry );
        type_die =  SkipPCH( type_die );
        if( type_die != DW_TAG_padding ) {
            Loc_T type_loc;

            FillLoc( &type_loc, type_die );

            DecorateType( decname, &type_loc, DW_TAG_padding );
        }
    }

    return( decname );
}

/*
 * decorate a member of a class or struct -- depends on loc.parent
 */

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

    DecorateVariable( decname, loc );

    ListConcat( &( decname->var_bas ), MemberKwd );
    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 );

    return( decname );
}

/*
 * Decorate a label.
 */
static BrokenName_T *DecorateLabel( BrokenName_T *decname, Loc_T *loc )
/*********************************************************************/
{
    String  lab_name;

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

    ListConcat( &( decname->var_bas ), LabelKwd );
                                                    /* NYI -- sb label */
    EndNode( &( decname->var_bas ), TRUE, loc->entry_st, DR_SYM_VARIABLE );
    ListConcat( &( decname->var_bas ), lab_name );
    EndNode( &( decname->var_bas ), FALSE, 0, DR_SYM_NOT_SYM );

    DWRFREE( lab_name.s );

    return( decname );
}

/*
 * Decorate a typedef.
 */

static BrokenName_T *DecorateTypedef( BrokenName_T *decname, Loc_T *loc )
/***********************************************************************/
{
    ListConcat( &( decname->dec_plg ), TypedefKwd );

    DecorateVariable( decname, loc );

    return( decname );
}

static BrokenName_T *DecorateNameSpace( BrokenName_T *decname, Loc_T *loc )
/*************************************************************************/
{
    ListConcat( &( decname->dec_plg ), NameSpaceKwd );

    DecorateVariable( decname, loc );

    return( decname );
}
/*
 * decorate a function.
 */
static dw_tagnum GetTag( dr_handle entry )
/****************************************/
{
    dr_handle   abbrev;
    dw_tagnum   tag;

    abbrev = DWRVMReadULEB128( &entry );
    abbrev = DWRLookupAbbrev( entry, abbrev );
    tag = DWRVMReadULEB128( &abbrev );
    return( tag );
}

static void GetContaining( List_T *list, dr_handle of )
/*****************************************************/
{
    scope_trail container;
    scope_entry *curr;

    DRGetScopeList( &container, of );
    curr = container.head;
    while( curr != NULL ) {
        String      containing_name;
        dw_tagnum   tag;

        tag = GetTag( curr->handle );
        switch( tag ){
        case DW_TAG_class_type:
        case DW_TAG_union_type:
        case DW_TAG_structure_type:
        case DW_TAG_WATCOM_namespace:
            GetClassName( curr->handle, &containing_name );
            if( containing_name.s != NULL ) {
                ListConcat( list, MemberKwd );

                EndNode( list, TRUE, curr->handle,
                        DR_SYM_CLASS );
                ListConcat( list, containing_name );
                EndNode( list, FALSE, 0, DR_SYM_NOT_SYM );
                DWRFREE( containing_name.s );
            }
            break;
        default:
            goto done_loop;
        }
        curr = curr->next;
    } done_loop:;
    DREndScopeList( &container );
}

static BrokenName_T *DecorateFunction( BrokenName_T *decname, Loc_T *loc )
/************************************************************************/
{
    String      func_name;
    List_T      parms;
    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( func_name.s != NULL ) {
        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 );
    }


    if( DWRScanForAttrib( &tmp_abbrev, &tmp_entry, DW_AT_external )
        == DW_AT_external ) {
        if( DWRReadConstant( tmp_abbrev, tmp_entry ) ) {
            ListConcat( &( decname->dec_plg ), ExternKwd );
        }
    }

    /* check to see if its a member of a containing entry */
    tmp_abbrev = loc->abbrev_cr;    /* reset */
    tmp_entry = loc->entry_cr;
    if( DWRScanForAttrib( &tmp_abbrev, &tmp_entry, DW_AT_containing_type )
                           ==  DW_AT_containing_type ){

⌨️ 快捷键说明

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