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