3 #include "walk_statements.h"
6 static void walk_expression(expression_t const *const expr, statement_callback const callback, void *const env)
8 switch (expr->base.kind) {
10 walk_statements(expr->statement.statement, callback, env);
14 walk_expression(expr->binary.left, callback, env);
15 walk_expression(expr->binary.right, callback, env);
18 EXPR_UNARY_CASES_OPTIONAL
19 if (expr->unary.value == NULL)
22 EXPR_UNARY_CASES_MANDATORY
23 walk_expression(expr->unary.value, callback, env);
27 for (call_argument_t *arg = expr->call.arguments; arg != NULL; arg = arg->next) {
28 walk_expression(arg->expression, callback, env);
34 panic("unexpected expr kind");
36 case EXPR_COMPOUND_LITERAL:
40 case EXPR_CONDITIONAL:
41 walk_expression(expr->conditional.condition, callback, env);
42 walk_expression(expr->conditional.true_expression, callback, env);
43 walk_expression(expr->conditional.false_expression, callback, env);
46 case EXPR_BUILTIN_PREFETCH:
47 walk_expression(expr->builtin_prefetch.adr, callback, env);
48 walk_expression(expr->builtin_prefetch.rw, callback, env);
49 walk_expression(expr->builtin_prefetch.locality, callback, env);
52 case EXPR_BUILTIN_CONSTANT_P:
53 walk_expression(expr->builtin_constant.value, callback, env);
57 walk_expression(expr->select.compound, callback, env);
60 case EXPR_ARRAY_ACCESS:
61 walk_expression(expr->array_access.array_ref, callback, env);
62 walk_expression(expr->array_access.index, callback, env);
65 case EXPR_CLASSIFY_TYPE:
66 walk_expression(expr->classify_type.type_expression, callback, env);
71 expression_t *tp_expression = expr->typeprop.tp_expression;
72 if (tp_expression != NULL) {
73 walk_expression(tp_expression, callback, env);
81 case EXPR_CHARACTER_CONSTANT:
82 case EXPR_WIDE_CHARACTER_CONSTANT:
83 case EXPR_STRING_LITERAL:
84 case EXPR_WIDE_STRING_LITERAL:
86 case EXPR_BUILTIN_SYMBOL:
89 case EXPR_LABEL_ADDRESS:
93 /* TODO FIXME: implement all the missing expressions here */
97 static void walk_declarations(const declaration_t * decl,
98 const declaration_t *const end,
99 statement_callback const callback,
102 for (; decl != end; decl = decl->next) {
103 if (decl->namespc != NAMESPACE_NORMAL)
106 const initializer_t *initializer = decl->init.initializer;
107 /* FIXME: should walk initializer hierarchies... */
108 if (initializer != NULL && initializer->kind == INITIALIZER_VALUE) {
109 walk_expression(initializer->value.value, callback, env);
115 void walk_statements(statement_t *const stmt, statement_callback const callback, void *const env)
119 switch (stmt->kind) {
120 case STATEMENT_COMPOUND:
121 for (statement_t *s = stmt->compound.statements; s != NULL; s = s->base.next) {
122 walk_statements(s, callback, env);
127 walk_declarations(stmt->fors.scope.declarations, NULL, callback, env);
128 if (stmt->fors.initialisation != NULL)
129 walk_expression(stmt->fors.initialisation, callback, env);
130 if (stmt->fors.condition != NULL)
131 walk_expression(stmt->fors.condition, callback, env);
132 if (stmt->fors.step != NULL)
133 walk_expression(stmt->fors.step, callback, env);
134 walk_statements(stmt->fors.body, callback, env);
138 walk_expression(stmt->ifs.condition, callback, env);
139 walk_statements(stmt->ifs.true_statement, callback, env);
140 if (stmt->ifs.false_statement != NULL)
141 walk_statements(stmt->ifs.false_statement, callback, env);
144 case STATEMENT_SWITCH:
145 walk_expression(stmt->switchs.expression, callback, env);
146 walk_statements(stmt->switchs.body, callback, env);
149 case STATEMENT_LABEL:
150 walk_statements(stmt->label.statement, callback, env);
153 case STATEMENT_CASE_LABEL:
154 walk_statements(stmt->case_label.statement, callback, env);
157 case STATEMENT_WHILE:
158 walk_expression(stmt->whiles.condition, callback, env);
159 walk_statements(stmt->whiles.body, callback, env);
162 case STATEMENT_DO_WHILE:
163 walk_statements(stmt->do_while.body, callback, env);
164 walk_expression(stmt->do_while.condition, callback, env);
167 case STATEMENT_EXPRESSION:
168 walk_expression(stmt->expression.expression, callback, env);
171 case STATEMENT_RETURN:
172 if (stmt->returns.value != NULL)
173 walk_expression(stmt->returns.value, callback, env);
176 case STATEMENT_DECLARATION:
177 walk_declarations(stmt->declaration.declarations_begin,
178 stmt->declaration.declarations_end->next,
182 case STATEMENT_MS_TRY:
183 walk_statements(stmt->ms_try.try_statement, callback, env);
184 walk_statements(stmt->ms_try.final_statement, callback, env);
187 case STATEMENT_INVALID:
188 case STATEMENT_EMPTY:
189 case STATEMENT_CONTINUE:
190 case STATEMENT_BREAK:
193 case STATEMENT_LEAVE:
197 panic("unhandled statement");