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 + -
显示快捷键?