Makefile: allow CC to be defined outside the makefile
[smatch.git] / smatch_recurse.c
blobb30ca216fc85fb5d3ed1062de1d26bb26f63e119
1 /*
2 * Copyright (C) 2013 Oracle.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
18 #include "smatch.h"
20 #define RECURSE_LIMIT 10
22 static int recurse(struct expression *expr,
23 int (func)(struct expression *expr, void *p),
24 void *param, int nr)
26 int ret;
28 if (!expr)
29 return 0;
31 ret = func(expr, param);
32 if (ret)
33 return ret;
35 if (nr > RECURSE_LIMIT)
36 return -1;
37 nr++;
39 switch (expr->type) {
40 case EXPR_PREOP:
41 ret = recurse(expr->unop, func, param, nr);
42 break;
43 case EXPR_POSTOP:
44 ret = recurse(expr->unop, func, param, nr);
45 break;
46 case EXPR_STATEMENT:
47 return -1;
48 break;
49 case EXPR_LOGICAL:
50 case EXPR_COMPARE:
51 case EXPR_BINOP:
52 case EXPR_COMMA:
53 ret = recurse(expr->left, func, param, nr);
54 if (ret)
55 return ret;
56 ret = recurse(expr->right, func, param, nr);
57 break;
58 case EXPR_ASSIGNMENT:
59 ret = recurse(expr->right, func, param, nr);
60 if (ret)
61 return ret;
62 ret = recurse(expr->left, func, param, nr);
63 break;
64 case EXPR_DEREF:
65 ret = recurse(expr->deref, func, param, nr);
66 break;
67 case EXPR_SLICE:
68 ret = recurse(expr->base, func, param, nr);
69 break;
70 case EXPR_CAST:
71 case EXPR_FORCE_CAST:
72 ret = recurse(expr->cast_expression, func, param, nr);
73 break;
74 case EXPR_SIZEOF:
75 case EXPR_OFFSETOF:
76 case EXPR_ALIGNOF:
77 break;
78 case EXPR_CONDITIONAL:
79 case EXPR_SELECT:
80 ret = recurse(expr->conditional, func, param, nr);
81 if (ret)
82 return ret;
83 ret = recurse(expr->cond_true, func, param, nr);
84 if (ret)
85 return ret;
86 ret = recurse(expr->cond_false, func, param, nr);
87 break;
88 case EXPR_CALL:
89 return -1;
90 break;
91 case EXPR_INITIALIZER:
92 return -1;
93 break;
94 case EXPR_IDENTIFIER:
95 ret = recurse(expr->ident_expression, func, param, nr);
96 break;
97 case EXPR_INDEX:
98 ret = recurse(expr->idx_expression, func, param, nr);
99 break;
100 case EXPR_POS:
101 ret = recurse(expr->init_expr, func, param, nr);
102 break;
103 case EXPR_SYMBOL:
104 case EXPR_STRING:
105 case EXPR_VALUE:
106 break;
107 default:
108 return -1;
109 break;
111 return ret;
114 static int has_symbol_helper(struct expression *expr, void *_sym)
116 struct symbol *sym = _sym;
118 if (!expr || expr->type != EXPR_SYMBOL)
119 return 0;
120 if (expr->symbol == sym)
121 return 1;
122 return 0;
125 int has_symbol(struct expression *expr, struct symbol *sym)
127 return recurse(expr, has_symbol_helper, sym, 0);
130 int has_variable(struct expression *expr, struct expression *var)
132 char *name;
133 struct symbol *sym;
135 name = expr_to_var_sym(var, &sym);
136 free_string(name);
137 if (!sym)
138 return -1;
139 return has_symbol(expr, sym);
142 static int has_inc_dec_helper(struct expression *expr, void *unused)
144 if (!expr)
145 return 0;
146 if (expr->type != EXPR_PREOP && expr->type != EXPR_POSTOP)
147 return 0;
148 if (expr->op == SPECIAL_INCREMENT || expr->op == SPECIAL_DECREMENT)
149 return 1;
150 return 0;
153 int has_inc_dec(struct expression *expr)
155 return recurse(expr, has_inc_dec_helper, NULL, 0);