From: Justin Seyster Date: Sat, 3 Jul 2010 00:42:44 +0000 (-0400) Subject: Merge branch 'doxygen' X-Git-Tag: release-v1.0~91 X-Git-Url: https://git.fsl.cs.stonybrook.edu/?a=commitdiff_plain;h=79f24a6a1ca702a8470b7803f4ea724a68dcf892;p=interaspect.git Merge branch 'doxygen' Conflicts: src/aop-pc-fun-call.c --- 79f24a6a1ca702a8470b7803f4ea724a68dcf892 diff --cc src/aop-pc-fun-call.c index a3a1c3d,0f96974..a900f45 --- a/src/aop-pc-fun-call.c +++ b/src/aop-pc-fun-call.c @@@ -39,89 -38,28 +39,94 @@@ #include "aop-type.h" #include "aop-dynval.h" + /** + * \defgroup call_pc Function Call Pointcut Functions + * \{ + */ + -/* Returns true if func_decl matches the arguments described in - param_list by type. */ +/* Given a GIMPLE_CALL statement, return the name of the called + function, or NULL if the function is not named. */ +static const char * +get_function_name (gimple call_stmt) +{ + tree func; + + aop_assert (gimple_code (call_stmt) == GIMPLE_CALL); + + func = gimple_call_fn (call_stmt); + + if (TREE_CODE (func) == ADDR_EXPR) + { + tree func_decl; + const char *func_name; + + func_decl = TREE_OPERAND (func, 0); + func_name = IDENTIFIER_POINTER (DECL_NAME (func_decl)); + + return func_name; + } + else + { + /* This is a call to a function pointer, so it has no name. */ + return NULL; + } +} + +/* Given a GIMPLE_CALL statement, return the type of the nth parameter + passed if there is an nth parameter or NULL if there is no nth + parameter. */ +static tree +get_param_type (gimple call_stmt, int n) +{ + aop_assert (gimple_code (call_stmt) == GIMPLE_CALL); + + if (n < gimple_call_num_args (call_stmt)) + return TREE_TYPE (gimple_call_arg (call_stmt, n)); + else + return NULL; +} + +/* Return true if a call statement matches the pointcut's criteria for + name, return type, and argument types. */ static bool -param_desc_matches (struct aop_param_desc *param_list, gimple func_stmt) +call_matches (struct aop_pointcut *pc, gimple call_stmt) { - int num_args = gimple_call_num_args (func_stmt); + tree return_type; + struct aop_param_desc *param; - while (param_list != NULL) + aop_assert (pc->kind == ATP_CALL); + aop_assert (gimple_code (call_stmt) == GIMPLE_CALL); + + /* Check function name only if the user filtered by name. */ + if (pc->pc_call.function_name != NULL) { - /* The param_list wants to match an argument that isn't - there. */ - if (param_list->param_id >= num_args) + const char *func_name; + + /* Note that get_function_name returns NULL if the call is to a + function pointer. We consider function pointer calls to + never match a name. */ + if ((func_name = get_function_name (call_stmt)) == NULL + || strcmp (pc->pc_call.function_name, func_name) != 0) return false; + } + + /* Check parameter types. */ + for (param = pc->pc_call.param_list_head ; param != NULL ; param = param->next) + { + tree param_type; - param_list = param_list->next; + if ((param_type = get_param_type (call_stmt, param->param_index)) == NULL + || !does_type_match (param_type, param->type)) + return false; } + /* Check return type (if the user filtered by return type). */ + return_type = gimple_call_return_type (call_stmt); + if (pc->pc_call.return_type != NULL + && !does_type_match (return_type, pc->pc_call.return_type)) + return false; + + /* All checks were OK. */ return true; } @@@ -403,90 -222,20 +408,95 @@@ op_get_param (struct aop_dynval *dv return param; } +/** + * Get a dynval representing parameter n passed to a function call. + * Note that you must use aop_filter_call_pc_by_param() to filter a + * pointcut by parameter type for any parameter you wish to capture + * with this function. + * \param jp A function call join point. Function call join points + * are obtained by joining on an aop_match_function_call() pointcut. + * \param n The index of the parameter to capture. Parameters are + * indexed from zero. + * \return A dynval with its type determined by + * aop_filter_call_pc_by_param(). + */ struct aop_dynval * -aop_capture_param (struct aop_joinpoint *jp, int param_index) +aop_capture_param (struct aop_joinpoint *jp, int n) { + struct aop_pointcut *pc; struct aop_dynval *dv; + struct aop_param_desc *param; + + pc = jp->pc; + if (pc->kind != ATP_CALL) + fatal_error ("(InterAspect) Attempt to capture parameter from an" + " unsupported join point."); + + /* Search for an aop_param_desc for this parameter, so that we know + its type. */ + for (param = pc->pc_call.param_list_head; param != NULL; param = param->next) + if (param->param_index == n) + break; /* Found it. */ + + /* If we don't find the appropriate aop_param_desc, param will be NULL. */ + if (param == NULL) + fatal_error ("(InterAspect) Attempt to capture parameter without specifying" + " type."); + + dv = ggc_alloc (sizeof (struct aop_dynval)); + dv->kind = ADV_FUN_PARAM; + dv->type = param->type; + dv->jp = jp; + dv->get_dynval = op_get_param; + dv->dynval_call.param_index = n; + return dv; +} + +/** + * Get a dynval representing parameter n passed to a function call if + * there is a parameter n and it matches the specified type. This + * function makes it possible to capture a parameter even if yuo have + * not filtered on its type with aop_filter_call_pc_by_param(). + * However, it returns NULL if there is no parameter n or if parameter + * n 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 n The index of the parameter to capture. Parameters are + * indexed from zero. + * \type This function verifies that the captured parameter matches + * the specified type. + * \return A dynval with its type determined by the specified type or + * NULL if there is no matching parameter n. + */ +struct aop_dynval * +aop_capture_param_by_type (struct aop_joinpoint *jp, int n, + const struct aop_type *type) +{ + struct aop_pointcut *pc; + struct aop_dynval *dv; + tree param_type; + + pc = jp->pc; + if (pc->kind != ATP_CALL) + fatal_error ("(InterAspect) Attempt to capture parameter from an" + " unsupported join point."); + + /* Check that there is a nth parameter and that it matches the + type. */ + if ((param_type = get_param_type (jp->stmt, n)) == NULL + || !does_type_match (param_type, type)) + return NULL; + dv = ggc_alloc (sizeof (struct aop_dynval)); dv->kind = ADV_FUN_PARAM; - dv->type = aop_t_all_unsigned (); + dv->type = type; dv->jp = jp; dv->get_dynval = op_get_param; - dv->dynval_call.param_id = param_index; + dv->dynval_call.param_index = n; return dv; } + + /* Close Doxygen defgroup block. */ + /** + * /} + */