pchdr.c

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

C
1,751
字号
}

static void OutPutEnums( ENUMPTR ep, TAGPTR parent )
{
    int         rc;
    unsigned    len;

    for( ; ep; ep = ep->thread ) {
        len = strlen( ep->name ) + sizeof( ENUMDEFN );
        len = _RoundUp( len, sizeof( int ) );
        ep->enum_len = len;
        rc = WritePHeader( ep, len );
        ep->parent = parent;            // enum_len is union'ed with parent
        if( rc != 0 ) {
            longjmp( PH_jmpbuf, rc );
        }
    }
}

static void OutPutFields( FIELDPTR field )
{
    int         rc;
    int         len;
    FIELDPTR    next_field;
    TYPEPTR     typ;

    while( field != NULL ) {
        len = strlen( field->name ) + sizeof( FIELD_ENTRY );
        len = _RoundUp( len, sizeof( int ) );
        next_field = field->next_field;         // save pointer
        field->field_len = len;                 // replace with length
        if( next_field == NULL ) {
            field->field_len = - len;           // marker for end of list
        }
        typ = field->field_type;                // save type pointer
        field->field_type_index = typ->type_index;// replace with type index
        rc = WritePHeader( field, len );
        field->next_field = next_field;         // restore pointer
        field->field_type = typ;                // restore type pointer
        if( rc != 0 ) {
            longjmp( PH_jmpbuf, rc );
        }
        field = next_field;
    }
}

static void OutPutATag( TAGPTR tag )
{
    int         rc;
    TYPEPTR     typ;
    unsigned    len;

    typ = tag->sym_type;
    tag->sym_type_index = typ->type_index;
    len = strlen( tag->name ) + sizeof( TAGDEFN );
    len = _RoundUp( len, sizeof( int ) );
    rc = WritePHeader( tag, len );
    tag->sym_type = typ;
    if( rc != 0 ) {
        longjmp( PH_jmpbuf, rc );
    }
    if( typ->decl_type == TYPE_ENUM ) {
        OutPutEnums( tag->u.enum_list, tag );
    } else {
        OutPutFields( tag->u.field_list );
    }
}

static void OutPutTags( void )
{
    WalkTagList( OutPutATag );
}

void SetTypeIndex( TYPEPTR typ )
{
    ++PH_TypeCount;
    typ->type_index = PH_TypeCount;
}

static void SetFuncTypeIndex( TYPEPTR typ, int index )
{
    // index;      /* unused */
    SetTypeIndex( typ );
}

static void NumberTypes( void )
{
    PH_TypeCount = 0;
    WalkTypeList( SetTypeIndex );
    WalkFuncTypeList( SetFuncTypeIndex );
}

static void SetTagIndex( TAGPTR tag )
{
    tag->tag_index = PH_TagCount;
    ++PH_TagCount;
}

static void SetDebugTag( TAGPTR tag )
{
    tag->refno = 0;
}

static void NumberTags( void )
{
    PH_TagCount = 0;
    WalkTagList( SetTagIndex );
}

static void InitDebugTags( void )
{
    WalkTagList( SetDebugTag );
}

static int WriteType( TYPEPTR typ )
{
    int         rc;
    TYPEPTR     object;

    object = typ->object;
    if( object != NULL ) {
        typ->object_index = object->type_index;
        rc = WritePHeader( typ, sizeof( TYPEDEFN ) );
        typ->object = object;
    } else {
        rc = WritePHeader( typ, sizeof( TYPEDEFN ) );
    }
    return( rc );
}

struct type_indices {
    int     basetype_index[TYPE_LAST_ENTRY];
    int     stringtype_index;
    int     constchartype_index;
};

static void OutPutTypeIndexes( void )                       /* 02-jan-95 */
{
    TYPEPTR             typ;
    int                 rc;
    int                 i;
    struct type_indices typ_index;

    for( i = TYPE_CHAR; i < TYPE_LAST_ENTRY; i++ ) {
        typ = BaseTypes[i];
        if( typ == NULL ) {
            typ_index.basetype_index[i] = 0;
        } else {
            typ_index.basetype_index[i] = typ->type_index;
        }
    }
    typ_index.stringtype_index = StringType->type_index;
    typ_index.constchartype_index = ConstCharType->type_index;
    rc = WritePHeader( &typ_index, sizeof( struct type_indices ) );
    if( rc != 0 ) {
        longjmp( PH_jmpbuf, rc );
    }
}

static void OutPutAType( TYPEPTR typ )
{
    TAGPTR              tag;
    int                 rc;
    struct array_info   *array;

    rc = 0;
    switch( typ->decl_type ) {
    case TYPE_ARRAY:
        array = typ->u.array;                   // save pointer
        typ->u.array_dimension = array->dimension;      // replace with dim
        rc = WriteType( typ );
        typ->u.array = array;                   // restore pointer
        break;
    case TYPE_STRUCT:
    case TYPE_UNION:
    case TYPE_ENUM:
        tag = typ->u.tag;                               // save tag
        typ->u.tag_index = tag->tag_index;              // replace with index
        rc = WriteType( typ );
        typ->u.tag = tag;                               // restore tag pointer
        break;
    default:
        if( typ->decl_type != TYPE_FUNCTION ) {
            rc = WriteType( typ );
        }
        break;
    }
    if( rc != 0 ) {
        longjmp( PH_jmpbuf, rc );
    }
}

static void OutPutAFuncType( TYPEPTR typ, int index )
{
    TYPEPTR     *parm_list;
    int         rc;

    parm_list = typ->u.fn.parms;                // save pointer
    typ->u.fn.parm_index = index;               // replace with index
    rc = WriteType( typ );
    typ->u.fn.parms = parm_list;                // restore pointer
    if( rc != 0 ) {
        longjmp( PH_jmpbuf, rc );
    }
}

static void OutPutFuncParmList( TYPEPTR typ, int index )
{
    TYPEPTR     *parm_list;
    int         rc;
    union parmtype {
        TYPEPTR parm_typ;
        int     type_index;
    } parm;

    // index;      /* unused */
    parm_list = typ->u.fn.parms;
    if( parm_list != NULL ) {
        for( ; *parm_list; ++parm_list ) {
            parm.type_index = (*parm_list)->type_index;
            rc = WritePHeader( &parm, sizeof( union parmtype ) );
            if( rc != 0 ) {
                longjmp( PH_jmpbuf, rc );
            }
        }
    }
    parm.type_index = -1;
    rc = WritePHeader( &parm, sizeof( union parmtype ) );
    if( rc != 0 ) {
        longjmp( PH_jmpbuf, rc );
    }
}

static void OutPutTypes( void )
{
    NumberTypes();
    NumberTags();
    WalkTypeList( OutPutAType );
    WalkFuncTypeList( OutPutAFuncType );
    WalkFuncTypeList( OutPutFuncParmList );
    OutPutTypeIndexes();
}

#if ( _CPU == 8086 ) || ( _CPU == 386 )
static void OutPutAuxInfo( struct aux_info *info )
{
    hw_reg_set          *regs;
    hw_reg_set          *save_parms;
    char                *save_objname;
    byte_seq            *save_code;
    int                 rc;
    unsigned            len;
    unsigned            padding;

    save_parms = info->parms;
    save_objname = info->objname;
    save_code = info->code;
    len = sizeof( struct aux_info );
    if( save_parms != NULL ) {
        info->parms_size = 0;
        regs = save_parms;
        for( ;; ) {
            info->parms_size += sizeof( hw_reg_set );
            if( HW_CEqual( *regs, HW_EMPTY ) ) break;
            ++regs;
        }
    }
    if( save_objname != NULL ) {
        info->objname_size = strlen( save_objname ) + 1;
        len += info->objname_size;
    }
    if( save_code != NULL ) {
        info->code_size = (save_code->length & MAX_BYTE_SEQ_LEN)
                                + sizeof( byte_seq );
        len += info->code_size;
    }
    padding = _RoundUp( len, sizeof( int ) ) - len;
    rc = WritePHeader( info, sizeof( struct aux_info ) );
    if( save_parms != NULL ) {
        regs = save_parms;
        for( ;; ) {
            rc |= WritePHeader( regs, sizeof( hw_reg_set ) );
            if( HW_CEqual( *regs, HW_EMPTY ) ) break;
            ++regs;
        }
    }
    if( save_objname != NULL ) {
        len = strlen( save_objname ) + 1;
        rc |= WritePHeader( save_objname, len );
    }
    if( save_code != NULL ) {
        len = (save_code->length & MAX_BYTE_SEQ_LEN) + sizeof( byte_seq );
        rc |= WritePHeader( save_code, len );
    }
    rc |= WritePHeader( "    ", padding );
    info->parms = save_parms;
    info->objname = save_objname;
    info->code = save_code;
    if( rc != 0 ) {
        longjmp( PH_jmpbuf, rc );
    }
}

static void OutPutPragmaInfo( void )
{
    struct aux_entry    *ent;
    struct aux_info     *info;
    unsigned            index;
    int                 rc;
    unsigned            len;

    for( index = 0; (info = BuiltinInfos[index]); ++index ) {
        OutPutAuxInfo( info );          // write out the aux_info struct
    }
    PH_PragmaCount = 0;
    for( ent = AuxList; ent; ent = ent->next ) {
        info = ent->info;
        info->index = PCH_NULL_INDEX;
    }
    index = PCH_FIRST_INDEX;
    for( ent = AuxList; ent; ent = ent->next ) {
        info = ent->info;
        if( info->index == PCH_NULL_INDEX ) {
            info->index = index;
            index++;
            OutPutAuxInfo( info );      // write out the aux_info struct
            ++PH_PragmaCount;
        }
    }
    for( ent = AuxList; ent; ent = ent->next ) {
        info = ent->info;
        ent->aux_info_index = info->index - PCH_FIRST_INDEX;
        // write out aux_entry
        len = sizeof( struct aux_entry ) + strlen( ent->name );
        len = _RoundUp( len, sizeof( int ) );
        rc = WritePHeader( ent, len );
        ent->info = info;                       // restore pointer
        if( rc != 0 ) {
            longjmp( PH_jmpbuf, rc );
        }
    }
}
#endif

static void OutPutMacros( void )
{
    int         i;
    int         rc;
    MEPTR       mentry;
    MEPTR       next_macro;
    unsigned    mentry_len;

    PH_MacroCount = 0;
    PH_MacroSize = PH_size;
    for( i = 0; i < MACRO_HASH_SIZE; ++i ) {
        for( mentry = MacHash[i]; mentry; mentry = mentry->next_macro ) {
            mentry_len = mentry->macro_len;
            next_macro = mentry->next_macro;        // save pointer
            mentry->macro_index = i;        // replace with hash index
            rc = WritePHeader( mentry, mentry_len );
            mentry->next_macro = next_macro;        // restore pointer
            mentry_len = _RoundUp( mentry_len, sizeof( int ) ) - mentry_len;
            rc |= WritePHeader( "    ", mentry_len );
            if( rc != 0 ) {
                longjmp( PH_jmpbuf, rc );
            }
            ++PH_MacroCount;
        }
    }
    /* write out undefined macro list.  26-may-94 */
    PH_UndefMacroCount = 0;
    for( mentry = UndefMacroList; mentry; mentry = mentry->next_macro ) {
        mentry_len = mentry->macro_len;
        rc = WritePHeader( mentry, mentry_len );
        mentry_len = _RoundUp( mentry_len, sizeof( int ) ) - mentry_len;
        rc |= WritePHeader( "    ", mentry_len );
        if( rc != 0 ) {
            longjmp( PH_jmpbuf, rc );
        }
        ++PH_UndefMacroCount;
    }
    PH_MacroSize = PH_size - PH_MacroSize;
}

static void OutPutSymHashTable( void )
{
    SYM_HASHPTR     hsym;
    SYM_HASHPTR     next_hsymptr;
    SYM_HASHPTR     sym_list;
    TYPEPTR         typ;
    int             i;
    int             rc;
    unsigned        len;

    for( i=0; i < SYM_HASH_SIZE; i++ ) {
        // reverse the list
        sym_list = NULL;
        for( hsym = HashTab[i]; hsym; hsym = next_hsymptr ) {
            next_hsymptr = hsym->next_sym;
            hsym->next_sym = sym_list;
            sym_list = hsym;
            ++PH_SymHashCount;
        }
        HashTab[i] = NULL;
        rc = 0;
        for( hsym = sym_list; hsym; hsym = next_hsymptr ) {
            next_hsymptr = hsym->next_sym;
            hsym->hash_index = i;
            typ = hsym->sym_type;               // save type pointer
            if( typ != NULL ) {
                hsym->sym_type_index = typ->type_index; // replace with index
            }
            len = strlen( hsym->name ) + sizeof( struct sym_hash_entry );
            len = _RoundUp( len, sizeof( int ) );
            rc |= WritePHeader( hsym, len );
            hsym->sym_type = typ;               // restore type pointer
            hsym->next_sym = HashTab[i];
            HashTab[i] = hsym;
        }
        if( rc != 0 ) {
            longjmp( PH_jmpbuf, rc );
        }
    }
}

static void OutPutSymbols( void )
{
    SYM_ENTRY   sym;
    SYM_HANDLE  sym_handle;
    int         rc;

    if( PH_computing_size ) {
        PH_size += SymGetNumSyms() * sizeof( SYM_ENTRY );
    } else {
        for( sym_handle = SymGetFirst(); sym_handle != SYM_INVALID ; sym_handle = SymGetNext( sym_handle ) ) {
            SymGet( &sym, sym_handle );
            if( sym.sym_type != NULL ) {
                sym.sym_type_index = sym.sym_type->type_index;

⌨️ 快捷键说明

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