]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/m2/m2pp.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / m2 / m2pp.cc
CommitLineData
1eee94d3
GM
1/* m2pp.c pretty print trees, output in Modula-2 where possible.
2
83ffe9cd 3Copyright (C) 2007-2023 Free Software Foundation, Inc.
1eee94d3
GM
4Contributed by Gaius Mulley <gaius@glam.ac.uk>.
5
6This file is part of GNU Modula-2.
7
8GNU Modula-2 is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3, or (at your option)
11any later version.
12
13GNU Modula-2 is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU Modula-2; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
21
22#if defined(GM2)
23#include "gm2-gcc/gcc-consolidation.h"
24
25#include "m2-tree.h"
26#include "gm2-lang.h"
27
28#include "gm2-gcc/m2tree.h"
29#include "gm2-gcc/m2expr.h"
30#include "gm2-gcc/m2type.h"
31#include "gm2-gcc/m2decl.h"
32#else
33#include "config.h"
34#include "system.h"
35#include "coretypes.h"
36#include "cp/cp-tree.h"
37#include "stringpool.h"
38#include "gm2-gcc/gcc-consolidation.h"
39#include "../cp/cp-tree.h"
40#endif
41
42#define M2PP_C
43#include "m2/m2pp.h"
44
45namespace modula2 {
46
47#undef DEBUGGING
48
49typedef struct pretty_t
50{
51 int needs_space;
52 int needs_indent;
53 int curpos;
54 int indent;
55 int issued_begin;
56 int in_vars;
57 int in_types;
58 tree block;
59 int bits;
60} pretty;
61
62typedef struct m2stack_t
63{
64 tree value;
65 struct m2stack_t *next;
66} stack;
67
68/* Prototypes. */
69
70static pretty *initPretty (int bits);
71static pretty *dupPretty (pretty *s);
72static int getindent (pretty *s);
73static void setindent (pretty *s, int n);
74static int getcurpos (pretty *s);
75static void m2pp_identifier (pretty *s, tree t);
76static void m2pp_needspace (pretty *s);
77static void m2pp_function (pretty *s, tree t);
78static void m2pp_function_header (pretty *s, tree t);
79static void m2pp_function_vars (pretty *s, tree t);
80static void m2pp_statement_sequence (pretty *s, tree t);
81static void m2pp_print (pretty *s, const char *p);
82static void m2pp_print_char (pretty *s, char ch);
83static void m2pp_parameter (pretty *s, tree t);
84static void m2pp_type (pretty *s, tree t);
85static void m2pp_ident_pointer (pretty *s, tree t);
86static void m2pp_set_type (pretty *s, tree t);
87static void m2pp_enum (pretty *s, tree t);
88static void m2pp_array (pretty *s, tree t);
89static void m2pp_subrange (pretty *s, tree t);
90static void m2pp_gimpified (pretty *s, tree t);
91static void m2pp_pointer_type (pretty *s, tree t);
92static void m2pp_record_type (pretty *s, tree t);
93static void m2pp_union_type (pretty *s, tree t);
94static void m2pp_simple_type (pretty *s, tree t);
95static void m2pp_expression (pretty *s, tree t);
96static void m2pp_relop (pretty *s, tree t, const char *p);
97static void m2pp_simple_expression (pretty *s, tree t);
98static void m2pp_statement_sequence (pretty *s, tree t);
99static void m2pp_unknown (pretty *s, const char *s1, const char *s2);
100static void m2pp_statement (pretty *s, tree t);
101static void m2pp_assignment (pretty *s, tree t);
102static void m2pp_designator (pretty *s, tree t);
103static void m2pp_conditional (pretty *s, tree t);
104static void m2pp_label_expr (pretty *s, tree t);
105static void m2pp_label_decl (pretty *s, tree t);
106static void m2pp_goto (pretty *s, tree t);
107static void m2pp_list (pretty *s, tree t);
108static void m2pp_offset (pretty *s, tree t);
109static void m2pp_indirect_ref (pretty *s, tree t);
110static void m2pp_integer_cst (pretty *s, tree t);
111static void m2pp_real_cst (pretty *s, tree t);
112static void m2pp_string_cst (pretty *s, tree t);
113static void m2pp_integer (pretty *s, tree t);
114static void m2pp_addr_expr (pretty *s, tree t);
115static void m2pp_nop (pretty *s, tree t);
116static void m2pp_convert (pretty *s, tree t);
117static void m2pp_var_decl (pretty *s, tree t);
118static void m2pp_binary (pretty *s, tree t, const char *p);
119static void m2pp_unary (pretty *s, tree t, const char *p);
120static void m2pp_call_expr (pretty *s, tree t);
121static void m2pp_procedure_call (pretty *s, tree t);
122static void m2pp_ssa (pretty *s, tree t);
123static void m2pp_block (pretty *s, tree t);
124static void m2pp_block_list (pretty *s, tree t);
125static void m2pp_var_list (pretty *s, tree t);
126static void m2pp_bind_expr (pretty *s, tree t);
127static void m2pp_return_expr (pretty *s, tree t);
128static void m2pp_result_decl (pretty *s, tree t);
129static void m2pp_try_block (pretty *s, tree t);
130static void m2pp_cleanup_point_expr (pretty *s, tree t);
131static void m2pp_handler (pretty *s, tree t);
132static void m2pp_component_ref (pretty *s, tree t);
133static void m2pp_array_ref (pretty *s, tree t);
134static void m2pp_begin (pretty *s);
135static void m2pp_var (pretty *s);
136static void m2pp_types (pretty *s);
137static void m2pp_decl_expr (pretty *s, tree t);
138static void m2pp_var_type_decl (pretty *s, tree t);
139static void m2pp_non_lvalue_expr (pretty *s, tree t);
140static void m2pp_procedure_type (pretty *s, tree t);
141static void m2pp_param_type (pretty *s, tree t);
142static void m2pp_type_lowlevel (pretty *s, tree t);
143static void m2pp_try_catch_expr (pretty *s, tree t);
144static void m2pp_throw (pretty *s, tree t);
145static void m2pp_catch_expr (pretty *s, tree t);
146static void m2pp_try_finally_expr (pretty *s, tree t);
147static void m2pp_complex (pretty *s, tree t);
148static void killPretty (pretty *s);
149static void m2pp_compound_expression (pretty *s, tree t);
150static void m2pp_target_expression (pretty *s, tree t);
151static void m2pp_constructor (pretty *s, tree t);
152static void m2pp_translation (pretty *s, tree t);
153static void m2pp_module_block (pretty *s, tree t);
154static void push (tree t);
155static void pop (void);
156static int begin_printed (tree t);
157static void m2pp_decl_list (pretty *s, tree t);
158static void m2pp_loc (pretty *s, tree t);
159
160void pet (tree t);
161void m2pp_integer (pretty *s, tree t);
162
163extern void stop (void);
164
165static stack *stackPtr = NULL;
166
167/* do_pf helper function for pf. */
168
169void
170do_pf (tree t, int bits)
171{
172 pretty *state = initPretty (bits);
173
174 if (TREE_CODE (t) == TRANSLATION_UNIT_DECL)
175 m2pp_translation (state, t);
176 else if (TREE_CODE (t) == BLOCK)
177 m2pp_module_block (state, t);
178 else if (TREE_CODE (t) == FUNCTION_DECL)
179 m2pp_function (state, t);
180 else
181 m2pp_statement_sequence (state, t);
182 killPretty (state);
183}
184
185/* pf print function. Expected to be printed interactively from
186 the debugger: print pf(func), or to be called from code. */
187
188void
189pf (tree t)
190{
191 do_pf (t, FALSE);
192}
193
194/* pe print expression. Expected to be printed interactively from
195 the debugger: print pe(expr), or to be called from code. */
196
197void
198pe (tree t)
199{
200 pretty *state = initPretty (FALSE);
201
202 m2pp_expression (state, t);
203 m2pp_needspace (state);
204 m2pp_print (state, ";\n");
205 killPretty (state);
206}
207
208/* pet print expression and its type. Expected to be printed
209 interactively from the debugger: print pet(expr), or to be called
210 from code. */
211
212void
213pet (tree t)
214{
215 pretty *state = initPretty (FALSE);
216
217 m2pp_expression (state, t);
218 m2pp_needspace (state);
219 m2pp_print (state, ":");
220 m2pp_type (state, TREE_TYPE (t));
221 m2pp_print (state, ";\n");
222 killPretty (state);
223}
224
225/* pt print type. Expected to be printed interactively from the
226 debugger: print pt(expr), or to be called from code. */
227
228void
229pt (tree t)
230{
231 pretty *state = initPretty (FALSE);
232 m2pp_type (state, t);
233 m2pp_needspace (state);
234 m2pp_print (state, ";\n");
235 killPretty (state);
236}
237
238/* ptl print type low level. Expected to be printed interactively
239 from the debugger: print ptl(type), or to be called from code. */
240
241void
242ptl (tree t)
243{
244 pretty *state = initPretty (FALSE);
245 m2pp_type_lowlevel (state, t);
246 m2pp_needspace (state);
247 m2pp_print (state, ";\n");
248 killPretty (state);
249}
250
251/* ptcl print TREE_CHAINed list. */
252
253void
254ptcl (tree t)
255{
256 pretty *state = initPretty (FALSE);
257
258 m2pp_decl_list (state, t);
259 m2pp_print (state, "\n");
260 killPretty (state);
261}
262
263/* loc if tree has a location then display it within a comment. */
264
265static void
266m2pp_loc (pretty *s, tree t)
267{
268 if (CAN_HAVE_LOCATION_P (t))
269 {
270 if (EXPR_HAS_LOCATION (t))
271 {
272 if (EXPR_LOCATION (t) == UNKNOWN_LOCATION)
273 m2pp_print (s, "(* missing location1 *)\n");
274 else
275 {
276 expanded_location l = expand_location (EXPR_LOCATION (t));
277
278 m2pp_print (s, "(* ");
279 m2pp_print (s, l.file);
280 m2pp_print (s, ":");
281 printf ("%d", l.line);
282 m2pp_print (s, " *)");
283 m2pp_print (s, "\n");
284 }
285 }
286 else
287 {
288 m2pp_print (s, "(* missing location2 *)\n");
289 }
290 }
291}
292
293/* m2pp_decl_list prints a TREE_CHAINed list for a decl node. */
294
295static void
296m2pp_decl_list (pretty *s, tree t)
297{
298 tree u = t;
299
300 m2pp_print (s, "(");
301 m2pp_needspace (s);
302 while (t != NULL_TREE)
303 {
304 m2pp_identifier (s, t);
305 t = TREE_CHAIN (t);
306 if (t == u || t == NULL_TREE)
307 break;
308 m2pp_print (s, ",");
309 m2pp_needspace (s);
310 }
311 m2pp_needspace (s);
312 m2pp_print (s, ")");
313}
314
315static void
316m2pp_decl_bool (pretty *s, tree t)
317{
318 if (TREE_STATIC (t))
319 m2pp_print (s, "static, ");
320 if (DECL_EXTERNAL (t))
321 m2pp_print (s, "external, ");
322 if (DECL_SEEN_IN_BIND_EXPR_P (t))
323 m2pp_print (s, "in bind expr, ");
324}
325
326void
327pv (tree t)
328{
329 if (t)
330 {
331 enum tree_code code = TREE_CODE (t);
332
333 if (code == PARM_DECL)
334 {
335 pretty *state = initPretty (FALSE);
336 m2pp_identifier (state, t);
337 m2pp_needspace (state);
338 m2pp_print (state, "<parm_decl context = ");
339 m2pp_identifier (state, DECL_CONTEXT (t));
340 if (DECL_ABSTRACT_ORIGIN (t) == t)
341 m2pp_print (state, ">\n");
342 else
343 {
344 m2pp_print (state, ", abstract origin = ");
345 m2pp_identifier (state, DECL_ABSTRACT_ORIGIN (t));
346 m2pp_print (state, ">\n");
347 modula2::pv (DECL_ABSTRACT_ORIGIN (t));
348 }
349 killPretty (state);
350 }
351 if (code == VAR_DECL)
352 {
353 pretty *state = initPretty (FALSE);
354 m2pp_identifier (state, t);
355 m2pp_needspace (state);
356 m2pp_print (state, "(* <var_decl context = ");
357 m2pp_identifier (state, DECL_CONTEXT (t));
358 m2pp_decl_bool (state, t);
359 if (DECL_ABSTRACT_ORIGIN (t) == t)
360 m2pp_print (state, "> *)\n");
361 else
362 {
363 m2pp_print (state, ", abstract origin = ");
364 m2pp_identifier (state, DECL_ABSTRACT_ORIGIN (t));
365 m2pp_print (state, "> *)\n");
366 modula2::pv (DECL_ABSTRACT_ORIGIN (t));
367 }
368 killPretty (state);
369 }
370 }
371}
372
373#if defined(GM2_MAINTAINER)
374
375/* remember an internal debugging hook. */
376static tree rememberF = NULL;
377
378static void
379remember (tree t)
380{
381 rememberF = t;
382 printf ("type: watch *((tree *) %p) != %p\n", (void *)&DECL_SAVED_TREE (t),
383 (void *)DECL_SAVED_TREE (t));
384}
385#endif
386
387/* push pushes tree t onto stack. */
388
389static void
390push (tree t)
391{
392 stack *s = (stack *)xmalloc (sizeof (stack));
393
394 s->value = t;
395 s->next = stackPtr;
396 stackPtr = s;
397}
398
399/* pop pops a tree, from the stack. */
400
401static void
402pop (void)
403{
404 stack *s = stackPtr;
405
406 stackPtr = stackPtr->next;
407 free (s);
408}
409
410/* being_printed returns TRUE if t is held on the stack. */
411
412static int
413begin_printed (tree t)
414{
415 stack *s = stackPtr;
416
417 while (s != NULL)
418 {
419 if (s->value == t)
420 return TRUE;
421 else
422 s = s->next;
423 }
424 return FALSE;
425}
426
427/* dupPretty duplicate and return a copy of state s. */
428
429static pretty *
430dupPretty (pretty *s)
431{
432 pretty *p = initPretty (s->bits);
433 *p = *s;
434 return p;
435}
436
437/* initPretty initialise the state of the pretty printer. */
438
439static pretty *
440initPretty (int bits)
441{
442 pretty *state = (pretty *)xmalloc (sizeof (pretty));
443 state->needs_space = FALSE;
444 state->needs_indent = FALSE;
445 state->curpos = 0;
446 state->indent = 0;
447 state->issued_begin = FALSE;
448 state->in_vars = FALSE;
449 state->in_types = FALSE;
450 state->block = NULL_TREE;
451 state->bits = bits;
452 return state;
453}
454
455/* killPretty cleans up the state. */
456
457static void
458killPretty (pretty *s)
459{
460 free (s);
461 fflush (stdout);
462}
463
464/* getindent returns the current indent value. */
465
466static int
467getindent (pretty *s)
468{
469 return s->indent;
470}
471
472/* setindent sets the current indent to, n. */
473
474static void
475setindent (pretty *s, int n)
476{
477 s->indent = n;
478}
479
480/* getcurpos returns the current cursor position. */
481
482static int
483getcurpos (pretty *s)
484{
485 if (s->needs_space)
486 return s->curpos + 1;
487 else
488 return s->curpos;
489}
490
491/* m2pp_type_lowlevel prints out the low level details of a
492 fundamental type. */
493
494static void
495m2pp_type_lowlevel (pretty *s, tree t)
496{
497 if (TREE_CODE (t) == INTEGER_TYPE)
498 {
499 m2pp_print (s, "min");
500 m2pp_needspace (s);
501 m2pp_integer_cst (s, TYPE_MIN_VALUE (t));
502 m2pp_print (s, ", max");
503 m2pp_needspace (s);
504 m2pp_integer_cst (s, TYPE_MAX_VALUE (t));
505 m2pp_print (s, ", type size unit");
506 m2pp_needspace (s);
507 m2pp_integer_cst (s, TYPE_SIZE_UNIT (t));
508 m2pp_print (s, ", type size");
509 m2pp_needspace (s);
510 m2pp_integer_cst (s, TYPE_SIZE (t));
511
512 printf (", precision %d, mode %d, align %d, user align %d",
513 TYPE_PRECISION (t), TYPE_MODE (t), TYPE_ALIGN (t),
514 TYPE_USER_ALIGN (t));
515
516 m2pp_needspace (s);
517 if (TYPE_UNSIGNED (t))
518 m2pp_print (s, "unsigned\n");
519 else
520 m2pp_print (s, "signed\n");
521 }
522}
523
524/* m2pp_var emit a VAR if necessary. */
525
526static void
527m2pp_var (pretty *s)
528{
529 if (!s->in_vars)
530 {
531 s->in_vars = TRUE;
532 m2pp_print (s, "VAR\n");
533 setindent (s, getindent (s) + 3);
534 }
535}
536
537/* m2pp_types emit a TYPE if necessary. */
538
539static void
540m2pp_types (pretty *s)
541{
542 if (!s->in_types)
543 {
544 s->in_types = TRUE;
545 m2pp_print (s, "TYPE\n");
546 setindent (s, getindent (s) + 3);
547 }
548}
549
550/* hextree displays the critical fields for function, block and
551 bind_expr trees in raw hex. */
552
553static void
554hextree (tree t)
555{
556 if (t == NULL_TREE)
557 return;
558
559 if (TREE_CODE (t) == BLOCK)
560 {
561 printf ("(* BLOCK %p *)\n", (void *)t);
562 printf ("BLOCK_VARS (t) = %p\n", (void *)BLOCK_VARS (t));
563 printf ("BLOCK_SUPERCONTEXT (t) = %p\n",
564 (void *)BLOCK_SUPERCONTEXT (t));
565 }
566 if (TREE_CODE (t) == BIND_EXPR)
567 {
568 printf ("(* BIND_EXPR %p *)\n", (void *)t);
569 printf ("BIND_EXPR_VARS (t) = %p\n", (void *)BIND_EXPR_VARS (t));
570 printf ("BIND_EXPR_BLOCK (t) = %p\n", (void *)BIND_EXPR_BLOCK (t));
571 printf ("BIND_EXPR_BODY (t) = %p\n", (void *)BIND_EXPR_BODY (t));
572 }
573 if (TREE_CODE (t) == FUNCTION_DECL)
574 {
575 printf ("(* FUNCTION_DECL %p *)\n", (void *)t);
576 printf ("DECL_INITIAL (t) = %p\n", (void *)DECL_INITIAL (t));
577 printf ("DECL_SAVED_TREE (t) = %p\n", (void *)DECL_SAVED_TREE (t));
578 hextree (DECL_INITIAL (t));
579 hextree (DECL_SAVED_TREE (t));
580 }
581 if (TREE_CODE (t) == VAR_DECL)
582 {
583 pretty *state = initPretty (FALSE);
584
585 printf ("(* VAR_DECL %p <", (void *)t);
586 if (DECL_SEEN_IN_BIND_EXPR_P (t))
587 printf ("b");
588 if (DECL_EXTERNAL (t))
589 printf ("e");
590 if (TREE_STATIC (t))
591 printf ("s");
592 printf ("> context = %p*)\n", (void *)decl_function_context (t));
593 m2pp_type (state, TREE_TYPE (t));
594 m2pp_needspace (state);
595 m2pp_print (state, ";\n");
596 killPretty (state);
597 }
598 if (TREE_CODE (t) == PARM_DECL)
599 {
600 pretty *state = initPretty (FALSE);
601
602 printf ("(* PARM_DECL %p <", (void *)t);
603 printf ("> context = %p*)\n", (void *)decl_function_context (t));
604 m2pp_type (state, TREE_TYPE (t));
605 m2pp_needspace (state);
606 m2pp_print (state, ";\n");
607 killPretty (state);
608 }
609}
610
611/* translation produce a pseudo implementation module from the tree t. */
612
613static void
614m2pp_translation (pretty *s, tree t)
615{
616 tree block = DECL_INITIAL (t);
617
618 m2pp_print (s, "IMPLEMENTATION MODULE ");
619 m2pp_identifier (s, t);
620 m2pp_print (s, "\n\n");
621
622 if (block != NULL)
623 {
624 m2pp_module_block (s, block);
625 m2pp_print (s, "\n");
626 }
627
628 m2pp_print (s, "\n");
629 m2pp_print (s, "END ");
630 m2pp_identifier (s, t);
631 m2pp_print (s, ".\n");
632}
633
634static void
635m2pp_module_block (pretty *s, tree t)
636{
637 t = BLOCK_VARS (t);
638
639 if (t != NULL_TREE)
640 for (; t != NULL_TREE; t = TREE_CHAIN (t))
641 {
642 switch (TREE_CODE (t))
643 {
644 case FUNCTION_DECL:
645 if (!DECL_EXTERNAL (t))
646 {
647 pretty *p = dupPretty (s);
648 printf ("\n");
649 p->in_vars = FALSE;
650 p->in_types = FALSE;
651 m2pp_function (p, t);
652 killPretty (p);
653 printf ("\n");
654 s->in_vars = FALSE;
655 s->in_types = FALSE;
656 }
657 break;
658
659 case TYPE_DECL:
660 {
661 int o = getindent (s);
662 int p;
663
664 m2pp_print (s, "\n");
665 m2pp_types (s);
666 setindent (s, o + 3);
667 m2pp_identifier (s, t);
668 m2pp_print (s, " = ");
669 p = getcurpos (s);
670 setindent (s, p);
671 m2pp_type (s, TREE_TYPE (t));
672 setindent (s, o);
673 m2pp_needspace (s);
674 m2pp_print (s, ";\n");
675 s->in_vars = FALSE;
676 }
677 break;
678
679 case VAR_DECL:
680 m2pp_var (s);
681 m2pp_identifier (s, t);
682 m2pp_needspace (s);
683 m2pp_print (s, ":");
684 m2pp_needspace (s);
685 m2pp_type (s, TREE_TYPE (t));
686 m2pp_needspace (s);
687 m2pp_print (s, ";\n");
688 s->in_types = FALSE;
689 break;
690
691 case DECL_EXPR:
692 printf ("is this node legal here? \n");
693 m2pp_decl_expr (s, t);
694 break;
695
696 default:
697 m2pp_unknown (s, __FUNCTION__, get_tree_code_name (TREE_CODE (t)));
698 }
699 }
700}
701
702/* m2pp_begin emit a BEGIN if necessary. */
703
704static void
705m2pp_begin (pretty *s)
706{
707 if (!s->issued_begin)
708 {
709 if (s->in_vars || s->in_types)
710 {
711 setindent (s, getindent (s) - 3);
712 m2pp_print (s, "BEGIN\n");
713 setindent (s, getindent (s) + 3);
714 }
715 else
716 {
717 m2pp_print (s, "BEGIN\n");
718 setindent (s, getindent (s) + 3);
719 }
720 s->issued_begin = TRUE;
721 s->in_vars = FALSE;
722 s->in_types = FALSE;
723 }
724}
725
726/* m2pp_function walk over the function. */
727
728static void
729m2pp_function (pretty *s, tree t)
730{
731 m2pp_function_header (s, t);
732 m2pp_function_vars (s, t);
733 m2pp_statement_sequence (s, DECL_SAVED_TREE (t));
734 if (TREE_CODE (t) == FUNCTION_DECL)
735 {
736 m2pp_begin (s);
737 setindent (s, getindent (s) - 3);
738 m2pp_print (s, "END");
739 m2pp_needspace (s);
740 m2pp_identifier (s, t);
741 m2pp_needspace (s);
742 m2pp_print (s, ";\n");
743 }
744}
745
746/* m2pp_bind_expr displays the bind expr tree node. */
747
748static void
749m2pp_bind_expr (pretty *s, tree t)
750{
751 if (TREE_CODE (t) == BIND_EXPR)
752 {
753 if (BIND_EXPR_VARS (t))
754 {
755 m2pp_print (s, "(* variables in bind_expr *)\n");
756 m2pp_var (s);
757 m2pp_var_list (s, BIND_EXPR_VARS (t));
758 }
759 if (BIND_EXPR_BLOCK (t))
760 {
761 m2pp_print (s, "(* bind_expr_block *)\n");
762 m2pp_statement_sequence (s, BIND_EXPR_BLOCK (t));
763 m2pp_needspace (s);
764 m2pp_print (s, "; \n");
765 }
766 m2pp_statement_sequence (s, BIND_EXPR_BODY (t));
767 }
768}
769
770/* m2pp_block_list iterates over the list of blocks. */
771
772static void
773m2pp_block_list (pretty *s, tree t)
774{
775 for (; t; t = BLOCK_CHAIN (t))
776 m2pp_block (s, t);
777}
778
779/* m2pp_block prints the VARiables and the TYPEs inside a block. */
780
781static void
782m2pp_block (pretty *s, tree t)
783{
784 if ((BLOCK_VARS (t) != NULL_TREE) && (s->block != BLOCK_VARS (t)))
785 {
786 s->block = BLOCK_VARS (t);
787 m2pp_print (s, "(* block variables *)\n");
788 m2pp_var (s);
789 m2pp_var_list (s, BLOCK_VARS (t));
790 }
791}
792
793/* m2pp_var_type_decl displays the variable and type declaration. */
794
795static void
796m2pp_var_type_decl (pretty *s, tree t)
797{
798 m2pp_identifier (s, t);
799 m2pp_needspace (s);
800 m2pp_print (s, ":");
801 m2pp_needspace (s);
802 m2pp_type (s, TREE_TYPE (t));
803 m2pp_needspace (s);
804 m2pp_print (s, ";\n");
805}
806
807/* m2pp_var_list print a variable list. */
808
809static void
810m2pp_var_list (pretty *s, tree t)
811{
812 if (t != NULL_TREE)
813 for (; t; t = TREE_CHAIN (t))
814 {
815 if (TREE_CODE (t) == FUNCTION_DECL)
816 {
817 pretty *p = dupPretty (s);
818 printf ("\n");
819 p->in_vars = FALSE;
820 p->in_types = FALSE;
821 m2pp_function (p, t);
822 killPretty (p);
823 printf ("\n");
824 }
825 else if (TREE_CODE (t) == TYPE_DECL)
826 m2pp_identifier (s, t);
827 else if (TREE_CODE (t) == DECL_EXPR)
828 {
829 printf ("is this node legal here? \n");
830 // is it legal to have a DECL_EXPR here ?
831 m2pp_var_type_decl (s, DECL_EXPR_DECL (t));
832 }
833 else
834 m2pp_var_type_decl (s, t);
835 }
836}
837
838#if 0
839/* m2pp_type_list print a variable list. */
840
841static void
842m2pp_type_list (pretty *s, tree t)
843{
844 if (t != NULL_TREE)
845 for (; t; t = TREE_CHAIN (t))
846 {
847 m2pp_identifier (s, t);
848 m2pp_needspace (s);
849 m2pp_print (s, "=");
850 m2pp_needspace (s);
851 m2pp_type (s, TREE_TYPE (t));
852 m2pp_needspace (s);
853 m2pp_print (s, ";\n");
854 }
855}
856#endif
857
858/* m2pp_needspace sets appropriate flag to TRUE. */
859
860static void
861m2pp_needspace (pretty *s)
862{
863 s->needs_space = TRUE;
864}
865
866/* m2pp_identifer prints an identifier. */
867
868static void
869m2pp_identifier (pretty *s, tree t)
870{
871 if (t)
872 {
873 if (TREE_CODE (t) == COMPONENT_REF)
874 m2pp_component_ref (s, t);
875 else if (DECL_NAME (t) && IDENTIFIER_POINTER (DECL_NAME (t)))
876 m2pp_ident_pointer (s, DECL_NAME (t));
877 else
878 {
879 char name[100];
880
881 if (TREE_CODE (t) == CONST_DECL)
882 snprintf (name, 100, "C_%u", DECL_UID (t));
883 else
884 snprintf (name, 100, "D_%u", DECL_UID (t));
885 m2pp_print (s, name);
886 }
887 }
888}
889
890/* m2pp_ident_pointer displays an ident pointer. */
891
892static void
893m2pp_ident_pointer (pretty *s, tree t)
894{
895 if (t)
896 m2pp_print (s, IDENTIFIER_POINTER (t));
897}
898
899/* m2pp_parameter prints out a param decl tree. */
900
901static void
902m2pp_parameter (pretty *s, tree t)
903{
904 if (TREE_CODE (t) == PARM_DECL)
905 {
906 if (TREE_TYPE (t) && (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE))
907 {
908 m2pp_print (s, "VAR");
909 m2pp_needspace (s);
910 m2pp_identifier (s, t);
911 m2pp_print (s, ":");
912 m2pp_needspace (s);
913 m2pp_simple_type (s, TREE_TYPE (TREE_TYPE (t)));
914 }
915 else
916 {
917 m2pp_identifier (s, t);
918 m2pp_print (s, ":");
919 m2pp_needspace (s);
920 m2pp_simple_type (s, TREE_TYPE (t));
921 }
922 }
923}
924
925/* m2pp_param_type prints out the type of parameter. */
926
927static void
928m2pp_param_type (pretty *s, tree t)
929{
930 if (t && (TREE_CODE (t) == REFERENCE_TYPE))
931 {
932 m2pp_print (s, "VAR");
933 m2pp_needspace (s);
934 m2pp_simple_type (s, TREE_TYPE (t));
935 }
936 else
937 m2pp_simple_type (s, t);
938}
939
940/* m2pp_procedure_type displays a procedure type. */
941
942static void
943m2pp_procedure_type (pretty *s, tree t)
944{
945 push (t);
946 if (TREE_CODE (t) == FUNCTION_TYPE)
947 {
948 tree i = TYPE_ARG_TYPES (t);
949 tree returnType = TREE_TYPE (TREE_TYPE (t));
950
951 m2pp_needspace (s);
952 m2pp_print (s, "PROCEDURE");
953 m2pp_needspace (s);
954 if (i != NULL_TREE)
955 {
956 int o = getindent (s);
957 int p;
958 int first = TRUE;
959
960 m2pp_print (s, "(");
961 p = getcurpos (s);
962 setindent (s, p);
963 while (i != NULL_TREE)
964 {
965 if (TREE_CHAIN (i) == NULL_TREE)
966 {
967 if (TREE_VALUE (i) == void_type_node)
968 /* Ignore void_type_node at the end. */
969 ;
970 else
971 {
972 m2pp_param_type (s, TREE_VALUE (i));
973 m2pp_print (s, ", ...");
974 }
975 break;
976 }
977 else
978 {
979 if (!first)
980 {
981 m2pp_print (s, ",");
982 m2pp_needspace (s);
983 }
984 m2pp_param_type (s, TREE_VALUE (i));
985 }
986 i = TREE_CHAIN (i);
987 first = FALSE;
988 }
989 m2pp_print (s, ")");
990 setindent (s, o);
991 }
992 else if (returnType != NULL_TREE)
993 {
994 m2pp_needspace (s);
995 m2pp_print (s, "()");
996 }
997 if (returnType != NULL_TREE)
998 {
999 m2pp_needspace (s);
1000 m2pp_print (s, ": ");
1001 m2pp_simple_type (s, returnType);
1002 }
1003 }
1004 pop ();
1005}
1006
1007/* m2pp_comment_header displays a simple header with some critical
1008 tree info. */
1009
1010static void
1011m2pp_comment_header (pretty *s, tree t)
1012{
1013 int o = getindent (s);
1014
1015 m2pp_print (s, "(*\n");
1016 setindent (s, o + 3);
1017 m2pp_identifier (s, t);
1018 m2pp_needspace (s);
1019 m2pp_print (s, "-");
1020 m2pp_needspace (s);
1021 if (TREE_PUBLIC (t))
1022 {
1023 m2pp_needspace (s);
1024 m2pp_print (s, "public,");
1025 }
1026 if (TREE_STATIC (t))
1027 {
1028 m2pp_needspace (s);
1029 m2pp_print (s, "static,");
1030 }
1031 if (DECL_EXTERNAL (t))
1032 {
1033 m2pp_needspace (s);
1034 m2pp_print (s, "extern");
1035 }
1036 m2pp_print (s, "\n");
1037 setindent (s, o);
1038 m2pp_print (s, "*)\n\n");
1039}
1040
1041/* m2pp_function_header displays the function header. */
1042
1043static void
1044m2pp_function_header (pretty *s, tree t)
1045{
1046 push (t);
1047 if (TREE_CODE (t) == FUNCTION_DECL)
1048 {
1049 tree i = DECL_ARGUMENTS (t);
1050 tree returnType = TREE_TYPE (TREE_TYPE (t));
1051
1052 m2pp_comment_header (s, t);
1053 m2pp_print (s, "PROCEDURE ");
1054 m2pp_identifier (s, t);
1055 m2pp_needspace (s);
1056 if (i != NULL_TREE)
1057 {
1058 int o = getindent (s);
1059 int p;
1060
1061 m2pp_print (s, "(");
1062 p = getcurpos (s);
1063 setindent (s, p);
1064 while (i != NULL_TREE)
1065 {
1066 m2pp_parameter (s, i);
1067 i = TREE_CHAIN (i);
1068 if (i != NULL_TREE)
1069 m2pp_print (s, ";\n");
1070 }
1071 m2pp_print (s, ")");
1072 m2pp_needspace (s);
1073 setindent (s, o);
1074 }
1075 else if (returnType != void_type_node)
1076 {
1077 m2pp_print (s, "()");
1078 m2pp_needspace (s);
1079 }
1080 if (returnType != void_type_node)
1081 {
1082 m2pp_print (s, ": ");
1083 m2pp_simple_type (s, returnType);
1084 m2pp_needspace (s);
1085 }
1086 m2pp_print (s, "; ");
1087 m2pp_loc (s, t);
1088 m2pp_print (s, "\n");
1089 }
1090 pop ();
1091}
1092
1093/* m2pp_add_var adds a variable into a list as defined by, data. */
1094
1095static tree
1096m2pp_add_var (tree *tp, int *walk_subtrees, void *data)
1097{
1098 tree t = *tp;
1099 pretty *s = (pretty *)data;
1100 enum tree_code code = TREE_CODE (t);
1101
1102 if (code == VAR_DECL)
1103 {
1104 m2pp_var (s);
1105 m2pp_identifier (s, t);
1106 m2pp_needspace (s);
1107 m2pp_print (s, ":");
1108 m2pp_needspace (s);
1109 m2pp_type (s, TREE_TYPE (t));
1110 m2pp_needspace (s);
1111 m2pp_print (s, ";\n");
1112 }
1113 if (code == SSA_NAME)
1114 {
1115 m2pp_var (s);
1116 m2pp_ssa (s, t);
1117 m2pp_identifier (s, SSA_NAME_VAR (t));
1118 m2pp_needspace (s);
1119 m2pp_print (s, ":");
1120 m2pp_needspace (s);
1121 m2pp_type (s, TREE_TYPE (t));
1122 m2pp_needspace (s);
1123 m2pp_print (s, ";\n");
1124 }
1125
1126 *walk_subtrees = 1;
1127 return NULL_TREE;
1128}
1129
1130/* m2pp_function_vars displays variables as defined by the function
1131 tree. */
1132
1133static void
1134m2pp_function_vars (pretty *s, tree t)
1135{
1136 walk_tree_without_duplicates (&t, m2pp_add_var, s);
1137
1138 if (TREE_CODE (t) == FUNCTION_DECL && DECL_INITIAL (t))
1139 {
1140 m2pp_print (s, "(* variables in function_decl (decl_initial) *)\n");
1141 m2pp_var (s);
1142 m2pp_statement_sequence (s, DECL_INITIAL (t));
1143 }
1144}
1145
1146/* m2pp_print print out a string p interpreting '\n' and
1147 adjusting the fields within state s. */
1148
1149static void
1150m2pp_print (pretty *s, const char *p)
1151{
1152 if (p)
1153 {
1154 int l = strlen (p);
1155 int i = 0;
1156
1157 if (s->needs_space)
1158 {
1159 printf (" ");
1160 s->needs_space = FALSE;
1161 s->curpos++;
1162 }
1163
1164 while (i < l)
1165 {
1166 if (p[i] == '\n')
1167 {
1168 s->needs_indent = TRUE;
1169 s->curpos = 0;
1170 printf ("\n");
1171 }
1172 else
1173 {
1174 if (s->needs_indent)
1175 {
1176 if (s->indent > 0)
1177 printf ("%*c", s->indent, ' ');
1178 s->needs_indent = FALSE;
1179 s->curpos += s->indent;
1180 }
1181 s->curpos++;
1182 putchar (p[i]);
1183 }
1184 i++;
1185 }
1186 }
1187}
1188
1189/* m2pp_print_char prints out a character ch obeying needs_space
1190 and needs_indent. */
1191
1192static void
1193m2pp_print_char (pretty *s, char ch)
1194{
1195 if (s->needs_space)
1196 {
1197 printf (" ");
1198 s->needs_space = FALSE;
1199 s->curpos++;
1200 }
1201 if (s->needs_indent)
1202 {
1203 if (s->indent > 0)
1204 printf ("%*c", s->indent, ' ');
1205 s->needs_indent = FALSE;
1206 s->curpos += s->indent;
1207 }
1208 if (ch == '\n')
1209 {
1210 s->curpos++;
1211 putchar ('\\');
1212 putchar ('n');
1213 }
1214 else
1215 putchar (ch);
1216 s->curpos++;
1217}
1218
1219/* m2pp_integer display the appropriate integer type. */
1220
1221#if defined(GM2)
1222void
1223m2pp_integer (pretty *s, tree t)
1224{
1225 if (t == m2type_GetM2ZType ())
1226 m2pp_print (s, "M2ZTYPE");
1227 else if (t == m2type_GetM2LongIntType ())
1228 m2pp_print (s, "LONGINT");
1229 else if (t == m2type_GetM2IntegerType ())
1230 m2pp_print (s, "INTEGER");
1231 else if (t == m2type_GetM2ShortIntType ())
1232 m2pp_print (s, "SHORTINT");
1233 else if (t == m2type_GetLongIntType ())
1234 m2pp_print (s, "long int");
1235 else if (t == m2type_GetIntegerType ())
1236 m2pp_print (s, "int");
1237 else if (t == m2type_GetShortIntType ())
1238 m2pp_print (s, "short");
1239 else if (t == m2type_GetM2LongCardType ())
1240 m2pp_print (s, "LONGCARD");
1241 else if (t == m2type_GetM2CardinalType ())
1242 m2pp_print (s, "CARDINAL");
1243 else if (t == m2type_GetM2ShortCardType ())
1244 m2pp_print (s, "SHORTCARD");
1245 else if (t == m2type_GetCardinalType ())
1246 m2pp_print (s, "CARDINAL");
1247 else if (t == m2type_GetPointerType ())
1248 m2pp_print (s, "ADDRESS");
1249 else if (t == m2type_GetByteType ())
1250 m2pp_print (s, "BYTE");
1251 else if (t == m2type_GetCharType ())
1252 m2pp_print (s, "CHAR");
1253 else if (t == m2type_GetBitsetType ())
1254 m2pp_print (s, "BITSET");
1255 else if (t == m2type_GetBitnumType ())
1256 m2pp_print (s, "BITNUM");
1257 else
1258 {
1259 if (TYPE_UNSIGNED (t))
1260 m2pp_print (s, "CARDINAL");
1261 else
1262 m2pp_print (s, "INTEGER");
1263 m2pp_integer_cst (s, TYPE_SIZE (t));
1264 }
1265}
1266#else
1267void
1268m2pp_integer (pretty *s, tree t ATTRIBUTE_UNUSED)
1269{
1270 m2pp_print (s, "INTEGER");
1271}
1272#endif
1273
1274/* m2pp_complex display the actual complex type. */
1275
1276#if defined(GM2)
1277static void
1278m2pp_complex (pretty *s, tree t)
1279{
1280 if (t == m2type_GetM2ComplexType ())
1281 m2pp_print (s, "COMPLEX");
1282 else if (t == m2type_GetM2LongComplexType ())
1283 m2pp_print (s, "LONGCOMPLEX");
1284 else if (t == m2type_GetM2ShortComplexType ())
1285 m2pp_print (s, "SHORTCOMPLEX");
1286 else if (t == m2type_GetM2CType ())
1287 m2pp_print (s, "C'omplex' type");
1288 else if (t == m2type_GetM2Complex32 ())
1289 m2pp_print (s, "COMPLEX32");
1290 else if (t == m2type_GetM2Complex64 ())
1291 m2pp_print (s, "COMPLEX64");
1292 else if (t == m2type_GetM2Complex96 ())
1293 m2pp_print (s, "COMPLEX96");
1294 else if (t == m2type_GetM2Complex128 ())
1295 m2pp_print (s, "COMPLEX128");
1296 else
1297 m2pp_print (s, "unknown COMPLEX type");
1298}
1299
1300#else
1301
1302static void
1303m2pp_complex (pretty *s, tree t ATTRIBUTE_UNUSED)
1304{
1305 m2pp_print (s, "a COMPLEX type");
1306}
1307#endif
1308
1309/* m2pp_type prints a full type. */
1310
1311void
1312m2pp_type (pretty *s, tree t)
1313{
1314 if (begin_printed (t))
1315 {
1316 m2pp_print (s, "<...>");
1317 return;
1318 }
1319 if ((TREE_CODE (t) != FIELD_DECL) && (TREE_CODE (t) != TYPE_DECL))
1320 m2pp_gimpified (s, t);
1321 switch (TREE_CODE (t))
1322 {
1323 case INTEGER_TYPE:
1324 m2pp_integer (s, t);
1325 break;
1326 case REAL_TYPE:
1327 m2pp_print (s, "REAL");
1328 break;
1329 case ENUMERAL_TYPE:
1330 m2pp_enum (s, t);
1331 break;
1332 case UNION_TYPE:
1333 m2pp_union_type (s, t);
1334 break;
1335 case RECORD_TYPE:
1336 m2pp_record_type (s, t);
1337 break;
1338 case ARRAY_TYPE:
1339 m2pp_array (s, t);
1340 break;
1341#if 0
1342 case FUNCTION_TYPE:
1343 m2pp_function_type (s, t);
1344 break;
1345#endif
1346 case TYPE_DECL:
1347 m2pp_identifier (s, t);
1348 break;
1349 case POINTER_TYPE:
1350 m2pp_pointer_type (s, t);
1351 break;
1352#if defined(GM2)
1353 case SET_TYPE:
1354 m2pp_set_type (s, t);
1355 break;
1356#endif
1357 case VOID_TYPE:
1358 m2pp_print (s, "ADDRESS");
1359 break;
1360 case COMPLEX_TYPE:
1361 m2pp_complex (s, t);
1362 break;
1363 default:
1364 m2pp_unknown (s, __FUNCTION__, get_tree_code_name (TREE_CODE (t)));
1365 }
1366}
1367
1368/* m2pp_set_type prints out the set type. */
1369
1370static void
1371m2pp_set_type (pretty *s, tree t)
1372{
1373 push (t);
1374 m2pp_print (s, "SET OF");
1375 m2pp_needspace (s);
1376 m2pp_type (s, TREE_TYPE (t));
1377 pop ();
1378}
1379
1380/* m2pp_enum print out the enumeration type. */
1381
1382static void
1383m2pp_enum (pretty *s, tree t)
1384{
1385 tree chain_p = TYPE_VALUES (t);
1386
1387 push (t);
1388 m2pp_print (s, "(");
1389 while (chain_p)
1390 {
1391 m2pp_ident_pointer (s, TREE_PURPOSE (chain_p));
1392 chain_p = TREE_CHAIN (chain_p);
1393 if (chain_p)
1394 m2pp_print (s, ", ");
1395 }
1396 m2pp_print (s, ")");
1397 pop ();
1398}
1399
1400/* m2pp_array prints out the array type. */
1401
1402static void
1403m2pp_array (pretty *s, tree t)
1404{
1405 push (t);
1406 m2pp_print (s, "ARRAY");
1407 m2pp_needspace (s);
1408 m2pp_subrange (s, TYPE_DOMAIN (t));
1409 m2pp_needspace (s);
1410 m2pp_print (s, "OF");
1411 m2pp_needspace (s);
1412 m2pp_type (s, TREE_TYPE (t));
1413 pop ();
1414}
1415
1416/* m2pp_subrange prints out the subrange, but probably the lower
1417 bound will always be zero. */
1418
1419static void
1420m2pp_subrange (pretty *s, tree t)
1421{
1422 tree min = TYPE_MIN_VALUE (t);
1423 tree max = TYPE_MAX_VALUE (t);
1424
1425 m2pp_print (s, "[");
1426 m2pp_expression (s, min);
1427 m2pp_print (s, "..");
1428 m2pp_expression (s, max);
1429 m2pp_print (s, "]");
1430}
1431
1432/* m2pp_gimplified print out a gimplified comment. */
1433
1434static void
1435m2pp_gimpified (pretty *s, tree t)
1436{
1437 if (!TYPE_SIZES_GIMPLIFIED (t))
1438 {
1439 m2pp_print (s, "(* <!g> *)");
1440 m2pp_needspace (s);
1441 }
1442}
1443
1444/* m2pp_printer_type display the pointer type. */
1445
1446static void
1447m2pp_pointer_type (pretty *s, tree t)
1448{
1449 push (t);
1450 if (TREE_CODE (t) == POINTER_TYPE)
1451 {
1452 if (TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1453 m2pp_procedure_type (s, TREE_TYPE (t));
1454 else if (t == ptr_type_node)
1455 m2pp_print (s, "ADDRESS");
1456 else
1457 {
1458 m2pp_print (s, "POINTER TO");
1459 m2pp_needspace (s);
1460 m2pp_type (s, TREE_TYPE (t));
1461 }
1462 }
1463 pop ();
1464}
1465
1466/* m2pp_record_alignment prints out whether this record is aligned
1467 (packed). */
1468
1469static void
1470m2pp_record_alignment (pretty *s, tree t)
1471{
1472 if (TYPE_PACKED (t))
1473 m2pp_print (s, "<* bytealignment (0) *>\n");
1474}
1475
1476static unsigned int
1477m2pp_getaligned (tree t)
1478{
1479 if (DECL_P (t))
1480 {
1481 if (DECL_USER_ALIGN (t))
1482 return DECL_ALIGN (t);
1483 }
1484 else if (TYPE_P (t))
1485 {
1486 if (TYPE_USER_ALIGN (t))
1487 return TYPE_ALIGN (t);
1488 }
1489 return 0;
1490}
1491
1492static void
1493m2pp_recordfield_alignment (pretty *s, tree t)
1494{
1495 unsigned int aligned = m2pp_getaligned (t);
1496
1497 if (aligned != 0)
1498 {
1499 int o = getindent (s);
1500 int p = getcurpos (s);
1501 m2pp_needspace (s);
1502 m2pp_print (s, "<* bytealignment (");
1503 setindent (s, p + 18);
1504
1505 printf ("%d", aligned / BITS_PER_UNIT);
1506
1507 m2pp_print (s, ")");
1508 m2pp_needspace (s);
1509 setindent (s, p);
1510 m2pp_print (s, "*>");
1511 setindent (s, o);
1512 }
1513}
1514
1515static void
1516m2pp_recordfield_bitfield (pretty *s, tree t)
1517{
1518 if ((TREE_CODE (t) == FIELD_DECL) && DECL_PACKED (t))
1519 {
1520 m2pp_print (s, " (* packed");
1521 if (DECL_NONADDRESSABLE_P (t))
1522 m2pp_print (s, ", non-addressible");
1523 if (DECL_BIT_FIELD (t))
1524 m2pp_print (s, ", bit-field");
1525 m2pp_print (s, ", offset: ");
1526 m2pp_expression (s, DECL_FIELD_OFFSET (t));
1527 m2pp_print (s, ", bit offset:");
1528 m2pp_expression (s, DECL_FIELD_BIT_OFFSET (t));
1529 m2pp_print (s, " *) ");
1530 }
1531}
1532
1533/* m2pp_record_type displays the record type. */
1534
1535static void
1536m2pp_record_type (pretty *s, tree t)
1537{
1538 push (t);
1539 if (TREE_CODE (t) == RECORD_TYPE)
1540 {
1541 tree i;
1542 int o = getindent (s);
1543 int p = getcurpos (s);
1544
1545 m2pp_print (s, "RECORD\n");
1546 setindent (s, p + 3);
1547 m2pp_record_alignment (s, t);
1548 for (i = TYPE_FIELDS (t); i != NULL_TREE; i = TREE_CHAIN (i))
1549 {
1550 m2pp_identifier (s, i);
1551 m2pp_print (s, " : ");
1552 m2pp_type (s, TREE_TYPE (i));
1553 m2pp_recordfield_bitfield (s, i);
1554 m2pp_recordfield_alignment (s, i);
1555 m2pp_print (s, ";\n");
1556 }
1557 setindent (s, p);
1558 m2pp_print (s, "END");
1559 setindent (s, o);
1560 }
1561 pop ();
1562}
1563
1564/* m2pp_record_type displays the record type. */
1565
1566static void
1567m2pp_union_type (pretty *s, tree t)
1568{
1569 push (t);
1570 if (TREE_CODE (t) == UNION_TYPE)
1571 {
1572 tree i;
1573 int o = getindent (s);
1574 int p = getcurpos (s);
1575
1576 m2pp_print (s, "CASE .. OF\n");
1577 setindent (s, p + 3);
1578 m2pp_record_alignment (s, t);
1579 for (i = TYPE_FIELDS (t); i != NULL_TREE; i = TREE_CHAIN (i))
1580 {
1581 m2pp_identifier (s, i);
1582 m2pp_print (s, " : ");
1583 m2pp_type (s, TREE_TYPE (i));
1584 m2pp_recordfield_bitfield (s, i);
1585 m2pp_print (s, ";\n");
1586 }
1587 setindent (s, p);
1588 m2pp_print (s, "END");
1589 setindent (s, o);
1590 }
1591 pop ();
1592}
1593
1594/* m2pp_simple_type. */
1595
1596static void
1597m2pp_simple_type (pretty *s, tree t)
1598{
1599 if (begin_printed (t))
1600 {
1601 m2pp_print (s, "<...>");
1602 return;
1603 }
1604
1605 m2pp_gimpified (s, t);
1606 switch (TREE_CODE (t))
1607 {
1608 case INTEGER_TYPE:
1609 m2pp_integer (s, t);
1610 break;
1611 case REAL_TYPE:
1612 m2pp_print (s, "REAL");
1613 break;
1614 case BOOLEAN_TYPE:
1615 m2pp_print (s, "BOOLEAN");
1616 break;
1617 case VOID_TYPE:
1618 m2pp_print (s, "ADDRESS");
1619 break;
1620 case TYPE_DECL:
1621 m2pp_identifier (s, t);
1622 break;
1623 case POINTER_TYPE:
1624 m2pp_pointer_type (s, t);
1625 break;
1626 case RECORD_TYPE:
1627 m2pp_record_type (s, t);
1628 break;
1629 case UNION_TYPE:
1630 m2pp_union_type (s, t);
1631 break;
1632 case ENUMERAL_TYPE:
1633 m2pp_enum (s, t);
1634 break;
1635 case COMPLEX_TYPE:
1636 m2pp_complex (s, t);
1637 break;
1638 default:
1639 m2pp_unknown (s, __FUNCTION__, get_tree_code_name (TREE_CODE (t)));
1640 }
1641}
1642
1643/* m2pp_expression display an expression. */
1644
1645static void
1646m2pp_expression (pretty *s, tree t)
1647{
1648 enum tree_code code = TREE_CODE (t);
1649
1650 switch (code)
1651 {
1652 case EQ_EXPR:
1653 m2pp_relop (s, t, "=");
1654 break;
1655 case NE_EXPR:
1656 m2pp_relop (s, t, "#");
1657 break;
1658 case LE_EXPR:
1659 m2pp_relop (s, t, "<=");
1660 break;
1661 case GE_EXPR:
1662 m2pp_relop (s, t, ">=");
1663 break;
1664 case LT_EXPR:
1665 m2pp_relop (s, t, "<");
1666 break;
1667 case GT_EXPR:
1668 m2pp_relop (s, t, ">");
1669 break;
1670 default:
1671 m2pp_simple_expression (s, t);
1672 }
1673}
1674
1675/* m2pp_relop displays the lhs relop rhs. */
1676
1677static void
1678m2pp_relop (pretty *s, tree t, const char *p)
1679{
1680 m2pp_expression (s, TREE_OPERAND (t, 0));
1681 m2pp_needspace (s);
1682 m2pp_print (s, p);
1683 m2pp_needspace (s);
1684 m2pp_expression (s, TREE_OPERAND (t, 1));
1685}
1686
1687/* m2pp_compound_expression handle compound expression tree. */
1688
1689static void
1690m2pp_compound_expression (pretty *s, tree t)
1691{
1692 m2pp_print (s, "compound expression {");
1693 m2pp_expression (s, TREE_OPERAND (t, 0));
1694 m2pp_print (s, " (* result ignored *), ");
1695 m2pp_expression (s, TREE_OPERAND (t, 1));
1696 m2pp_print (s, "}");
1697 m2pp_needspace (s);
1698}
1699
1700/* m2pp_target_expression handle target expression tree. */
1701
1702static void
1703m2pp_target_expression (pretty *s, tree t)
1704{
1705 m2pp_print (s, "{");
1706 m2pp_needspace (s);
1707 if (TREE_OPERAND (t, 0) != NULL_TREE)
1708 {
1709 m2pp_print (s, "(* target *) ");
1710 m2pp_expression (s, TREE_OPERAND (t, 0));
1711 m2pp_print (s, ",");
1712 m2pp_needspace (s);
1713 }
1714 if (TREE_OPERAND (t, 1) != NULL_TREE)
1715 {
1716 m2pp_print (s, "(* initializer *) ");
1717 m2pp_expression (s, TREE_OPERAND (t, 1));
1718 m2pp_print (s, ",");
1719 m2pp_needspace (s);
1720 }
1721 if (TREE_OPERAND (t, 2) != NULL_TREE)
1722 {
1723 m2pp_print (s, "(* cleanup *) ");
1724 m2pp_expression (s, TREE_OPERAND (t, 2));
1725 m2pp_print (s, ",");
1726 m2pp_needspace (s);
1727 }
1728 if (TREE_OPERAND (t, 3) != NULL_TREE)
1729 {
1730 m2pp_print (s, "(* saved initializer *) ");
1731 m2pp_expression (s, TREE_OPERAND (t, 3));
1732 m2pp_print (s, ",");
1733 m2pp_needspace (s);
1734 }
1735 m2pp_print (s, "}");
1736 m2pp_needspace (s);
1737}
1738
1739/* m2pp_constructor print out a constructor. */
1740
1741static void
1742m2pp_constructor (pretty *s, tree t)
1743{
1744 tree purpose, value;
1745 unsigned HOST_WIDE_INT ix;
1746
1747 m2pp_print (s, "{ ");
1748 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), ix, purpose, value)
1749 {
1750 m2pp_print (s, "(index: ");
1751 m2pp_simple_expression (s, purpose);
1752 m2pp_print (s, ") ");
1753 m2pp_simple_expression (s, value);
1754 m2pp_print (s, ", ");
1755 }
1756 m2pp_print (s, "}");
1757 m2pp_print (s, "(* type: ");
1758 setindent (s, getindent (s) + 8);
1759 m2pp_type (s, TREE_TYPE (t));
1760 setindent (s, getindent (s) - 8);
1761 m2pp_print (s, " *)\n");
1762}
1763
1764/* m2pp_complex_expr handle GCC complex_expr tree. */
1765
1766static void
1767m2pp_complex_expr (pretty *s, tree t)
1768{
1769 if (TREE_CODE (t) == COMPLEX_CST)
1770 {
1771 m2pp_print (s, "CMPLX(");
1772 m2pp_needspace (s);
1773 m2pp_expression (s, TREE_REALPART (t));
1774 m2pp_print (s, ",");
1775 m2pp_needspace (s);
1776 m2pp_expression (s, TREE_IMAGPART (t));
1777 m2pp_print (s, ")");
1778 }
1779 else
1780 {
1781 m2pp_print (s, "CMPLX(");
1782 m2pp_needspace (s);
1783 m2pp_expression (s, TREE_OPERAND (t, 0));
1784 m2pp_print (s, ",");
1785 m2pp_needspace (s);
1786 m2pp_expression (s, TREE_OPERAND (t, 1));
1787 m2pp_print (s, ")");
1788 }
1789}
1790
1791/* m2pp_imagpart_expr handle imagpart_expr tree. */
1792
1793static void
1794m2pp_imagpart_expr (pretty *s, tree t)
1795{
1796 m2pp_print (s, "IM(");
1797 m2pp_needspace (s);
1798 if (TREE_CODE (t) == IMAGPART_EXPR)
1799 m2pp_expression (s, TREE_OPERAND (t, 0));
1800 else if (TREE_CODE (t) == COMPLEX_CST)
1801 m2pp_expression (s, TREE_IMAGPART (t));
1802 m2pp_needspace (s);
1803 m2pp_print (s, ")");
1804}
1805
1806/* m2pp_realpart_expr handle imagpart_expr tree. */
1807
1808static void
1809m2pp_realpart_expr (pretty *s, tree t)
1810{
1811 m2pp_print (s, "RE(");
1812 m2pp_needspace (s);
1813 if (TREE_CODE (t) == REALPART_EXPR)
1814 m2pp_expression (s, TREE_OPERAND (t, 0));
1815 else if (TREE_CODE (t) == COMPLEX_CST)
1816 m2pp_expression (s, TREE_REALPART (t));
1817 m2pp_needspace (s);
1818 m2pp_print (s, ")");
1819}
1820
1821/* m2pp_bit_ior_expr generate a C style bit or. */
1822
1823static void
1824m2pp_bit_ior_expr (pretty *s, tree t)
1825{
1826 m2pp_binary (s, t, "|");
1827}
1828
1829/* m2pp_truth_expr. */
1830
1831static void
1832m2pp_truth_expr (pretty *s, tree t, const char *op)
1833{
1834 m2pp_print (s, "(");
1835 m2pp_expression (s, TREE_OPERAND (t, 0));
1836 m2pp_print (s, ")");
1837 m2pp_needspace (s);
1838 m2pp_print (s, op);
1839 m2pp_needspace (s);
1840 m2pp_print (s, "(");
1841 m2pp_expression (s, TREE_OPERAND (t, 1));
1842 m2pp_print (s, ")");
1843}
1844
1845/* m2pp_simple_expression handle GCC expression tree. */
1846
1847static void
1848m2pp_simple_expression (pretty *s, tree t)
1849{
1850 enum tree_code code = TREE_CODE (t);
1851
1852 switch (code)
1853 {
1854 case ERROR_MARK:
1855 m2pp_print (s, "(* !!! ERROR NODE !!! *)");
1856 break;
1857 case CONSTRUCTOR:
1858 m2pp_constructor (s, t);
1859 break;
1860 case IDENTIFIER_NODE:
1861 m2pp_ident_pointer (s, t);
1862 break;
1863 case PARM_DECL:
1864 m2pp_identifier (s, t);
1865 break;
1866 case FIELD_DECL:
1867 m2pp_identifier (s, t);
1868 break;
1869 case TREE_LIST:
1870 m2pp_list (s, t);
1871 break;
1872 case BLOCK:
1873 m2pp_print (s, "(* BLOCK NODE *)");
1874 break;
1875 case OFFSET_TYPE:
1876 m2pp_offset (s, t);
1877 break;
1878 case INTEGER_CST:
1879 m2pp_integer_cst (s, t);
1880 break;
1881 case REAL_CST:
1882 m2pp_real_cst (s, t);
1883 break;
1884 case STRING_CST:
1885 m2pp_string_cst (s, t);
1886 break;
1887 case INDIRECT_REF:
1888 m2pp_indirect_ref (s, t);
1889 break;
1890 case ADDR_EXPR:
1891 m2pp_addr_expr (s, t);
1892 break;
1893 case NOP_EXPR:
1894 m2pp_nop (s, t);
1895 break;
1896 case CONVERT_EXPR:
1897 m2pp_convert (s, t);
1898 break;
1899 case VAR_DECL:
1900 m2pp_var_decl (s, t);
1901 break;
1902 case RESULT_DECL:
1903 m2pp_result_decl (s, t);
1904 break;
1905 case PLUS_EXPR:
1906 m2pp_binary (s, t, "+");
1907 break;
1908 case MINUS_EXPR:
1909 m2pp_binary (s, t, "-");
1910 break;
1911 case MULT_EXPR:
1912 m2pp_binary (s, t, "*");
1913 break;
1914 case FLOOR_DIV_EXPR:
1915 case CEIL_DIV_EXPR:
1916 case TRUNC_DIV_EXPR:
1917 case ROUND_DIV_EXPR:
1918 m2pp_binary (s, t, "DIV");
1919 break;
1920 case FLOOR_MOD_EXPR:
1921 case CEIL_MOD_EXPR:
1922 case TRUNC_MOD_EXPR:
1923 case ROUND_MOD_EXPR:
1924 m2pp_binary (s, t, "MOD");
1925 break;
1926 case NEGATE_EXPR:
1927 m2pp_unary (s, t, "-");
1928 break;
1929 case CALL_EXPR:
1930 m2pp_call_expr (s, t);
1931 break;
1932 case SSA_NAME:
1933 m2pp_ssa (s, t);
1934 break;
1935 case COMPONENT_REF:
1936 m2pp_component_ref (s, t);
1937 break;
1938 case RETURN_EXPR:
1939 m2pp_return_expr (s, t);
1940 break;
1941 case ARRAY_REF:
1942 m2pp_array_ref (s, t);
1943 break;
1944 case NON_LVALUE_EXPR:
1945 m2pp_non_lvalue_expr (s, t);
1946 break;
1947 case EXPR_STMT:
1948 m2pp_expression (s, EXPR_STMT_EXPR (t));
1949 break;
1950#if 0
1951 case EXC_PTR_EXPR:
1952 m2pp_print (s, "GCC_EXCEPTION_OBJECT");
1953 break;
1954#endif
1955 case INIT_EXPR:
1956 case MODIFY_EXPR:
1957 m2pp_assignment (s, t);
1958 break;
1959 case COMPOUND_EXPR:
1960 m2pp_compound_expression (s, t);
1961 break;
1962 case TARGET_EXPR:
1963 m2pp_target_expression (s, t);
1964 break;
1965 case THROW_EXPR:
1966 m2pp_throw (s, t);
1967 break;
1968 case FUNCTION_DECL:
1969 m2pp_identifier (s, t);
1970 break;
1971 case COMPLEX_EXPR:
1972 m2pp_complex_expr (s, t);
1973 break;
1974 case REALPART_EXPR:
1975 m2pp_realpart_expr (s, t);
1976 break;
1977 case IMAGPART_EXPR:
1978 m2pp_imagpart_expr (s, t);
1979 break;
1980 case CONST_DECL:
1981 m2pp_identifier (s, t);
1982 break;
1983 case POINTER_PLUS_EXPR:
1984 m2pp_binary (s, t, "+");
1985 break;
1986 case CLEANUP_POINT_EXPR:
1987 m2pp_cleanup_point_expr (s, t);
1988 break;
1989 case BIT_IOR_EXPR:
1990 m2pp_bit_ior_expr (s, t);
1991 break;
1992 case TRUTH_ANDIF_EXPR:
1993 m2pp_truth_expr (s, t, "AND");
1994 break;
1995 case TRUTH_ORIF_EXPR:
1996 m2pp_truth_expr (s, t, "OR");
1997 break;
1998 default:
1999 m2pp_unknown (s, __FUNCTION__, get_tree_code_name (code));
2000 }
2001}
2002
2003/* non_lvalue_expr indicates that operand 0 is not an lvalue. */
2004
2005static void
2006m2pp_non_lvalue_expr (pretty *s, tree t)
2007{
2008 m2pp_needspace (s);
2009 m2pp_print (s, "assert_non_lvalue(");
2010 m2pp_needspace (s);
2011 m2pp_expression (s, TREE_OPERAND (t, 0));
2012 m2pp_needspace (s);
2013 m2pp_print (s, ")");
2014}
2015
2016/* m2pp_array_ref prints out the array reference. */
2017
2018static void
2019m2pp_array_ref (pretty *s, tree t)
2020{
2021 m2pp_expression (s, TREE_OPERAND (t, 0));
2022 m2pp_print (s, "[");
2023 m2pp_expression (s, TREE_OPERAND (t, 1));
2024 m2pp_print (s, "]");
2025}
2026
2027/* m2pp_ssa prints out the ssa variable name. */
2028
2029static void
2030m2pp_ssa (pretty *s, tree t)
2031{
2032 m2pp_identifier (s, SSA_NAME_VAR (t));
2033}
2034
2035/* m2pp_binary print the binary operator, p, and lhs, rhs. */
2036
2037static void
2038m2pp_binary (pretty *s, tree t, const char *p)
2039{
2040 tree left = TREE_OPERAND (t, 0);
2041 tree right = TREE_OPERAND (t, 1);
2042
2043 m2pp_expression (s, left);
2044 m2pp_needspace (s);
2045 m2pp_print (s, p);
2046 m2pp_needspace (s);
2047 m2pp_expression (s, right);
2048}
2049
2050/* m2pp_unary print the unary operator, p, and expression. */
2051
2052static void
2053m2pp_unary (pretty *s, tree t, const char *p)
2054{
2055 tree expr = TREE_OPERAND (t, 0);
2056
2057 m2pp_needspace (s);
2058 m2pp_print (s, p);
2059 m2pp_expression (s, expr);
2060}
2061
2062/* m2pp_integer_cst displays the integer constant. */
2063
2064static void
2065m2pp_integer_cst (pretty *s, tree t)
2066{
2067 char val[100];
2068
2069 snprintf (val, 100, "%lud", TREE_INT_CST_LOW (t));
2070 m2pp_print (s, val);
2071}
2072
2073/* m2pp_real_cst displays the real constant. */
2074
2075static void
2076m2pp_real_cst (pretty *s, tree t ATTRIBUTE_UNUSED)
2077{
2078 m2pp_print (s, "<unknown real>");
2079}
2080
2081/* m2pp_string_cst displays the real constant. */
2082
2083static void
2084m2pp_string_cst (pretty *s, tree t)
2085{
2086 const char *p = TREE_STRING_POINTER (t);
2087 int i = 0;
2088
2089 m2pp_print (s, "\"");
2090 while (p[i] != '\0')
2091 {
2092 m2pp_print_char (s, p[i]);
2093 i++;
2094 }
2095 m2pp_print (s, "\"");
2096}
2097
2098/* m2pp_statement_sequence iterates over a statement list
2099 displaying each statement in turn. */
2100
2101static void
2102m2pp_statement_sequence (pretty *s, tree t)
2103{
2104 if (t != NULL_TREE)
2105 {
2106 if (TREE_CODE (t) == STATEMENT_LIST)
2107 {
2108 tree_stmt_iterator i;
2109 m2pp_print (s, "(* statement list *)\n");
2110
2111 for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
2112 m2pp_statement (s, *tsi_stmt_ptr (i));
2113 }
2114 else
2115 m2pp_statement (s, t);
2116 }
2117}
2118
2119/* m2pp_unknown displays an error message. */
2120
2121static void
2122m2pp_unknown (pretty *s, const char *s1, const char *s2)
2123{
2124 m2pp_begin (s);
2125 m2pp_print (s, s1);
2126 m2pp_needspace (s);
2127 m2pp_print (s, s2);
2128 m2pp_needspace (s);
2129}
2130
2131/* m2pp_throw displays a throw statement. */
2132
2133static void
2134m2pp_throw (pretty *s, tree t)
2135{
2136 tree expr = TREE_OPERAND (t, 0);
2137
2138 m2pp_begin (s);
2139 if (expr == NULL_TREE)
2140 m2pp_print (s, "THROW ;\n");
2141 else
2142 {
2143 m2pp_print (s, "THROW (");
2144 m2pp_expression (s, TREE_OPERAND (t, 0));
2145 m2pp_print (s, ")\n");
2146 }
2147}
2148
2149/* m2pp_catch_expr attempts to reconstruct a catch expr. */
2150
2151static void
2152m2pp_catch_expr (pretty *s, tree t)
2153{
2154 tree types = CATCH_TYPES (t);
2155 tree body = CATCH_BODY (t);
2156
2157 m2pp_print (s, "(* CATCH expression ");
2158 if (types != NULL_TREE)
2159 {
2160 m2pp_print (s, "(");
2161 m2pp_expression (s, types);
2162 m2pp_print (s, ")");
2163 }
2164 m2pp_print (s, "*)\n");
2165 m2pp_print (s, "(* catch body *)\n");
2166 m2pp_statement_sequence (s, body);
2167 m2pp_print (s, "(* end catch body *)\n");
2168}
2169
2170/* m2pp_try_finally_expr attemts to reconstruct a try finally expr. */
2171
2172static void
2173m2pp_try_finally_expr (pretty *s, tree t)
2174{
2175 m2pp_begin (s);
2176 m2pp_print (s, "(* try_finally_expr *)\n");
2177 setindent (s, getindent (s) + 3);
2178 m2pp_statement_sequence (s, TREE_OPERAND (t, 0));
2179 setindent (s, getindent (s) - 3);
2180 m2pp_print (s,
2181 "(* finally (cleanup which is executed after the above) *)\n");
2182 setindent (s, getindent (s) + 3);
2183 m2pp_statement_sequence (s, TREE_OPERAND (t, 1));
2184 setindent (s, getindent (s) - 3);
2185 m2pp_print (s, "(* end try_finally_expr *)\n");
2186}
2187
2188#if !defined(GM2)
2189/* m2pp_if_stmt pretty print a C++ if_stmt. */
2190
2191static void
2192m2pp_if_stmt (pretty *s, tree t)
2193{
2194 m2pp_print (s, "(* only C++ uses if_stmt nodes *)\n");
2195 m2pp_print (s, "IF ");
2196 m2pp_expression (s, TREE_OPERAND (t, 0));
2197 m2pp_print (s, "\n");
2198 m2pp_print (s, "THEN\n");
2199 setindent (s, getindent (s) + 3);
2200 m2pp_statement_sequence (s, TREE_OPERAND (t, 1));
2201 setindent (s, getindent (s) - 3);
2202 m2pp_print (s, "ELSE\n");
2203 setindent (s, getindent (s) + 3);
2204 m2pp_statement_sequence (s, TREE_OPERAND (t, 2));
2205 setindent (s, getindent (s) - 3);
2206 m2pp_print (s, "END\n");
2207}
2208#endif
2209
2210/* m2pp_statement attempts to reconstruct a statement. */
2211
2212static void
2213m2pp_statement (pretty *s, tree t)
2214{
2215 enum tree_code code = TREE_CODE (t);
2216
2217 m2pp_loc (s, t);
2218 switch (code)
2219 {
2220 case COND_EXPR:
2221 m2pp_conditional (s, t);
2222 break;
2223 case LABEL_EXPR:
2224 m2pp_label_expr (s, t);
2225 break;
2226 case LABEL_DECL:
2227 m2pp_label_decl (s, t);
2228 break;
2229 case GOTO_EXPR:
2230 m2pp_goto (s, t);
2231 break;
2232 case INIT_EXPR:
2233 case MODIFY_EXPR:
2234 m2pp_assignment (s, t);
2235 break;
2236 case CALL_EXPR:
2237 m2pp_procedure_call (s, t);
2238 break;
2239 case BLOCK:
2240 m2pp_block_list (s, t);
2241 break;
2242 case BIND_EXPR:
2243 m2pp_bind_expr (s, t);
2244 break;
2245 case RETURN_EXPR:
2246 m2pp_return_expr (s, t);
2247 break;
2248 case DECL_EXPR:
2249 m2pp_decl_expr (s, t);
2250 break;
2251 case TRY_BLOCK:
2252 m2pp_try_block (s, t);
2253 break;
2254 case HANDLER:
2255 m2pp_handler (s, t);
2256 break;
2257 case CLEANUP_POINT_EXPR:
2258 m2pp_cleanup_point_expr (s, t);
2259 break;
2260 case THROW_EXPR:
2261 m2pp_throw (s, t);
2262 break;
2263 case TRY_CATCH_EXPR:
2264 m2pp_try_catch_expr (s, t);
2265 break;
2266 case TRY_FINALLY_EXPR:
2267 m2pp_try_finally_expr (s, t);
2268 break;
2269 case CATCH_EXPR:
2270 m2pp_catch_expr (s, t);
2271 break;
2272#if defined(CPP)
2273 case IF_STMT:
2274 m2pp_if_stmt (s, t);
2275 break;
2276#endif
2277 case ERROR_MARK:
2278 m2pp_print (s, "<ERROR CODE>\n");
2279 break;
2280 default:
2281 m2pp_unknown (s, __FUNCTION__, get_tree_code_name (TREE_CODE (t)));
2282 }
2283}
2284
2285/* m2pp_try_catch_expr is used after gimplification. */
2286
2287static void
2288m2pp_try_catch_expr (pretty *s, tree t)
2289{
2290 m2pp_print (s, "(* try_catch_expr begins *)\n");
2291 m2pp_statement_sequence (s, TREE_OPERAND (t, 0));
2292 setindent (s, 0);
2293 m2pp_print (s, "EXCEPT\n");
2294 setindent (s, 3);
2295 m2pp_statement_sequence (s, TREE_OPERAND (t, 1));
2296 m2pp_print (s, "(* try_catch_expr ends *)\n");
2297}
2298
2299/* m2pp_cleanup_point_expr emits a comment indicating a GCC
2300 cleanup_point_expr is present. */
2301
2302static void
2303m2pp_cleanup_point_expr (pretty *s, tree t)
2304{
2305 m2pp_begin (s);
2306 m2pp_print (s, "(* cleanup point begins *)\n");
2307 m2pp_expression (s, TREE_OPERAND (t, 0));
2308 m2pp_print (s, "(* cleanup point ends *)\n");
2309}
2310
2311/* m2pp_decl_expr displays a local declaration. */
2312
2313static void
2314m2pp_decl_expr (pretty *s, tree t)
2315{
2316 m2pp_var (s);
2317 m2pp_print (s, "(* variable in decl_expr *)\n");
2318 m2pp_var_type_decl (s, DECL_EXPR_DECL (t));
2319}
2320
2321/* m2pp_procedure_call print a call to a procedure. */
2322
2323static void
2324m2pp_procedure_call (pretty *s, tree t)
2325{
2326 m2pp_begin (s);
2327 m2pp_call_expr (s, t);
2328 m2pp_needspace (s);
2329 m2pp_print (s, ";\n");
2330}
2331
2332/* args displays each argument in an iter list by calling expression. */
2333
2334static void
2335m2pp_args (pretty *s, tree e)
2336{
2337 call_expr_arg_iterator iter;
2338 tree arg;
2339
2340 m2pp_print (s, "(");
2341 m2pp_needspace (s);
2342 FOR_EACH_CALL_EXPR_ARG (arg, iter, e)
2343 {
2344 m2pp_expression (s, arg);
2345 if (more_call_expr_args_p (&iter))
2346 {
2347 m2pp_print (s, ",");
2348 m2pp_needspace (s);
2349 }
2350 }
2351 m2pp_print (s, ")");
2352}
2353
2354/* m2pp_call_expr print a call to a procedure or function. */
2355
2356static void
2357m2pp_call_expr (pretty *s, tree t)
2358{
2359 tree call = CALL_EXPR_FN (t);
2360 tree args = TREE_OPERAND (t, 1);
2361 tree type = TREE_TYPE (t);
2362 int has_return_type = TRUE;
2363 tree proc;
2364
2365 if (type && (TREE_CODE (type) == VOID_TYPE))
2366 has_return_type = FALSE;
2367
2368 if (TREE_CODE (call) == ADDR_EXPR || TREE_CODE (call) == NON_LVALUE_EXPR)
2369 proc = TREE_OPERAND (call, 0);
2370 else
2371 proc = call;
2372
2373 m2pp_expression (s, proc);
2374 if (args || has_return_type)
2375 m2pp_args (s, t);
2376}
2377
2378/* m2pp_return_expr displays the return statement. */
2379
2380static void
2381m2pp_return_expr (pretty *s, tree t)
2382{
2383 tree e = TREE_OPERAND (t, 0);
2384
2385 m2pp_begin (s);
2386 if (e == NULL_TREE)
2387 {
2388 m2pp_print (s, "RETURN");
2389 }
2390 else if (TREE_CODE (e) == MODIFY_EXPR || (TREE_CODE (e) == INIT_EXPR))
2391 {
2392 m2pp_assignment (s, e);
2393 m2pp_print (s, "RETURN");
2394 m2pp_needspace (s);
2395 m2pp_expression (s, TREE_OPERAND (e, 0));
2396 }
2397 else
2398 {
2399 m2pp_print (s, "RETURN");
2400 m2pp_needspace (s);
2401 m2pp_expression (s, e);
2402 }
2403 m2pp_needspace (s);
2404 m2pp_print (s, ";\n");
2405}
2406
2407/* m2pp_try_block displays the try block. */
2408
2409static void
2410m2pp_try_block (pretty *s, tree t)
2411{
2412 tree stmts = TRY_STMTS (t);
2413 tree handlers = TRY_HANDLERS (t);
2414
2415 m2pp_begin (s);
2416 m2pp_print (s, "(* TRY *)\n");
2417 m2pp_statement_sequence (s, stmts);
2418 setindent (s, 0);
2419 m2pp_print (s, "EXCEPT\n");
2420 setindent (s, 3);
2421 m2pp_statement_sequence (s, handlers);
2422 m2pp_print (s, "(* END TRY *)\n");
2423}
2424
2425/* m2pp_try_block displays the handler block. */
2426
2427static void
2428m2pp_handler (pretty *s, tree t)
2429{
2430 tree parms = HANDLER_PARMS (t);
2431 tree body = HANDLER_BODY (t);
2432 tree type = HANDLER_TYPE (t);
2433
2434 m2pp_print (s, "(* handler *)\n");
2435 if (parms != NULL_TREE)
2436 {
2437 m2pp_print (s, "(* handler parameter has a type (should be NULL_TREE) "
2438 "in Modula-2 *)\n");
2439 m2pp_print (s, "CATCH (");
2440 m2pp_expression (s, parms);
2441 m2pp_print (s, ")\n");
2442 }
2443 if (type != NULL_TREE)
2444 m2pp_print (s, "(* handler type (should be NULL_TREE) in Modula-2 *)\n");
2445 m2pp_statement_sequence (s, body);
2446}
2447
2448/* m2pp_assignment prints out the assignment statement. */
2449
2450static void
2451m2pp_assignment (pretty *s, tree t)
2452{
2453 int o;
2454
2455 m2pp_begin (s);
2456 m2pp_designator (s, TREE_OPERAND (t, 0));
2457 m2pp_needspace (s);
2458 m2pp_print (s, ":=");
2459 m2pp_needspace (s);
2460 o = getindent (s);
2461 setindent (s, getcurpos (s) + 1);
2462 m2pp_expression (s, TREE_OPERAND (t, 1));
2463 m2pp_needspace (s);
2464 m2pp_print (s, ";\n");
2465 setindent (s, o);
2466}
2467
2468/* m2pp_designator displays the lhs of an assignment. */
2469
2470static void
2471m2pp_designator (pretty *s, tree t)
2472{
2473 m2pp_expression (s, t);
2474}
2475
2476/* m2pp_indirect_ref displays the indirect operator. */
2477
2478static void
2479m2pp_indirect_ref (pretty *s, tree t)
2480{
2481 m2pp_print (s, "(");
2482 m2pp_expression (s, TREE_OPERAND (t, 0));
2483 m2pp_print (s, ")^");
2484}
2485
2486/* m2pp_conditional builds an IF THEN ELSE END. With more work
2487 this should be moved into statement sequence which could look for
2488 repeat and while loops. */
2489
2490static void
2491m2pp_conditional (pretty *s, tree t)
2492{
2493 int o;
2494
2495 m2pp_begin (s);
2496 m2pp_print (s, "IF");
2497 m2pp_needspace (s);
2498 m2pp_expression (s, TREE_OPERAND (t, 0));
2499 m2pp_print (s, "\nTHEN\n");
2500 o = getindent (s);
2501 setindent (s, o + 3);
2502 m2pp_statement_sequence (s, TREE_OPERAND (t, 1));
2503 setindent (s, o);
2504 if (TREE_OPERAND (t, 2) != NULL_TREE)
2505 {
2506 m2pp_print (s, "ELSE\n");
2507 setindent (s, o + 3);
2508 m2pp_statement_sequence (s, TREE_OPERAND (t, 2));
2509 setindent (s, o);
2510 }
2511 m2pp_print (s, "END ;\n");
2512}
2513
2514/* m2pp_label_decl displays a label. Again should be moved into
2515 statement sequence to determine proper loop constructs. */
2516
2517static void
2518m2pp_label_decl (pretty *s, tree t)
2519{
2520 m2pp_begin (s);
2521 m2pp_print (s, "(* label ");
2522 m2pp_identifier (s, t);
2523 m2pp_print (s, ": *)\n");
2524}
2525
2526/* m2pp_label_expr skips the LABEL_EXPR to find the LABEL_DECL. */
2527
2528static void
2529m2pp_label_expr (pretty *s, tree t)
2530{
2531 m2pp_begin (s);
2532 m2pp_statement (s, TREE_OPERAND (t, 0));
2533}
2534
2535/* m2pp_goto displays a goto statement. Again should be moved into
2536 statement sequence to determine proper loop constructs. */
2537
2538static void
2539m2pp_goto (pretty *s, tree t)
2540{
2541 m2pp_begin (s);
2542 m2pp_print (s, "(* goto ");
2543 m2pp_identifier (s, TREE_OPERAND (t, 0));
2544 m2pp_print (s, " *)\n");
2545}
2546
2547/* m2pp_list prints a TREE_CHAINed list. */
2548
2549static void
2550m2pp_list (pretty *s, tree t)
2551{
2552 tree u = t;
2553
2554 m2pp_print (s, "(");
2555 m2pp_needspace (s);
2556 while (t != NULL_TREE)
2557 {
2558 m2pp_expression (s, TREE_VALUE (t));
2559 t = TREE_CHAIN (t);
2560 if (t == u || t == NULL_TREE)
2561 break;
2562 m2pp_print (s, ",");
2563 m2pp_needspace (s);
2564 }
2565 m2pp_needspace (s);
2566 m2pp_print (s, ")");
2567}
2568
2569/* m2pp_offset displays the offset operator. */
2570
2571static void
2572m2pp_offset (pretty *s, tree t)
2573{
2574 tree type = TREE_TYPE (t);
2575 tree base = TYPE_OFFSET_BASETYPE (t);
2576
2577 m2pp_print (s, "OFFSET (");
2578 m2pp_type (s, base);
2579 m2pp_print (s, ".");
2580 m2pp_type (s, type);
2581 m2pp_print (s, ")");
2582}
2583
2584/* m2pp_addr_expr create an ADR expression. */
2585
2586static void
2587m2pp_addr_expr (pretty *s, tree t)
2588{
2589 m2pp_needspace (s);
2590 m2pp_print (s, "ADR (");
2591 m2pp_expression (s, TREE_OPERAND (t, 0));
2592 m2pp_print (s, ")");
2593}
2594
2595/* m2pp_nop generate a CAST expression. */
2596
2597static void
2598m2pp_nop (pretty *s, tree t)
2599{
2600 m2pp_needspace (s);
2601 m2pp_print (s, "CAST (");
2602 m2pp_simple_type (s, TREE_TYPE (t));
2603 m2pp_print (s, ", ");
2604 m2pp_expression (s, TREE_OPERAND (t, 0));
2605 m2pp_print (s, ")");
2606}
2607
2608/* m2pp_convert generate a CONVERT expression. */
2609
2610static void
2611m2pp_convert (pretty *s, tree t)
2612{
2613 m2pp_needspace (s);
2614 m2pp_print (s, "CONVERT (");
2615 m2pp_simple_type (s, TREE_TYPE (t));
2616 m2pp_print (s, ", ");
2617 m2pp_expression (s, TREE_OPERAND (t, 0));
2618 m2pp_print (s, ")");
2619}
2620
2621/* m2pp_var_decl generate a variable. */
2622
2623static void
2624m2pp_var_decl (pretty *s, tree t)
2625{
2626 m2pp_identifier (s, t);
2627}
2628
2629/* m2pp_result_decl generate a result declaration (variable). */
2630
2631static void
2632m2pp_result_decl (pretty *s, tree t)
2633{
2634 m2pp_identifier (s, t);
2635}
2636
2637/* m2pp_component_ref generate a record field access. */
2638
2639static void
2640m2pp_component_ref (pretty *s, tree t)
2641{
2642 m2pp_simple_expression (s, TREE_OPERAND (t, 0));
2643 m2pp_print (s, ".");
2644 m2pp_simple_expression (s, TREE_OPERAND (t, 1));
2645}
2646
2647}