2 * This file is part of cparser.
3 * Copyright (C) 2007-2009 Matthias Braun <matze@braunis.de>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22 #include "adt/error.h"
25 #include "walk_statements.h"
28 static void walk_expression(expression_t const *const expr,
29 statement_callback const callback, void *const env)
31 switch (expr->base.kind) {
33 walk_statements(expr->statement.statement, callback, env);
37 walk_expression(expr->binary.left, callback, env);
38 walk_expression(expr->binary.right, callback, env);
41 EXPR_UNARY_CASES_OPTIONAL
42 if (expr->unary.value == NULL)
45 EXPR_UNARY_CASES_MANDATORY
46 walk_expression(expr->unary.value, callback, env);
50 for (call_argument_t *arg = expr->call.arguments; arg != NULL;
52 walk_expression(arg->expression, callback, env);
57 panic("unexpected expr kind");
59 case EXPR_COMPOUND_LITERAL:
63 case EXPR_CONDITIONAL:
64 walk_expression(expr->conditional.condition, callback, env);
65 /* may be NULL because of gnu extension */
66 if (expr->conditional.true_expression != NULL)
67 walk_expression(expr->conditional.true_expression, callback, env);
68 walk_expression(expr->conditional.false_expression, callback, env);
71 case EXPR_BUILTIN_CONSTANT_P:
72 walk_expression(expr->builtin_constant.value, callback, env);
76 walk_expression(expr->select.compound, callback, env);
79 case EXPR_ARRAY_ACCESS:
80 walk_expression(expr->array_access.array_ref, callback, env);
81 walk_expression(expr->array_access.index, callback, env);
84 case EXPR_CLASSIFY_TYPE:
85 walk_expression(expr->classify_type.type_expression, callback, env);
90 expression_t *tp_expression = expr->typeprop.tp_expression;
91 if (tp_expression != NULL) {
92 walk_expression(tp_expression, callback, env);
98 walk_expression(expr->va_starte.ap, callback, env);
102 walk_expression(expr->va_arge.ap, callback, env);
106 walk_expression(expr->va_copye.src, callback, env);
107 walk_expression(expr->va_copye.dst, callback, env);
113 case EXPR_REFERENCE_ENUM_VALUE:
115 case EXPR_CHARACTER_CONSTANT:
116 case EXPR_WIDE_CHARACTER_CONSTANT:
117 case EXPR_STRING_LITERAL:
118 case EXPR_WIDE_STRING_LITERAL:
120 case EXPR_LABEL_ADDRESS:
121 case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
125 /* TODO FIXME: implement all the missing expressions here */
128 static void walk_initializer(const initializer_t *initializer,
129 statement_callback callback,
132 switch(initializer->kind) {
133 case INITIALIZER_VALUE:
134 walk_expression(initializer->value.value, callback, env);
137 /* FIXME: should walk initializer hierarchies... */
142 static void walk_declarations(const entity_t* entity,
143 const entity_t* const last,
144 statement_callback const callback,
147 entity_t const *const end = last != NULL ? last->base.next : NULL;
148 for (; entity != end; entity = entity->base.next) {
149 /* we only look at variables */
150 if (entity->kind != ENTITY_VARIABLE)
153 const variable_t *variable = &entity->variable;
154 const initializer_t *initializer = variable->initializer;
155 if (initializer != NULL) {
156 walk_initializer(initializer, callback, env);
162 void walk_statements(statement_t *const stmt, statement_callback const callback, void *const env)
166 switch (stmt->kind) {
167 case STATEMENT_COMPOUND:
168 for (statement_t *s = stmt->compound.statements; s != NULL; s = s->base.next) {
169 walk_statements(s, callback, env);
174 walk_declarations(stmt->fors.scope.entities, NULL, callback, env);
175 if (stmt->fors.initialisation != NULL)
176 walk_expression(stmt->fors.initialisation, callback, env);
177 if (stmt->fors.condition != NULL)
178 walk_expression(stmt->fors.condition, callback, env);
179 if (stmt->fors.step != NULL)
180 walk_expression(stmt->fors.step, callback, env);
181 walk_statements(stmt->fors.body, callback, env);
185 walk_expression(stmt->ifs.condition, callback, env);
186 walk_statements(stmt->ifs.true_statement, callback, env);
187 if (stmt->ifs.false_statement != NULL)
188 walk_statements(stmt->ifs.false_statement, callback, env);
191 case STATEMENT_SWITCH:
192 walk_expression(stmt->switchs.expression, callback, env);
193 walk_statements(stmt->switchs.body, callback, env);
196 case STATEMENT_LABEL:
197 walk_statements(stmt->label.statement, callback, env);
200 case STATEMENT_CASE_LABEL:
201 walk_statements(stmt->case_label.statement, callback, env);
204 case STATEMENT_WHILE:
205 walk_expression(stmt->whiles.condition, callback, env);
206 walk_statements(stmt->whiles.body, callback, env);
209 case STATEMENT_DO_WHILE:
210 walk_statements(stmt->do_while.body, callback, env);
211 walk_expression(stmt->do_while.condition, callback, env);
214 case STATEMENT_EXPRESSION:
215 walk_expression(stmt->expression.expression, callback, env);
218 case STATEMENT_RETURN:
219 if (stmt->returns.value != NULL)
220 walk_expression(stmt->returns.value, callback, env);
223 case STATEMENT_DECLARATION:
224 walk_declarations(stmt->declaration.declarations_begin,
225 stmt->declaration.declarations_end, callback, env);
228 case STATEMENT_MS_TRY:
229 walk_statements(stmt->ms_try.try_statement, callback, env);
230 walk_statements(stmt->ms_try.final_statement, callback, env);
233 case STATEMENT_INVALID:
234 case STATEMENT_EMPTY:
235 case STATEMENT_CONTINUE:
236 case STATEMENT_BREAK:
239 case STATEMENT_LEAVE:
243 panic("unhandled statement");