⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cstmt2.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    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 + -