be more helpful if a method does not exist
[libfirm] / ir / external / read.c
1 /* -*- c -*- */
2
3 /*
4  * Project:     libFIRM
5  * File name:   ir/external/read.c
6  * Purpose:     Read descriptions of external effects
7  * Author:      Florian
8  * Modified by: Boris Boesler
9  * Created:     11.10.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 #ifdef HAVE_CONFIG_H
16 # include "config.h"
17 #endif
18
19 /* get prototype for alloca somehow */
20 #ifdef HAVE_ALLOCA_H
21 # include <alloca.h>
22 #endif
23 #ifdef HAVE_STDLIB_H
24 # include <stdlib.h>
25 #endif
26
27 # include <string.h>
28
29 #include "read_t.h"
30 #include "read.h"
31 #include "irprog.h"
32 #include "irgraph.h"
33 #include "ircons.h"
34 #include "irmode.h"
35 #include "irdump.h"
36 #include "irvrfy.h"
37 #include "type.h"
38 #include "tv.h"
39
40 #define VERBOSE_PRINTING 0
41
42 #if VERBOSE_PRINTING
43 # define VERBOSE_PRINT(s) fprintf s
44 #else
45 # define VERBOSE_PRINT(s)
46 #endif
47
48 #define NO_ID NULL
49
50 static type_t *types = NULL;
51 static entity_t *entities = NULL;
52 static proc_t *procs = NULL;
53 static module_t *modules = NULL;
54
55 /* @@@ HACK */
56 static module_t *current_module = NULL;
57
58 #if VERBOSE_PRINTING
59 /* this is only used inside a VERBOSE_PRINT() call */
60 static char *effect_string[] = {
61   "arg",
62   "valref",
63   "select",
64   "load",
65   "store",
66   "alloc",
67   "call",
68   "unknown",
69   "join",
70   "raise",
71   "ret"
72 };
73 #endif /* defined VERBOSE_PRINTING */
74
75 static const ident*
76 getNodeModuleIdent (xmlNodePtr node)
77 {
78   const char *mod_str = (const char*) xmlGetProp (node, BAD_CAST "module");
79
80   if (NULL == mod_str) {
81     return (NULL);
82   } else {
83     const ident *res = new_id_from_str (mod_str);
84     return (res);
85   }
86 }
87
88 static const char*
89 getNodeProcName (xmlNodePtr node)
90 {
91   const char *proc_str = (const char*) xmlGetProp (node, BAD_CAST "procname");
92   assert (proc_str);
93   return (proc_str);
94 }
95
96 static char*
97 getNodeClassName (xmlNodePtr node)
98 {
99   char *proc_str = (char*) xmlGetProp (node, BAD_CAST "class");
100   assert (proc_str);
101   return ( (proc_str));
102 }
103
104 static const char*
105 getNodeId (xmlNodePtr node)
106 {
107   const char *id_str = (const char*) xmlGetProp (node, BAD_CAST "id");
108   assert (id_str);
109   return (id_str);
110 }
111
112 static const char *
113 getNodeRefId (xmlNodePtr node)
114 {
115   const char *refid_str = (char*) xmlGetProp (node, BAD_CAST "refid");
116   assert (refid_str);
117   return ((refid_str));
118 }
119
120 static const char*
121 getNodeTypeId (xmlNodePtr node)
122 {
123   const char *type_str = (char*) xmlGetProp (node, BAD_CAST "type");
124   assert (type_str);
125   return ((type_str));
126 }
127
128 static const char
129 *getNodeTypeStr (xmlNodePtr node)
130 {
131   const char *type_str = (char*) xmlGetProp (node, BAD_CAST "type");
132   assert (type_str);
133   return (type_str);
134 }
135
136 static const char*
137 getNodeOwnerStr (xmlNodePtr node)
138 {
139   const char *owner_str = (char*) xmlGetProp (node, BAD_CAST "owner");
140   assert (owner_str);
141   return (owner_str);
142 }
143
144 static const char
145 *getNodeEntityStr (xmlNodePtr node)
146 {
147   const char *ent_str = (char*) xmlGetProp (node, BAD_CAST "entity");
148   assert (ent_str);
149
150   return (ent_str);
151 }
152
153
154 /*
155   was Public Interface
156 */
157 static
158 type_t *getTypeByIdent (const ident *id)
159 {
160   type_t *curr = types; // @@@ TODO module -> types
161
162   while (NULL != curr) {
163     if (id == curr -> type_ident) {
164       return (curr);
165     }
166     curr = curr->prev;
167   }
168
169   return (NULL);
170 }
171
172 static
173 type_t *getTypeById (const ident *id)
174 {
175   type_t *curr = types; // which ones?
176
177   while (NULL != curr) {
178     if (id == curr -> id) {
179       return (curr);
180     }
181     curr = curr->prev;
182   }
183
184   return (NULL);
185 }
186
187 static
188 entity_t *getEntityByIdents (const ident *name, const ident *tp_ident)
189 {
190   entity_t *curr = entities; // TODO module -> entities
191
192   while (NULL != curr) {
193     if ((name == curr -> ent_ident)
194     && (tp_ident == curr -> tp_ident)) {
195       return (curr);
196     }
197     curr = curr->prev;
198   }
199
200   return (NULL);
201 }
202
203 static
204 entity_t *getEntityById (const ident *id)
205 {
206   entity_t *curr = entities;
207
208   while (NULL != curr) {
209     if (id == curr -> id) {
210       return (curr);
211     }
212     curr = curr->prev;
213   }
214
215   return (NULL);
216 }
217
218 static
219 proc_t *getEffectByName (const ident *proc_ident)
220 {
221   proc_t *curr_effs = procs;
222
223   while (NULL != curr_effs) {
224     if (proc_ident == curr_effs -> proc_ident) {
225       return (curr_effs);
226     }
227     curr_effs = curr_effs->next;
228   }
229
230   return (NULL);
231 }
232
233 static
234 xmlNodePtr get_any_valid_child(xmlNodePtr elem)
235 {
236   xmlNodePtr child;
237
238   assert(elem && "no element");
239   child = elem -> xmlChildrenNode;
240   while(child && (NODE_NAME (child, comment))) {
241     child = child -> next;
242   }
243   return(child);
244 }
245
246 static
247 xmlNodePtr get_valid_child(xmlNodePtr elem)
248 {
249   xmlNodePtr child;
250
251   child = get_any_valid_child(elem);
252   assert(child && "lost child in deep black forest");
253   return(child);
254 }
255
256 /*
257  * parse XML structure and construct an additional structure
258  */
259 static eff_t *
260 parseArg (xmlDocPtr doc, xmlNodePtr argelm)
261 {
262   const char *id;
263   const char *typeid;
264   int num;
265   char *num_str;
266   eff_t *arg;
267
268   CHECK_NAME (argelm, arg);
269   VERBOSE_PRINT ((stdout, "arg node \t0x%08x\n", (int) argelm));
270
271   id = getNodeId (argelm);
272   VERBOSE_PRINT ((stdout, "arg->id = \"%s\"\n", id));
273   num_str = (char*) xmlGetProp (argelm, BAD_CAST "number");
274   num = atoi (num_str);
275   VERBOSE_PRINT ((stdout, "arg->no = \"%d\"\n", num));
276
277   typeid = getNodeTypeStr (argelm);
278
279   arg = NEW (eff_t);
280   arg -> kind = eff_arg;
281   arg -> id = new_id_from_str(id);
282   arg -> effect.arg.num = num;
283   arg -> effect.arg.type_ident = new_id_from_str(typeid);
284
285   return (arg);
286 }
287
288 static eff_t*
289 parseValref (xmlDocPtr doc, xmlNodePtr valelm)
290 {
291   const char *ref_id;
292   eff_t *valref;
293
294   CHECK_NAME (valelm, valref);
295   VERBOSE_PRINT ((stdout, "valref node \t0x%08x\n", (int) valelm));
296
297   ref_id = getNodeRefId (valelm);
298   VERBOSE_PRINT ((stdout, "val->refid = \"%s\"\n", ref_id));
299
300   valref = NEW (eff_t);
301   valref->kind = eff_valref;
302   valref-> id = new_id_from_str(ref_id);
303
304   return (valref);
305 }
306
307 static eff_t*
308 parseSelect (xmlDocPtr doc, xmlNodePtr selelm)
309 {
310   const ident *entity_id = new_id_from_str(getNodeEntityStr (selelm));
311   entity_t *ent;
312   xmlNodePtr child;
313   eff_t *valref = NULL;
314   eff_t *sel = NEW (eff_t);
315   sel->kind = eff_select;
316
317   CHECK_NAME (selelm, select);
318   VERBOSE_PRINT ((stdout, "select node \t0x%08x\n", (int) selelm));
319
320   ent = getEntityById (entity_id);
321   assert(ent && "entity not found");
322   VERBOSE_PRINT ((stdout, "select entity %s\n", get_id_str(ent -> ent_ident)));
323
324   child = selelm->xmlChildrenNode;
325
326   if (child) {
327     valref = parseValref (doc, child);
328   }
329
330   sel-> id = valref ? valref-> id : NO_ID;
331   sel-> effect.select.ent = ent;
332
333   if (valref) {
334     free (valref);
335   }
336
337   return (sel);
338 }
339
340 static eff_t*
341 parseLoad (xmlDocPtr doc, xmlNodePtr loadelm)
342 {
343   const ident *id;
344   xmlNodePtr child;
345   eff_t *sel;
346   eff_t *load = NEW (eff_t);
347   load->kind = eff_load;
348
349   CHECK_NAME (loadelm, load);
350   VERBOSE_PRINT ((stdout, "load node \t0x%08x\n", (int) loadelm));
351   id = new_id_from_str(getNodeId (loadelm));
352
353   child = get_valid_child(loadelm);
354   if(NODE_NAME (child, select)) {
355     sel = parseSelect (doc, child);
356     load-> effect.load.ent = sel-> effect.select.ent;
357     VERBOSE_PRINT ((stdout, "load entity \t%s\n",
358             get_id_str(load -> effect.load.ent -> ent_ident)));
359   }
360   else {
361     sel = parseValref (doc, child);
362     load-> effect.load.ent = NULL;
363   }
364
365   load-> id = id;
366   load-> effect.load.ptrrefid = sel-> id;
367
368   free (sel);
369
370   return (load);
371 }
372
373 static eff_t*
374 parseStore (xmlDocPtr doc, xmlNodePtr storeelm)
375 {
376   xmlNodePtr child;
377   eff_t *sel;
378   eff_t *valref;
379   eff_t *store = NEW (eff_t);
380   store->kind = eff_store;
381
382   CHECK_NAME (storeelm, store);
383   VERBOSE_PRINT ((stdout, "store node \t0x%08x\n", (int) storeelm));
384
385   child = get_valid_child(storeelm);
386   if(NODE_NAME (child, select)) {
387     sel = parseSelect (doc, child);
388     store-> effect.store.ent = sel-> effect.select.ent;
389   }
390   else {
391     sel = parseValref (doc, child);
392     store-> effect.store.ent = NULL;
393   }
394
395   child = child->next;
396   valref = parseValref (doc, child);
397
398   store-> effect.store.ptrrefid = sel-> id;
399   store-> effect.store.valrefid = valref-> id;
400
401   free (sel);
402   free (valref);
403
404   return (store);
405 }
406
407 static eff_t*
408 parseAlloc (xmlDocPtr doc, xmlNodePtr allocelm)
409 {
410   const ident *id;
411   const ident *type_id;
412   eff_t *alloc = NEW (eff_t); /* ...! */
413   alloc->kind = eff_alloc;
414
415   CHECK_NAME (allocelm, alloc);
416   VERBOSE_PRINT ((stdout, "alloc node \t0x%08x\n", (int) allocelm));
417   id = new_id_from_str(getNodeId (allocelm));
418   VERBOSE_PRINT ((stdout, "alloc->id = \"%s\"\n", get_id_str(id)));
419   type_id = new_id_from_str(getNodeTypeId (allocelm));
420   VERBOSE_PRINT ((stdout, "alloc->type_id = \"%s\"\n", get_id_str(type_id)));
421
422   alloc-> id = id;
423   alloc-> effect.alloc.tp_id = type_id;
424
425   return (alloc);
426 }
427
428 static eff_t*
429 parseCall (xmlDocPtr doc, xmlNodePtr callelm)
430 {
431   const ident *id;
432   xmlNodePtr child;
433   eff_t *sel;
434   xmlNodePtr arg;
435   int n_args;
436   eff_t *call = NEW (eff_t);
437   call->kind = eff_call;
438
439   CHECK_NAME (callelm, call);
440   VERBOSE_PRINT ((stdout, "call node \t0x%08x\n", (int) callelm));
441   id = new_id_from_str(getNodeId (callelm));
442   VERBOSE_PRINT ((stdout, "call->id = \"%s\"\n", get_id_str(id)));
443
444   child = get_valid_child(callelm);
445   if(NODE_NAME (child, select)) {
446     sel = parseSelect (doc, child);
447     call-> effect.call.ent = sel-> effect.select.ent;
448   }
449   else {
450     sel = parseValref (doc, child);
451     call-> effect.call.ent = NULL;
452   }
453
454   arg = child = child->next;
455   n_args = 0;
456
457   while (NULL != child) {
458     n_args ++;
459     child = child->next;
460   }
461
462   call-> id = id;
463   call-> effect.call.valrefid = sel-> id;
464   call-> effect.call.n_args = n_args;
465   call-> effect.call.args = NULL;
466
467   free (sel);
468
469   if (0 != n_args) {
470     const ident **args = (const ident**) malloc(n_args * sizeof(const ident*));
471     int i = 0;
472
473     while (NULL != arg) {
474       eff_t *valref = parseValref (doc, arg);
475       args [i ++] = valref-> id;
476       free (valref);
477       arg = arg->next;
478     }
479
480     call-> effect.call.args = args;
481   }
482
483   return (call);
484 }
485
486 static eff_t*
487 parseJoin (xmlDocPtr doc, xmlNodePtr joinelm)
488 {
489   const ident *id;
490   int n_ins;
491   const ident **ins;
492   int i;
493   xmlNodePtr child;
494   eff_t *join = NEW (eff_t);
495   join->kind = eff_join;
496
497   CHECK_NAME (joinelm, join);
498   VERBOSE_PRINT ((stdout, "join node \t0x%08x\n", (int) joinelm));
499   id = new_id_from_str(getNodeId (joinelm));
500   VERBOSE_PRINT ((stdout, "join->id = \"%s\"\n", get_id_str(id)));
501
502   child = get_valid_child(joinelm);
503   n_ins = 0;
504
505   while (NULL != child) {
506     n_ins ++;
507     child = child->next;
508   }
509
510   ins = (const ident **) malloc (n_ins * sizeof (const ident *) );
511   i = 0;
512   child = get_valid_child(joinelm);
513
514   while (NULL != child) {
515     eff_t *valref = parseValref (doc, child);
516     ins [i ++] = valref-> id;
517     free(valref);
518     child = child->next;
519   }
520
521   join-> id = id;
522   join-> effect.join.n_ins = n_ins;
523   join-> effect.join.ins = ins;
524
525   return (join);
526 }
527
528 static eff_t*
529 parseUnknown (xmlDocPtr doc, xmlNodePtr unknownelm)
530 {
531   const ident *id;
532   eff_t *unknown = NEW (eff_t);
533   unknown->kind = eff_unknown;
534
535   CHECK_NAME (unknownelm, unknown);
536   VERBOSE_PRINT ((stdout, "unknown node \t0x%08x\n", (int) unknownelm));
537   id = new_id_from_str(getNodeId (unknownelm));
538   unknown-> id = id;
539
540   return (unknown);
541 }
542
543 static eff_t*
544 parseReturn (xmlDocPtr doc, xmlNodePtr retelm)
545 {
546   xmlNodePtr child;
547   eff_t *ret = NEW (eff_t);
548   ret->kind = eff_ret;
549
550   CHECK_NAME (retelm, ret);
551   VERBOSE_PRINT ((stdout, "ret node \t0x%08x\n", (int) retelm));
552
553   child = get_any_valid_child(retelm);
554
555   if (child) {
556     eff_t *valref = parseValref (doc, child);
557     ret-> effect.ret.ret_id = valref-> id;
558     free (valref);
559   } else {
560     ret-> effect.ret.ret_id = NO_ID;
561   }
562
563   return (ret);
564 }
565
566 static eff_t*
567 parseRaise (xmlDocPtr doc, xmlNodePtr raiseelm)
568 {
569   const char *tp_id;
570   eff_t *valref;
571   xmlNodePtr child;
572   eff_t *raise = NEW (eff_t);
573   raise->kind = eff_raise;
574
575   CHECK_NAME (raiseelm, raise);
576   VERBOSE_PRINT ((stdout, "raise node \t0x%08x\n", (int) raiseelm));
577   tp_id = getNodeTypeId (raiseelm);
578   VERBOSE_PRINT ((stdout, "raise->type = \"%s\"\n", tp_id));
579   child = get_valid_child(raiseelm);
580
581   assert (NULL != child);
582
583   valref = parseValref (doc, child);
584   raise-> effect.raise.valref = valref-> id;
585   raise-> effect.raise.tp_id = new_id_from_str(tp_id);
586   free (valref);
587
588   return (raise);
589 }
590
591
592 /*
593   Types and Entities
594 */
595
596 /** parse a type node and insert it into the list */
597 static void
598 parseType (xmlDocPtr doc, xmlNodePtr typeelm)
599 {
600   type_t *type;
601   const char *tp_id = getNodeId (typeelm);
602   VERBOSE_PRINT ((stdout, "type node \t0x%08x (%s)\n", (int) typeelm, tp_id));
603   VERBOSE_PRINT ((stdout, "type = \"%s\"\n", getNodeTypeStr (typeelm)));
604
605   type = (type_t*) malloc (sizeof (type_t));
606   type -> type_ident = new_id_from_str(getNodeTypeStr (typeelm));
607   type -> id         = new_id_from_str(tp_id);
608
609   type->prev = types;
610   types = type;
611 }
612
613 /** parse an entity node and insert it into the list */
614 static void
615 parseEntity (xmlDocPtr doc, xmlNodePtr entelm)
616 {
617   entity_t *ent = NEW (entity_t);
618
619   /* parse it */
620   const char *ent_id = getNodeId (entelm);
621   /* fprintf (stdout, "entity node \t0x%08x (%d)\n", (int) entelm, ent_id); */
622   VERBOSE_PRINT ((stdout, "ent  = \"%s.%s\"\n",
623           getNodeTypeStr (entelm),
624           getNodeEntityStr (entelm)));
625
626
627   ent -> ent_ident = new_id_from_str (getNodeEntityStr (entelm));
628   ent -> tp_ident  = new_id_from_str (getNodeTypeStr   (entelm));
629   ent -> owner     = new_id_from_str (getNodeOwnerStr  (entelm));
630   ent -> id = new_id_from_str(ent_id);
631
632   ent->prev = entities;
633   entities = ent;
634 }
635
636 /** parse any effect, and turn it into an eff_t (TODO) */
637 static void
638 parseEffect (xmlDocPtr doc, xmlNodePtr effelm)
639 {
640   xmlNodePtr cur;
641   const char *procname = getNodeProcName (effelm);
642   const char *ownerid = getNodeOwnerStr (effelm);
643   proc_t *curr_effs = NULL;
644   int i = 0;
645   int n_effs = 0;
646
647   VERBOSE_PRINT ((stdout, "effect for method \"%s\"\n", procname));
648
649   cur = effelm -> xmlChildrenNode;
650   while (NULL != cur) {
651     n_effs ++;
652     cur = cur->next;
653   }
654   VERBOSE_PRINT ((stdout, "has %d effects\n", n_effs));
655
656   curr_effs = NEW (proc_t);
657   curr_effs -> proc_ident = new_id_from_str(procname);
658   curr_effs -> ownerid = new_id_from_str(ownerid);
659   curr_effs->effs = (eff_t**) malloc (n_effs * sizeof (eff_t*));
660
661   cur = effelm -> xmlChildrenNode;
662   while (NULL != cur) {
663     eff_t *eff = NULL;
664
665     if (NODE_NAME (cur, arg)) {
666       eff = (eff_t*) parseArg (doc, cur);
667     } else if (NODE_NAME (cur, load)) {
668       eff = (eff_t*) parseLoad (doc, cur);
669     } else if (NODE_NAME (cur, store)) {
670       eff = (eff_t*) parseStore (doc, cur);
671     } else if (NODE_NAME (cur, alloc)) {
672       eff = (eff_t*) parseAlloc (doc, cur);
673     } else if (NODE_NAME (cur, call)) {
674       eff = (eff_t*) parseCall (doc, cur);
675     } else if (NODE_NAME (cur, join)) {
676       eff = (eff_t*) parseJoin (doc, cur);
677     } else if (NODE_NAME (cur, unknown)) {
678       eff = (eff_t*) parseUnknown (doc, cur);
679     } else if (NODE_NAME (cur, ret)) {
680       eff = (eff_t*) parseReturn (doc, cur);
681     } else if (NODE_NAME (cur, raise)) {
682       eff = (eff_t*) parseRaise (doc, cur);
683     } else if (NODE_NAME (cur, comment)) {
684       /* comment */
685       --n_effs;
686     } else {
687       fprintf (stderr, "wrong element \"%s\"\n", BAD_CAST cur->name);
688       exit (EXIT_FAILURE);
689     }
690     if(eff) {
691       VERBOSE_PRINT ((stdout, "effect %p@%d\n", (void*)eff, i));
692       curr_effs -> effs[i++] = eff;
693     }
694     cur = cur -> next;
695   }
696   assert((i == n_effs) && "incorrect number of effects");
697   curr_effs -> n_effs = n_effs;
698   curr_effs -> next = procs;
699   procs = curr_effs;
700 }
701
702
703 static
704 void read_extern (const char *filename)
705 {
706   /* xmlNsPtr ns = NULL; */           /* no namespace for us */
707   xmlDocPtr doc;                /* whole document */
708   xmlNodePtr cur;               /* current node */
709   ident *mod_id;
710   module_t *module;
711
712   /* i've got no idea what the VERSION cast is all about. voodoo
713      programming at its finest. */
714   LIBXML_TEST_VERSION xmlKeepBlanksDefault (0);
715   VERBOSE_PRINT((stdout, "read file %s\n", filename));
716   doc = xmlParseFile (filename);
717   CHECK (doc, "xmlParseFile");
718
719   cur = xmlDocGetRootElement (doc);
720   CHECK (cur, "xmlDocGetRootElement");
721
722   if (! NODE_NAME (cur, effects)) {
723     fprintf (stderr,"root node \"%s\" != \"effects\"\n", BAD_CAST cur->name);
724     xmlFreeDoc (doc);
725     exit (EXIT_FAILURE);
726   }
727
728   mod_id = getNodeModuleIdent (cur);
729   if (NULL != mod_id) {
730     VERBOSE_PRINT ((stdout, "effects for \"%s\"\n",
731             get_id_str(mod_id)));
732   }
733   else {
734     VERBOSE_PRINT ((stdout, "effects \t0x%08x\n", (int) cur));
735   }
736
737   /* parse entities */
738   cur = cur->xmlChildrenNode;
739   while (cur != NULL) {
740     if (NODE_NAME (cur, type)) {
741       parseType (doc, cur);
742     } else if (NODE_NAME (cur, entity)) {
743       parseEntity (doc, cur);
744     } else if (NODE_NAME (cur, effect)) {
745       parseEffect (doc, cur);
746     } else if ((NODE_NAME (cur, comment))) {
747       /* comment */
748     } else {
749       fprintf (stderr, "wrong element \"%s\"\n", BAD_CAST cur->name);
750       exit (EXIT_FAILURE);
751     }
752     cur = cur->next;
753   }
754
755   module = NEW(module_t);
756   module -> id = mod_id;
757   module -> types = types;
758   module -> entities = entities;
759   module -> procs = procs;
760
761   types = NULL;
762   entities = NULL;
763   procs = NULL;
764
765   module -> next = modules;
766   modules = module;
767 }
768
769 /********************************************************************/
770
771 /*
772  * free additional structure
773  */
774 static
775 void freeArg (eff_t *arg)
776 {
777   VERBOSE_PRINT ((stdout, "free arg node \t0x%08x\n", (int) arg));
778   free(arg);
779   return;
780 }
781
782 static
783 void freeValref (eff_t *valref)
784 {
785   VERBOSE_PRINT ((stdout, "free valref node \t0x%08x\n", (int) valref));
786   free(valref);
787   return;
788 }
789
790 static
791 void freeSelect (eff_t *sel)
792 {
793   VERBOSE_PRINT ((stdout, "free select node \t0x%08x\n", (int) sel));
794   free(sel);
795   return;
796 }
797
798 static
799 void freeLoad (eff_t *load)
800 {
801   VERBOSE_PRINT ((stdout, "free load node \t0x%08x\n", (int) load));
802   free (load);
803   return;
804 }
805
806 static
807 void freeStore (eff_t *store)
808 {
809   VERBOSE_PRINT ((stdout, "free store node \t0x%08x\n", (int) store));
810   free (store);
811   return;
812 }
813
814 static
815 void freeAlloc (eff_t *alloc)
816 {
817   VERBOSE_PRINT ((stdout, "free alloc node \t0x%08x\n", (int) alloc));
818   free(alloc);
819   return;
820 }
821
822 static
823 void freeCall (eff_t *call)
824 {
825   VERBOSE_PRINT ((stdout, "free call node \t0x%08x\n", (int) call));
826   free(call -> effect.call.args);
827   free(call);
828   return;
829 }
830
831 static
832 void freeJoin (eff_t *join)
833 {
834   VERBOSE_PRINT ((stdout, "free join node \t0x%08x\n", (int) join));
835   free(join -> effect.join.ins);
836   free(join);
837   return;
838 }
839
840 static
841 void freeUnknown (eff_t *unknown)
842 {
843   VERBOSE_PRINT ((stdout, "free unknown node \t0x%08x\n", (int) unknown));
844   free(unknown);
845   return;
846 }
847
848 static
849 void freeReturn (eff_t *ret)
850 {
851   VERBOSE_PRINT ((stdout, "free ret node \t0x%08x\n", (int) ret));
852   free(ret);
853   return;
854 }
855
856 static
857 void freeRaise (eff_t *raise)
858 {
859   VERBOSE_PRINT ((stdout, "free raise node \t0x%08x\n", (int) raise));
860   free (raise);
861   return;
862 }
863
864
865 static
866 void freeProcEffs(proc_t *proc)
867 {
868   int i;
869   int num;
870
871   VERBOSE_PRINT ((stdout, "free effect for method \"%s\"\n",
872           get_id_str(proc -> proc_ident)));
873
874   num = proc -> n_effs;
875   for(i = 0; i < num; i++) {
876     switch(proc -> effs[i] -> kind) {
877     case eff_arg:
878       freeArg(proc -> effs[i]);
879       break;
880     case eff_valref:
881       freeValref(proc -> effs[i]);
882       break;
883     case eff_select:
884       freeSelect(proc -> effs[i]);
885       break;
886     case eff_load:
887       freeLoad(proc -> effs[i]);
888       break;
889     case eff_store:
890       freeStore(proc -> effs[i]);
891       break;
892     case eff_alloc:
893       freeAlloc(proc -> effs[i]);
894       break;
895     case eff_call:
896       freeCall(proc -> effs[i]);
897       break;
898     case eff_unknown:
899       freeUnknown(proc -> effs[i]);
900       break;
901     case eff_join:
902       freeJoin(proc -> effs[i]);
903       break;
904     case eff_raise:
905       freeRaise(proc -> effs[i]);
906       break;
907     case eff_ret:
908       freeReturn(proc -> effs[i]);
909       break;
910     default:
911       assert(0 && "try to free an unknown effect");
912       break;
913     }
914   }
915   free(proc -> effs);
916   proc -> effs = NULL;
917 }
918
919 static
920 void freeModuleProcs(module_t *module)
921 {
922   proc_t *next_proc, *proc;
923
924   VERBOSE_PRINT ((stdout, "free procs for module \"%s\"\n",
925           get_id_str(module -> id)));
926
927   proc = module -> procs;
928   while(proc) {
929     next_proc = proc -> next;
930     freeProcEffs(proc);
931     free(proc);
932     proc = next_proc;
933   }
934 }
935
936 static
937 void free_data(void)
938 {
939   module_t *module, *next_module;
940
941   module = modules;
942   while(module) {
943     freeModuleProcs(module);
944     next_module = module -> next;
945     free(module);
946     module = next_module;
947   }
948 }
949
950 /********************************************************************/
951
952 static
953 type_t *find_type_in_module(module_t *module, const ident *typeid)
954 {
955   type_t *type;
956
957   for(type = module -> types; type; type = type -> prev) {
958     VERBOSE_PRINT((stdout, "test typeid %s\n", get_id_str(type -> id)));
959     if(type -> id == typeid) {
960       VERBOSE_PRINT((stdout, "found\n"));
961       return(type);
962     }
963   }
964   VERBOSE_PRINT((stdout, "did not find type id %s\n", get_id_str(typeid)));
965   return(NULL);
966 }
967
968 /********************************************************************/
969
970 static void add_value_to_proc(proc_t *proc, eff_t *eff)
971 {
972   eff -> next = proc -> values;
973   proc -> values = eff;
974 }
975
976
977 eff_t *find_valueid_in_proc_effects(const ident *id, proc_t *proc)
978 {
979   eff_t *val;
980
981   val = proc -> values;
982   while(val) {
983     if(id == val -> id) {
984       return(val);
985     }
986     val = val -> next;
987   }
988   return(NULL);
989 }
990
991 static void create_abstract_return(ir_graph *irg, proc_t *proc, eff_t *eff)
992 {
993   ir_node *x;
994   eff_t *eff_res;
995
996   VERBOSE_PRINT((stdout, "create effect:return in %s\n",
997          get_id_str(proc -> proc_ident)));
998   if(NO_ID == eff -> effect.ret.ret_id) {
999     /* return void */
1000     x = new_Return (get_store(), 0, NULL);
1001   }
1002   else {
1003     ir_node *in[1];
1004
1005     /* return one value */
1006     eff_res = find_valueid_in_proc_effects(eff -> effect.ret.ret_id, proc);
1007     assert(eff_res -> firmnode && "firm in effect not set");
1008     in[0] = eff_res -> firmnode;
1009     x = new_Return (get_store(), 1, in);
1010   }
1011   eff -> firmnode = x;
1012
1013   /* Now we generated all instructions for this block and all its predecessor
1014    * blocks so we can mature it.  (There are not too much.) */
1015   mature_immBlock (get_irg_current_block(irg));
1016
1017   /* This adds the in edge of the end block which originates at the return statement.
1018    * The return node passes controlflow to the end block.  */
1019   add_immBlock_pred (get_irg_end_block(irg), x);
1020 }
1021
1022
1023 static void create_abstract_arg(ir_graph *irg, proc_t *proc, eff_t *eff)
1024 {
1025   ir_node *arg;
1026   entity *ent;
1027   ir_mode *mode;
1028   type *typ;
1029   int num;
1030
1031   VERBOSE_PRINT((stdout, "create effect:arg %d in %s\n",
1032          eff -> effect.arg.num, get_id_str(proc -> proc_ident)));
1033   ent = get_irg_entity(irg);
1034   typ = get_entity_type(ent);
1035
1036   /* read argument eff -> effect.arg.num and place in values list */
1037   num = get_method_n_params(typ);
1038   assert((num >= eff -> effect.arg.num) && "number too big");
1039   typ = get_method_param_type(typ, eff -> effect.arg.num);
1040   mode = get_type_mode(typ);
1041
1042   arg = new_Proj(get_irg_args(irg), mode, eff -> effect.arg.num);
1043   eff -> firmnode = arg;
1044
1045   add_value_to_proc(proc, eff);
1046 }
1047
1048
1049 static void create_abstract_load(ir_graph *irg, proc_t *proc, eff_t *eff)
1050 {
1051   ir_node *sel, *load;
1052   entity *ent;
1053   ir_mode *mode;
1054   eff_t *addr;
1055
1056   VERBOSE_PRINT((stdout, "create load in %s\n",
1057          get_id_str(proc -> proc_ident)));
1058
1059   if(eff -> effect.load.ent) {
1060     ent = eff -> effect.load.ent -> f_ent;
1061     VERBOSE_PRINT((stdout, "load from %s\n", get_entity_name(ent)));
1062   }
1063   else {
1064     VERBOSE_PRINT((stdout, "store to memory\n"));
1065     ent = NULL;
1066   }
1067
1068   addr = find_valueid_in_proc_effects(eff -> effect.load.ptrrefid, proc);
1069   assert(addr && "no address for load");
1070   /* if addr is Unknown, set proper mode */
1071   if(iro_Unknown == get_irn_opcode(addr -> firmnode)) {
1072     set_irn_mode(addr -> firmnode, mode_P);
1073   }
1074
1075   if(ent) {
1076     sel = new_simpleSel(get_store(), addr -> firmnode, ent);
1077     mode = get_type_mode(get_entity_type(ent));
1078   }
1079   else {
1080     sel = addr -> firmnode;
1081     mode = mode_ANY;
1082   }
1083   load = new_Load(get_store(), sel, mode);
1084   set_store(new_Proj(load, mode_M, 0));
1085   eff -> firmnode = new_Proj(load, mode, 2);
1086
1087   add_value_to_proc(proc, eff);
1088 }
1089
1090
1091 static void create_abstract_store(ir_graph *irg, proc_t *proc, eff_t *eff)
1092 {
1093   ir_node *sel, *store;
1094   entity *ent;
1095   eff_t *addr, *val;
1096
1097   VERBOSE_PRINT((stdout, "create store in %s\n",
1098          get_id_str(proc -> proc_ident)));
1099
1100   if(eff -> effect.store.ent) {
1101     ent = eff -> effect.store.ent -> f_ent;
1102     VERBOSE_PRINT((stdout, "store to entity %s\n", get_entity_name(ent)));
1103   }
1104   else {
1105     VERBOSE_PRINT((stdout, "store to memory\n"));
1106     ent = NULL;
1107   }
1108
1109   addr = find_valueid_in_proc_effects(eff -> effect.store.ptrrefid, proc);
1110   assert(addr && "no address for store");
1111   /* if addr is Unknown, set propper mode */
1112   if(iro_Unknown == get_irn_opcode(addr -> firmnode)) {
1113     set_irn_mode(addr -> firmnode, mode_P);
1114   }
1115
1116   val = find_valueid_in_proc_effects(eff -> effect.store.valrefid, proc);
1117   assert(val && "no address for store");
1118   /* if addr is Unknown, set propper mode */
1119   if(iro_Unknown == get_irn_opcode(val -> firmnode)) {
1120     set_irn_mode(val -> firmnode, get_type_mode(get_entity_type(ent)));
1121   }
1122
1123   if(ent) {
1124     sel = new_simpleSel(get_store(), addr -> firmnode, ent);
1125   }
1126   else {
1127     sel = addr -> firmnode;
1128   }
1129   store = new_Store(get_store(), sel, val -> firmnode);
1130   set_store(new_Proj(store, mode_M, 0));
1131   eff -> firmnode = store;
1132 }
1133
1134
1135 static void create_abstract_alloc(ir_graph *irg, proc_t *proc, eff_t *eff)
1136 {
1137   type *ftype;
1138   ir_node *alloc;
1139   type_t *xtype;
1140   symconst_symbol sym;
1141
1142   VERBOSE_PRINT((stdout, "create alloc in %s\n",
1143          get_id_str(proc -> proc_ident)));
1144
1145   xtype = find_type_in_module(current_module, eff -> effect.alloc.tp_id);
1146   assert(xtype && "type not found");
1147   ftype = xtype -> f_tp;
1148
1149   sym.type_p = ftype;
1150   alloc = new_Alloc(get_store(), new_SymConst(sym, symconst_size), ftype,
1151             heap_alloc);
1152   set_store(new_Proj(alloc, mode_M, 0));
1153   eff -> firmnode = new_Proj(alloc, mode_P, 2);
1154
1155   add_value_to_proc(proc, eff);
1156 }
1157
1158
1159 static void create_abstract_unknown(ir_graph *irg, proc_t *proc, eff_t *eff)
1160 {
1161   ir_node *unknown;
1162
1163   VERBOSE_PRINT((stdout, "create unknown in %s\n",
1164          get_id_str(proc -> proc_ident)));
1165
1166   unknown = new_Unknown(mode_ANY);
1167   eff -> firmnode = unknown;
1168
1169   add_value_to_proc(proc, eff);
1170 }
1171
1172
1173 static void create_abstract_call(ir_graph *irg, proc_t *proc, eff_t *eff)
1174 {
1175   ir_node *sel, *call;
1176   entity *ent;
1177   eff_t *addr;
1178   ir_node **irns;
1179   int i, num;
1180   type *mtype;
1181   int mik; /* is method somehow known? */
1182
1183   VERBOSE_PRINT((stdout, "create call in %s\n",
1184          get_id_str(proc -> proc_ident)));
1185
1186   if(eff -> effect.call.ent) {
1187     ent = eff -> effect.call.ent -> f_ent;
1188     VERBOSE_PRINT((stdout, "call %s\n", get_entity_name(ent)));
1189   }
1190   else {
1191     ent = NULL;
1192     VERBOSE_PRINT((stdout, "call something in memory\n"));
1193   }
1194
1195   addr = find_valueid_in_proc_effects(eff -> effect.call.valrefid, proc);
1196   assert(addr && "no address for load");
1197   /* if addr is Unknown, set propper mode */
1198   if(iro_Unknown == get_irn_opcode(addr -> firmnode)) {
1199     set_irn_mode(addr -> firmnode, mode_P);
1200   }
1201
1202   if(ent) {
1203     /* the address */
1204     sel = new_simpleSel(get_store(), addr -> firmnode, ent);
1205     /* mthod type */
1206     mtype = get_entity_type(ent);
1207     mik = true;
1208   }
1209   else {
1210     /* the address */
1211     sel = addr -> firmnode;
1212     /* mthod type */
1213     mtype = get_unknown_type();
1214     mik = false;
1215   }
1216
1217   /* the args */
1218   num = eff -> effect.call.n_args;
1219   VERBOSE_PRINT((stdout, "number of args given: %d\n", num));
1220   if(mik) {
1221     VERBOSE_PRINT((stdout, "number of args expected: %d\n",
1222            get_method_n_params(mtype)));
1223   }
1224   irns = alloca(num * sizeof(ir_node*));
1225   for(i = 0; i < num; i++) {
1226     irns[i] = find_valueid_in_proc_effects(eff -> effect.call.args[i], proc)
1227       -> firmnode;
1228     if(iro_Unknown == get_irn_opcode(irns[i])) {
1229       if(mik) {
1230     set_irn_mode(irns[i], get_type_mode(get_method_param_type(mtype, i)));
1231       }
1232       else {
1233     set_irn_mode(irns[i], mode_ANY);
1234       }
1235     }
1236   }
1237   call = new_Call(get_store(), sel, num, irns, mtype);
1238   set_store(new_Proj(call, mode_M, 0));
1239   if(mik && (0 != get_method_n_ress(mtype))) {
1240     eff -> firmnode = new_Proj(call,
1241                    get_type_mode(get_method_res_type(mtype, 0)),
1242                    0);
1243     add_value_to_proc(proc, eff); /* result can be accessed */
1244   }
1245   else {
1246     eff -> firmnode = NULL; /* result can not be accessed */
1247   }
1248 }
1249
1250 static void create_abstract_join (ir_graph *irg, proc_t *proc, eff_t *eff)
1251 {
1252   ir_node **ins    = NULL;
1253   ir_node *unknown = NULL;
1254   ir_node *cond    = NULL;
1255   ir_node *block   = NULL;
1256   ir_node *c_block = NULL;
1257   ir_node *phi     = NULL;
1258   ir_mode *join_md = mode_ANY;
1259   int n_ins = -1;
1260   int i;
1261
1262   VERBOSE_PRINT((stdout, "create join in %s\n",
1263          get_id_str(proc -> proc_ident)));
1264
1265   assert (eff_join == eff->kind);
1266
1267   n_ins = eff->effect.join.n_ins;
1268
1269   /* seems like current_block is not always mature at this point */
1270   mature_immBlock (get_cur_block ());
1271
1272   block = get_cur_block ();     /* remember this so we can put the ProjXs into it */
1273
1274   /* jump based on an unknown condition so all values are possible */
1275   unknown = new_Unknown (mode_Iu);
1276   cond    = new_Cond (unknown);
1277
1278   c_block   = new_immBlock ();  /* for the Phi after the branch(es) */
1279
1280   ins = (ir_node**) malloc (n_ins * sizeof (ir_node*));
1281   for (i = 0; i < n_ins; i ++) {
1282     ir_node *projX   = NULL;
1283     ir_node *s_block = NULL;
1284     ir_node *jmp     = NULL;
1285     eff_t *in_eff;
1286
1287     /* make sure the projX is in the 'switch' block */
1288     set_cur_block (block);
1289     projX   = new_Proj (cond, mode_X, (long) i);
1290
1291     /* this also sets current_block, so the rest of the code ends up there: */
1292     s_block = new_immBlock ();
1293
1294     add_immBlock_pred (s_block, projX);
1295     mature_immBlock (s_block);
1296
1297     in_eff = find_valueid_in_proc_effects (eff->effect.join.ins [i], proc);
1298
1299     ins [i] = in_eff->firmnode;
1300
1301     /* need to find a suitable mode for the Phi node */
1302     if (mode_ANY != get_irn_mode (ins [i])) {
1303       join_md = get_irn_mode (ins [i]);
1304     }
1305
1306     jmp = new_Jmp ();
1307     add_immBlock_pred (c_block, jmp);
1308   }
1309
1310   set_cur_block (c_block);
1311
1312   phi = new_Phi (n_ins, ins, join_md);
1313
1314   mature_immBlock (c_block);
1315   memset (ins, 0x00, n_ins * sizeof (ir_node*));
1316   free (ins);
1317
1318   eff->firmnode = phi;
1319
1320   add_value_to_proc (proc, eff);
1321 }
1322
1323 static void create_abstract_raise (ir_graph *irg, proc_t *proc, eff_t *eff)
1324 {
1325   ir_node *block   = NULL;
1326   ir_node *unknown = NULL;
1327   ir_node *cond    = NULL;
1328
1329   /* seems like current_block is not always mature at this point */
1330   mature_immBlock (get_cur_block ());
1331   block = get_cur_block ();     /* remember this so we can put the ProjXs into it */
1332
1333   /* jump based on an unknown condition so both values are possible */
1334   unknown = new_Unknown (mode_Iu);
1335   cond    = new_Cond (unknown);
1336
1337   /* one branch for 'throw-exception' case */
1338   {
1339     ir_node *projX = new_Proj (cond, mode_X, 1L);
1340     ir_node *b_exc = new_immBlock ();
1341     ir_node *obj   = NULL;
1342     ir_node *thrw  = NULL;
1343     eff_t *thrw_eff = NULL;
1344
1345     add_immBlock_pred (b_exc, projX);
1346
1347     thrw_eff = find_valueid_in_proc_effects (eff->effect.raise.valref, proc);
1348     obj = thrw_eff->firmnode;
1349
1350     thrw = new_Raise (get_store (), obj);
1351     /* exc-jump to end block */
1352     thrw = new_Proj (thrw, mode_X, 0L);
1353
1354     add_immBlock_pred (get_irg_end_block (irg), thrw);
1355     mature_immBlock (get_cur_block ());
1356   }
1357
1358   set_cur_block (block);     /* back to the first block */
1359
1360   /* one branch for 'non-exception' case */
1361   {
1362     ir_node *projX = new_Proj (cond, mode_X, 0);
1363     new_immBlock ();            /* also sets current_block */
1364     add_immBlock_pred (get_cur_block (), projX);
1365     mature_immBlock (get_cur_block ());
1366     /* continue building in current_block */
1367   }
1368
1369 }
1370
1371 static void create_abstract_firm(module_t *module, proc_t *proc, entity *fent)
1372 {
1373   eff_t *eff;
1374   ir_graph *irg;
1375   int i, num;
1376
1377   /* test entity */
1378   assert(visibility_external_allocated == get_entity_visibility(fent)
1379      && peculiarity_existent == get_entity_peculiarity(fent)
1380      && "not an abstract entity");
1381   /* create irg in entity */
1382   irg = new_ir_graph(fent, 0);
1383   set_irg_inline_property(irg, irg_inline_forbidden);
1384
1385   VERBOSE_PRINT((stdout, "create effects for %s\n",
1386          get_id_str(proc -> proc_ident)));
1387
1388   /* create effects in irg */
1389   num = proc -> n_effs;
1390   for(i = 0; i < num; i++) {
1391     eff = proc -> effs[i];
1392     VERBOSE_PRINT((stdout,
1393            "create effect \"%s\"\n", effect_string[(int)eff -> kind]));
1394     switch(eff -> kind) {
1395     case eff_ret:
1396       create_abstract_return(irg, proc, eff);
1397       break;
1398     case eff_arg:
1399       create_abstract_arg(irg, proc, eff);
1400       break;
1401     case eff_load:
1402       create_abstract_load(irg, proc, eff);
1403       break;
1404     case eff_store:
1405       create_abstract_store(irg, proc, eff);
1406       break;
1407     case eff_unknown:
1408       create_abstract_unknown(irg, proc, eff);
1409       break;
1410     case eff_alloc:
1411       create_abstract_alloc(irg, proc, eff);
1412       break;
1413     case eff_call:
1414       create_abstract_call(irg, proc, eff);
1415       break;
1416     case eff_join:
1417       create_abstract_join(irg, proc, eff);
1418       break;
1419     case eff_raise:
1420       create_abstract_raise(irg, proc, eff);
1421       break;
1422     default:
1423       assert(0 && "effect not implemented");
1424       break;
1425     }
1426   }
1427
1428   /* close irg in entity */
1429   /* Now we can mature the end block as all it's predecessors are known. */
1430   mature_immBlock (get_irg_end_block(irg));
1431
1432   /* Verify the graph.  Finds some very bad errors in the graph. */
1433   VERBOSE_PRINT((stdout, "verify graph\n"));
1434   irg_vrfy(irg);
1435   VERBOSE_PRINT((stdout, "finalize construction\n"));
1436   finalize_cons (irg);
1437 }
1438
1439 /********************************************************************/
1440
1441 static void assign_firm_entity(module_t *module, entity_t *xmlent)
1442 {
1443   int i, num;
1444   type_t *typ;
1445   type *type;
1446   entity *ent;
1447
1448   VERBOSE_PRINT((stdout, "assign entity %s to typeid %s\n",
1449          get_id_str(xmlent -> ent_ident),
1450          get_id_str(xmlent -> owner)));
1451
1452   typ = find_type_in_module(module, xmlent -> owner);
1453   assert(typ && "class not found in module");
1454   type = typ -> f_tp;
1455   assert(is_class_type(type));
1456
1457   num = get_class_n_members(type);
1458   ent = NULL;
1459   for(i = 0; i < num; i++) {
1460     ent = get_class_member(type, i);
1461     VERBOSE_PRINT((stdout, "compare entity %s and %s\n",
1462            get_id_str(xmlent -> ent_ident), get_entity_name(ent)));
1463
1464     if(get_entity_ident(ent) == xmlent -> ent_ident) {
1465       break;
1466     }
1467     ent = NULL;
1468   }
1469   assert(ent && "did not find a entity");
1470
1471   xmlent -> f_ent = ent;
1472 }
1473
1474 /********************************************************************/
1475 /* must be primitive type or class type */
1476 static void assign_firm_type(type_t *xmltype)
1477 {
1478   int i;
1479   type *typ = NULL;
1480   int num;
1481
1482   VERBOSE_PRINT((stdout, "assign firm type to type %s\n",
1483                  get_id_str(xmltype -> type_ident)));
1484
1485   /* is it global type? */
1486   typ = get_glob_type();
1487   if(xmltype -> type_ident == get_type_ident(typ)) {
1488     /* yes */
1489     xmltype -> f_tp = typ;
1490     VERBOSE_PRINT((stdout, "is global type %s\n", get_type_name(typ)));
1491   } else {
1492     num = get_irp_n_types();
1493     for(i = 0; i < num; i++) {
1494       typ = get_irp_type(i);
1495       VERBOSE_PRINT((stdout, "test type %s\n", get_type_name(typ)));
1496       if(xmltype -> type_ident == get_type_ident(typ)) {
1497         VERBOSE_PRINT((stdout, "found type %s\n", get_type_name(typ)));
1498         xmltype -> f_tp = typ;
1499         break;
1500       }
1501       typ = NULL;
1502     }
1503   }
1504   assert(typ && "did not find a type");
1505 }
1506
1507 /********************************************************************/
1508 static
1509 void create_abstract_proc_effect(module_t *module, proc_t *proc)
1510 {
1511   int i, num;
1512   type *class_typ = NULL;
1513   type_t *type;
1514   entity *fent;
1515
1516   /* find the class of a procedure */
1517   VERBOSE_PRINT((stdout, "do find owner id %s\n", get_id_str(proc -> ownerid)));
1518   type = find_type_in_module(module, proc -> ownerid);
1519   assert(type && "class not found in module");
1520
1521   class_typ = get_glob_type();
1522   VERBOSE_PRINT((stdout, "test type %s\n", get_type_name(class_typ)));
1523   if(type -> type_ident != get_type_ident(class_typ)) {
1524     /* find module as class */
1525     num = get_irp_n_types();
1526     for(i = 0; i < num; i++) {
1527       class_typ = get_irp_type(i);
1528       VERBOSE_PRINT((stdout, "test type %s\n", get_type_name(class_typ)));
1529       if(is_class_type(class_typ)
1530      && (type -> type_ident == get_type_ident(class_typ))) {
1531     /* found class type */
1532     VERBOSE_PRINT((stdout, "found type %s\n", get_type_name(class_typ)));
1533     break;
1534       }
1535       class_typ = NULL;
1536     }
1537   }
1538   else {
1539     VERBOSE_PRINT((stdout, "found global type %s\n", get_type_name(class_typ)));
1540   }
1541   assert(class_typ && "type not found");
1542   assert(is_class_type(class_typ) && "is not a class type");
1543   type -> f_tp = class_typ;
1544
1545   /* find entity for procedure in class */
1546   VERBOSE_PRINT((stdout, "find method %s\n",
1547          get_id_str(proc -> proc_ident)));
1548
1549   num = get_class_n_members(class_typ);
1550   fent = NULL;
1551   for(i = 0; i < num; i++) {
1552     fent = get_class_member(class_typ, i);
1553     VERBOSE_PRINT((stdout, "test proc %s\n", get_entity_name(fent)));
1554     if(proc -> proc_ident == get_entity_ident(fent)) {
1555       VERBOSE_PRINT((stdout, "found proc %s\n",
1556              get_id_str(proc -> proc_ident)));
1557       /* @@@ TODO check args types - not in xml yet */
1558       /* create Firm stuff */
1559       create_abstract_firm(module, proc, fent);
1560       return;
1561     }
1562     else {
1563       fent = NULL;
1564     }
1565   }
1566
1567   /* fail */
1568   fprintf(stderr,
1569           "method %s not found\nNo effects generated\nCandidates are:\n",
1570           get_id_str(proc -> proc_ident));
1571   for(i = 0; i < num; i++) {
1572     fent = get_class_member(class_typ, i);
1573     fprintf(stderr, "%s\n", get_entity_name(fent));
1574   }
1575   //assert(fent && "procedure not found in class");
1576 }
1577
1578 static
1579 void create_abstract_module(module_t *module)
1580 {
1581   proc_t *proc;
1582   type_t *type;
1583   entity_t *ent;
1584
1585   VERBOSE_PRINT((stdout, "create an abstraction for module %s\n",
1586          get_id_str(module -> id)));
1587
1588   VERBOSE_PRINT((stdout, "--handle types for module\n"));
1589   for(type = module -> types; type; type = type -> prev) {
1590     assign_firm_type(type);
1591   }
1592
1593   VERBOSE_PRINT((stdout, "--handle entities for module\n"));
1594   /* @@@ TODO */
1595   for(ent = module -> entities; ent; ent = ent -> prev) {
1596     assign_firm_entity(module, ent);
1597   }
1598
1599   VERBOSE_PRINT((stdout, "--handle procs for module\n"));
1600   for(proc = module -> procs; proc; proc = proc -> next) {
1601     create_abstract_proc_effect(module, proc);
1602   }
1603 }
1604
1605
1606 void create_abstraction(const char *filename)
1607 {
1608   module_t *module;
1609
1610   /* read and parse XML file */
1611   read_extern(filename);
1612
1613   /* finished reading and parsing here */
1614   /* build FIRM graphs */
1615   module = modules;
1616   while(module) {
1617     current_module = module;
1618     create_abstract_module(module);
1619     module = module -> next;
1620   }
1621   current_module = NULL;
1622
1623   /* free data structures */
1624   free_data();
1625
1626   types = NULL;
1627   entities = NULL;
1628   procs = NULL;
1629   modules = NULL;
1630 }
1631
1632 /********************************************************************/
1633
1634 \f
1635 /*
1636  * $Log$
1637  * Revision 1.14  2004/11/10 14:42:00  boesler
1638  * be more helpful if a method does not exist
1639  *
1640  * Revision 1.13  2004/11/05 14:00:53  liekweg
1641  * added raise
1642  *
1643  * Revision 1.12  2004/11/02 14:30:31  liekweg
1644  * fixed multi-input join (thx, Boris) --flo
1645  *
1646  * Revision 1.11  2004/10/29 18:51:53  liekweg
1647  * Added Join
1648  *
1649  * Revision 1.10  2004/10/25 13:52:24  boesler
1650  * seperated read.h (public interface) and read_t.h (types)
1651  *
1652  * Revision 1.9  2004/10/22 13:51:35  boesler
1653  * prohibit inlining of pseudo ir_graphs
1654  *
1655  * Revision 1.8  2004/10/22 13:13:27  boesler
1656  * replaced char* by idents, minor fix in Firm codegen for call
1657  *
1658  * Revision 1.7  2004/10/21 15:31:55  boesler
1659  * added lots of stuff:
1660  * - build abstract syntax trees
1661  * - build Firm graphs for many effects, still todos
1662  *
1663  * Revision 1.5  2004/10/18 12:48:20  liekweg
1664  * avoid warning
1665  *
1666  * Revision 1.4  2004/10/14 11:31:53  liekweg
1667  * ...
1668  *
1669  * Revision 1.3  2004/10/13 13:36:28  rubino
1670  * fix for strdup
1671  *
1672  * Revision 1.2  2004/10/11 15:56:09  liekweg
1673  * Cleanup, comments ...
1674  * Added init func --flo
1675  *
1676  * Revision 1.1  2004/10/11 09:31:06  liekweg
1677  * First Import of XML reading procs --flo
1678  *
1679  */