fixed iterator type
[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 Universitaet 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 #include "dbginfo_t.h"
28
29 /**
30  * identify a firm object type
31  */
32 static int firm_get_arg_type(const arg_occ_t *occ) {
33   /* Firm objects are always pointer */
34   return arg_type_ptr;
35 }
36
37 static int firm_get_arg_type_int(const arg_occ_t *occ) {
38   return arg_type_int;
39 }
40
41
42 static int bitset_get_arg_type(const arg_occ_t *occ) {
43   return arg_type_ptr;
44 }
45
46 static int bitset_emit(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
47 {
48   int res = 2;
49   bitset_t *b = arg->v_ptr;
50   bitset_pos_t p;
51   char buf[32];
52   const char *prefix = "";
53
54   arg_append(app, occ, "[", 1);
55   for(p = bitset_next_set(b, 0); p != -1; p = bitset_next_set(b, p)) {
56     int n;
57
58     n = snprintf(buf, sizeof(buf), "%s%d", prefix, (int) p);
59     arg_append(app, occ, buf, n);
60     prefix = ", ";
61     res += n;
62   }
63   arg_append(app, occ, "]", 1);
64
65   return res;
66 }
67
68 /**
69  * emit an opaque Firm dbg_info object
70  */
71 static int firm_emit_dbg(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
72 {
73   char buf[1024];
74   ir_node *irn = arg->v_ptr;
75   dbg_info *dbg = get_irn_dbg_info(irn);
76
77   buf[0] = '\0';
78   if (dbg && __dbg_info_snprint) {
79     if (__dbg_info_snprint(buf, sizeof(buf), dbg) <= 0)
80       buf[0] = '\0';
81   }
82   return arg_append(app, occ, buf, strlen(buf));
83 }
84
85 /**
86  * emit a Firm object
87  */
88 static int firm_emit(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
89 {
90 #define A(s)    occ->flag_hash ? s " ": ""
91
92   void *X = arg->v_ptr;
93   firm_kind *obj = X;
94   int i, n;
95   ir_node *block;
96   char add[64];
97   char buf[256];
98   char tv[256];
99
100   buf[0] = '\0';
101   add[0] = '\0';
102
103   if (! X)
104     strncpy(buf, "(null)", sizeof(buf));
105   else {
106     switch (*obj) {
107     case k_BAD:
108       snprintf(buf, sizeof(buf), "BAD");
109       snprintf(add, sizeof(add), "[%p]", X);
110       break;
111     case k_entity:
112       snprintf(buf, sizeof(buf), "%s%s", A("ent"),
113           isupper(occ->conversion) ? get_entity_ld_name(X): get_entity_name(X));
114       snprintf(add, sizeof(add), "[%ld]", get_entity_nr(X));
115       break;
116     case k_type:
117       snprintf(buf, sizeof(buf), "%s%s:%s", A("type"), get_type_tpop_name(X), get_type_name(X));
118       snprintf(add, sizeof(add), "[%ld]", get_type_nr(X));
119       break;
120     case k_ir_graph:
121       snprintf(buf, sizeof(buf), "%s%s", A("irg"), get_entity_name(get_irg_entity(X)));
122       snprintf(add, sizeof(add), "[%ld]", get_irg_graph_nr(X));
123       break;
124     case k_ir_node:
125       switch (occ->conversion) {
126       case 'B':
127         block = is_no_Block(X) ? get_nodes_block(X) : X;
128         snprintf(buf, sizeof(buf), "%s%s%s", A("irn"), get_irn_opname(block),
129             get_mode_name(get_irn_mode(block)));
130         snprintf(add, sizeof(add), "[%ld]", get_irn_node_nr(block));
131         break;
132       case 'N':
133         snprintf(buf, sizeof(buf), "%ld", get_irn_node_nr(X));
134         break;
135       default:
136         if (is_Const(X)) {
137           char tbuf[128];
138           tarval_snprintf(tv, sizeof(tv), X);
139           snprintf(buf, sizeof(buf), "%s%s%s<%s>", A("irn"), get_irn_opname(X),
140             get_mode_name(get_irn_mode(X)), tbuf);
141         }
142         else
143           snprintf(buf, sizeof(buf), "%s%s%s", A("irn"), get_irn_opname(X),
144             get_mode_name(get_irn_mode(X)));
145         snprintf(add, sizeof(add), "[%ld]", get_irn_node_nr(X));
146       }
147       break;
148     case k_ir_mode:
149       snprintf(buf, sizeof(buf), "%s%s", A("mode"), get_mode_name(X));
150       break;
151     case k_tarval:
152       tarval_snprintf(tv, sizeof(tv), X);
153       snprintf(buf, sizeof(buf), "%s%s", A("tv"), tv);
154       break;
155     case k_ir_loop:
156       snprintf(buf, sizeof(buf), "ldepth[%d]", get_loop_depth(X));
157       break;
158     case k_ir_op:
159       snprintf(buf, sizeof(buf), "%s%s", A("op"), get_op_name(X));
160       break;
161     case k_ir_compound_graph_path:
162       strncat(buf, A("cgp"), sizeof(buf));
163
164       n = get_compound_graph_path_length(X);
165       for (i = 0; i < n; ++i) {
166         entity *ent = get_compound_graph_path_node(X, i);
167         strncat(buf, get_entity_name(ent), sizeof(buf));
168         if (i < n - 1)
169           strncat(buf, ".", sizeof(buf));
170       }
171       break;
172     default:
173       snprintf(buf, sizeof(buf), "UNKWN");
174       snprintf(add, sizeof(add), "[%p]", X);
175     }
176   }
177
178   if(occ->flag_plus)
179         strncat(buf, add, sizeof(buf));
180
181   return arg_append(app, occ, buf, strlen(buf));
182
183 #undef A
184 }
185
186 /**
187  * emit an ident
188  */
189 static int firm_emit_ident(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
190 {
191   ident *id = (ident *)arg->v_ptr;
192   const char *p = id ? get_id_str(id) : "(null)";
193
194   return arg_append(app, occ, p, strlen(p));
195 }
196
197 /**
198  * Emit indent.
199  */
200 static int firm_emit_indent(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
201 {
202         int i;
203         int amount = arg->v_int;
204
205         for(i = 0; i < amount; ++i)
206                 appendable_chadd(app, ' ');
207
208         return amount;
209 }
210
211 /**
212  * Emit pnc.
213  */
214 static int firm_emit_pnc(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
215 {
216   int value = arg->v_int;
217   const char *p = get_pnc_string(value);
218
219   return arg_append(app, occ, p, strlen(p));
220 }
221
222 arg_env_t *firm_get_arg_env(void)
223 {
224 #define X(name, letter) {"firm:" name, letter}
225
226   static arg_env_t *env = NULL;
227
228   static arg_handler_t firm_handler   = { firm_get_arg_type, firm_emit };
229   static arg_handler_t ident_handler  = { firm_get_arg_type, firm_emit_ident };
230   static arg_handler_t indent_handler = { firm_get_arg_type_int, firm_emit_indent };
231   static arg_handler_t pnc_handler    = { firm_get_arg_type_int, firm_emit_pnc };
232   static arg_handler_t bitset_handler = { bitset_get_arg_type, bitset_emit };
233   static arg_handler_t debug_handler  = { firm_get_arg_type, firm_emit_dbg };
234
235   static struct {
236     const char *name;
237     char letter;
238   } args[] = {
239     X("type",      't'),
240     X("entity",    'e'),
241     X("entity_ld", 'E'),
242     X("tarval",    'T'),
243     X("irn",       'n'),
244     X("op",        'O'),
245     X("irn_nr",    'N'),
246     X("mode",      'm'),
247     X("block",     'B'),
248     X("pnc",       '='),
249   };
250
251   int i;
252
253   if(env == NULL) {
254     env = arg_new_env();
255     arg_add_std(env);
256
257     arg_register(env, "firm", 'F', &firm_handler);
258     for (i = 0; i < sizeof(args)/sizeof(args[0]); ++i)
259       arg_register(env, args[i].name, args[i].letter, &firm_handler);
260
261     arg_register(env, "firm:ident", 'I', &ident_handler);
262     arg_register(env, "firm:indent", 'D', &indent_handler);
263     arg_register(env, "firm:pnc",      '=', &pnc_handler);
264     arg_register(env, "firm:dbg_info", 'g', &debug_handler);
265     /* arg_register(env, "firm:bitset", 'b', &bitset_handler); */
266   }
267
268   return env;
269 }