Added block successor edges to the iredges module.
[libfirm] / ir / ir / irargs.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/ir/irargs.c
4  * Purpose:     Support for libcore IR object output.
5  * Author:      Sebastian Hack
6  * Modified by:
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1998-2005 Universit�t Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif
16
17 #include "bitset.h"
18
19 #include <ctype.h>
20 #include <libcore/xprintf.h>
21
22 #include "firm_common.h"
23 #include "irnode_t.h"
24 #include "entity_t.h"
25 #include "irloop_t.h"
26 #include "tv_t.h"
27
28 /**
29  * identify a firm object type
30  */
31 static int firm_get_arg_type(const arg_occ_t *occ) {
32   /* Firm objects are always pointer */
33   return arg_type_ptr;
34 }
35
36 static int firm_get_arg_type_int(const arg_occ_t *occ) {
37   return arg_type_int;
38 }
39
40
41 static int bitset_get_arg_type(const arg_occ_t *occ) {
42   return arg_type_ptr;
43 }
44
45 static int bitset_emit(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
46 {
47   int res = 2;
48   bitset_t *b = arg->v_ptr;
49   bitset_pos_t p;
50   char buf[32];
51   const char *prefix = "";
52
53   arg_append(app, occ, "[", 1);
54   for(p = bitset_next_set(b, 0); p != -1; p = bitset_next_set(b, p)) {
55     int n;
56
57     n = snprintf(buf, sizeof(buf), "%s%d", prefix, (int) p);
58     arg_append(app, occ, buf, n);
59     prefix = ", ";
60     res += n;
61   }
62   arg_append(app, occ, "]", 1);
63
64   return res;
65 }
66
67 /**
68  * emit a Firm object
69  */
70 static int firm_emit(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
71 {
72 #define A(s)    occ->flag_hash ? s " ": ""
73
74   void *X = arg->v_ptr;
75   firm_kind *obj = X;
76   int i, n;
77   ir_node *block;
78         char add[64];
79   char buf[256];
80   char tv[256];
81
82   buf[0] = '\0';
83   add[0] = '\0';
84
85   if (! X)
86     strncpy(buf, "(null)", sizeof(buf));
87   else {
88     switch (*obj) {
89     case k_BAD:
90       snprintf(buf, sizeof(buf), "BAD");
91       snprintf(add, sizeof(add), "[%p]", X);
92       break;
93     case k_entity:
94       snprintf(buf, sizeof(buf), "%s%s", A("ent"),
95           isupper(occ->conversion) ? get_entity_ld_name(X): get_entity_name(X));
96       snprintf(add, sizeof(add), "[%ld]", get_entity_nr(X));
97       break;
98     case k_type:
99       snprintf(buf, sizeof(buf), "%s%s:%s", A("type"), get_type_tpop_name(X), get_type_name(X));
100       snprintf(add, sizeof(add), "[%ld]", get_type_nr(X));
101       break;
102     case k_ir_graph:
103       snprintf(buf, sizeof(buf), "%s%s", A("irg"), get_entity_name(get_irg_entity(X)));
104       snprintf(add, sizeof(add), "[%ld]", get_irg_graph_nr(X));
105       break;
106     case k_ir_node:
107       switch (occ->conversion) {
108       case 'B':
109         block = is_no_Block(X) ? get_nodes_block(X) : X;
110         snprintf(buf, sizeof(buf), "%s%s%s", A("irn"), get_irn_opname(block),
111             get_mode_name(get_irn_mode(block)));
112         snprintf(add, sizeof(add), "[%ld]", get_irn_node_nr(block));
113         break;
114       case 'N':
115         snprintf(buf, sizeof(buf), "%ld", get_irn_node_nr(X));
116         break;
117       default:
118         snprintf(buf, sizeof(buf), "%s%s%s", A("irn"), get_irn_opname(X),
119             get_mode_name(get_irn_mode(X)));
120         snprintf(add, sizeof(add), "[%ld]", get_irn_node_nr(X));
121       }
122       break;
123     case k_ir_mode:
124       snprintf(buf, sizeof(buf), "%s%s", A("mode"), get_mode_name(X));
125       break;
126     case k_tarval:
127       tarval_snprintf(tv, sizeof(tv), X);
128       snprintf(buf, sizeof(buf), "%s%s", A("tv"), tv);
129       break;
130     case k_ir_loop:
131       snprintf(buf, sizeof(buf), "ldepth[%d]", get_loop_depth(X));
132       break;
133     case k_ir_op:
134       snprintf(buf, sizeof(buf), "%s%s", A("op"), get_op_name(X));
135       break;
136     case k_ir_compound_graph_path:
137       strncat(buf, A("cgp"), sizeof(buf));
138
139       n = get_compound_graph_path_length(X);
140       for (i = 0; i < n; ++i) {
141         entity *ent = get_compound_graph_path_node(X, i);
142         strncat(buf, get_entity_name(ent), sizeof(buf));
143         if (i < n - 1)
144           strncat(buf, ".", sizeof(buf));
145       }
146       break;
147     default:
148       snprintf(buf, sizeof(buf), "UNKWN");
149       snprintf(add, sizeof(add), "[%p]", X);
150     }
151   }
152
153   if(occ->flag_plus)
154         strncat(buf, add, sizeof(buf));
155
156   return arg_append(app, occ, buf, strlen(buf));
157
158 #undef A
159 }
160
161 /**
162  * emit an ident
163  */
164 static int firm_emit_ident(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
165 {
166   ident *id = (ident *)arg->v_ptr;
167   const char *p = id ? get_id_str(id) : "(null)";
168
169   return arg_append(app, occ, p, strlen(p));
170 }
171
172
173
174 /**
175  * Emit indent.
176  */
177 static int firm_emit_indent(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
178 {
179         int i;
180         int amount = arg->v_int;
181
182         for(i = 0; i < amount; ++i)
183                 appendable_chadd(app, ' ');
184
185         return amount;
186 }
187
188 arg_env_t *firm_get_arg_env(void)
189 {
190 #define X(name, letter) {"firm:" name, letter}
191
192   static arg_env_t *env = NULL;
193
194   static arg_handler_t firm_handler   = { firm_get_arg_type, firm_emit };
195   static arg_handler_t ident_handler  = { firm_get_arg_type, firm_emit_ident };
196   static arg_handler_t indent_handler = { firm_get_arg_type_int, firm_emit_indent };
197   static arg_handler_t bitset_handler = { bitset_get_arg_type, bitset_emit };
198
199   static struct {
200     const char *name;
201     char letter;
202   } args[] = {
203     X("type",      't'),
204     X("entity",    'e'),
205     X("entity_ld", 'E'),
206     X("tarval",    'T'),
207     X("irn",       'n'),
208     X("op",        'O'),
209     X("irn_nr",    'N'),
210     X("mode",      'm'),
211     X("block",     'B'),
212   };
213
214   int i;
215
216   if(env == NULL) {
217     env = arg_new_env();
218     arg_add_std(env);
219
220                 arg_register(env, "firm", 'F', &firm_handler);
221     for (i = 0; i < sizeof(args)/sizeof(args[0]); ++i)
222       arg_register(env, args[i].name, args[i].letter, &firm_handler);
223
224     arg_register(env, "firm:ident", 'I', &ident_handler);
225                 arg_register(env, "firm:indent", 'D', &indent_handler);
226                 /* arg_register(env, "firm:bitset", 'b', &bitset_handler); */
227   }
228
229   return env;
230 }