SOURCES = $(INSTALL_HEADERS)
SOURCES += Makefile.in \
- ircons.c ircons_t.h irgmod.c irgraph_t.h irnode.c iropt.c irvrfy.c \
- irgwalk.c irgwalk_blk.c irdump.c irgopt.c irnode_t.h iropt_t.h \
+ ircons.c ircons_t.h irgmod.c irgraph_t.h irnode.c iropt.c iropt_t.h irvrfy.c \
+ irgwalk.c irgwalk_blk.c irdump.c irdumptxt.c irgopt.c irnode_t.h \
irmode.c irop.c irprog.c irflag.c irflag_t.h irgraph.c \
irmode_t.h irop_t.h irprog_t.h ircgcons.c ircgopt.c
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
+#include "firm_common_t.h"
+
#include "irnode_t.h"
#include "irgraph_t.h"
#include "irprog_t.h"
#include "entity_t.h"
#include "irop_t.h"
-#include "firm_common_t.h"
#include "irdump.h"
#endif
-int my_special_flag = 0;
+/* basis for a color range for vcg */
+static int n_colors = 0;
+static int base_color = 0;
static const char *get_mode_name_ex(ir_mode *mode, int *bad)
{
/* global and ahead declarations */
/*******************************************************************/
-/* A suffix to manipulate the file name. */
-
-char *dump_file_filter = "";
-
static void dump_whole_node(ir_node *n, void *env);
static INLINE void dump_loop_nodes_into_graph(FILE *F, ir_graph *irg);
/* flags to steer output */
/*******************************************************************/
+const char *dump_file_filter = "";
+
/* A compiler option to turn off edge labels */
int edge_label = 1;
/* A compiler option to turn off dumping values of constant entities */
return false;
}
+void only_dump_method_with_name(ident *name) {
+ dump_file_filter = get_id_str(name);
+}
+
+
/* To turn off display of edge labels. Edge labels offen cause xvcg to
abort with a segmentation fault. */
void turn_off_edge_labels(void) {
}
#define X(a) case a: fprintf(F, #a); break
-void dump_entity_node(FILE *F, entity *ent)
+void dump_entity_node(FILE *F, entity *ent, int color)
{
fprintf (F, "node: {title: \"");
PRINT_ENTID(ent); fprintf(F, "\"");
fprintf (F, DEFAULT_TYPE_ATTRIBUTE);
fprintf (F, "label: ");
- fprintf (F, "\"ent %s\" " ENTITY_NODE_ATTR , get_ent_dump_name(ent));
+ fprintf (F, "\"ent %s\" ", get_ent_dump_name(ent));
+ if (color)
+ fprintf(F, "color: %d", color);
+ else
+ fprintf (F, ENTITY_NODE_ATTR);
fprintf (F, "\n info1: \"");
- dump_entity_to_file(F, ent);
+ dump_entity_to_file(F, ent, dump_verbosity_max);
fprintf(F, "\"\n}\n");
}
entity *ent = (entity *)tore;
ir_node *value;
/* The node */
- dump_entity_node(F, ent);
+ dump_entity_node(F, ent, 0);
/* The Edges */
/* skip this to reduce graph. Member edge of type is parallel to this edge. *
fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
if (!is_method_type(get_entity_type(ent))) break; /* GL */
if (env->dump_ent && is_class_type(get_entity_owner(ent))) {
/* The node */
- dump_entity_node(F, ent);
+ dump_entity_node(F, ent, 0);
/* The edges */
print_type_ent_edge(F,get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
for(i = 0; i < get_entity_n_overwrites(ent); i++)
"infoname 2: \"Verification errors\"\n",
name, label, orientation);
+ /* don't use all, the range is too whith/black. */
+ n_colors = 18;
+ base_color = 105;
+ fprintf (F,
+ "colorentry 100: 0 0 0\n"
+ "colorentry 101: 20 0 0\n"
+ "colorentry 102: 40 0 0\n"
+ "colorentry 103: 60 0 0\n"
+ "colorentry 104: 80 0 0\n"
+ "colorentry 105: 100 0 0\n"
+ "colorentry 106: 120 0 0\n"
+ "colorentry 107: 140 0 0\n"
+ "colorentry 108: 150 0 0\n"
+ "colorentry 109: 180 0 0\n"
+ "colorentry 110: 200 0 0\n"
+ "colorentry 111: 220 0 0\n"
+ "colorentry 112: 240 0 0\n"
+ "colorentry 113: 255 0 0\n"
+ "colorentry 113: 255 20 20\n"
+ "colorentry 114: 255 40 40\n"
+ "colorentry 115: 255 60 60\n"
+ "colorentry 116: 255 80 80\n"
+ "colorentry 117: 255 100 100\n"
+ "colorentry 118: 255 120 120\n"
+ "colorentry 119: 255 140 140\n"
+ "colorentry 120: 255 150 150\n"
+ "colorentry 121: 255 180 180\n"
+ "colorentry 122: 255 200 200\n"
+ "colorentry 123: 255 220 220\n"
+ "colorentry 124: 255 240 240\n"
+ "colorentry 125: 255 250 250\n"
+ );
+
fprintf (F, "\n"); /* a separator */
}
char *suffix1;
rem = current_ir_graph;
- if(strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter))!=0) return;
+ if (strncmp(get_entity_name(get_irg_entity(irg)), dump_file_filter, strlen(dump_file_filter)) != 0) return;
current_ir_graph = irg;
if (interprocedural_view) suffix1 = "-pure-ip";
else suffix1 = "-pure";
current_ir_graph = rem;
}
+static int weight_overall(int rec, int loop) {
+ return 2*rec + loop;
+}
+
+static int compute_color (int my, int max) {
+ int color;
+ if (!max) {
+ color = 0;
+ } else {
+ /* if small, scale to the full color range. */
+ if (max < n_colors)
+ my = my * (n_colors/max);
+
+ int step = 1 + (max / n_colors);
+
+ color = my/step;
+ }
+ return base_color + n_colors - color;
+}
+
+static int get_entity_color(entity *ent) {
+ assert(get_entity_irg(ent));
+ ir_graph *irg = get_entity_irg(ent);
+
+ int rec_depth = get_irg_recursion_depth(irg);
+ int loop_depth = get_irg_loop_depth(irg);
+ int overall_depth = weight_overall(rec_depth, loop_depth);
+
+ int max_rec_depth = irp->max_callgraph_recursion_depth;
+ int max_loop_depth = irp->max_callgraph_loop_depth;
+ int max_overall_depth = weight_overall(max_rec_depth, max_loop_depth);
+
+ int my_rec_color = compute_color(rec_depth, max_rec_depth);
+ int my_loop_color = compute_color(loop_depth, max_loop_depth);
+ int my_overall_color = compute_color(overall_depth, max_overall_depth);;
+
+ return my_overall_color;
+}
+
void dump_callgraph(const char *suffix) {
FILE *F;
int i, n_irgs = get_irp_n_irgs();
int rem = edge_label;
edge_label = 1;
-
- my_special_flag = 1;
+ //ident *prefix = new_id_from_str("java/");
F = vcg_open_name("Callgraph", suffix);
dump_vcg_header(F, "Callgraph", NULL);
entity *ent = get_irg_entity(irg);
int j, n_callees = get_irg_n_callees(irg);
- dump_entity_node(F, ent);
+ /* Do not dump runtime system. */
+ //if (id_is_prefix(prefix, get_entity_ld_ident(ent))) continue;
+
+ dump_entity_node(F, ent, get_entity_color(ent));
for (j = 0; j < n_callees; ++j) {
entity *c = get_irg_entity(get_irg_callee(irg, j));
+ //if (id_is_prefix(prefix, get_entity_ld_ident(c))) continue;
int be = is_irg_callee_backedge(irg, j);
char *attr;
attr = (be) ?
- "label:\"recursion %d\" color:red" :
- "label:\"calls %d\"";
- print_ent_ent_edge(F, ent, c, be, attr, get_irg_callee_loop_depth(irg, j));
+ "label:\"recursion %d\" color: %d" :
+ "label:\"calls %d\" color: %d";
+ print_ent_ent_edge(F, ent, c, be, attr, get_irg_callee_loop_depth(irg, j), get_entity_color(ent));
}
}
- my_special_flag = 0;
edge_label = rem;
vcg_close(F);
}
current_ir_graph = rem;
}
-void dump_callgraph_loop_tree(char *suffix) {
+void dump_callgraph_loop_tree(const char *suffix) {
FILE *F;
F = vcg_open_name("Callgraph_looptree", suffix);
dump_vcg_header(F, "callgraph looptree", "top_to_bottom");
# include "irloop.h"
-/** Set this to the name (not the ld_name) of the method to be dumped. */
-extern char *dump_file_filter;
+/* **************************************************************************** */
+/* GRAPH DUMPERS */
+/* **************************************************************************** */
-/**
- * Dump a firm graph.
+/** Dump a firm graph.
*
* @param irg The firm graph to be dumped.
*
* @see turn_off_edge_labels()
*/
void dump_ir_graph (ir_graph *irg, const char *suffix);
-#define dump_cg_graph dump_ir_graph
-/**
- * Dump a firm graph without explicit block nodes.
+/** Dump a firm graph without explicit block nodes.
*
* @param irg The firm graph to be dumped.
*
* @see turn_off_edge_labels()
*/
void dump_ir_block_graph (ir_graph *irg, const char *suffix);
-#define dump_cg_block_graph dump_ir_block_graph
/** Dumps all graphs in interprocedural view to a file named All_graphs.vcg.
*/
void dump_all_cg_block_graph(const char *suffix);
-/**
- * Dumps a firm graph and all the type information needed for Calls,
+/** Dumps a firm graph and all the type information needed for Calls,
* Sels, ... in this graph.
*
* @param irg The firm graph to be dumped with its type information.
*/
void dump_ir_graph_w_types (ir_graph *irg, const char *suffix);
-/**
- * Dumps a firm graph and all the type information needed for Calls,
+/** Dumps a firm graph and all the type information needed for Calls,
* Sels, ... in this graph.
*
* @param irg The firm graph to be dumped with its type information.
*/
void dump_ir_block_graph_w_types (ir_graph *irg, const char *suffix);
-/**
- * The type of a walker function that is called for each graph.
+/** The type of a walker function that is called for each graph.
*
- * @param irg current visited graph
+ * @param irg current visited graph
*/
typedef void dump_graph_func(ir_graph *irg, const char *suffix);
-/**
- * A walker that calls a dumper for each graph.
+/** A walker that calls a dumper for each graph.
*
* @param dump_graph The dumper to be used for dumping.
*
void dump_all_ir_graphs (dump_graph_func *dump_graph, const char *suffix);
-/**
- * Dump the control flow graph of a procedure.
+/** Dump the control flow graph of a procedure.
*
* @param irg The firm graph whose CFG shall be dumped.
*
void dump_cfg (ir_graph *irg, const char *suffix);
+/* **************************************************************************** */
+/* CALLGRAPH DUMPERS */
+/* **************************************************************************** */
+
+
/** Dump the call graph.
*
* Dumps the callgraph to a file "Callgraph"<suffix>".vcg".
*/
void dump_callgraph(const char *suffix);
+/* **************************************************************************** */
+/* TYPEGRAPH DUMPERS */
+/* **************************************************************************** */
+
/**
* Dumps all the type information needed for Calls, Sels, ... in this graph.
* Does not dump the graph!
*/
void dump_type_graph (ir_graph *irg, const char *suffix);
-/**
- * Dumps all type information.
+/** Dumps all type information.
*
* @return
* A file containing all type information for the program in standard
*/
void dump_all_types (const char *suffix);
-/**
- * Dumps the class hierarchy with or without entities.
+/** Dumps the class hierarchy with or without entities.
*
* @param entities Flag whether to dump the entities.
*
*/
void dump_class_hierarchy (bool entities, const char *suffix);
+/* **************************************************************************** */
+/* LOOPTREE DUMPERS */
+/* **************************************************************************** */
/**
* Dump a standalone loop tree, which contains the loop nodes and the firm nodes
void dump_loop_tree(ir_graph *irg, const char *suffix);
/** Dumps the firm nodes in the sub-loop-tree of loop to a graph.
- * Dumps the loop nodes if dump_loop_information() is set.
*
+ * Dumps the loop nodes if dump_loop_information() is set.
* The name of the file is loop_<loop_nr><suffix>.vcg.
*
* @arg loop Dump the loop tree for this loop.
*
* @arg suffix Suffix to filename.
*/
-void dump_callgraph_loop_tree(char *suffix);
+void dump_callgraph_loop_tree(const char *suffix);
+
+
+/* **************************************************************************** */
+/* TEXT DUMPERS */
+/* **************************************************************************** */
+
+/** Verbosity for text dumpers */
+typedef enum {
+ dump_verbosity_onlynames = 0x00000001, /**< only dump type names. turns off all other
+ flags up to 0x00010000. */
+ dump_verbosity_fields = 0x00000002, /**< dump types and fields (like a type declaration) */
+ dump_verbosity_methods = 0x00000004, /**< dump types and methods (like a type declaration) */
+ dump_verbosity_typeattrs = 0x00000008, /**< dump all type attributes */
+ dump_verbosity_entattrs = 0x00000010, /**< dump all entity attributes */
+ dump_verbosity_entconsts = 0x00000020, /**< dump entity constants */
+
+ dump_verbosity_noClassTypes = 0x00001000, /**< dump no class types */
+ dump_verbosity_noStructTypes = 0x00002000, /**< dump no struct types */
+ dump_verbosity_noUnionTypes = 0x00004000, /**< dump no union types */
+ dump_verbosity_noArrayTypes = 0x00008000, /**< dump no array types */
+ dump_verbosity_noPointerTypes = 0x00010000, /**< dump no pointer types */
+ dump_verbosity_noMethodTypes = 0x00020000, /**< dump no method types */
+ dump_verbosity_noPrimitiveTypes = 0x00040000, /**< dump no primitive types */
+ dump_verbosity_noEnumerationTypes= 0x00080000, /**< dump no enumeration types */
+
+ dump_verbosity_onlyClassTypes = 0x000FE000, /**< dump only class types */
+ dump_verbosity_onlyStructTypes = 0x000FD000, /**< dump only struct types */
+ dump_verbosity_onlyUnionTypes = 0x000FB000, /**< dump only union types */
+ dump_verbosity_onlyArrayTypes = 0x000F8000, /**< dump only array types */
+ dump_verbosity_onlyPointerTypes = 0x000EF000, /**< dump only pointer types */
+ dump_verbosity_onlyMethodTypes = 0x000DF000, /**< dump only method types */
+ dump_verbosity_onlyPrimitiveTypes = 0x000BF000, /**< dump only primitive types */
+ dump_verbosity_onlyEnumerationTypes=0x0008F000, /**< dump only enumeration types */
+
+ dump_verbosity_max = 0x48888888, /**< turn on all verbosity. */
+} dump_verbosity;
+
+
+/** Write the entity and all its attributes to the passed file.
+ * */
+void dump_entity_to_file (FILE *F, entity *ent, unsigned verbosity);
+
+/** Write the entity and all its attributes to the stdout.
+ *
+ * Calls dump_entity_to_file(). */
+void dump_entity (entity *ent);
+
+/** Write the type and all its attributes to the file passed.
+ * */
+void dump_type_to_file (FILE *f, type *tp, unsigned verbosity);
+
+/** Write the type and all its attributes to stdout.
+ * */
+void dump_type (type *tp);
+
+
+/** Dump type information as text.
+ *
+ * Often type graphs are unhandy in their vcg representation. The text
+ * dumper represents the information for a single type more compact, but
+ * the relations between the types only implicitly.
+ * Dumps only 'real' types, i.e., those in the type list. Does not dump
+ * the global type nor frame types or the like.
+ *
+ * The file name is the program name (get_irp_name()), or 'TextTypes'
+ * if the program name is not set appended by <suffix>-types.txt.
+ */
+void dump_types_as_text(unsigned verbosity, const char *suffix);
+
+/* **************************************************************************** */
+/* FLAGS */
+/* **************************************************************************** */
+
+/** Output a selected graph.
+ *
+ * All graph dumpers check this name. If the name is != "" and
+ * not a prefix of the graph to be dumped, the dumper does not
+ * dump the graph.
+ *
+ * @param name The prefix of the name (not the ld_name) of the method
+ * entity to be dumped.
+ */
+void only_dump_method_with_name(ident *name);
/** Sets the vcg flag "display_edge_labels" to no.
*
/**
* If set to true constants will be replicated for every use. In non
- * blocked view edges from constant to block are scipped. Vcg then
+ * blocked view edges from constant to block are skipped. Vcg then
* layouts the graphs more compact, this makes them better readable.
* The flag is automatically and temporarily set to false if other
* edges are dumped, as outs, loop, ...
*/
bool get_opt_dump_const_local(void);
-/**
- * Turns off dumping the values of constant entities. Makes type graphs
+/** Turns off dumping the values of constant entities. Makes type graphs
* better readable.
*/
void turn_off_constant_entity_values(void);
-/**
- * Turns on dumping the edges from the End node to nodes to be kept
- * alive
+/** Turns on dumping the edges from the End node to nodes to be kept
+ * alive.
*/
void dump_keepalive_edges(bool b);
bool get_opt_dump_keepalive_edges(void);
-/**
- * Turns on dumping the out edges starting from the Start block in
- * dump_ir_graph. To test the consistency of the out datastructure.
+/** Turns on dumping the out edges starting from the Start block in
+ * dump_ir_graph.
+ *
+ * To test the consistency of the out datastructure.
*/
void dump_out_edges(void);
-/**
- * If this flag is set the dumper dumps edges to immediate dominator in cfg.
+/** If this flag is set the dumper dumps edges to immediate dominator in cfg.
*/
void dump_dominator_information(void);
-/**
- * If this flag is set the dumper dumps loop nodes and edges from
- * these nodes to the contained ir nodes.
- * Can be turned off with dont_dump_loop_information().
- * If the loops are interprocedural nodes can be missing.
+/** If this flag is set the dumper dumps loop nodes and edges from
+ * these nodes to the contained ir nodes.
+ *
+ * Can be turned off with dont_dump_loop_information().
+ * If the loops are interprocedural nodes can be missing.
*/
void dump_loop_information(void);
*/
void dont_dump_loop_information(void);
-/**
- * If set and backedge info is computed, backedges are dumped dashed
- * and as vcg 'backedge' construct. Default: set.
+/** If set and backedge info is computed, backedges are dumped dashed
+ * and as vcg 'backedge' construct.
+ *
+ * Default: set.
*/
void dump_backedge_information(bool b);
-/**
- * Dump the information of type field specified in ana/irtypeinfo.h.
+/** Dump the information of type field specified in ana/irtypeinfo.h.
+ *
* If the flag is set, the type name is output in [] in the node label,
* else it is output as info.
*/
void dump_analysed_type_info(bool b);
-/**
- * Write the address of a node into the vcg info.
- * This is off per default for automatic comparisons of
- * vcg graphs -- these will differ in the pointer values!
+/** Write the address of a node into the vcg info.
+ *
+ * This is off per default for automatic comparisons of
+ * vcg graphs -- these will differ in the pointer values!
*/
void dump_pointer_values_to_info(bool b);
--- /dev/null
+/*
+ * Project: libFIRM
+ * File name: ir/ir/irdump.c
+ * Purpose: Write vcg representation of firm to file.
+ * Author: Martin Trapp, Christian Schaefer
+ * Modified by: Goetz Lindenmaier, Hubert Schmidt
+ * Created:
+ * CVS-ID: $Id$
+ * Copyright: (c) 1998-2003 Universität Karlsruhe
+ * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "irdump.h"
+
+#include "firm_common_t.h"
+
+#include "irgraph_t.h"
+#include "irprog_t.h"
+#include "entity_t.h"
+
+int dump_node_opcode(FILE *F, ir_node *n); /* from irdump.c */
+
+
+
+#define X(a) case a: fprintf(F, #a); break
+void dump_entity_to_file_prefix (FILE *F, entity *ent, char *prefix, unsigned verbosity) {
+ int i, j;
+ assert(ent && ent->kind == k_entity);
+ type *owner = get_entity_owner(ent);
+ type *type = get_entity_type(ent);
+
+ if (verbosity & dump_verbosity_onlynames) {
+ fprintf(F, "%sentity %s (%ld)\n", prefix, get_entity_name(ent), get_entity_nr(ent));
+ return;
+ }
+
+ if (verbosity & dump_verbosity_entattrs) {
+ fprintf(F, "%sentity %s (%ld)\n", prefix, get_entity_name(ent), get_entity_nr(ent));
+ fprintf(F, "%s type: %s (%ld)\n", prefix, get_type_name(type), get_type_nr(type));
+ fprintf(F, "%s owner: %s (%ld)\n", prefix, get_type_name(owner), get_type_nr(owner));
+
+ if (is_class_type(get_entity_owner(ent))) {
+ if (get_entity_n_overwrites(ent) > 0) {
+ fprintf(F, "%s overwrites:\n", prefix);
+ for (i = 0; i < get_entity_n_overwrites(ent); ++i) {
+ entity *ov = get_entity_overwrites(ent, i);
+ fprintf(F, "%s %d: %s of class %s\n", prefix, i, get_entity_name(ov),
+ get_type_name(get_entity_owner(ov)));
+ }
+ } else {
+ fprintf(F, "%s Does not overwrite other entities. \n", prefix);
+ }
+ if (get_entity_n_overwrittenby(ent) > 0) {
+ fprintf(F, "%s overwritten by:\n", prefix);
+ for (i = 0; i < get_entity_n_overwrittenby(ent); ++i) {
+ entity *ov = get_entity_overwrittenby(ent, i);
+ fprintf(F, "%s %d: %s of class %s\n", prefix, i, get_entity_name(ov),
+ get_type_name(get_entity_owner(ov)));
+ }
+ } else {
+ fprintf(F, "%s Is not overwriten by other entities. \n", prefix);
+ }
+ }
+
+ fprintf(F, "%s allocation: ", prefix);
+ switch (get_entity_allocation(ent)) {
+ X(allocation_dynamic);
+ X(allocation_automatic);
+ X(allocation_static);
+ X(allocation_parameter);
+ }
+
+ fprintf(F, "\n%s visibility: ", prefix);
+ switch (get_entity_visibility(ent)) {
+ X(visibility_local);
+ X(visibility_external_visible);
+ X(visibility_external_allocated);
+ }
+
+ fprintf(F, "\n%s variability: ", prefix);
+ switch (get_entity_variability(ent)) {
+ X(variability_uninitialized);
+ X(variability_initialized);
+ X(variability_part_constant);
+ X(variability_constant);
+ }
+ fprintf(F, "\n");
+ } else { /* no entityattrs */
+ fprintf(F, "%s(%3d) %*s: %s", prefix,
+ get_entity_offset_bits(ent), -40, get_type_name(get_entity_type(ent)), get_entity_name(ent));
+ if (is_method_type(get_entity_type(ent))) fprintf(F, "(...)");
+ fprintf(F, "\n");
+ }
+
+ if (verbosity & dump_verbosity_entconsts) {
+ if (get_entity_variability(ent) != variability_uninitialized) {
+ if (is_atomic_entity(ent)) {
+ fprintf(F, "%s atomic value: ", prefix);
+ dump_node_opcode(F, get_atomic_ent_value(ent));
+ } else {
+ fprintf(F, "%s compound values:", prefix);
+ for (i = 0; i < get_compound_ent_n_values(ent); ++i) {
+ compound_graph_path *path = get_compound_ent_value_path(ent, i);
+ entity *ent0 = get_compound_graph_path_node(path, 0);
+ fprintf(F, "\n%s %3d ", prefix, get_entity_offset_bits(ent0));
+ if (get_type_state(type) == layout_fixed)
+ fprintf(F, "(%3d) ", get_compound_ent_value_offset_bits(ent, i));
+ fprintf(F, "%s", get_entity_name(ent0));
+ for (j = 0; j < get_compound_graph_path_length(path); ++j) {
+ entity *node = get_compound_graph_path_node(path, j);
+ fprintf(F, ".%s", get_entity_name(node));
+ if (is_array_type(get_entity_owner(node)))
+ fprintf(F, "[%d]", get_compound_graph_path_array_index(path, j));
+ }
+ fprintf(F, "\t = ");
+ dump_node_opcode(F, get_compound_ent_value(ent, i));
+ }
+ }
+ fprintf(F, "\n");
+ }
+ }
+
+
+ if (verbosity & dump_verbosity_entattrs) {
+ fprintf(F, "%s volatility: ", prefix);
+ switch (get_entity_volatility(ent)) {
+ X(volatility_non_volatile);
+ X(volatility_is_volatile);
+ }
+
+ fprintf(F, "\n%s peculiarity: %s", prefix, get_peculiarity_string(get_entity_peculiarity(ent)));
+ fprintf(F, "\n%s ld_name: %s", prefix, ent->ld_name ? get_entity_ld_name(ent) : "no yet set");
+ fprintf(F, "\n%s offset: %d", prefix, get_entity_offset_bits(ent));
+ if (is_method_type(get_entity_type(ent))) {
+ if (get_entity_irg(ent)) /* can be null */ {
+ fprintf(F, "\n%s irg = %ld", prefix, get_irg_graph_nr(get_entity_irg(ent)));
+ if (get_irp_callgraph_state() == irp_callgraph_and_calltree_consistent) {
+ fprintf(F, "\n%s recursion depth %d", prefix, get_irg_recursion_depth(get_entity_irg(ent)));
+ fprintf(F, "\n%s loop depth %d", prefix, get_irg_loop_depth(get_entity_irg(ent)));
+ }
+ } else {
+ fprintf(F, "\n%s irg = NULL", prefix);
+ }
+ }
+ fprintf(F, "\n");
+ }
+}
+#undef X
+
+void dump_entity_to_file (FILE *F, entity *ent, unsigned verbosity) {
+ dump_entity_to_file_prefix (F, ent, "", verbosity);
+ fprintf(F, "\n");
+}
+
+void dump_entity (entity *ent) {
+ dump_entity_to_file(stdout, ent, dump_verbosity_max);
+}
+
+void dump_type_to_file (FILE *F, type *tp, dump_verbosity verbosity) {
+ int i;
+
+ if ((is_class_type(tp)) && (verbosity & dump_verbosity_noClassTypes)) return;
+ if ((is_struct_type(tp)) && (verbosity & dump_verbosity_noStructTypes)) return;
+ if ((is_union_type(tp)) && (verbosity & dump_verbosity_noUnionTypes)) return;
+ if ((is_array_type(tp)) && (verbosity & dump_verbosity_noArrayTypes)) return;
+ if ((is_pointer_type(tp)) && (verbosity & dump_verbosity_noPointerTypes)) return;
+ if ((is_method_type(tp)) && (verbosity & dump_verbosity_noMethodTypes)) return;
+ if ((is_primitive_type(tp)) && (verbosity & dump_verbosity_noPrimitiveTypes)) return;
+ if ((is_enumeration_type(tp)) && (verbosity & dump_verbosity_noEnumerationTypes)) return;
+
+ fprintf(F, "%s type %s (%ld)", get_tpop_name(get_type_tpop(tp)), get_type_name(tp), get_type_nr(tp));
+ if (verbosity & dump_verbosity_onlynames) { fprintf(F, "\n"); return; }
+
+ switch (get_type_tpop_code(tp)) {
+
+ case tpo_class:
+ if ((verbosity & dump_verbosity_methods) || (verbosity & dump_verbosity_fields)) {
+ fprintf(F, "\n members: \n");
+ }
+ for (i = 0; i < get_class_n_members(tp); ++i) {
+ entity *mem = get_class_member(tp, i);
+ if (((verbosity & dump_verbosity_methods) && is_method_type(get_entity_type(mem))) ||
+ ((verbosity & dump_verbosity_fields) && !is_method_type(get_entity_type(mem))) ) {
+ dump_entity_to_file_prefix(F, mem, " ", verbosity);
+ }
+ }
+ if (verbosity & dump_verbosity_typeattrs) {
+ fprintf(F, " supertypes: ");
+ for (i = 0; i < get_class_n_supertypes(tp); ++i) {
+ type *stp = get_class_supertype(tp, i);
+ fprintf(F, "\n %s", get_type_name(stp));
+ }
+ fprintf(F, "\n subtypes: ");
+ for (i = 0; i < get_class_n_subtypes(tp); ++i) {
+ type *stp = get_class_subtype(tp, i);
+ fprintf(F, "\n %s", get_type_name(stp));
+ }
+
+ fprintf(F, "\n peculiarity: %s", get_peculiarity_string(get_class_peculiarity(tp)));
+ }
+ break;
+
+ case tpo_union:
+ case tpo_struct:
+ if (verbosity & dump_verbosity_fields) fprintf(F, "\n members: ");
+ for (i = 0; i < get_compound_n_members(tp); ++i) {
+ entity *mem = get_compound_member(tp, i);
+ if (verbosity & dump_verbosity_fields) {
+ dump_entity_to_file_prefix(F, mem, " ", verbosity);
+ }
+ }
+ break;
+
+ case tpo_pointer: {
+ if (verbosity & dump_verbosity_typeattrs) {
+ type *tt = get_pointer_points_to_type(tp);
+ fprintf(F, "\n points to %s (%ld)", get_type_name(tt), get_type_nr(tt));
+ }
+
+ } break;
+
+ default:
+ if (verbosity & dump_verbosity_typeattrs) {
+ fprintf(F, ": details not implemented\n");
+ }
+ }
+ fprintf(F, "\n\n");
+}
+
+void dump_type(type *tp) {
+ dump_type_to_file (stdout, tp, dump_verbosity_max);
+}
+
+
+
+static FILE *text_open (const char *basename, const char * suffix1, const char *suffix2) {
+ FILE *F;
+ int len = strlen(basename), i, j;
+ char *fname; /* filename to put the vcg information in */
+
+ if (!basename) assert(basename);
+ if (!suffix1) suffix1 = "";
+ if (!suffix2) suffix2 = "";
+
+ /* open file for vcg graph */
+ fname = malloc (strlen(basename)*2 + strlen(suffix1) + strlen(suffix2) + 5); /* *2: space for excapes. */
+
+ j = 0;
+ for (i = 0; i < len; ++i) { /* replase '/' in the name: escape by @. */
+ if (basename[i] == '/') {
+ fname[j] = '@'; j++; fname[j] = '1'; j++;
+ } else if (basename[i] == '@') {
+ fname[j] = '@'; j++; fname[j] = '2'; j++;
+ } else {
+ fname[j] = basename[i]; j++;
+ }
+ }
+ fname[j] = '\0';
+ strcat (fname, suffix1); /* append file suffix */
+ strcat (fname, suffix2); /* append file suffix */
+ strcat (fname, ".txt"); /* append the .txt suffix */
+
+ F = fopen (fname, "w"); /* open file for writing */
+ if (!F) {
+ assert(0);
+ }
+ free(fname);
+
+ return F;
+}
+
+void dump_types_as_text(unsigned verbosity, const char *suffix) {
+ const char *basename;
+ FILE *F;
+ int i, n_types = get_irp_n_types();
+
+ if (get_irp_prog_ident() == new_id_from_str("no_name_set")) {
+ basename = "TextTypes";
+ } else {
+ basename = get_irp_prog_name();
+ }
+ F = text_open (basename, suffix, "-types");
+
+ for (i = 0; i < n_types; ++i) {
+ type *t = get_irp_type(i);
+ dump_type_to_file(F, t, verbosity);
+ }
+
+ fclose (F);
+}