}
}
- init_joinpoint (&jp, &gsi, pc, stmt);
+ static void join_on_bb_assign (basic_block bb, struct aop_pointcut *pc,
+ join_callback cb, void *callback_param)
+ {
+ gimple_stmt_iterator gsi;
++ expanded_location xloc;
+
+ for (gsi = gsi_start_bb (bb) ; !gsi_end_p (gsi) ; gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+
+ if (stmt_matches_pointcut (pc, stmt))
+ {
+ struct aop_joinpoint jp;
++ xloc = expand_location (gimple_location (stmt));
++ init_joinpoint (&jp, &gsi, pc, stmt, xloc.line, xloc.file);
+ cb (&jp, callback_param);
+ }
+ }
+ }
+
static void
op_join_on_assign (struct aop_pointcut *pc, join_callback cb,
void *callback_param)
#include <basic-block.h>
#include <gimple.h>
#include <string.h>
+#include <tree-flow.h>
#include "aop.h"
+ #include "aop-duplicate.h"
#include "aop-pointcut.h"
#include "aop-type.h"
* \{
*/
+static expanded_location
+get_function_entry_xloc()
+{
+ basic_block bb;
+ expanded_location xloc;
+
+ bb = ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun);
+ xloc = expand_location (gimple_location (first_stmt (bb->next_bb)));
+ return xloc;
+}
+
+ /* Function have only one entry. Return true if that entry matches
+ the pointcut's filtering criteria. */
+ static bool
+ is_function_entry_matching (struct aop_pointcut *pc)
+ {
+ /* Filter by name. */
+ if(pc->pc_entry.function_name == NULL)
+ {
+ /* No name filter in place. */
+ return true;
+ }
+ else
+ {
+ const char *func_name =
+ IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
+ return (strcmp (func_name, pc->pc_entry.function_name) == 0);
+ }
+ }
-
+ /* We represent the function's entry as a control-flow graph edge.
+ That edge is the only thing necessary to join on the pointcut's one
+ join point. */
static void
- op_join_on_function_entry (struct aop_pointcut *pc, join_callback cb,
- void *callback_param)
+ join_on_entry_edge (struct aop_pointcut *pc, edge in_edge, join_callback cb,
+ void *callback_param)
{
struct aop_joinpoint jp;
gimple_stmt_iterator gsi;
+ expanded_location xloc;
- aop_assert (pc->kind == ATP_ENTRY);
-
- /* Filter this pointcut by function name if necessary. */
- if(pc->pc_entry.function_name != NULL)
- {
- const char *func_name =
- IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
- if (strcmp (func_name, pc->pc_entry.function_name) != 0)
- return;
- }
-
/* Note that the gimple iterator gets initialized by
op_prepare_entry when it is time to insert advice. (We poison it
just to make sure that initialization is getting called.)*/
memset (&gsi, 0xfa, sizeof (gimple_stmt_iterator));
- init_joinpoint (&jp, &gsi, pc, NULL);
+
+ xloc = get_function_entry_xloc ();
+ init_joinpoint (&jp, &gsi, pc, NULL, xloc.line, xloc.file);
+ jp.in_edge = in_edge;
cb (&jp, callback_param);
}
* \{
*/
- init_joinpoint (&jp, &gsi, pc, stmt);
+ static void
+ join_on_bb_function_exit (basic_block bb, struct aop_pointcut *pc,
+ join_callback cb, void *callback_param)
+ {
+ gimple_stmt_iterator gsi;
++ expanded_location xloc;
+
+ for (gsi = gsi_start_bb (bb) ; !gsi_end_p (gsi) ; gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+
+ if (gimple_code (stmt) == GIMPLE_RETURN)
+ {
+ struct aop_joinpoint jp;
++ xloc = expand_location (gimple_location (stmt));
++ init_joinpoint (&jp, &gsi, pc, stmt, xloc.line, xloc.file);
+ cb (&jp, callback_param);
+
+ /* It's possible that gsi is no longer a valid iterator if
+ the callback inserted advice. Anyway, that's fine
+ because there shouldn't be any statements in the basic
+ block after the return! On to the next basic block. */
+ break;
+ }
+ }
+ }
+
static void
op_join_on_function_exit (struct aop_pointcut *pc, join_callback cb,
void *callback_param)
{
basic_block bb;
- gimple stmt;
- expanded_location xloc;
++
aop_assert (pc->kind == ATP_EXIT);
FOR_EACH_BB(bb)
}
static void
- op_join_on_function_call (struct aop_pointcut *pc, join_callback cb,
- void *callback_param)
+ join_on_bb_function_call (basic_block bb, struct aop_pointcut *pc,
+ join_callback cb, void *callback_param)
{
- basic_block my_basic_block;
gimple_stmt_iterator gsi;
+ expanded_location xloc;
- aop_assert (pc->kind == ATP_CALL);
-
- FOR_EACH_BB(my_basic_block)
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- for (gsi = gsi_start_bb (my_basic_block) ; !gsi_end_p (gsi) ;
- gsi_next (&gsi))
+ gimple stmt = gsi_stmt (gsi);
+
+ /* At this stage, there should be no GIMPLE statements with
+ sub-statements. */
+ gcc_assert(!gimple_has_substatements (stmt));
+
+ if (gimple_code (stmt) == GIMPLE_CALL)
{
- gimple stmt = gsi_stmt (gsi);
-
- /* At this stage, there should be no GIMPLE statements with
- sub-statements. */
- gcc_assert(!gimple_has_substatements (stmt));
-
- if (gimple_code (stmt) == GIMPLE_CALL)
- {
- if (call_matches (pc, stmt))
- {
- struct aop_joinpoint jp;
- xloc = expand_location (gimple_location (stmt));
- init_joinpoint (&jp, &gsi, pc, stmt, xloc.line, xloc.file);
- cb (&jp, callback_param);
- }
+ if (call_matches (pc, stmt))
+ {
+ struct aop_joinpoint jp;
- init_joinpoint (&jp, &gsi, pc, stmt);
++ xloc = expand_location (gimple_location (stmt));
++ init_joinpoint (&jp, &gsi, pc, stmt, xloc.line, xloc.file);
+ cb (&jp, callback_param);
}
}
}
jp->pc = pc;
jp->gsi = gsi;
jp->stmt = stmt;
+ jp->line = line;
+ 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;
}
enum aop_pckind kind;
void (*join_on) (struct aop_pointcut *, join_callback, void *);
+ void (*join_on_copy) (struct aop_pointcut *, int copy, join_callback, void *);
insert_callback insert_before;
insert_callback insert_after;
-
+
/* prepare_for_weave() gets called once for each joinpoint before
any advice gets inserted at that joinpoint. */
void (*prepare_for_weave) (struct aop_joinpoint *);