2 * sparse/smatch_modification_hooks.c
4 * Copyright (C) 2009 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
13 #include "smatch_function_hashtable.h"
16 modification_hook
*call_back
;
20 ALLOCATOR(mcall_back
, "modification call backs");
21 DECLARE_PTR_LIST(mod_cb_list
, struct mcall_back
);
23 DEFINE_FUNCTION_HASHTABLE_STATIC(mcall
, struct mcall_back
, struct mod_cb_list
);
24 static struct hashtable
*var_hash
;
26 static struct mcall_back
*alloc_mcall_back(modification_hook
*call_back
,
29 struct mcall_back
*cb
;
31 cb
= __alloc_mcall_back(0);
32 cb
->call_back
= call_back
;
37 void add_modification_hook(const char *variable
, modification_hook
*call_back
, void *info
)
39 struct mcall_back
*cb
;
41 cb
= alloc_mcall_back(call_back
, info
);
42 add_mcall(var_hash
, variable
, cb
);
45 void add_modification_hook_expr(struct expression
*expr
, modification_hook
*call_back
, void *info
)
47 struct mcall_back
*cb
;
50 expr
= strip_expr(expr
);
51 name
= get_variable_from_expr(expr
, NULL
);
54 cb
= alloc_mcall_back(call_back
, info
);
55 add_mcall(var_hash
, name
, cb
);
59 static void call_call_backs(struct mod_cb_list
*list
,
62 struct expression
*expr
)
64 struct mcall_back
*tmp
;
66 FOR_EACH_PTR(list
, tmp
) {
67 (tmp
->call_back
)(variable
, sym
, expr
, tmp
->info
);
68 } END_FOR_EACH_PTR(tmp
);
72 static void match_assign(struct expression
*expr
)
74 struct mod_cb_list
*call_backs
;
75 struct expression
*left
;
79 left
= strip_expr(expr
->left
);
80 name
= get_variable_from_expr(left
, &sym
);
83 call_backs
= search_mcall(var_hash
, name
);
86 call_call_backs(call_backs
, name
, sym
, expr
);
91 static void unop_expr(struct expression
*expr
)
93 struct mod_cb_list
*call_backs
;
97 if (expr
->op
!= SPECIAL_DECREMENT
&& expr
->op
!= SPECIAL_INCREMENT
)
100 expr
= strip_expr(expr
->unop
);
101 name
= get_variable_from_expr(expr
, &sym
);
104 call_backs
= search_mcall(var_hash
, name
);
107 call_call_backs(call_backs
, name
, sym
, expr
);
112 static void match_call(struct expression
*expr
)
114 struct mod_cb_list
*call_backs
;
115 struct expression
*arg
;
119 FOR_EACH_PTR(expr
->args
, arg
) {
120 arg
= strip_expr(arg
);
121 if (arg
->type
!= EXPR_PREOP
|| arg
->op
!= '&')
123 arg
= strip_expr(arg
->unop
);
124 name
= get_variable_from_expr(arg
, &sym
);
127 call_backs
= search_mcall(var_hash
, name
);
129 call_call_backs(call_backs
, name
, sym
, expr
);
131 } END_FOR_EACH_PTR(arg
);
134 static void match_end_func(struct symbol
*sym
)
136 destroy_function_hashtable(var_hash
);
137 var_hash
= create_function_hashtable(100);
140 void register_modification_hooks(int id
)
142 var_hash
= create_function_hashtable(100);
143 add_hook(&match_assign
, ASSIGNMENT_HOOK
);
144 add_hook(&unop_expr
, OP_HOOK
);
145 add_hook(&match_call
, FUNCTION_CALL_HOOK
);
146 add_hook(&match_end_func
, END_FUNC_HOOK
);