2 * This file is part of cparser.
3 * Copyright (C) 2012 Matthias Braun <matze@braunis.de>
12 #include <libfirm/adt/pset.h>
14 typedef struct walk_env_t {
16 declaration_callback declaration_func;
17 statement_callback statement_func;
18 expression_callback expression_func;
22 static void walk_expression(expression_t *expr, const walk_env_t *const env);
23 static void walk_statement(statement_t *stmt, const walk_env_t *env);
24 static void walk_entity(entity_t *entity, const walk_env_t *env);
25 static void walk_designator(const designator_t *, const walk_env_t *);
26 static void walk_initializer(const initializer_t *, const walk_env_t *);
27 static void walk_scope(const scope_t *const scope, const walk_env_t *const env);
29 static void walk_type(type_t *const type, const walk_env_t *const env)
31 if (pset_find_ptr(env->visited_types, type) != NULL)
33 pset_insert_ptr(env->visited_types, type);
43 walk_type(type->pointer.points_to, env);
46 walk_type(type->array.element_type, env);
47 if (type->array.size_expression != NULL)
48 walk_expression(type->array.size_expression, env);
51 for (function_parameter_t *parameter = type->function.parameters;
52 parameter != NULL; parameter = parameter->next) {
53 walk_type(parameter->type, env);
55 walk_type(type->function.return_type, env);
58 walk_expression(type->typeoft.expression, env);
61 walk_entity((entity_t*)type->typedeft.typedefe, env);
63 case TYPE_COMPOUND_STRUCT:
64 case TYPE_COMPOUND_UNION:
65 walk_entity((entity_t*)type->compound.compound, env);
68 walk_entity((entity_t*)type->enumt.enume, env);
71 panic("invalid type");
74 static void walk_expression(expression_t *const expr,
75 const walk_env_t *const env)
77 env->expression_func(expr, env->env);
79 switch (expr->base.kind) {
81 walk_statement(expr->statement.statement, env);
84 case EXPR_BINARY_CASES:
85 walk_expression(expr->binary.left, env);
86 walk_expression(expr->binary.right, env);
89 case EXPR_UNARY_CASES_OPTIONAL:
90 if (expr->unary.value == NULL)
93 case EXPR_UNARY_CASES_MANDATORY:
94 walk_expression(expr->unary.value, env);
98 for (call_argument_t *arg = expr->call.arguments; arg != NULL;
100 walk_expression(arg->expression, env);
104 case EXPR_COMPOUND_LITERAL:
105 walk_initializer(expr->compound_literal.initializer, env);
108 case EXPR_CONDITIONAL:
109 walk_expression(expr->conditional.condition, env);
110 /* may be NULL because of gnu extension */
111 if (expr->conditional.true_expression != NULL)
112 walk_expression(expr->conditional.true_expression, env);
113 walk_expression(expr->conditional.false_expression, env);
116 case EXPR_BUILTIN_CONSTANT_P:
117 walk_expression(expr->builtin_constant.value, env);
120 case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
121 walk_type(expr->builtin_types_compatible.left, env);
122 walk_type(expr->builtin_types_compatible.right, env);
126 walk_expression(expr->select.compound, env);
129 case EXPR_ARRAY_ACCESS:
130 walk_expression(expr->array_access.array_ref, env);
131 walk_expression(expr->array_access.index, env);
134 case EXPR_CLASSIFY_TYPE:
135 walk_expression(expr->classify_type.type_expression, env);
140 expression_t *tp_expression = expr->typeprop.tp_expression;
141 if (tp_expression != NULL) {
142 walk_expression(tp_expression, env);
148 walk_expression(expr->va_starte.ap, env);
152 walk_expression(expr->va_arge.ap, env);
156 walk_expression(expr->va_copye.src, env);
157 walk_expression(expr->va_copye.dst, env);
161 walk_designator(expr->offsetofe.designator, env);
164 case EXPR_LITERAL_CASES:
165 case EXPR_LITERAL_CHARACTER:
167 case EXPR_ENUM_CONSTANT:
168 case EXPR_STRING_LITERAL:
170 case EXPR_LABEL_ADDRESS:
174 panic("invalid expr kind");
177 static void walk_designator(const designator_t *designator,
178 const walk_env_t *const env)
180 for ( ; designator != NULL; designator = designator->next) {
181 if (designator->array_index != NULL)
182 walk_expression(designator->array_index, env);
186 static void walk_initializer(const initializer_t *initializer,
187 const walk_env_t *const env)
189 switch (initializer->kind) {
190 case INITIALIZER_VALUE:
191 walk_expression(initializer->value.value, env);
193 case INITIALIZER_LIST: {
194 for (size_t i = 0; i < initializer->list.len; ++i) {
195 walk_initializer(initializer->list.initializers[i], env);
199 case INITIALIZER_DESIGNATOR:
200 walk_designator(initializer->designator.designator, env);
203 case INITIALIZER_STRING:
208 static void walk_entity(entity_t *entity, const walk_env_t *const env)
210 env->declaration_func(entity, env->env);
212 switch (entity->kind) {
213 case ENTITY_VARIABLE: {
214 const variable_t *variable = &entity->variable;
215 const initializer_t *initializer = variable->initializer;
216 walk_type(entity->declaration.type, env);
217 if (initializer != NULL) {
218 walk_initializer(initializer, env);
222 case ENTITY_ENUM_VALUE:
223 if (entity->enum_value.value != NULL)
224 walk_expression(entity->enum_value.value, env);
227 walk_type(entity->typedefe.type, env);
229 case ENTITY_FUNCTION:
230 walk_type(entity->declaration.type, env);
231 if (entity->function.body != NULL)
232 walk_statement(entity->function.body, env);
234 case ENTITY_COMPOUND_MEMBER:
235 case ENTITY_PARAMETER:
236 walk_type(entity->declaration.type, env);
241 walk_scope(&entity->compound.members, env);
243 case ENTITY_NAMESPACE:
244 walk_scope(&entity->namespacee.members, env);
247 for (entity = entity->base.next;
248 entity != NULL && entity->kind == ENTITY_ENUM_VALUE;
249 entity = entity->base.next) {
250 walk_entity(entity, env);
254 case ENTITY_LOCAL_LABEL:
257 panic("invalid entity");
260 static void walk_declarations(entity_t* entity,
261 entity_t* const last,
262 const walk_env_t *const env)
264 entity_t const *const end = last != NULL ? last->base.next : NULL;
265 for (; entity != end; entity = entity->base.next) {
266 walk_entity(entity, env);
270 static void walk_scope(const scope_t *const scope, const walk_env_t *const env)
272 walk_declarations(scope->entities, NULL, env);
275 static void walk_statement(statement_t *const stmt, const walk_env_t *const env)
277 env->statement_func(stmt, env->env);
279 switch (stmt->kind) {
280 case STATEMENT_COMPOUND:
281 for (statement_t *s = stmt->compound.statements; s != NULL;
283 walk_statement(s, env);
288 walk_declarations(stmt->fors.scope.entities, NULL, env);
289 if (stmt->fors.initialisation != NULL)
290 walk_expression(stmt->fors.initialisation, env);
291 if (stmt->fors.condition != NULL)
292 walk_expression(stmt->fors.condition, env);
293 if (stmt->fors.step != NULL)
294 walk_expression(stmt->fors.step, env);
295 walk_statement(stmt->fors.body, env);
299 walk_expression(stmt->ifs.condition, env);
300 walk_statement(stmt->ifs.true_statement, env);
301 if (stmt->ifs.false_statement != NULL)
302 walk_statement(stmt->ifs.false_statement, env);
305 case STATEMENT_SWITCH:
306 walk_expression(stmt->switchs.expression, env);
307 walk_statement(stmt->switchs.body, env);
310 case STATEMENT_LABEL:
311 walk_statement(stmt->label.statement, env);
314 case STATEMENT_CASE_LABEL:
315 if (stmt->case_label.expression) {
316 walk_expression(stmt->case_label.expression, env);
317 if (stmt->case_label.end_range)
318 walk_expression(stmt->case_label.end_range, env);
320 walk_statement(stmt->case_label.statement, env);
323 case STATEMENT_DO_WHILE:
324 walk_statement(stmt->do_while.body, env);
325 walk_expression(stmt->do_while.condition, env);
328 case STATEMENT_EXPRESSION:
329 walk_expression(stmt->expression.expression, env);
332 case STATEMENT_RETURN:
333 if (stmt->returns.value != NULL)
334 walk_expression(stmt->returns.value, env);
337 case STATEMENT_DECLARATION:
338 walk_declarations(stmt->declaration.declarations_begin,
339 stmt->declaration.declarations_end, env);
342 case STATEMENT_MS_TRY:
343 walk_statement(stmt->ms_try.try_statement, env);
344 walk_statement(stmt->ms_try.final_statement, env);
347 case STATEMENT_COMPUTED_GOTO:
348 walk_expression(stmt->computed_goto.expression, env);
351 case STATEMENT_ERROR:
352 case STATEMENT_EMPTY:
353 case STATEMENT_CONTINUE:
354 case STATEMENT_BREAK:
357 case STATEMENT_LEAVE:
361 panic("unhandled statement");
364 static void null_declaration_func(entity_t *entity, void *env)
370 static void null_statement_func(statement_t *statement, void *env)
376 static void null_expression_func(expression_t *expression, void *env)
382 void walk_translation_unit(translation_unit_t *unit,
383 declaration_callback declaration_func,
384 statement_callback statement_func,
385 expression_callback expression_func, void *env)
387 walk_env_t walk_env = {
388 pset_new_ptr_default(),
389 declaration_func != NULL ? declaration_func : null_declaration_func,
390 statement_func != NULL ? statement_func : null_statement_func,
391 expression_func != NULL ? expression_func : null_expression_func,
394 walk_scope(&unit->scope, &walk_env);
395 del_pset(walk_env.visited_types);
398 void walk_statements(statement_t *statement, statement_callback func, void *env)
401 = { pset_new_ptr_default(),
402 null_declaration_func, func, null_expression_func, env };
403 walk_statement(statement, &walk_env);
404 del_pset(walk_env.visited_types);