OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [tree-pretty-print.c] - Blame information for rev 16

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
/* Pretty formatting of GENERIC trees in C syntax.
2
   Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3
   Adapted from c-pretty-print.c by Diego Novillo <dnovillo@redhat.com>
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify it under
8
the terms of the GNU General Public License as published by the Free
9
Software Foundation; either version 2, or (at your option) any later
10
version.
11
 
12
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13
WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING.  If not, write to the Free
19
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20
02110-1301, USA.  */
21
 
22
#include "config.h"
23
#include "system.h"
24
#include "coretypes.h"
25
#include "tm.h"
26
#include "tree.h"
27
#include "diagnostic.h"
28
#include "real.h"
29
#include "hashtab.h"
30
#include "tree-flow.h"
31
#include "langhooks.h"
32
#include "tree-iterator.h"
33
#include "tree-chrec.h"
34
#include "tree-pass.h"
35
 
36
/* Local functions, macros and variables.  */
37
static int op_prio (tree);
38
static const char *op_symbol (tree);
39
static void pretty_print_string (pretty_printer *, const char*);
40
static void print_call_name (pretty_printer *, tree);
41
static void newline_and_indent (pretty_printer *, int);
42
static void maybe_init_pretty_print (FILE *);
43
static void print_declaration (pretty_printer *, tree, int, int);
44
static void print_struct_decl (pretty_printer *, tree, int, int);
45
static void do_niy (pretty_printer *, tree);
46
static void dump_vops (pretty_printer *, tree, int, int);
47
static void dump_generic_bb_buff (pretty_printer *, basic_block, int, int);
48
 
49
#define INDENT(SPACE) do { \
50
  int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
51
 
52
#define NIY do_niy(buffer,node)
53
 
54
#define PRINT_FUNCTION_NAME(NODE)  pp_printf             \
55
  (buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ?              \
56
   lang_hooks.decl_printable_name (TREE_OPERAND (NODE, 0), 1) : \
57
   lang_hooks.decl_printable_name (NODE, 1))
58
 
59
static pretty_printer buffer;
60
static int initialized = 0;
61
static bool dumping_stmts;
62
 
63
/* Try to print something for an unknown tree code.  */
64
 
65
static void
66
do_niy (pretty_printer *buffer, tree node)
67
{
68
  int i, len;
69
 
70
  pp_string (buffer, "<<< Unknown tree: ");
71
  pp_string (buffer, tree_code_name[(int) TREE_CODE (node)]);
72
 
73
  if (EXPR_P (node))
74
    {
75
      len = TREE_CODE_LENGTH (TREE_CODE (node));
76
      for (i = 0; i < len; ++i)
77
        {
78
          newline_and_indent (buffer, 2);
79
          dump_generic_node (buffer, TREE_OPERAND (node, i), 2, 0, false);
80
        }
81
    }
82
 
83
  pp_string (buffer, " >>>\n");
84
}
85
 
86
void
87
debug_generic_expr (tree t)
88
{
89
  print_generic_expr (stderr, t, TDF_VOPS|TDF_UID);
90
  fprintf (stderr, "\n");
91
}
92
 
93
void
94
debug_generic_stmt (tree t)
95
{
96
  print_generic_stmt (stderr, t, TDF_VOPS|TDF_UID);
97
  fprintf (stderr, "\n");
98
}
99
 
100
/* Prints declaration DECL to the FILE with details specified by FLAGS.  */
101
void
102
print_generic_decl (FILE *file, tree decl, int flags)
103
{
104
  maybe_init_pretty_print (file);
105
  dumping_stmts = true;
106
  print_declaration (&buffer, decl, 2, flags);
107
  pp_write_text_to_stream (&buffer);
108
}
109
 
110
/* Print tree T, and its successors, on file FILE.  FLAGS specifies details
111
   to show in the dump.  See TDF_* in tree.h.  */
112
 
113
void
114
print_generic_stmt (FILE *file, tree t, int flags)
115
{
116
  maybe_init_pretty_print (file);
117
  dumping_stmts = true;
118
  dump_generic_node (&buffer, t, 0, flags, true);
119
  pp_flush (&buffer);
120
}
121
 
122
/* Print tree T, and its successors, on file FILE.  FLAGS specifies details
123
   to show in the dump.  See TDF_* in tree.h.  The output is indented by
124
   INDENT spaces.  */
125
 
126
void
127
print_generic_stmt_indented (FILE *file, tree t, int flags, int indent)
128
{
129
  int i;
130
 
131
  maybe_init_pretty_print (file);
132
  dumping_stmts = true;
133
 
134
  for (i = 0; i < indent; i++)
135
    pp_space (&buffer);
136
  dump_generic_node (&buffer, t, indent, flags, true);
137
  pp_flush (&buffer);
138
}
139
 
140
/* Print a single expression T on file FILE.  FLAGS specifies details to show
141
   in the dump.  See TDF_* in tree.h.  */
142
 
143
void
144
print_generic_expr (FILE *file, tree t, int flags)
145
{
146
  maybe_init_pretty_print (file);
147
  dumping_stmts = false;
148
  dump_generic_node (&buffer, t, 0, flags, false);
149
}
150
 
151
/* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set
152
   in FLAGS.  */
153
 
154
static void
155
dump_decl_name (pretty_printer *buffer, tree node, int flags)
156
{
157
  if (DECL_NAME (node))
158
    pp_tree_identifier (buffer, DECL_NAME (node));
159
 
160
  if ((flags & TDF_UID)
161
      || DECL_NAME (node) == NULL_TREE)
162
    {
163
      if (TREE_CODE (node) == LABEL_DECL
164
          && LABEL_DECL_UID (node) != -1)
165
        pp_printf (buffer, "L." HOST_WIDE_INT_PRINT_DEC,
166
                   LABEL_DECL_UID (node));
167
      else
168
        {
169
          char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D';
170
          pp_printf (buffer, "%c.%u", c, DECL_UID (node));
171
        }
172
    }
173
}
174
 
175
/* Like the above, but used for pretty printing function calls.  */
176
 
177
static void
178
dump_function_name (pretty_printer *buffer, tree node)
179
{
180
  if (DECL_NAME (node))
181
    PRINT_FUNCTION_NAME (node);
182
  else
183
    dump_decl_name (buffer, node, 0);
184
}
185
 
186
/* Dump a function declaration.  NODE is the FUNCTION_TYPE.  BUFFER, SPC and
187
   FLAGS are as in dump_generic_node.  */
188
 
189
static void
190
dump_function_declaration (pretty_printer *buffer, tree node,
191
                           int spc, int flags)
192
{
193
  bool wrote_arg = false;
194
  tree arg;
195
 
196
  pp_space (buffer);
197
  pp_character (buffer, '(');
198
 
199
  /* Print the argument types.  The last element in the list is a VOID_TYPE.
200
     The following avoids printing the last element.  */
201
  arg = TYPE_ARG_TYPES (node);
202
  while (arg && TREE_CHAIN (arg) && arg != error_mark_node)
203
    {
204
      wrote_arg = true;
205
      dump_generic_node (buffer, TREE_VALUE (arg), spc, flags, false);
206
      arg = TREE_CHAIN (arg);
207
      if (TREE_CHAIN (arg) && TREE_CODE (TREE_CHAIN (arg)) == TREE_LIST)
208
        {
209
          pp_character (buffer, ',');
210
          pp_space (buffer);
211
        }
212
    }
213
 
214
  if (!wrote_arg)
215
    pp_string (buffer, "void");
216
 
217
  pp_character (buffer, ')');
218
}
219
 
220
/* Dump the domain associated with an array.  */
221
 
222
static void
223
dump_array_domain (pretty_printer *buffer, tree domain, int spc, int flags)
224
{
225
  pp_character (buffer, '[');
226
  if (domain)
227
    {
228
      tree min = TYPE_MIN_VALUE (domain);
229
      tree max = TYPE_MAX_VALUE (domain);
230
 
231
      if (min && max
232
          && integer_zerop (min)
233
          && host_integerp (max, 0))
234
        pp_wide_integer (buffer, TREE_INT_CST_LOW (max) + 1);
235
      else
236
        {
237
          if (min)
238
            dump_generic_node (buffer, min, spc, flags, false);
239
          pp_character (buffer, ':');
240
          if (max)
241
            dump_generic_node (buffer, max, spc, flags, false);
242
        }
243
    }
244
  else
245
    pp_string (buffer, "<unknown>");
246
  pp_character (buffer, ']');
247
}
248
 
249
/* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of indent.
250
   FLAGS specifies details to show in the dump (see TDF_* in tree.h).  If
251
   IS_STMT is true, the object printed is considered to be a statement
252
   and it is terminated by ';' if appropriate.  */
253
 
254
int
255
dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
256
                   bool is_stmt)
257
{
258
  tree type;
259
  tree op0, op1;
260
  const char *str;
261
  bool is_expr;
262
 
263
  if (node == NULL_TREE)
264
    return spc;
265
 
266
  is_expr = EXPR_P (node);
267
 
268
  if (TREE_CODE (node) != ERROR_MARK
269
      && is_gimple_stmt (node)
270
      && (flags & TDF_VOPS)
271
      && stmt_ann (node)
272
      && TREE_CODE (node) != PHI_NODE)
273
    dump_vops (buffer, node, spc, flags);
274
 
275
  if (is_stmt && (flags & TDF_STMTADDR))
276
    pp_printf (buffer, "<&%p> ", (void *)node);
277
 
278
  if (dumping_stmts
279
      && (flags & TDF_LINENO)
280
      && EXPR_HAS_LOCATION (node))
281
    {
282
      expanded_location xloc = expand_location (EXPR_LOCATION (node));
283
      pp_character (buffer, '[');
284
      if (xloc.file)
285
        {
286
          pp_string (buffer, xloc.file);
287
          pp_string (buffer, " : ");
288
        }
289
      pp_decimal_int (buffer, xloc.line);
290
      pp_string (buffer, "] ");
291
    }
292
 
293
  switch (TREE_CODE (node))
294
    {
295
    case ERROR_MARK:
296
      pp_string (buffer, "<<< error >>>");
297
      break;
298
 
299
    case IDENTIFIER_NODE:
300
      pp_tree_identifier (buffer, node);
301
      break;
302
 
303
    case TREE_LIST:
304
      while (node && node != error_mark_node)
305
        {
306
          if (TREE_PURPOSE (node))
307
            {
308
              dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
309
              pp_space (buffer);
310
            }
311
          dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
312
          node = TREE_CHAIN (node);
313
          if (node && TREE_CODE (node) == TREE_LIST)
314
            {
315
              pp_character (buffer, ',');
316
              pp_space (buffer);
317
            }
318
        }
319
      break;
320
 
321
    case TREE_BINFO:
322
      dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
323
 
324
    case TREE_VEC:
325
      {
326
        size_t i;
327
        if (TREE_VEC_LENGTH (node) > 0)
328
          {
329
            size_t len = TREE_VEC_LENGTH (node);
330
            for (i = 0; i < len - 1; i++)
331
              {
332
                dump_generic_node (buffer, TREE_VEC_ELT (node, i), spc, flags,
333
                                   false);
334
                pp_character (buffer, ',');
335
                pp_space (buffer);
336
              }
337
            dump_generic_node (buffer, TREE_VEC_ELT (node, len - 1), spc,
338
                               flags, false);
339
          }
340
      }
341
      break;
342
 
343
    case BLOCK:
344
      NIY;
345
      break;
346
 
347
    case VOID_TYPE:
348
    case INTEGER_TYPE:
349
    case REAL_TYPE:
350
    case COMPLEX_TYPE:
351
    case VECTOR_TYPE:
352
    case ENUMERAL_TYPE:
353
    case BOOLEAN_TYPE:
354
    case CHAR_TYPE:
355
      {
356
        unsigned int quals = TYPE_QUALS (node);
357
        enum tree_code_class class;
358
 
359
        if (quals & TYPE_QUAL_CONST)
360
          pp_string (buffer, "const ");
361
        else if (quals & TYPE_QUAL_VOLATILE)
362
          pp_string (buffer, "volatile ");
363
        else if (quals & TYPE_QUAL_RESTRICT)
364
          pp_string (buffer, "restrict ");
365
 
366
        class = TREE_CODE_CLASS (TREE_CODE (node));
367
 
368
        if (class == tcc_declaration)
369
          {
370
            if (DECL_NAME (node))
371
              dump_decl_name (buffer, node, flags);
372
            else
373
              pp_string (buffer, "<unnamed type decl>");
374
          }
375
        else if (class == tcc_type)
376
          {
377
            if (TYPE_NAME (node))
378
              {
379
                if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
380
                  pp_tree_identifier (buffer, TYPE_NAME (node));
381
                else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
382
                         && DECL_NAME (TYPE_NAME (node)))
383
                  dump_decl_name (buffer, TYPE_NAME (node), flags);
384
                else
385
                  pp_string (buffer, "<unnamed type>");
386
              }
387
            else if (TREE_CODE (node) == VECTOR_TYPE)
388
              {
389
                pp_string (buffer, "vector ");
390
                dump_generic_node (buffer, TREE_TYPE (node),
391
                                   spc, flags, false);
392
              }
393
            else
394
              pp_string (buffer, "<unnamed type>");
395
          }
396
        break;
397
      }
398
 
399
    case POINTER_TYPE:
400
    case REFERENCE_TYPE:
401
      str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
402
 
403
      if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
404
        {
405
          tree fnode = TREE_TYPE (node);
406
 
407
          dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
408
          pp_space (buffer);
409
          pp_character (buffer, '(');
410
          pp_string (buffer, str);
411
          if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
412
            dump_decl_name (buffer, TYPE_NAME (node), flags);
413
          else
414
            pp_printf (buffer, "<T%x>", TYPE_UID (node));
415
 
416
          pp_character (buffer, ')');
417
          dump_function_declaration (buffer, fnode, spc, flags);
418
        }
419
      else
420
        {
421
          unsigned int quals = TYPE_QUALS (node);
422
 
423
          dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
424
          pp_space (buffer);
425
          pp_string (buffer, str);
426
 
427
          if (quals & TYPE_QUAL_CONST)
428
            pp_string (buffer, " const");
429
          else if (quals & TYPE_QUAL_VOLATILE)
430
            pp_string (buffer,  "volatile");
431
          else if (quals & TYPE_QUAL_RESTRICT)
432
            pp_string (buffer, " restrict");
433
 
434
          if (TYPE_REF_CAN_ALIAS_ALL (node))
435
            pp_string (buffer, " {ref-all}");
436
        }
437
      break;
438
 
439
    case OFFSET_TYPE:
440
      NIY;
441
      break;
442
 
443
    case METHOD_TYPE:
444
      dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
445
      pp_string (buffer, "::");
446
      break;
447
 
448
    case TARGET_MEM_REF:
449
      {
450
        const char *sep = "";
451
        tree tmp;
452
 
453
        pp_string (buffer, "MEM[");
454
 
455
        tmp = TMR_SYMBOL (node);
456
        if (tmp)
457
          {
458
            pp_string (buffer, sep);
459
            sep = ", ";
460
            pp_string (buffer, "symbol: ");
461
            dump_generic_node (buffer, tmp, spc, flags, false);
462
          }
463
        tmp = TMR_BASE (node);
464
        if (tmp)
465
          {
466
            pp_string (buffer, sep);
467
            sep = ", ";
468
            pp_string (buffer, "base: ");
469
            dump_generic_node (buffer, tmp, spc, flags, false);
470
          }
471
        tmp = TMR_INDEX (node);
472
        if (tmp)
473
          {
474
            pp_string (buffer, sep);
475
            sep = ", ";
476
            pp_string (buffer, "index: ");
477
            dump_generic_node (buffer, tmp, spc, flags, false);
478
          }
479
        tmp = TMR_STEP (node);
480
        if (tmp)
481
          {
482
            pp_string (buffer, sep);
483
            sep = ", ";
484
            pp_string (buffer, "step: ");
485
            dump_generic_node (buffer, tmp, spc, flags, false);
486
          }
487
        tmp = TMR_OFFSET (node);
488
        if (tmp)
489
          {
490
            pp_string (buffer, sep);
491
            sep = ", ";
492
            pp_string (buffer, "offset: ");
493
            dump_generic_node (buffer, tmp, spc, flags, false);
494
          }
495
        pp_string (buffer, "]");
496
        if (flags & TDF_DETAILS)
497
          {
498
            pp_string (buffer, "{");
499
            dump_generic_node (buffer, TMR_ORIGINAL (node), spc, flags,
500
                               false);
501
            pp_string (buffer, "}");
502
          }
503
      }
504
      break;
505
 
506
    case ARRAY_TYPE:
507
      {
508
        tree tmp;
509
 
510
        /* Print the innermost component type.  */
511
        for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
512
             tmp = TREE_TYPE (tmp))
513
          ;
514
        dump_generic_node (buffer, tmp, spc, flags, false);
515
 
516
        /* Print the dimensions.  */
517
        for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE; tmp = TREE_TYPE (tmp))
518
          dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
519
        break;
520
      }
521
 
522
    case RECORD_TYPE:
523
    case UNION_TYPE:
524
    case QUAL_UNION_TYPE:
525
      /* Print the name of the structure.  */
526
      if (TREE_CODE (node) == RECORD_TYPE)
527
        pp_string (buffer, "struct ");
528
      else if (TREE_CODE (node) == UNION_TYPE)
529
        pp_string (buffer, "union ");
530
 
531
      if (TYPE_NAME (node))
532
        dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
533
      else
534
        print_struct_decl (buffer, node, spc, flags);
535
      break;
536
 
537
    case LANG_TYPE:
538
      NIY;
539
      break;
540
 
541
    case INTEGER_CST:
542
      if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
543
        {
544
          /* In the case of a pointer, one may want to divide by the
545
             size of the pointed-to type.  Unfortunately, this not
546
             straightforward.  The C front-end maps expressions
547
 
548
             (int *) 5
549
             int *p; (p + 5)
550
 
551
             in such a way that the two INTEGER_CST nodes for "5" have
552
             different values but identical types.  In the latter
553
             case, the 5 is multiplied by sizeof (int) in c-common.c
554
             (pointer_int_sum) to convert it to a byte address, and
555
             yet the type of the node is left unchanged.  Argh.  What
556
             is consistent though is that the number value corresponds
557
             to bytes (UNITS) offset.
558
 
559
             NB: Neither of the following divisors can be trivially
560
             used to recover the original literal:
561
 
562
             TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
563
             TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node)))  */
564
          pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
565
          pp_string (buffer, "B"); /* pseudo-unit */
566
        }
567
      else if (! host_integerp (node, 0))
568
        {
569
          tree val = node;
570
 
571
          if (tree_int_cst_sgn (val) < 0)
572
            {
573
              pp_character (buffer, '-');
574
              val = build_int_cst_wide (NULL_TREE,
575
                                        -TREE_INT_CST_LOW (val),
576
                                        ~TREE_INT_CST_HIGH (val)
577
                                        + !TREE_INT_CST_LOW (val));
578
            }
579
          /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
580
             systems?  */
581
          {
582
            static char format[10]; /* "%x%09999x\0" */
583
            if (!format[0])
584
              sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
585
            sprintf (pp_buffer (buffer)->digit_buffer, format,
586
                     TREE_INT_CST_HIGH (val),
587
                     TREE_INT_CST_LOW (val));
588
            pp_string (buffer, pp_buffer (buffer)->digit_buffer);
589
          }
590
        }
591
      else
592
        pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
593
      break;
594
 
595
    case REAL_CST:
596
      /* Code copied from print_node.  */
597
      {
598
        REAL_VALUE_TYPE d;
599
        if (TREE_OVERFLOW (node))
600
          pp_string (buffer, " overflow");
601
 
602
#if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
603
        d = TREE_REAL_CST (node);
604
        if (REAL_VALUE_ISINF (d))
605
          pp_string (buffer, " Inf");
606
        else if (REAL_VALUE_ISNAN (d))
607
          pp_string (buffer, " Nan");
608
        else
609
          {
610
            char string[100];
611
            real_to_decimal (string, &d, sizeof (string), 0, 1);
612
            pp_string (buffer, string);
613
          }
614
#else
615
        {
616
          HOST_WIDE_INT i;
617
          unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
618
          pp_string (buffer, "0x");
619
          for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
620
            output_formatted_integer (buffer, "%02x", *p++);
621
        }
622
#endif
623
        break;
624
      }
625
 
626
    case COMPLEX_CST:
627
      pp_string (buffer, "__complex__ (");
628
      dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
629
      pp_string (buffer, ", ");
630
      dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
631
      pp_string (buffer, ")");
632
      break;
633
 
634
    case STRING_CST:
635
      pp_string (buffer, "\"");
636
      pretty_print_string (buffer, TREE_STRING_POINTER (node));
637
      pp_string (buffer, "\"");
638
      break;
639
 
640
    case VECTOR_CST:
641
      {
642
        tree elt;
643
        pp_string (buffer, "{ ");
644
        for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
645
          {
646
            dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
647
            if (TREE_CHAIN (elt))
648
              pp_string (buffer, ", ");
649
          }
650
        pp_string (buffer, " }");
651
      }
652
      break;
653
 
654
    case FUNCTION_TYPE:
655
      break;
656
 
657
    case FUNCTION_DECL:
658
    case CONST_DECL:
659
      dump_decl_name (buffer, node, flags);
660
      break;
661
 
662
    case LABEL_DECL:
663
      if (DECL_NAME (node))
664
        dump_decl_name (buffer, node, flags);
665
      else if (LABEL_DECL_UID (node) != -1)
666
        pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
667
                   LABEL_DECL_UID (node));
668
      else
669
        pp_printf (buffer, "<D%u>", DECL_UID (node));
670
      break;
671
 
672
    case TYPE_DECL:
673
      if (DECL_IS_BUILTIN (node))
674
        {
675
          /* Don't print the declaration of built-in types.  */
676
          break;
677
        }
678
      if (DECL_NAME (node))
679
        dump_decl_name (buffer, node, flags);
680
      else
681
        {
682
          if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
683
               || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
684
              && TYPE_METHODS (TREE_TYPE (node)))
685
            {
686
              /* The type is a c++ class: all structures have at least
687
                 4 methods.  */
688
              pp_string (buffer, "class ");
689
              dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
690
            }
691
          else
692
            {
693
              pp_string (buffer,
694
                         (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
695
                          ? "union" : "struct "));
696
              dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
697
            }
698
        }
699
      break;
700
 
701
    case VAR_DECL:
702
    case PARM_DECL:
703
    case FIELD_DECL:
704
    case NAMESPACE_DECL:
705
      dump_decl_name (buffer, node, flags);
706
      break;
707
 
708
    case RESULT_DECL:
709
      pp_string (buffer, "<retval>");
710
      break;
711
 
712
    case COMPONENT_REF:
713
      op0 = TREE_OPERAND (node, 0);
714
      str = ".";
715
      if (TREE_CODE (op0) == INDIRECT_REF)
716
        {
717
          op0 = TREE_OPERAND (op0, 0);
718
          str = "->";
719
        }
720
      if (op_prio (op0) < op_prio (node))
721
        pp_character (buffer, '(');
722
      dump_generic_node (buffer, op0, spc, flags, false);
723
      if (op_prio (op0) < op_prio (node))
724
        pp_character (buffer, ')');
725
      pp_string (buffer, str);
726
      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
727
 
728
      if (TREE_CODE (op0) != VALUE_HANDLE)
729
        {
730
          op0 = component_ref_field_offset (node);
731
          if (op0 && TREE_CODE (op0) != INTEGER_CST)
732
            {
733
              pp_string (buffer, "{off: ");
734
              dump_generic_node (buffer, op0, spc, flags, false);
735
              pp_character (buffer, '}');
736
            }
737
        }
738
      break;
739
 
740
    case BIT_FIELD_REF:
741
      pp_string (buffer, "BIT_FIELD_REF <");
742
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
743
      pp_string (buffer, ", ");
744
      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
745
      pp_string (buffer, ", ");
746
      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
747
      pp_string (buffer, ">");
748
      break;
749
 
750
    case ARRAY_REF:
751
    case ARRAY_RANGE_REF:
752
      op0 = TREE_OPERAND (node, 0);
753
      if (op_prio (op0) < op_prio (node))
754
        pp_character (buffer, '(');
755
      dump_generic_node (buffer, op0, spc, flags, false);
756
      if (op_prio (op0) < op_prio (node))
757
        pp_character (buffer, ')');
758
      pp_character (buffer, '[');
759
      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
760
      if (TREE_CODE (node) == ARRAY_RANGE_REF)
761
        pp_string (buffer, " ...");
762
      pp_character (buffer, ']');
763
 
764
      op0 = array_ref_low_bound (node);
765
      op1 = array_ref_element_size (node);
766
 
767
      if (!integer_zerop (op0)
768
          || (TYPE_SIZE_UNIT (TREE_TYPE (node))
769
              && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
770
        {
771
          pp_string (buffer, "{lb: ");
772
          dump_generic_node (buffer, op0, spc, flags, false);
773
          pp_string (buffer, " sz: ");
774
          dump_generic_node (buffer, op1, spc, flags, false);
775
          pp_character (buffer, '}');
776
        }
777
      break;
778
 
779
    case CONSTRUCTOR:
780
      {
781
        unsigned HOST_WIDE_INT ix;
782
        tree field, val;
783
        bool is_struct_init = FALSE;
784
        pp_character (buffer, '{');
785
        if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
786
            || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
787
          is_struct_init = TRUE;
788
        FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (node), ix, field, val)
789
          {
790
            if (field && is_struct_init)
791
              {
792
                pp_character (buffer, '.');
793
                dump_generic_node (buffer, field, spc, flags, false);
794
                pp_string (buffer, "=");
795
              }
796
            if (val && TREE_CODE (val) == ADDR_EXPR)
797
              if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
798
                val = TREE_OPERAND (val, 0);
799
            if (val && TREE_CODE (val) == FUNCTION_DECL)
800
                dump_decl_name (buffer, val, flags);
801
            else
802
                dump_generic_node (buffer, val, spc, flags, false);
803
            if (ix != VEC_length (constructor_elt, CONSTRUCTOR_ELTS (node)) - 1)
804
              {
805
                pp_character (buffer, ',');
806
                pp_space (buffer);
807
              }
808
          }
809
        pp_character (buffer, '}');
810
      }
811
      break;
812
 
813
    case COMPOUND_EXPR:
814
      {
815
        tree *tp;
816
        if (flags & TDF_SLIM)
817
          {
818
            pp_string (buffer, "<COMPOUND_EXPR>");
819
            break;
820
          }
821
 
822
        dump_generic_node (buffer, TREE_OPERAND (node, 0),
823
                           spc, flags, dumping_stmts);
824
        if (dumping_stmts)
825
          newline_and_indent (buffer, spc);
826
        else
827
          {
828
            pp_character (buffer, ',');
829
            pp_space (buffer);
830
          }
831
 
832
        for (tp = &TREE_OPERAND (node, 1);
833
             TREE_CODE (*tp) == COMPOUND_EXPR;
834
             tp = &TREE_OPERAND (*tp, 1))
835
          {
836
            dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
837
                               spc, flags, dumping_stmts);
838
            if (dumping_stmts)
839
              newline_and_indent (buffer, spc);
840
            else
841
              {
842
                pp_character (buffer, ',');
843
                pp_space (buffer);
844
              }
845
          }
846
 
847
        dump_generic_node (buffer, *tp, spc, flags, dumping_stmts);
848
      }
849
      break;
850
 
851
    case STATEMENT_LIST:
852
      {
853
        tree_stmt_iterator si;
854
        bool first = true;
855
 
856
        if ((flags & TDF_SLIM) || !dumping_stmts)
857
          {
858
            pp_string (buffer, "<STATEMENT_LIST>");
859
            break;
860
          }
861
 
862
        for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
863
          {
864
            if (!first)
865
              newline_and_indent (buffer, spc);
866
            else
867
              first = false;
868
            dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
869
          }
870
      }
871
      break;
872
 
873
    case MODIFY_EXPR:
874
    case INIT_EXPR:
875
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
876
      pp_space (buffer);
877
      pp_character (buffer, '=');
878
      pp_space (buffer);
879
      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
880
      break;
881
 
882
    case TARGET_EXPR:
883
      pp_string (buffer, "TARGET_EXPR <");
884
      dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
885
      pp_character (buffer, ',');
886
      pp_space (buffer);
887
      dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
888
      pp_character (buffer, '>');
889
      break;
890
 
891
    case DECL_EXPR:
892
      print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
893
      is_stmt = false;
894
      break;
895
 
896
    case COND_EXPR:
897
      if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
898
        {
899
          pp_string (buffer, "if (");
900
          dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
901
          pp_character (buffer, ')');
902
          /* The lowered cond_exprs should always be printed in full.  */
903
          if (COND_EXPR_THEN (node)
904
              && (IS_EMPTY_STMT (COND_EXPR_THEN (node))
905
                  || TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR)
906
              && COND_EXPR_ELSE (node)
907
              && (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
908
                  || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
909
            {
910
              pp_space (buffer);
911
              dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
912
              pp_string (buffer, " else ");
913
              dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
914
            }
915
          else if (!(flags & TDF_SLIM))
916
            {
917
              /* Output COND_EXPR_THEN.  */
918
              if (COND_EXPR_THEN (node))
919
                {
920
                  newline_and_indent (buffer, spc+2);
921
                  pp_character (buffer, '{');
922
                  newline_and_indent (buffer, spc+4);
923
                  dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
924
                                     flags, true);
925
                  newline_and_indent (buffer, spc+2);
926
                  pp_character (buffer, '}');
927
                }
928
 
929
              /* Output COND_EXPR_ELSE.  */
930
              if (COND_EXPR_ELSE (node))
931
                {
932
                  newline_and_indent (buffer, spc);
933
                  pp_string (buffer, "else");
934
                  newline_and_indent (buffer, spc+2);
935
                  pp_character (buffer, '{');
936
                  newline_and_indent (buffer, spc+4);
937
                  dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
938
                                     flags, true);
939
                  newline_and_indent (buffer, spc+2);
940
                  pp_character (buffer, '}');
941
                }
942
            }
943
          is_expr = false;
944
        }
945
      else
946
        {
947
          dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
948
          pp_space (buffer);
949
          pp_character (buffer, '?');
950
          pp_space (buffer);
951
          dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
952
          pp_space (buffer);
953
          pp_character (buffer, ':');
954
          pp_space (buffer);
955
          dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
956
        }
957
      break;
958
 
959
    case BIND_EXPR:
960
      pp_character (buffer, '{');
961
      if (!(flags & TDF_SLIM))
962
        {
963
          if (BIND_EXPR_VARS (node))
964
            {
965
              pp_newline (buffer);
966
 
967
              for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
968
                {
969
                  print_declaration (buffer, op0, spc+2, flags);
970
                  pp_newline (buffer);
971
                }
972
            }
973
 
974
          newline_and_indent (buffer, spc+2);
975
          dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
976
          newline_and_indent (buffer, spc);
977
          pp_character (buffer, '}');
978
        }
979
      is_expr = false;
980
      break;
981
 
982
    case CALL_EXPR:
983
      print_call_name (buffer, node);
984
 
985
      /* Print parameters.  */
986
      pp_space (buffer);
987
      pp_character (buffer, '(');
988
      op1 = TREE_OPERAND (node, 1);
989
      if (op1)
990
        dump_generic_node (buffer, op1, spc, flags, false);
991
      pp_character (buffer, ')');
992
 
993
      op1 = TREE_OPERAND (node, 2);
994
      if (op1)
995
        {
996
          pp_string (buffer, " [static-chain: ");
997
          dump_generic_node (buffer, op1, spc, flags, false);
998
          pp_character (buffer, ']');
999
        }
1000
 
1001
      if (CALL_EXPR_RETURN_SLOT_OPT (node))
1002
        pp_string (buffer, " [return slot optimization]");
1003
      if (CALL_EXPR_TAILCALL (node))
1004
        pp_string (buffer, " [tail call]");
1005
      break;
1006
 
1007
    case WITH_CLEANUP_EXPR:
1008
      NIY;
1009
      break;
1010
 
1011
    case CLEANUP_POINT_EXPR:
1012
      pp_string (buffer, "<<cleanup_point ");
1013
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1014
      pp_string (buffer, ">>");
1015
      break;
1016
 
1017
    case PLACEHOLDER_EXPR:
1018
      pp_string (buffer, "<PLACEHOLDER_EXPR ");
1019
      dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1020
      pp_character (buffer, '>');
1021
      break;
1022
 
1023
      /* Binary arithmetic and logic expressions.  */
1024
    case MULT_EXPR:
1025
    case PLUS_EXPR:
1026
    case MINUS_EXPR:
1027
    case TRUNC_DIV_EXPR:
1028
    case CEIL_DIV_EXPR:
1029
    case FLOOR_DIV_EXPR:
1030
    case ROUND_DIV_EXPR:
1031
    case TRUNC_MOD_EXPR:
1032
    case CEIL_MOD_EXPR:
1033
    case FLOOR_MOD_EXPR:
1034
    case ROUND_MOD_EXPR:
1035
    case RDIV_EXPR:
1036
    case EXACT_DIV_EXPR:
1037
    case LSHIFT_EXPR:
1038
    case RSHIFT_EXPR:
1039
    case LROTATE_EXPR:
1040
    case RROTATE_EXPR:
1041
    case VEC_LSHIFT_EXPR:
1042
    case VEC_RSHIFT_EXPR:
1043
    case BIT_IOR_EXPR:
1044
    case BIT_XOR_EXPR:
1045
    case BIT_AND_EXPR:
1046
    case TRUTH_ANDIF_EXPR:
1047
    case TRUTH_ORIF_EXPR:
1048
    case TRUTH_AND_EXPR:
1049
    case TRUTH_OR_EXPR:
1050
    case TRUTH_XOR_EXPR:
1051
    case LT_EXPR:
1052
    case LE_EXPR:
1053
    case GT_EXPR:
1054
    case GE_EXPR:
1055
    case EQ_EXPR:
1056
    case NE_EXPR:
1057
    case UNLT_EXPR:
1058
    case UNLE_EXPR:
1059
    case UNGT_EXPR:
1060
    case UNGE_EXPR:
1061
    case UNEQ_EXPR:
1062
    case LTGT_EXPR:
1063
    case ORDERED_EXPR:
1064
    case UNORDERED_EXPR:
1065
      {
1066
        const char *op = op_symbol (node);
1067
        op0 = TREE_OPERAND (node, 0);
1068
        op1 = TREE_OPERAND (node, 1);
1069
 
1070
        /* When the operands are expressions with less priority,
1071
           keep semantics of the tree representation.  */
1072
        if (op_prio (op0) < op_prio (node))
1073
          {
1074
            pp_character (buffer, '(');
1075
            dump_generic_node (buffer, op0, spc, flags, false);
1076
            pp_character (buffer, ')');
1077
          }
1078
        else
1079
          dump_generic_node (buffer, op0, spc, flags, false);
1080
 
1081
        pp_space (buffer);
1082
        pp_string (buffer, op);
1083
        pp_space (buffer);
1084
 
1085
        /* When the operands are expressions with less priority,
1086
           keep semantics of the tree representation.  */
1087
        if (op_prio (op1) < op_prio (node))
1088
          {
1089
            pp_character (buffer, '(');
1090
            dump_generic_node (buffer, op1, spc, flags, false);
1091
            pp_character (buffer, ')');
1092
          }
1093
        else
1094
          dump_generic_node (buffer, op1, spc, flags, false);
1095
      }
1096
      break;
1097
 
1098
      /* Unary arithmetic and logic expressions.  */
1099
    case NEGATE_EXPR:
1100
    case BIT_NOT_EXPR:
1101
    case TRUTH_NOT_EXPR:
1102
    case ADDR_EXPR:
1103
    case PREDECREMENT_EXPR:
1104
    case PREINCREMENT_EXPR:
1105
    case ALIGN_INDIRECT_REF:
1106
    case MISALIGNED_INDIRECT_REF:
1107
    case INDIRECT_REF:
1108
      if (TREE_CODE (node) == ADDR_EXPR
1109
          && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
1110
              || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
1111
        ;       /* Do not output '&' for strings and function pointers.  */
1112
      else
1113
        pp_string (buffer, op_symbol (node));
1114
 
1115
      if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1116
        {
1117
          pp_character (buffer, '(');
1118
          dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1119
          pp_character (buffer, ')');
1120
        }
1121
      else
1122
        dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1123
 
1124
      if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
1125
        {
1126
          pp_string (buffer, "{misalignment: ");
1127
          dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1128
          pp_character (buffer, '}');
1129
        }
1130
      break;
1131
 
1132
    case POSTDECREMENT_EXPR:
1133
    case POSTINCREMENT_EXPR:
1134
      if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
1135
        {
1136
          pp_character (buffer, '(');
1137
          dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1138
          pp_character (buffer, ')');
1139
        }
1140
      else
1141
        dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1142
      pp_string (buffer, op_symbol (node));
1143
      break;
1144
 
1145
    case MIN_EXPR:
1146
      pp_string (buffer, "MIN_EXPR <");
1147
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1148
      pp_string (buffer, ", ");
1149
      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1150
      pp_character (buffer, '>');
1151
      break;
1152
 
1153
    case MAX_EXPR:
1154
      pp_string (buffer, "MAX_EXPR <");
1155
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1156
      pp_string (buffer, ", ");
1157
      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1158
      pp_character (buffer, '>');
1159
      break;
1160
 
1161
    case ABS_EXPR:
1162
      pp_string (buffer, "ABS_EXPR <");
1163
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1164
      pp_character (buffer, '>');
1165
      break;
1166
 
1167
    case RANGE_EXPR:
1168
      NIY;
1169
      break;
1170
 
1171
    case FIX_TRUNC_EXPR:
1172
    case FIX_CEIL_EXPR:
1173
    case FIX_FLOOR_EXPR:
1174
    case FIX_ROUND_EXPR:
1175
    case FLOAT_EXPR:
1176
    case CONVERT_EXPR:
1177
    case NOP_EXPR:
1178
      type = TREE_TYPE (node);
1179
      op0 = TREE_OPERAND (node, 0);
1180
      if (type != TREE_TYPE (op0))
1181
        {
1182
          pp_character (buffer, '(');
1183
          dump_generic_node (buffer, type, spc, flags, false);
1184
          pp_string (buffer, ") ");
1185
        }
1186
      if (op_prio (op0) < op_prio (node))
1187
        pp_character (buffer, '(');
1188
      dump_generic_node (buffer, op0, spc, flags, false);
1189
      if (op_prio (op0) < op_prio (node))
1190
        pp_character (buffer, ')');
1191
      break;
1192
 
1193
    case VIEW_CONVERT_EXPR:
1194
      pp_string (buffer, "VIEW_CONVERT_EXPR<");
1195
      dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
1196
      pp_string (buffer, ">(");
1197
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1198
      pp_character (buffer, ')');
1199
      break;
1200
 
1201
    case NON_LVALUE_EXPR:
1202
      pp_string (buffer, "NON_LVALUE_EXPR <");
1203
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1204
      pp_character (buffer, '>');
1205
      break;
1206
 
1207
    case SAVE_EXPR:
1208
      pp_string (buffer, "SAVE_EXPR <");
1209
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1210
      pp_character (buffer, '>');
1211
      break;
1212
 
1213
    case COMPLEX_EXPR:
1214
      pp_string (buffer, "COMPLEX_EXPR <");
1215
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1216
      pp_string (buffer, ", ");
1217
      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1218
      pp_string (buffer, ">");
1219
      break;
1220
 
1221
    case CONJ_EXPR:
1222
      pp_string (buffer, "CONJ_EXPR <");
1223
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1224
      pp_string (buffer, ">");
1225
      break;
1226
 
1227
    case REALPART_EXPR:
1228
      pp_string (buffer, "REALPART_EXPR <");
1229
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1230
      pp_string (buffer, ">");
1231
      break;
1232
 
1233
    case IMAGPART_EXPR:
1234
      pp_string (buffer, "IMAGPART_EXPR <");
1235
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1236
      pp_string (buffer, ">");
1237
      break;
1238
 
1239
    case VA_ARG_EXPR:
1240
      pp_string (buffer, "VA_ARG_EXPR <");
1241
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1242
      pp_string (buffer, ">");
1243
      break;
1244
 
1245
    case TRY_FINALLY_EXPR:
1246
    case TRY_CATCH_EXPR:
1247
      pp_string (buffer, "try");
1248
      newline_and_indent (buffer, spc+2);
1249
      pp_string (buffer, "{");
1250
      newline_and_indent (buffer, spc+4);
1251
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
1252
      newline_and_indent (buffer, spc+2);
1253
      pp_string (buffer, "}");
1254
      newline_and_indent (buffer, spc);
1255
      pp_string (buffer,
1256
                         (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
1257
      newline_and_indent (buffer, spc+2);
1258
      pp_string (buffer, "{");
1259
      newline_and_indent (buffer, spc+4);
1260
      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
1261
      newline_and_indent (buffer, spc+2);
1262
      pp_string (buffer, "}");
1263
      is_expr = false;
1264
      break;
1265
 
1266
    case CATCH_EXPR:
1267
      pp_string (buffer, "catch (");
1268
      dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
1269
      pp_string (buffer, ")");
1270
      newline_and_indent (buffer, spc+2);
1271
      pp_string (buffer, "{");
1272
      newline_and_indent (buffer, spc+4);
1273
      dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
1274
      newline_and_indent (buffer, spc+2);
1275
      pp_string (buffer, "}");
1276
      is_expr = false;
1277
      break;
1278
 
1279
    case EH_FILTER_EXPR:
1280
      pp_string (buffer, "<<<eh_filter (");
1281
      dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
1282
      pp_string (buffer, ")>>>");
1283
      newline_and_indent (buffer, spc+2);
1284
      pp_string (buffer, "{");
1285
      newline_and_indent (buffer, spc+4);
1286
      dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
1287
      newline_and_indent (buffer, spc+2);
1288
      pp_string (buffer, "}");
1289
      is_expr = false;
1290
      break;
1291
 
1292
    case LABEL_EXPR:
1293
      op0 = TREE_OPERAND (node, 0);
1294
      /* If this is for break or continue, don't bother printing it.  */
1295
      if (DECL_NAME (op0))
1296
        {
1297
          const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1298
          if (strcmp (name, "break") == 0
1299
              || strcmp (name, "continue") == 0)
1300
            break;
1301
        }
1302
      dump_generic_node (buffer, op0, spc, flags, false);
1303
      pp_character (buffer, ':');
1304
      if (DECL_NONLOCAL (op0))
1305
        pp_string (buffer, " [non-local]");
1306
      break;
1307
 
1308
    case EXC_PTR_EXPR:
1309
      pp_string (buffer, "<<<exception object>>>");
1310
      break;
1311
 
1312
    case FILTER_EXPR:
1313
      pp_string (buffer, "<<<filter object>>>");
1314
      break;
1315
 
1316
    case LOOP_EXPR:
1317
      pp_string (buffer, "while (1)");
1318
      if (!(flags & TDF_SLIM))
1319
        {
1320
          newline_and_indent (buffer, spc+2);
1321
          pp_character (buffer, '{');
1322
          newline_and_indent (buffer, spc+4);
1323
          dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
1324
          newline_and_indent (buffer, spc+2);
1325
          pp_character (buffer, '}');
1326
        }
1327
      is_expr = false;
1328
      break;
1329
 
1330
    case RETURN_EXPR:
1331
      pp_string (buffer, "return");
1332
      op0 = TREE_OPERAND (node, 0);
1333
      if (op0)
1334
        {
1335
          pp_space (buffer);
1336
          if (TREE_CODE (op0) == MODIFY_EXPR)
1337
            dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
1338
          else
1339
            dump_generic_node (buffer, op0, spc, flags, false);
1340
        }
1341
      break;
1342
 
1343
    case EXIT_EXPR:
1344
      pp_string (buffer, "if (");
1345
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1346
      pp_string (buffer, ") break");
1347
      break;
1348
 
1349
    case SWITCH_EXPR:
1350
      pp_string (buffer, "switch (");
1351
      dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
1352
      pp_character (buffer, ')');
1353
      if (!(flags & TDF_SLIM))
1354
        {
1355
          newline_and_indent (buffer, spc+2);
1356
          pp_character (buffer, '{');
1357
          if (SWITCH_BODY (node))
1358
            {
1359
              newline_and_indent (buffer, spc+4);
1360
              dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
1361
            }
1362
          else
1363
            {
1364
              tree vec = SWITCH_LABELS (node);
1365
              size_t i, n = TREE_VEC_LENGTH (vec);
1366
              for (i = 0; i < n; ++i)
1367
                {
1368
                  tree elt = TREE_VEC_ELT (vec, i);
1369
                  newline_and_indent (buffer, spc+4);
1370
                  dump_generic_node (buffer, elt, spc+4, flags, false);
1371
                  pp_string (buffer, " goto ");
1372
                  dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
1373
                  pp_semicolon (buffer);
1374
                }
1375
            }
1376
          newline_and_indent (buffer, spc+2);
1377
          pp_character (buffer, '}');
1378
        }
1379
      is_expr = false;
1380
      break;
1381
 
1382
    case GOTO_EXPR:
1383
      op0 = GOTO_DESTINATION (node);
1384
      if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
1385
        {
1386
          const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
1387
          if (strcmp (name, "break") == 0
1388
              || strcmp (name, "continue") == 0)
1389
            {
1390
              pp_string (buffer, name);
1391
              break;
1392
            }
1393
        }
1394
      pp_string (buffer, "goto ");
1395
      dump_generic_node (buffer, op0, spc, flags, false);
1396
      break;
1397
 
1398
    case RESX_EXPR:
1399
      pp_string (buffer, "resx");
1400
      /* ??? Any sensible way to present the eh region?  */
1401
      break;
1402
 
1403
    case ASM_EXPR:
1404
      pp_string (buffer, "__asm__");
1405
      if (ASM_VOLATILE_P (node))
1406
        pp_string (buffer, " __volatile__");
1407
      pp_character (buffer, '(');
1408
      dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
1409
      pp_character (buffer, ':');
1410
      dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
1411
      pp_character (buffer, ':');
1412
      dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
1413
      if (ASM_CLOBBERS (node))
1414
        {
1415
          pp_character (buffer, ':');
1416
          dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
1417
        }
1418
      pp_string (buffer, ")");
1419
      break;
1420
 
1421
    case CASE_LABEL_EXPR:
1422
      if (CASE_LOW (node) && CASE_HIGH (node))
1423
        {
1424
          pp_string (buffer, "case ");
1425
          dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1426
          pp_string (buffer, " ... ");
1427
          dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
1428
        }
1429
      else if (CASE_LOW (node))
1430
        {
1431
          pp_string (buffer, "case ");
1432
          dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
1433
        }
1434
      else
1435
        pp_string (buffer, "default ");
1436
      pp_character (buffer, ':');
1437
      break;
1438
 
1439
    case OBJ_TYPE_REF:
1440
      pp_string (buffer, "OBJ_TYPE_REF(");
1441
      dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
1442
      pp_character (buffer, ';');
1443
      dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
1444
      pp_character (buffer, '-');
1445
      pp_character (buffer, '>');
1446
      dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
1447
      pp_character (buffer, ')');
1448
      break;
1449
 
1450
    case PHI_NODE:
1451
      {
1452
        int i;
1453
 
1454
        dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
1455
        pp_string (buffer, " = PHI <");
1456
        for (i = 0; i < PHI_NUM_ARGS (node); i++)
1457
          {
1458
            dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
1459
            pp_string (buffer, "(");
1460
            pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
1461
            pp_string (buffer, ")");
1462
            if (i < PHI_NUM_ARGS (node) - 1)
1463
              pp_string (buffer, ", ");
1464
          }
1465
        pp_string (buffer, ">;");
1466
      }
1467
      break;
1468
 
1469
    case SSA_NAME:
1470
      dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
1471
      pp_string (buffer, "_");
1472
      pp_decimal_int (buffer, SSA_NAME_VERSION (node));
1473
      if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
1474
        pp_string (buffer, "(ab)");
1475
      break;
1476
 
1477
    case WITH_SIZE_EXPR:
1478
      pp_string (buffer, "WITH_SIZE_EXPR <");
1479
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1480
      pp_string (buffer, ", ");
1481
      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1482
      pp_string (buffer, ">");
1483
      break;
1484
 
1485
    case VALUE_HANDLE:
1486
      pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
1487
      break;
1488
 
1489
    case ASSERT_EXPR:
1490
      pp_string (buffer, "ASSERT_EXPR <");
1491
      dump_generic_node (buffer, ASSERT_EXPR_VAR (node), spc, flags, false);
1492
      pp_string (buffer, ", ");
1493
      dump_generic_node (buffer, ASSERT_EXPR_COND (node), spc, flags, false);
1494
      pp_string (buffer, ">");
1495
      break;
1496
 
1497
    case SCEV_KNOWN:
1498
      pp_string (buffer, "scev_known");
1499
      break;
1500
 
1501
    case SCEV_NOT_KNOWN:
1502
      pp_string (buffer, "scev_not_known");
1503
      break;
1504
 
1505
    case POLYNOMIAL_CHREC:
1506
      pp_string (buffer, "{");
1507
      dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
1508
      pp_string (buffer, ", +, ");
1509
      dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
1510
      pp_string (buffer, "}_");
1511
      dump_generic_node (buffer, CHREC_VAR (node), spc, flags, false);
1512
      is_stmt = false;
1513
      break;
1514
 
1515
    case REALIGN_LOAD_EXPR:
1516
      pp_string (buffer, "REALIGN_LOAD <");
1517
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1518
      pp_string (buffer, ", ");
1519
      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1520
      pp_string (buffer, ", ");
1521
      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1522
      pp_string (buffer, ">");
1523
      break;
1524
 
1525
    case VEC_COND_EXPR:
1526
      pp_string (buffer, " VEC_COND_EXPR < ");
1527
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1528
      pp_string (buffer, " , ");
1529
      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
1530
      pp_string (buffer, " , ");
1531
      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
1532
      pp_string (buffer, " > ");
1533
      break;
1534
 
1535
    case REDUC_MAX_EXPR:
1536
      pp_string (buffer, " REDUC_MAX_EXPR < ");
1537
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1538
      pp_string (buffer, " > ");
1539
      break;
1540
 
1541
    case REDUC_MIN_EXPR:
1542
      pp_string (buffer, " REDUC_MIN_EXPR < ");
1543
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1544
      pp_string (buffer, " > ");
1545
      break;
1546
 
1547
    case REDUC_PLUS_EXPR:
1548
      pp_string (buffer, " REDUC_PLUS_EXPR < ");
1549
      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
1550
      pp_string (buffer, " > ");
1551
      break;
1552
 
1553
    default:
1554
      NIY;
1555
    }
1556
 
1557
  if (is_stmt && is_expr)
1558
    pp_semicolon (buffer);
1559
  pp_write_text_to_stream (buffer);
1560
 
1561
  return spc;
1562
}
1563
 
1564
/* Print the declaration of a variable.  */
1565
 
1566
static void
1567
print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
1568
{
1569
  INDENT (spc);
1570
 
1571
  if (TREE_CODE (t) == TYPE_DECL)
1572
    pp_string (buffer, "typedef ");
1573
 
1574
  if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t))
1575
    pp_string (buffer, "register ");
1576
 
1577
  if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
1578
    pp_string (buffer, "extern ");
1579
  else if (TREE_STATIC (t))
1580
    pp_string (buffer, "static ");
1581
 
1582
  /* Print the type and name.  */
1583
  if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1584
    {
1585
      tree tmp;
1586
 
1587
      /* Print array's type.  */
1588
      tmp = TREE_TYPE (t);
1589
      while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1590
        tmp = TREE_TYPE (tmp);
1591
      dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
1592
 
1593
      /* Print variable's name.  */
1594
      pp_space (buffer);
1595
      dump_generic_node (buffer, t, spc, flags, false);
1596
 
1597
      /* Print the dimensions.  */
1598
      tmp = TREE_TYPE (t);
1599
      while (TREE_CODE (tmp) == ARRAY_TYPE)
1600
        {
1601
          dump_array_domain (buffer, TYPE_DOMAIN (tmp), spc, flags);
1602
          tmp = TREE_TYPE (tmp);
1603
        }
1604
    }
1605
  else if (TREE_CODE (t) == FUNCTION_DECL)
1606
    {
1607
      dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
1608
      pp_space (buffer);
1609
      dump_decl_name (buffer, t, flags);
1610
      dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
1611
    }
1612
  else
1613
    {
1614
      /* Print type declaration.  */
1615
      dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
1616
 
1617
      /* Print variable's name.  */
1618
      pp_space (buffer);
1619
      dump_generic_node (buffer, t, spc, flags, false);
1620
    }
1621
 
1622
  if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
1623
    {
1624
      pp_string (buffer, " __asm__ ");
1625
      pp_character (buffer, '(');
1626
      dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
1627
      pp_character (buffer, ')');
1628
    }
1629
 
1630
  /* The initial value of a function serves to determine wether the function
1631
     is declared or defined.  So the following does not apply to function
1632
     nodes.  */
1633
  if (TREE_CODE (t) != FUNCTION_DECL)
1634
    {
1635
      /* Print the initial value.  */
1636
      if (DECL_INITIAL (t))
1637
        {
1638
          pp_space (buffer);
1639
          pp_character (buffer, '=');
1640
          pp_space (buffer);
1641
          dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
1642
        }
1643
    }
1644
 
1645
  pp_character (buffer, ';');
1646
}
1647
 
1648
 
1649
/* Prints a structure: name, fields, and methods.
1650
   FIXME: Still incomplete.  */
1651
 
1652
static void
1653
print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
1654
{
1655
  /* Print the name of the structure.  */
1656
  if (TYPE_NAME (node))
1657
    {
1658
      INDENT (spc);
1659
      if (TREE_CODE (node) == RECORD_TYPE)
1660
        pp_string (buffer, "struct ");
1661
      else if ((TREE_CODE (node) == UNION_TYPE
1662
                || TREE_CODE (node) == QUAL_UNION_TYPE))
1663
        pp_string (buffer, "union ");
1664
 
1665
      dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
1666
    }
1667
 
1668
  /* Print the contents of the structure.  */
1669
  pp_newline (buffer);
1670
  INDENT (spc);
1671
  pp_character (buffer, '{');
1672
  pp_newline (buffer);
1673
 
1674
  /* Print the fields of the structure.  */
1675
  {
1676
    tree tmp;
1677
    tmp = TYPE_FIELDS (node);
1678
    while (tmp)
1679
      {
1680
        /* Avoid to print recursively the structure.  */
1681
        /* FIXME : Not implemented correctly...,
1682
           what about the case when we have a cycle in the contain graph? ...
1683
           Maybe this could be solved by looking at the scope in which the
1684
           structure was declared.  */
1685
        if (TREE_TYPE (tmp) != node
1686
            || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1687
                && TREE_TYPE (TREE_TYPE (tmp)) != node))
1688
          {
1689
            print_declaration (buffer, tmp, spc+2, flags);
1690
            pp_newline (buffer);
1691
          }
1692
        tmp = TREE_CHAIN (tmp);
1693
      }
1694
  }
1695
  INDENT (spc);
1696
  pp_character (buffer, '}');
1697
}
1698
 
1699
/* Return the priority of the operator OP.
1700
 
1701
   From lowest to highest precedence with either left-to-right (L-R)
1702
   or right-to-left (R-L) associativity]:
1703
 
1704
     1  [L-R] ,
1705
     2  [R-L] = += -= *= /= %= &= ^= |= <<= >>=
1706
     3  [R-L] ?:
1707
     4  [L-R] ||
1708
     5  [L-R] &&
1709
     6  [L-R] |
1710
     7  [L-R] ^
1711
     8  [L-R] &
1712
     9  [L-R] == !=
1713
    10  [L-R] < <= > >=
1714
    11  [L-R] << >>
1715
    12  [L-R] + -
1716
    13  [L-R] * / %
1717
    14  [R-L] ! ~ ++ -- + - * & (type) sizeof
1718
    15  [L-R] fn() [] -> .
1719
 
1720
   unary +, - and * have higher precedence than the corresponding binary
1721
   operators.  */
1722
 
1723
static int
1724
op_prio (tree op)
1725
{
1726
  if (op == NULL)
1727
    return 9999;
1728
 
1729
  switch (TREE_CODE (op))
1730
    {
1731
    case TREE_LIST:
1732
    case COMPOUND_EXPR:
1733
    case BIND_EXPR:
1734
      return 1;
1735
 
1736
    case MODIFY_EXPR:
1737
    case INIT_EXPR:
1738
      return 2;
1739
 
1740
    case COND_EXPR:
1741
      return 3;
1742
 
1743
    case TRUTH_OR_EXPR:
1744
    case TRUTH_ORIF_EXPR:
1745
      return 4;
1746
 
1747
    case TRUTH_AND_EXPR:
1748
    case TRUTH_ANDIF_EXPR:
1749
      return 5;
1750
 
1751
    case BIT_IOR_EXPR:
1752
      return 6;
1753
 
1754
    case BIT_XOR_EXPR:
1755
    case TRUTH_XOR_EXPR:
1756
      return 7;
1757
 
1758
    case BIT_AND_EXPR:
1759
      return 8;
1760
 
1761
    case EQ_EXPR:
1762
    case NE_EXPR:
1763
      return 9;
1764
 
1765
    case UNLT_EXPR:
1766
    case UNLE_EXPR:
1767
    case UNGT_EXPR:
1768
    case UNGE_EXPR:
1769
    case UNEQ_EXPR:
1770
    case LTGT_EXPR:
1771
    case ORDERED_EXPR:
1772
    case UNORDERED_EXPR:
1773
    case LT_EXPR:
1774
    case LE_EXPR:
1775
    case GT_EXPR:
1776
    case GE_EXPR:
1777
      return 10;
1778
 
1779
    case LSHIFT_EXPR:
1780
    case RSHIFT_EXPR:
1781
    case LROTATE_EXPR:
1782
    case RROTATE_EXPR:
1783
      return 11;
1784
 
1785
    case PLUS_EXPR:
1786
    case MINUS_EXPR:
1787
      return 12;
1788
 
1789
    case MULT_EXPR:
1790
    case TRUNC_DIV_EXPR:
1791
    case CEIL_DIV_EXPR:
1792
    case FLOOR_DIV_EXPR:
1793
    case ROUND_DIV_EXPR:
1794
    case RDIV_EXPR:
1795
    case EXACT_DIV_EXPR:
1796
    case TRUNC_MOD_EXPR:
1797
    case CEIL_MOD_EXPR:
1798
    case FLOOR_MOD_EXPR:
1799
    case ROUND_MOD_EXPR:
1800
      return 13;
1801
 
1802
    case TRUTH_NOT_EXPR:
1803
    case BIT_NOT_EXPR:
1804
    case POSTINCREMENT_EXPR:
1805
    case POSTDECREMENT_EXPR:
1806
    case PREINCREMENT_EXPR:
1807
    case PREDECREMENT_EXPR:
1808
    case NEGATE_EXPR:
1809
    case ALIGN_INDIRECT_REF:
1810
    case MISALIGNED_INDIRECT_REF:
1811
    case INDIRECT_REF:
1812
    case ADDR_EXPR:
1813
    case FLOAT_EXPR:
1814
    case NOP_EXPR:
1815
    case CONVERT_EXPR:
1816
    case FIX_TRUNC_EXPR:
1817
    case FIX_CEIL_EXPR:
1818
    case FIX_FLOOR_EXPR:
1819
    case FIX_ROUND_EXPR:
1820
    case TARGET_EXPR:
1821
      return 14;
1822
 
1823
    case CALL_EXPR:
1824
    case ARRAY_REF:
1825
    case ARRAY_RANGE_REF:
1826
    case COMPONENT_REF:
1827
      return 15;
1828
 
1829
      /* Special expressions.  */
1830
    case MIN_EXPR:
1831
    case MAX_EXPR:
1832
    case ABS_EXPR:
1833
    case REALPART_EXPR:
1834
    case IMAGPART_EXPR:
1835
    case REDUC_MAX_EXPR:
1836
    case REDUC_MIN_EXPR:
1837
    case REDUC_PLUS_EXPR:
1838
    case VEC_LSHIFT_EXPR:
1839
    case VEC_RSHIFT_EXPR:
1840
      return 16;
1841
 
1842
    case SAVE_EXPR:
1843
    case NON_LVALUE_EXPR:
1844
      return op_prio (TREE_OPERAND (op, 0));
1845
 
1846
    default:
1847
      /* Return an arbitrarily high precedence to avoid surrounding single
1848
         VAR_DECLs in ()s.  */
1849
      return 9999;
1850
    }
1851
}
1852
 
1853
 
1854
/* Return the symbol associated with operator OP.  */
1855
 
1856
static const char *
1857
op_symbol (tree op)
1858
{
1859
  gcc_assert (op);
1860
 
1861
  switch (TREE_CODE (op))
1862
    {
1863
    case MODIFY_EXPR:
1864
      return "=";
1865
 
1866
    case TRUTH_OR_EXPR:
1867
    case TRUTH_ORIF_EXPR:
1868
      return "||";
1869
 
1870
    case TRUTH_AND_EXPR:
1871
    case TRUTH_ANDIF_EXPR:
1872
      return "&&";
1873
 
1874
    case BIT_IOR_EXPR:
1875
      return "|";
1876
 
1877
    case TRUTH_XOR_EXPR:
1878
    case BIT_XOR_EXPR:
1879
      return "^";
1880
 
1881
    case ADDR_EXPR:
1882
    case BIT_AND_EXPR:
1883
      return "&";
1884
 
1885
    case ORDERED_EXPR:
1886
      return "ord";
1887
    case UNORDERED_EXPR:
1888
      return "unord";
1889
 
1890
    case EQ_EXPR:
1891
      return "==";
1892
    case UNEQ_EXPR:
1893
      return "u==";
1894
 
1895
    case NE_EXPR:
1896
      return "!=";
1897
 
1898
    case LT_EXPR:
1899
      return "<";
1900
    case UNLT_EXPR:
1901
      return "u<";
1902
 
1903
    case LE_EXPR:
1904
      return "<=";
1905
    case UNLE_EXPR:
1906
      return "u<=";
1907
 
1908
    case GT_EXPR:
1909
      return ">";
1910
    case UNGT_EXPR:
1911
      return "u>";
1912
 
1913
    case GE_EXPR:
1914
      return ">=";
1915
    case UNGE_EXPR:
1916
      return "u>=";
1917
 
1918
    case LTGT_EXPR:
1919
      return "<>";
1920
 
1921
    case LSHIFT_EXPR:
1922
      return "<<";
1923
 
1924
    case RSHIFT_EXPR:
1925
      return ">>";
1926
 
1927
    case VEC_LSHIFT_EXPR:
1928
      return "v<<";
1929
 
1930
    case VEC_RSHIFT_EXPR:
1931
      return "v>>";
1932
 
1933
    case PLUS_EXPR:
1934
      return "+";
1935
 
1936
    case REDUC_PLUS_EXPR:
1937
      return "r+";
1938
 
1939
    case NEGATE_EXPR:
1940
    case MINUS_EXPR:
1941
      return "-";
1942
 
1943
    case BIT_NOT_EXPR:
1944
      return "~";
1945
 
1946
    case TRUTH_NOT_EXPR:
1947
      return "!";
1948
 
1949
    case MULT_EXPR:
1950
    case INDIRECT_REF:
1951
      return "*";
1952
 
1953
    case ALIGN_INDIRECT_REF:
1954
      return "A*";
1955
 
1956
    case MISALIGNED_INDIRECT_REF:
1957
      return "M*";
1958
 
1959
    case TRUNC_DIV_EXPR:
1960
    case RDIV_EXPR:
1961
      return "/";
1962
 
1963
    case CEIL_DIV_EXPR:
1964
      return "/[cl]";
1965
 
1966
    case FLOOR_DIV_EXPR:
1967
      return "/[fl]";
1968
 
1969
    case ROUND_DIV_EXPR:
1970
      return "/[rd]";
1971
 
1972
    case EXACT_DIV_EXPR:
1973
      return "/[ex]";
1974
 
1975
    case TRUNC_MOD_EXPR:
1976
      return "%";
1977
 
1978
    case CEIL_MOD_EXPR:
1979
      return "%[cl]";
1980
 
1981
    case FLOOR_MOD_EXPR:
1982
      return "%[fl]";
1983
 
1984
    case ROUND_MOD_EXPR:
1985
      return "%[rd]";
1986
 
1987
    case PREDECREMENT_EXPR:
1988
      return " --";
1989
 
1990
    case PREINCREMENT_EXPR:
1991
      return " ++";
1992
 
1993
    case POSTDECREMENT_EXPR:
1994
      return "-- ";
1995
 
1996
    case POSTINCREMENT_EXPR:
1997
      return "++ ";
1998
 
1999
    default:
2000
      return "<<< ??? >>>";
2001
    }
2002
}
2003
 
2004
/* Prints the name of a CALL_EXPR.  */
2005
 
2006
static void
2007
print_call_name (pretty_printer *buffer, tree node)
2008
{
2009
  tree op0;
2010
 
2011
  gcc_assert (TREE_CODE (node) == CALL_EXPR);
2012
 
2013
  op0 = TREE_OPERAND (node, 0);
2014
 
2015
  if (TREE_CODE (op0) == NON_LVALUE_EXPR)
2016
    op0 = TREE_OPERAND (op0, 0);
2017
 
2018
  switch (TREE_CODE (op0))
2019
    {
2020
    case VAR_DECL:
2021
    case PARM_DECL:
2022
      dump_function_name (buffer, op0);
2023
      break;
2024
 
2025
    case ADDR_EXPR:
2026
    case INDIRECT_REF:
2027
    case NOP_EXPR:
2028
      dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2029
      break;
2030
 
2031
    case COND_EXPR:
2032
      pp_string (buffer, "(");
2033
      dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2034
      pp_string (buffer, ") ? ");
2035
      dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
2036
      pp_string (buffer, " : ");
2037
      dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
2038
      break;
2039
 
2040
    case COMPONENT_REF:
2041
      /* The function is a pointer contained in a structure.  */
2042
      if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
2043
          TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2044
        dump_function_name (buffer, TREE_OPERAND (op0, 1));
2045
      else
2046
        dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
2047
      /* else
2048
         We can have several levels of structures and a function
2049
         pointer inside.  This is not implemented yet...  */
2050
      /*                  NIY;*/
2051
      break;
2052
 
2053
    case ARRAY_REF:
2054
      if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
2055
        dump_function_name (buffer, TREE_OPERAND (op0, 0));
2056
      else
2057
        dump_generic_node (buffer, op0, 0, 0, false);
2058
      break;
2059
 
2060
    case SSA_NAME:
2061
    case OBJ_TYPE_REF:
2062
      dump_generic_node (buffer, op0, 0, 0, false);
2063
      break;
2064
 
2065
    default:
2066
      NIY;
2067
    }
2068
}
2069
 
2070
/* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ...  */
2071
 
2072
static void
2073
pretty_print_string (pretty_printer *buffer, const char *str)
2074
{
2075
  if (str == NULL)
2076
    return;
2077
 
2078
  while (*str)
2079
    {
2080
      switch (str[0])
2081
        {
2082
        case '\b':
2083
          pp_string (buffer, "\\b");
2084
          break;
2085
 
2086
        case '\f':
2087
          pp_string (buffer, "\\f");
2088
          break;
2089
 
2090
        case '\n':
2091
          pp_string (buffer, "\\n");
2092
          break;
2093
 
2094
        case '\r':
2095
          pp_string (buffer, "\\r");
2096
          break;
2097
 
2098
        case '\t':
2099
          pp_string (buffer, "\\t");
2100
          break;
2101
 
2102
        case '\v':
2103
          pp_string (buffer, "\\v");
2104
          break;
2105
 
2106
        case '\\':
2107
          pp_string (buffer, "\\\\");
2108
          break;
2109
 
2110
        case '\"':
2111
          pp_string (buffer, "\\\"");
2112
          break;
2113
 
2114
        case '\'':
2115
          pp_string (buffer, "\\'");
2116
          break;
2117
 
2118
        case '\0':
2119
          pp_string (buffer, "\\0");
2120
          break;
2121
 
2122
        case '\1':
2123
          pp_string (buffer, "\\1");
2124
          break;
2125
 
2126
        case '\2':
2127
          pp_string (buffer, "\\2");
2128
          break;
2129
 
2130
        case '\3':
2131
          pp_string (buffer, "\\3");
2132
          break;
2133
 
2134
        case '\4':
2135
          pp_string (buffer, "\\4");
2136
          break;
2137
 
2138
        case '\5':
2139
          pp_string (buffer, "\\5");
2140
          break;
2141
 
2142
        case '\6':
2143
          pp_string (buffer, "\\6");
2144
          break;
2145
 
2146
        case '\7':
2147
          pp_string (buffer, "\\7");
2148
          break;
2149
 
2150
        default:
2151
          pp_character (buffer, str[0]);
2152
          break;
2153
        }
2154
      str++;
2155
    }
2156
}
2157
 
2158
static void
2159
maybe_init_pretty_print (FILE *file)
2160
{
2161
  if (!initialized)
2162
    {
2163
      pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
2164
      pp_needs_newline (&buffer) = true;
2165
      initialized = 1;
2166
    }
2167
 
2168
  buffer.buffer->stream = file;
2169
}
2170
 
2171
static void
2172
newline_and_indent (pretty_printer *buffer, int spc)
2173
{
2174
  pp_newline (buffer);
2175
  INDENT (spc);
2176
}
2177
 
2178
static void
2179
dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
2180
{
2181
  tree use;
2182
  use_operand_p use_p;
2183
  def_operand_p def_p;
2184
  use_operand_p kill_p;
2185
  ssa_op_iter iter;
2186
 
2187
  if (!ssa_operands_active ())
2188
    return;
2189
 
2190
  FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
2191
    {
2192
      pp_string (buffer, "#   ");
2193
      dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2194
                         spc + 2, flags, false);
2195
      pp_string (buffer, " = V_MAY_DEF <");
2196
      dump_generic_node (buffer, USE_FROM_PTR (use_p),
2197
                         spc + 2, flags, false);
2198
      pp_string (buffer, ">;");
2199
      newline_and_indent (buffer, spc);
2200
    }
2201
 
2202
  FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_p, stmt, iter)
2203
    {
2204
      pp_string (buffer, "#   ");
2205
      dump_generic_node (buffer, DEF_FROM_PTR (def_p),
2206
                         spc + 2, flags, false);
2207
      pp_string (buffer, " = V_MUST_DEF <");
2208
      dump_generic_node (buffer, USE_FROM_PTR (kill_p),
2209
                         spc + 2, flags, false);
2210
      pp_string (buffer, ">;");
2211
      newline_and_indent (buffer, spc);
2212
    }
2213
 
2214
  FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
2215
    {
2216
      pp_string (buffer, "#   VUSE <");
2217
      dump_generic_node (buffer, use, spc + 2, flags, false);
2218
      pp_string (buffer, ">;");
2219
      newline_and_indent (buffer, spc);
2220
    }
2221
}
2222
 
2223
/* Dumps basic block BB to FILE with details described by FLAGS and
2224
   indented by INDENT spaces.  */
2225
 
2226
void
2227
dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
2228
{
2229
  maybe_init_pretty_print (file);
2230
  dumping_stmts = true;
2231
  dump_generic_bb_buff (&buffer, bb, indent, flags);
2232
  pp_flush (&buffer);
2233
}
2234
 
2235
/* Dumps header of basic block BB to buffer BUFFER indented by INDENT
2236
   spaces and details described by flags.  */
2237
 
2238
static void
2239
dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
2240
{
2241
  edge e;
2242
  tree stmt;
2243
  edge_iterator ei;
2244
 
2245
  if (flags & TDF_BLOCKS)
2246
    {
2247
      INDENT (indent);
2248
      pp_string (buffer, "# BLOCK ");
2249
      pp_decimal_int (buffer, bb->index);
2250
      if (bb->frequency)
2251
        {
2252
          pp_string (buffer, " freq:");
2253
          pp_decimal_int (buffer, bb->frequency);
2254
        }
2255
      if (bb->count)
2256
        {
2257
          pp_string (buffer, " count:");
2258
          pp_widest_integer (buffer, bb->count);
2259
        }
2260
 
2261
      if (flags & TDF_LINENO)
2262
        {
2263
          block_stmt_iterator bsi;
2264
 
2265
          for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2266
            if (get_lineno (bsi_stmt (bsi)) != -1)
2267
              {
2268
                pp_string (buffer, ", starting at line ");
2269
                pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
2270
                break;
2271
              }
2272
        }
2273
      newline_and_indent (buffer, indent);
2274
 
2275
      pp_string (buffer, "# PRED:");
2276
      pp_write_text_to_stream (buffer);
2277
      FOR_EACH_EDGE (e, ei, bb->preds)
2278
        if (flags & TDF_SLIM)
2279
          {
2280
            pp_string (buffer, " ");
2281
            if (e->src == ENTRY_BLOCK_PTR)
2282
              pp_string (buffer, "ENTRY");
2283
            else
2284
              pp_decimal_int (buffer, e->src->index);
2285
          }
2286
        else
2287
          dump_edge_info (buffer->buffer->stream, e, 0);
2288
      pp_newline (buffer);
2289
    }
2290
  else
2291
    {
2292
      stmt = first_stmt (bb);
2293
      if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
2294
        {
2295
          INDENT (indent - 2);
2296
          pp_string (buffer, "<bb ");
2297
          pp_decimal_int (buffer, bb->index);
2298
          pp_string (buffer, ">:");
2299
          pp_newline (buffer);
2300
        }
2301
    }
2302
  pp_write_text_to_stream (buffer);
2303
  check_bb_profile (bb, buffer->buffer->stream);
2304
}
2305
 
2306
/* Dumps end of basic block BB to buffer BUFFER indented by INDENT
2307
   spaces.  */
2308
 
2309
static void
2310
dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
2311
{
2312
  edge e;
2313
  edge_iterator ei;
2314
 
2315
  INDENT (indent);
2316
  pp_string (buffer, "# SUCC:");
2317
  pp_write_text_to_stream (buffer);
2318
  FOR_EACH_EDGE (e, ei, bb->succs)
2319
    if (flags & TDF_SLIM)
2320
      {
2321
        pp_string (buffer, " ");
2322
        if (e->dest == EXIT_BLOCK_PTR)
2323
          pp_string (buffer, "EXIT");
2324
        else
2325
          pp_decimal_int (buffer, e->dest->index);
2326
      }
2327
    else
2328
      dump_edge_info (buffer->buffer->stream, e, 1);
2329
  pp_newline (buffer);
2330
}
2331
 
2332
/* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
2333
   FLAGS indented by INDENT spaces.  */
2334
 
2335
static void
2336
dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
2337
{
2338
  tree phi = phi_nodes (bb);
2339
  if (!phi)
2340
    return;
2341
 
2342
  for (; phi; phi = PHI_CHAIN (phi))
2343
    {
2344
      if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
2345
        {
2346
          INDENT (indent);
2347
          pp_string (buffer, "# ");
2348
          dump_generic_node (buffer, phi, indent, flags, false);
2349
          pp_newline (buffer);
2350
        }
2351
    }
2352
}
2353
 
2354
/* Dump jump to basic block BB that is represented implicitly in the cfg
2355
   to BUFFER.  */
2356
 
2357
static void
2358
pp_cfg_jump (pretty_printer *buffer, basic_block bb)
2359
{
2360
  tree stmt;
2361
 
2362
  stmt = first_stmt (bb);
2363
 
2364
  pp_string (buffer, "goto <bb ");
2365
  pp_decimal_int (buffer, bb->index);
2366
  pp_string (buffer, ">");
2367
  if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
2368
    {
2369
      pp_string (buffer, " (");
2370
      dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
2371
      pp_string (buffer, ")");
2372
    }
2373
  pp_semicolon (buffer);
2374
}
2375
 
2376
/* Dump edges represented implicitly in basic block BB to BUFFER, indented
2377
   by INDENT spaces, with details given by FLAGS.  */
2378
 
2379
static void
2380
dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
2381
                     int flags)
2382
{
2383
  edge e;
2384
  edge_iterator ei;
2385
 
2386
  /* If there is a fallthru edge, we may need to add an artificial goto to the
2387
     dump.  */
2388
  FOR_EACH_EDGE (e, ei, bb->succs)
2389
    if (e->flags & EDGE_FALLTHRU)
2390
      break;
2391
  if (e && e->dest != bb->next_bb)
2392
    {
2393
      INDENT (indent);
2394
 
2395
      if ((flags & TDF_LINENO)
2396
#ifdef USE_MAPPED_LOCATION
2397
          && e->goto_locus != UNKNOWN_LOCATION
2398
#else
2399
          && e->goto_locus
2400
#endif
2401
          )
2402
        {
2403
          expanded_location goto_xloc;
2404
#ifdef USE_MAPPED_LOCATION
2405
          goto_xloc = expand_location (e->goto_locus);
2406
#else
2407
          goto_xloc = *e->goto_locus;
2408
#endif
2409
          pp_character (buffer, '[');
2410
          if (goto_xloc.file)
2411
            {
2412
              pp_string (buffer, goto_xloc.file);
2413
              pp_string (buffer, " : ");
2414
            }
2415
          pp_decimal_int (buffer, goto_xloc.line);
2416
          pp_string (buffer, "] ");
2417
        }
2418
 
2419
      pp_cfg_jump (buffer, e->dest);
2420
      pp_newline (buffer);
2421
    }
2422
}
2423
 
2424
/* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
2425
   indented by INDENT spaces.  */
2426
 
2427
static void
2428
dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
2429
                      int indent, int flags)
2430
{
2431
  block_stmt_iterator bsi;
2432
  tree stmt;
2433
  int label_indent = indent - 2;
2434
 
2435
  if (label_indent < 0)
2436
    label_indent = 0;
2437
 
2438
  dump_bb_header (buffer, bb, indent, flags);
2439
 
2440
  dump_phi_nodes (buffer, bb, indent, flags);
2441
 
2442
  for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2443
    {
2444
      int curr_indent;
2445
 
2446
      stmt = bsi_stmt (bsi);
2447
 
2448
      curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
2449
 
2450
      INDENT (curr_indent);
2451
      dump_generic_node (buffer, stmt, curr_indent, flags, true);
2452
      pp_newline (buffer);
2453
    }
2454
 
2455
  dump_implicit_edges (buffer, bb, indent, flags);
2456
 
2457
  if (flags & TDF_BLOCKS)
2458
    dump_bb_end (buffer, bb, indent, flags);
2459
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.