5 File name: ir/ana/pto_name.c
6 Purpose: Names for abstract objects
9 Created: Sat Nov 13 19:35:27 CET 2004
11 Copyright: (c) 1999-2004 Universität Karlsruhe
12 Licence: This file is protected by the GPL - GNU GENERAL PUBLIC LICENSE.
20 pto_name: Names for abstract objects
24 # include "pto_name.h"
25 # include "pto_util.h"
27 # include <string.h> /* for memcpy */
35 # include "pto_debug.h"
38 # define obstack_chunk_alloc xmalloc
39 # define obstack_chunk_free free
41 # define NALLOC(size) obstack_alloc (name_obst, size)
43 /* Local Data Types: */
45 /* Local Variables: */
46 struct obstack *qset_obst = NULL;
47 struct obstack *name_obst = NULL;
49 static desc_t *all_descs = NULL;
51 static int name_id = 0;
53 /* Local Prototypes: */
55 /* ===================================================
57 =================================================== */
58 /* See whether the given entity is a field. */
59 static int is_field (entity *ent)
61 type *tp = get_entity_type (ent);
63 if (is_primitive_type (tp) || is_pointer_type (tp)) {
64 /* actually, we could get by by restricting ourselves to pointer types */
71 /* Helper to collect_fields(type*): collect all fields of the given
72 clazz and its super classes into the given obstack. */
73 static void _collect_fields (type *clazz, struct obstack *obst)
75 int n_members = get_class_n_members (clazz);
76 int n_supers = get_class_n_supertypes (clazz);
79 for (i = 0; i < n_members; i ++) {
80 entity *ent = get_class_member (clazz, i);
83 if (allocation_static != get_entity_allocation (ent)) {
84 obstack_ptr_grow (obst, ent);
89 for (i = 0; i < n_supers; i ++) {
90 type *s_clazz = get_class_supertype (clazz, i);
92 _collect_fields (s_clazz, obst);
96 /* Collect the fields of the given class and its super classes into an array.
97 The last entry of the array is written NULL. */
98 static entity **collect_fields (type *clazz)
100 if (NULL != get_type_link (clazz)) {
101 DBGPRINT (3, (stdout, "%s: reusing field list for \"%s\"\n",
102 __FUNCTION__, get_type_name (clazz)));
104 return ((entity **) get_type_link (clazz));
106 DBGPRINT (2, (stdout, "%s: new field list for \"%s\"\n",
107 __FUNCTION__, get_type_name (clazz)));
112 obstack_init (&obst);
114 _collect_fields (clazz, &obst);
116 /* append terminating NULL */
117 int *the_null = NULL;
118 obstack_ptr_grow (&obst, the_null);
120 int n_fields = obstack_object_size (&obst) / sizeof (void*);
122 entity ** fields = (entity**) NALLOC (n_fields * sizeof (entity*));
123 void *tmp = obstack_finish (&obst);
125 memcpy (fields, tmp, n_fields * sizeof (entity*));
127 obstack_free (&obst, NULL);
129 set_type_link (clazz, (void*) fields);
134 /* Write the intro text for a name dump into the given stream */
135 static void pto_name_dump_start (FILE *stream)
137 fprintf (stream, "digraph \"Names\" {\n");
138 fprintf (stream, "\tgraph [rankdir=\"LR\", ordering=\"out\"];\n");
139 fprintf (stream, "\tnode [shape=\"record\", style=\"filled\"];\n");
140 fprintf (stream, "\tedge [color=\"black\"];\n");
141 fprintf (stream, "\n");
144 /* Write the extro text for a name dump into the given stream */
145 static void pto_name_dump_finish (FILE *stream)
147 fprintf (stream, "}\n");
150 /* Write a node for the given descriptor into the given stream */
151 static void pto_name_dump_desc (desc_t *desc, FILE *stream)
154 const char *tp_name = get_type_name (tp);
156 fprintf (stream, "\t/* %s \"%s\" */\n",
157 object == desc->kind ? "Object" : "Array",
160 fprintf (stream, "\tdesc_%i [label=\"<HEAD>type=\\\"%s\\\"",
164 ir_node *nd = desc->node;
167 fprintf (stream, "|<NODE>node=%s\\[%li\\]",
168 get_op_name (get_irn_op (nd)),
169 get_irn_node_nr (nd));
172 if (desc->kind == object) {
173 obj_desc_t *obj_desc = (obj_desc_t*) desc;
176 for (i = 0; i < obj_desc->n_fields; i ++) {
177 const char *ent_name = get_entity_name (obj_desc->fields [i]);
179 fprintf (stream, "|<%i>%s", i, ent_name);
181 } else if (array == desc->kind) {
182 arr_desc_t *arr_desc = (arr_desc_t*) desc;
184 fprintf (stream, "|<arr>[]");
186 assert (0 && "invalid descriptor");
189 fprintf (stream, "\"];\n");
190 fprintf (stream, "\n");
193 if (desc->kind == object) {
194 obj_desc_t *obj_desc = (obj_desc_t*) desc;
197 for (i = 0; i < obj_desc->n_fields; i ++) {
198 desc_t *tgt = (desc_t*) qset_start (obj_desc->values [i]);
200 while (NULL != tgt) {
201 fprintf (stream, "\tdesc_%i:%i -> desc_%i:HEAD;\n",
202 desc->id, i, tgt->id);
204 tgt = (desc_t*) qset_next (obj_desc->values [i]);
207 } else if (array == desc->kind) {
208 arr_desc_t *arr_desc = (arr_desc_t*) desc;
210 desc_t *tgt = (desc_t*) qset_start (arr_desc->value);
212 while (NULL != tgt) {
213 fprintf (stream, "\tdesc_%i:arr -> desc_%i:HEAD;\n",
216 tgt = (desc_t*) qset_next (arr_desc->value);
220 fprintf (stream, "\n");
224 /* ===================================================
225 Exported Implementation:
226 =================================================== */
227 /* Find the given descriptor's entry for the given entity */
228 qset_t *get_entry (desc_t *desc, entity *ent)
231 if (desc->kind == object) {
232 obj_desc_t *obj_desc = (obj_desc_t*) desc;
234 const int n_fields = obj_desc->n_fields;
236 for (i = 0; i < n_fields; i ++) {
237 if (ent == obj_desc->fields [i]) {
238 return (obj_desc->values [i]);
242 assert (0 && "entry not found");
243 } else if (desc->kind = array) {
244 arr_desc_t *arr_desc = (arr_desc_t*) desc;
246 return (arr_desc->value);
248 assert (0 && "invalid descriptor");
253 /* get a new descriptor for the given type at the given node */
254 desc_t *new_name (type *tp, ir_node *node)
258 assert ((is_class_type (tp) || is_array_type (tp)) && "unsuitable type");
260 DBGPRINT (2, (stdout, "%s: new name for type \"%s\"\n", __FUNCTION__,
261 get_type_name (tp)));
264 if (is_class_type (tp)) {
265 obj_desc_t *obj_desc = (obj_desc_t*) NALLOC (sizeof (obj_desc_t));
269 obj_desc->kind = object;
270 obj_desc->fields = collect_fields (tp);
272 for (n_fields = 0; (NULL != obj_desc->fields [n_fields]); n_fields ++) {
273 /* nothing, just count ... */
276 obj_desc->n_fields = n_fields;
277 obj_desc->values = (qset_t**) NALLOC (n_fields * sizeof (qset_t));
279 for (i = 0; i < n_fields; i ++) {
280 obj_desc->values [i] = qset_new (N_INITIAL_OJBS, qset_obst);
283 desc = (desc_t*) obj_desc;
284 } else if (is_array_type (tp)) {
285 arr_desc_t *arr_desc = (arr_desc_t*) NALLOC (sizeof (arr_desc_t));
287 arr_desc->kind = array;
288 arr_desc->value = qset_new (N_INITIAL_OJBS, qset_obst);
290 desc = (desc_t*) arr_desc;
293 desc->id = name_id ++;
297 desc->prev = all_descs;
303 # define N_GLOB_INITIAL_FIELDS 20
304 static obj_desc_t *obj_glob = NULL;
305 static int n_glob_fields = N_GLOB_INITIAL_FIELDS;
307 /* get a new descriptor for the given (presumably static) entity */
308 desc_t *new_ent_name (entity *ent)
312 type *tp = get_entity_type (ent);
314 assert (is_pointer_type (tp));
315 tp = get_pointer_points_to_type (tp);
316 assert (is_class_type (tp));
318 assert (((allocation_static == get_entity_allocation (ent)) ||
319 (allocation_automatic == get_entity_allocation (ent))) &&
320 "not a static/automatic field");
322 if (NULL == obj_glob) {
323 obj_glob = (obj_desc_t*) NALLOC (sizeof (obj_desc_t));
325 obj_glob->id = name_id ++;
326 obj_glob->kind = object;
327 obj_glob->tp = get_glob_type ();
328 obj_glob->node = NULL;
330 obj_glob->n_fields = 0;
331 obj_glob->fields = (entity**) NALLOC (N_GLOB_INITIAL_FIELDS * sizeof (entity*));
332 obj_glob->values = (qset_t**) NALLOC (N_GLOB_INITIAL_FIELDS * sizeof (qset_t*));
334 obj_glob->prev = all_descs;
335 all_descs = (desc_t*) obj_glob;
338 for (i = 0; missing && (i < obj_glob->n_fields); i ++) {
339 if (ent == obj_glob->fields [i]) {
345 if (obj_glob->n_fields == n_glob_fields) {
346 entity **fields = obj_glob->fields;
347 qset_t **values = obj_glob->values;
350 obj_glob->fields = (entity**) NALLOC (n_glob_fields * sizeof (entity*));
351 obj_glob->values = (qset_t**) NALLOC (n_glob_fields * sizeof (qset_t*));
353 memcpy (obj_glob->fields, fields, obj_glob->n_fields * sizeof (entity*));
354 memcpy (obj_glob->values, values, obj_glob->n_fields * sizeof (qset_t*));
360 obj_glob->fields [obj_glob->n_fields ] = ent;
361 obj_glob->values [obj_glob->n_fields ++] = qset_new (N_INITIAL_OJBS, qset_obst);
364 return ((desc_t*) obj_glob);
366 # undef N_GLOB_INITIAL_FIELDS
368 /* Dump all names to a file of the given name */
369 void pto_dump (const char *name)
371 desc_t *desc = all_descs;
372 FILE *stream = fopen (name, "w");
375 if (NULL == stream) {
376 fprintf (stderr, "%s: unable to open %s (%s)\n",
377 __FUNCTION__, name, strerror (errno));
381 pto_name_dump_start (stream);
383 while (NULL != desc) {
384 pto_name_dump_desc (desc, stream);
389 pto_name_dump_finish (stream);
393 /* Initialise the name module */
394 void pto_name_init ()
396 DBGPRINT (3, (stdout, "(%s:%i) %s\n", __FILE__, __LINE__, __FUNCTION__));
397 assert (NULL == name_obst);
398 assert (NULL == qset_obst);
400 name_obst = xmalloc (sizeof (struct obstack));
401 qset_obst = xmalloc (sizeof (struct obstack));
403 obstack_init (name_obst);
404 obstack_init (qset_obst);
407 /* Cleanup the name module */
408 void pto_name_cleanup ()
410 DBGPRINT (3, (stdout, "(%s:%i) %s\n", __FILE__, __LINE__, __FUNCTION__));
411 obstack_free (name_obst, NULL);
412 obstack_free (qset_obst, NULL);
414 memset (name_obst, 0x00, sizeof (struct obstack));
415 memset (qset_obst, 0x00, sizeof (struct obstack));
427 Revision 1.3 2004/11/30 14:47:54 liekweg
428 fix initialisation; do correct iteration
430 Revision 1.2 2004/11/24 14:53:56 liekweg
433 Revision 1.1 2004/11/18 16:37:34 liekweg