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;