17 static int dump_string(dump_state *dump,
22 dump_state *dump_new(FILE *fp) {
23 dump_state *dump = xmalloc(sizeof *dump);
29 void dump_locations(struct dump_state *dump, int flag) {
30 dump->locations = flag;
33 static int location(dump_state *dump, const struct location *l, int ind) {
34 int change_path = 0, change_line = 0;
37 || strcmp(dump->path, l->path))
39 else if(dump->line != l->line)
41 else if(dump->y > MARGIN)
45 if(change_line && l->line > dump->line && l->line - dump->line < 5) {
46 while(dump->line < l->line) {
47 if(fputc('\n', dump->fp) < 0) return -1;
52 if(fputc('\n', dump->fp) < 0) return -1;
54 if(fprintf(dump->fp, "# %d", l->line) < 0) return -1;
56 if(fputc(' ', dump->fp) < 0) return -1;
57 if(dump_string(dump, l->path, 0, '"')) return -1;
59 if(fputc('\n', dump->fp) < 0) return -1;
65 if(fprintf(dump->fp, "%*s", ind, "") < 0) return -1;
70 static int word(dump_state *dump, const char *w) {
71 int force_space_before = 1;
81 force_space_before = 0;
84 if(force_space_before) {
85 if(fputc(' ', dump->fp) < 0) return -1;
88 if(fputs(w, dump->fp) < 0) return -1;
94 static int punc(dump_state *dump, int c) {
96 int force_space_before = 1;
103 force_space_before = (dump->last == '-');
107 force_space_before = (dump->last == '+');
111 force_space_before = (dump->last == '-');
172 if(dump->last == ',') break;
179 force_space_before = 0;
182 if(force_space_before && dump->last && dump->last != ' ') {
183 if(fputc(' ', dump->fp) < 0) return -1;
187 if(fputs(s, dump->fp) < 0) return -1;
188 dump->y += strlen(s);
190 if(fputc(c, dump->fp) < 0) return -1;
212 unsigned mask, value;
216 static const struct masktable type_specifier_table[] = {
217 { TS__BASIC, TS_VOID, "void" },
218 { TS__BASIC, TS_CHAR, "char" },
219 { TS__BASIC, TS_INT, "int" },
220 { TS__BASIC, TS_FLOAT, "float" },
221 { TS__BASIC, TS_DOUBLE, "double" },
222 { TS__BASIC, TS_BOOL, "_Bool" },
223 { TS__BASIC, TS_STRUCT, "struct" },
224 { TS__BASIC, TS_UNION, "union" },
225 { TS__BASIC, TS_ENUM, "enum" },
226 { TS__BASIC, TS_GCC_VA_LIST, "__builtin_va_list" },
228 { TS__CI, TS_COMPLEX, "_Complex" },
229 { TS__CI, TS_IMAGINARY, "_Imaginary" },
231 { TS__LENGTH, TS_SHORT, "short" },
232 { TS__LENGTH, TS_LONG, "long" },
233 { TS__LENGTH, TS_LONGLONG , "long long" },
235 { TS__SIGN, TS_SIGNED, "signed" },
236 { TS__SIGN, TS_UNSIGNED, "unsigned" },
241 static const struct table storage_class_specifier_table[] = {
242 { SCS_TYPEDEF, "typedef" },
243 { SCS_EXTERN, "extern" },
244 { SCS_STATIC, "static" },
245 { SCS_AUTO, "auto" },
246 { SCS_REGISTER, "register" },
250 static const struct table type_qualifier_table[] = {
251 { TQ_CONST, "const" },
252 { TQ_VOLATILE, "volatile" },
253 { TQ_RESTRICT, RESTRICT_KW },
257 static const struct table function_specifier_table[] = {
258 { FS_INLINE, "inline" },
262 static int dump_on_bit(dump_state *dump,
264 const struct table *t) {
266 for(n = 0; t[n].bit; ++n)
268 if(word(dump, t[n].kw)) return -1;
272 int dump_declaration_specifiers(dump_state *dump,
273 const struct declaration_specifiers *ds,
275 struct declaration *d;
276 struct enumerator *e;
280 if(dump_on_bit(dump, ds->storage_class_specifiers,
281 storage_class_specifier_table)) return -1;
282 if(dump_on_bit(dump, ds->function_specifiers, function_specifier_table))
284 if(dump_on_bit(dump, ds->type_qualifiers, type_qualifier_table)) return -1;
285 for(n = 0; type_specifier_table[n].mask; ++n)
286 if((ds->type_specifiers & type_specifier_table[n].mask)
287 == type_specifier_table[n].value)
288 if(word(dump, type_specifier_table[n].kw)) return -1;
290 if(word(dump, ds->name)) return -1;
291 if(ds->type_specifiers & TS_DEFINITION) {
292 if(punc(dump, '{')) return -1;
293 switch(ds->type_specifiers & TS__BASIC) {
296 for(d = ds->structure; d; d = d->next)
297 if(dump_declaration(dump, d, ind + INDENT)) return -1;
302 if(location(dump, &ds->enumerators->where, ind + INDENT)) return -1;
303 for(e = ds->enumerators; e; e = e->next) {
304 if(word(dump, e->name)) return -1;
306 if(punc(dump, '=')) return -1;
307 if(dump_expression(dump, e->value, ind + 2 * INDENT)) return -1;
310 if(punc(dump, ',')) return -1;
311 if(location(dump, &e->next->where, ind + INDENT)) return -1;
316 if(punc(dump, '}')) return -1;
321 static int dump_pointer_declarator(dump_state *dump,
322 const struct declarator *d,
323 const struct declarator_type *t,
325 if(t && t->type == dt_pointer) {
326 if(dump_pointer_declarator(dump, d, t->next, ind)) return -1;
327 if(punc(dump, '*')) return -1;
328 if(dump_on_bit(dump, t->type_qualifiers, type_qualifier_table))
334 static int dump_identifier_list(dump_state *dump,
335 const struct identifier_list *i) {
337 if(word(dump, i->id)) return -1;
339 if(punc(dump, ',')) return -1;
345 static int dump_declaration_raw(dump_state *dump,
346 const struct declaration *d,
348 struct declarator *dc;
350 if(dump_declaration_specifiers(dump, d->declaration_specifiers, ind))
352 for(dc = d->declarator_list; dc; dc = dc->next) {
353 /*if((dc->name || dc->type) && space(dump)) return -1;*/
354 if(dump_declarator(dump, dc, ind + INDENT))
357 if(punc(dump, ',')) return -1;
362 static int dump_parameter_list(dump_state *dump,
363 const struct declaration *p,
365 if(location(dump, &p->where, ind)) return -1;
367 if(dump_declaration_raw(dump, p, ind)) return -1;
369 if(punc(dump, ',')) return -1;
370 if(location(dump, &p->next->where, ind + INDENT)) return -1;
377 static int dump_declarator_type(dump_state *dump,
378 const struct declarator *d,
379 const struct declarator_type *t,
381 const struct declarator_type *u;
384 /* C declarator syntax really bites */
388 for(u = t; u && u->type == dt_pointer; u = u->next)
391 if(punc(dump, '(')) return -1;
392 if(dump_pointer_declarator(dump, d, t, ind + INDENT)) return -1;
393 if(dump_declarator_type(dump, d, 0, ind + INDENT)) return -1;
394 if(punc(dump, ')')) return -1;
395 if(dump_declarator_type(dump, 0, u, ind)) return -1;
397 if(dump_pointer_declarator(dump, d, t, ind)) return -1;
398 if(dump_declarator_type(dump, d, u, ind)) return -1;
402 if(dump_declarator_type(dump, d, t->next, ind)) return -1;
403 if(punc(dump, '[')) return -1;
404 if(dump_on_bit(dump, t->storage_class_specifiers,
405 storage_class_specifier_table)) return -1;
406 if(dump_on_bit(dump, t->type_qualifiers, type_qualifier_table))
408 if(t->u.array.flags & AF_STAR) {
409 if(punc(dump, '*')) return -1;
410 } else if(t->u.array.size)
411 if(dump_expression(dump, t->u.array.size, ind + INDENT)) return -1;
412 if(punc(dump, ']')) return -1;
414 case dt_old_function:
415 if(dump_declarator_type(dump, d, t->next, ind)) return -1;
416 if(punc(dump, '(')) return -1;
417 if(dump_identifier_list(dump, t->u.old_function.args))
419 if(punc(dump, ')')) return -1;
422 if(dump_declarator_type(dump, d, t->next, ind)) return -1;
423 if(punc(dump, '(')) return -1;
425 if(dump_parameter_list(dump, t->u.function.args, ind + INDENT)) return -1;
426 if(t->u.function.variadic) {
427 if(punc(dump, ',')) return -1;
428 if(punc(dump, VARARG)) return -1;
430 if(punc(dump, ')')) return -1;
434 if(d && d->name && word(dump, d->name)) return -1;
438 int dump_declarator(dump_state *dump,
439 const struct declarator *d,
441 if(location(dump, &d->where, ind)) return -1;
442 if(dump_declarator_type(dump, d, d->declarator_type, ind)) return -1;
444 if(punc(dump, ':')) return -1;
445 if(dump_expression(dump, d->bits, ind + INDENT)) return -1;
448 if(punc(dump, '=')) return -1;
449 if(dump_initializer(dump, d->initializer, ind + INDENT)) return -1;
454 int dump_declaration(dump_state *dump,
455 const struct declaration *d,
457 if(location(dump, &d->where, ind)) return -1;
458 if(dump_declaration_raw(dump, d, ind)) return -1;
459 if(punc(dump, ';')) return -1;
463 int dump_translation_unit(dump_state *dump,
464 const struct external_declaration *ed,
466 for(; ed; ed = ed->next)
469 if(dump_declaration(dump, ed->u.declaration, ind)) return -1;
471 case ed_function_definition:
472 if(dump_function_definition(dump, ed->u.function_definition, ind))
476 if(fputc('\n', dump->fp) < 0) return -1;
482 static int dump_string(dump_state *dump,
487 if(fputc(' ', dump->fp) < 0) return -1;
489 if(fputc(l, dump->fp) < 0) return -1;
490 if(fputc(q, dump->fp) < 0) return -1;
491 if(fputs(s, dump->fp) < 0) return -1;
492 if(fputc(q, dump->fp) < 0) return -1;
498 static int dump_expression_list(dump_state *dump,
499 const struct expression_list *l,
502 if(dump_expression(dump, l->e, ind)) return -1;
504 if(punc(dump, ',')) return -1;
510 static int dump_initializer_list(dump_state *dump,
511 const struct initializer *i,
515 if(punc(dump, '{')) return -1;
518 if(dump_initializer(dump, i, ind + INDENT)) return -1;
520 if(punc(dump, ',')) return -1;
523 return punc(dump, '}');
526 int dump_initializer(dump_state *dump,
527 const struct initializer *i,
529 struct designator *d;
532 for(d = i->designator; d; d = d->next) {
533 if(location(dump, &d->where, ind)) return -1;
536 if(punc(dump, '[')) return -1;
537 if(dump_expression(dump, d->u.expr, ind + INDENT)) return -1;
538 if(punc(dump, ']')) return -1;
541 if(i->syntax == des_c99 || d != i->designator)
542 if(punc(dump, '.')) return -1;
543 if(word(dump, d->u.name)) return -1;
549 if(punc(dump, '=')) return -1;
552 if(punc(dump, ':')) return -1;
559 case in_expr: return dump_expression(dump, i->u.expr, ind);
560 case in_list: return dump_initializer_list(dump, i->u.list, ind);
565 int dump_expression(dump_state *dump,
566 const struct expression *e,
570 if(location(dump, &e->where, ind)) return -1;
571 if(punc(dump, '(')) return -1;
572 if(dump_expression(dump, e->u.unary, ind + INDENT)) return -1;
573 if(punc(dump, ')')) return -1;
576 if(location(dump, &e->where, ind)) return -1;
577 if(punc(dump, e->operator)) return -1;
578 if(dump_expression(dump, e->u.unary, ind + INDENT)) return -1;
581 if(e->operator != '[') {
582 if(dump_expression(dump, e->u.binary.l, ind)) return -1;
583 if(location(dump, &e->where, ind)) return -1;
584 if(punc(dump, e->operator)) return -1;
585 if(dump_expression(dump, e->u.binary.r, ind + INDENT)) return -1;
587 if(dump_expression(dump, e->u.binary.l, ind)) return -1;
588 if(location(dump, &e->where, ind + INDENT)) return -1;
589 if(punc(dump, '[')) return -1;
590 if(dump_expression(dump, e->u.binary.r, ind + INDENT)) return -1;
591 if(punc(dump, ']')) return -1;
595 if(dump_expression(dump, e->u.unary, ind)) return -1;
596 if(location(dump, &e->where, ind)) return -1;
597 if(punc(dump, e->operator)) return -1;
600 if(location(dump, &e->where, ind)) return -1;
601 if(word(dump, e->u.name)) return -1;
604 if(location(dump, &e->where, ind)) return -1;
605 if(word(dump, e->u.constant)) return -1;
608 if(location(dump, &e->where, ind)) return -1;
609 if(dump_string(dump, e->u.constant, 0, '\''))
613 if(location(dump, &e->where, ind)) return -1;
614 if(dump_string(dump, e->u.constant, 0, '"'))
618 if(location(dump, &e->where, ind)) return -1;
619 if(dump_string(dump, e->u.constant, 'L', '\''))
623 if(location(dump, &e->where, ind)) return -1;
624 if(dump_string(dump, e->u.constant, 'L', '"'))
628 if(dump_expression(dump, e->u.fncall.fn, ind)) return -1;
629 if(location(dump, &e->where, ind)) return -1;
630 if(punc(dump, '(')) return -1;
631 if(dump_expression_list(dump, e->u.fncall.args, ind + INDENT))
633 if(punc(dump, ')')) return -1;
636 if(word(dump, "__builtin_va_arg")) return -1;
637 if(punc(dump, '(')) return -1;
638 if(dump_expression(dump, e->u.gcc_va_arg.arg, ind + INDENT))
640 if(punc(dump, ',')) return -1;
641 if(dump_declaration_raw(dump, e->u.gcc_va_arg.type, ind + INDENT))
643 if(punc(dump, ')')) return -1;
646 if(word(dump, "__builtin_expect")) return -1;
647 if(punc(dump, '(')) return -1;
648 if(dump_expression(dump, e->u.binary.l, ind + INDENT))
650 if(punc(dump, ',')) return -1;
651 if(dump_expression(dump, e->u.binary.r, ind + INDENT))
653 if(punc(dump, ')')) return -1;
655 case ex_compound_literal:
656 if(location(dump, &e->where, ind)) return -1;
657 if(punc(dump, '(')) return -1;
658 if(location(dump, &e->u.compound_literal.type->where, ind + INDENT))
660 if(dump_declaration_raw(dump, e->u.compound_literal.type, ind + INDENT))
662 if(punc(dump, ')')) return -1;
663 if(dump_initializer_list(dump, e->u.compound_literal.value,
668 if(location(dump, &e->where, ind)) return -1;
669 if(word(dump, "sizeof")) return -1;
670 if(punc(dump, '(')) return -1;
671 if(location(dump, &e->u.type->where, ind + INDENT)) return -1;
672 if(dump_declaration_raw(dump, e->u.type, ind + 2 * INDENT)) return -1;
673 if(punc(dump, ')')) return -1;
676 if(location(dump, &e->where, ind)) return -1;
677 if(punc(dump, '(')) return -1;
678 if(location(dump, &e->valuetype->where, ind + INDENT)) return -1;
679 if(dump_declaration_specifiers(dump, e->valuetype->declaration_specifiers,
682 if(dump_declarator(dump, e->valuetype, ind + INDENT)) return -1;
683 if(punc(dump, ')')) return -1;
684 if(dump_expression(dump, e->u.cast, ind + 2 * INDENT)) return -1;
686 case ex_implicit_conversion:
687 if(dump_expression(dump, e->u.cast, ind)) return -1;
693 int dump_function_definition(dump_state *dump,
694 const struct function_definition *fd,
696 const struct declaration *d;
698 if(location(dump, &fd->declaration->where, ind)) return -1;
699 if(dump_declaration_raw(dump, fd->declaration, ind)) return -1;
700 for(d = fd->args; d; d = d->next)
701 if(dump_declaration(dump, d, ind + INDENT)) return -1;
702 if(dump_statement(dump, fd->body, ind)) return -1;
706 int dump_statement(dump_state *dump,
707 const struct statement *s,
709 const struct statement *ss;
713 if(location(dump, &s->where, 0)) return -1;
717 if(location(dump, &s->where, ind - CASEIND)) return -1;
720 if(location(dump, &s->where, ind)) return -1;
725 if(word(dump, s->u.label.label)) return -1;
726 if(punc(dump, ':')) return -1;
727 if(dump_statement(dump, s->u.label.body, ind)) return -1;
730 if(word(dump, "case")) return -1;
731 if(dump_expression(dump, s->u.case_.value, ind + INDENT)) return -1;
732 if(punc(dump, ':')) return -1;
733 if(dump_statement(dump, s->u.case_.body, ind)) return -1;
736 if(word(dump, "default")) return -1;
737 if(punc(dump, ':')) return -1;
738 if(dump_statement(dump, s->u.default_, ind)) return -1;
741 if(dump_declaration(dump, s->u.declaration, ind + INDENT)) return -1;
744 if(s->u.expression && dump_expression(dump, s->u.expression, ind + INDENT))
746 if(punc(dump, ';')) return -1;
749 if(word(dump, "if")) return -1;
750 if(punc(dump, '(')) return -1;
751 if(dump_expression(dump, s->u.if_.cond, ind + INDENT))
753 if(punc(dump, ')')) return -1;
754 if(dump_statement(dump, s->u.if_.true, ind + INDENT)) return -1;
756 if(word(dump, "else")) return -1;
757 if(dump_statement(dump, s->u.if_.false, ind + INDENT)) return -1;
761 if(word(dump, "switch")) return -1;
762 if(punc(dump, '(')) return -1;
763 if(dump_expression(dump, s->u.switch_.cond, ind + INDENT))
765 if(punc(dump, ')')) return -1;
766 if(dump_statement(dump, s->u.switch_.body, ind + INDENT)) return -1;
769 if(word(dump, "while")) return -1;
770 if(punc(dump, '(')) return -1;
771 if(dump_expression(dump, s->u.while_.cond, ind + INDENT))
773 if(punc(dump, ')')) return -1;
774 if(dump_statement(dump, s->u.while_.body, ind + INDENT)) return -1;
777 if(word(dump, "do")) return -1;
778 if(dump_statement(dump, s->u.while_.body, ind + INDENT)) return -1;
779 if(word(dump, "while")) return -1;
780 if(punc(dump, '(')) return -1;
781 if(dump_expression(dump, s->u.while_.cond, ind + INDENT))
783 if(punc(dump, ')')) return -1;
784 if(punc(dump, ';')) return -1;
787 if(word(dump, "for")) return -1;
788 if(punc(dump, '(')) return -1;
789 if(s->u.for_.init && dump_expression(dump, s->u.for_.init, ind + INDENT))
791 if(punc(dump, ';')) return -1;
792 if(s->u.for_.cond && dump_expression(dump, s->u.for_.cond, ind + INDENT))
794 if(punc(dump, ';')) return -1;
795 if(s->u.for_.iter && dump_expression(dump, s->u.for_.iter, ind + INDENT))
797 if(punc(dump, ')')) return -1;
798 if(dump_statement(dump, s->u.for_.body, ind + INDENT)) return -1;
800 case st_for_declaration:
801 if(word(dump, "for")) return -1;
802 if(punc(dump, '(')) return -1;
803 if(s->u.for_declaration.init
804 && dump_declaration_raw(dump, s->u.for_declaration.init, ind + INDENT))
806 if(punc(dump, ';')) return -1;
807 if(s->u.for_declaration.cond
808 && dump_expression(dump, s->u.for_declaration.cond, ind + INDENT))
810 if(punc(dump, ';')) return -1;
811 if(s->u.for_declaration.iter
812 && dump_expression(dump, s->u.for_declaration.iter, ind + INDENT))
814 if(punc(dump, ')')) return -1;
815 if(dump_statement(dump, s->u.for_declaration.body, ind + INDENT)) return -1;
818 if(word(dump, "goto")) return -1;
819 if(word(dump, s->u.goto_)) return -1;
820 if(punc(dump, ';')) return -1;
823 if(word(dump, "continue")) return -1;
824 if(punc(dump, ';')) return -1;
827 if(word(dump, "break")) return -1;
828 if(punc(dump, ';')) return -1;
831 if(word(dump, "return")) return -1;
832 if(s->u.expression && dump_expression(dump, s->u.expression, ind + INDENT))
834 if(punc(dump, ';')) return -1;
837 if(ind == 0) ind = INDENT; /* top level */
838 if(punc(dump, '{')) return -1;
839 for(ss = s->u.compound.body; ss; ss = ss->next)
840 if(dump_statement(dump, ss, ind)) return -1;
841 if(location(dump, &s->u.compound.endwhere, ind - INDENT)) return -1;
842 if(punc(dump, '}')) return -1;