386BSD 0.0 development
authorWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Tue, 16 Jan 1990 23:22:25 +0000 (15:22 -0800)
committerWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Tue, 16 Jan 1990 23:22:25 +0000 (15:22 -0800)
Work on file usr/src/usr.bin/g++/cc1plus/print-tree.c

Co-Authored-By: Lynne Greer Jolitz <ljolitz@cardio.ucsf.edu>
Synthesized-from: 386BSD-0.0/src

usr/src/usr.bin/g++/cc1plus/print-tree.c [new file with mode: 0644]

diff --git a/usr/src/usr.bin/g++/cc1plus/print-tree.c b/usr/src/usr.bin/g++/cc1plus/print-tree.c
new file mode 100644 (file)
index 0000000..ecbb5f7
--- /dev/null
@@ -0,0 +1,673 @@
+/* Prints out tree in human readable form - GNU C-compiler
+   Copyright (C) 1987 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+
+#include "config.h"
+#include "tree.h"
+#include <stdio.h>
+
+extern char **tree_code_name;
+
+extern char *mode_name[];
+
+extern char spaces[];
+
+#define MIN(x,y) ((x < y) ? x : y)
+
+static FILE *outfile;
+
+extern int tree_node_counter;
+
+/* markvec[i] is 1 if node number i has been seen already.  */
+
+static char *markvec;
+
+static void dump ();
+void dump_tree ();
+
+void
+debug_dump_tree (root)
+     tree root;
+{
+  dump_tree (stderr, root);
+}
+
+void
+dump_tree (outf, root)
+     FILE *outf;
+     tree root;
+{
+  markvec = (char *) alloca (tree_node_counter + 1);
+  bzero (markvec, tree_node_counter + 1);
+  outfile = outf;
+  dump (root, 0);
+  fflush (outf);
+}
+\f
+static
+void
+wruid (node)
+     tree node;
+{
+  if (node == NULL)
+    fputs ("<>", outfile);
+  else {
+    fprintf (outfile, "%1d", TREE_UID (node));
+  }
+}
+
+static 
+void
+part (title, node)
+     char title[];
+     tree node;
+{
+  fprintf (outfile, " %s = ", title);
+  wruid (node);
+  putc (';', outfile);
+}
+
+/* Similar to `part' but prefix with @ if value is not constant
+   and print the constant value if it is constant.  */
+static
+void
+cpart (title, ct, punct)
+     char *title;
+     tree ct;
+     char punct;
+{
+  fprintf (outfile, " %s = ", title);
+  if (ct == NULL)
+    fputs ("<>", outfile);
+  else
+    {
+      if (!TREE_LITERAL (ct))
+       {
+         putc ('@', outfile);
+         wruid (ct);
+       }
+      else
+       fprintf (outfile, "%ld", TREE_INT_CST_LOW (ct));
+    }
+  putc (punct, outfile);
+}
+
+static void
+walk (node, leaf, indent)
+     tree node;
+     tree leaf;
+     int indent;
+{
+  if (node != NULL
+      /* Don't walk any global nodes reached from local nodes!
+        The global nodes will be dumped at the end, all together.
+        Also don't mention a FUNCTION_DECL node that is marked local
+        since it was fully described when it was dumped locally.  */
+      && (TREE_CODE (node) != FUNCTION_DECL
+         || TREE_PERMANENT (node))
+      && (TREE_PERMANENT (leaf) == TREE_PERMANENT (node)))
+    dump (node, indent+1);
+}
+
+static void
+cwalk (s, leaf, indent)
+     tree s;
+     tree leaf;
+     int indent;
+{
+  if (s != NULL) 
+    if (!TREE_LITERAL (s))
+      walk (s, leaf, indent);
+}
+\f 
+static void
+prtypeinfo (node)
+     register tree node;
+{
+  int first;
+  
+  part ("type", TREE_TYPE (node));
+  first = 1;
+  fputs (" [", outfile);
+  if (TREE_EXTERNAL (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("external", outfile);
+      first = 0;
+    }
+  if (TREE_PUBLIC (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("public", outfile);
+      first = 0;
+    }
+  if (TREE_STATIC (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("static", outfile);
+      first = 0;
+    }
+  if (TREE_VOLATILE (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("volatile", outfile);
+      first = 0;
+    }
+  if (TREE_PACKED (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("packed", outfile);
+      first = 0;
+    }
+  if (TREE_READONLY (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("readonly", outfile);
+      first = 0;
+    }
+  if (TREE_LITERAL (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("literal", outfile);
+      first = 0;
+    }
+  if (TREE_NONLOCAL (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("nonlocal", outfile);
+      first = 0;
+    }
+  if (TREE_ADDRESSABLE (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("addressable", outfile);
+      first = 0;
+    }
+  if (TREE_REGDECL (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("regdecl", outfile);
+      first = 0;
+    }
+  if (TREE_THIS_VOLATILE (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("this_vol", outfile);
+      first = 0;
+    }
+  if (TREE_UNSIGNED (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("unsigned", outfile);
+      first = 0;
+    }
+  if (TREE_ASM_WRITTEN (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("asm_written", outfile);
+      first = 0;
+    }
+  if (TREE_INLINE (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("inline", outfile);
+      first = 0;
+    }
+  if (TREE_USED (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("used", outfile);
+      first = 0;
+    }
+  if (TREE_PERMANENT (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("permanent", outfile);
+      first = 0;
+    }
+  if (TREE_LANG_FLAG_1 (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("lang_flag_1", outfile);
+      first = 0;
+    }
+  if (TREE_LANG_FLAG_2 (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("lang_flag_2", outfile);
+      first = 0;
+    }
+  if (TREE_LANG_FLAG_3 (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("lang_flag_3", outfile);
+      first = 0;
+    }
+  if (TREE_LANG_FLAG_4 (node))
+    {
+      if (!first) putc (' ', outfile);
+      fputs ("lang_flag_4", outfile);
+      first = 0;
+    }
+  fputs ("] ", outfile);
+}
+
+static void
+prdeclmodeinfo (node)
+     tree node;
+{
+  register enum machine_mode mode = DECL_MODE (node);
+  fprintf (outfile, " %s;", mode_name[(int) mode]);
+
+  cpart ("size", DECL_SIZE (node), '*');
+  fprintf (outfile, "%d;", DECL_SIZE_UNIT (node));
+
+  fprintf (outfile, " alignment = %1d;", DECL_ALIGN (node));
+}
+
+static void
+prtypemodeinfo (node)
+     tree node;
+{
+  register enum machine_mode mode = TYPE_MODE (node);
+  fprintf (outfile, " %s;", mode_name[(int) mode]);
+
+  cpart ("size", TYPE_SIZE (node), '*');
+  fprintf (outfile, "%d;", TYPE_SIZE_UNIT (node));
+
+  fprintf (outfile, " alignment = %1d;", TYPE_ALIGN (node));
+}
+
+static void
+skip (indent)
+     int indent;
+{
+  putc ('\n',outfile);
+  fputs (spaces + (strlen (spaces) - (12 + MIN (40,(indent+1)*2))), outfile);
+}
+\f
+/* Output a description of the tree node NODE
+   if its description has not been output already.  */
+
+static 
+void
+dump (node, indent)
+     tree node;
+     int indent;
+{
+  register enum tree_code code = TREE_CODE (node);
+  register int i;
+  register int len, first_rtl;
+  int nochain = 0;
+
+  if (markvec[TREE_UID (node)])
+    return;
+  markvec[TREE_UID (node)] = 1;
+
+  fputs ("   ", outfile);
+  fprintf (outfile, "%5d", TREE_UID (node));
+  fputs (spaces + (strlen (spaces) - MIN (40, (indent+1)*2)), outfile);
+  fputs (tree_code_name[(int) code], outfile);
+
+  switch (*tree_code_type[(int) code])
+    {
+    case 'd':
+      fputs (" name = ", outfile);
+      if (DECL_NAME (node) == NULL)
+       fputs ("<>;", outfile);
+      else
+       fprintf (outfile, "%s;",
+                IDENTIFIER_POINTER (DECL_NAME (node)));
+      if (code != PARM_DECL)
+       fprintf (outfile, " at %s line %d;",
+                DECL_SOURCE_FILE (node), DECL_SOURCE_LINE (node));
+      skip (indent);
+      prdeclmodeinfo (node);
+      prtypeinfo (node);
+#ifdef PRINT_LANG_DECL
+      print_lang_decl (node);
+#endif
+      skip (indent);
+      fprintf (outfile, " offset = %1d;", DECL_OFFSET (node));
+      if (DECL_VOFFSET (node) != NULL)
+       {
+         fputs ("voffset = ", outfile);
+         wruid (DECL_VOFFSET (node));
+         fprintf (outfile, "*%1d;", DECL_VOFFSET_UNIT (node));
+       }
+      part ("context", DECL_CONTEXT (node));
+      if (code == FUNCTION_DECL)
+       {
+         if (DECL_ARGUMENTS (node) || DECL_RESULT (node)
+             || DECL_INITIAL (node))
+           {
+             skip (indent);
+             part ("arguments", DECL_ARGUMENTS (node));
+             part ("result", DECL_RESULT (node));
+             if ((int) (DECL_INITIAL (node)) == 1)
+               fprintf (outfile, " initial = const 1;");
+             else
+               part ("initial", DECL_INITIAL (node));
+           }
+       }
+      else if (DECL_INITIAL (node))
+       {
+         if ((int) (DECL_INITIAL (node)) == 1)
+           fprintf (outfile, " initial = const 1;");
+         else
+           part ("initial", DECL_INITIAL (node));
+       }
+#ifdef PRINT_LANG_DECL
+      walk_lang_decl (node);
+#endif
+      part ("chain", TREE_CHAIN (node));
+      /* A Decl's chain contents is not part of the decl.  */
+      nochain = 1;
+      fputc ('\n', outfile);
+      cwalk (DECL_SIZE (node), node, indent);
+      walk (TREE_TYPE (node), node, indent);
+      walk (DECL_VOFFSET (node), node, indent);
+      walk (DECL_CONTEXT (node), node, indent);
+      if (code == FUNCTION_DECL)
+       {
+         walk (DECL_ARGUMENTS (node), node, indent);
+         walk (DECL_RESULT (node), node, indent);
+       }
+      if ((int) (DECL_INITIAL (node)) != 1)
+       walk (DECL_INITIAL (node), node, indent);
+      break;
+
+    case 't':
+      prtypemodeinfo (node);
+      prtypeinfo (node);
+#ifdef PRINT_LANG_TYPE
+      print_lang_type (node);
+#endif
+      skip (indent);
+      part ("pointers_to_this", TYPE_POINTER_TO (node));
+      if (code == ARRAY_TYPE || code == SET_TYPE)
+       {
+         part ("domain", TYPE_DOMAIN (node));
+         cpart ("separation", TYPE_SEP (node), '*');
+         fprintf (outfile, "%d;", TYPE_SEP_UNIT (node));
+       }
+      else if (code == INTEGER_TYPE)
+       {
+         cpart ("min", TYPE_MIN_VALUE (node), ';');
+         cpart ("max", TYPE_MAX_VALUE (node), ';');
+         fprintf (outfile, "precision = %d;", TYPE_PRECISION (node));
+       }
+      else if (code == ENUMERAL_TYPE)
+       {
+         cpart ("min", TYPE_MIN_VALUE (node), ';');
+         cpart ("max", TYPE_MAX_VALUE (node), ';');
+         part ("values", TYPE_VALUES (node));
+         fprintf (outfile, "precision = %d;", TYPE_PRECISION (node));
+       }
+      else if (code == REAL_TYPE)
+       {
+         fprintf (outfile, "precision = %d;", TYPE_PRECISION (node));
+       }
+      else if (code == RECORD_TYPE
+              || code == UNION_TYPE)
+       {
+         part ("fields", TYPE_FIELDS (node));
+       }
+      else if (code == FUNCTION_TYPE)
+       {
+         part ("arg_types", TYPE_ARG_TYPES (node));
+       }
+      else if (code == METHOD_TYPE)
+       {
+         part ("arg_types", TYPE_ARG_TYPES (node));
+       }
+#ifdef PRINT_LANG_TYPE
+      walk_lang_type (node);
+#endif
+      part ("chain", TREE_CHAIN (node));
+      /* A type's chain's contents are not printed because the chain of types
+        is not part of the meaning of any particular type.  */
+      nochain = 1;
+      fputc ('\n', outfile);
+      cwalk (TYPE_SIZE (node), node, indent);
+      walk (TREE_TYPE (node), node, indent);
+      walk (TYPE_VALUES (node), node, indent);
+      walk (TYPE_SEP (node), node, indent);
+      walk (TYPE_POINTER_TO (node), node, indent);
+      walk (TYPE_REFERENCE_TO (node), node, indent);
+      break;
+
+    case 'e':
+    case 'r':
+      prtypeinfo (node);
+      fputs (" ops =", outfile);
+      first_rtl = len = tree_code_length[(int) code];
+      /* These kinds of nodes contain rtx's, not trees,
+        after a certain point.  Print the rtx's as rtx's.  */
+      switch (code)
+       {
+       case SAVE_EXPR:
+         first_rtl = 1;
+         break;
+       case CALL_EXPR:
+         first_rtl = 2;
+         break;
+       case METHOD_CALL_EXPR:
+         first_rtl = 3;
+         break;
+       case WITH_CLEANUP_EXPR:
+         /* Should be defined to be 2.  */
+         first_rtl = 1;
+         break;
+       case RTL_EXPR:
+         first_rtl = 0;
+       }
+      for (i = 0; i < len; i++)
+       {
+         if (i >= first_rtl)
+           {
+             skip (indent);
+             if (TREE_OPERAND (node, i))
+               print_rtl (outfile, TREE_OPERAND (node, i));
+             else
+               fprintf (outfile, "(nil)");
+             fprintf (outfile, "\n");
+           }
+         else
+           {
+             fputs (" ", outfile);
+             wruid (TREE_OPERAND (node, i));
+             fputs (";", outfile);
+           }
+       }
+      part ("chain", TREE_CHAIN (node));
+      fputc ('\n', outfile);
+      walk (TREE_TYPE (node), node, indent);
+      for (i = 0; i < len && i < first_rtl; i++)
+       walk (TREE_OPERAND (node, i), node, indent);
+      break;
+
+    case 's':
+      prtypeinfo (node);
+      fprintf (outfile, " at %s line %d;",
+              STMT_SOURCE_FILE (node), STMT_SOURCE_LINE (node));
+      switch (TREE_CODE (node))
+       {
+       case IF_STMT:
+         part ("cond", STMT_COND (node));
+         part ("then", STMT_THEN (node));
+         part ("else", STMT_ELSE (node));
+         break;
+
+       case LET_STMT:
+       case WITH_STMT:
+         part ("vars", STMT_VARS (node));
+         part ("tags", STMT_TYPE_TAGS (node));
+         part ("supercontext", STMT_SUPERCONTEXT (node));
+         part ("bind_size", STMT_BIND_SIZE (node));
+         part ("body", STMT_BODY (node));
+         part ("subblocks", STMT_SUBBLOCKS (node));
+         break;
+
+       case CASE_STMT:
+         part ("case_index", STMT_CASE_INDEX (node));
+         part ("case_list", STMT_CASE_LIST (node));
+         break;
+
+       default:
+         part ("body", STMT_BODY (node));
+         break;
+       }
+      part ("chain", TREE_CHAIN (node));
+      fputc ('\n', outfile);
+      walk (TREE_TYPE (node), node, indent);
+      switch (TREE_CODE (node))
+       {
+       case IF_STMT:
+         walk (STMT_COND (node), node, indent);
+         walk (STMT_THEN (node), node, indent);
+         walk (STMT_ELSE (node), node, indent);
+         break;
+
+       case LET_STMT:
+       case WITH_STMT:
+         walk (STMT_VARS (node), node, indent);
+         walk (STMT_TYPE_TAGS (node), node, indent);
+         walk (STMT_SUPERCONTEXT (node), node, indent);
+         walk (STMT_BIND_SIZE (node), node, indent);
+         walk (STMT_BODY (node), node, indent);
+         walk (STMT_SUBBLOCKS (node), node, indent);
+         break;
+
+       case CASE_STMT:
+         walk (STMT_CASE_INDEX (node), node, indent);
+         walk (STMT_CASE_LIST (node), node, indent);
+         break;
+
+       default:
+         walk (STMT_BODY (node), node, indent);
+         break;
+       }
+      break;
+
+    case 'c':
+      switch (code)
+       {
+       case INTEGER_CST:
+         if (TREE_INT_CST_HIGH (node) == 0)
+           fprintf (outfile, " = %1u;", TREE_INT_CST_LOW (node));
+         else if (TREE_INT_CST_HIGH (node) == -1
+                  && TREE_INT_CST_LOW (node) != 0)
+           fprintf (outfile, " = -%1u;", -TREE_INT_CST_LOW (node));
+         else
+           fprintf (outfile, " = 0x%x%08x;",
+                    TREE_INT_CST_HIGH (node),
+                    TREE_INT_CST_LOW (node));
+         break;
+
+       case REAL_CST:
+#ifndef REAL_IS_NOT_DOUBLE
+         fprintf (outfile, " = %e;", TREE_REAL_CST (node));
+#else
+         {
+           int i;
+           char *p = (char *) &TREE_REAL_CST (node);
+           fprintf (outfile, " = 0x");
+           for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
+             fprintf (outfile, "%02x", *p++);
+           fprintf (outfile, ";");
+         }
+#endif /* REAL_IS_NOT_DOUBLE */
+         break;
+
+       case COMPLEX_CST:
+         part ("realpart", TREE_REALPART (node));
+         part ("imagpart", TREE_IMAGPART (node));
+         walk (TREE_REALPART (node), node, indent);
+         walk (TREE_IMAGPART (node), node, indent);
+         break;
+
+       case STRING_CST:
+         fprintf (outfile, " = \"%s\";", TREE_STRING_POINTER (node));
+       }
+      prtypeinfo (node);
+      part ("chain", TREE_CHAIN (node));
+      fputc ('\n', outfile);
+      walk (TREE_TYPE (node), node, indent);
+      break;
+
+    case 'x':
+      if (code == IDENTIFIER_NODE)
+       {
+         fprintf (outfile, " = %s;\n", IDENTIFIER_POINTER (node));
+         nochain = 1;
+       }
+      else if (code == TREE_LIST)
+       {
+         prtypeinfo (node);
+         part ("purpose", TREE_PURPOSE (node));
+         part ("value", TREE_VALUE (node));
+         part ("chain", TREE_CHAIN (node));
+         fputc ('\n', outfile);
+         walk (TREE_TYPE (node), node, indent);
+         walk (TREE_PURPOSE (node), node, indent);
+         walk (TREE_VALUE (node), node, indent);
+       }
+      else if (code == TREE_VEC)
+       {
+         prtypeinfo (node);
+         len = TREE_VEC_LENGTH (node);
+         fprintf (outfile, "length = %d\n", len);
+         for (i = 0; i < len; i++)
+           {
+             fputs (" ", outfile);
+             wruid (TREE_VEC_ELT (node, i));
+             fputs (";", outfile);
+           }
+         part ("chain", TREE_CHAIN (node));
+         fputc ('\n', outfile);
+         walk (TREE_TYPE (node), node, indent);
+         for (i = 0; i < len; i++)
+           walk (TREE_VEC_ELT (node, i), node, indent);
+       }
+      else if (code == OP_IDENTIFIER)
+       {
+         prtypeinfo (node);
+         part ("op1", TREE_PURPOSE (node));
+         part ("op2", TREE_VALUE (node));
+         part ("chain", TREE_CHAIN (node));
+         fputc ('\n', outfile);
+         walk (TREE_TYPE (node), node, indent);
+         walk (TREE_PURPOSE (node), node, indent);
+         walk (TREE_VALUE (node), node, indent);
+       }
+      else if (code == ERROR_MARK)
+       fputc ('\n', outfile);
+      else abort ();
+
+      break;
+
+    default:
+      abort ();
+    } /* switch */
+
+  if (TREE_CHAIN (node) != NULL && ! nochain)
+    dump (TREE_CHAIN (node), indent);
+}