Esempio n. 1
0
int main() {
    //srand(time(0));
    srand(50);

    heap *h = make_heap();
    node **nodes = malloc(TESTSIZE * sizeof(node *));
    for(int i = 0; i < TESTSIZE; i++) {
        nodes[i] = insert(h, rand() % 100);
    }

    while (h->size > 0) {
        make_dot(nodes, "after_inserts.dot");
        getchar();

        if (rand() % 2) {
            printf("decrease_key\n");
            decrease_key(h, nodes[rand() % TESTSIZE], rand() % 100);
        } else {
            printf("delete_min\n");
            delete_min(h);
        }

        if (h->size > 0) 
            printf("heap size = %d and root key = %d\n", h->size, h->root->key);
    }

    free(nodes);
    return 1;
}
Esempio n. 2
0
/*! \brief Fixes references to struct pointers that have become unions.
 *
 * \param e
 *  the Expr to process.
 * \param data
 *  used to pass in the interprocedural symbol table.
 *
 * This function is indended to be applied postorder.
 *
 * If \a e is a OP_arrow or OP_dot that now refers to a union that was
 * created to hold pointers to different structs with the same name,
 * add an OP_dot to get the correct pointer out of the union.
 *
 * When we inserted the union, types that were previously struct pointers
 * became unions.  This corrupted the Expr tree as far as determining
 * expression type, as we might now be treating a union as a union pointer.
 *
 * This function processes all children first, so by the time we look at
 * \a e, the Expr tree below \a e is mostly valid.
 */
static void
fix_multi_ref (Expr e, void *data)
{
    SymbolTable ip_table = (SymbolTable)data;
    Key expr_type, scope_key;

    if (e)
    {
        scope_key = PST_GetExprScope (ip_table, e);

        expr_type = PST_ExprType (ip_table, e);

        if (is_multi_type (ip_table, expr_type) && \
                !(PST_GetTypeQualifier (ip_table, expr_type) & TY_CONST))
            e = make_dot (ip_table, e, expr_type, scope_key);
    }

    return;
}
Esempio n. 3
0
/*! \brief Validates a return statement.
 *
 * \param s
 *  the Stmt to validate.
 * \param data
 *  a pointer to a validate_arg struct.
 *
 * If \a s is a return statement, this function validates the expression
 * returned to make sure its type is as specified in the function's prototype.
 */
static void
validate_return (Stmt s, void *data)
{
    validate_arg *arg = (validate_arg *)data;
    FuncDcl parent_func;
    Type return_type, expr_type;
    bool return_is_multi, return_is_pointer, expr_is_multi, expr_is_pointer;
    Expr ret;

    if (P_GetStmtType (s) == ST_RETURN && (ret = P_GetStmtRet (s)))
    {
        /* Find the return's parent FuncDcl. */
        parent_func = PST_GetStmtParentFunc (arg->ip_table, s);

        return_type = PST_GetTypeType (arg->ip_table,
                                       P_GetFuncDclType (parent_func));
        expr_type = PST_ExprType (arg->ip_table, ret);

        return_is_multi = is_multi_type (arg->ip_table, return_type);
        return_is_pointer = is_pointer_type (arg->ip_table, return_type);
        expr_is_multi = is_multi_type (arg->ip_table, expr_type);
        expr_is_pointer = is_pointer_type (arg->ip_table, expr_type);

        if (return_is_multi && !expr_is_multi)
        {
            /* Build (t.field = cur_arg, t) */
            make_struct_pointer_multi (arg->ip_table, return_type, ret);

            arg->must_flatten = TRUE;
        }
        else if (return_is_multi && expr_is_pointer)
        {
            /* Build (arg.field). */
            ret = make_dot (arg->ip_table, ret, expr_type,
                            PST_GetFuncDclScope (arg->ip_table, parent_func));

            arg->must_flatten = TRUE;
        }
    }

    return;
}
Esempio n. 4
0
/*! \brief Validates a function call.
 *
 * \param e
 *  the Expr to inspect.
 * \param data
 *  a pointer to a validate_arg struct.
 *
 * Validates the arguments to a function call against the called
 * function's param types.  If a parameter is of a multi type union,
 * the correct field is selected.  If the call has too many or too few
 * arguments, this is corrected
 */
static void
validate_call (Expr e, void *data)
{
    validate_arg *arg = (validate_arg *)data;
    Expr callee_expr, cur_arg, next_arg;
    FuncDcl func;
    Key func_scope_key;
    Type func_type, param_type, cur_arg_type;
    Param param;

    if (e && P_GetExprOpcode (e) == OP_call)
    {
        /* Get the callee function's type. */
        callee_expr = P_GetExprOperands (e);
        func_type = PST_ExprType (arg->ip_table, P_GetExprOperands (e));

        /* We can only validate direct calls of defined functions. */
        if (P_IsIndirectFunctionCall (e))
        {
            func_scope_key = PST_GetScopeFromEntryKey (arg->ip_table, func_type);

            /* If we have an indirect call with unspecified parameters, we
             * can't do anything more. */
            if (PST_GetTypeParam (arg->ip_table, func_type) == NULL)
                return;
        }
        else if (P_IsDirectFunctionCall (e))
        {
            func = PST_GetFuncDclEntry (arg->ip_table,
                                        P_GetExprVarKey (callee_expr));

            if (!P_TstFuncDclQualifier (func, VQ_DEFINED) || \
                    P_TstFuncDclQualifier (func, VQ_APP_ELLIPSIS))
                goto done;

            func_scope_key = \
                             PST_GetScopeFromEntryKey (arg->ip_table,
                                     P_GetExprVarKey (callee_expr));
        }

        if (!PST_IsFunctionType (arg->ip_table, func_type))
            P_punt ("validate.c:validate_call:%d e does not result in a\n"
                    "function type (%d, %d)", __LINE__, func_type.file,
                    func_type.sym);

        /* Loop through the call arguments and the function parameters to
         * determine if we need to do anything. */
        cur_arg = P_GetExprSibling (callee_expr);
        param = PST_GetTypeParam (arg->ip_table, func_type);
        while (cur_arg && param)
        {
            bool arg_is_multi, arg_is_pointer, param_is_multi, param_is_pointer;

            next_arg = P_GetExprNext (cur_arg);

            param_type = P_GetParamKey (param);
            cur_arg_type = PST_ExprType (arg->ip_table, cur_arg);

            /* If the current param is a vararg, the call does not require
             * repair. */
            if (PST_IsVarargType (arg->ip_table, param_type))
                goto done;

            arg_is_multi = is_multi_type (arg->ip_table, cur_arg_type);
            arg_is_pointer = is_pointer_type (arg->ip_table, cur_arg_type);
            param_is_multi = is_multi_type (arg->ip_table, param_type);
            param_is_pointer = is_pointer_type (arg->ip_table, param_type);

            if (param_is_pointer && arg_is_pointer)
            {
                /* Build (t.field1 = cur_arg, t).field2 */
                TypeDcl td = PST_GetTypeTypeDcl (arg->ip_table, param_type);
                Type multi_type = Plink_GetTypeDclMultiType (td);

                cur_arg = make_struct_pointer_multi (arg->ip_table, multi_type,
                                                     cur_arg);
                cur_arg = make_dot (arg->ip_table, cur_arg, multi_type,
                                    func_scope_key);

                arg->must_flatten = TRUE;
            }
            else if (param_is_pointer && arg_is_multi)
            {
                /* Build (arg.field). */
                cur_arg = make_dot (arg->ip_table, cur_arg, cur_arg_type,
                                    func_scope_key);

                arg->must_flatten = TRUE;
            }
            else if (param_is_multi && !arg_is_multi)
            {
                /* Build (t.field = cur_arg, t) */
                make_struct_pointer_multi (arg->ip_table, param_type, cur_arg);

                arg->must_flatten = TRUE;
            }
            else
            {
                /* If the argument type doesn't match the parameter type, cast
                 * it. */
                if (PST_IsPointerType (arg->ip_table, param_type) && \
                        PST_IsIntegralType (arg->ip_table, cur_arg_type))
                {
                    Key scope_key = PST_GetExprScope (arg->ip_table, cur_arg);
                    Expr cast = PST_ScopeNewExprWithOpcode (arg->ip_table,
                                                            scope_key, OP_cast);

                    P_ExprSwap (&cur_arg, &cast);
                    P_AppendExprOperands (cast, cur_arg);
                    PST_SetExprType (arg->ip_table, cast, param_type);
                }
            }

            cur_arg = next_arg;
            param = P_GetParamNext (param);
        }

        if (cur_arg || param)
        {
            if (cur_arg)
            {
                /* If there are too many arguments, we need to remove extra ones
                 * from the end. */
                e->pragma = \
                            P_AppendPragmaNext (e->pragma,
                                                P_NewPragmaWithSpecExpr ("PLV_REMOVE",
                                                        NULL));
                remove_args (arg->ip_table, e, cur_arg);

                arg->must_flatten = TRUE;
            }
            else if (param)
            {
                /* If there are too few arguments, we need to add extras to pad
                 * the call. */
                e->pragma = \
                            P_AppendPragmaNext (e->pragma,
                                                P_NewPragmaWithSpecExpr ("PLV_ADD", NULL));
                add_args (arg->ip_table, e, param);
            }
        }
    }

done:
    return;
}