Esempio n. 1
0
static void ChkParms( void )
{
    PARMPTR             parm;
    PARMPTR             prev_parm;
    SYM_HANDLE          sym_handle;
    SYM_HANDLE          prev_sym_handle;
    TYPEPTR             typ;

    CurFunc->u.func.locals = SYM_NULL;
    CurFunc->u.func.parms = SYM_NULL;
    typ = *(CurFunc->sym_type->u.fn.parms);
    SKIP_TYPEDEFS( typ );
    if( typ->decl_type != TYPE_VOID ) {
        prev_sym_handle = SYM_NULL;
        prev_parm = NULL;
        for( parm = ParmList; parm != NULL; parm = parm->next_parm ) {
            if( parm->sym.name == NULL ) {
                parm->sym.name = ".J";
                parm->sym.flags |= SYM_REFERENCED;
            }
            if( parm->sym.name[0] == '\0' ) {
                parm->sym.name = ".I";
                InvDecl();
            }
            if( parm->sym.sym_type == NULL ) {
                parm->sym.sym_type = TypeDefault();
            }
            /* make sure name not already defined in this SymLevel */
            sym_handle = SymAdd( parm->sym.info.hash, &parm->sym );
            if( prev_parm == NULL ) {
                CurFunc->u.func.parms = sym_handle;
            } else {
                prev_parm->sym.handle = sym_handle;
                SymReplace( &prev_parm->sym, prev_sym_handle );
                CMemFree( prev_parm );
            }
            prev_parm = parm;
            prev_sym_handle = sym_handle;
            parm->sym.flags |= SYM_DEFINED | SYM_ASSIGNED;
            parm->sym.attribs.is_parm = true;
        }
        if( prev_parm != NULL ) {
#if _CPU == 370
            {
                SYM_ENTRY   var_parm;

                if( VarParm( CurFunc ) ) {
                    typ = ArrayNode( GetType( TYPE_CHAR ) );
                    typ->u.array->dimension = 160;
                    sym_handle = GetNewSym( &var_parm, 'V', typ, SC_AUTO );
                    SymReplace( &var_parm, sym_handle );
                    prev_parm->sym.handle = sym_handle;
                }
            }
#endif
            SymReplace( &prev_parm->sym, prev_sym_handle );
            CMemFree( prev_parm );
        }
    }
}
Esempio n. 2
0
/*
//    does the specified symbol take variable args? hash calc'ed
//
*/
bool VarFunc( SYMPTR sym )
{
    unsigned    hash;
    size_t      len;
    char        *p;

    if( sym == NULL )
        return( FALSE );

    if( sym->flags & SYM_FUNCTION ) {
        p = sym->name;
        len = strlen( p );
        hash = (len + VarFuncWeights[p[0] - 'a'] + VarFuncWeights[p[len - 1] -'a']) & 31;

        if( memcmp( p, VarParmFuncs[hash], len + 1 ) == 0 
            && ( CompFlags.extensions_enabled || ( ( 1 << hash ) & VAR_PARM_FUNCS_ANSI ) ) )
            return( TRUE );

        return( VarParm( sym ) );
    }
    return( FALSE );
}
Esempio n. 3
0
/*
//    does the specified symbol take variable args? hash calc'ed
//
*/
int VarFunc( SYMPTR sym )
{
    int         hash;
    int         len;
    char        *p;

    if( sym == NULL )
        return( 0 );

    if( sym->flags & SYM_FUNCTION ) {
        p = sym->name;
        len = strlen( p );
        hash = (len + VarFuncWeights[ p[0] - 'a' ]
                 + VarFuncWeights[ p[len-1] -'a' ]) & 31;

        if( strcmp( p, VarParmFuncs[ hash ] ) == 0 
            && ( CompFlags.extensions_enabled
                 || ( ( 1 << hash ) & VAR_PARM_FUNCS_ANSI ) ) )
            return( 1 );

        return( VarParm( sym ) );
    }
    return( 0 );
}
Esempio n. 4
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;
    }
}
Esempio n. 5
0
static void ParmDeclList( void )     /* process old style function definitions */
{
    TYPEPTR             typ;
    PARMPTR             parm;
    decl_state          state;
    SYM_ENTRY           sym;
    decl_info           info;
    size_t              len;

    while( CurToken != T_LEFT_BRACE ) {
        FullDeclSpecifier( &info );
        if( info.stg == SC_NONE && info.typ == NULL ) {
            if( CurToken == T_ID ) {
                CErr2p( ERR_MISSING_DATA_TYPE, Buffer );
            }
        }
        if( info.stg != SC_NONE && info.stg != SC_REGISTER ) {
            CErr1( ERR_INVALID_STG_CLASS_FOR_PARM );
            info.stg = SC_NONE;
        }
        state = DECL_STATE_NONE;
        typ = info.typ;
        if( typ == NULL ) {
            state |= DECL_STATE_NOTYPE;
            typ = TypeDefault();
        }
        if( info.stg == SC_NONE )
            info.stg = SC_AUTO;

        for( ;; ) {
            if( CurToken == T_SEMI_COLON ) {
                Chk_Struct_Union_Enum( typ );
            } else {
                sym.name = NULL;
                Declarator( &sym, info.mod, typ, state );
                if( sym.name == NULL || sym.name[0] == '\0' ) {
                    InvDecl();
                } else {
                    len = strlen( sym.name ) + 1;
                    for( parm = ParmList; parm != NULL; parm = parm->next_parm ) {
                        if( parm->sym.name != NULL ) {
                            if( memcmp( parm->sym.name, sym.name, len ) == 0 ) {
                                break;
                            }
                        }
                    }
                    if( parm == NULL ) {
                        CErr2p( ERR_SYM_NOT_IN_PARM_LIST, sym.name );
                    } else if( parm->sym.sym_type != NULL ) {
                        CErr2p( ERR_PARM_ALREADY_DECLARED, sym.name );
                    } else {
                        ArgPromotion( &sym );
                        parm->sym.sym_type = sym.sym_type;
                        parm->sym.attribs.stg_class = info.stg;
                    }
                }
                CMemFree( sym.name );
            }

            if( CurToken == T_SEMI_COLON ) {
                NextToken();
                break;
            }
            if( CurToken == T_LEFT_BRACE ) {
                CErr1( ERR_MISSING_SEMICOLON );
                break;
            }
            if( CurToken == T_EOF )
                return;
            MustRecog( T_COMMA );
        }
    }
    ReverseParms();
    if( CurFunc->sym_type->u.fn.parms == NULL ) {
        CurFunc->flags |= SYM_OLD_STYLE_FUNC;
        AddParms();
    } else {
        ChkParms();
    }
    ParmList = NULL;
    if( VarParm( CurFunc ) ) {
        CurFunc->flags &= ~ SYM_OK_TO_RECURSE;
    }
}