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