From: Justin Seyster Date: Wed, 20 Oct 2010 21:42:34 +0000 (-0400) Subject: Merge branch 'doxygen-style' X-Git-Tag: release-v1.0~28 X-Git-Url: https://git.fsl.cs.stonybrook.edu/?a=commitdiff_plain;h=4c67ef0fbf11c7abe9d2bc8b1f0c8bc17c89f6ed;p=interaspect.git Merge branch 'doxygen-style' Conflicts: src/aop-pointcut.c src/aop.h --- 4c67ef0fbf11c7abe9d2bc8b1f0c8bc17c89f6ed diff --cc src/aop-pointcut.c index fcf856d,fa9fcf3..04b936c --- a/src/aop-pointcut.c +++ b/src/aop-pointcut.c @@@ -82,211 -64,41 +82,227 @@@ init_joinpoint (struct aop_joinpoint *j jp->file = file; jp->in_edge = NULL; jp->is_prepared = false; +} + - int - aop_capture_lineno (struct aop_joinpoint *jp) - { - return jp->line; - } - - const char * - aop_capture_file_name (struct aop_joinpoint *jp) - { - return jp->file; - } - +/* Sometimes we want to capture a parameter some place that is not at + the beginning of the function. The parameter may change during the + function, so we save its value at function start to preserve it + until we need it. + + Returns the temporary variable holding the preserved parameter + value. */ +static tree +save_param(tree param) +{ + edge in_edge; + tree tmp_val; + gimple new_assign; + + aop_assert (TREE_CODE (param) == PARM_DECL); + + tmp_val = create_tmp_var (TREE_TYPE (param), "ia_preserved_param"); + new_assign = gimple_build_assign (tmp_val, stabilize_reference (param)); + + /* Insert the assignment at the very beginning of the function. */ + in_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun)); + gsi_insert_on_edge_immediate (in_edge, new_assign); + + return tmp_val; +} + +static tree +op_get_in_param (struct aop_dynval *dv) +{ + gimple stmt; + tree param = NULL; + tree param_iter; + struct aop_joinpoint *jp = dv->jp; + int index = 0; + + aop_assert (dv->kind == ADV_FUN_PARAM); + + stmt = jp->stmt; + for (param_iter = DECL_ARGUMENTS (current_function_decl); + param_iter; param_iter = TREE_CHAIN (param_iter)) + { + if (index == dv->dynval_in_param.param_index) + { + param = save_param (param_iter); + break; + } + index++; + } + + aop_assert (param != NULL); + return param; } /** - * \defgroup univeral Universal Capture Functions + * Get a dynval representing the nth parameter passed to the current + * fuction. Be careful not to capture the in_param of + * the current function when you actually intend to capture the + * call_param being passed to a function call join point. + * (For the latter, use aop_capture_param() instead). * - * These capture functions work on any kind of join point. - * \{ + * Note that you must use aop_filter_by_in_param() to filter a + * pointcut by parameter type for any parameter you wish to capture + * with this function. + * \param jp Any kind of join point. Join points are obtained by + * joining on a 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_by_in_param(). */ +struct aop_dynval * +aop_capture_in_param (struct aop_joinpoint *jp, int n) +{ + struct aop_pointcut *pc; + struct aop_dynval *dv; + struct aop_param_desc *param; + + pc = jp->pc; + + /* Search for an aop_param_desc for this parameter, so that we know + its type. */ + for (param = pc->in_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_in_param; + dv->dynval_in_param.param_index = n; + return dv; +} + +bool +check_in_param (struct aop_param_desc *param_desc) +{ + tree param_type; + tree param_decl; + int index = 0; + bool index_found = false; + for (param_decl = DECL_ARGUMENTS (current_function_decl); + param_decl; param_decl = TREE_CHAIN (param_decl)) + { + if (index == param_desc->param_index) + { + /* Index found check the type */ + if ((param_type = TREE_TYPE (param_decl)) == NULL + || !does_type_match (param_type, param_desc->type)) + index_found = false; + else + index_found = true; + + break; + } + index++; + } + return index_found; +} + +bool +check_in_params (struct aop_pointcut *pc) +{ + struct aop_param_desc *param_desc; + + /* Check parameter types. */ + for (param_desc = pc->in_param_list_head ; param_desc != NULL ; + param_desc = param_desc->next) + { + if(!check_in_param (param_desc)) + return false; + } + + return true; +} + +/** + * Filter a pointcut (of any type) to only include join points within + * functions that take an nth parameter matching the specified type. + * Be careful not to use this function when you actually intend to + * filter a function call pointcut by the parameters that the function + * call takes. (For the latter, use aop_filter_call_pc_by_param()). + * + * Because pointcuts are created per function, this kind of filtering + * is actually all-or-nothing. It will either empty the pointcut or + * leave it as is. + * + * Filters on the same parameter do not stack on top of each other. + * If multiple parameter filters with the same n are applied a + * pointcut, only the last one will have any effect. + * + * Note that you must filter a parameter by its type in order to + * capture it with aop_capture_in_param(). + * \param pc The pointcut to filter. + * \param n The index of the parameter to filter on. Parameters are + * indexed from zero. + * \param The parameter type to filter by. + */ +void +aop_filter_by_in_param (struct aop_pointcut *pc, int n, + const struct aop_type *type) +{ + struct aop_param_desc *param = NULL; + struct aop_param_desc *iter; + + /* Is there already a filter for this parameter? */ + for (iter = pc->in_param_list_head ; iter != NULL ; iter = iter->next) + { + if (iter->param_index == n) + { + param = iter; + break; + } + } + + /* No? Then create one and add it to the list. */ + if (param == NULL) + { + param = ggc_alloc (sizeof (struct aop_param_desc)); + + param->next = pc->in_param_list_head; + pc->in_param_list_head = param; + } + + param->param_index = n; + param->type = type; +} + /** + * Get the line number of join point. You usually want to call this + * with aop_capture_file_name() to fully identify the line of code the + * join point is from. + * \param jp Any join point. + */ + int + aop_capture_lineno (struct aop_joinpoint *jp) + { + return jp->line; + } + + /** + * Get the name of the file this join point is in. This function will + * usually return the name of the file that is currently being + * compiled, but compiler macros make it possible for their to be join + * points from other files. + * \param jp Any join point. + */ + const char * + aop_capture_file_name (struct aop_joinpoint *jp) + { + return jp->file; + } + + /** + * \} + */ diff --cc src/aop.h index ced0d87,3ef73eb..8e20f7b --- a/src/aop.h +++ b/src/aop.h @@@ -268,14 -303,13 +320,18 @@@ enum aop_argkind */ #define AOP_DYNVAL(VAL) ATA_DYNVAL, VAL + /** + * \} + */ + -extern const char *aop_capture_function_name (struct aop_joinpoint *jp); +extern const char *aop_get_function_name (void); extern struct aop_pointcut *aop_match_function_entry (); +extern void aop_filter_by_in_param (struct aop_pointcut *pc, int n, + const struct aop_type *type); +extern struct aop_dynval *aop_capture_in_param (struct aop_joinpoint *jp, + int param_index); + extern struct aop_pointcut *aop_match_function_exit (); extern void aop_filter_entry_by_name(struct aop_pointcut *pc_function_entry,