OSDN Git Service

* builtins.c (expand_builtin_setjmp_receiver): Const-ify.
[pf3gnuchains/gcc-fork.git] / gcc / c-dump.c
index 30b0816..c26f288 100644 (file)
@@ -2,22 +2,22 @@
    Copyright (C) 1999, 2000 Free Software Foundation, Inc.
    Written by Mark Mitchell <mark@codesourcery.com>
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-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 2, or (at your option)
-any later version.
+GCC 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 2, 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.
+GCC 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, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -40,7 +40,6 @@ static void dequeue_and_dump PARAMS ((dump_info_p));
 static void dump_new_line PARAMS ((dump_info_p));
 static void dump_maybe_newline PARAMS ((dump_info_p));
 static void dump_string_field PARAMS ((dump_info_p, const char *, const char *));
-static void dump_node PARAMS ((tree, FILE *));
 
 /* Add T to the end of the queue of nodes to dump.  Returns the index
    assigned to T.  */
@@ -139,6 +138,11 @@ queue_and_dump_type (di, t)
   queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
 }
 
+/* Dump column control */
+#define SOL_COLUMN 25          /* Start of line column.  */
+#define EOL_COLUMN 55          /* End of line column.  */
+#define COLUMN_ALIGNMENT 15    /* Alignment.  */
+
 /* Insert a new line in the dump output, and indent to an appropriate
    place to start printing more fields.  */
 
@@ -146,8 +150,8 @@ static void
 dump_new_line (di)
      dump_info_p di;
 {
-  fprintf (di->stream, "\n%25s", "");
-  di->column = 25;
+  fprintf (di->stream, "\n%*s", SOL_COLUMN, "");
+  di->column = SOL_COLUMN;
 }
 
 /* If necessary, insert a new line.  */
@@ -156,18 +160,33 @@ static void
 dump_maybe_newline (di)
      dump_info_p di;
 {
+  int extra;
+  
   /* See if we need a new line.  */
-  if (di->column > 53)
+  if (di->column > EOL_COLUMN)
     dump_new_line (di);
   /* See if we need any padding.  */
-  else if ((di->column - 25) % 14 != 0)
+  else if ((extra = (di->column - SOL_COLUMN) % COLUMN_ALIGNMENT) != 0)
     {
-      fprintf (di->stream, "%*s", 14 - ((di->column - 25) % 14), "");
-      di->column += 14 - (di->column - 25) % 14;
+      fprintf (di->stream, "%*s", COLUMN_ALIGNMENT - extra, "");
+      di->column += COLUMN_ALIGNMENT - extra;
     }
 }
 
-/* Dump I using FIELD to identity it.  */
+/* Dump pointer PTR using FIELD to identify it.  */
+
+void
+dump_pointer (di, field, ptr)
+     dump_info_p di;
+     const char *field;
+     void *ptr;
+{
+  dump_maybe_newline (di);
+  fprintf (di->stream, "%-4s: %-8lx ", field, (long) ptr);
+  di->column += 15;
+}
+
+/* Dump integer I using FIELD to identify it.  */
 
 void
 dump_int (di, field, i)
@@ -325,7 +344,7 @@ dequeue_and_dump (di)
       /* All declarations have names.  */
       if (DECL_NAME (t))
        dump_child ("name", DECL_NAME (t));
-      if (DECL_ASSEMBLER_NAME (t) 
+      if (DECL_ASSEMBLER_NAME_SET_P (t) 
          && DECL_ASSEMBLER_NAME (t) != DECL_NAME (t))
        dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
       /* And types.  */
@@ -349,7 +368,7 @@ dequeue_and_dump (di)
       /* And any declaration can be compiler-generated.  */
       if (DECL_ARTIFICIAL (t))
        dump_string (di, "artificial");
-      if (TREE_CHAIN (t))
+      if (TREE_CHAIN (t) && !dump_flag (di, TDF_SLIM, NULL))
        dump_child ("chan", TREE_CHAIN (t));
     }
   else if (code_class == 't')
@@ -504,6 +523,8 @@ dequeue_and_dump (di)
        dump_string (di, "extern");
       else
        dump_string (di, "static");
+      if (DECL_LANG_SPECIFIC (t) && !dump_flag (di, TDF_SLIM, t))
+       dump_child ("body", DECL_SAVED_TREE (t));
       break;
 
     case ASM_STMT:
@@ -707,15 +728,30 @@ dequeue_and_dump (di)
     }
 
  done:
+  if (dump_flag (di, TDF_ADDRESS, NULL))
+    dump_pointer (di, "addr", (void *)t);
+  
   /* Terminate the line.  */
   fprintf (di->stream, "\n");
 }
 
+/* Return non-zero if FLAG has been specified for the dump, and NODE
+   is not the root node of the dump.  */
+
+int dump_flag (di, flag, node)
+     dump_info_p di;
+     int flag;
+     tree node;
+{
+  return (di->flags & flag) && (node != di->node);
+}
+
 /* Dump T, and all its children, on STREAM.  */
 
-static void
-dump_node (t, stream)
+void
+dump_node (t, flags, stream)
      tree t;
+     int flags;
      FILE *stream;
 {
   struct dump_info di;
@@ -729,6 +765,8 @@ dump_node (t, stream)
   di.queue = 0;
   di.queue_end = 0;
   di.free_list = 0;
+  di.flags = flags;
+  di.node = t;
   di.nodes = splay_tree_new (splay_tree_compare_pointers, 0, 
                             (splay_tree_delete_value_fn) &free);
 
@@ -748,21 +786,148 @@ dump_node (t, stream)
   splay_tree_delete (di.nodes);
 }
 
-/* Dump T, and all its children, to FILE.  */
+/* Define a tree dump switch.  */
+struct dump_file_info
+{
+  const char *suffix;          /* suffix to give output file.  */
+  const char *swtch;           /* command line switch */
+  int flags;                   /* user flags */
+  int state;                   /* state of play */
+};
+
+/* Table of tree dump switches. This must be consistent with the
+   TREE_DUMP_INDEX enumeration in c-common.h */
+static struct dump_file_info dump_files[TDI_end] =
+{
+  {".tu", "dump-translation-unit", 0, 0},
+  {".class", "dump-class-hierarchy", 0, 0},
+  {".original", "dump-tree-original", 0, 0},
+  {".optimized", "dump-tree-optimized", 0, 0},
+  {".inlined", "dump-tree-inlined", 0, 0},
+};
+
+/* Define a name->number mapping for a dump flag value. */
+struct dump_option_value_info
+{
+  const char *const name;      /* the name of the value */
+  const int value;             /* the value of the name */
+};
+
+/* Table of dump options. This must be consistent with the TDF_* flags
+   in c-common.h */
+static const struct dump_option_value_info dump_options[] =
+{
+  {"address", TDF_ADDRESS},
+  {"slim", TDF_SLIM},
+  {"all", ~0},
+  {NULL, 0}
+};
+
+/* Begin a tree dump for PHASE. Stores any user supplied flag in
+   *FLAG_PTR and returns a stream to write to. If the dump is not
+   enabled, returns NULL.
+   Multiple calls will reopen and append to the dump file.  */
+
+FILE *
+dump_begin (phase, flag_ptr)
+     enum tree_dump_index phase;
+     int *flag_ptr;
+{
+  FILE *stream;
+  char *name;
+  
+  if (!dump_files[phase].state)
+    return NULL;
+  
+  name = concat (dump_base_name, dump_files[phase].suffix, NULL);
+  stream = fopen (name, dump_files[phase].state < 0 ? "w" : "a");
+  if (!stream)
+    error ("could not open dump file `%s'", name);
+  else
+    dump_files[phase].state = 1;
+  free (name);
+  if (flag_ptr)
+    *flag_ptr = dump_files[phase].flags;
+  
+  return stream;
+}
+
+/* Returns non-zero if tree dump PHASE is enabled.  */
+
+int
+dump_enabled_p (phase)
+     enum tree_dump_index phase;
+{
+  return dump_files[phase].state;
+}
+
+/* Returns the switch name of PHASE.  */
+
+const char *
+dump_flag_name (phase)
+     enum tree_dump_index phase;
+{
+  return dump_files[phase].swtch;
+}
+
+/* Finish a tree dump for PHASE. STREAM is the stream created by
+   dump_begin.  */
 
 void
-dump_node_to_file (t, file)
-     tree t;
-     const char *file;
+dump_end (phase, stream)
+     enum tree_dump_index phase ATTRIBUTE_UNUSED;
+     FILE *stream;
 {
-  FILE *f;
+  fclose (stream);
+}
 
-  f = fopen (file, "w");
-  if (!f)
-    error ("could not open dump file `%s'", file);
-  else
-    {
-      dump_node (t, f);
-      fclose (f);
-    }
+/* Parse ARG as a dump switch. Return non-zero if it is, and store the
+   relevant details in the dump_files array.  */
+
+int
+dump_switch_p (arg)
+     const char *arg;
+{
+  unsigned ix;
+  const char *option_value;
+  
+  for (ix = 0; ix != TDI_end; ix++)
+    if ((option_value = skip_leading_substring (arg, dump_files[ix].swtch)))
+      {
+       const char *ptr = option_value;
+       int flags = 0;
+       
+       while (*ptr)
+         {
+           const struct dump_option_value_info *option_ptr;
+           const char *end_ptr;
+           unsigned length;
+           
+           while (*ptr == '-')
+             ptr++;
+           end_ptr = strchr (ptr, '-');
+           if (!end_ptr)
+             end_ptr = ptr + strlen (ptr);
+           length = end_ptr - ptr;
+           
+           for (option_ptr = dump_options; option_ptr->name;
+                option_ptr++)
+             if (strlen (option_ptr->name) == length
+                 && !memcmp (option_ptr->name, ptr, length))
+               {
+                 flags |= option_ptr->value;
+                 goto found;
+               }
+           warning ("ignoring unknown option `%.*s' in `-f%s'",
+                    length, ptr, dump_files[ix].swtch);
+         found:;
+           ptr = end_ptr;
+         }
+       
+       dump_files[ix].state = -1;
+       dump_files[ix].flags = flags;
+       
+       return 1;
+      }
+  return 0;
 }