#undef PACKAGE_VERSION
#include <locale.h>
-
#include <config.h>
#include <system.h>
#include <coretypes.h>
#include <ggc.h>
#include <basic-block.h>
#include <gimple.h>
+#include <diagnostic.h>
#include <string.h>
+
#include "aop.h"
#include "aop-pointcut.h"
#include "aop-type.h"
if (gimple_code (my_statement) == GIMPLE_CALL)
{
func = gimple_call_fn(my_statement);
+
+ if (TREE_CODE(func) != ADDR_EXPR)
+ {
+ /* This is a call to a function pointer. Don't worry about it. */
+ fprintf(stderr, "CALL_EXPR with non-ADDR_EXPR function.\n");
+ continue;
+ }
+
func_decl = TREE_OPERAND (func, 0);
func_name = IDENTIFIER_POINTER (DECL_NAME (func_decl));
+
if (strcmp (pc->pc_call.function_name, func_name) == 0)
{
+ int num_args = gimple_call_num_args(my_statement);
+ fprintf(stderr," Function call to %s has %d parameters passed.\n",pc->pc_call.function_name,num_args);
+ struct aop_param_desc *iter = NULL;
+ if(pc->pc_call.param_list_head != NULL ) {
+ iter = pc->pc_call.param_list_head;
+ while( iter->next != NULL ) {
+ iter = iter->next;
+ if(iter->param_id > num_args - 1 || iter->param_id < 0) {
+ fprintf(stderr," Function call to %s does not satisfy the pointcut.\n",pc->pc_call.function_name);
+ return;
+ }
+ }
+ }
+
struct aop_joinpoint jp;
jp.pc = pc;
jp.gsi = &gsi;
- cb (&jp, callback_param);
- fprintf (stderr,"Function call to %s captured...",pc->pc_call.function_name);
+ cb (&jp, callback_param);
+ fprintf (stderr,"Function call to %s captured...\n",pc->pc_call.function_name);
}
}
pc = ggc_alloc (sizeof (struct aop_pointcut));
pc->kind = ATP_CALL;
pc->join_on = op_join_on_function_call;
- pc->insert_before = op_default_insert_before;
+ pc->insert_after = op_default_insert_after;
+ /*
+ Initialize the list to NULL
+ */
+ pc->pc_call.param_list_head = NULL;
return pc;
}
const char *advice_function_call)
{
pc_function_call->pc_call.function_name=advice_function_call;
+}
+void aop_add_param_descriptor(struct aop_pointcut *pc,int param_id)
+{
+ struct aop_param_desc *iter = NULL;
+ struct aop_param_desc *desc = ggc_alloc (sizeof (struct aop_param_desc));
+ desc->param_id=param_id;
+ desc->next = NULL;
+ if(pc->pc_call.param_list_head == NULL ) {
+
+ pc->pc_call.param_list_head= desc;
+ }
+ else {
+ iter = pc->pc_call.param_list_head;
+ while( iter->next != NULL ) {
+ iter = iter->next;
+ }
+ iter->next = desc;
+ }
}
void aop_filter_function_call_pointcut_by_param_index(struct aop_pointcut *pc,
int param_id)
{
- pc->pc_call.param_id=param_id;
-
+
+ aop_add_param_descriptor(pc,param_id);
}
-/*
-void aop_filter_function_call_pointcut(struct aop_pointcut *pc_function_call,
- const char *advice_function_call)
-{
- pc_function_call->pc_call.function_name=advice_function_call;
-}
-*/
static tree
op_get_return_value (struct aop_dynval *dv)
{
{
fprintf(stderr,"call_lhs is NULL\n");
/*
- tree new_lhs = create_tmp_var(gimple_call_return_type(stmt), "hcos_mem_result");
+ tree new_lhs = create_tmp_var(gimple_call_return_type(stmt), "aop_result");
add_referenced_var(new_lhs);
new_lhs = make_ssa_name(new_lhs, stmt);
-
gimple_call_set_lhs(stmt, new_lhs);
update_stmt(stmt);
*/
}
- fprintf(stderr,"Before stabilize_reference\n");
return_value = stabilize_reference(gimple_call_lhs(stmt));
+ debug_gimple_stmt(stmt);
return return_value;
}
dv->type = aop_t_all_unsigned ();
dv->jp = jp;
dv->get_dynval = op_get_return_value;
- fprintf(stderr,"Came here.......\n");
return dv;
}
{
gimple stmt;
tree param;
-
struct aop_joinpoint *jp = dv->jp;
- fprintf(stderr,"In op_get_param\n");
aop_assert (dv->kind == ADV_FUN_PARAM);
aop_assert (jp->pc->kind == ATP_CALL);
-
- fprintf(stderr,"op_get_param after assert\n");
stmt = gsi_stmt (*(jp->gsi));
- /*
- if (gimple_call_num_args(stmt) < 1)
- {
- error("Invalid argument specification in ptcut.\n");
- return NULL;
- }
- */
- fprintf(stderr,"op_get_param before stab ref \n");
- param = stabilize_reference(gimple_call_arg(stmt, 0));
-// param = gimple_call_arg(stmt, 0);
-// param = build_int_cst(integer_type_node, 0);
- fprintf(stderr,"op_get_param after stab ref \n");
+ param = stabilize_reference(gimple_call_arg(stmt, dv->dynval_call.param_id));
return param;
}
struct aop_dynval *
-aop_capture_param (struct aop_joinpoint *jp)
+aop_capture_param (struct aop_joinpoint *jp, int param_index)
{
struct aop_dynval *dv;
dv = ggc_alloc (sizeof (struct aop_dynval));
dv->type = aop_t_all_unsigned ();
dv->jp = jp;
dv->get_dynval = op_get_param;
+ dv->dynval_call.param_id = param_index;
return dv;
}
gsi_insert_before (jp->gsi, stmt, GSI_SAME_STMT);
}
+
+/* This is the default insert_after() operation for aop_pointcut
+ objects. It just inserts a gimple statement before the iterator in
+ the aop_joinpoint object. This function holds to the requirement
+ that inserting multiple gimple statements at the joinpoint will
+ result in those statements appearing in the order they were
+ added. */
+void
+op_default_insert_after (struct aop_joinpoint *jp, gimple stmt)
+{
+ gsi_insert_after (jp->gsi, stmt, GSI_SAME_STMT);
+}
+
void
-aop_insert_advice (struct aop_joinpoint *jp, const char *func_name, ...)
+aop_insert_advice (struct aop_joinpoint *jp, const char *func_name,
+ enum aop_insert_location location, ...)
{
va_list argp;
gimple func_call;
struct aop_pointcut *pc;
- va_start (argp, func_name);
+ va_start (argp, location);
func_call = build_gcc_call (func_name, void_type_node, argp);
va_end (argp);
pc = jp->pc;
- pc->insert_before(jp, func_call);
+ if(location == AOP_INSERT_BEFORE)
+ {
+ pc->insert_before(jp, func_call);
+ }
+ else if(location == AOP_INSERT_AFTER)
+ {
+ pc->insert_after(jp, func_call);
+ }
}