fcsyms.c

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

C
1,580
字号
/****************************************************************************
*
*                            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:  Symbol table processing.
*
****************************************************************************/


#include "ftnstd.h"
#include "global.h"
#include "wf77defs.h"
#include "wf77aux.h"
#include "cg.h"
#include "ecflags.h"
#include "cpopt.h"
#include "segsw.h"
#include "fcgbls.h"
#include "wf77labe.h"
#include "falloc.h"
#include "nmlinfo.h"
#include "fmemmgr.h"
#include "types.h"
#include "fctypes.h"

#include <string.h>

//=================== Back End Code Generation Routines ====================

extern  void            BEFiniBack(back_handle);
extern  void            BEFiniLabel(label_handle);
extern  void            BEFreeBack(back_handle);
extern  segment_id      BESetSeg(segment_id);
extern  unsigned long   BETypeLength(cg_type);
extern  label_handle    BENewLabel(void);
extern  back_handle     BENewBack(sym_handle);
extern  void            CGAutoDecl(pointer,cg_type);
extern  void            CGParmDecl(pointer,cg_type);
extern  void            CGLastParm(void);
extern  sel_handle      CGSelInit(void);
extern  void            CGSelCase(sel_handle,label_handle,signed_32);
extern  void            CGSelOther(sel_handle,label_handle);
extern  void            CGSelect(sel_handle,cg_name);
extern  void            CGControl(cg_op,cg_name,label_handle);
extern  cg_name         CGUnary(cg_op,cg_name,cg_type);
extern  cg_name         CGBinary(cg_op,cg_name,cg_name,cg_type);
extern  cg_name         CGFEName(sym_handle,cg_type);
extern  cg_name         CGAssign(cg_name,cg_name,cg_type);
extern  void            CGDone(cg_name);
extern  void            DGBackPtr(back_handle,segment_id,signed long,cg_type);
extern  void            DGLabel(back_handle);
extern  void            DGAlign(uint);
extern  void            DGString(char *,uint);
extern  void            DGBytes(unsigned long,char *);
extern  void            DGInteger(unsigned_32,cg_type);
extern  void            DGUBytes(unsigned long);
extern  void            DGIBytes(unsigned long,byte);
extern  unsigned long   DGSeek(unsigned long);
extern  void            DBLocalSym(sym_handle,cg_type);
extern  void            DBModSym(sym_handle,cg_type);
extern  void            DBGenSym(sym_handle,dbg_loc,int);
extern  dbg_loc         DBLocInit(void);
extern  dbg_loc         DBLocSym(dbg_loc,sym_handle);
extern  dbg_loc         DBLocConst(dbg_loc,unsigned_32);
extern  dbg_loc         DBLocOp(dbg_loc,dbg_loc_op,unsigned);
extern  void            DBLocFini(dbg_loc);
extern  temp_handle     CGTemp(cg_type);
extern  cg_name         CGTempName(temp_handle,cg_type);
extern  cg_name         CGInteger(signed_32,cg_type);
extern  cg_name         CGBackName(back_handle,cg_type);

//=========================================================================

extern  fe_attr         FEAttr(sym_id);
extern  pointer         ConstBack(sym_id);
extern  pointer         FEBack(sym_id);
extern  void            FCMessage(fc_msg_class,void *);
extern  segment_id      GetComSeg(sym_id,unsigned_32);
extern  seg_offset      GetComOffset(unsigned_32);
extern  segment_id      GetGlobalSeg(unsigned_32);
extern  seg_offset      GetGlobalOffset(unsigned_32);
extern  label_handle    GetLabel(label_id);
extern  label_handle    GetStmtLabel(sym_id);
extern  void            FiniLabels(uint);
extern  void            DumpFormats(void);
extern  void            FreeSFHeader(sym_id);
extern  void            MakeName(char *,char *,char *);
extern  char            *SDFName(char *);
extern  cg_type         F772CGType(sym_id);
extern  bool            EntryWithAltRets(void);
extern  bool            ChkForAltRets(entry_pt *);
extern  aux_info        *AuxLookup(sym_id);
extern  cg_type         ArrayPtrType(sym_id);
extern  void            ReverseList(void **);
extern  cg_name         SCBPtrAddr(cg_name);
extern  bool            ForceStatic(unsigned_16);
extern  segment_id      AllocImpSegId(void);
extern  sym_id          STArgShadow(sym_id);
extern  sym_id          STAdvShadow(sym_id);
extern  cg_name         SCBLenAddr(cg_name);
extern  cg_name         SCBFlagsAddr(cg_name);
extern  cg_name         SubAltSCB(sym_id);
extern  sym_id          FindEqSetShadow(sym_id);
extern  sym_id          FindAdvShadow(sym_id);
extern  cg_type         CmplxBaseType(cg_type);
extern  bool            TypeCmplx(TYPE);
extern  cg_name         StructRef(cg_name,int);

extern  segment_id      CurrCodeSegId;

static  back_handle     ModuleName = { NULL };

back_handle             TraceEntry;

typedef struct old_back_handle {
                struct old_back_handle  *next;
                back_handle             old;
} old_back_handle;

static old_back_handle *OldBackHandles = NULL;

/*
static  back_handle     MakeStaticSCB( int len ) {
//================================================

    back_handle scb;

    scb = BENewBack( NULL );
    DGAlign( ALIGN_DWORD );
    DGLabel( scb );
    DGIBytes( BETypeLength( T_POINTER ), 0 );
    DGInteger( len, T_INTEGER );
    return( scb );
}
*/


static  void            CheckAutoSize( sym_id sym, cg_type typ ) {
//================================================================

#if _CPU == 8086

    if( BETypeLength( typ ) <= 0x7fff ) return;

    if( sym->ns.flags & SY_IN_EQUIV ) {
        FCMessage( FCMSG_EQUIV_TOO_LARGE, sym );
    } else if( ( sym->ns.flags & SY_CLASS ) == SY_SUBPROGRAM ) {
        FCMessage( FCMSG_RET_VAL_TOO_LARGE, sym );
    } else {
        FCMessage( FCMSG_VARIABLE_TOO_LARGE, sym );
    }
#else
    sym = sym;
    typ = typ;
#endif

}


static  temp_handle     MakeTempSCB( int len ) {
//==============================================

    temp_handle scb;

    scb = CGTemp( T_CHAR );
    // if it's character*(*), the SCB will get filled in by FCDArgInit()
    if( len != 0 ) {
        CGDone( CGAssign( SCBLenAddr( CGTempName( scb, T_CHAR ) ),
                          CGInteger( len, T_INTEGER ), T_INTEGER ) );
    }
    return( scb );
}


uint    SymAlign( sym_id sym ) {
//==============================

    switch( sym->ns.typ ) {
    case TY_LOGICAL_1 :
    case TY_LOGICAL :
    case TY_INTEGER_1 :
    case TY_INTEGER_2 :
    case TY_INTEGER :
        return( sym->ns.xt.size );
    case TY_REAL :
    case TY_COMPLEX :
        return( ALIGN_DWORD );
    case TY_DOUBLE :
    case TY_DCOMPLEX :
        return( ALIGN_QWORD );
    case TY_TRUE_EXTENDED :
    case TY_TRUE_XCOMPLEX :
        return( ALIGN_SEGMENT );
    case TY_CHAR :
        return( ALIGN_DWORD );
    default :
        return( 1 );
    }
}


static  segment_id      LocalData( sym_id sym, unsigned_32 size ) {
//=================================================================

    segment_id  seg;
    segment_id  old_seg;

    if( sym->ns.flags & SY_DATA_INIT ) {
        seg = WF77_LDATA;
    } else {
        seg = WF77_UDATA;
    }
    old_seg = BESetSeg( seg );
    DGAlign( SymAlign( sym ) );
    DGLabel( FEBack( sym ) );
    DGUBytes( size );
    BESetSeg( old_seg );
    return( seg );
}


static  unsigned_32     CheckThreshold( sym_id sym, unsigned_32 g_offset ) {
//==========================================================================

    unsigned_32 item_size;
    segment_id  old_seg;

    item_size = _SymSize( sym );
    if( sym->ns.flags & SY_SUBSCRIPTED ) {
        item_size *= sym->ns.si.va.dim_ext->num_elts;
    }
    if( item_size > DataThreshold ) {
        sym->ns.si.va.vi.seg_id = GetGlobalSeg( g_offset );
        old_seg = BESetSeg( sym->ns.si.va.vi.seg_id );
        DGSeek( GetGlobalOffset( g_offset ) );
        DGLabel( FEBack( sym ) );
        BESetSeg( old_seg );
        return( item_size );
    } else {
        sym->ns.si.va.vi.seg_id = LocalData( sym, item_size );
        return( 0 );
    }
}


static  void    DumpSCB( back_handle scb, back_handle data, int len,
                         bool allocatable, signed_32 offset ) {
//=============================================================

// Dump an SCB.

    segment_id  old_seg;

    old_seg = BESetSeg( WF77_LDATA );
    DGAlign( ALIGN_DWORD );
    DGLabel( scb );
    if( data == NULL ) {
        DGIBytes( BETypeLength( T_POINTER ), 0 );
    } else {
        DGBackPtr( data, old_seg, offset, T_POINTER );
    }
    DGInteger( len, T_INTEGER );
    if( allocatable ) {
        DGInteger( ALLOC_STRING, T_UINT_2 );
    }
    BESetSeg( old_seg );
}


static  back_handle     DumpCharVar( sym_id sym ) {
//=================================================

// Dump a character variable.

    back_handle data;

    data = BENewBack( NULL );
    DGLabel( data );
    if( (SubProgId->ns.flags & SY_SUBPROG_TYPE) != SY_BLOCK_DATA ) {
        DumpSCB( FEBack( sym ), data, sym->ns.xt.size, _Allocatable( sym ), 0 );
    }
    return( data );
}


static  void     DumpCharVarInCommon( sym_id sym, com_eq *ce_ext,
                                      segment_id seg, signed_32 offset ) {
//========================================================================

// Dump a character variable into the common block.

    if( (SubProgId->ns.flags & SY_SUBPROG_TYPE) != SY_BLOCK_DATA ) {
        seg = BESetSeg( seg );
        DumpSCB( FEBack( sym ), FEBack( ce_ext->com_blk ), sym->ns.xt.size,
                _Allocatable( sym ), GetComOffset( ce_ext->offset + offset ) );
        BESetSeg( seg );
    }
}


static  void    InitSCB( sym_id sym, cg_name data ) {
//===================================================

    CGDone( CGAssign( SCBPtrAddr( CGFEName( sym, T_CHAR ) ),
            data, T_POINTER ) );
    CGDone( CGAssign( SCBLenAddr( CGFEName( sym, T_CHAR ) ),
            CGInteger( sym->ns.xt.size, T_INTEGER ), T_INTEGER ) );
}


static  void    DumpAutoSCB( sym_id sym, cg_type typ ) {
//======================================================

    if( _Allocatable( sym ) ) {
        CGAutoDecl( sym, T_CHAR_ALLOCATABLE );
    } else {
        CGAutoDecl( sym, T_CHAR );
    }
    if( _Allocatable( sym ) ) {
        InitSCB( sym, CGInteger( 0, T_POINTER ) );
        CGDone( CGAssign( SCBFlagsAddr( CGFEName( sym, T_CHAR ) ),
                CGInteger( ALLOC_STRING, T_UINT_2 ), T_UINT_2 ) );
    } else {
        InitSCB( sym, CGTempName( CGTemp( typ ), typ ) );
    }
    sym->ns.si.va.dim_ext = NULL; // indicate NULL back handle
}


static  void    DumpGlobalSCB( sym_id sym, unsigned_32 g_offset ) {
//=================================================================

    segment_id  old_seg;

    if( _Allocatable( sym ) ) {
        DumpSCB( FEBack( sym ), NULL, 0, TRUE, 0 );
    } else {
        sym->ns.si.va.vi.seg_id = GetGlobalSeg( g_offset );
        old_seg = BESetSeg( sym->ns.si.va.vi.seg_id );
        DGSeek( GetGlobalOffset( g_offset ) );
        sym->ns.si.va.bck_hdl = DumpCharVar( sym );
        if( !(sym->ns.flags & SY_DATA_INIT) ) {
            BEFreeBack( sym->ns.si.va.bck_hdl );
        }
        BESetSeg( old_seg );
    }
}


bool    SCBRequired( sym_id sym ) {
//=================================

    if( !(Options & OPT_DESCRIPTOR) ) return( TRUE );
    if( sym->ns.flags & SY_VALUE_PARM ) return( TRUE );
    if( sym->ns.xt.size != 0 ) return( TRUE );
    return( FALSE );
}


static  unsigned_32     DumpVariable( sym_id sym, unsigned_32 g_offset ) {
//========================================================================

// Allocate space for the given variable.

    unsigned_16 flags;
    uint        size;
    segment_id  old_seg;
    TYPE        typ;
    sym_id      leader;
    signed_32   offset;
    com_eq      *ce_ext;
    cg_type     cgtyp;

⌨️ 快捷键说明

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