ADV_ASSIGN_VAL,
};
+struct aop_dynval_in_param {
+ int param_index;
+};
+
struct aop_dynval_fun_call {
int param_index;
};
union {
struct aop_dynval_fun_call dynval_call;
+ struct aop_dynval_in_param dynval_in_param;
};
/* Ops vector for aop_dynval. */
#include <gimple.h>
#include <string.h>
#include <tree-flow.h>
+#include <toplev.h>
#include "aop.h"
#include "aop-duplicate.h"
+#include "aop-dynval.h"
#include "aop-pointcut.h"
#include "aop-type.h"
const char *func_name =
IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
return (strcmp (func_name, pc->pc_entry.function_name) == 0);
- }
+ }
+ return check_in_params (pc);
}
/* We represent the function's entry as a control-flow graph edge.
pc->prepare_for_weave = op_prepare_entry;
pc->pc_entry.function_name = NULL;
+ pc->in_param_list_head = NULL;
return pc;
}
pc_function_entry->pc_entry.function_name = advice_function_entry;
}
+/**
+ * Filter a function entry pointcut to only include function entries
+ * with a parameter that matches a specified type. This filter removes join
+ * points when parameter n does not match type or when there is no
+ * parameter n.
+ *
+ * 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 function call pointcut to filter. Function entry
+ * pointcuts are created with aop_match_function_entry().
+ * \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_entry_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;
+}
+
/* Close Doxygen defgroup block. */
/**
* \}
#include <config.h>
#include <system.h>
#include <coretypes.h>
+#include <toplev.h>
#include <tm.h>
#include <ggc.h>
#include <gimple.h>
#include "aop.h"
+#include "aop-dynval.h"
#include "aop-pointcut.h"
+#include "aop-type.h"
/* Allocates a pointcut and initializes it with default values. */
struct aop_pointcut *
{
return jp->file;
}
+
+static tree
+op_get_in_param (struct aop_dynval *dv)
+{
+ gimple stmt;
+ tree param;
+ tree param_iter;
+ struct aop_joinpoint *jp = dv->jp;
+ int index = 0;
+
+ aop_assert (dv->kind == ADV_FUN_PARAM);
+ aop_assert (jp->pc->kind == ATP_ENTRY);
+
+ 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 = param_iter;
+ param = stabilize_reference (param);
+ break;
+ }
+ index++;
+ }
+ return param;
+}
+
+/**
+ * Get a dynval representing parameter n passed to a function call.
+ * Note that you must use aop_filter_entry_by_in_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 entry join points
+ * are obtained by joining on an aop_match_function_entry() 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_in_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_ENTRY)
+ 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->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;
+ bool params_matched = false;
+ /* 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))
+ {
+ params_matched = false;
+ break;
+ }
+ else
+ {
+ params_matched = true;
+ }
+ }
+ return params_matched;
+}
any advice gets inserted at that joinpoint. */
void (*prepare_for_weave) (struct aop_joinpoint *);
+ struct aop_param_desc *in_param_list_head;
+
union {
struct aop_pc_assign pc_assign;
struct aop_pc_entry pc_entry;
void op_default_insert_before (struct aop_joinpoint *jp, gimple stmt);
void op_default_insert_after (struct aop_joinpoint *jp, gimple stmt);
+bool check_in_params (struct aop_pointcut *pc);
#endif
extern const char *aop_capture_function_name (struct aop_joinpoint *jp);
extern struct aop_pointcut *aop_match_function_entry ();
+extern void aop_filter_entry_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,