add docu and prototype for find_value()
[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 ir_type *java_lang_Throwable_tp = NULL;
69
70 static ir_type *get_java_lang_Throwable (void)
71 {
72   assert (NULL != java_lang_Throwable_tp);
73
74   return (java_lang_Throwable_tp);
75 }
76
77 static void find_java_lang_Throwable (ir_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 (ir_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 (ir_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 (ir_type *otype, ir_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     ir_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 (ir_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     ir_type *sub = get_class_subtype (otype, i);
181
182     _collect_subtypes (sub, set);
183   }
184 }
185
186 static lset_t *subtype_closure (ir_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, ir_type *stype)
245 {
246   ir_type *curs = (ir_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       ir_type *one_type = one->res.type;
353       ir_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     ir_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 (ir_type *clazz, entity *meth, ir_graph *graph)
427 {
428   ir_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     ir_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     ir_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   ir_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                name);
530       cough_and_die (call_ptr);
531     } else if (get_SymConst_kind (call_ptr) == symconst_type_tag) {
532       fprintf (stdout, "%s: cannot handle Call[%li] (symconst_type_tag)\n",
533                __FUNCTION__, get_irn_node_nr (call));
534       cough_and_die (call_ptr);
535     } else {
536       fprintf (stdout, "%s: cannot handle Call[%li] (%i)\n",
537                __FUNCTION__, get_irn_node_nr (call),
538                get_SymConst_kind (call_ptr));
539       cough_and_die (call_ptr);
540     }
541   }
542
543   tp = get_entity_type (ent);
544   assert (is_Method_type (tp));
545
546   tp = get_method_res_type (tp, 0);
547
548   while (is_Pointer_type (tp)) {
549     tp = get_pointer_points_to_type (tp);
550   }
551
552   res = ta_type (tp);
553
554   return (res);
555 }
556
557
558 /**
559    Find an approximation to the given load node's value's types
560 */
561 static typalise_t *typalise_load (ir_node *load)
562 {
563   entity *ent = NULL;
564   ir_type *tp = NULL;
565   typalise_t *res = NULL;
566   ir_node *load_ptr = get_Load_ptr (load);
567
568   if (iro_Sel == get_irn_opcode (load_ptr)) {
569     ent = get_Sel_entity (load_ptr);
570   } else if (iro_SymConst == get_irn_opcode (load_ptr)) {
571     if (get_SymConst_kind (load_ptr) == symconst_addr_ent) {
572       ent = get_SymConst_entity (load_ptr);
573     } else if (get_SymConst_kind (load_ptr) == symconst_type_tag) {
574       tp = get_SymConst_type (load_ptr);
575     } else {
576       fprintf (stdout, "%s: cannot handle load (%s)\n",
577                __FUNCTION__, get_op_name (get_irn_op (load_ptr)));
578
579       cough_and_die (load_ptr);
580     }
581   } else {
582     fprintf (stdout, "%s: cannot handle load (%s)\n",
583              __FUNCTION__, get_op_name (get_irn_op (load_ptr)));
584       cough_and_die (load_ptr);
585   }
586
587   tp = get_entity_type (ent);
588
589   while (is_Pointer_type (tp)) {
590     tp = get_pointer_points_to_type (tp);
591   }
592
593   res = ta_type (tp);
594
595   return (res);
596 }
597
598
599 /**
600     Find an approximation to the given proj node's value's types
601 */
602 static typalise_t *typalise_proj (ir_node *proj)
603 {
604   typalise_t *res = NULL;
605   ir_node *proj_in = get_Proj_pred (proj);
606
607   if (iro_Proj  == get_irn_opcode (proj_in)) {
608     /* fprintf (stdout, "\tProj (Proj)\n"); */
609
610     proj_in = get_Proj_pred (proj_in);
611     if (iro_Start == get_irn_opcode (proj_in)) {
612       /* aha, proj arg */
613       ir_graph *graph = get_irn_irg (proj);
614       entity   *meth  = get_irg_entity (graph);
615
616       long n = get_Proj_proj (proj);
617       ir_type *tp = get_method_param_type (get_entity_type (meth), n);
618       if (is_Pointer_type (tp)) {
619         tp = get_pointer_points_to_type (tp);
620       }
621
622       res = ta_type (tp);
623
624     } else if (iro_Call == get_irn_opcode (proj_in)) {
625       /* call result ... 'whatever' */
626       res = typalise_call (proj_in);
627     } else {
628       fprintf (stdout, "\n Proj (Proj (%s)) not handled\n",
629                get_op_name (get_irn_op (proj_in)));
630       cough_and_die (proj_in);
631     }
632   } else {
633     opcode op = get_irn_opcode (proj_in);
634     if ((iro_Load != op) && (iro_Alloc != op) && (iro_Call != op)) {
635       fprintf (stdout, "\n Proj (%s) not handled\n",
636                get_op_name (get_irn_op (proj_in)));
637       cough_and_die (proj_in);
638     }
639     res = typalise (proj_in);      /* everything else */
640     /* Proj (Load), Proj (New), Proj (Call) */
641   }
642
643   return (res);
644 }
645
646
647
648 /*
649   Public Interface
650 */
651 /**
652    Given a set of graphs and a typalise_t,  return the method (s) in
653    the set that are supported by the typalise_t.  Also, deallocates
654    the given set.
655 */
656 lset_t *filter_for_ta (lset_t *set, typalise_t *ta)
657 {
658   lset_t *res = lset_create ();
659   ir_graph *curs = (ir_graph*) lset_first (set);
660
661   while (NULL != curs) {
662     if (ta_supports (ta, curs)) {
663       lset_insert (res, curs);
664     }
665
666     curs = lset_next (set);
667   }
668
669   lset_destroy (set);
670
671   return (res);
672 }
673
674 /**
675    For the given ptr, do a quick check about what (class) types may be
676    brought along on it.
677 */
678 typalise_t *typalise (ir_node *node)
679 {
680   opcode op = get_irn_opcode (node);
681   typalise_t *res = NULL;
682
683   switch (op) {
684   case (iro_Cast): {
685     /* casts always succeed */
686     typalise_t *ta = NULL;
687     ir_type *tp = get_Cast_type (node);
688
689     if (is_Pointer_type (tp)) {
690       tp = get_pointer_points_to_type (tp);
691     }
692     assert (is_Class_type (tp));
693
694     ta = typalise (get_Cast_op (node));
695
696     if (NULL == ta) {           /* no type found */
697       ta = ta_type (tp);
698     } else if (type_exact == ta->kind) { /* one type found */
699       /* nothing (maybe check cast? */
700     } else if (type_type == ta->kind) { /* some types found */
701       if (is_subtype (tp, ta->res.type)) {
702         ta->res.type = tp;     /* assume cast is correct */
703       } else {
704         /* should assert (is_subtype (ta->res.type, tp)) */
705       }
706     } else if (type_types == ta->kind) {
707       lset_t *ftp = filter_for_type (ta->res.types, tp);
708       lset_destroy (ta->res.types);
709       ta->res.types = ftp;
710     }
711
712     res = ta;
713   } break;
714
715   case (iro_Proj): {
716     res = typalise_proj (node);
717   } break;
718
719   case (iro_Load): {
720     res = typalise_load (node);
721   } break;
722
723   case (iro_Sel): {
724     /* FILTER */
725     /* it's call (sel (ptr)) or load (sel (ptr)) */
726     entity *ent = get_Sel_entity (node);
727     ir_type *tp = get_entity_type (ent);
728
729     if (is_Method_type (tp)) {
730       /* obsoleted by typalise_call */
731       assert (0);
732       tp = get_entity_type (ent);
733       tp = get_method_res_type (tp, 0);
734
735       if (is_Pointer_type (tp)) {
736         tp = get_pointer_points_to_type (tp);
737       }
738
739       res = ta_type (tp);
740     } else if (is_Class_type (tp)) {
741       tp = get_entity_type (ent);
742
743       if (is_Pointer_type (tp)) {
744         tp = get_pointer_points_to_type (tp);
745       }
746
747       res = ta_type (tp);
748     } else if (is_Pointer_type (tp)) {
749       tp = get_pointer_points_to_type (tp);
750       res = ta_type (tp);
751     } else {
752       assert (0 && "select not handled");
753     }
754   } break;
755
756   case (iro_Phi): {
757     int n_ins = get_irn_arity (node);
758     int i;
759     ir_node *phi_in = NULL;
760     typalise_t *ta = NULL;
761
762     for (i = 0; i < n_ins; i ++) {
763       typalise_t *ta_in;
764
765       phi_in = get_irn_n (node, i);
766       ta_in = typalise (phi_in);
767
768       if (NULL != ta_in) {
769         ta = (NULL == ta) ? ta_in : ta_join (ta, ta_in);
770       }
771     }
772
773     res = ta;
774   } break;
775
776   case (iro_Alloc): {
777     ir_type *type = get_Alloc_type (node);
778     res = ta_exact (type);
779   } break;
780
781   case (iro_Call): {
782     /* presumably call (sel (proj (call))) */
783     ir_node *ptr = get_Call_ptr (node);
784     entity *meth = NULL;
785     if (iro_Sel == get_irn_opcode (ptr)) {
786       meth = get_Sel_entity (ptr);
787     } else if (iro_SymConst == get_irn_opcode (ptr)) {
788       if (get_SymConst_kind (ptr) == symconst_addr_ent) {
789         meth = get_SymConst_entity (ptr);
790       } else {
791         meth = NULL;            /* WTF? */
792       }
793     }
794
795     if (NULL != meth) {
796       ir_type *tp = get_method_res_type ((ir_type*) meth, 0);
797       res = ta_type (tp);
798     } else {
799       /* could be anything */
800       /* fprintf (stdout, "meth= (null)"); */
801       res = NULL;
802     }
803
804     /* fprintf (stdout, "]\n"); */
805
806   } break;
807
808   case (iro_SymConst): {
809     if (get_SymConst_kind (node) == symconst_type_tag) {
810       ir_type *tp = get_SymConst_type (node);
811
812       res = ta_type (tp);
813     } else if (get_SymConst_kind (node) == symconst_addr_ent) {
814       entity *ent = get_SymConst_entity (node);
815       ir_type *tp = get_entity_owner (ent);
816
817       while (is_Pointer_type (tp)) {
818         tp = get_pointer_points_to_type (tp);
819       }
820
821       assert (is_Class_type (tp));
822
823       res = ta_type (tp);       /* can't use ta_exact */
824     } else if (get_SymConst_kind (node) == symconst_addr_name) {
825       /* oh, this is not a real call but a placeholder (exception stuff) */
826       fprintf (stdout, "%s (%s:%i): can't handle pseudo-call %s\n",
827                __FUNCTION__, __FILE__, __LINE__,
828                get_op_name (get_irn_op (node)));
829
830       res = NULL;
831     } else {
832       fprintf (stdout, "%s (%s:%i): can't handle SymConst %s\n",
833                __FUNCTION__, __FILE__, __LINE__,
834                get_op_name (get_irn_op (node)));
835
836       res = NULL;
837     }
838   } break;
839   case (iro_Const): {
840     /* presumably a NULL constant */
841     /* this also means we cannot handle calls against a NULL pointer. */
842     res = NULL;
843   } break;
844
845     /* template:
846        case (iro_Cast): {}
847        break;
848     */
849
850   default: {
851     fprintf (stdout, "what's with %s?\n", get_op_name (get_irn_op (node)));
852     cough_and_die (node);
853   } break;
854   }
855
856   return (res);
857 }
858
859 /*
860   Initialise the Typalise module
861 */
862 void typalise_init (void)
863 {
864   if (NULL == java_lang_Throwable_tp) {
865     class_walk_super2sub (find_java_lang_Throwable, NULL, NULL);
866
867     /* make sure we have found it */
868     get_java_lang_Throwable ();
869   }
870 }
871
872
873
874 \f
875 /*
876   $Log$
877   Revision 1.12  2006/01/13 21:54:02  beck
878   renamed all types 'type' to 'ir_type'
879
880   Revision 1.11  2005/05/13 16:35:14  beck
881   made (void) prototypes
882   removed unused fprintf arguments
883
884   Revision 1.10  2005/05/06 12:02:34  beck
885   added missing includes
886   removed C99 features
887
888   Revision 1.9  2005/03/22 13:56:09  liekweg
889   "small" fix for exception b/d
890
891   Revision 1.8  2005/01/14 14:13:24  liekweg
892   fix gnu extension
893
894   Revision 1.7  2005/01/10 17:26:34  liekweg
895   fixup printfs, don't put environments on the stack
896
897   Revision 1.6  2005/01/05 14:25:54  beck
898   renames all is_x*_type() functions to is_X*_type() to prevent name clash with EDG fronten
899
900   Revision 1.5  2004/12/22 14:43:14  beck
901   made allocations C-like
902
903   Revision 1.4  2004/12/21 15:50:18  beck
904   removed C99 constructs
905
906   Revision 1.3  2004/12/02 16:17:51  beck
907   fixed config.h include
908
909   Revision 1.2  2004/10/22 09:53:10  liekweg
910   Correctly handle proj_args
911
912   Revision 1.1  2004/10/21 11:09:37  liekweg
913   Moved memwalk stuf into irmemwalk
914   Moved lset stuff into lset
915   Moved typalise stuff into typalise
916
917
918  */