added real function call setting
[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 <ctype.h>
18 #include <libcore/xprintf.h>
19
20 #include "firm_common.h"
21 #include "irnode.h"
22 #include "entity.h"
23 #include "irloop.h"
24 #include "tv.h"
25
26 /**
27  * identify a firm object type
28  */
29 static int firm_get_arg_type(const arg_occ_t *occ) {
30   /* Firm objects are always pointer */
31   return arg_type_ptr;
32 }
33
34 static int firm_get_arg_type_int(const arg_occ_t *occ) {
35   return arg_type_int;
36 }
37
38 /**
39  * emit a Firm object
40  */
41 static int firm_emit(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
42 {
43 #define A(s)    occ->flag_hash ? s " ": ""
44
45   void *X = arg->v_ptr;
46   firm_kind *obj = X;
47
48   int i, n;
49   ir_node *block;
50   char buf[256];
51   char tv[256];
52
53   buf[0] = '\0';
54
55   if (! X)
56     strncpy(buf, "(null)", sizeof(buf));
57   else {
58     switch (*obj) {
59     case k_BAD:
60       snprintf(buf, sizeof(buf), "BAD[%p]", X);
61       break;
62     case k_entity:
63       snprintf(buf, sizeof(buf), "%s%s[%ld]", A("ent"),
64           isupper(occ->conversion) ? get_entity_ld_name(X): get_entity_name(X),
65           get_entity_nr(X));
66       break;
67     case k_type:
68       snprintf(buf, sizeof(buf), "%s%s:%s[%ld]", A("type"), get_type_tpop_name(X), get_type_name(X), get_type_nr(X));
69       break;
70     case k_ir_graph:
71       snprintf(buf, sizeof(buf), "%s%s[%ld]", A("irg"), get_entity_name(get_irg_entity(X)), get_irg_graph_nr(X));
72       break;
73     case k_ir_node:
74       switch (occ->conversion) {
75       case 'B':
76         block = is_no_Block(X) ? get_nodes_block(X) : X;
77         snprintf(buf, sizeof(buf), "%s%s%s[%ld]", A("irn"), get_irn_opname(block),
78             get_mode_name(get_irn_mode(block)), get_irn_node_nr(block));
79         break;
80       case 'N':
81         snprintf(buf, sizeof(buf), "%ld", get_irn_node_nr(X));
82         break;
83       default:
84         snprintf(buf, sizeof(buf), "%s%s%s[%ld]", A("irn"), get_irn_opname(X),
85             get_mode_name(get_irn_mode(X)), get_irn_node_nr(X));
86       }
87       break;
88     case k_ir_mode:
89       snprintf(buf, sizeof(buf), "%s%s", A("mode"), get_mode_name(X));
90       break;
91     case k_tarval:
92       tarval_snprintf(tv, sizeof(tv), X);
93       snprintf(buf, sizeof(buf), "%s%s", A("tv"), tv);
94       break;
95     case k_ir_loop:
96       snprintf(buf, sizeof(buf), "ldepth[%d]", get_loop_depth(X));
97       break;
98     case k_ir_op:
99       snprintf(buf, sizeof(buf), "%s%s", A("op"), get_op_name(X));
100       break;
101     case k_ir_compound_graph_path:
102       strncat(buf, A("cgp"), sizeof(buf));
103
104       n = get_compound_graph_path_length(X);
105       for (i = 0; i < n; ++i) {
106         entity *ent = get_compound_graph_path_node(X, i);
107         strncat(buf, get_entity_name(ent), sizeof(buf));
108         if (i < n - 1)
109           strncat(buf, ".", sizeof(buf));
110       }
111       break;
112     default:
113       snprintf(buf, sizeof(buf), "UNKWN[%p]", X);
114     }
115   }
116   return arg_append(app, occ, buf, strlen(buf));
117
118 #undef A
119 }
120
121 /**
122  * emit an ident
123  */
124 static int firm_emit_ident(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
125 {
126   ident *id = (ident *)arg->v_ptr;
127   const char *p = id ? get_id_str(id) : "(null)";
128
129   return arg_append(app, occ, p, strlen(p));
130 }
131
132
133
134 /**
135  * Emit indent.
136  */
137 static int firm_emit_indent(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
138 {
139         int i;
140         int amount = arg->v_int;
141
142         for(i = 0; i < amount; ++i)
143                 appendable_chadd(app, ' ');
144
145         return amount;
146 }
147
148 arg_env_t *firm_get_arg_env(void)
149 {
150 #define X(name, letter) {"firm:" name, letter}
151
152   static arg_env_t *env = NULL;
153
154   static arg_handler_t firm_handler   = { firm_get_arg_type, firm_emit };
155   static arg_handler_t ident_handler  = { firm_get_arg_type, firm_emit_ident };
156   static arg_handler_t indent_handler = { firm_get_arg_type_int, firm_emit_indent };
157
158   static struct {
159     const char *name;
160     char letter;
161   } args[] = {
162     X("type",      't'),
163     X("entity",    'e'),
164     X("entity_ld", 'E'),
165     X("tarval",    'T'),
166     X("irn",       'n'),
167     X("op",        'O'),
168     X("irn_nr",    'N'),
169     X("mode",      'm'),
170     X("block",     'B'),
171   };
172
173   int i;
174
175   if(env == NULL) {
176     env = arg_new_env();
177     arg_add_std(env);
178
179                 arg_register(env, "firm", 'F', &firm_handler);
180     for (i = 0; i < sizeof(args)/sizeof(args[0]); ++i)
181       arg_register(env, args[i].name, args[i].letter, &firm_handler);
182
183     arg_register(env, "firm:ident", 'I', &ident_handler);
184                 arg_register(env, "firm:indent", 'D', &indent_handler);
185   }
186
187   return env;
188 }