6 #include "walk_statements.h"
9 static void walk_expression(expression_t const *const expr,
10 statement_callback const callback, void *const env)
12 switch (expr->base.kind) {
14 walk_statements(expr->statement.statement, callback, env);
18 walk_expression(expr->binary.left, callback, env);
19 walk_expression(expr->binary.right, callback, env);
22 EXPR_UNARY_CASES_OPTIONAL
23 if (expr->unary.value == NULL)
26 EXPR_UNARY_CASES_MANDATORY
27 walk_expression(expr->unary.value, callback, env);
31 for (call_argument_t *arg = expr->call.arguments; arg != NULL;
33 walk_expression(arg->expression, callback, env);
38 panic("unexpected expr kind");
40 case EXPR_COMPOUND_LITERAL:
44 case EXPR_CONDITIONAL:
45 walk_expression(expr->conditional.condition, callback, env);
46 /* may be NULL because of gnu extension */
47 if (expr->conditional.true_expression != NULL)
48 walk_expression(expr->conditional.true_expression, callback, env);
49 walk_expression(expr->conditional.false_expression, callback, env);
52 case EXPR_BUILTIN_ADDRESS:
53 walk_expression(expr->builtin_address.value, callback, env);
56 case EXPR_BUILTIN_PREFETCH: {
57 builtin_prefetch_expression_t const *const pf = &expr->builtin_prefetch;
58 walk_expression(pf->adr, callback, env);
60 walk_expression(pf->rw, callback, env);
61 if (pf->locality != NULL)
62 walk_expression(pf->locality, callback, env);
67 case EXPR_BUILTIN_CONSTANT_P:
68 walk_expression(expr->builtin_constant.value, callback, env);
72 walk_expression(expr->select.compound, callback, env);
75 case EXPR_ARRAY_ACCESS:
76 walk_expression(expr->array_access.array_ref, callback, env);
77 walk_expression(expr->array_access.index, callback, env);
80 case EXPR_CLASSIFY_TYPE:
81 walk_expression(expr->classify_type.type_expression, callback, env);
86 expression_t *tp_expression = expr->typeprop.tp_expression;
87 if (tp_expression != NULL) {
88 walk_expression(tp_expression, callback, env);
96 case EXPR_REFERENCE_ENUM_VALUE:
98 case EXPR_CHARACTER_CONSTANT:
99 case EXPR_WIDE_CHARACTER_CONSTANT:
100 case EXPR_STRING_LITERAL:
101 case EXPR_WIDE_STRING_LITERAL:
103 case EXPR_BUILTIN_SYMBOL:
106 case EXPR_LABEL_ADDRESS:
110 /* TODO FIXME: implement all the missing expressions here */
113 static void walk_initializer(const initializer_t *initializer,
114 statement_callback callback,
117 switch(initializer->kind) {
118 case INITIALIZER_VALUE:
119 walk_expression(initializer->value.value, callback, env);
122 /* FIXME: should walk initializer hierarchies... */
127 static void walk_declarations(const entity_t* entity,
128 const entity_t* const last,
129 statement_callback const callback,
132 entity_t const *const end = last != NULL ? last->base.next : NULL;
133 for (; entity != end; entity = entity->base.next) {
134 /* we only look at variables */
135 if (entity->kind != ENTITY_VARIABLE)
138 const variable_t *variable = &entity->variable;
139 const initializer_t *initializer = variable->initializer;
140 if (initializer != NULL) {
141 walk_initializer(initializer, callback, env);
147 void walk_statements(statement_t *const stmt, statement_callback const callback, void *const env)
151 switch (stmt->kind) {
152 case STATEMENT_COMPOUND:
153 for (statement_t *s = stmt->compound.statements; s != NULL; s = s->base.next) {
154 walk_statements(s, callback, env);
159 walk_declarations(stmt->fors.scope.entities, NULL, callback, env);
160 if (stmt->fors.initialisation != NULL)
161 walk_expression(stmt->fors.initialisation, callback, env);
162 if (stmt->fors.condition != NULL)
163 walk_expression(stmt->fors.condition, callback, env);
164 if (stmt->fors.step != NULL)
165 walk_expression(stmt->fors.step, callback, env);
166 walk_statements(stmt->fors.body, callback, env);
170 walk_expression(stmt->ifs.condition, callback, env);
171 walk_statements(stmt->ifs.true_statement, callback, env);
172 if (stmt->ifs.false_statement != NULL)
173 walk_statements(stmt->ifs.false_statement, callback, env);
176 case STATEMENT_SWITCH:
177 walk_expression(stmt->switchs.expression, callback, env);
178 walk_statements(stmt->switchs.body, callback, env);
181 case STATEMENT_LABEL:
182 walk_statements(stmt->label.statement, callback, env);
185 case STATEMENT_CASE_LABEL:
186 walk_statements(stmt->case_label.statement, callback, env);
189 case STATEMENT_WHILE:
190 walk_expression(stmt->whiles.condition, callback, env);
191 walk_statements(stmt->whiles.body, callback, env);
194 case STATEMENT_DO_WHILE:
195 walk_statements(stmt->do_while.body, callback, env);
196 walk_expression(stmt->do_while.condition, callback, env);
199 case STATEMENT_EXPRESSION:
200 walk_expression(stmt->expression.expression, callback, env);
203 case STATEMENT_RETURN:
204 if (stmt->returns.value != NULL)
205 walk_expression(stmt->returns.value, callback, env);
208 case STATEMENT_DECLARATION:
209 walk_declarations(stmt->declaration.declarations_begin,
210 stmt->declaration.declarations_end, callback, env);
213 case STATEMENT_MS_TRY:
214 walk_statements(stmt->ms_try.try_statement, callback, env);
215 walk_statements(stmt->ms_try.final_statement, callback, env);
218 case STATEMENT_INVALID:
219 case STATEMENT_EMPTY:
220 case STATEMENT_CONTINUE:
221 case STATEMENT_BREAK:
224 case STATEMENT_LEAVE:
228 panic("unhandled statement");