*new* add smatch_data/kernel.silenced_functions to silence common noise
[smatch.git] / smatch_data_source.c
blob6cb833a7002de0ac706d44771a21f2395d344bb2
1 /*
2 * smatch/smatch_data_source.c
4 * Copyright (C) 2013 Oracle.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include "smatch.h"
11 #include "smatch_slist.h"
13 static int my_id;
15 static char *get_source_parameter(struct expression *expr)
17 struct symbol *sym;
18 char *name;
19 int param;
20 struct sm_state *orig, *cur;
21 char *ret = NULL;
22 char buf[32];
24 name = expr_to_var_sym(expr, &sym);
25 if (!name || !sym)
26 goto out;
27 param = get_param_num_from_sym(sym);
28 if (param < 0)
29 goto out;
30 cur = get_sm_state(SMATCH_EXTRA, name, sym);
31 if (!cur)
32 goto out;
33 orig = get_sm_state_slist(get_start_states(), SMATCH_EXTRA, name, sym);
34 if (!orig)
35 goto out;
36 if (orig != cur)
37 goto out;
39 snprintf(buf, sizeof(buf), "p %d", param);
40 ret = alloc_string(buf);
42 out:
43 free_string(name);
44 return ret;
47 static char *get_source_assignment(struct expression *expr)
49 struct expression *right;
50 char *name;
51 char buf[64];
52 char *ret;
54 right = get_assigned_expr(expr);
55 right = strip_expr(right);
56 if (!right)
57 return NULL;
58 if (right->type != EXPR_CALL || right->fn->type != EXPR_SYMBOL)
59 return NULL;
60 name = expr_to_str(right->fn);
61 if (!name)
62 return NULL;
63 snprintf(buf, sizeof(buf), "r %s", name);
64 ret = alloc_string(buf);
65 free_string(name);
66 return ret;
69 static char *get_source_str(struct expression *expr)
71 char *source;
73 source = get_source_parameter(expr);
74 if (source)
75 return source;
76 return get_source_assignment(expr);
79 static void match_caller_info(struct expression *expr)
81 struct expression *tmp;
82 char *source;
83 int i;
85 i = -1;
86 FOR_EACH_PTR(expr->args, tmp) {
87 i++;
88 source = get_source_str(tmp);
89 if (!source)
90 continue;
91 sql_insert_caller_info(expr, DATA_SOURCE, i, "$$", source);
92 free_string(source);
93 } END_FOR_EACH_PTR(tmp);
96 void register_data_source(int id)
98 if (!option_info)
99 return;
100 my_id = id;
101 add_hook(&match_caller_info, FUNCTION_CALL_HOOK);