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

📄 cinfo.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/



#include "cvars.h"
#include "cg.h"
#include "cgdefs.h"
#include "cgswitch.h"
#include "standard.h"
#include "cgprotos.h"
#include "cgaux.h"
#include "langenv.h"

struct user_seg {
        struct user_seg *next;
        char            *name;
        SYM_HANDLE      sym_handle;                     /* 15-mar-92 */
        int             segtype;                        /* 22-oct-92 */
        int             segment;                        /* 22-oct-92 */
        char            *class_name;                    /* 22-oct-92 */
        hw_reg_set      pegged_register;                /* 29-may-93 */
        bool            used;
};


void AssignSeg( SYM_ENTRY *sym )
{
    SetFarHuge( sym, 1 );
    if( (sym->stg_class == SC_AUTO) || (sym->stg_class == SC_REGISTER)
        || (sym->stg_class == SC_TYPEDEF) ) {
        /* if stack/register var, there is no segment */
        sym->u.var.segment = 0;
    } else if( sym->stg_class != SC_EXTERN ) {  /* if not imported */
        if( (sym->flags & SYM_INITIALIZED) == 0 ) {
            if( sym->u.var.segment == 0 ) {             /* 15-mar-92 */
                SetSegment( sym );
            }
            if( sym->u.var.segment == SEG_DATA ) {
                sym->u.var.segment = SEG_BSS;
                CompFlags.bss_segment_used = 1;
            }
            SetSegAlign( sym );                 /* 02-feb-92 */
        }
    } else if( sym->attrib & (FLAG_FAR | FLAG_HUGE) ) {
        sym->u.var.segment = SegImport;
        --SegImport;
    } else if( (SegData != 0) && (sym->attrib & FLAG_NEAR) ){ // imported and near
        sym->u.var.segment = SegData;
    }
}


void SetFarHuge( SYMPTR sym, int report )
{
    TYPEPTR             typ;
    unsigned            attrib;
    auto unsigned long  size;

    report = report; /* in case not used */
    #if _CPU == 8086
        if( sym->declspec == DECLSPEC_DLLIMPORT
         || sym->declspec == DECLSPEC_DLLEXPORT ) {      /* 16-dec-94 */
            sym->attrib |= FLAG_FAR;
        } else if( sym->attrib & FLAG_EXPORT ) {
            sym->attrib |= FLAG_FAR;
        }
    #endif
    size = SizeOfArg( sym->sym_type );
    if( TargetSwitches & BIG_DATA ) {
        attrib = sym->attrib;
        if( (attrib & (FLAG_NEAR|FLAG_FAR|FLAG_HUGE)) == 0 ) {
            if( size == 0 ) {   /* unspecified array size */
                if( sym->stg_class == SC_EXTERN ) {
                    typ = sym->sym_type;
                    if( typ->decl_type == TYPE_ARRAY ) {
                        attrib |= FLAG_FAR;
                    }
                }
            } else if( size > DataThreshold ) {
                attrib |= FLAG_FAR;
            } else if( (/* sym->stg_class == SC_STATIC || 17-may-91 */
                    CompFlags.strings_in_code_segment ) /*JD: 29-oct-90*/
                    && sym->attrib & FLAG_CONST ) {
                    attrib |= FLAG_FAR;
            }
            #if _CPU == 8086
                if( (attrib & FLAG_FAR) && size > 0x10000 ) {
                    attrib &= ~FLAG_FAR;
                    attrib |= FLAG_HUGE;
                }
            #endif
            sym->attrib = attrib;
        }
    }
    #if _CPU == 8086
       if( report && size > 0x10000 && !(sym->attrib & FLAG_HUGE) ) {
            SetSymLoc( sym );
            CErr( ERR_VAR_TOO_LARGE );
       }
    #endif
}


#define CONSTANT( decl_flags ) ( ( decl_flags \
                          & ( FLAG_CONST | FLAG_VOLATILE ) ) \
                                        == FLAG_CONST )



static fe_attr FESymAttr( SYMPTR sym )
/************************************/
{
    fe_attr         attr;

    attr = 0;
    switch( sym->stg_class ) {
    case SC_FORWARD:
    case SC_EXTERN:
        attr = FE_GLOBAL | FE_IMPORT | FE_STATIC;
        break;
    case SC_NULL:
        attr = FE_GLOBAL | FE_STATIC;
        break;
    case SC_STATIC:
        attr = FE_STATIC | FE_VISIBLE;
        if( sym->level != 0 ) {
            attr |= FE_INTERNAL;
        }
        break;
    }
    if( sym->flags & SYM_FUNCTION ) {
        attr |= FE_PROC | FE_STATIC;
        #if _MACHINE == _ALPHA || _MACHINE == _PPC
            if( VarFunc( sym ) ) attr |= FE_VARARGS;
        #endif
        if( CompFlags.unique_functions ) {
            if( (attr & FE_GLOBAL) || (sym->flags & SYM_ADDR_TAKEN) ) {
                attr |= FE_UNIQUE;
            }
        }
    }
    if( sym->flags & SYM_USED_IN_PRAGMA ) {
        attr |= FE_MEMORY | FE_ADDR_TAKEN | FE_VOLATILE;
    }
    if( sym->flags & SYM_TRY_VOLATILE ) {
        attr |= FE_MEMORY | FE_VOLATILE;
    }
    if( sym->attrib & FLAG_VOLATILE ) {
        attr |= FE_MEMORY | FE_VOLATILE;
    } else if( sym->attrib & FLAG_CONST ) {
        attr |= FE_CONSTANT;
    }
    switch( sym->declspec ){
    case DECLSPEC_DLLIMPORT:
        if( (attr & FE_IMPORT) || CompFlags.rent ) {
            attr |= FE_DLLIMPORT;
        }
        break;
    case DECLSPEC_DLLEXPORT:
        if( sym->stg_class == SC_NULL ) {
            attr |= FE_DLLEXPORT;
        }
        break;
    case DECLSPEC_THREAD:
        attr |= FE_THREAD_DATA;
        break;
    }
    if( sym->naked ){
        attr |= FE_NAKED;
    }
    if( sym->rent ){ //Override on function or r/w data
        attr |= FE_THREAD_DATA;
    }
    return( attr );
}


void    FEGenProc( CGSYM_HANDLE hdl, call_handle call_list  )
/***********************************/
{
    SYM_HANDLE sym_handle = hdl;
    GenInLineFunc( sym_handle );
}


fe_attr FEAttr( CGSYM_HANDLE cgsym_handle )
/*****************************************/
{
    SYM_HANDLE sym_handle = cgsym_handle;

    return( FESymAttr( SymGetPtr( sym_handle ) ) );
}


segment_id SymSegId( SYMPTR sym )
{
    fe_attr attr;

    attr = FESymAttr( sym );
    if( attr & FE_PROC ) return( SEG_CODE );
    if( !CompFlags.rent ){
        if( attr & FE_CONSTANT ) return( SEG_CONST2 );
    }
    return( SEG_DATA );
}


void SetSegment( SYMPTR sym )
{
    struct segment_list *seg;
    auto unsigned long  size;


    #if _CPU == 8086
        if( ( ( sym->attrib & FLAG_FAR ) && CompFlags.zc_switch_used ) ) {
            if( CONSTANT( sym->attrib ) ||
            (sym->stg_class == SC_STATIC  &&  (sym->flags & SYM_TEMP) ) ) {
                sym->u.var.segment = SEG_CODE;
                return;
            }
        }
    #elif _CPU == 386
        if( !CompFlags.rent ){
            if( ( (sym->attrib & FLAG_FAR) || (TargetSwitches & FLAT_MODEL) ) ) {
               if( CONSTANT( sym->attrib ) && CompFlags.zc_switch_used  ){
                    sym->u.var.segment = SEG_CODE;
                    return;
               }
               if( (sym->stg_class == SC_STATIC )&& (sym->flags & SYM_TEMP) ) {
                    sym->u.var.segment = SEG_CODE;
                    return;
                }
             }
         }
    #endif
    if( sym->attrib & ( FLAG_FAR | FLAG_HUGE ) ) {
        size = SizeOfArg( sym->sym_type );
        seg = NULL;
        #if _CPU == 8086
            if( size < 0x10000 ) {
                auto unsigned int isize;

                isize = size;
                for( seg = SegListHead; seg; seg = seg->next_segment ) {
                    if( seg->size_left >= isize ) break;
                }
            }
        #else
            seg = SegListHead;
        #endif
        if( seg == NULL ) {
            if( SegListHead == NULL ) {
                SegListHead = CMemAlloc( sizeof( struct segment_list ) );
                seg = SegListHead;
            } else {
                for( seg = SegListHead; seg->next_segment; ) {
                    seg = seg->next_segment;
                }
                seg->next_segment =
                            CMemAlloc( sizeof( struct segment_list ) );
                seg = seg->next_segment;
            }
            seg->segment_number = SegmentNum;
            ++SegmentNum;
            #if _CPU == 8086
                if( size > 0xFFFF ) {
                    while( size > 0x0FFFF ) {       /* while >= 64K */
                        ++SegmentNum;
                        size -= 0x10000;
                    }
                    seg->size_left = 0;
                } else {
                    seg->size_left  =  0x10000-size;
                }
            #endif
        } else {
            seg->size_left -= size;
        }
        sym->u.var.segment = seg->segment_number;
    } else {
        sym->u.var.segment = SymSegId( sym );
    }
}

#ifndef WCPP

struct  seg_name {
    char        *name;
    int         segment;
};

static struct seg_name Predefined_Segs[] = {
        { "_CODE",      SEG_CODE },
        { "_CONST",     SEG_CONST },
        { "_DATA",      SEG_DATA },
        { "_STACK",     SEG_STACK },                    /* 13-dec-92 */
        { NULL,         0 }
};

static int UserSegment;

#define FIRST_USER_SEGMENT      10000

static struct user_seg *AllocUserSeg( char *segname, char *class_name, seg_type segtype ){
    struct user_seg     *useg;

    useg = CMemAlloc( sizeof( struct user_seg ) );
    useg->next = NULL;
    useg->name = CStrSave( segname );
    useg->class_name = NULL;
    useg->segtype = segtype;
    if( class_name != NULL ) {
        useg->class_name = CStrSave( class_name );
    }
    useg->segment = UserSegment;
    ++UserSegment;
    return( useg );
}

#define INITFINI_SIZE 12
struct spc_info {
    char    *name;
    char    *class_name;
    seg_type segtype;
};

⌨️ 快捷键说明

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