From: Justin Seyster Date: Thu, 1 Jul 2010 23:29:40 +0000 (-0400) Subject: Added aop_capture_return_value_by_type(). X-Git-Tag: release-v1.0~94 X-Git-Url: https://git.fsl.cs.stonybrook.edu/?a=commitdiff_plain;h=a55a1c82b34e9cda6e48147a5d6a6122a29523f1;p=interaspect.git Added aop_capture_return_value_by_type(). --- diff --git a/src/aop-pc-fun-call.c b/src/aop-pc-fun-call.c index e142cef..f0bb683 100644 --- a/src/aop-pc-fun-call.c +++ b/src/aop-pc-fun-call.c @@ -39,6 +39,39 @@ #include "aop-type.h" #include "aop-dynval.h" +/* Given a GIMPLE_CALL statement, return the FUNCTION_TYPE tree node + that represents the function prototype. */ +static tree +get_function_prototype (gimple call_stmt) +{ + tree func; + tree func_type_pointer; + tree func_type; + + aop_assert (gimple_code (call_stmt) == GIMPLE_CALL); + + func = gimple_call_fn (call_stmt); + + /* Get the function type. The func tree should have a pointer type, + pointing to the actual function type. */ + func_type_pointer = TREE_TYPE (func); + aop_assert (TREE_CODE (func_type_pointer) == POINTER_TYPE); + func_type = TREE_TYPE (func_type_pointer); + aop_assert (TREE_CODE (func_type) == FUNCTION_TYPE); + + return func_type; +} + +/* Given a GIMPLE_CALL statement, return the type node for the + function's return type. */ +static tree +get_return_type (gimple call_stmt) +{ + aop_assert (gimple_code (call_stmt) == GIMPLE_CALL); + + return TREE_TYPE (get_function_prototype (call_stmt)); +} + /* Returns true if func_decl matches the arguments described in param_list by type. */ static bool @@ -65,8 +98,7 @@ static bool call_matches (struct aop_pointcut *pc, gimple call_stmt) { tree func; - tree func_type_pointer; - tree func_type; + tree return_type; aop_assert (pc->kind == ATP_CALL); aop_assert (gimple_code (call_stmt) == GIMPLE_CALL); @@ -97,16 +129,10 @@ call_matches (struct aop_pointcut *pc, gimple call_stmt) } } - /* Get the function type. The func tree should have a pointer type, - pointing to the actual function type. */ - func_type_pointer = TREE_TYPE (func); - aop_assert (TREE_CODE (func_type_pointer) == POINTER_TYPE); - func_type = TREE_TYPE (func_type_pointer); - aop_assert (TREE_CODE (func_type) == FUNCTION_TYPE); - /* Check return type (if the user filtered by return type). */ + return_type = get_return_type (call_stmt); if (pc->pc_call.return_type != NULL - && !does_type_match (TREE_TYPE (func_type), pc->pc_call.return_type)) + && !does_type_match (return_type, pc->pc_call.return_type)) return false; /* All checks were OK. */ @@ -141,6 +167,7 @@ op_join_on_function_call (struct aop_pointcut *pc, join_callback cb, struct aop_joinpoint jp; jp.pc = pc; jp.gsi = &gsi; + jp.stmt = stmt; jp.is_prepared = false; cb (&jp, callback_param); } @@ -261,7 +288,7 @@ aop_filter_call_pc_by_return_type (struct aop_pointcut *pc, * order to capture the return value using aop_capture_return_value(). * \param jp A function call join point. Function call join points * are obtained by joining on an aop_match_function_call() pointcut. - * \return A dynval with a type determined by + * \return A dynval with its type determined by * aop_filter_call_pc_by_return_type(). */ struct aop_dynval * @@ -287,6 +314,45 @@ aop_capture_return_value (struct aop_joinpoint *jp) return dv; } +/** + * Get a dynval representing a function call's return value if the + * return value matches the specified type. This function makes it + * possible to capture the return value of a function even if you have + * not filtered with aop_filter_call_pc_by_return_type(). However, it + * returns NULL if the return value does not match the specified type. + * \param jp A function call join point. Function call join points + * are obtained by joining on an aop_match_function_call() pointcut. + * \param type This function verifies that the return value's type + * matches this specified type. + * \return A dynval with its type determined by the specified type or + * NULL if the return value does not match the specified type. + */ +struct aop_dynval * +aop_capture_return_value_by_type (struct aop_joinpoint *jp, + const struct aop_type *type) +{ + struct aop_pointcut *pc; + struct aop_dynval *dv; + tree return_type; + + pc = jp->pc; + if (pc->kind != ATP_CALL) + fatal_error ("(InterAspect) Attempt to capture return value from an" + " unsupported join point."); + + /* Does this join point match the specified type? */ + return_type = get_return_type (jp->stmt); + if (!does_type_match (return_type, type)) + return NULL; + + dv = ggc_alloc (sizeof (struct aop_dynval)); + dv->kind = ADV_FUN_RETVAL; + dv->type = type; + dv->jp = jp; + dv->get_dynval = op_get_return_value; + return dv; +} + static tree op_get_param (struct aop_dynval *dv) { diff --git a/src/aop.h b/src/aop.h index 381d635..5560ea2 100644 --- a/src/aop.h +++ b/src/aop.h @@ -109,6 +109,8 @@ extern void aop_filter_function_call_pointcut_by_param_index ( struct aop_pointcut *pc, int param_index); extern struct aop_dynval *aop_capture_return_value (struct aop_joinpoint *jp); +extern struct aop_dynval *aop_capture_return_value_by_type ( + struct aop_joinpoint *jp, const struct aop_type *type); extern struct aop_dynval *aop_capture_param (struct aop_joinpoint *jp, int param_index);