--- /dev/null
+/* This program is free software: you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Whether we want them or not (we don't), Autoconf _insists_ on
+ defining these. Since GCC's config.h (which we must include) also
+ defines them, we have to undef them here. */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <locale.h>
+
+#include <config.h>
+#include <system.h>
+#include <coretypes.h>
+#include <tm.h>
+#include <tree.h>
+#include <ggc.h>
+#include <basic-block.h>
+#include <gimple.h>
+#include <string.h>
+
+#include "aop.h"
+#include "aop-pointcut.h"
+#include "aop-type.h"
+#include "aop-dynval.h"
+
+
+static void
+op_join_on_function_call (struct aop_pointcut *pc, join_callback cb,
+ void *callback_param)
+{
+ aop_assert (pc->kind == ATP_CALL);
+
+ basic_block my_basic_block;
+ gimple_stmt_iterator gsi;
+ tree func_decl;
+ tree func;
+
+ const char * func_name;
+
+ FOR_EACH_BB(my_basic_block)
+ {
+ for (gsi = gsi_start_bb (my_basic_block);
+ !gsi_end_p (gsi);
+ gsi_next (&gsi))
+ {
+ gimple my_statement = gsi_stmt (gsi);
+
+ /* At this stage, there should be no GIMPLE statements with sub-statements. */
+ gcc_assert(!gimple_has_substatements (my_statement));
+
+ if (gimple_code (my_statement) == GIMPLE_CALL)
+ {
+ func = gimple_call_fn(my_statement);
+ func_decl = TREE_OPERAND (func, 0);
+ func_name = IDENTIFIER_POINTER (DECL_NAME (func_decl));
+ if (strcmp (pc->pc_call.function_name, func_name) == 0)
+ {
+ 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);
+ }
+ }
+
+ }
+ }
+}
+
+struct aop_pointcut *
+aop_match_function_call ()
+{
+ struct aop_pointcut *pc;
+
+ 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;
+ return pc;
+}
+
+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;
+
+}
+
+void aop_filter_function_call_pointcut_by_param_index(struct aop_pointcut *pc,
+ int param_id)
+{
+ pc->pc_call.param_id=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)
+{
+ gimple stmt;
+ tree return_value;
+
+ /*
+ If this function isn't on the right side of an assignment, we
+ need to _put it_ on the right hand side of an assignment so
+ we can grab its return value.
+ */
+ struct aop_joinpoint *jp = dv->jp;
+ stmt = gsi_stmt (*(jp->gsi));
+
+ /* If this function isn't on the right side of an assignment, we
+ need to _put it_ on the right hand side of an assignment so
+ we can grab its return value. */
+ if (gimple_call_lhs(stmt) == NULL)
+ {
+ fprintf(stderr,"call_lhs is NULL\n");
+ /*
+ tree new_lhs = create_tmp_var(gimple_call_return_type(stmt), "hcos_mem_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));
+ return return_value;
+
+}
+
+struct aop_dynval *
+aop_capture_return_value (struct aop_joinpoint *jp)
+{
+ struct aop_dynval *dv;
+ dv = ggc_alloc (sizeof (struct aop_dynval));
+ dv->kind = ADV_FUN_RETVAL;
+ dv->type = aop_t_all_unsigned ();
+ dv->jp = jp;
+ dv->get_dynval = op_get_return_value;
+ fprintf(stderr,"Came here.......\n");
+ return dv;
+
+}
+
+static tree
+op_get_param (struct aop_dynval *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");
+ return param;
+}
+
+
+struct aop_dynval *
+aop_capture_param (struct aop_joinpoint *jp)
+{
+ struct aop_dynval *dv;
+ dv = ggc_alloc (sizeof (struct aop_dynval));
+ dv->kind = ADV_FUN_PARAM;
+ dv->type = aop_t_all_unsigned ();
+ dv->jp = jp;
+ dv->get_dynval = op_get_param;
+ return dv;
+}
+