Пример #1
0
static void ParseArg (ArgDesc* Arg, Type* Type)
/* Parse one argument but do not push it onto the stack. Make all fields in
 * Arg valid.
 */
{
    /* We have a prototype, so chars may be pushed as chars */
    Arg->Flags = CF_FORCECHAR;

    /* Remember the required argument type */
    Arg->ArgType = Type;

    /* Read the expression we're going to pass to the function */
    MarkedExprWithCheck (hie1, &Arg->Expr);

    /* Remember the actual argument type */
    Arg->Type = Arg->Expr.Type;

    /* Convert this expression to the expected type */
    TypeConversion (&Arg->Expr, Type);

    /* Remember the following code position */
    GetCodePos (&Arg->Load);

    /* If the value is a constant, set the flag, otherwise load it into the
     * primary register.
     */
    if (ED_IsConstAbsInt (&Arg->Expr) && ED_CodeRangeIsEmpty (&Arg->Expr)) {
        /* Remember that we have a constant value */
        Arg->Flags |= CF_CONST;
    } else {
        /* Load into the primary */
        LoadExpr (CF_NONE, &Arg->Expr);
    }

    /* Remember the following code position */
    GetCodePos (&Arg->Push);
    GetCodePos (&Arg->End);

    /* Use the type of the argument for the push */
    Arg->Flags |= TypeOf (Arg->Expr.Type);
}
Пример #2
0
static void ReturnStatement (void)
/* Handle the 'return' statement */
{
    ExprDesc Expr;

    NextToken ();
    if (CurTok.Tok != TOK_SEMI) {

        /* Evaluate the return expression */
        hie0 (&Expr);

        /* If we return something in a void function, print an error and
        ** ignore the value. Otherwise convert the value to the type of the
        ** return.
        */
        if (F_HasVoidReturn (CurrentFunc)) {
            Error ("Returning a value in function with return type void");
        } else {
            /* Convert the return value to the type of the function result */
            TypeConversion (&Expr, F_GetReturnType (CurrentFunc));

            /* Load the value into the primary */
            LoadExpr (CF_NONE, &Expr);
        }

    } else if (!F_HasVoidReturn (CurrentFunc) && !F_HasOldStyleIntRet (CurrentFunc)) {
        Error ("Function `%s' must return a value", F_GetFuncName (CurrentFunc));
    }

    /* Mark the function as having a return statement */
    F_ReturnFound (CurrentFunc);

    /* Cleanup the stack in case we're inside a block with locals */
    g_space (StackPtr - F_GetTopLevelSP (CurrentFunc));

    /* Output a jump to the function exit code */
    g_jump (F_GetRetLab (CurrentFunc));
}