fnbody.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,160 行 · 第 1/5 页
C
2,160 行
, SF_REFERENCED | SF_ALIAS | SF_CATCH_ALIAS
, name );
catch_var->u.alias = try_var;
return catch_var;
}
static void parseCatchHandler( // PARSE CATCH STATEMENT
void )
{
DECL_INFO *info; // - info. about parsed catch variable
SYMBOL try_var; // - try variable
SYMBOL catch_var; // - variable for catch
CSTACK *try_block; // - try block for catch
TOKEN_LOCN posn; // - position of catch
TOKEN_LOCN blk; // - position of catch block
SrcFileGetTokenLocn( &posn );
try_block = currFunction->control;
if( ( try_block->id != CS_CATCH ) && ( try_block->id != CS_TRY ) ) {
CErr1( ERR_MISPLACED_CATCH );
try_block = NULL;
}
ExceptionsCheck();
nextYYToken();
mustRecog( T_LEFT_PAREN );
if( CurToken == T_DOT_DOT_DOT ) {
nextYYToken();
info = NULL;
} else {
info = ParseException();
if( info == NULL ) {
try_block = NULL;
}
}
mustRecog( T_RIGHT_PAREN );
currFunction->dead_code = FALSE;
SrcPosnEmitCurrent();
SrcFileGetTokenLocn( &blk );
mustRecog( T_LEFT_BRACE );
startBlock();
SrcPosnEmitCurrent();
if( try_block != NULL ) {
if( info == NULL ) {
makeFNCATCH( NULL, try_block, &posn );
} else {
makeFNCATCH( info->type, try_block, &posn );
try_var = updateTryVar( try_block, info->type );
}
try_block->id = CS_CATCH;
++try_block->u.t.catch_no;
LabelSwitch( try_block->u.t.defn_scope );
SrcFileGetTokenLocn( &posn );
CgFrontSwitchCase( try_block->u.t.defn_scope
, FALSE
, &posn
, try_block->u.t.catch_no );
LabelBlkCatch( &blk, try_block );
if( info != NULL ) {
if( ! try_block->u.t.catch_err ) {
catch_var = makeCatchVar( try_var, info );
if( catch_var != NULL ) {
LabelDeclInited( catch_var );
if( SymRequiresDtoring( catch_var ) ) {
IcEmitDtorAutoSym( catch_var );
}
}
}
FreeDeclInfo( info );
}
}
}
static void parseAsmStmt( TYPE fn_type )
{
PTREE expr;
ParseFlush(); // cleanup YYDRIVER
expr = AsmStmt();
if( expr != NULL ) {
emitStmtExpr( expr );
if( fn_type->flag & TF1_NAKED ) {
FunctionBodyDeadCode();
}
}
}
static boolean endOfStmt( // PROCESS END-OF-STATEMENT
boolean recog ) // - TRUE ==> need to recognize token
{
CSTACK *top_block;
CSTACK *next;
int id;
boolean dead_code;
top_block = currFunction->control;
id = top_block->id;
for(;;) {
switch( id ) {
case CS_BLOCK:
next = top_block->next;
switch( next->id ) {
case CS_SWITCH :
if( top_block->u.b.block_switch ) {
if( next->u.s.default_dropped || ! GetCurrScope()->dtor_naked ) {
if( ! next->u.s.default_dropped ) {
TOKEN_LOCN locn;
locn = SrcPosnEmitCurrent();
genDefaultStmt( next, &locn );
}
next->u.s.imm_block = GetCurrScope();
}
}
if( ! currFunction->dead_code ) {
SrcPosnEmitCurrent();
jumpFwdBlkLabel( &next->outside );
}
break;
case CS_CATCH :
if( ! currFunction->dead_code ) {
SrcPosnEmitCurrent();
jumpFwdBlkLabel( &next->outside );
}
break;
case CS_TRY :
if( ! currFunction->dead_code ) {
SrcPosnEmitCurrent();
jumpFwdBlkLabel( &next->outside );
}
break;
}
endBlock();
break;
case CS_IF:
if( recog ) {
nextYYToken();
recog = FALSE;
}
if( CurToken == T_ELSE ) {
parseElseStmt();
/* Note that the scope opened in parseIfStmt is not
* closed when there is an "else" part. Also note that
* parseElseStmt doesn't open a new scope, so the
* closeScope in the CS_ELSE case below will close the
* scope opened in parseIfStmt.
*
* See 6.4 (3): the name introduced by a declaration
* in a conditoin is in scope until the end of the
* "else" part. BTW, re-declaring that name is not
* allowed by the standard, but the current code
* doesn't catch that.
*/
return recog;
}
if( ! top_block->expr_true ) {
dumpBlkLabel( &top_block->u.i.else_part );
}
closeScope();
CgFrontLabfreeCs( 2 );
break;
case CS_ELSE:
dead_code = currFunction->dead_code;
if( ! top_block->expr_false ) {
dumpOutsideLabel( top_block );
}
if( ! dead_code ) {
currFunction->dead_code = FALSE;
}
closeScope();
CgFrontLabfreeCs( 1 );
break;
case CS_FOR:
case CS_WHILE:
if( top_block->u.l.continue_loop.defn != NULL ) {
dumpBlkLabel( &top_block->u.l.continue_loop );
}
closeScope();
doJUMP( IC_LABEL_CS, O_GOTO, top_block->u.l.top_loop );
dumpOutsideLabel( top_block );
if( id == CS_FOR && ! CompFlags.use_old_for_scope ) {
closeScope();
}
CgFrontLabfreeCs( 3 );
break;
case CS_DO:
if( recog ) {
nextYYToken();
recog = FALSE;
}
mustRecog( T_WHILE );
if( top_block->u.l.continue_loop.defn != NULL ) {
dumpBlkLabel( &top_block->u.l.continue_loop );
}
if( EXPR_ANAL_OK == parseBracketExpr( &AnalyseBoolExpr ) ) {
ensureLiveCode();
if( top_block->expr_false ) {
CgFrontCode( IC_EXPR_TRASH );
} else if( top_block->expr_true ) {
CgFrontCode( IC_EXPR_TRASH );
doJUMP( IC_LABEL_CS, O_GOTO, top_block->u.l.top_loop );
} else {
jumpBlkLabel( &top_block->outside, O_IF_FALSE );
doJUMP( IC_LABEL_CS, O_GOTO, top_block->u.l.top_loop );
}
} else {
doJUMP( IC_LABEL_CS, O_GOTO, top_block->u.l.top_loop );
currFunction->dead_code = FALSE;
}
mustRecog( T_SEMI_COLON );
dumpOutsideLabel( top_block );
CgFrontLabfreeCs( 3 );
break;
case CS_SWITCH:
closeScope();
if( NULL == top_block->u.s.imm_block ) {
if( ! top_block->u.s.default_dropped ) {
CgFrontCodeUint( IC_SWITCH_OUTSIDE
, top_block->outside.id - 1 );
if( top_block->outside.defn == NULL ) {
top_block->outside.defn = LabelAllocLabDef();
}
}
if( ( ! currFunction->dead_code )
&&( ! top_block->u.s.block_after ) ) {
jumpFwdBlkLabel( &top_block->outside );
}
}
SrcPosnEmit( &top_block->u.s.switch_locn );
CgFrontSwitchEnd();
SrcPosnEmitCurrent();
dumpOutsideLabel( top_block );
CgFrontLabfreeCs( 1 );
if( top_block->u.s.cases != NULL ) {
RingCarveFree( carveSWCASE, &(top_block->u.s.cases) );
} else {
// make sure switch is valid before warning
if( top_block->u.s.type != NULL ) {
SetErrLoc( &top_block->u.s.switch_locn );
CErr1( WARN_SWITCH_NO_CASE_LABELS );
}
}
closeScope();
break;
case CS_TRY:
if( recog ) {
nextYYToken();
recog = FALSE;
}
if( CurToken == T_CATCH ) return recog;
if( ! top_block->u.t.catch_err ) {
CErr1( ERR_CATCH_MISSING );
}
completeTry( top_block );
break;
case CS_CATCH:
if( recog ) {
nextYYToken();
recog = FALSE;
}
if( CurToken == T_CATCH ) return recog;
completeTry( top_block );
break;
}
endControl();
top_block = currFunction->control;
if( top_block == NULL ) return recog;
id = top_block->id;
if( id == CS_FUNCTION || id == CS_BLOCK ) break;
}
return recog;
}
// Scalar return values are assigned to a magic symbol.
//
// Class return values are allocated in the caller. The magic symbol is
// in the function scope, under the magic name (as the last parameter).
//
static void insertFunctionReturn( SYMBOL func )
{
TYPE ret; // - return type
TYPE base; // - base type for return
SYMBOL retn_sym; // - return symbol
ret = FunctionDeclarationType( func->sym_type );
base = TypedefModifierRemove( ret->of );
switch( ObjModelFunctionReturn( ret ) ) {
case OMR_VOID :
break;
case OMR_SCALAR :
case OMR_CLASS_VAL :
retn_sym = SymAllocReturn( GetCurrScope(), base );
CgFrontCodePtr( IC_FUNCTION_RETN, retn_sym );
break;
case OMR_CLASS_REF :
if( NULL == SymFunctionReturn() ) {
retn_sym = SymAllocReturn( GetCurrScope()->enclosing, base );
CgFrontCodePtr( IC_FUNCTION_RETN, retn_sym );
}
break;
}
}
static void exceptSpec( // GENERATE AN EXCEPTION SPECIFICATION
TYPE except ) // - type of spec
{
boolean err_occurred; // - TRUE ==> error during type-sig
TypeSigFind( 0, except, NULL, &err_occurred );
#ifndef NDEBUG
if( err_occurred ) {
CFatal( "setExceptionSpecs -- unexpected error" );
}
#endif
CgFrontCodePtr( IC_EXCEPT_SPEC, except );
ScopeKeep( GetCurrScope() );
}
static void setExceptionSpecs( // SET EXCEPTION SPEC.S FOR FUNCTION
SYMBOL func ) // - the function
{
TYPE *excepts; // - vector of exception specifications
TYPE except; // - current exception specification
boolean no_excepts_allowed; // - TRUE ==> no exceptions allowed
excepts = SymFuncArgList( func )->except_spec;
if( excepts != NULL ) {
ExceptionsCheck();
no_excepts_allowed = TRUE;
for( ; ; ) {
except = *excepts++;
if( NULL == except ) break;
no_excepts_allowed = FALSE;
exceptSpec( except );
}
if( no_excepts_allowed ) {
exceptSpec( NULL );
}
FunctionHasRegistration();
}
}
static void initFunctionData( // INITIALIZE FUNCTION DATA (BEFORE FNSTARTUP)
SYMBOL func, // - function
FUNCTION_DATA *f ) // - data
{
char *fn_name;
CtxFunction( func );
f->next = currFunction;
currFunction = f;
f->fn_scope = NULL;
f->depth = 0;
f->outer_depth = 0;
f->control = NULL;
f->labels = NULL;
f->block_count = 0;
f->flag_count = 0;
f->init_var.var = NULL;
f->init_var.mask = 1;
f->access_errs = NULL;
f->retn_opt_sym = NULL;
f->dead_code = FALSE;
f->dead_diagnosed = FALSE;
f->always_dead_code = FALSE;
f->is_ctor = FALSE;
f->is_dtor = FALSE;
f->is_assign = FALSE;
f->is_defarg = FALSE;
f->ret_reqd = FALSE;
f->has_mem_init = FALSE;
f->has_state_tab = FALSE;
f->can_throw = FALSE;
f->does_throw = FALSE;
f->ctor_test = FALSE;
f->floating_ss = FALSE;
f->retn_opt = TRUE;
fn_name = func->name->name;
if( fn_name == CppConstructorName() ) {
f->is_ctor = TRUE;
} else if( fn_name == CppDestructorName() ) {
f->is_dtor = TRUE;
} else if( fn_name == CppOperatorName( CO_EQUAL ) ) {
f->is_assign = TRUE;
}
}
static void doFnStartup( SYMBOL func
, FUNCTION_DATA *fdata
, REWRITE *mem_initial
, TOKEN_LOCN *srcposn
, enum special_func flags )
{
PTREE mem_init;
fdata->fn_scope = GetCurrScope();
func->flag |= SF_INITIALIZED;
if( flags & FUNC_NO_STACK_CHECK ) {
/* in case the type was derived from a stack-checked function */
func->sym_type = RemoveFunctionFlag( func->sym_type, TF1_STACK_CHECK );
} else {
if( PragToggle.check_stack ) {
func->sym_type = AddFunctionFlag( func->sym_type, TF1_STACK_CHECK );
}
}
fdata->init_state_tab = CgFrontFuncOpen( func, srcposn );
CgSegIdFunction( func );
LabelInitFunc( &fdata->label_mem );
startBlock();
setExceptionSpecs( func );
insertFunctionReturn( func );
if( fdata->is_ctor ) {
mem_init = ClassMemInit( func, mem_initial );
CtorPrologue( func, mem_init, &startBlock );
FnRetnOptOff();
startBlock();
} else if( fdata->is_dtor ) {
DtorPrologue( func, &fdata->end_dtor, &fdata->dtor_beg );
FnRetnOptOff();
startBlock();
}
fdata->outer_depth = fdata->depth;
}
void FunctionBodyStartup( // COMMON START-UP FOR ALL COMPILED FUNCTIONS
SYMBOL func, // - function being compiled
FUNCTION_DATA *f, // - function data for current function
enum special_func flags ) // - extra flags
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?