cginfo.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,577 行 · 第 1/4 页
C
1,577 行
/****************************************************************************
*
* 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: Callback functions invoked from cg - communicate
* auxiliary information to the backend.
*
****************************************************************************/
#include "plusplus.h"
#include "compcfg.h"
#include "tgtenv.h"
#include <process.h>
#include <limits.h>
#include "preproc.h"
#include "cgdata.h"
#include "codegen.h"
#include "errdefns.h"
#include "memmgr.h"
#include "pragdefn.h"
#include "pdefn2.h"
#include "iosupp.h"
#include "segment.h"
#include "cginfo.h"
#include "cgback.h"
#include "rtfuns.h"
#include "rtfuncod.h"
#include "module.h"
#include "srcfile.h"
#include "symdbg.h"
#include "dwarfdbg.h"
#include "extrf.h"
#include "ctexcept.h"
#include "name.h"
#include "cginlibs.h"
#include "cginimps.h"
#include "initdefs.h"
#include "iosupp.h"
#include "cppexit.h"
#include "cgbackut.h"
#include "cginmisc.h"
#include "pragdefn.h"
#include "specfuns.h"
#include "autodept.h"
#if _CPU == 386
extern struct inline_funcs Fs_Functions[]; // FS PRAGMAS
#endif
static SYMBOL lastFunctionOutOfMem;
#define _HAS_EXE_MAIN ( CompFlags.has_main \
|| CompFlags.has_winmain \
)
#define _HAS_DLL_MAIN ( CompFlags.bd_switch_used \
|| CompFlags.has_libmain \
|| CompFlags.has_dllmain \
)
#define _HAS_ANY_MAIN ( _HAS_EXE_MAIN \
|| _HAS_DLL_MAIN \
)
static AUX_INFO *getLangInfo( // GET LANGUAGE INFO. FOR SYMBOL
SYMBOL sym ) // - the symbol
;
static void init( // MODULE INITIALIZATION
INITFINI* def ) // - definition
{
def = def;
CompFlags.low_on_memory_printed = FALSE;
}
INITDEFN( cg_info, init, InitFiniStub )
char *FEName( // RETURN THE SYMBOL'S NAME
SYMBOL sym )
{
char *sym_name; // - symbol's name
if( sym == NULL || sym->name == NULL ) {
sym_name = "!NULL!";
} else {
sym_name = CppNameDebug( sym );
}
return( sym_name );
}
void FEMessage( // MESSAGES FROM CODE-GENERATOR
msg_class class, // - message class
void *parm ) // - parameter
{
switch( class ) {
case MSG_SYMBOL_TOO_LONG:
CErr2p( WARN_MANGLED_NAME_TOO_LONG, (SYMBOL)parm );
break;
case MSG_BLIP:
if( CompFlags.ide_console_output ) {
if( ! CompFlags.quiet_mode ) {
putchar( '.' );
fflush( stdout );
}
}
break;
case MSG_INFO_FILE:
case MSG_INFO_PROC:
if( CompFlags.ide_console_output ) {
if( ! CompFlags.quiet_mode ) {
MsgDisplayLine( parm );
}
}
break;
case MSG_CODE_SIZE:
if( CompFlags.ide_console_output ) {
if( ! CompFlags.quiet_mode ) {
char buffer[16];
utoa( (unsigned)parm, buffer, 10 );
MsgDisplayLineArgs( "\rCode size: "
, buffer
, NULL );
}
}
break;
case MSG_DATA_SIZE:
break;
case MSG_ERROR:
CErr2p( ERR_USER_ERROR_MSG, parm );
break;
case MSG_FATAL:
CErr2p( ERR_FATAL_ERROR, parm );
CppExit( 1 ); /* exit to DOS do not pass GO */
break;
case MSG_BAD_PARM_REGISTER:
CErr2( ERR_BAD_PARM_REGISTER, (int)parm );
break;
case MSG_BAD_RETURN_REGISTER:
CErr2p( ERR_BAD_RETURN_REGISTER, FEName( (SYMBOL)parm ) );
break;
case MSG_SCHEDULER_DIED:
case MSG_REGALLOC_DIED:
case MSG_SCOREBOARD_DIED:
if( ! (GenSwitches & NO_OPTIMIZATION) ) {
if( lastFunctionOutOfMem != parm ) {
lastFunctionOutOfMem = parm;
CErr2p( WARN_CG_MEM_PROC, FEName( (SYMBOL)parm ) );
}
}
break;
case MSG_PEEPHOLE_FLUSHED:
if( ! (GenSwitches & NO_OPTIMIZATION) ) {
if( ! CompFlags.low_on_memory_printed ) {
CompFlags.low_on_memory_printed = TRUE;
CErr1( WARN_CG_MEM_PEEPHOLE );
}
}
break;
case MSG_BACK_END_ERROR:
CErr2( ERR_BACK_END_ERROR, (int)parm );
break;
case MSG_BAD_SAVE:
CErr2p( ERR_BAD_SAVE, FEName( (SYMBOL)parm ) );
break;
case MSG_NO_SEG_REGS:
CErr2p( ERR_NO_SEG_REGS, FEName( (SYMBOL)parm ) );
break;
}
}
char *FEModuleName( // RETURN MODULE NAME
void )
{
return( ModuleName );
}
int FETrue( // RETURN TRUE
void )
{
return( 1 );
}
int FESymIndex( // STUB EXCEPT FOR JAVA
SYMBOL sym )
{
return( 0 );
}
int FECodeBytes( // STUB EXCEPT FOR JAVA
const char *buffer,
int len )
{
return( FALSE );
}
static fe_attr basic_attributes(// GET BASIC ATTRIBUTES
SYMBOL sym ) // - symbol
{
fe_attr attr; // - attribute
switch( sym->id ) {
case SC_EXTERN:
attr = FE_STATIC | FE_GLOBAL | FE_IMPORT ;
break;
case SC_PUBLIC:
attr = FE_STATIC | FE_GLOBAL;
break;
case SC_STATIC:
attr = FE_STATIC | FE_VISIBLE;
break;
default :
attr = 0;
break;
}
return( attr );
}
fe_attr FEAttr( // GET SYMBOL ATTRIBUTES
SYMBOL sym ) // - symbol
{
fe_attr attr; // - attribute
fe_attr mask; // - remove these attributes
SYMBOL_NAME sym_name; // - symbol name of symbol
SCOPE scope; // - scope of symbol
char *name; // - name of symbol
TYPE unmod_type; // - type for symbol
type_flag mod_flags; // - modifier flags
scf_mask scf_info; // - sym comdat function info
attr = 0;
mask = 0;
name = NULL;
sym_name = sym->name;
if( sym_name != NULL ) {
scope = sym_name->containing;
if( ScopeEnclosedInUnnamedNameSpace( scope ) ) {
mask = FE_GLOBAL;
}
name = sym_name->name;
if( name != NULL ) {
if( IsNameDummy( name ) ) {
attr |= FE_INTERNAL;
}
}
}
unmod_type = TypeModFlags( sym->sym_type, &mod_flags );
if( unmod_type->id == TYP_FUNCTION ) {
attr |= FE_PROC;
if( !IsCppNameInterestingDebug( sym ) ){
attr |= FE_COMPILER;
}
if( SymIsInitialized( sym ) ) {
scf_info = SymComdatFunInfo( sym );
if( scf_info & SCF_COMDAT ) {
if( scf_info & SCF_STATIC ) {
mask = FE_COMMON | FE_GLOBAL;
} else {
attr |= FE_COMMON;
}
}
if( unmod_type->flag & TF1_NAKED ) {
attr |= FE_NAKED;
}
if( CompFlags.unique_functions ) {
attr |= FE_UNIQUE;
}
} else {
attr |= FE_IMPORT;
}
if( TypeHasEllipsisArg( unmod_type ) ) {
attr |= FE_VARARGS;
}
} else {
if( SymIsInitialized( sym ) ) {
if( SymIsComdatData( sym ) ) {
attr |= FE_COMMON;
}
}
if( mod_flags & TF1_STAY_MEMORY ) {
attr |= FE_VOLATILE;
}
if( mod_flags & TF1_CONST ) {
attr |= FE_CONSTANT;
}
if( mod_flags & TF1_THREAD ) {
attr |= FE_THREAD_DATA;
}
if( ! ( mod_flags & TF1_HUGE ) ) {
attr |= FE_ONESEG;
}
}
// don't export addressability thunks
if(( sym->flag & SF_ADDR_THUNK ) == 0 ) {
if( mod_flags & (TF1_DLLEXPORT|TF1_DLLIMPORT) ) {
if( SymIsInitialized( sym ) ) {
if( mod_flags & TF1_DLLEXPORT ) {
attr |= FE_DLLEXPORT;
}
} else {
if( mod_flags & TF1_DLLIMPORT ) {
// fill vftables with 'S::f' not '__imp_S::f'
if( ! SymIsVirtual( sym ) ) {
attr |= FE_DLLIMPORT;
}
}
}
}
}
// change to this: if( sym->flag & SF_CG_ADDR_TAKEN ) {
if( sym->flag & SF_CG_ADDR_TAKEN ) {
attr |= FE_ADDR_TAKEN;
}
if( SymIsClassMember( sym ) ) {
if( SymIsStatic( sym ) && IsCppMembPtrOffsetName( name ) ) {
attr |= FE_UNIQUE;
}
if( SymIsInitialized( sym ) ) {
attr |= FE_STATIC;
/* only set FE_GLOBAL if it's not an in-class
* initialization of a const static member */
if( ! ( sym->flag & SF_IN_CLASS_INIT ) ) {
attr |= FE_GLOBAL;
}
} else {
attr |= FE_STATIC | FE_GLOBAL | FE_IMPORT ;
}
} else {
attr |= basic_attributes( sym );
}
if( mod_flags & TF1_COMMON
&& 0 == mask ) {
/* should never execute this but just in case ... */
attr |= FE_COMMON | FE_GLOBAL;
} else if( attr & FE_COMMON ) {
attr |= FE_GLOBAL;
}
DbgAssert( mask == 0 || ( attr & FE_COMMON ) == 0 );
attr &= ~mask;
#ifndef NDEBUG
if( PragDbgToggle.auxinfo ) {
printf( "FeAttr( %x = %s ) -> %x\n"
, sym
, GetMangledName( sym )
, attr );
}
#endif
return( attr );
}
segment_id FESegID( // GET SEGMENT ID FOR SYMBOL
SYMBOL sym ) // - symbol
{
return( CgSegId( sym ) );
}
int FELexLevel( // GET LEXICAL LEVEL OF SYMBOL
SYMBOL sym ) // - the symbol
{
sym = sym;
return( 0 );
}
int FEParmType( // ARGUMENT PROMOTION ?
SYMBOL func, // function being called
SYMBOL parm, // parameter being passed
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?