cgbkscop.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,225 行 · 第 1/3 页
C
1,225 行
/****************************************************************************
*
* 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 "plusplus.h"
#include "cgfront.h"
#include "cgback.h"
#include "errdefns.h"
#include "codegen.h"
#include "cgbackut.h"
#include "ring.h"
#include "carve.h"
#include "vstk.h"
#include "callgrph.h"
#include "cdopt.h"
#include "reposit.h"
#include "scoperes.h"
//typedef struct unr_usage UNR_USAGE; // unresolved usage
typedef struct scope_res SCOPE_RES; // unresolved scope
typedef struct res_act RES_ACT; // resolution actions
#define USAGE_DEFS /* unresolved usages */ \
/* - function usages: */ \
USAGE_DEF( FNUSE_CALL ) /* - - call in a scope */ \
,USAGE_DEF( FNUSE_CALL_TEMP ) /* - - call in statement scope */ \
,USAGE_DEF( FNUSE_CALL_SCOPE ) /* - - call in block scope */ \
,USAGE_DEF( FNUSE_CALL_CTOR ) /* - - ctor call in statement scope */ \
,USAGE_DEF( FNUSE_SCOPE ) /* - - scope resolution req'd */ \
/* - scope usages: */ \
,USAGE_DEF( SCUSE_DTOR_BLK ) /* - - dtor: block */ \
,USAGE_DEF( SCUSE_DTOR_TEMP ) /* - - dtor: temporary */ \
,USAGE_DEF( SCUSE_DTOR_COMPONENT ) /* - - dtor: component */
#define RES_DEFS /* type of resolution */ \
RES_DEF( RES_FN_TH ) /* - function resolved to be SF_LONGJUMP */ \
,RES_DEF( RES_FN_NT ) /* - function resolved to be SF_NO_LONGJUMP */ \
,RES_DEF( RES_SC_SG ) /* - scope resolved as STAB_GEN */ \
,RES_DEF( RES_SC_NG ) /* - scope resolved as ~ STAB_GEN */
typedef enum { // UNR_USE -- unresolved usage
#define USAGE_DEF(a) a
USAGE_DEFS
#undef USAGE_DEF
, MAX_USAGE_DEF
} UNR_USE;
typedef enum { // RES_TYPE -- type of resolution
#define RES_DEF(a) a
RES_DEFS
#undef RES_DEF
, MAX_RES_DEF
} RES_TYPE;
struct unr_usage // UNR_USAGE -- unresolved usage
{ UNR_USAGE* next; // - next in ring
SCOPE scope; // - scope referenced
union { // - one of:
CALLNODE* node; // - - CALLNODE for function used
SYMBOL fun; // - - SYMBOL for function used
SCOPE_RES* res_scope; // - - scope to be resolved
void* unresolved; };// - - general entry
UNR_USE type; // - type of usage
unsigned :0; // - alignment
};
struct scope_res // SCOPE_RES -- unresolved scope
{ SCOPE_RES* next; // - next scope resolution
SCOPE_RES* enclosing; // - enclosing scope
SCOPE scope; // - the scope in question
UNR_USAGE* unresolved; // - ring of unresolved
int toresolve; // - # items to be resolved
CALLNODE* func; // - function containing scope
DT_METHOD dtm; // - function dtor method
unsigned : 0; // - alignment
unsigned dtorables; // - # dtorable items in scope
unsigned statement : 1; // - TRUE ==> is statement scope
unsigned dtor_ct : 1; // - TRUE ==> has can-throw dtorable
unsigned call_ct : 1; // - TRUE ==> has can-throw call
unsigned scanning : 1; // - TRUE ==> is being scanned now
unsigned gen_stab : 1; // - TRUE ==> scan detected state-table req'd
unsigned scope_throw : 1; // - TRUE ==> IC_SCOPE_THROW in scope
unsigned : 0; // - alignment
};
struct res_act // RES_ACT -- resolution action
{ RES_TYPE type; // - type of resolution
unsigned :0; // - alignment
union // - one of:
{ CALLNODE* node; // - - unresolved function
SCOPE_RES* scope; // - - unresolved scope
};
};
static VSTK_CTL actions; // actions pending
static carve_t carveUsage; // carver: scope uses
static carve_t carveScRes; // carver: unresolved scopes
static VSTK_CTL open_scopes; // open scopes
static SCOPE_RES* scopes; // unresolved scopes
#ifndef NDEBUG
#include "dbg.h"
#include "pragdefn.h"
static char const * usage_names[] = {
#define USAGE_DEF(a) # a
USAGE_DEFS
#undef USAGE_DEF
};
static char const * res_names[] = {
#define RES_DEF(a) # a
RES_DEFS
#undef RES_DEF
};
#define strcase( v ) case v: name = #v; break;
static void _print( char const * msg )
{
if( PragDbgToggle.callgraph_scan ) {
printf( msg );
}
}
static char const* _res_type( RES_TYPE type )
{
return ( type < MAX_RES_DEF ) ? res_names[ type ] : "BAD RES_TYPE";
}
static char const* _unr_use( UNR_USE type )
{
return ( type < MAX_USAGE_DEF ) ? usage_names[ type ] : "BAD UNR_USE";
}
static void _printAction( RES_ACT const * ra, char const * msg )
{
if( PragDbgToggle.callgraph_scan
&& ra != NULL ) {
printf( "RES_ACT[%x] %s %x %s\n"
, ra
, _res_type( ra->type )
, ra->node
, msg );
}
}
static void _printScopeRes( SCOPE_RES const *sr, char const * msg )
{
if( PragDbgToggle.callgraph_scan ) {
printf( "SCOPE_RES[%x] %s\n"
" next[%x] enclosing[%x] scope[%x] unresolved[%x]\n"
" toresolve[%d] func[%x] dtm[%x]\n"
" statement-%d dtor_ct-%d call_ct-%d scanning-%d gen_stab-%d"
" scope_throw-%d\n"
, sr
, msg
, sr->next
, sr->enclosing
, sr->scope
, sr->unresolved
, sr->toresolve
, sr->func
, sr->dtm
, sr->statement
, sr->dtor_ct
, sr->call_ct
, sr->scanning
, sr->gen_stab
, sr->scope_throw );
}
}
static void _printUnrUsage( UNR_USAGE const *fu, char const * msg )
{
if( PragDbgToggle.callgraph_scan ) {
printf( "UNR_USAGE[%x] %s %x %s\n"
, fu
, _unr_use( fu->type )
, fu->node
, msg );
}
}
static void _printScopeResAll( SCOPE_RES const *sr, char const * msg )
{
UNR_USAGE* su;
if( PragDbgToggle.callgraph_scan ) {
_printScopeRes( sr, msg );
RingIterBeg( sr->unresolved, su ) {
_printUnrUsage( su, msg );
} RingIterEnd( su );
}
}
static void _printFunction( SYMBOL fun, char const * msg )
{
if( PragDbgToggle.callgraph_scan ) {
printf( "%s [%x] %s\n"
, msg
, fun
, DbgSymNameFull( fun ) );
}
}
static boolean _printCallNode
( CALLGRAPH* ctl
, CALLNODE* node )
{
UNR_USAGE *fu;
ctl = ctl;
if( PragDbgToggle.callgraph_scan ) {
printf( "CALLNODE[%x] unresolved[%x] %s\n"
, node
, node->unresolved
, DbgSymNameFull( node->base.object ) );
RingIterBeg( node->unresolved, fu ) {
_printUnrUsage( fu, "" );
} RingIterEnd( fu );
}
return FALSE;
}
#else
#define _print(a)
#define _res_type(a)
#define _unr_use(a)
#define _printAction(a,b)
#define _printScopeRes(a,b)
#define _printScopeResAll(a,b)
#define _printFnUsage(a,b)
#define _printScUsage(a,b)
#define _printFunction(a,b)
#define _printCallNode(a,b)
#define _printUnrUsage(a,b)
#endif
static SYMBOL symDefaultBase( // GET ACTUAL SYMBOL FOR A DEFAULT
SYMBOL fun ) // - function symbol
{
if( fun != NULL ) {
fun = SymDefaultBase( fun );
}
return fun;
}
static SCOPE_RES* openScopesTop // GET TOP OF OPEN-SCOPES STACK
( void )
{
SCOPE_RES** a_sr; // - addr[ unresolved scope ]
SCOPE_RES* sr; // - unresolved scope
a_sr = VstkTop( &open_scopes );
if( a_sr == NULL ) {
sr = NULL;
} else {
sr = *a_sr;
}
return sr;
}
static SCOPE_RES* openScopesPush // PUSH OPEN-SCOPES STACK
( void )
{
SCOPE_RES** a_sr; // - addr[ unresolved scope ]
SCOPE_RES* sr; // - unresolved scope
SCOPE_RES* enclosing; // - enclosing scope
enclosing = openScopesTop();
a_sr = VstkPush( &open_scopes );
sr = CarveAlloc( carveScRes );
*a_sr = sr;
sr->enclosing = enclosing;
if( NULL != enclosing ) {
++ enclosing->toresolve;
sr->scope_throw = enclosing->scope_throw;
} else {
sr->scope_throw = FALSE;
}
return sr;
}
static SCOPE_RES* openScopesPop // POP OPEN-SCOPES STACK
( void )
{
SCOPE_RES** a_sr; // - addr[ unresolved scope ]
SCOPE_RES* sr; // - unresolved scope
a_sr = VstkPop( &open_scopes );
if( a_sr == NULL ) {
sr = NULL;
} else {
sr = *a_sr;
}
return sr;
}
#define OpenScopesIterBeg( it ) \
{ SCOPE_RES** a_sr; \
VstkIterBeg( &open_scopes, a_sr ) { \
it = *a_sr;
#define OpenScopesIterEnd( it ) \
} \
}
static RES_ACT* pushAction // PUSH ACTION
( RES_TYPE type ) // - type of action
{
RES_ACT* res = VstkPush( &actions );
res->type = type;
return res;
}
static RES_ACT* pushActionCaller// PUSH FUNCTION-RELATED ACTION
( CALLNODE* node // - call node
, RES_TYPE type ) // - type of action
{
RES_ACT* res; // - new entry
if( NULL == node->unresolved ) {
res = NULL;
} else {
res = pushAction( type );
res->node = node;
}
return res;
}
static CALLNODE* makeThrowFun // FUNCTION BECOMES A THROWING FUNCTION
( CALLNODE* owner ) // - owner
{
SYMBOL fun; // - owner symbol
RES_ACT* res; // - resolution action
fun = owner->base.object;
fun = symDefaultBase( fun );
DbgVerify( ! ( fun->flag & SF_NO_LONGJUMP )
, "makeThrowFun -- has SF_NO_LONGJUMP" );
if( ! ( fun->flag & SF_LONGJUMP ) ) {
fun->flag |= SF_LONGJUMP;
res = pushActionCaller( owner, RES_FN_TH );
_printAction( res, "Function resolved: throwable" );
CgResolve();
}
return owner;
}
static CALLNODE* makeNonThrowFun// FUNCTION BECOMES A NON-THROWING FUNCTION
( CALLNODE* owner ) // - owner
{
SYMBOL fun; // - owner symbol
RES_ACT* res; // - resolution action
fun = owner->base.object;
fun = symDefaultBase( fun );
DbgVerify( ! ( fun->flag & SF_LONGJUMP )
, "makeNonThrowFun -- has SF_LONGJUMP" );
if( ! ( fun->flag & SF_NO_LONGJUMP ) ) {
fun->flag |= SF_NO_LONGJUMP;
res = pushActionCaller( owner, RES_FN_NT );
_printAction( res, "Function resolved: non-throwable" );
CgResolve();
}
return owner;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?