Use struct string_literal_expression_t instead of struct literal_expression_t for...
[cparser] / walk.c
1 /*
2  * This file is part of cparser.
3  * Copyright (C) 2007-2009 Matthias Braun <matze@braunis.de>
4  *
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.
9  *
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.
14  *
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
18  * 02111-1307, USA.
19  */
20 #include <config.h>
21
22 #include "adt/error.h"
23 #include "ast_t.h"
24 #include "entity_t.h"
25 #include "type_t.h"
26 #include "walk.h"
27 #include <libfirm/adt/pset.h>
28
29 typedef struct walk_env_t {
30         pset *visited_types;
31         declaration_callback declaration_func;
32         statement_callback   statement_func;
33         expression_callback  expression_func;
34         void *env;
35 } walk_env_t;
36
37 static void walk_expression(expression_t *expr, const walk_env_t *const env);
38 static void walk_statement(statement_t *stmt, const walk_env_t *env);
39 static void walk_entity(entity_t *entity, const walk_env_t *env);
40 static void walk_designator(const designator_t *, const walk_env_t *);
41 static void walk_initializer(const initializer_t  *, const walk_env_t *);
42 static void walk_scope(const scope_t *const scope, const walk_env_t *const env);
43
44 static void walk_type(type_t *const type, const walk_env_t *const env)
45 {
46         if (pset_find_ptr(env->visited_types, type) != NULL)
47                 return;
48         pset_insert_ptr(env->visited_types, type);
49
50         switch (type->kind) {
51         case TYPE_ATOMIC:
52         case TYPE_COMPLEX:
53         case TYPE_IMAGINARY:
54         case TYPE_REFERENCE:
55         case TYPE_ERROR:
56                 return;
57         case TYPE_POINTER:
58                 walk_type(type->pointer.points_to, env);
59                 return;
60         case TYPE_ARRAY:
61                 walk_type(type->array.element_type, env);
62                 if (type->array.size_expression != NULL)
63                         walk_expression(type->array.size_expression, env);
64                 return;
65         case TYPE_FUNCTION:
66                 for (function_parameter_t *parameter = type->function.parameters;
67                      parameter != NULL; parameter = parameter->next) {
68                         walk_type(parameter->type, env);
69                 }
70                 walk_type(type->function.return_type, env);
71                 return;
72         case TYPE_TYPEOF:
73                 walk_expression(type->typeoft.expression, env);
74                 return;
75         case TYPE_TYPEDEF:
76                 walk_entity((entity_t*)type->typedeft.typedefe, env);
77                 return;
78         case TYPE_COMPOUND_STRUCT:
79         case TYPE_COMPOUND_UNION:
80                 walk_entity((entity_t*)type->compound.compound, env);
81                 return;
82         case TYPE_ENUM:
83                 walk_entity((entity_t*)type->enumt.enume, env);
84                 return;
85         }
86         panic("invalid type found");
87 }
88
89 static void walk_expression(expression_t *const expr,
90                             const walk_env_t *const env)
91 {
92         env->expression_func(expr, env->env);
93
94         switch (expr->base.kind) {
95         case EXPR_STATEMENT:
96                 walk_statement(expr->statement.statement, env);
97                 return;
98
99         case EXPR_BINARY_CASES:
100                 walk_expression(expr->binary.left, env);
101                 walk_expression(expr->binary.right, env);
102                 return;
103
104         case EXPR_UNARY_CASES_OPTIONAL:
105                 if (expr->unary.value == NULL)
106                         return;
107                 /* FALLTHROUGH */
108         case EXPR_UNARY_CASES_MANDATORY:
109                 walk_expression(expr->unary.value, env);
110                 return;
111
112         case EXPR_CALL:
113                 for (call_argument_t *arg = expr->call.arguments; arg != NULL;
114                      arg = arg->next) {
115                         walk_expression(arg->expression, env);
116                 }
117                 return;
118
119         case EXPR_COMPOUND_LITERAL:
120                 walk_initializer(expr->compound_literal.initializer, env);
121                 return;
122
123         case EXPR_CONDITIONAL:
124                 walk_expression(expr->conditional.condition, env);
125                 /* may be NULL because of gnu extension */
126                 if (expr->conditional.true_expression != NULL)
127                         walk_expression(expr->conditional.true_expression, env);
128                 walk_expression(expr->conditional.false_expression, env);
129                 return;
130
131         case EXPR_BUILTIN_CONSTANT_P:
132                 walk_expression(expr->builtin_constant.value, env);
133                 return;
134
135         case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
136                 walk_type(expr->builtin_types_compatible.left, env);
137                 walk_type(expr->builtin_types_compatible.right, env);
138                 return;
139
140         case EXPR_SELECT:
141                 walk_expression(expr->select.compound, env);
142                 return;
143
144         case EXPR_ARRAY_ACCESS:
145                 walk_expression(expr->array_access.array_ref, env);
146                 walk_expression(expr->array_access.index, env);
147                 return;
148
149         case EXPR_CLASSIFY_TYPE:
150                 walk_expression(expr->classify_type.type_expression, env);
151                 return;
152
153         case EXPR_SIZEOF:
154         case EXPR_ALIGNOF: {
155                 expression_t *tp_expression = expr->typeprop.tp_expression;
156                 if (tp_expression != NULL) {
157                         walk_expression(tp_expression, env);
158                 }
159                 return;
160         }
161
162         case EXPR_VA_START:
163                 walk_expression(expr->va_starte.ap, env);
164                 return;
165
166         case EXPR_VA_ARG:
167                 walk_expression(expr->va_arge.ap, env);
168                 return;
169
170         case EXPR_VA_COPY:
171                 walk_expression(expr->va_copye.src, env);
172                 walk_expression(expr->va_copye.dst, env);
173                 return;
174
175         case EXPR_OFFSETOF:
176                 walk_designator(expr->offsetofe.designator, env);
177                 return;
178
179         case EXPR_LITERAL_CASES:
180         case EXPR_LITERAL_CHARACTER:
181         case EXPR_LITERAL_WIDE_CHARACTER:
182         case EXPR_REFERENCE:
183         case EXPR_ENUM_CONSTANT:
184         case EXPR_STRING_LITERAL:
185         case EXPR_FUNCNAME:
186         case EXPR_LABEL_ADDRESS:
187         case EXPR_ERROR:
188                 return;
189         }
190         panic("invalid expr kind");
191 }
192
193 static void walk_designator(const designator_t *designator,
194                             const walk_env_t *const env)
195 {
196         for ( ; designator != NULL; designator = designator->next) {
197                 if (designator->array_index != NULL)
198                         walk_expression(designator->array_index, env);
199         }
200 }
201
202 static void walk_initializer(const initializer_t  *initializer,
203                              const walk_env_t *const env)
204 {
205         switch(initializer->kind) {
206         case INITIALIZER_VALUE:
207                 walk_expression(initializer->value.value, env);
208                 return;
209         case INITIALIZER_LIST: {
210                 for (size_t i = 0; i < initializer->list.len; ++i) {
211                         walk_initializer(initializer->list.initializers[i], env);
212                 }
213                 return;
214         }
215         case INITIALIZER_DESIGNATOR:
216                 walk_designator(initializer->designator.designator, env);
217                 return;
218         case INITIALIZER_STRING:
219         case INITIALIZER_WIDE_STRING:
220                 return;
221         }
222 }
223
224 static void walk_entity(entity_t *entity, const walk_env_t *const env)
225 {
226         env->declaration_func(entity, env->env);
227
228         switch (entity->kind) {
229         case ENTITY_VARIABLE: {
230                 const variable_t    *variable    = &entity->variable;
231                 const initializer_t *initializer = variable->initializer;
232                 walk_type(entity->declaration.type, env);
233                 if (initializer != NULL) {
234                         walk_initializer(initializer, env);
235                 }
236                 return;
237         }
238         case ENTITY_ENUM_VALUE:
239                 if (entity->enum_value.value != NULL)
240                         walk_expression(entity->enum_value.value, env);
241                 return;
242         case ENTITY_TYPEDEF:
243                 walk_type(entity->typedefe.type, env);
244                 return;
245         case ENTITY_FUNCTION:
246                 walk_type(entity->declaration.type, env);
247                 if (entity->function.statement != NULL)
248                         walk_statement(entity->function.statement, env);
249                 return;
250         case ENTITY_COMPOUND_MEMBER:
251         case ENTITY_PARAMETER:
252                 walk_type(entity->declaration.type, env);
253                 return;
254         case ENTITY_CLASS:
255         case ENTITY_STRUCT:
256         case ENTITY_UNION:
257                 walk_scope(&entity->compound.members, env);
258                 return;
259         case ENTITY_NAMESPACE:
260                 walk_scope(&entity->namespacee.members, env);
261                 return;
262         case ENTITY_ENUM:
263                 for (entity = entity->base.next;
264                      entity != NULL && entity->kind == ENTITY_ENUM_VALUE;
265                          entity = entity->base.next) {
266                         walk_entity(entity, env);
267                 }
268                 return;
269         case ENTITY_LABEL:
270         case ENTITY_LOCAL_LABEL:
271                 return;
272         }
273         panic("invalid entity found");
274 }
275
276 static void walk_declarations(entity_t*            entity,
277                               entity_t*      const last,
278                                                           const walk_env_t    *const env)
279 {
280         entity_t const *const end = last != NULL ? last->base.next : NULL;
281         for (; entity != end; entity = entity->base.next) {
282                 walk_entity(entity, env);
283         }
284 }
285
286 static void walk_scope(const scope_t *const scope, const walk_env_t *const env)
287 {
288         walk_declarations(scope->entities, NULL, env);
289 }
290
291 static void walk_statement(statement_t *const stmt, const walk_env_t *const env)
292 {
293         env->statement_func(stmt, env->env);
294
295         switch (stmt->kind) {
296         case STATEMENT_COMPOUND:
297                 for (statement_t *s = stmt->compound.statements; s != NULL;
298                      s = s->base.next) {
299                         walk_statement(s, env);
300                 }
301                 return;
302
303         case STATEMENT_FOR:
304                 walk_declarations(stmt->fors.scope.entities, NULL, env);
305                 if (stmt->fors.initialisation != NULL)
306                         walk_expression(stmt->fors.initialisation, env);
307                 if (stmt->fors.condition != NULL)
308                         walk_expression(stmt->fors.condition, env);
309                 if (stmt->fors.step != NULL)
310                         walk_expression(stmt->fors.step, env);
311                 walk_statement(stmt->fors.body, env);
312                 return;
313
314         case STATEMENT_IF:
315                 walk_expression(stmt->ifs.condition, env);
316                 walk_statement(stmt->ifs.true_statement, env);
317                 if (stmt->ifs.false_statement != NULL)
318                         walk_statement(stmt->ifs.false_statement, env);
319                 return;
320
321         case STATEMENT_SWITCH:
322                 walk_expression(stmt->switchs.expression, env);
323                 walk_statement(stmt->switchs.body, env);
324                 return;
325
326         case STATEMENT_LABEL:
327                 walk_statement(stmt->label.statement, env);
328                 return;
329
330         case STATEMENT_CASE_LABEL:
331                 if (stmt->case_label.expression) {
332                         walk_expression(stmt->case_label.expression, env);
333                         if (stmt->case_label.end_range)
334                                 walk_expression(stmt->case_label.end_range, env);
335                 }
336                 walk_statement(stmt->case_label.statement, env);
337                 return;
338
339         case STATEMENT_WHILE:
340                 walk_expression(stmt->whiles.condition, env);
341                 walk_statement(stmt->whiles.body, env);
342                 return;
343
344         case STATEMENT_DO_WHILE:
345                 walk_statement(stmt->do_while.body, env);
346                 walk_expression(stmt->do_while.condition, env);
347                 return;
348
349         case STATEMENT_EXPRESSION:
350                 walk_expression(stmt->expression.expression, env);
351                 return;
352
353         case STATEMENT_RETURN:
354                 if (stmt->returns.value != NULL)
355                         walk_expression(stmt->returns.value, env);
356                 return;
357
358         case STATEMENT_DECLARATION:
359                 walk_declarations(stmt->declaration.declarations_begin,
360                                 stmt->declaration.declarations_end, env);
361                 return;
362
363         case STATEMENT_MS_TRY:
364                 walk_statement(stmt->ms_try.try_statement, env);
365                 walk_statement(stmt->ms_try.final_statement, env);
366                 return;
367
368         case STATEMENT_COMPUTED_GOTO:
369                 walk_expression(stmt->computed_goto.expression, env);
370                 return;
371
372         case STATEMENT_ERROR:
373         case STATEMENT_EMPTY:
374         case STATEMENT_CONTINUE:
375         case STATEMENT_BREAK:
376         case STATEMENT_ASM:
377         case STATEMENT_GOTO:
378         case STATEMENT_LEAVE:
379                 return;
380         }
381
382         panic("unhandled statement");
383 }
384
385 static void null_declaration_func(entity_t *entity, void *env)
386 {
387         (void) entity;
388         (void) env;
389 }
390
391 static void null_statement_func(statement_t *statement, void *env)
392 {
393         (void) statement;
394         (void) env;
395 }
396
397 static void null_expression_func(expression_t *expression, void *env)
398 {
399         (void) expression;
400         (void) env;
401 }
402
403 void walk_translation_unit(translation_unit_t *unit,
404                            declaration_callback declaration_func,
405                                                    statement_callback statement_func,
406                                                    expression_callback expression_func, void *env)
407 {
408         walk_env_t walk_env = {
409                 pset_new_ptr_default(),
410                 declaration_func != NULL ? declaration_func : null_declaration_func,
411                 statement_func != NULL ? statement_func : null_statement_func,
412                 expression_func != NULL ? expression_func : null_expression_func,
413                 env
414         };
415         walk_scope(&unit->scope, &walk_env);
416         del_pset(walk_env.visited_types);
417 }
418
419 void walk_statements(statement_t *statement, statement_callback func, void *env)
420 {
421         walk_env_t walk_env
422                 = { pset_new_ptr_default(),
423                     null_declaration_func, func, null_expression_func, env };
424         walk_statement(statement, &walk_env);
425         del_pset(walk_env.visited_types);
426 }