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"
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. */
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. */
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. */
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)
/* 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. */
/* 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')
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:
}
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;
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);
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;
}