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