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