📄 cstmt2.c
字号:
return_at_outer_level = 0; /* 28-feb-92 */
DeadCode = 0;
LoopDepth = 0;
LabelIndex = 0;
BlockStack = NULL;
LoopStack = NULL;
SwitchStack = NULL;
#ifdef __SEH__
TryCount = -1;
TryScope = -1;
#endif
startNewBlock();
NextToken(); // skip over {
++SymLevel;
tree = LeafNode( OPR_LABELCOUNT );
AddStmt( tree );
if( GrabLabels() == 0 ) { /* 29-nov-94 */
GetLocalVarDecls();
}
func_result = MakeNewSym( &sym, 'R', CurFunc->sym_type->object, SC_AUTO );
sym.flags |= SYM_FUNC_RETURN_VAR; /* 25-oct-91 */
SymReplace( &sym, func_result );
for( ;; ) {
CompFlags.pending_dead_code = 0;
GrabLabels();
skip_to_next_token = 0;
switch( CurToken ) {
case T_IF:
startNewBlock();
NextToken();
BlockStack->break_label = NextLabel();
JumpFalse( BracketExpr(), BlockStack->break_label );
/* 23-dec-88, only issue msg if ';' is on same line as 'if' */
if( CurToken == T_SEMI_COLON && SrcLineNum == TokenLine ) {
SetErrLoc( ErrFName, TokenLine ); /* 04-nov-91 */
NextToken(); /* look ahead for else keyword */
if( CurToken != T_ELSE ) { /* 02-apr-91 */
ChkUseful(); /* 08-dec-88 */
}
SetErrLoc( NULL, 0 ); /* 04-nov-91 */
break;
}
continue;
case T_WHILE:
NewLoop();
NextToken();
BlockStack->break_label = NextLabel();
if( ! JumpFalse( BracketExpr(), BlockStack->break_label ) ) {
BlockStack->break_label = 0; /* 09-sep-92 */
}
if( CurToken == T_SEMI_COLON ) { /* 08-dec-88 */
if( ! CompFlags.useful_side_effect ) {
CWarn1( WARN_MEANINGLESS, ERR_MEANINGLESS );
}
}
continue;
case T_DO:
NewLoop();
NextToken();
if( CurToken == T_RIGHT_BRACE ) {
CErr1( ERR_STMT_REQUIRED_AFTER_DO );
break;
}
continue;
case T_FOR:
ForStmt();
continue;
case T_SWITCH:
SwitchStmt();
DeadCode = 1;
continue;
case T_CASE:
DeadCode = 0;
CaseStmt();
continue;
case T_DEFAULT:
DefaultStmt();
continue;
case T_BREAK:
BreakStmt();
DeadCode = 1;
if( BlockStack->block_type != T_LEFT_BRACE ) break;
continue;
case T_CONTINUE:
ContinueStmt();
DeadCode = 1;
if( BlockStack->block_type != T_LEFT_BRACE ) break;
continue;
#ifdef __SEH__
case T__LEAVE:
LeaveStmt();
DeadCode = 1;
if( BlockStack->block_type != T_LEFT_BRACE ) break;
continue;
#endif
case T_RETURN:
ReturnStmt( func_result, &return_info );
if( BlockStack->prev_block == NULL ) { /* 28-feb-92 */
return_at_outer_level = 1;
}
MustRecog( T_SEMI_COLON );
if( SymLevel != 1 || CurToken != T_RIGHT_BRACE ||
BlockStack->block_type != T_LEFT_BRACE ) {
if( end_of_func_label == 0 ) {
end_of_func_label = NextLabel();
}
Jump( end_of_func_label );
}
if( BlockStack->block_type != T_LEFT_BRACE ) break;
continue;
case T_GOTO:
GotoStmt();
if( BlockStack->block_type != T_LEFT_BRACE ) break;
continue;
case T_SEMI_COLON:
NextToken();
if( BlockStack->block_type != T_LEFT_BRACE ) break;
continue;
case T_LEFT_BRACE:
LeftBrace();
continue;
case T_RIGHT_BRACE:
if( BlockStack->block_type != T_LEFT_BRACE ) {
CErr1( ERR_MISPLACED_RIGHT_BRACE );
}
if( BlockStack->prev_block == NULL ) {
skip_to_next_token = 1;
} else {
NextToken();
}
break;
case T_STATIC:
case T_EXTERN:
case T_VOID:
case T_INT:
case T_LONG:
case T_SHORT:
case T_FLOAT:
case T_DOUBLE:
case T_EOF:
CErr1( ERR_MISSING_RIGHT_BRACE );
break;
#ifdef __SEH__
case T__TRY:
TryStmt();
continue;
#endif
case T___ASM:
AsmStmt();
continue;
default:
if( DeadCode == 1 ) {
DeadMsg();
}
StmtExpr();
if( BlockStack->block_type != T_LEFT_BRACE ) break;
continue;
}
EndOfStmt();
if( BlockStack == NULL ) break;
if( skip_to_next_token ) NextToken();
}
if( !return_info.with_expr ) { /* no return values present */
if( !CurFunc->naked ){
ChkRetValue();
}
} else if( ! return_at_outer_level ) { /* 28-feb-92 */
if( ! DeadCode && !CurFunc->naked ) {
CWarn( WARN_MISSING_RETURN_VALUE,
ERR_MISSING_RETURN_VALUE, CurFunc->name );
}
}
if( end_of_func_label != 0 ) DropLabel( end_of_func_label );
DeadCode = 0;
tree->op.label_count = LabelIndex;
tree = LeafNode( OPR_FUNCEND );
if( !return_info.with_expr ) {
tree->expr_type = NULL;
tree->op.sym_handle = 0;
} else {
tree->op.sym_handle = func_result;
SetFuncReturnNode( tree );
}
AddStmt( tree );
AddSymList( CurFunc->u.func.locals );
SrcLineNum = TokenLine;
SrcFno = TokenFno;
FreeLabels();
if( skip_to_next_token ) NextToken();
if( CompFlags.generate_prototypes ) {
if( DefFile == NULL ) OpenDefFile();
if( DefFile != NULL &&
CurFunc->stg_class == SC_NULL ) { /* if function exported */
DumpFuncDefn();
}
}
if( Toggles & TOGGLE_INLINE ){
if( Inline_Threshold < NodeCount ){
CurFuncNode->op.func.flags &= ~FUNC_OK_TO_INLINE;
}
}
if( VarParm( CurFunc ) ) {
CurFuncNode->op.func.flags &= ~FUNC_OK_TO_INLINE;
}
NodeCount = 0;
if( CompFlags.addr_of_auto_taken ) { /* 23-oct-91 */
CurFunc->flags &= ~ SYM_OK_TO_RECURSE;
}
}
static void EndOfStmt( void )
{
do {
switch( BlockStack->block_type ) {
case T_LEFT_BRACE:
EndBlock();
break;
case T_IF:
if( CurToken == T_ELSE ) {
ElseStmt();
return;
}
DropBreakLabel();
break;
case T_ELSE:
DropBreakLabel();
break;
case T_WHILE:
DropContinueLabel();
Jump( BlockStack->top_label );
--LoopDepth;
DropBreakLabel();
break;
case T_FOR:
EndForStmt();
--LoopDepth;
DropBreakLabel();
break;
case T_DO:
DropContinueLabel();
MustRecog( T_WHILE );
SrcLineNum = TokenLine; /* 20-dec-88 */
SrcFno = TokenFno;
JumpTrue( BracketExpr(), BlockStack->top_label );
MustRecog( T_SEMI_COLON );
SrcLineNum = TokenLine;
SrcFno = TokenFno;
--LoopDepth;
DropBreakLabel();
break;
case T_SWITCH:
EndSwitch();
DropBreakLabel();
break;
#ifdef __SEH__
case T__TRY:
if( EndTry() ) return;
break;
case T__EXCEPT:
DropBreakLabel();
TryScope = BlockStack->parent_index;
CompFlags.exception_handler = 0;
break;
case T__FINALLY: /* 23-mar-94 */
AddStmt( LeafNode( OPR_END_FINALLY ) );
CompFlags.in_finally_block = 0;
TryScope = BlockStack->parent_index;
break;
#endif
}
PopBlock();
if( BlockStack == NULL ) break;
} while( BlockStack->block_type != T_LEFT_BRACE );
}
static void LeftBrace( void )
{
TREEPTR tree;
TREEPTR first_stmt;
TREEPTR last_stmt;
TREEPTR new_first;
TREEPTR new_last;
/*
<storage> <type> function( <parms> )
{ <- this is SymLevel == 1
(weird code is for SymLevel > 1 )
*/
// DeclList might generate some quads to do some initializers
// if that happens, we want them output after the OPR_NEWBLOCK node
startNewBlock();
NextToken();
++SymLevel;
first_stmt = FirstStmt;
last_stmt = LastStmt;
FirstStmt = NULL;
LastStmt = NULL;
BlockStack->sym_list = 0;
DeclList( &BlockStack->sym_list );
new_first = FirstStmt;
new_last = LastStmt;
FirstStmt = first_stmt;
LastStmt = last_stmt;
if( BlockStack->sym_list != 0 ) {
tree = LeafNode( OPR_NEWBLOCK );
tree->op.sym_handle = BlockStack->sym_list;
AddStmt( tree );
}
if( new_first != NULL ) {
LastStmt->left = new_first;
LastStmt = new_last;
}
}
static void JumpBreak( BLOCKPTR block )
{
if( ! DeadCode ) { /* 05-apr-92 */
if( block->break_label == 0 ) {
block->break_label = NextLabel();
}
Jump( block->break_label );
}
}
static void BreakStmt( void )
{
BLOCKPTR block;
int try_scope;
NextToken();
try_scope = -2;
block = BlockStack;
if( block != NULL ) {
while( block != LoopStack ) {
if( block->block_type == T_SWITCH ) break;
if( block->block_type == T__TRY ) {
try_scope = block->parent_index;
}
block = block->prev_block;
}
}
if( block != NULL ) {
if( try_scope != -2 ) {
UnWindTry( try_scope );
}
JumpBreak( block );
} else {
CErr1( ERR_MISPLACED_BREAK );
}
MustRecog( T_SEMI_COLON );
}
#ifdef __SEH__
static void LeaveStmt( void )
{
BLOCKPTR block;
NextToken();
block = BlockStack;
while( block != NULL ) {
if( block->block_type == T__TRY ) break;
block = block->prev_block;
}
if( block != NULL ) {
JumpBreak( block );
} else {
CErr1( ERR_MISPLACED_LEAVE );
}
MustRecog( T_SEMI_COLON );
}
#endif
static void ContinueStmt( void )
{
BLOCKPTR block;
int try_scope;
NextToken();
if( LoopStack != NULL ) {
if( ! DeadCode ) { /* 05-apr-92 */
try_scope = -2;
block = BlockStack;
while( block != LoopStack ) {
if( block->block_type == T__TRY ) {
try_scope = block->parent_index;
}
block = block->prev_block;
}
if( try_scope != -2 ) {
UnWindTry( try_scope );
}
if( LoopStack->continue_label == 0 ) {
LoopStack->continue_label = NextLabel();
}
Jump( LoopStack->continue_label );
}
} else {
CErr1( ERR_MISPLACED_CONTINUE );
}
MustRecog( T_SEMI_COLON );
}
static void DropBreakLabel( void )
{
if( BlockStack->break_label != 0 ) { /* 05-apr-92 */
DropLabel( BlockStack->break_label );
}
}
static void DropContinueLabel( void )
{
if( BlockStack->continue_label != 0 ) {
DropLabel( BlockStack->continue_label );
}
}
static void DefaultStmt( void )
{
NextToken();
MustRecog( T_COLON );
if( SwitchStack ) {
if( SwitchStack->default_label == 0 ) {
SwitchStack->default_label = NextLabel();
DropLabel( SwitchStack->default_label );
} else {
CErr1( ERR_ONLY_1_DEFAULT );
}
if( CurToken == T_RIGHT_BRACE ) {
CErr1( ERR_STMT_REQUIRED_AFTER_DEFAULT );
}
} else {
CErr1( ERR_MISPLACED_DEFAULT );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -