コード例 #1
0
void CpRemBlock( void )
{
    sym_id      rb;

    if( EmptyCSList() == FALSE ) {
        StmtErr( SP_BLK_IN_STRUCTURE );
    }
    AddCSNode( CS_REMOTEBLOCK );
    CSHead->bottom = NextLabel();
    CSHead->branch = NextLabel();
    GBranch( CSHead->branch );
    if( BlockName( SY_RB_DEFINED ) ) {
        rb = CITNode->sym_ptr;
        if( ( rb->ns.flags & SY_REFERENCED ) == 0 ) {
            rb->ns.si.rb.ref_count = 0;
        }
        rb->ns.si.rb.ref_count++;
        CSHead->cs_info.rb = rb;
        GStartBlock();
        BIStartRBorEP( rb );
    }
    AdvanceITPtr();
    ReqEOS();
    StNumbers.in_remote = TRUE;
    ClearRem();
}
コード例 #2
0
ファイル: csloops.c プロジェクト: bhanug/open-watcom-v2
static void InitLoop( int loop_type )
{
    AddCSNode( loop_type );
    CSHead->branch = NextLabel();
    CSHead->bottom = NextLabel();
    CSHead->cycle = NextLabel();
    GLabel( CSHead->branch );
}
コード例 #3
0
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 )
                        || ( 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 );
}
コード例 #4
0
static void EndSwitch( void )
{
    SWITCHPTR   sw;
//    CASEPTR   ce;

    sw = SwitchStack;
    SwitchStack = sw->prev_switch;
    if( sw->default_label == 0 ) {
        if( BlockStack->break_label == 0 ) {
            sw->default_label = NextLabel();
            DropLabel( sw->default_label );
        } else {
            sw->default_label = BlockStack->break_label;
        }
    }
//      if( sw->case_list == NULL ) {
//          CWarn1( WARN_EMPTY_SWITCH, ERR_EMPTY_SWITCH );
//      }
#if 0
    for( ; ce = sw->case_list; ) {
        sw->case_list = ce->next_case;
        CMemFree( ce );
    }
    CMemFree( sw );
#endif
}
コード例 #5
0
static bool BlockName( unsigned_16 rb_defined )
{
    sym_id      sym_ptr;
    unsigned_16 flag_mask;
    bool        rb_name;

    CSExtn();
    rb_name = FALSE;
    if( ReqName( NAME_REM_BLOCK ) ) {
        sym_ptr = LkSym();
        if( ( sym_ptr->ns.flags & ~SY_REFERENCED ) == 0 ) {
            sym_ptr->ns.si.rb.entry = NextLabel();
            sym_ptr->ns.flags = RB_FLAGS;
        }
        flag_mask = (unsigned_16)~( SY_RB_DEFINED | SY_REFERENCED );
        if( ( ( sym_ptr->ns.flags & flag_mask ) == RB_FLAGS ) &&
            ( ( sym_ptr->ns.flags & rb_defined ) == 0 ) ) {
            sym_ptr->ns.flags |= rb_defined;
            rb_name = TRUE;
        } else {
            IllName( sym_ptr );
        }
    }
    return( rb_name );
}
コード例 #6
0
ファイル: csif.c プロジェクト: Azarien/open-watcom-v2
void    CpElseIf(void) {
//==================

// Process an ELSEIF statement.

    if( ( CSHead->typ == CS_IF ) || ( CSHead->typ == CS_ELSEIF ) ) {
        GBranch( CSHead->bottom );
        GLabel( CSHead->branch );
        FreeLabel( CSHead->branch );
        CSHead->typ = CS_ELSEIF;
        CSHead->branch = NextLabel();
        CSHead->block = ++BlockNum;
    } else if( CSHead->typ == CS_ELSE ) {
        Error( IF_ELSE_LAST );
    } else {
        Match();
    }
    CSCond( CSHead->branch );
    if( RecKeyWord( "THEN" ) ) {
        AdvanceITPtr();
        ReqEOS();
    } else {
        Error( IF_NO_THEN );
    }
}
コード例 #7
0
ファイル: rststmt.c プロジェクト: ABratovic/open-watcom-v2
sym_id  STStmtNo( unsigned_32 stmnt_no ) {
//========================================

// Search the symbol table for a statement number. If it is not
// already in the symbol table, add it to the symbol table.

    sym_id      ste_ptr;
    unsigned_32 st_number;

    ste_ptr = SList;
    while( ste_ptr != NULL ) {
        st_number = GetStmtNum( ste_ptr );
        if( st_number == stmnt_no ) {
            return( ste_ptr );
        }
        ste_ptr = ste_ptr->u.st.link;
    }
    ste_ptr = FMemAlloc( sizeof( stmtno ) );
    ste_ptr->u.st.block = CSHead->block;
    ste_ptr->u.st.flags = SN_INIT;
    if( stmnt_no > 65535 ) {
        stmnt_no -= 65535;
        ste_ptr->u.st.flags |= SN_ADD_65535;
    }
    ste_ptr->u.st.number = stmnt_no;
    ste_ptr->u.st.address = NextLabel();
    ste_ptr->u.st.ref_count = 0;
    ste_ptr->u.st.link = SList;
    SList = ste_ptr;
    return( ste_ptr );
}
コード例 #8
0
static void AddCaseLabel( unsigned long value )
{
    CASEPTR         ce, prev_ce, new_ce;
    unsigned long   old_value, converted_value;
    TREEPTR         tree;
    char            buffer[12];

    prev_ce = NULL;
#if 0
    leaf.u.ulong_konst = value;
    leaf.data_type = SwitchStack->case_type;
    SetLeafType( &leaf, 1 );
//      converted_value = value & SwitchStack->case_mask;
    converted_value = leaf.u.ulong_konst;
#else
    converted_value = value;
#endif
    old_value = converted_value + 1;  /* make old_value different */
    for( ce = SwitchStack->case_list; ce; ce = ce->next_case ) {
        old_value = ce->value;
        if( old_value >= converted_value ) break;
        prev_ce = ce;
    }
    if( converted_value == old_value ) {   /* duplicate case value found */
        sprintf( buffer, SwitchStack->case_format, value );
        CErr2p( ERR_DUPLICATE_CASE_VALUE, buffer );
    } else {
        new_ce = (CASEPTR)CMemAlloc( sizeof( CASEDEFN ) );
        new_ce->value = converted_value;
        if( prev_ce == NULL ) {
            new_ce->next_case = SwitchStack->case_list;
            SwitchStack->case_list = new_ce;
        } else {
            prev_ce->next_case = new_ce;
            new_ce->next_case = ce;
        }
        /* Check if the previous statement was a 'case'. If so, reuse the label, as generating
         * too many labels seriously slows down code generation.
         */
        if( prev_ce && LastStmt->op.opr == OPR_STMT && LastStmt->right->op.opr == OPR_CASE ) {
            new_ce->label = SwitchStack->last_case_label;
            new_ce->gen_label = FALSE;
        } else {
            new_ce->label = NextLabel();
            new_ce->gen_label = TRUE;
        }
        SwitchStack->number_of_cases++;
        if( converted_value < SwitchStack->low_value ) {
            SwitchStack->low_value = converted_value;
        }
        if( converted_value > SwitchStack->high_value ) {
            SwitchStack->high_value = converted_value;
        }
        SwitchStack->last_case_label = new_ce->label;
        tree = LeafNode( OPR_CASE );
        tree->op.case_info = new_ce;
        AddStmt( tree );
    }
}
コード例 #9
0
static void NewLoop( void )
{
    StartNewBlock();
    LoopStack = BlockStack;
    LoopStack->top_label = NextLabel();
    DropLabel( LoopStack->top_label );
    ++LoopDepth;
}
コード例 #10
0
static int EndTry( void )
{
    int         parent_scope;
    TREEPTR     expr;
    TREEPTR     func;
    TREEPTR     tree;
    TYPEPTR     typ;
    int         expr_type;

    DropBreakLabel();           /* _leave jumps to this label */
    parent_scope = BlockStack->parent_index;
    tree = LeafNode( OPR_TRY );
    tree->op.st.try_index = BlockStack->try_index;
    tree->op.st.parent_scope = parent_scope;
    AddStmt( tree );
    if( (CurToken == T__EXCEPT) || (CurToken == T___EXCEPT) ) {
        NextToken();
        BlockStack->block_type = T__EXCEPT;
        BlockStack->break_label = NextLabel();
        Jump( BlockStack->break_label );
        DeadCode = 0;
        tree = LeafNode( OPR_EXCEPT );
        tree->op.st.try_sym_handle = DummyTrySymbol();
        tree->op.st.parent_scope = parent_scope;
        AddStmt( tree );
        CompFlags.exception_filter_expr = 1;
        expr = RValue( BracketExpr() );
        CompFlags.exception_filter_expr = 0;
        CompFlags.exception_handler = 1;
        typ = TypeOf( expr );
        expr_type = DataTypeOf( typ );
        if( expr_type != TYPE_VOID ) {
            if( expr_type > TYPE_ULONG ) {
                CErr1( ERR_EXPR_MUST_BE_INTEGRAL );
            }
        }
        func = VarLeaf( SymGetPtr( SymExcept ), SymExcept );
        func->op.opr = OPR_FUNCNAME;
        expr = ExprNode( NULL, OPR_PARM, expr );
        expr->expr_type = typ;
        expr->op.result_type = typ;
        tree = ExprNode( func, OPR_CALL, expr );
        tree->expr_type = GetType( TYPE_VOID );
        AddStmt( tree );
        return( 1 );
    } else if( (CurToken == T__FINALLY) || (CurToken == T___FINALLY) ) {
        CompFlags.in_finally_block = 1;
        NextToken();
        BlockStack->block_type = T__FINALLY;
        DeadCode = 0;
        tree = LeafNode( OPR_FINALLY );
        tree->op.st.try_sym_handle = DummyTrySymbol();
        tree->op.st.parent_scope = parent_scope;
        AddStmt( tree );
        return( 1 );
    }
    return( 0 );
}
コード例 #11
0
static void JumpBreak( BLOCKPTR block )
{
    if( !DeadCode ) {                           /* 05-apr-92 */
        if( block->break_label == 0 ) {
            block->break_label = NextLabel();
        }
        Jump( block->break_label );
    }
}
コード例 #12
0
void    GGotoEpilog( void ) {
//=====================

// Generate a branch to the epilogue.

    if( EpilogLabel == 0 ) {
        EpilogLabel = NextLabel();
    }
    GBranch( EpilogLabel );
}
コード例 #13
0
ファイル: csloops.c プロジェクト: bhanug/open-watcom-v2
void InitDo( signed_32 term )
{
// Initialize a DO or implied DO.
// Process "do i=e1,e2,e3" where e1, e2 and e3 are numeric expressions.
//

    do_entry    *do_pointer;
    sym_id      do_var;

    if( ( StmtSw & SS_DATA_INIT ) == 0 ) {
        CSHead->branch = NextLabel();
        CSHead->bottom = NextLabel();
        CSHead->cycle = NextLabel();
    }
    do_pointer = FMemAlloc( sizeof( do_entry ) );
    CSHead->cs_info.do_parms = do_pointer;
    do_pointer->do_term = term;
    do_pointer->do_parm = NULL;
    if( ReqDoVar() ) {
        CkTypeDeclared();
        do_var = CITNode->sym_ptr;
        BIOutSymbol( do_var );
        do_var->u.ns.flags |= SY_REFERENCED;
        do_var->u.ns.u1.s.xflags |= SY_DEFINED;
        if( do_var->u.ns.flags & SY_DO_PARM ) {
            Error( DO_PARM_REDEFINED );
        }
        do_pointer->do_parm = do_var;   // remember id of "i"
        ReqNextOpr( OPR_EQU, EQ_NO_EQUALS );
        if( StmtSw & SS_DATA_INIT ) {
            if( !_IsTypeInteger( do_var->u.ns.u1.s.typ ) ) {
                NameErr( DA_BAD_DO_VAR, do_var );
            }
            do_var = STShadow( do_var );
            CITNode->flags = do_var->u.ns.flags;
        }
        CITNode->sym_ptr = do_var;
        GDoInit( do_var->u.ns.u1.s.typ );
        do_var->u.ns.flags |= SY_DO_PARM;
    }
}
コード例 #14
0
ファイル: ioprockw.c プロジェクト: bhanug/open-watcom-v2
void    FormatIdd( void ) {
//=========================

    cs_label    fmt_label;
    grp_entry   *ge;

    if( RecName() && ( NameListFind() != NULL ) ) {
        BIOutNameList( CITNode->sym_ptr );
        ge = CITNode->sym_ptr->u.nl.group_list;
        while( ge != NULL ) {
            ge->sym->u.ns.flags |= SY_REFERENCED;
            ge = ge->link;
        }
        GSetNameList( FC_SET_NML );
        KWRememb( IO_NAMELIST );
    } else if( RecNumber() ) {
        GPassStmtNo( LkUpFormat(), FC_SET_FMT );
    } else if( RecNOpn() && RecNextOpr( OPR_MUL ) ) {
        if( CITNode->link->opn.ds == DSOPN_PHI ) {
            AdvanceITPtr();   // nothing needs to be loaded for default
            KWRememb( IO_LIST_DIR );
        }
    } else if( RecNOpn() && RecNextOpr( OPR_COM ) ) {
        Extension( IL_NO_ASTERISK );
    } else if( RecIntVar() ) {
        CkVarRef();
        StNumbers.var_format = true;
        GFmtVarSet();
    } else {
        ProcIOExpr();           // will allow for array name alone
        if( !AError ) {
            if( RecArrName() ) {
                if( CITNode->typ != FT_CHAR ) {
                    Extension( IL_NON_CHARACTER );
                }
                ChkAssumed();
                GFmtArrSet();
            } else if( CITNode->typ != FT_CHAR ) {
                Error( IL_BAD_FMT_SPEC );
            } else if( ( CITNode->opn.us == USOPN_CON ) ) {
                AddConst( CITNode ); // in case single constant
                fmt_label.g_label = NextLabel();
                FScan( CITNode->sym_ptr->u.lt.length,
                       (char *)&CITNode->sym_ptr->u.lt.value, fmt_label );
                GPassLabel( fmt_label.g_label, RT_SET_FMT );
            } else {
                GFmtExprSet();
            }
        }
    }
}
コード例 #15
0
ファイル: csif.c プロジェクト: Azarien/open-watcom-v2
void    CpLogIf(void) {
//=================

// Process a logical IF statement.

    label_id    if_skip;

    if_skip = NextLabel();
    CSCond( if_skip );
    if( RecKeyWord( "THEN" ) &&
        ( RecNextOpr( OPR_TRM ) || RecNextOpr( OPR_COL ) ) ) {
        AddCSNode( CS_IF );
        CSHead->branch = if_skip;
        CSHead->bottom = NextLabel();
        CITNode->opn.ds = DSOPN_PHI;       // not part of the block label
        BlockLabel();
        CtrlFlgs |= CF_BAD_DO_ENDING;
    } else {
        Recurse();
        GLabel( if_skip );
        FreeLabel( if_skip );
    }
}
コード例 #16
0
static void ElseStmt( void )
{
    LABEL_INDEX if_label;

    SrcLoc = TokenLoc;
    NextToken();
    BlockStack->block_type = T_ELSE;
    if_label = BlockStack->break_label;
    if( DeadCode ) {                            /* 05-apr-92 */
        BlockStack->break_label = 0;
    } else {
        BlockStack->break_label = NextLabel();
        Jump( BlockStack->break_label );
    }
    DropLabel( if_label );
}
コード例 #17
0
static void ForStmt( void )
{
    bool    parsed_semi_colon = FALSE;

    NextToken();
    MustRecog( T_LEFT_PAREN );
    if( CompFlags.c99_extensions ) {
        PushBlock();    // 'for' opens new scope
    }
    if( CurToken != T_SEMI_COLON ) {
        if( CompFlags.c99_extensions ) {
            TREEPTR     tree;

            tree = LeafNode( OPR_NEWBLOCK );
            AddStmt( tree );
            BlockStack->gen_endblock = TRUE;
            if( !LoopDecl( &BlockStack->sym_list ) ) {
                ChkStmtExpr();      // no declarator, try init_expr
            } else {
                parsed_semi_colon = TRUE;   // LoopDecl ate it up
            }
            tree->op.sym_handle = BlockStack->sym_list;
        } else {
            ChkStmtExpr();          // init_expr
        }
    }
    if( !parsed_semi_colon ) {
        MustRecog( T_SEMI_COLON );
    }
    NewLoop();
    BlockStack->block_type = T_FOR;
    if( CurToken != T_SEMI_COLON ) {
        BlockStack->break_label = NextLabel();
        if( !JumpFalse( Expr(), BlockStack->break_label ) ) {
            BlockStack->break_label = 0;        /* 09-sep-92 */
        }
    }
    MustRecog( T_SEMI_COLON );
    BlockStack->inc_var = NULL;
    if( CurToken != T_RIGHT_PAREN ) {
        BlockStack->inc_var = Expr();                   // save this
        if( CompFlags.meaningless_stmt == 1 ) {
            ChkUseful();
        }
    }
    MustRecog( T_RIGHT_PAREN );
}
コード例 #18
0
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 );
    }
}
コード例 #19
0
void    GEPProlog( void ) {
//===================

// Generate an entry point prologue.

    sym_id      ep;
    char        *ptr;
    char        name[MAX_SYMLEN+3];

    ep = ArgList->id;
    ep->u.ns.si.sp.u.entry = NextLabel();
    GLabel( ep->u.ns.si.sp.u.entry );
    // by the time we define the label for the entry point, the code that
    // references it will have been executed
    FreeLabel( ep->u.ns.si.sp.u.entry );
    SetArgAddrs();
    if( CommonEntry == NULL ) {
        ptr = name;
        *ptr = '$';
        ptr++;
        ptr = STGetName( SubProgId, ptr );
        *ptr = '.';
        ptr++;
        *ptr = NULLCHAR;
        CommonEntry = SymLookup( name, SubProgId->u.ns.u2.name_len + 2 );
        if( (SubProgId->u.ns.flags & SY_SUBPROG_TYPE) == SY_SUBROUTINE ) {
            CommonEntry->u.ns.flags = SY_USAGE | SY_SUBPROGRAM | SY_SUBROUTINE |
                                    SY_SENTRY | SY_REFERENCED;
        } else {
            CommonEntry->u.ns.flags = SY_USAGE | SY_SUBPROGRAM | SY_FUNCTION |
                                    SY_SENTRY | SY_REFERENCED;
        }
        EPValue = SymLookup( "$@EVAL", 6 );
        EPValue->u.ns.flags |= SY_REFERENCED;
        EPValue->u.ns.u1.s.xflags |= SY_DEFINED;
    }
}
コード例 #20
0
void Statement( void )
{
    LABEL_INDEX         end_of_func_label;
    SYM_HANDLE          func_result;
    TREEPTR             tree;
    bool                return_at_outer_level;
    bool                skip_to_next_token;
    bool                declaration_allowed;
    struct return_info  return_info;
    SYM_ENTRY           sym;

#ifndef NDEBUG
    if( DebugFlag >= 1 ) {
        printf( "***** line %u, func=%s\n", TokenLoc.line, CurFunc->name );
        PrintStats();
    }
#endif
    ++FuncCount;
    return_info.with = RETURN_WITH_NONE; /* indicate no return statements */
    return_info.with_expr = FALSE;
    CompFlags.label_dropped = 0;
    CompFlags.addr_of_auto_taken = 0;           /* 23-oct-91 */
    end_of_func_label = 0;
    return_at_outer_level = FALSE;              /* 28-feb-92 */
    declaration_allowed   = FALSE;
    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;
        if( GrabLabels() == 0 && declaration_allowed && IsDeclarator( CurToken ) ) {
            GetLocalVarDecls();
        }
        if( CompFlags.c99_extensions ) {
            declaration_allowed = TRUE;
        }
        skip_to_next_token = FALSE;
        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  &&  SrcLoc.line == TokenLoc.line && SrcLoc.fno == TokenLoc.fno ) {
                SetErrLoc( &TokenLoc );
                NextToken();    /* look ahead for else keyword */
                if( CurToken != T_ELSE ) {              /* 02-apr-91 */
                    ChkUseful();                        /* 08-dec-88 */
                }
                InitErrLoc();
                break;
            }
            declaration_allowed = FALSE;
            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 );
                }
            }
            declaration_allowed = FALSE;
            continue;
        case T_DO:
            NewLoop();
            NextToken();
            if( CurToken == T_RIGHT_BRACE ) {
                CErr1( ERR_STMT_REQUIRED_AFTER_DO );
                break;
            }
            declaration_allowed = FALSE;
            continue;
        case T_FOR:
            ForStmt();
            declaration_allowed = FALSE;
            continue;
        case T_SWITCH:
            SwitchStmt();
            DeadCode = 1;
            declaration_allowed = FALSE;
            continue;
        case T_CASE:
            DeadCode = 0;
            CaseStmt();
            declaration_allowed = FALSE;
            continue;
        case T_DEFAULT:
            DefaultStmt();
            declaration_allowed = FALSE;
            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:
        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 = TRUE;
            }
            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 ) {
                if( CurToken == T_ELSE ) {
                    declaration_allowed = FALSE;
                }
                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 = TRUE;
            } else {
                NextToken();
            }
            break;
        case T_EXTERN:
        case T_STATIC:
        case T_AUTO:
        case T_REGISTER:
        case T_VOID:
        case T_CHAR:
        case T_SHORT:
        case T_INT:
        case T_LONG:
        case T_FLOAT:
        case T_DOUBLE:
        case T_SIGNED:
        case T_UNSIGNED:
            if( CompFlags.c99_extensions )
                CErr1( ERR_UNEXPECTED_DECLARATION );
            else
                CErr1( ERR_MISSING_RIGHT_BRACE );
            break;
        case T_EOF:
            CErr1( ERR_MISSING_RIGHT_BRACE );
            break;
#ifdef __SEH__
        case T__TRY:
        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();
        }
    }
    /* C99 has special semantics for return value of main() */
    if( CompFlags.c99_extensions && !strcmp( CurFunc->name, "main" ) ) {
        if( !return_at_outer_level ) {
            FixupC99MainReturn( func_result, &return_info );
            return_at_outer_level = TRUE;
        }
    }
    if( !return_info.with_expr ) {   /* no return values present */
        if( !DeadCode && !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 );
    SrcLoc = TokenLoc;
    FreeLabels();
    if( skip_to_next_token ) {
        NextToken();
    }
    if( CompFlags.generate_prototypes ) {
        if( DefFile == NULL ) {
            OpenDefFile();
        }
        if( DefFile != NULL && CurFunc->stg_class == SC_NULL ) {
            /* 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;
    }
}