more documentation
[libfirm] / ir / ana2 / typalise.c
1 /* -*- c -*- */
2
3 /*
4  * Project:     libFIRM
5  * File name:   ir/ana2/pto.c
6  * Purpose:     Pto
7  * Author:      Florian
8  * Modified by:
9  * Created:     Mon 18 Oct 2004
10  * CVS-ID:      $Id$
11  * Copyright:   (c) 1999-2004 Universität Karlsruhe
12  * Licence:     This file is protected by GPL -  GNU GENERAL PUBLIC LICENSE.
13  */
14
15
16 # ifdef HAVE_CONFIG_H
17 #  include "config.h"
18 # endif
19
20 # include "typalise.h"
21
22 # ifndef TRUE
23 #  define TRUE 1
24 #  define FALSE 0
25 # endif /* not defined TRUE */
26
27 # include <assert.h>
28
29 #ifdef HAVE_STRING_H
30 # include <string.h>
31 #endif
32
33 # include "irnode_t.h"
34 # include "irgwalk.h"
35 # include "xmalloc.h"
36 # include "gnu_ext.h"
37 # include "irdump.h"
38 # include "typewalk.h"
39
40
41 /*
42   Local Globals
43 */
44
45 static long ta_id = 0;
46
47 /*
48   Local Protos
49 */
50 static typalise_t *typalise_proj (ir_node*);
51
52 /* DEBUGGING only */
53 static void cough_and_die (ir_node *node)
54 {
55   ir_graph *graph = get_irn_irg (node);
56
57   fprintf (stdout, "%s: %s[%li]\n",
58            __FUNCTION__,
59            get_op_name (get_irn_op (node)),
60            get_irn_node_nr (node));
61   dump_ir_block_graph (graph, "-typealise");
62   assert (0);
63 }
64
65 /*
66   Exception b/d
67 */
68 static type *java_lang_Throwable_tp = NULL;
69
70 static type *get_java_lang_Throwable ()
71 {
72   assert (NULL != java_lang_Throwable_tp);
73
74   return (java_lang_Throwable_tp);
75 }
76
77 static void find_java_lang_Throwable (type *tp, void *_unused)
78 {
79   const char *name = get_type_name (tp);
80
81   if (0 == strcmp (name, "java/lang/Throwable")) {
82     assert (NULL == java_lang_Throwable_tp);
83
84     java_lang_Throwable_tp = tp;
85   }
86 }
87
88
89 /*
90   Ctors, Dtors for typalise_t-s
91 */
92 static typalise_t *ta_exact (type *tp)
93 {
94   typalise_t *ta = xmalloc (sizeof (typalise_t));
95   ta->kind = type_exact;
96   ta->res.type = tp;
97   ta->id = ta_id ++;
98
99   assert (is_Class_type (tp));
100
101   return (ta);
102 }
103
104 static typalise_t *ta_types (lset_t *set)
105 {
106   typalise_t *ta = xmalloc (sizeof (typalise_t));
107   ta->kind = type_types;
108   ta->res.types = set;
109   ta->id = ta_id ++;
110
111   return (ta);
112 }
113
114 static typalise_t *ta_type (type *tp)
115 {
116   typalise_t *ta = xmalloc (sizeof (typalise_t));
117   ta->kind = type_type;
118   ta->res.type = tp;
119   ta->id = ta_id ++;
120
121   assert (is_Class_type (tp));
122
123   return (ta);
124 }
125
126 static void ta_delete (typalise_t *ta)
127 {
128   if (type_types == ta->kind) {
129     lset_destroy (ta->res.types);
130     ta->res.types = NULL;
131   } else {
132     ta->res.type = NULL;
133   }
134
135   ta->kind = type_invalid;
136
137   free (ta);
138 }
139
140 /*
141   Helpers for inheritance, overwriting and stuff
142 */
143 /**
144    Find out whether otype is a subtype of stype.
145    Return non-zero iff otype is a subtype of stype.
146 */
147 static int is_subtype (type *otype, type *stype)
148 {
149   int n_sub = get_class_n_subtypes (stype);
150   int is_sub = FALSE;
151   int i;
152
153   if (otype == stype) {
154     return (TRUE);
155   }
156
157   for (i = 0; (!is_sub) && (i < n_sub); i ++) {
158     type *sub = get_class_subtype (stype, i);
159
160     is_sub |= is_subtype (otype, sub);
161   }
162
163
164   return (is_sub);
165 }
166
167
168 /**
169     Compute the closure of all subtypes of otype (including otype
170     itself)
171 */
172 static void _collect_subtypes (type *otype, lset_t *set)
173 {
174   int i, n_sub;
175
176   lset_insert (set, otype);
177
178   n_sub = get_class_n_subtypes (otype);
179   for (i = 0; i < n_sub; i ++) {
180     type *sub = get_class_subtype (otype, i);
181
182     _collect_subtypes (sub, set);
183   }
184 }
185
186 static lset_t *subtype_closure (type *otype)
187 {
188   lset_t *set = lset_create ();
189
190   _collect_subtypes (otype, set);
191
192   return (set);
193 }
194
195 /**
196    Helper method for get_owner_types
197 */
198 static void _collect_owner_types (entity *method, ir_graph *graph, lset_t *tps)
199 {
200   int i, n_over;
201
202   /* search DOWNwards in clazz hierarchy */
203
204   if ((peculiarity_description == get_entity_peculiarity (method)) ||
205       (peculiarity_inherited   == get_entity_peculiarity (method))) {
206     lset_insert (tps, get_entity_owner (method));
207   } else if (peculiarity_existent == get_entity_peculiarity (method)) {
208     ir_graph *ex_graph = get_entity_irg (method);
209
210     if ((NULL == ex_graph) || (ex_graph == graph)) {
211       /* wtf? they define the same graph again? well, whatever: */
212       lset_insert (tps, get_entity_owner (method));
213     } else {
214       /* aha: they define a new graph. can't have that, so bail out */
215       return;
216     }
217   }
218
219   n_over = get_entity_n_overwrittenby (method);
220   for (i = 0; i < n_over; i ++) {
221     entity *ometh = get_entity_overwrittenby (method, i);
222
223     _collect_owner_types (ometh, graph, tps);
224   }
225 }
226
227
228 /**
229    Collect all classes that use the given implementation of a method.
230 */
231 static lset_t *get_owner_types (ir_graph *graph)
232 {
233   lset_t *tps = lset_create ();
234   entity *meth = get_irg_entity (graph);
235
236   _collect_owner_types (meth, graph, tps);
237
238   return (tps);
239 }
240
241 /**
242    Return a list containing all types of 'set' which are a subtype of 'type'.
243 */
244 static lset_t *filter_for_type (lset_t *set, type *stype)
245 {
246   type *curs = (type*) lset_first (set);
247   lset_t *lset = lset_create ();
248
249   while (NULL != curs) {
250     if (is_subtype (curs, stype)) {
251       lset_insert (lset, curs);
252     }
253
254     curs = lset_next (set);
255   }
256
257   return (lset);
258 }
259
260 /*
261  Handle typalise_t-s
262 */
263 /**
264     Join 'one' and 'two'; both args are deallocated, result is freshly
265     allocated.
266 */
267 static typalise_t *ta_join (typalise_t *one, typalise_t *two)
268 {
269   typalise_t *res = NULL;
270
271   /* now, one==NULL or two==NULL cannot happen legitimately (if we hit a NULL pointer constant)
272   if (NULL == one) {
273     return (two);
274   }
275
276   if (NULL == two) {
277     return (one);
278   }
279   */
280   switch (one->kind) {
281   case (type_invalid): { /* shut up, gcc */ }
282   case (type_exact): {
283     switch (two->kind) {
284     case (type_invalid): { /* shut up, gcc */ }
285     case (type_exact): {
286       if (one->res.type == two->res.type) {
287         res = one;
288       } else {
289         lset_t *set = lset_create ();
290         lset_insert (set, one->res.type);
291         lset_insert (set, two->res.type);
292         res = ta_types (set);
293
294         ta_delete (one);
295       }
296
297       ta_delete (two);
298     } break;
299     case (type_types): {
300       lset_insert (two->res.types, one->res.type);
301       ta_delete (one);
302
303       res = two;
304     } break;
305     case (type_type): {
306       if (is_subtype (one->res.type, two->res.type)) {
307         ta_delete (one);
308         res = two;
309       } else {
310         lset_t *closure = subtype_closure (two->res.type);
311         lset_insert (closure, one->res.type);
312
313         ta_delete (two);
314
315         res = one;
316       }
317     } break;
318     }
319   } break;
320   case (type_types): {
321     switch (two->kind) {
322     case (type_invalid): { /* shut up, gcc */ }
323     case (type_exact): {
324       res = ta_join (two, one);
325     } break;
326     case (type_types): {
327       lset_insert_all (one->res.types, two->res.types);
328       ta_delete (two);
329
330       res = one;
331     } break;
332     case (type_type): {
333       lset_t *closure = subtype_closure (two->res.type);
334       lset_append (one->res.types, closure);
335
336       ta_delete (two);
337
338       res = one;
339     } break;
340     }
341   } break;
342   case (type_type): {
343     switch (two->kind) {
344     case (type_invalid): { /* shut up, gcc */ }
345     case (type_exact): {
346       res = ta_join (two, one);
347     } break;
348     case (type_types): {
349       res = ta_join (two, one);
350     } break;
351     case (type_type): {
352       type *one_type = one->res.type;
353       type *two_type = two->res.type;
354
355       if (is_subtype (one_type, two_type)) {
356         ta_delete (one);
357         res = two;
358       } else if (is_subtype (two_type, one_type)) {
359         ta_delete (two);
360         res = one;
361       } else {
362         lset_t *one_closure = subtype_closure (one->res.type);
363         lset_t *two_closure = subtype_closure (two->res.type);
364
365         lset_append (one_closure, two_closure);
366
367         ta_delete (two);
368         ta_delete (one);
369
370         res = ta_types (one_closure);
371       }
372     } break;
373     }
374   } break;
375   }
376
377   assert (res && "no result");
378
379   return (res);
380 }
381
382
383 # ifdef SHUT_UP_GCC
384 static const char *ta_name (typalise_t *ta)
385 {
386 # define BUF_SIZE 1024
387   static char buf [BUF_SIZE];
388
389   int len = sprintf (buf, "[%d] ", ta->id);
390
391   switch (ta->kind) {
392   case (type_invalid): { /* shut up, gcc */ }
393   case (type_exact): {
394     len += sprintf (buf+len, "only ");
395     strncat (buf, get_type_name (ta->res.type), BUF_SIZE);
396   } break;
397   case (type_types): {
398     len += sprintf (buf+len, "one_of ");
399
400     type *iter = lset_first (ta->res.types);
401
402     int size = BUF_SIZE - len - 1;
403     while ((NULL != iter) && (0 < size)) {
404       char *dest = strncat (buf, get_type_name (iter), size);
405       size = (dest - buf);
406
407       iter = lset_next (ta->res.types);
408     }
409   } break;
410   case (type_type): {
411     len += sprintf (buf+len, "poly ");
412     strncat (buf, get_type_name (ta->res.type), BUF_SIZE);
413   } break;
414   }
415
416   return (buf);
417   /* # undef BUF_SIZE */
418 }
419 # endif /* SHUT_UP_GCC */
420
421 /**
422    Find out whether the given clazz uses the given implementation of a
423    method.  Presumably, this is because clazz inherits the graph as
424    the implementation for a method.
425 */
426 static int uses_graph (type *clazz, entity *meth, ir_graph *graph)
427 {
428   type *g_clazz = get_entity_owner (meth);
429   int i, n_over, use = FALSE;
430
431   if (g_clazz == clazz) {
432     return (TRUE);
433   }
434
435   if (peculiarity_existent == get_entity_peculiarity (meth)) {
436     ir_graph *g_graph = get_entity_irg (meth);
437
438     if (g_graph != graph) {
439       return (FALSE);
440     }
441   }
442
443   /* else inherited or description */
444   n_over = get_entity_n_overwrittenby (meth); /* DOWN-wards */
445   for (i = 0; (i < n_over) && (!use); i ++) {
446     entity *over = get_entity_overwrittenby (meth, i);
447
448     use |= uses_graph (clazz, over, graph);
449   }
450
451   return (use);
452 }
453
454 /**
455    Check whether the given typalise_t includes the given type.
456 */
457 static int ta_supports (typalise_t *ta, ir_graph *graph)
458 {
459   switch (ta->kind) {
460   case (type_invalid): { /* shut up, gcc */ }
461   case (type_exact): {
462     int res = FALSE;
463     lset_t *tps = get_owner_types (graph);
464
465     if (lset_contains (tps, ta->res.type)) {
466       res = TRUE;
467     }
468
469     lset_destroy (tps);
470
471     return (res);
472   }
473   case (type_type): {
474     entity *meth = get_irg_entity (graph);
475     type *tp = get_entity_owner (meth);
476     int res = is_subtype (tp, ta->res.type);
477
478     if (res) {
479       return (TRUE);
480     } else {
481       res = uses_graph (ta->res.type, meth, graph);
482     }
483
484     return (res);
485   }
486   case (type_types): {
487     type *tp = get_entity_owner (get_irg_entity (graph));
488
489     return (lset_contains (ta->res.types, tp));
490   }
491   }
492
493   assert (0 && "invalid ta");
494   return FALSE;
495 }
496
497
498 /* =========== WHAT ELSE ? =========== */
499
500 /*
501   Helpers to typalise (ir_node*)
502 */
503 /**
504    Find an approximation to the given load node's value's types
505 */
506 static typalise_t *typalise_call (ir_node *call)
507 {
508   entity *ent = NULL;
509   type *tp = NULL;
510   typalise_t *res = NULL;
511   ir_node *call_ptr = get_Call_ptr (call);
512
513   if (iro_Sel == get_irn_opcode (call_ptr)) {
514     ent = get_Sel_entity (call_ptr);
515   } else if (iro_SymConst == get_irn_opcode (call_ptr)) {
516     if (get_SymConst_kind (call_ptr) == symconst_addr_ent) {
517       ent = get_SymConst_entity (call_ptr);
518     } else if (get_SymConst_kind (call_ptr) == symconst_addr_name) {
519       ident *id = get_SymConst_name (call_ptr);
520       const char *name = get_id_str (id);
521       if (0 == strcmp (name, "iro_Catch")) {
522         res = ta_type (java_lang_Throwable_tp);
523
524         return (res);
525       }
526
527       fprintf (stdout, "%s: cannot handle Call[%li] (symconst_addr_name=\"%s\")\n",
528                __FUNCTION__, get_irn_node_nr (call),
529                get_op_name (get_irn_op (call_ptr)),
530                name);
531       cough_and_die (call_ptr);
532     } else if (get_SymConst_kind (call_ptr) == symconst_type_tag) {
533       fprintf (stdout, "%s: cannot handle Call[%li] (symconst_type_tag)\n",
534                __FUNCTION__, get_irn_node_nr (call),
535                get_op_name (get_irn_op (call_ptr)));
536       cough_and_die (call_ptr);
537     } else {
538       fprintf (stdout, "%s: cannot handle Call[%li] (%i)\n",
539                __FUNCTION__, get_irn_node_nr (call),
540                get_SymConst_kind (call_ptr));
541       cough_and_die (call_ptr);
542     }
543   }
544
545   tp = get_entity_type (ent);
546   assert (is_Method_type (tp));
547
548   tp = get_method_res_type (tp, 0);
549
550   while (is_Pointer_type (tp)) {
551     tp = get_pointer_points_to_type (tp);
552   }
553
554   res = ta_type (tp);
555
556   return (res);
557 }
558
559
560 /**
561    Find an approximation to the given load node's value's types
562 */
563 static typalise_t *typalise_load (ir_node *load)
564 {
565   entity *ent = NULL;
566   type *tp = NULL;
567   typalise_t *res = NULL;
568   ir_node *load_ptr = get_Load_ptr (load);
569
570   if (iro_Sel == get_irn_opcode (load_ptr)) {
571     ent = get_Sel_entity (load_ptr);
572   } else if (iro_SymConst == get_irn_opcode (load_ptr)) {
573     if (get_SymConst_kind (load_ptr) == symconst_addr_ent) {
574       ent = get_SymConst_entity (load_ptr);
575     } else if (get_SymConst_kind (load_ptr) == symconst_type_tag) {
576       tp = get_SymConst_type (load_ptr);
577     } else {
578       fprintf (stdout, "%s: cannot handle load (%s)\n",
579                __FUNCTION__, get_op_name (get_irn_op (load_ptr)));
580
581       cough_and_die (load_ptr);
582     }
583   } else {
584     fprintf (stdout, "%s: cannot handle load (%s)\n",
585              __FUNCTION__, get_op_name (get_irn_op (load_ptr)));
586       cough_and_die (load_ptr);
587   }
588
589   tp = get_entity_type (ent);
590
591   while (is_Pointer_type (tp)) {
592     tp = get_pointer_points_to_type (tp);
593   }
594
595   res = ta_type (tp);
596
597   return (res);
598 }
599
600
601 /**
602     Find an approximation to the given proj node's value's types
603 */
604 static typalise_t *typalise_proj (ir_node *proj)
605 {
606   typalise_t *res = NULL;
607   ir_node *proj_in = get_Proj_pred (proj);
608
609   if (iro_Proj  == get_irn_opcode (proj_in)) {
610     /* fprintf (stdout, "\tProj (Proj)\n"); */
611
612     proj_in = get_Proj_pred (proj_in);
613     if (iro_Start == get_irn_opcode (proj_in)) {
614       /* aha, proj arg */
615       ir_graph *graph = get_irn_irg (proj);
616       entity   *meth  = get_irg_entity (graph);
617
618       long n = get_Proj_proj (proj);
619       type *tp = get_method_param_type (get_entity_type (meth), n);
620       if (is_Pointer_type (tp)) {
621         tp = get_pointer_points_to_type (tp);
622       }
623
624       res = ta_type (tp);
625
626     } else if (iro_Call == get_irn_opcode (proj_in)) {
627       /* call result ... 'whatever' */
628       res = typalise_call (proj_in);
629     } else {
630       fprintf (stdout, "\n Proj (Proj (%s)) not handled\n",
631                get_op_name (get_irn_op (proj_in)));
632       cough_and_die (proj_in);
633     }
634   } else {
635     opcode op = get_irn_opcode (proj_in);
636     if ((iro_Load != op) && (iro_Alloc != op) && (iro_Call != op)) {
637       fprintf (stdout, "\n Proj (%s) not handled\n",
638                get_op_name (get_irn_op (proj_in)));
639       cough_and_die (proj_in);
640     }
641     res = typalise (proj_in);      /* everything else */
642     /* Proj (Load), Proj (New), Proj (Call) */
643   }
644
645   return (res);
646 }
647
648
649
650 /*
651   Public Interface
652 */
653 /**
654    Given a set of graphs and a typalise_t,  return the method (s) in
655    the set that are supported by the typalise_t.  Also, deallocates
656    the given set.
657 */
658 lset_t *filter_for_ta (lset_t *set, typalise_t *ta)
659 {
660   lset_t *res = lset_create ();
661   ir_graph *curs = (ir_graph*) lset_first (set);
662
663   while (NULL != curs) {
664     if (ta_supports (ta, curs)) {
665       lset_insert (res, curs);
666     }
667
668     curs = lset_next (set);
669   }
670
671   lset_destroy (set);
672
673   return (res);
674 }
675
676 /**
677    For the given ptr, do a quick check about what (class) types may be
678    brought along on it.
679 */
680 typalise_t *typalise (ir_node *node)
681 {
682   opcode op = get_irn_opcode (node);
683   typalise_t *res = NULL;
684
685   switch (op) {
686   case (iro_Cast): {
687     /* casts always succeed */
688     typalise_t *ta = NULL;
689     type *tp = get_Cast_type (node);
690
691     if (is_Pointer_type (tp)) {
692       tp = get_pointer_points_to_type (tp);
693     }
694     assert (is_Class_type (tp));
695
696     ta = typalise (get_Cast_op (node));
697
698     if (NULL == ta) {           /* no type found */
699       ta = ta_type (tp);
700     } else if (type_exact == ta->kind) { /* one type found */
701       /* nothing (maybe check cast? */
702     } else if (type_type == ta->kind) { /* some types found */
703       if (is_subtype (tp, ta->res.type)) {
704         ta->res.type = tp;     /* assume cast is correct */
705       } else {
706         /* should assert (is_subtype (ta->res.type, tp)) */
707       }
708     } else if (type_types == ta->kind) {
709       lset_t *ftp = filter_for_type (ta->res.types, tp);
710       lset_destroy (ta->res.types);
711       ta->res.types = ftp;
712     }
713
714     res = ta;
715   } break;
716
717   case (iro_Proj): {
718     res = typalise_proj (node);
719   } break;
720
721   case (iro_Load): {
722     res = typalise_load (node);
723   } break;
724
725   case (iro_Sel): {
726     /* FILTER */
727     /* it's call (sel (ptr)) or load (sel (ptr)) */
728     entity *ent = get_Sel_entity (node);
729     type *tp = get_entity_type (ent);
730
731     if (is_Method_type (tp)) {
732       /* obsoleted by typalise_call */
733       assert (0);
734       tp = get_entity_type (ent);
735       tp = get_method_res_type (tp, 0);
736
737       if (is_Pointer_type (tp)) {
738         tp = get_pointer_points_to_type (tp);
739       }
740
741       res = ta_type (tp);
742     } else if (is_Class_type (tp)) {
743       tp = get_entity_type (ent);
744
745       if (is_Pointer_type (tp)) {
746         tp = get_pointer_points_to_type (tp);
747       }
748
749       res = ta_type (tp);
750     } else if (is_Pointer_type (tp)) {
751       tp = get_pointer_points_to_type (tp);
752       res = ta_type (tp);
753     } else {
754       assert (0 && "select not handled");
755     }
756   } break;
757
758   case (iro_Phi): {
759     int n_ins = get_irn_arity (node);
760     int i;
761     ir_node *phi_in = NULL;
762     typalise_t *ta = NULL;
763
764     for (i = 0; i < n_ins; i ++) {
765       typalise_t *ta_in;
766
767       phi_in = get_irn_n (node, i);
768       ta_in = typalise (phi_in);
769
770       if (NULL != ta_in) {
771         ta = (NULL == ta) ? ta_in : ta_join (ta, ta_in);
772       }
773     }
774
775     res = ta;
776   } break;
777
778   case (iro_Alloc): {
779     type *type = get_Alloc_type (node);
780     res = ta_exact (type);
781   } break;
782
783   case (iro_Call): {
784     /* presumably call (sel (proj (call))) */
785     ir_node *ptr = get_Call_ptr (node);
786     entity *meth = NULL;
787     if (iro_Sel == get_irn_opcode (ptr)) {
788       meth = get_Sel_entity (ptr);
789     } else if (iro_SymConst == get_irn_opcode (ptr)) {
790       if (get_SymConst_kind (ptr) == symconst_addr_ent) {
791         meth = get_SymConst_entity (ptr);
792       } else {
793         meth = NULL;            /* WTF? */
794       }
795     }
796
797     if (NULL != meth) {
798       type *tp = get_method_res_type ((type*) meth, 0);
799       res = ta_type (tp);
800     } else {
801       /* could be anything */
802       /* fprintf (stdout, "meth= (null)"); */
803       res = NULL;
804     }
805
806     /* fprintf (stdout, "]\n"); */
807
808   } break;
809
810   case (iro_SymConst): {
811     if (get_SymConst_kind (node) == symconst_type_tag) {
812       type *tp = get_SymConst_type (node);
813
814       res = ta_type (tp);
815     } else if (get_SymConst_kind (node) == symconst_addr_ent) {
816       entity *ent = get_SymConst_entity (node);
817       type *tp = get_entity_owner (ent);
818
819       while (is_Pointer_type (tp)) {
820         tp = get_pointer_points_to_type (tp);
821       }
822
823       assert (is_Class_type (tp));
824
825       res = ta_type (tp);       /* can't use ta_exact */
826     } else if (get_SymConst_kind (node) == symconst_addr_name) {
827       /* oh, this is not a real call but a placeholder (exception stuff) */
828       fprintf (stdout, "%s (%s:%i): can't handle pseudo-call %s\n",
829                __FUNCTION__, __FILE__, __LINE__,
830                get_op_name (get_irn_op (node)));
831
832       res = NULL;
833     } else {
834       fprintf (stdout, "%s (%s:%i): can't handle SymConst %s\n",
835                __FUNCTION__, __FILE__, __LINE__,
836                get_op_name (get_irn_op (node)));
837
838       res = NULL;
839     }
840   } break;
841   case (iro_Const): {
842     /* presumably a NULL constant */
843     /* this also means we cannot handle calls against a NULL pointer. */
844     res = NULL;
845   } break;
846
847     /* template:
848        case (iro_Cast): {}
849        break;
850     */
851
852   default: {
853     fprintf (stdout, "what's with %s?\n", get_op_name (get_irn_op (node)));
854     cough_and_die (node);
855   } break;
856   }
857
858   return (res);
859 }
860
861 /*
862   Initialise the Typalise module
863 */
864 void typalise_init ()
865 {
866   if (NULL == java_lang_Throwable_tp) {
867     class_walk_super2sub (find_java_lang_Throwable, NULL, NULL);
868
869     /* make sure we have found it */
870     get_java_lang_Throwable ();
871   }
872 }
873
874
875
876 \f
877 /*
878   $Log$
879   Revision 1.10  2005/05/06 12:02:34  beck
880   added missing includes
881   removed C99 features
882
883   Revision 1.9  2005/03/22 13:56:09  liekweg
884   "small" fix for exception b/d
885
886   Revision 1.8  2005/01/14 14:13:24  liekweg
887   fix gnu extension
888
889   Revision 1.7  2005/01/10 17:26:34  liekweg
890   fixup printfs, don't put environments on the stack
891
892   Revision 1.6  2005/01/05 14:25:54  beck
893   renames all is_x*_type() functions to is_X*_type() to prevent name clash with EDG fronten
894
895   Revision 1.5  2004/12/22 14:43:14  beck
896   made allocations C-like
897
898   Revision 1.4  2004/12/21 15:50:18  beck
899   removed C99 constructs
900
901   Revision 1.3  2004/12/02 16:17:51  beck
902   fixed config.h include
903
904   Revision 1.2  2004/10/22 09:53:10  liekweg
905   Correctly handle proj_args
906
907   Revision 1.1  2004/10/21 11:09:37  liekweg
908   Moved memwalk stuf into irmemwalk
909   Moved lset stuff into lset
910   Moved typalise stuff into typalise
911
912
913  */