Evaluating a symbol turns into a dereference of the address
[smatch.git] / show-parse.c
blobc0da6d2675fe3bdee086807440e47aec9e4ae8b5
1 /*
2 * sparse/show-parse.c
4 * Copyright (C) 2003 Transmeta Corp, 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]", "inline", "[addressable]",
37 "[nocast]", "[noderef]",
38 NULL
40 ptr = names;
41 while ((res = *ptr++) != NULL) {
42 if (mod & 1) {
43 char c;
44 while ((c = *res++) != '\0')
45 *p++ = c;
46 *p++ = ' ';
48 mod >>= 1;
50 *p = 0;
51 return buffer;
54 void show_struct_member(struct symbol *sym, void *data, int flags)
56 if (flags & ITERATE_FIRST)
57 printf(" {\n\t");
58 printf("%s:%d:%ld at offset %ld", show_ident(sym->ident), sym->bit_size, sym->ctype.alignment, sym->offset);
59 if (sym->fieldwidth)
60 printf("[%d..%d]", sym->bit_offset, sym->bit_offset+sym->fieldwidth-1);
61 if (flags & ITERATE_LAST)
62 printf("\n} ");
63 else
64 printf(", ");
67 static void show_one_symbol(struct symbol *sym, void *sep, int flags)
69 show_symbol(sym);
70 if (!(flags & ITERATE_LAST))
71 printf("%s", (const char *)sep);
74 void show_symbol_list(struct symbol_list *list, const char *sep)
76 symbol_iterate(list, show_one_symbol, (void *)sep);
79 void show_type_list(struct symbol *sym)
81 while (sym) {
82 show_symbol(sym);
83 sym = sym->next;
87 struct type_name {
88 char *start;
89 char *end;
92 static void prepend(struct type_name *name, const char *fmt, ...)
94 static char buffer[512];
95 int n;
97 va_list args;
98 va_start(args, fmt);
99 n = vsprintf(buffer, fmt, args);
100 va_end(args);
102 name->start -= n;
103 memcpy(name->start, buffer, n);
106 static void append(struct type_name *name, const char *fmt, ...)
108 static char buffer[512];
109 int n;
111 va_list args;
112 va_start(args, fmt);
113 n = vsprintf(buffer, fmt, args);
114 va_end(args);
116 memcpy(name->end, buffer, n);
117 name->end += n;
120 static void do_show_type(struct symbol *sym, struct type_name *name)
122 int i, modlen;
123 const char *mod;
124 static struct ctype_name {
125 struct symbol *sym;
126 char *name;
127 } typenames[] = {
128 { & char_ctype, "char" },
129 { &uchar_ctype, "unsigned char" },
130 { & short_ctype, "short" },
131 { &ushort_ctype, "unsigned short" },
132 { & int_ctype, "int" },
133 { &uint_ctype, "unsigned int" },
134 { & long_ctype, "long" },
135 { &ulong_ctype, "unsigned long" },
136 { & llong_ctype, "long long" },
137 { &ullong_ctype, "unsigned long long" },
139 { &void_ctype, "void" },
140 { &bool_ctype, "bool" },
141 { &string_ctype, "string" },
143 { &float_ctype, "float" },
144 { &double_ctype, "double" },
145 { &ldouble_ctype,"long double" },
148 if (!sym)
149 return;
151 for (i = 0; i < sizeof(typenames)/sizeof(typenames[0]); i++) {
152 if (typenames[i].sym == sym) {
153 int len = strlen(typenames[i].name);
154 *--name->start = ' ';
155 name->start -= len;
156 memcpy(name->start, typenames[i].name, len);
157 return;
161 /* Prepend */
162 switch (sym->type) {
163 case SYM_PTR:
164 prepend(name, "*");
165 break;
166 case SYM_FN:
167 prepend(name, "( ");
168 break;
169 case SYM_STRUCT:
170 prepend(name, "struct %s ", show_ident(sym->ident));
171 return;
173 case SYM_UNION:
174 prepend(name, "union %s ", show_ident(sym->ident));
175 return;
177 case SYM_ENUM:
178 prepend(name, "enum %s ", show_ident(sym->ident));
179 return;
181 case SYM_NODE:
182 append(name, "%s", show_ident(sym->ident));
183 break;
185 case SYM_BITFIELD:
186 append(name, ":%d", sym->fieldwidth);
187 break;
189 case SYM_LABEL:
190 append(name, "label(%s:%p)", show_ident(sym->ident), sym);
191 break;
193 case SYM_ARRAY:
194 break;
196 default:
197 prepend(name, "unknown type %d", sym->type);
198 return;
201 mod = modifier_string(sym->ctype.modifiers);
202 modlen = strlen(mod);
203 name->start -= modlen;
204 memcpy(name->start, mod, modlen);
206 do_show_type(sym->ctype.base_type, name);
208 /* Postpend */
209 if (sym->ctype.as)
210 append(name, "<asn:%d>", sym->ctype.as);
212 switch (sym->type) {
213 case SYM_PTR:
214 return;
216 case SYM_FN:
217 append(name, " )( ... )");
218 return;
220 case SYM_ARRAY:
221 append(name, "[%d]", sym->array_size);
222 return;
223 default:
224 break;
228 void show_type(struct symbol *sym)
230 char array[200];
231 struct type_name name;
233 name.start = name.end = array+100;
234 do_show_type(sym, &name);
235 *name.end = 0;
236 printf("%s", name.start);
239 void show_symbol(struct symbol *sym)
241 struct symbol *type;
243 show_type(sym);
244 type = sym->ctype.base_type;
245 if (!type)
246 return;
249 * Show actual implementation information
251 switch (type->type) {
252 case SYM_STRUCT:
253 symbol_iterate(type->symbol_list, show_struct_member, NULL);
254 break;
256 case SYM_UNION:
257 symbol_iterate(type->symbol_list, show_struct_member, NULL);
258 break;
260 case SYM_FN:
261 printf("\n");
262 show_statement(type->stmt);
263 break;
265 default:
266 break;
269 if (sym->initializer) {
270 printf(" = ");
271 show_expression(sym->initializer);
276 * Print out a statement
278 void show_statement(struct statement *stmt)
280 if (!stmt)
281 return;
282 switch (stmt->type) {
283 case STMT_RETURN:
284 printf("\treturn ");
285 show_expression(stmt->expression);
286 break;
287 case STMT_COMPOUND:
288 printf("{\n");
289 if (stmt->syms) {
290 printf("\t");
291 show_symbol_list(stmt->syms, "\n\t");
292 printf("\n\n");
294 show_statement_list(stmt->stmts, ";\n");
295 printf("\n}\n\n");
296 break;
297 case STMT_EXPRESSION:
298 printf("\t");
299 show_expression(stmt->expression);
300 return;
301 case STMT_IF:
302 printf("\tif (");
303 show_expression(stmt->if_conditional);
304 printf(")\n");
305 show_statement(stmt->if_true);
306 if (stmt->if_false) {
307 printf("\nelse\n");
308 show_statement(stmt->if_false);
310 break;
311 case STMT_SWITCH:
312 printf("\tswitch (");
313 show_expression(stmt->switch_expression);
314 printf(")\n");
315 show_statement(stmt->switch_statement);
316 break;
318 case STMT_CASE:
319 if (!stmt->case_expression)
320 printf("default");
321 else {
322 printf("case ");
323 show_expression(stmt->case_expression);
324 if (stmt->case_to) {
325 printf(" ... ");
326 show_expression(stmt->case_to);
329 printf(":");
330 show_statement(stmt->case_statement);
331 break;
333 case STMT_BREAK:
334 printf("\tbreak");
335 break;
337 case STMT_ITERATOR: {
338 struct statement *pre_statement = stmt->iterator_pre_statement;
339 struct expression *pre_condition = stmt->iterator_pre_condition;
340 struct statement *statement = stmt->iterator_statement;
341 struct statement *post_statement = stmt->iterator_post_statement;
342 struct expression *post_condition = stmt->iterator_post_condition;
345 * THIS IS ONLY APPROXIMATE!
347 * Real iterators are more generic than
348 * any of for/while/do-while, and can't
349 * be printed out as C without goto's
351 if (post_statement || !post_condition) {
352 printf("\tfor ( ");
353 show_statement(pre_statement);
354 printf(" ; ");
355 show_expression(pre_condition);
356 printf(" ; ");
357 show_statement(post_statement);
358 printf(" )\n");
359 show_statement(statement);
360 } else if (pre_condition) {
361 if (pre_statement) {
362 show_statement(pre_statement);
363 printf(";\n");
365 printf("\twhile (");
366 show_expression(pre_condition);
367 printf(")\n");
368 show_statement(statement);
369 } else {
370 if (pre_statement) {
371 show_statement(pre_statement);
372 printf(";\n");
374 printf("\tdo\n");
375 show_statement(statement);
376 printf("\twhile (");
377 show_expression(post_condition);
378 printf(")");
380 break;
382 case STMT_NONE:
383 printf("\tNONE");
384 break;
386 case STMT_CONTINUE:
387 printf("\tcontinue");
388 break;
390 case STMT_LABEL:
391 show_symbol(stmt->label_identifier);
392 printf(":\n");
393 show_statement(stmt->label_statement);
394 break;
396 case STMT_GOTO:
397 if (stmt->goto_expression) {
398 printf("\tgoto *");
399 show_expression(stmt->goto_expression);
400 } else {
401 printf("\tgoto ");
402 show_symbol(stmt->goto_label);
404 break;
405 case STMT_ASM:
406 printf("\tasm( .... )");
407 break;
412 static void show_one_statement(struct statement *stmt, void *sep, int flags)
414 show_statement(stmt);
415 if (!(flags & ITERATE_LAST))
416 printf("%s", (const char *)sep);
419 void show_statement_list(struct statement_list *stmt, const char *sep)
421 statement_iterate(stmt, show_one_statement, (void *)sep);
424 static void show_size(struct symbol *sym)
426 if (sym)
427 printf("%d:%ld", sym->bit_size, sym->ctype.alignment);
430 static void show_one_expression(struct expression *expr, void *sep, int flags)
432 show_expression(expr);
433 if (!(flags & ITERATE_LAST))
434 printf("%s", (const char *)sep);
437 void show_expression_list(struct expression_list *list, const char *sep)
439 expression_iterate(list, show_one_expression, (void *)sep);
443 * Print out an expression
445 void show_expression(struct expression *expr)
447 if (!expr)
448 return;
450 printf("< (");
451 show_size(expr->ctype);
452 show_type(expr->ctype);
453 printf(") ");
454 switch (expr->type) {
455 case EXPR_CALL:
456 show_expression(expr->fn);
457 printf("( ");
458 show_expression_list(expr->args, ", ");
459 printf(" )");
460 break;
462 case EXPR_ASSIGNMENT:
463 show_expression(expr->left);
464 printf(" %s ", show_special(expr->op));
465 show_expression(expr->right);
466 break;
467 case EXPR_BINOP:
468 case EXPR_COMMA:
469 case EXPR_COMPARE:
470 show_expression(expr->left);
471 printf(" %s ", show_special(expr->op));
472 show_expression(expr->right);
473 break;
474 case EXPR_PREOP:
475 printf("%s<", show_special(expr->op));
476 show_expression(expr->unop);
477 printf(">");
478 break;
479 case EXPR_POSTOP:
480 show_expression(expr->unop);
481 printf(" %s ", show_special(expr->op));
482 break;
483 case EXPR_SYMBOL:
484 show_type(expr->symbol);
485 break;
486 case EXPR_DEREF:
487 show_expression(expr->deref);
488 printf("%s", show_special(expr->op));
489 printf("%s", show_ident(expr->member));
490 break;
491 case EXPR_CAST:
492 printf("<cast>(");
493 show_type(expr->cast_type);
494 printf(")");
495 show_expression(expr->cast_expression);
496 break;
497 case EXPR_VALUE:
498 printf("(%lld)", expr->value);
499 break;
500 case EXPR_STRING:
501 printf("%s", show_string(expr->string));
502 break;
503 case EXPR_SIZEOF:
504 printf("sizeof(");
505 if (expr->cast_type)
506 show_type(expr->cast_type);
507 else
508 show_expression(expr->cast_expression);
509 printf(")");
510 break;
511 case EXPR_BITFIELD:
512 printf("bits[%d-%d](", expr->bitpos, expr->bitpos + expr->nrbits - 1);
513 show_expression(expr->address);
514 printf(")");
515 break;
516 case EXPR_INITIALIZER:
517 printf(" {\n\t");
518 show_expression_list(expr->expr_list, ", ");
519 printf("\n} ");
520 break;
521 case EXPR_IDENTIFIER:
522 printf("%s: ", show_ident(expr->expr_ident));
523 break;
524 case EXPR_INDEX:
525 if (expr->idx_from == expr->idx_to) {
526 printf("[%d]: ", expr->idx_from);
527 } else {
528 printf("[%d ... %d]: ", expr->idx_from, expr->idx_to);
530 break;
531 case EXPR_CONDITIONAL:
532 show_expression(expr->conditional);
533 printf(" ? ");
534 show_expression(expr->cond_true);
535 printf(" : ");
536 show_expression(expr->cond_false);
537 break;
538 case EXPR_STATEMENT:
539 printf("({\n\t");
540 show_statement(expr->statement);
541 printf("\n})");
542 break;
544 printf(" >");