Start doing constant strings right: do proper concatenation of strings,
[smatch.git] / show-parse.c
blob7e7209336b737d9d5941fed39713229c27964362
1 /*
2 * sparse/show-parse.c
4 * Copyright (C) 2003 Linus Torvalds, all rights reserved.
6 * Print out results of parsing for debugging and testing.
7 */
8 #include <stdarg.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <ctype.h>
13 #include <unistd.h>
14 #include <fcntl.h>
16 #include "lib.h"
17 #include "token.h"
18 #include "parse.h"
19 #include "symbol.h"
20 #include "scope.h"
21 #include "expression.h"
24 * Symbol type printout. The type system is by far the most
25 * complicated part of C - everything else is trivial.
27 const char *modifier_string(unsigned long mod)
29 static char buffer[100];
30 char *p = buffer;
31 const char *res,**ptr, *names[] = {
32 "auto", "register", "static", "extern",
33 "const", "volatile", "[signed]", "[unsigned]",
34 "[char]", "[short]", "[long]", "[long]",
35 "[typdef]", "[structof]", "[unionof]", "[enum]",
36 "[typeof]", "[attribute]",
37 NULL
39 ptr = names;
40 while ((res = *ptr++) != NULL) {
41 if (mod & 1) {
42 char c;
43 while ((c = *res++) != '\0')
44 *p++ = c;
45 *p++ = ' ';
47 mod >>= 1;
49 *p = 0;
50 return buffer;
53 void show_struct_member(struct symbol *sym, void *data, int flags)
55 if (flags & ITERATE_FIRST)
56 printf(" { ");
57 printf("%s:%d:%d at offset %ld", show_ident(sym->ident), sym->bit_size, sym->alignment, sym->offset);
58 if (sym->fieldwidth)
59 printf("[%d..%d]", sym->bit_offset, sym->bit_offset+sym->fieldwidth-1);
60 if (flags & ITERATE_LAST)
61 printf(" } ");
62 else
63 printf(", ");
66 static void show_one_symbol(struct symbol *sym, void *sep, int flags)
68 show_symbol(sym);
69 if (!(flags & ITERATE_LAST))
70 printf("%s", (const char *)sep);
73 void show_symbol_list(struct symbol_list *list, const char *sep)
75 symbol_iterate(list, show_one_symbol, (void *)sep);
78 void show_type_list(struct symbol *sym)
80 while (sym) {
81 show_symbol(sym);
82 sym = sym->next;
86 void show_type(struct symbol *sym)
88 int i;
89 static struct ctype_name {
90 struct symbol *sym;
91 char *name;
92 } typenames[] = {
93 { & char_ctype, "char" },
94 { &uchar_ctype, "unsigned char" },
95 { & short_ctype, "short" },
96 { &ushort_ctype, "unsigned short" },
97 { & int_ctype, "int" },
98 { &uint_ctype, "unsigned int" },
99 { & long_ctype, "long" },
100 { &ulong_ctype, "unsigned long" },
101 { & llong_ctype, "long long" },
102 { &ullong_ctype, "unsigned long long" },
104 { &void_ctype, "void" },
105 { &bool_ctype, "bool" },
106 { &string_ctype, "string" },
108 { &float_ctype, "float" },
109 { &double_ctype, "double" },
110 { &ldouble_ctype,"long double" },
113 if (!sym)
114 return;
116 for (i = 0; i < sizeof(typenames)/sizeof(typenames[0]); i++) {
117 if (typenames[i].sym == sym) {
118 printf("%s", typenames[i].name);
119 return;
123 printf("%s", modifier_string(sym->ctype.modifiers));
124 switch (sym->type) {
125 case SYM_PTR:
126 printf("*");
127 show_type(sym->ctype.base_type);
128 return;
130 case SYM_FN:
131 printf("<fn>(");
132 show_type(sym->ctype.base_type);
133 printf(")");
134 printf("(");
135 show_symbol_list(sym->arguments, ", ");
136 if (sym->variadic)
137 printf(", ...");
138 printf(")");
139 return;
141 case SYM_ARRAY:
142 printf("<array [%d] of>(", sym->array_size);
143 show_type(sym->ctype.base_type);
144 printf(")");
145 return;
147 case SYM_STRUCT:
148 printf("struct %s", show_ident(sym->ident));
149 return;
151 case SYM_UNION:
152 printf("union %s", show_ident(sym->ident));
153 return;
155 case SYM_ENUM:
156 printf("enum %s", show_ident(sym->ident));
157 return;
159 case SYM_NODE: {
160 struct symbol *type = sym->ctype.base_type;
161 if (!type)
162 printf("notype");
163 else
164 show_type(type);
165 printf(": %s", show_ident(sym->ident));
166 return;
169 case SYM_BITFIELD:
170 show_type(sym->ctype.base_type);
171 printf(":%d", sym->fieldwidth);
172 return;
174 default:
175 printf("strange type %d '%s' of type ", sym->type, show_ident(sym->ident));
176 show_type(sym->ctype.base_type);
177 return;
181 void show_symbol(struct symbol *sym)
183 struct symbol *type;
185 if (sym->type != SYM_NODE)
186 *(int *)0 = 0;
187 show_type(sym);
188 type = sym->ctype.base_type;
189 if (!type)
190 return;
193 * Show actual implementation information
195 switch (type->type) {
196 case SYM_STRUCT:
197 printf("\n");
198 symbol_iterate(type->symbol_list, show_struct_member, NULL);
199 return;
201 case SYM_UNION:
202 printf("\n");
203 symbol_iterate(type->symbol_list, show_struct_member, NULL);
204 return;
206 case SYM_FN:
207 printf("\n");
208 show_statement(type->stmt);
209 return;
211 default:
212 break;
217 * Print out a statement
219 void show_statement(struct statement *stmt)
221 if (!stmt)
222 return;
223 switch (stmt->type) {
224 case STMT_RETURN:
225 printf("\treturn ");
226 show_expression(stmt->expression);
227 break;
228 case STMT_COMPOUND:
229 printf("{\n");
230 if (stmt->syms) {
231 printf("\t");
232 show_symbol_list(stmt->syms, "\n\t");
233 printf("\n\n");
235 show_statement_list(stmt->stmts, ";\n");
236 printf("\n}\n\n");
237 break;
238 case STMT_EXPRESSION:
239 printf("\t");
240 show_expression(stmt->expression);
241 return;
242 case STMT_IF:
243 printf("\tif (");
244 show_expression(stmt->if_conditional);
245 printf(")\n");
246 show_statement(stmt->if_true);
247 if (stmt->if_false) {
248 printf("\nelse\n");
249 show_statement(stmt->if_false);
251 break;
252 case STMT_SWITCH:
253 printf("\tswitch (");
254 show_expression(stmt->switch_expression);
255 printf(")\n");
256 show_statement(stmt->switch_statement);
257 break;
259 case STMT_CASE:
260 if (!stmt->case_expression)
261 printf("default");
262 else {
263 printf("case ");
264 show_expression(stmt->case_expression);
265 if (stmt->case_to) {
266 printf(" ... ");
267 show_expression(stmt->case_to);
270 printf(":");
271 show_statement(stmt->case_statement);
272 break;
274 case STMT_BREAK:
275 printf("\tbreak");
276 break;
278 case STMT_ITERATOR: {
279 struct statement *pre_statement = stmt->iterator_pre_statement;
280 struct expression *pre_condition = stmt->iterator_pre_condition;
281 struct statement *statement = stmt->iterator_statement;
282 struct statement *post_statement = stmt->iterator_post_statement;
283 struct expression *post_condition = stmt->iterator_post_condition;
286 * THIS IS ONLY APPROXIMATE!
288 * Real iterators are more generic than
289 * any of for/while/do-while, and can't
290 * be printed out as C without goto's
292 if (post_statement || !post_condition) {
293 printf("\tfor ( ");
294 show_statement(pre_statement);
295 printf(" ; ");
296 show_expression(pre_condition);
297 printf(" ; ");
298 show_statement(post_statement);
299 printf(" )\n");
300 show_statement(statement);
301 } else if (pre_condition) {
302 if (pre_statement) {
303 show_statement(pre_statement);
304 printf(";\n");
306 printf("\twhile (");
307 show_expression(pre_condition);
308 printf(")\n");
309 show_statement(statement);
310 } else {
311 if (pre_statement) {
312 show_statement(pre_statement);
313 printf(";\n");
315 printf("\tdo\n");
316 show_statement(statement);
317 printf("\twhile (");
318 show_expression(post_condition);
319 printf(")");
321 break;
323 case STMT_NONE:
324 printf("\tNONE");
325 break;
327 case STMT_CONTINUE:
328 printf("\tcontinue");
329 break;
331 case STMT_LABEL:
332 printf("%s:\n", show_token(stmt->label_identifier));
333 show_statement(stmt->label_statement);
334 break;
336 case STMT_GOTO:
337 if (stmt->goto_expression) {
338 printf("\tgoto *");
339 show_expression(stmt->goto_expression);
340 } else
341 printf("goto %s", show_token(stmt->goto_label));
342 break;
343 case STMT_ASM:
344 printf("\tasm( .... )");
345 break;
350 static void show_one_statement(struct statement *stmt, void *sep, int flags)
352 show_statement(stmt);
353 if (!(flags & ITERATE_LAST))
354 printf("%s", (const char *)sep);
357 void show_statement_list(struct statement_list *stmt, const char *sep)
359 statement_iterate(stmt, show_one_statement, (void *)sep);
362 static void show_size(struct symbol *sym)
364 if (sym)
365 printf("%d:%d", sym->bit_size, sym->alignment);
368 static void show_one_expression(struct expression *expr, void *sep, int flags)
370 show_expression(expr);
371 if (!(flags & ITERATE_LAST))
372 printf("%s", (const char *)sep);
375 void show_expression_list(struct expression_list *list, const char *sep)
377 expression_iterate(list, show_one_expression, (void *)sep);
381 * Print out an expression
383 void show_expression(struct expression *expr)
385 if (!expr)
386 return;
388 printf("< (");
389 show_size(expr->ctype);
390 show_type(expr->ctype);
391 printf(") ");
392 switch (expr->type) {
393 case EXPR_CALL:
394 show_expression(expr->fn);
395 printf("( ");
396 show_expression_list(expr->args, ", ");
397 printf(" )");
398 break;
400 case EXPR_ASSIGNMENT:
401 show_expression(expr->left);
402 printf(" %s ", show_special(expr->op));
403 show_expression(expr->right);
404 break;
405 case EXPR_BINOP:
406 case EXPR_COMMA:
407 case EXPR_COMPARE:
408 show_expression(expr->left);
409 printf(" %s ", show_special(expr->op));
410 show_expression(expr->right);
411 break;
412 case EXPR_PREOP:
413 printf("%s<", show_special(expr->op));
414 show_expression(expr->unop);
415 printf(">");
416 break;
417 case EXPR_POSTOP:
418 show_expression(expr->unop);
419 printf(" %s ", show_special(expr->op));
420 break;
421 case EXPR_CONSTANT:
422 printf("%s", show_token(expr->token));
423 break;
424 case EXPR_SYMBOL:
425 if (!expr->symbol) {
426 warn(expr->pos, "undefined symbol '%s'", show_ident(expr->symbol_name));
427 printf("<nosymbol>");
428 break;
430 printf("<%s:", show_ident(expr->symbol_name));
431 show_type(expr->symbol->ctype.base_type);
432 printf(">");
433 break;
434 case EXPR_DEREF:
435 show_expression(expr->deref);
436 printf("%s", show_special(expr->op));
437 printf("%s", show_ident(expr->member));
438 break;
439 case EXPR_CAST:
440 printf("<cast>(");
441 show_type(expr->cast_type);
442 printf(")");
443 show_expression(expr->cast_expression);
444 break;
445 case EXPR_VALUE:
446 printf("(%lld)", expr->value);
447 break;
448 case EXPR_STRING:
449 printf("%s", show_string(expr->string));
450 break;
451 case EXPR_SIZEOF:
452 printf("sizeof(");
453 if (expr->cast_type)
454 show_type(expr->cast_type);
455 else
456 show_expression(expr->cast_expression);
457 printf(")");
458 break;
459 case EXPR_BITFIELD:
460 printf("bits[%d-%d](", expr->bitpos, expr->bitpos + expr->nrbits - 1);
461 show_expression(expr->address);
462 printf(")");
463 break;
464 default:
465 printf("WTF");
467 printf(" >");