Print this page
11972 resync smatch
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/smatch/src/smatch_hooks.c
+++ new/usr/src/tools/smatch/src/smatch_hooks.c
1 1 /*
2 2 * Copyright (C) 2006 Dan Carpenter.
3 3 *
4 4 * This program is free software; you can redistribute it and/or
5 5 * modify it under the terms of the GNU General Public License
6 6 * as published by the Free Software Foundation; either version 2
7 7 * of the License, or (at your option) any later version.
8 8 *
9 9 * This program is distributed in the hope that it will be useful,
10 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
11 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 * GNU General Public License for more details.
13 13 *
14 14 * You should have received a copy of the GNU General Public License
15 15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
16 16 */
17 17
18 18 #include "smatch.h"
19 19
20 20 enum data_type {
21 + NO_DATA,
21 22 EXPR_PTR,
22 23 STMT_PTR,
23 24 SYMBOL_PTR,
24 25 SYM_LIST_PTR,
25 26 };
26 27
27 28 struct hook_container {
28 29 int hook_type;
29 - enum data_type data_type;
30 + int owner;
30 31 void *fn;
31 32 };
32 33 ALLOCATOR(hook_container, "hook functions");
33 34 DECLARE_PTR_LIST(hook_func_list, struct hook_container);
35 +
36 +typedef void (expr_func)(struct expression *expr);
37 +typedef void (stmt_func)(struct statement *stmt);
38 +typedef void (sym_func)(struct symbol *sym);
39 +typedef void (sym_list_func)(struct symbol_list *sym_list);
40 +
34 41 static struct hook_func_list *merge_funcs;
35 42 static struct hook_func_list *unmatched_state_funcs;
36 43 static struct hook_func_list *hook_array[NUM_HOOKS] = {};
37 -void (**pre_merge_hooks)(struct sm_state *sm);
44 +static const enum data_type data_types[NUM_HOOKS] = {
45 + [EXPR_HOOK] = EXPR_PTR,
46 + [EXPR_HOOK_AFTER] = EXPR_PTR,
47 + [STMT_HOOK] = STMT_PTR,
48 + [STMT_HOOK_AFTER] = STMT_PTR,
49 + [SYM_HOOK] = EXPR_PTR,
50 + [STRING_HOOK] = EXPR_PTR,
51 + [DECLARATION_HOOK] = SYMBOL_PTR,
52 + [ASSIGNMENT_HOOK] = EXPR_PTR,
53 + [ASSIGNMENT_HOOK_AFTER] = EXPR_PTR,
54 + [RAW_ASSIGNMENT_HOOK] = EXPR_PTR,
55 + [GLOBAL_ASSIGNMENT_HOOK] = EXPR_PTR,
56 + [CALL_ASSIGNMENT_HOOK] = EXPR_PTR,
57 + [MACRO_ASSIGNMENT_HOOK] = EXPR_PTR,
58 + [BINOP_HOOK] = EXPR_PTR,
59 + [OP_HOOK] = EXPR_PTR,
60 + [LOGIC_HOOK] = EXPR_PTR,
61 + [PRELOOP_HOOK] = STMT_PTR,
62 + [CONDITION_HOOK] = EXPR_PTR,
63 + [SELECT_HOOK] = EXPR_PTR,
64 + [WHOLE_CONDITION_HOOK] = EXPR_PTR,
65 + [FUNCTION_CALL_HOOK] = EXPR_PTR,
66 + [CALL_HOOK_AFTER_INLINE] = EXPR_PTR,
67 + [FUNCTION_CALL_HOOK_AFTER_DB] = EXPR_PTR,
68 + [DEREF_HOOK] = EXPR_PTR,
69 + [CASE_HOOK] = NO_DATA,
70 + [ASM_HOOK] = STMT_PTR,
71 + [CAST_HOOK] = EXPR_PTR,
72 + [SIZEOF_HOOK] = EXPR_PTR,
73 + [BASE_HOOK] = SYMBOL_PTR,
74 + [FUNC_DEF_HOOK] = SYMBOL_PTR,
75 + [AFTER_DEF_HOOK] = SYMBOL_PTR,
76 + [END_FUNC_HOOK] = SYMBOL_PTR,
77 + [AFTER_FUNC_HOOK] = SYMBOL_PTR,
78 + [RETURN_HOOK] = EXPR_PTR,
79 + [INLINE_FN_START] = EXPR_PTR,
80 + [INLINE_FN_END] = EXPR_PTR,
81 + [END_FILE_HOOK] = SYM_LIST_PTR,
82 +};
38 83
84 +void (**pre_merge_hooks)(struct sm_state *cur, struct sm_state *other);
85 +
39 86 struct scope_container {
40 87 void *fn;
41 88 void *data;
42 89 };
43 90 ALLOCATOR(scope_container, "scope hook functions");
44 91 DECLARE_PTR_LIST(scope_hook_list, struct scope_container);
45 92 DECLARE_PTR_LIST(scope_hook_stack, struct scope_hook_list);
46 93 static struct scope_hook_stack *scope_hooks;
47 94
48 95 void add_hook(void *func, enum hook_type type)
49 96 {
50 97 struct hook_container *container = __alloc_hook_container(0);
51 98
52 99 container->hook_type = type;
53 100 container->fn = func;
54 - switch (type) {
55 - case EXPR_HOOK:
56 - container->data_type = EXPR_PTR;
57 - break;
58 - case STMT_HOOK:
59 - container->data_type = STMT_PTR;
60 - break;
61 - case STMT_HOOK_AFTER:
62 - container->data_type = STMT_PTR;
63 - break;
64 - case SYM_HOOK:
65 - container->data_type = EXPR_PTR;
66 - break;
67 - case STRING_HOOK:
68 - container->data_type = EXPR_PTR;
69 - break;
70 - case DECLARATION_HOOK:
71 - container->data_type = SYMBOL_PTR;
72 - break;
73 - case ASSIGNMENT_HOOK:
74 - container->data_type = EXPR_PTR;
75 - break;
76 - case ASSIGNMENT_HOOK_AFTER:
77 - container->data_type = EXPR_PTR;
78 - break;
79 - case RAW_ASSIGNMENT_HOOK:
80 - container->data_type = EXPR_PTR;
81 - break;
82 - case GLOBAL_ASSIGNMENT_HOOK:
83 - container->data_type = EXPR_PTR;
84 - break;
85 - case CALL_ASSIGNMENT_HOOK:
86 - container->data_type = EXPR_PTR;
87 - break;
88 - case MACRO_ASSIGNMENT_HOOK:
89 - container->data_type = EXPR_PTR;
90 - break;
91 - case BINOP_HOOK:
92 - container->data_type = EXPR_PTR;
93 - break;
94 - case OP_HOOK:
95 - container->data_type = EXPR_PTR;
96 - break;
97 - case LOGIC_HOOK:
98 - container->data_type = EXPR_PTR;
99 - break;
100 - case PRELOOP_HOOK:
101 - container->data_type = STMT_PTR;
102 - break;
103 - case CONDITION_HOOK:
104 - container->data_type = EXPR_PTR;
105 - break;
106 - case SELECT_HOOK:
107 - container->data_type = EXPR_PTR;
108 - break;
109 - case WHOLE_CONDITION_HOOK:
110 - container->data_type = EXPR_PTR;
111 - break;
112 - case FUNCTION_CALL_HOOK:
113 - container->data_type = EXPR_PTR;
114 - break;
115 - case CALL_HOOK_AFTER_INLINE:
116 - container->data_type = EXPR_PTR;
117 - break;
118 - case FUNCTION_CALL_HOOK_AFTER_DB:
119 - container->data_type = EXPR_PTR;
120 - break;
121 - case DEREF_HOOK:
122 - container->data_type = EXPR_PTR;
123 - break;
124 - case CASE_HOOK:
125 - /* nothing needed */
126 - break;
127 - case ASM_HOOK:
128 - container->data_type = STMT_PTR;
129 - break;
130 - case CAST_HOOK:
131 - container->data_type = EXPR_PTR;
132 - break;
133 - case SIZEOF_HOOK:
134 - container->data_type = EXPR_PTR;
135 - break;
136 - case BASE_HOOK:
137 - container->data_type = SYMBOL_PTR;
138 - break;
139 - case FUNC_DEF_HOOK:
140 - container->data_type = SYMBOL_PTR;
141 - break;
142 - case AFTER_DEF_HOOK:
143 - container->data_type = SYMBOL_PTR;
144 - break;
145 - case END_FUNC_HOOK:
146 - container->data_type = SYMBOL_PTR;
147 - break;
148 - case AFTER_FUNC_HOOK:
149 - container->data_type = SYMBOL_PTR;
150 - break;
151 - case RETURN_HOOK:
152 - container->data_type = EXPR_PTR;
153 - break;
154 - case INLINE_FN_START:
155 - container->data_type = EXPR_PTR;
156 - break;
157 - case INLINE_FN_END:
158 - container->data_type = EXPR_PTR;
159 - break;
160 - case END_FILE_HOOK:
161 - container->data_type = SYM_LIST_PTR;
162 - break;
163 - }
101 +
164 102 add_ptr_list(&hook_array[type], container);
165 103 }
166 104
167 105 void add_merge_hook(int client_id, merge_func_t *func)
168 106 {
169 107 struct hook_container *container = __alloc_hook_container(0);
170 - container->data_type = client_id;
108 + container->owner = client_id;
171 109 container->fn = func;
172 110 add_ptr_list(&merge_funcs, container);
173 111 }
174 112
175 113 void add_unmatched_state_hook(int client_id, unmatched_func_t *func)
176 114 {
177 115 struct hook_container *container = __alloc_hook_container(0);
178 - container->data_type = client_id;
116 + container->owner = client_id;
179 117 container->fn = func;
180 118 add_ptr_list(&unmatched_state_funcs, container);
181 119 }
182 120
183 -void add_pre_merge_hook(int client_id, void (*hook)(struct sm_state *sm))
121 +void add_pre_merge_hook(int client_id, void (*hook)(struct sm_state *cur, struct sm_state *other))
184 122 {
185 123 pre_merge_hooks[client_id] = hook;
186 124 }
187 125
188 -static void pass_to_client(void *fn)
189 -{
190 - typedef void (expr_func)();
191 - ((expr_func *) fn)();
192 -}
193 -
194 126 static void pass_expr_to_client(void *fn, void *data)
195 127 {
196 - typedef void (expr_func)(struct expression *expr);
197 - ((expr_func *) fn)((struct expression *) data);
128 + ((expr_func *)fn)((struct expression *)data);
198 129 }
199 130
200 131 static void pass_stmt_to_client(void *fn, void *data)
201 132 {
202 - typedef void (stmt_func)(struct statement *stmt);
203 - ((stmt_func *) fn)((struct statement *) data);
133 + ((stmt_func *)fn)((struct statement *)data);
204 134 }
205 135
206 136 static void pass_sym_to_client(void *fn, void *data)
207 137 {
208 - typedef void (sym_func)(struct symbol *sym);
209 - ((sym_func *) fn)((struct symbol *) data);
138 + ((sym_func *)fn)((struct symbol *)data);
210 139 }
211 140
212 141 static void pass_sym_list_to_client(void *fn, void *data)
213 142 {
214 - typedef void (sym_func)(struct symbol_list *sym_list);
215 - ((sym_func *) fn)((struct symbol_list *) data);
143 + ((sym_list_func *)fn)((struct symbol_list *)data);
216 144 }
217 145
218 146 void __pass_to_client(void *data, enum hook_type type)
219 147 {
220 148 struct hook_container *container;
221 149
222 -
223 150 FOR_EACH_PTR(hook_array[type], container) {
224 - switch (container->data_type) {
151 + switch (data_types[type]) {
225 152 case EXPR_PTR:
226 153 pass_expr_to_client(container->fn, data);
227 154 break;
228 155 case STMT_PTR:
229 156 pass_stmt_to_client(container->fn, data);
230 157 break;
231 158 case SYMBOL_PTR:
232 159 pass_sym_to_client(container->fn, data);
233 160 break;
234 161 case SYM_LIST_PTR:
235 162 pass_sym_list_to_client(container->fn, data);
236 163 break;
237 164 }
238 165 } END_FOR_EACH_PTR(container);
239 166 }
240 167
241 -void __pass_to_client_no_data(enum hook_type type)
242 -{
243 - struct hook_container *container;
244 -
245 - FOR_EACH_PTR(hook_array[type], container) {
246 - pass_to_client(container->fn);
247 - } END_FOR_EACH_PTR(container);
248 -}
249 -
250 168 void __pass_case_to_client(struct expression *switch_expr,
251 169 struct range_list *rl)
252 170 {
253 171 typedef void (case_func)(struct expression *switch_expr,
254 172 struct range_list *rl);
255 173 struct hook_container *container;
256 174
257 175 FOR_EACH_PTR(hook_array[CASE_HOOK], container) {
258 - ((case_func *) container->fn)(switch_expr, rl);
176 + ((case_func *)container->fn)(switch_expr, rl);
259 177 } END_FOR_EACH_PTR(container);
260 178 }
261 179
262 180 int __has_merge_function(int client_id)
263 181 {
264 182 struct hook_container *tmp;
265 183
266 184 FOR_EACH_PTR(merge_funcs, tmp) {
267 - if (tmp->data_type == client_id)
185 + if (tmp->owner == client_id)
268 186 return 1;
269 187 } END_FOR_EACH_PTR(tmp);
270 188 return 0;
271 189 }
272 190
273 191 struct smatch_state *__client_merge_function(int owner,
274 192 struct smatch_state *s1,
275 193 struct smatch_state *s2)
276 194 {
277 195 struct smatch_state *tmp_state;
278 196 struct hook_container *tmp;
279 197
280 198 /* Pass NULL states first and the rest alphabetically by name */
281 199 if (!s2 || (s1 && strcmp(s2->name, s1->name) < 0)) {
282 200 tmp_state = s1;
283 201 s1 = s2;
284 202 s2 = tmp_state;
285 203 }
286 204
287 205 FOR_EACH_PTR(merge_funcs, tmp) {
288 - if (tmp->data_type == owner)
289 - return ((merge_func_t *) tmp->fn)(s1, s2);
206 + if (tmp->owner == owner)
207 + return ((merge_func_t *)tmp->fn)(s1, s2);
290 208 } END_FOR_EACH_PTR(tmp);
291 209 return &undefined;
292 210 }
293 211
294 212 struct smatch_state *__client_unmatched_state_function(struct sm_state *sm)
295 213 {
296 214 struct hook_container *tmp;
297 215
298 216 FOR_EACH_PTR(unmatched_state_funcs, tmp) {
299 - if (tmp->data_type == sm->owner)
300 - return ((unmatched_func_t *) tmp->fn)(sm);
217 + if (tmp->owner == sm->owner)
218 + return ((unmatched_func_t *)tmp->fn)(sm);
301 219 } END_FOR_EACH_PTR(tmp);
302 220 return &undefined;
303 221 }
304 222
305 -void call_pre_merge_hook(struct sm_state *sm)
223 +void call_pre_merge_hook(struct sm_state *cur, struct sm_state *other)
306 224 {
307 - if (sm->owner >= num_checks)
225 + if (cur->owner >= num_checks)
308 226 return;
309 227
310 - if (pre_merge_hooks[sm->owner])
311 - pre_merge_hooks[sm->owner](sm);
228 + if (pre_merge_hooks[cur->owner])
229 + pre_merge_hooks[cur->owner](cur, other);
312 230 }
313 231
314 232 static struct scope_hook_list *pop_scope_hook_list(struct scope_hook_stack **stack)
315 233 {
316 234 struct scope_hook_list *hook_list;
317 235
318 236 hook_list = last_ptr_list((struct ptr_list *)*stack);
319 237 delete_ptr_list_last((struct ptr_list **)stack);
320 238 return hook_list;
321 239 }
322 240
323 241 static void push_scope_hook_list(struct scope_hook_stack **stack, struct scope_hook_list *l)
324 242 {
325 243 add_ptr_list(stack, l);
326 244 }
327 245
328 246 void add_scope_hook(scope_hook *fn, void *data)
329 247 {
330 248 struct scope_hook_list *hook_list;
331 249 struct scope_container *new;
332 250
333 251 if (!scope_hooks)
334 252 return;
335 253 hook_list = pop_scope_hook_list(&scope_hooks);
336 254 new = __alloc_scope_container(0);
337 255 new->fn = fn;
338 256 new->data = data;
339 257 add_ptr_list(&hook_list, new);
340 258 push_scope_hook_list(&scope_hooks, hook_list);
341 259 }
342 260
343 261 void __push_scope_hooks(void)
344 262 {
345 263 push_scope_hook_list(&scope_hooks, NULL);
346 264 }
347 265
↓ open down ↓ |
26 lines elided |
↑ open up ↑ |
348 266 void __call_scope_hooks(void)
349 267 {
350 268 struct scope_hook_list *hook_list;
351 269 struct scope_container *tmp;
352 270
353 271 if (!scope_hooks)
354 272 return;
355 273
356 274 hook_list = pop_scope_hook_list(&scope_hooks);
357 275 FOR_EACH_PTR(hook_list, tmp) {
358 - ((scope_hook *) tmp->fn)(tmp->data);
276 + ((scope_hook *)tmp->fn)(tmp->data);
359 277 __free_scope_container(tmp);
360 278 } END_FOR_EACH_PTR(tmp);
361 279 }
362 280
363 281 void allocate_hook_memory(void)
364 282 {
365 283 pre_merge_hooks = malloc(num_checks * sizeof(*pre_merge_hooks));
366 284 memset(pre_merge_hooks, 0, num_checks * sizeof(*pre_merge_hooks));
367 285 }
368 286
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX