⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cgen2.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                    SymGet( &sym, sym_handle );
                    sym.flags |= SYM_EMITTED;
                    SymReplace( &sym, sym_handle );
                }
            }
        } else if( sym.stg_class != SC_EXTERN &&
                   sym.stg_class != SC_TYPEDEF ) {      /* 25-nov-94 */
            if( sym.flags & SYM_ADDR_TAKEN ) {
                emit_extra_info = 1;
            }
            typ = sym.sym_type;
            while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
            switch( typ->decl_type ) {
            case TYPE_UNION:
            case TYPE_STRUCT:
            case TYPE_ARRAY:
            case TYPE_FCOMPLEX:
            case TYPE_DCOMPLEX:
            case TYPE_LDCOMPLEX:
                emit_extra_info = 1;
                break;
            }
            dtype = CGenType( typ );
            if( sym.flags & SYM_FUNC_RETURN_VAR ) {
                sym.info.return_var = CGTemp( dtype );
                SymReplace( &sym, sym_handle );
            } else {
                CGAutoDecl( sym_handle, dtype );
            }
        }
#if _CPU != 370
        if( ! CompFlags.debug_info_some ) emit_extra_info = 0;
#endif
        if( emit_debug_info != 0 || emit_extra_info != 0 ) {
            if( Saved_CurFunc == 0 ) {  /* if we are not inlining */
                if( GenSwitches & DBG_LOCALS ) {
                    if( !(sym.flags & SYM_TEMP) ) {
                        DBLocalSym( sym_handle, TY_DEFAULT );
                    }
                }
            }
        }
        sym_handle = sym.handle;
    }
}


local void FreeSymBackInfo( SYM_ENTRY *sym, SYM_HANDLE sym_handle )
{
    if( sym->info.backinfo != NULL ) {
        BEFiniBack( sym->info.backinfo );
        BEFreeBack( sym->info.backinfo );
        sym->info.backinfo = NULL;
        SymReplace( sym, sym_handle );
    }
}

#ifdef __SEH__
static void FreeTrySymBackInfo( void )
{
    SYM_ENTRY   sym;

    SymGet( &sym, TrySymHandle );
    FreeSymBackInfo( &sym, TrySymHandle );
}

static void FreeTryTableBackHandles( void )
{
    struct try_table_back_handles       *try_backinfo;

    for(;;) {
        try_backinfo = TryTableBackHandles;
        if( try_backinfo == NULL )  break;
        TryTableBackHandles = try_backinfo->next;
        BEFreeBack( try_backinfo->try_table_back_handle );
        CMemFree( try_backinfo );
    }
}
#endif

local void FreeLocalVars( SYM_HANDLE sym_list )
{
    SYM_HANDLE          sym_handle;
    auto SYM_ENTRY      sym;

    for( ; sym_handle = sym_list; ) {
        SymGet( &sym, sym_handle );
        sym_list = sym.handle;
        if( sym.stg_class != SC_EXTERN ) {
            if( ! (sym.flags & SYM_FUNC_RETURN_VAR) ) {
                if( sym.sym_type->decl_type != TYPE_VOID ) {
                    FreeSymBackInfo( &sym, sym_handle );
                }
            }
        }
    }
}


local void FreeGblVars( SYM_HANDLE sym_handle )
{
    SYMPTR      sym;

    for( ; sym_handle; ) {
        sym = SymGetPtr( sym_handle );
        sym_handle = sym->handle;
        if( sym->info.backinfo != NULL ) {
//              BEFiniBack( sym->info.backinfo );
            BEFreeBack( sym->info.backinfo );
        }
    }
}

local void RelExtVars( SYM_HANDLE sym_handle )
{
    SYMPTR      sym;

    for( ; sym_handle; ) {
        sym = SymGetPtr( sym_handle );
        sym_handle = sym->handle;
        if( !(sym->flags & SYM_FUNC_RETURN_VAR) ) {
            if( sym->stg_class == SC_EXTERN || sym->stg_class == SC_STATIC ||
                sym->sym_type->decl_type == TYPE_VOID ) {
                if( sym->info.backinfo != NULL ) {
                    BEFreeBack( sym->info.backinfo );
                }
            }
        }
    }
}

local void FreeExtVars()                                /* 02-apr-92 */
{
    SYM_LISTS   *sym_list;
    SYM_LISTS   *next_sym;

    for( sym_list = SymListHeads; sym_list; ) {
        RelExtVars( sym_list->sym_head );
        next_sym = sym_list->next;
        CMemFree( sym_list );
        sym_list = next_sym;
    }
}

int CGenType( TYPEPTR typ )
{
    int         dtype;
    int         flags;
    int         align;

    while( typ->decl_type == TYPE_TYPEDEF )  typ = typ->object;
    switch( typ->decl_type ) {

    case TYPE_FCOMPLEX:
    case TYPE_DCOMPLEX:
    case TYPE_LDCOMPLEX:
    case TYPE_STRUCT:
    case TYPE_UNION:
        if( typ->object != NULL ) { /* 15-jun-94 */
            /* structure has a zero length array as last field */
            dtype = NewRefno();
            align = GetTypeAlignment( typ );
            BEDefType( dtype, align, TypeSize(typ) );
        } else if( typ->u.tag->refno == 0 ) {
            dtype = NewRefno();
            align = GetTypeAlignment( typ );
            BEDefType( dtype, align, TypeSize(typ) );
            typ->u.tag->refno = dtype;
        } else {
            dtype = typ->u.tag->refno;
        }
        break;
    case TYPE_ARRAY:
        if( typ->u.array->refno == 0 ) {
            dtype = NewRefno();
            align = GetTypeAlignment( typ );
            BEDefType( dtype, align, SizeOfArg( typ ) );
            typ->u.array->refno = dtype;
        }
        dtype = typ->u.array->refno;
        break;
    case TYPE_FIELD:
    case TYPE_UFIELD:
        dtype = CGDataType[ typ->u.f.field_type ];
        break;
    case TYPE_FUNCTION:
        dtype = CodePtrType( FLAG_NONE ); /* 20-nov-87 */
        break;
    case TYPE_POINTER:
        flags = typ->u.p.decl_flags;
        dtype = PtrType( typ->object, flags );
        break;
    case TYPE_ENUM:
        typ = typ->object;
    default:
        dtype = CGDataType[ typ->decl_type ];
    }
    return( dtype );
}


local int CodePtrType( int flags )
{
#if _MACHINE == _PC
    int         dtype;

    if( flags & FLAG_FAR ) {
        dtype = T_LONG_CODE_PTR;
    } else if( flags & FLAG_NEAR ) {
        dtype = T_NEAR_CODE_PTR;
    } else {
        dtype = T_CODE_PTR;
    }
    return( dtype );
#else
    return( T_CODE_PTR );
#endif
}


extern int PtrType( TYPEPTR typ, int flags )
{
    int         dtype;

    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;/*03-dec-91*/
    if( typ->decl_type == TYPE_FUNCTION ) {
        dtype = CodePtrType( flags );
    } else {
#if _MACHINE == _PC
        if( flags & FLAG_FAR ) {
            dtype = T_LONG_POINTER;
        } else if( flags & FLAG_HUGE ) {
            dtype = T_HUGE_POINTER;
        } else if( flags & FLAG_NEAR ) {
            dtype = T_NEAR_POINTER;
        } else {
            dtype = T_POINTER;
        }
#else
        dtype = T_POINTER;
#endif
    }
    return( dtype );
}


local int StringSegment( STR_HANDLE strlit )
{
#if _MACHINE == _PC
    if( strlit->flags & FLAG_FAR )
        return( FarStringSegment );
#endif
    if( strlit->flags & FLAG_CONST )
        return( SEG_CODE );                 /* 01-sep-89*/
    return( SEG_CONST );
}

void EmitStrPtr( STR_HANDLE str_handle, int pointer_type )
{
    str_handle->ref_count++;
    Emit1String( str_handle );
    DGBackPtr( str_handle->cg_back_handle, StringSegment( str_handle ),
                    0, pointer_type );
}


local void Emit1String( STR_HANDLE str_handle )
{
    if( str_handle->cg_back_handle == 0 ) {
        str_handle->cg_back_handle = BENewBack( NULL );
        if( ! (str_handle->flags & FLAG_CONST) ) {
            EmitLiteral( str_handle );
        }
    }
}


int EmitBytes( STR_HANDLE strlit )
{
    DGBytes( strlit->length, strlit->literal );
    return( strlit->length );
}


local void EmitLiteral( STR_HANDLE strlit )
{
    segment_id  old_segment;

    old_segment = BESetSeg( StringSegment( strlit ) );
    if( strlit->flags & STRLIT_WIDE ) {
        DGAlign( TARGET_SHORT );    /* NT requires word aligned wide strings */
    }
    DGLabel( strlit->cg_back_handle );
    EmitBytes( strlit );
    BESetSeg( old_segment );
}


local void FreeStrings( void )
{
    STR_HANDLE  strlit, next;
    int         i;

    for( i = 0; i < STRING_HASH_SIZE; ++i ) {
        for( strlit = StringHash[i]; strlit; ) {
            if( strlit->cg_back_handle != 0 ) {
                BEFiniBack( strlit->cg_back_handle );
                BEFreeBack( strlit->cg_back_handle );
                strlit->cg_back_handle = 0;
            }
            next = strlit->next_string;
            FreeLiteral( strlit );
            strlit = next;
        }
        StringHash[i] = 0;
    }
}


local void DumpCS_Strings( STR_HANDLE strlit )
{
    while( strlit != NULL ) {
        if( strlit->flags & FLAG_CONST  &&
            strlit->ref_count != 0 ) {          /* 17-aug-91 */
            strlit->cg_back_handle = BENewBack( NULL );
            EmitLiteral( strlit );
        }
        strlit = strlit->next_string;
    }
}


local void EmitCS_Strings( void )
{
    int         i;

    if( CompFlags.strings_in_code_segment ) {
        for( i = STRING_HASH_SIZE - 1; i >= 0; --i ) {
            DumpCS_Strings( StringHash[i] );
        }
    }
}

#ifdef __SEH__
static void GenerateTryBlock( TREEPTR tree )
{
    TREEPTR     stmt;
    int         try_index;
    int         max_try_index;

    try_index = 0;
    max_try_index = -1;
    for(;;) {
        stmt = tree->right;
        if( stmt->op.opr == OPR_FUNCEND ) break;
        switch( stmt->op.opr ) {
        case OPR_TRY:
            try_index = stmt->op.try_index;
            if( try_index > max_try_index )  max_try_index = try_index;
            break;
        case OPR_EXCEPT:
        case OPR_FINALLY:
            ValueStack[ try_index ] = (TREEPTR)stmt->op.try_sym_handle;
            Class[ try_index ] = stmt->op.parent_scope;
            Token[ try_index ] = stmt->op.opr;
            break;
        }
        tree = tree->left;
        if( tree == NULL ) break;               // should never happen
    }
    if( max_try_index != -1 ) {
        segment_id      old_segment;
        back_handle     except_label;
        back_handle     except_table;
        struct try_table_back_handles *try_backinfo;

        old_segment = BESetSeg( SEG_DATA );
        except_table = BENewBack( NULL );
        try_backinfo = (struct try_table_back_handles *)
                        CMemAlloc( sizeof( struct try_table_back_handles ) );
        try_backinfo->try_table_back_handle = except_table;
        try_backinfo->next = TryTableBackHandles;
        TryTableBackHandles = try_backinfo;
        DGLabel( except_table );
        for( try_index = 0; try_index <= max_try_index; try_index++ ) {
            DGInteger( Class[ try_index ], T_UINT_1 );  // parent index
            if( Token[ try_index ] == OPR_EXCEPT ) {
                DGInteger( 0, T_UINT_1 );
            } else {
                DGInteger( 1, T_UINT_1 );
            }
            except_label = FEBack( (SYM_HANDLE)ValueStack[ try_index ] );
            DGBackPtr( except_label, FESegID( CurFuncHandle ), 0,
                            T_CODE_PTR );
        }
        BESetSeg( old_segment );
        SetTryTable( except_table );
        BEFiniBack( except_table );
    }
}
#endif

⌨️ 快捷键说明

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