Evaluate and show return statement with proper type promotion.
[smatch.git] / show-parse.c
bloba7c9a6a370bb6bd27822425b0b7badcf632fca63
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"
22 #include "target.h"
25 * Symbol type printout. The type system is by far the most
26 * complicated part of C - everything else is trivial.
28 const char *modifier_string(unsigned long mod)
30 static char buffer[100];
31 char *p = buffer;
32 const char *res,**ptr, *names[] = {
33 "auto", "register", "static", "extern",
34 "const", "volatile", "[signed]", "[unsigned]",
35 "[char]", "[short]", "[long]", "[long]",
36 "[typdef]", "[structof]", "[unionof]", "[enum]",
37 "[typeof]", "[attribute]", "inline", "[addressable]",
38 "[nocast]", "[noderef]",
39 NULL
41 ptr = names;
42 while ((res = *ptr++) != NULL) {
43 if (mod & 1) {
44 char c;
45 while ((c = *res++) != '\0')
46 *p++ = c;
47 *p++ = ' ';
49 mod >>= 1;
51 *p = 0;
52 return buffer;
55 void show_struct_member(struct symbol *sym, void *data, int flags)
57 if (flags & ITERATE_FIRST)
58 printf(" {\n\t");
59 printf("%s:%d:%ld at offset %ld", show_ident(sym->ident), sym->bit_size, sym->ctype.alignment, sym->offset);
60 if (sym->fieldwidth)
61 printf("[%d..%d]", sym->bit_offset, sym->bit_offset+sym->fieldwidth-1);
62 if (flags & ITERATE_LAST)
63 printf("\n} ");
64 else
65 printf(", ");
68 static void show_one_symbol(struct symbol *sym, void *sep, int flags)
70 show_symbol(sym);
71 if (!(flags & ITERATE_LAST))
72 printf("%s", (const char *)sep);
75 void show_symbol_list(struct symbol_list *list, const char *sep)
77 symbol_iterate(list, show_one_symbol, (void *)sep);
80 void show_type_list(struct symbol *sym)
82 while (sym) {
83 show_symbol(sym);
84 sym = sym->next;
88 struct type_name {
89 char *start;
90 char *end;
93 static void prepend(struct type_name *name, const char *fmt, ...)
95 static char buffer[512];
96 int n;
98 va_list args;
99 va_start(args, fmt);
100 n = vsprintf(buffer, fmt, args);
101 va_end(args);
103 name->start -= n;
104 memcpy(name->start, buffer, n);
107 static void append(struct type_name *name, const char *fmt, ...)
109 static char buffer[512];
110 int n;
112 va_list args;
113 va_start(args, fmt);
114 n = vsprintf(buffer, fmt, args);
115 va_end(args);
117 memcpy(name->end, buffer, n);
118 name->end += n;
121 static void do_show_type(struct symbol *sym, struct type_name *name)
123 int i, modlen;
124 const char *mod;
125 static struct ctype_name {
126 struct symbol *sym;
127 char *name;
128 } typenames[] = {
129 { & char_ctype, "char" },
130 { &uchar_ctype, "unsigned char" },
131 { & short_ctype, "short" },
132 { &ushort_ctype, "unsigned short" },
133 { & int_ctype, "int" },
134 { &uint_ctype, "unsigned int" },
135 { & long_ctype, "long" },
136 { &ulong_ctype, "unsigned long" },
137 { & llong_ctype, "long long" },
138 { &ullong_ctype, "unsigned long long" },
140 { &void_ctype, "void" },
141 { &bool_ctype, "bool" },
142 { &string_ctype, "string" },
144 { &float_ctype, "float" },
145 { &double_ctype, "double" },
146 { &ldouble_ctype,"long double" },
149 if (!sym)
150 return;
152 for (i = 0; i < sizeof(typenames)/sizeof(typenames[0]); i++) {
153 if (typenames[i].sym == sym) {
154 int len = strlen(typenames[i].name);
155 *--name->start = ' ';
156 name->start -= len;
157 memcpy(name->start, typenames[i].name, len);
158 return;
162 /* Prepend */
163 switch (sym->type) {
164 case SYM_PTR:
165 prepend(name, "*");
166 break;
167 case SYM_FN:
168 prepend(name, "( ");
169 break;
170 case SYM_STRUCT:
171 prepend(name, "struct %s ", show_ident(sym->ident));
172 return;
174 case SYM_UNION:
175 prepend(name, "union %s ", show_ident(sym->ident));
176 return;
178 case SYM_ENUM:
179 prepend(name, "enum %s ", show_ident(sym->ident));
180 return;
182 case SYM_NODE:
183 append(name, "%s", show_ident(sym->ident));
184 break;
186 case SYM_BITFIELD:
187 append(name, ":%d", sym->fieldwidth);
188 break;
190 case SYM_LABEL:
191 append(name, "label(%s:%p)", show_ident(sym->ident), sym);
192 break;
194 case SYM_ARRAY:
195 break;
197 default:
198 prepend(name, "unknown type %d", sym->type);
199 return;
202 mod = modifier_string(sym->ctype.modifiers);
203 modlen = strlen(mod);
204 name->start -= modlen;
205 memcpy(name->start, mod, modlen);
207 do_show_type(sym->ctype.base_type, name);
209 /* Postpend */
210 if (sym->ctype.as)
211 append(name, "<asn:%d>", sym->ctype.as);
213 switch (sym->type) {
214 case SYM_PTR:
215 return;
217 case SYM_FN:
218 append(name, " )( ... )");
219 return;
221 case SYM_ARRAY:
222 append(name, "[%d]", sym->array_size);
223 return;
224 default:
225 break;
229 void show_type(struct symbol *sym)
231 char array[200];
232 struct type_name name;
234 name.start = name.end = array+100;
235 do_show_type(sym, &name);
236 *name.end = 0;
237 printf("%s", name.start);
240 void show_symbol(struct symbol *sym)
242 struct symbol *type;
244 if (!sym)
245 return;
247 show_type(sym);
248 type = sym->ctype.base_type;
249 if (!type)
250 return;
253 * Show actual implementation information
255 switch (type->type) {
256 case SYM_STRUCT:
257 symbol_iterate(type->symbol_list, show_struct_member, NULL);
258 break;
260 case SYM_UNION:
261 symbol_iterate(type->symbol_list, show_struct_member, NULL);
262 break;
264 case SYM_FN:
265 printf("\n");
266 show_statement(type->stmt);
267 break;
269 default:
270 break;
273 if (sym->initializer) {
274 printf(" = ");
275 show_expression(sym->initializer);
279 static int show_return_stmt(struct statement *stmt)
281 struct expression *expr = stmt->expression;
283 if (expr) {
284 int val = show_expression(expr);
285 printf("\tmov.%d\t\tretval,v%d\n",
286 expr->ctype->bit_size, val);
288 printf("\tret\n");
289 return 0;
293 * Print out a statement
295 int show_statement(struct statement *stmt)
297 if (!stmt)
298 return 0;
299 switch (stmt->type) {
300 case STMT_RETURN:
301 return show_return_stmt(stmt);
302 case STMT_COMPOUND: {
303 struct statement *s;
304 int last;
306 if (stmt->syms) {
307 printf("\t");
308 show_symbol_list(stmt->syms, "\n\t");
309 printf("\n\n");
311 FOR_EACH_PTR(stmt->stmts, s) {
312 last = show_statement(s);
313 } END_FOR_EACH_PTR;
314 return last;
317 case STMT_EXPRESSION:
318 return show_expression(stmt->expression);
319 case STMT_IF:
320 printf("\tif (");
321 show_expression(stmt->if_conditional);
322 printf(")\n");
323 show_statement(stmt->if_true);
324 if (stmt->if_false) {
325 printf("\nelse\n");
326 show_statement(stmt->if_false);
328 break;
329 case STMT_SWITCH:
330 printf("\tswitch (");
331 show_expression(stmt->switch_expression);
332 printf(")\n");
333 show_statement(stmt->switch_statement);
334 break;
336 case STMT_CASE:
337 if (!stmt->case_expression)
338 printf("default");
339 else {
340 printf("case ");
341 show_expression(stmt->case_expression);
342 if (stmt->case_to) {
343 printf(" ... ");
344 show_expression(stmt->case_to);
347 printf(":");
348 show_statement(stmt->case_statement);
349 break;
351 case STMT_BREAK:
352 printf("\tbreak");
353 break;
355 case STMT_ITERATOR: {
356 struct statement *pre_statement = stmt->iterator_pre_statement;
357 struct expression *pre_condition = stmt->iterator_pre_condition;
358 struct statement *statement = stmt->iterator_statement;
359 struct statement *post_statement = stmt->iterator_post_statement;
360 struct expression *post_condition = stmt->iterator_post_condition;
363 * THIS IS ONLY APPROXIMATE!
365 * Real iterators are more generic than
366 * any of for/while/do-while, and can't
367 * be printed out as C without goto's
369 if (post_statement || !post_condition) {
370 printf("\tfor ( ");
371 show_statement(pre_statement);
372 printf(" ; ");
373 show_expression(pre_condition);
374 printf(" ; ");
375 show_statement(post_statement);
376 printf(" )\n");
377 show_statement(statement);
378 } else if (pre_condition) {
379 if (pre_statement) {
380 show_statement(pre_statement);
381 printf(";\n");
383 printf("\twhile (");
384 show_expression(pre_condition);
385 printf(")\n");
386 show_statement(statement);
387 } else {
388 if (pre_statement) {
389 show_statement(pre_statement);
390 printf(";\n");
392 printf("\tdo\n");
393 show_statement(statement);
394 printf("\twhile (");
395 show_expression(post_condition);
396 printf(")");
398 break;
400 case STMT_NONE:
401 printf("\tNONE");
402 break;
404 case STMT_CONTINUE:
405 printf("\tcontinue");
406 break;
408 case STMT_LABEL:
409 show_symbol(stmt->label_identifier);
410 printf(":\n");
411 show_statement(stmt->label_statement);
412 break;
414 case STMT_GOTO:
415 if (stmt->goto_expression) {
416 printf("\tgoto *");
417 show_expression(stmt->goto_expression);
418 } else {
419 printf("\tgoto ");
420 show_symbol(stmt->goto_label);
422 break;
423 case STMT_ASM:
424 printf("\tasm( .... )");
425 break;
428 return 0;
431 static void show_one_statement(struct statement *stmt, void *sep, int flags)
433 show_statement(stmt);
434 if (!(flags & ITERATE_LAST))
435 printf("%s", (const char *)sep);
438 void show_statement_list(struct statement_list *stmt, const char *sep)
440 statement_iterate(stmt, show_one_statement, (void *)sep);
443 static void show_one_expression(struct expression *expr, void *sep, int flags)
445 show_expression(expr);
446 if (!(flags & ITERATE_LAST))
447 printf("%s", (const char *)sep);
450 void show_expression_list(struct expression_list *list, const char *sep)
452 expression_iterate(list, show_one_expression, (void *)sep);
455 static int new_pseudo(void)
457 static int nr = 0;
458 return ++nr;
461 static int show_call_expression(struct expression *expr)
463 struct expression *arg, *fn;
464 int fncall, retval;
465 int framesize;
467 framesize = 0;
468 FOR_EACH_PTR_REVERSE(expr->args, arg) {
469 int new = show_expression(arg);
470 int size = arg->ctype->bit_size;
471 printf("\tpush.%d\t\tv%d\n", size, new);
472 framesize += size >> 3;
473 } END_FOR_EACH_PTR;
475 fn = expr->fn;
476 /* Remove dereference, if any */
477 if (fn->type == EXPR_PREOP)
478 fn = fn->unop;
479 fncall = show_expression(fn);
480 retval = new_pseudo();
482 printf("\tcall\t\t*v%d\n", fncall);
483 if (framesize)
484 printf("\tadd.%d\t\tvSP,vSP,$%d\n", BITS_IN_POINTER, framesize);
485 printf("\tmov.%d\t\tv%d,retval\n", expr->ctype->bit_size, retval);
486 return retval;
489 static int show_binop(struct expression *expr)
491 int left = show_expression(expr->left);
492 int right = show_expression(expr->right);
493 int new = new_pseudo();
494 const char *opname;
495 static const char *name[] = {
496 ['+'] = "add", ['-'] = "sub",
497 ['*'] = "mul", ['/'] = "div",
498 ['%'] = "mod"
500 unsigned int op = expr->op;
502 opname = show_special(op);
503 if (op < sizeof(name)/sizeof(*name))
504 opname = name[op];
505 printf("\t%s.%d\t\tv%d,v%d,v%d\n", opname,
506 expr->ctype->bit_size,
507 new, left, right);
508 return new;
511 static int show_regular_preop(struct expression *expr)
513 int target = show_expression(expr->unop);
514 int new = new_pseudo();
515 static const char *name[] = {
516 ['!'] = "nonzero", ['-'] = "neg",
517 ['~'] = "not",
519 unsigned int op = expr->op;
520 const char *opname;
522 opname = show_special(op);
523 if (op < sizeof(name)/sizeof(*name))
524 opname = name[op];
525 printf("\t%s.%d\t\tv%d,v%d\n", opname, expr->ctype->bit_size, new, target);
526 return new;
530 * FIXME! Not all accesses are memory loads. We should
531 * check what kind of symbol is behind the dereference.
533 static int show_address_gen(struct expression *expr)
535 if (expr->type == EXPR_PREOP)
536 return show_expression(expr->unop);
537 return show_expression(expr->address);
540 static int show_load_gen(int bits, struct expression *expr, int addr)
542 int new = new_pseudo();
544 printf("\tld.%d\t\tv%d,[v%d]\n", bits, new, addr);
545 if (expr->type == EXPR_PREOP)
546 return new;
548 /* bitfield load! */
549 if (expr->bitpos)
550 printf("\tshr.%d\t\tv%d,v%d,$%d\n", bits, new, new, expr->bitpos);
551 printf("\tandi.%d\t\tv%d,v%d,$%llu\n", bits, new, new, (1ULL << expr->nrbits)-1);
552 return new;
555 static void show_store_gen(int bits, int value, struct expression *expr, int addr)
557 /* FIXME!!! Bitfield store! */
558 printf("\tst.%d\t\tv%d,[v%d]\n", bits, value, addr);
561 static int show_assignment(struct expression *expr)
563 struct expression *target = expr->left;
564 int val, addr, bits = expr->ctype->bit_size;
566 val = show_expression(expr->right);
567 addr = show_address_gen(target);
568 show_store_gen(bits, val, target, addr);
569 return val;
572 static int show_access(struct expression *expr)
574 int addr = show_address_gen(expr);
575 return show_load_gen(expr->ctype->bit_size, expr, addr);
578 static int show_inc_dec(struct expression *expr, int postop)
580 int addr = show_address_gen(expr->unop);
581 int retval, new;
582 const char *opname = expr->op == SPECIAL_INCREMENT ? "add" : "sub";
583 int bits = expr->ctype->bit_size;
585 retval = show_load_gen(bits, expr->unop, addr);
586 new = retval;
587 if (postop)
588 new = new_pseudo();
589 printf("\t%s.%d\t\tv%d,v%d,$1\n", opname, bits, new, retval);
590 show_store_gen(bits, new, expr->unop, addr);
591 return retval;
594 static int show_preop(struct expression *expr)
597 * '*' is an lvalue access, and is fundamentally different
598 * from an arithmetic operation. Maybe it should have an
599 * expression type of its own..
601 if (expr->op == '*')
602 return show_access(expr);
603 if (expr->op == SPECIAL_INCREMENT || expr->op == SPECIAL_DECREMENT)
604 return show_inc_dec(expr, 0);
605 return show_regular_preop(expr);
608 static int show_postop(struct expression *expr)
610 return show_inc_dec(expr, 1);
613 static int show_symbol_expr(struct expression *expr)
615 int new = new_pseudo();
616 printf("\tmovi.%d\t\tv%d,$%s\n", BITS_IN_POINTER, new, show_ident(expr->symbol_name));
617 return new;
620 static int type_is_signed(struct symbol *sym)
622 if (sym->type == SYM_NODE)
623 sym = sym->ctype.base_type;
624 if (sym->type == SYM_PTR)
625 return 0;
626 return !(sym->ctype.modifiers & MOD_UNSIGNED);
629 static int show_cast_expr(struct expression *expr)
631 struct symbol *old_type, *new_type;
632 int op = show_expression(expr->cast_expression);
633 int oldbits, newbits;
634 int new, is_signed;
636 old_type = expr->cast_expression->ctype;
637 new_type = expr->cast_type;
639 oldbits = old_type->bit_size;
640 newbits = new_type->bit_size;
641 if (oldbits >= newbits)
642 return op;
643 new = new_pseudo();
644 is_signed = type_is_signed(old_type);
645 if (is_signed) {
646 printf("\tsext%d.%d\tv%d,v%d\n", oldbits, newbits, new, op);
647 } else {
648 printf("\tandl.%d\t\tv%d,v%d,$%lu\n", newbits, new, op, (1UL << oldbits)-1);
650 return new;
653 static int show_value(struct expression *expr)
655 int new = new_pseudo();
656 unsigned long long value = expr->value;
658 printf("\tmovi.%d\t\tv%d,$%llu\n", expr->ctype->bit_size, new, value);
659 return new;
662 static int show_string_expr(struct expression *expr)
664 int new = new_pseudo();
666 printf("\tmovi.%d\t\tv%d,&%s\n", BITS_IN_POINTER, new, show_string(expr->string));
667 return new;
670 static int show_bitfield_expr(struct expression *expr)
672 return show_access(expr);
675 static int show_conditional_expr(struct expression *expr)
677 int cond = show_expression(expr->conditional);
678 int true = show_expression(expr->cond_true);
679 int false = show_expression(expr->cond_false);
680 int new = new_pseudo();
682 if (!true)
683 true = cond;
684 printf("[v%d]\tcmov.%d\t\tv%d,v%d,v%d\n", cond, expr->ctype->bit_size, new, true, false);
685 return new;
688 static int show_statement_expr(struct expression *expr)
690 return show_statement(expr->statement);
694 * Print out an expression. Return the pseudo that contains the
695 * variable.
697 int show_expression(struct expression *expr)
699 if (!expr)
700 return 0;
702 switch (expr->type) {
703 case EXPR_CALL:
704 return show_call_expression(expr);
706 case EXPR_ASSIGNMENT:
707 return show_assignment(expr);
709 case EXPR_BINOP:
710 case EXPR_COMMA:
711 case EXPR_COMPARE:
712 case EXPR_LOGICAL:
713 return show_binop(expr);
714 case EXPR_PREOP:
715 return show_preop(expr);
716 case EXPR_POSTOP:
717 return show_postop(expr);
718 case EXPR_SYMBOL:
719 return show_symbol_expr(expr);
720 case EXPR_DEREF:
721 case EXPR_SIZEOF:
722 warn(expr->pos, "invalid expression after evaluation");
723 return 0;
724 case EXPR_CAST:
725 return show_cast_expr(expr);
726 case EXPR_VALUE:
727 return show_value(expr);
728 case EXPR_STRING:
729 return show_string_expr(expr);
730 case EXPR_BITFIELD:
731 return show_bitfield_expr(expr);
732 case EXPR_INITIALIZER:
733 warn(expr->pos, "unable to show initializer expression");
734 return 0;
735 case EXPR_IDENTIFIER:
736 warn(expr->pos, "unable to show identifier expression");
737 return 0;
738 case EXPR_INDEX:
739 warn(expr->pos, "unable to show index expression");
740 return 0;
741 case EXPR_CONDITIONAL:
742 return show_conditional_expr(expr);
743 case EXPR_STATEMENT:
744 return show_statement_expr(expr);
746 return 0;