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