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
20 #define RECURSE_LIMIT 10
22 int recurse(struct expression
*expr
,
23 int (func
)(struct expression
*expr
, void *p
),
31 ret
= func(expr
, param
);
35 if (nr
> RECURSE_LIMIT
)
41 ret
= recurse(expr
->unop
, func
, param
, nr
);
44 ret
= recurse(expr
->unop
, func
, param
, nr
);
53 ret
= recurse(expr
->left
, func
, param
, nr
);
56 ret
= recurse(expr
->right
, func
, param
, nr
);
59 ret
= recurse(expr
->right
, func
, param
, nr
);
62 ret
= recurse(expr
->left
, func
, param
, nr
);
65 ret
= recurse(expr
->deref
, func
, param
, nr
);
68 ret
= recurse(expr
->base
, func
, param
, nr
);
72 ret
= recurse(expr
->cast_expression
, func
, param
, nr
);
78 case EXPR_CONDITIONAL
:
80 ret
= recurse(expr
->conditional
, func
, param
, nr
);
83 ret
= recurse(expr
->cond_true
, func
, param
, nr
);
86 ret
= recurse(expr
->cond_false
, func
, param
, nr
);
91 case EXPR_INITIALIZER
:
95 ret
= recurse(expr
->ident_expression
, func
, param
, nr
);
98 ret
= recurse(expr
->idx_expression
, func
, param
, nr
);
101 ret
= recurse(expr
->init_expr
, func
, param
, nr
);
114 static int has_symbol_helper(struct expression
*expr
, void *_sym
)
116 struct symbol
*sym
= _sym
;
118 if (!expr
|| expr
->type
!= EXPR_SYMBOL
)
120 if (expr
->symbol
== sym
)
125 int has_symbol(struct expression
*expr
, struct symbol
*sym
)
127 return recurse(expr
, has_symbol_helper
, sym
, 0);
130 struct expr_name_sym
{
131 struct expression
*expr
;
136 static int has_var_helper(struct expression
*expr
, void *_var
)
138 struct expr_name_sym
*xns
= _var
;
145 if (expr
->type
!= xns
->expr
->type
)
147 // I hope this is defined for everything? It should work, right?
148 if (expr
->op
!= xns
->expr
->op
)
151 name
= expr_to_var_sym(expr
, &sym
);
154 if (sym
== xns
->sym
&& strcmp(name
, xns
->name
) == 0)
161 int has_variable(struct expression
*expr
, struct expression
*var
)
163 struct expr_name_sym xns
;
167 xns
.name
= expr_to_var_sym(var
, &xns
.sym
);
168 if (!xns
.name
|| !xns
.sym
)
170 ret
= recurse(expr
, has_var_helper
, &xns
, 0);
172 free_string(xns
.name
);
176 static int has_inc_dec_helper(struct expression
*expr
, void *unused
)
180 if (expr
->type
!= EXPR_PREOP
&& expr
->type
!= EXPR_POSTOP
)
182 if (expr
->op
== SPECIAL_INCREMENT
|| expr
->op
== SPECIAL_DECREMENT
)
187 int has_inc_dec(struct expression
*expr
)
189 return recurse(expr
, has_inc_dec_helper
, NULL
, 0);