Remove unnecessary return; at end of void functions.
[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 # 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 }
821
822 static
823 void freeValref (eff_t *valref)
824 {
825   VERBOSE_PRINT ((stdout, "free valref node \t0x%08x\n", (int) valref));
826   free(valref);
827 }
828
829 static
830 void freeSelect (eff_t *sel)
831 {
832   VERBOSE_PRINT ((stdout, "free select node \t0x%08x\n", (int) sel));
833   free(sel);
834 }
835
836 static
837 void freeLoad (eff_t *load)
838 {
839   VERBOSE_PRINT ((stdout, "free load node \t0x%08x\n", (int) load));
840   free (load);
841 }
842
843 static
844 void freeStore (eff_t *store)
845 {
846   VERBOSE_PRINT ((stdout, "free store node \t0x%08x\n", (int) store));
847   free (store);
848 }
849
850 static
851 void freeAlloc (eff_t *alloc)
852 {
853   VERBOSE_PRINT ((stdout, "free alloc node \t0x%08x\n", (int) alloc));
854   free(alloc);
855 }
856
857 static
858 void freeCall (eff_t *call)
859 {
860   VERBOSE_PRINT ((stdout, "free call node \t0x%08x\n", (int) call));
861   free(call -> effect.call.args);
862   free(call);
863 }
864
865 static
866 void freeJoin (eff_t *join)
867 {
868   VERBOSE_PRINT ((stdout, "free join node \t0x%08x\n", (int) join));
869   free(join -> effect.join.ins);
870   free(join);
871 }
872
873 static
874 void freeUnknown (eff_t *unknown)
875 {
876   VERBOSE_PRINT ((stdout, "free unknown node \t0x%08x\n", (int) unknown));
877   free(unknown);
878 }
879
880 static
881 void freeReturn (eff_t *ret)
882 {
883   VERBOSE_PRINT ((stdout, "free ret node \t0x%08x\n", (int) ret));
884   free(ret);
885 }
886
887 static
888 void freeRaise (eff_t *raise)
889 {
890   VERBOSE_PRINT ((stdout, "free raise node \t0x%08x\n", (int) raise));
891   free (raise);
892 }
893
894
895 static
896 void freeProcEffs(proc_t *proc)
897 {
898   int i;
899   int num;
900
901   VERBOSE_PRINT ((stdout, "free effect for method \"%s\"\n",
902           get_id_str(proc -> proc_ident)));
903
904   num = proc -> n_effs;
905   for(i = 0; i < num; i++) {
906     switch(proc -> effs[i] -> kind) {
907     case eff_arg:
908       freeArg(proc -> effs[i]);
909       break;
910     case eff_valref:
911       freeValref(proc -> effs[i]);
912       break;
913     case eff_select:
914       freeSelect(proc -> effs[i]);
915       break;
916     case eff_load:
917       freeLoad(proc -> effs[i]);
918       break;
919     case eff_store:
920       freeStore(proc -> effs[i]);
921       break;
922     case eff_alloc:
923       freeAlloc(proc -> effs[i]);
924       break;
925     case eff_call:
926       freeCall(proc -> effs[i]);
927       break;
928     case eff_unknown:
929       freeUnknown(proc -> effs[i]);
930       break;
931     case eff_join:
932       freeJoin(proc -> effs[i]);
933       break;
934     case eff_raise:
935       freeRaise(proc -> effs[i]);
936       break;
937     case eff_ret:
938       freeReturn(proc -> effs[i]);
939       break;
940     default:
941       assert(0 && "try to free an unknown effect");
942       break;
943     }
944   }
945   free(proc -> effs);
946   proc -> effs = NULL;
947 }
948
949 static
950 void freeModuleProcs(module_t *module)
951 {
952   proc_t *next_proc, *proc;
953
954   VERBOSE_PRINT ((stdout, "free procs for module \"%s\"\n",
955           get_id_str(module -> id)));
956
957   proc = module -> procs;
958   while(proc) {
959     next_proc = proc -> next;
960     freeProcEffs(proc);
961     free(proc);
962     proc = next_proc;
963   }
964 }
965
966 static
967 void free_data(void)
968 {
969   module_t *module, *next_module;
970
971   module = modules;
972   while(module) {
973     freeModuleProcs(module);
974     next_module = module -> next;
975     free(module);
976     module = next_module;
977   }
978 }
979
980 /********************************************************************/
981
982 static
983 type_t *find_type_in_module(module_t *module, ident *typeid)
984 {
985   type_t *type;
986
987   for(type = module -> types; type; type = type -> prev) {
988     VERBOSE_PRINT((stdout, "test typeid %s\n", get_id_str(type -> id)));
989     if(type -> id == typeid) {
990       VERBOSE_PRINT((stdout, "found\n"));
991       return(type);
992     }
993   }
994   VERBOSE_PRINT((stdout, "did not find type id %s\n", get_id_str(typeid)));
995   return(NULL);
996 }
997
998 /********************************************************************/
999
1000 static void add_value_to_proc(proc_t *proc, eff_t *eff)
1001 {
1002   eff -> next = proc -> values;
1003   proc -> values = eff;
1004 }
1005
1006
1007 eff_t *find_valueid_in_proc_effects(ident *id, proc_t *proc)
1008 {
1009   eff_t *val;
1010
1011   val = proc -> values;
1012   while(val) {
1013     if(id == val -> id) {
1014       return(val);
1015     }
1016     val = val -> next;
1017   }
1018   return(NULL);
1019 }
1020
1021 static void create_abstract_return(ir_graph *irg, proc_t *proc, eff_t *eff)
1022 {
1023   ir_node *x;
1024   eff_t *eff_res;
1025
1026   VERBOSE_PRINT((stdout, "create effect:return in %s\n",
1027          get_id_str(proc -> proc_ident)));
1028   if(NO_ID == eff -> effect.ret.ret_id) {
1029     /* return void */
1030     x = new_Return (get_store(), 0, NULL);
1031   }
1032   else {
1033     ir_node *in[1];
1034
1035     /* return one value */
1036     eff_res = find_valueid_in_proc_effects(eff -> effect.ret.ret_id, proc);
1037     assert(eff_res -> firmnode && "firm in effect not set");
1038     in[0] = eff_res -> firmnode;
1039     x = new_Return (get_store(), 1, in);
1040   }
1041   eff -> firmnode = x;
1042
1043   /* Now we generated all instructions for this block and all its predecessor
1044    * blocks so we can mature it.  (There are not too much.) */
1045   mature_immBlock (get_irg_current_block(irg));
1046
1047   /* This adds the in edge of the end block which originates at the return statement.
1048    * The return node passes controlflow to the end block.  */
1049   add_immBlock_pred (get_irg_end_block(irg), x);
1050 }
1051
1052
1053 static void create_abstract_arg(ir_graph *irg, proc_t *proc, eff_t *eff)
1054 {
1055   ir_node *arg;
1056   ir_entity *ent;
1057   ir_mode *mode;
1058   ir_type *typ;
1059   int num;
1060
1061   VERBOSE_PRINT((stdout, "create effect:arg %d in %s\n",
1062          eff -> effect.arg.num, get_id_str(proc -> proc_ident)));
1063   ent = get_irg_entity(irg);
1064   typ = get_entity_type(ent);
1065
1066   /* read argument eff -> effect.arg.num and place in values list */
1067   num = get_method_n_params(typ);
1068   assert((num >= eff -> effect.arg.num) && "number too big");
1069   typ = get_method_param_type(typ, eff -> effect.arg.num);
1070   mode = get_type_mode(typ);
1071
1072   arg = new_Proj(get_irg_args(irg), mode, eff -> effect.arg.num);
1073   eff -> firmnode = arg;
1074
1075   add_value_to_proc(proc, eff);
1076 }
1077
1078
1079 static void create_abstract_load(ir_graph *irg, proc_t *proc, eff_t *eff)
1080 {
1081   ir_node *sel, *load;
1082   ir_entity *ent;
1083   ir_mode *mode;
1084   eff_t *addr;
1085   (void) irg;
1086
1087   VERBOSE_PRINT((stdout, "create load in %s\n",
1088          get_id_str(proc -> proc_ident)));
1089
1090   if(eff -> effect.load.ent) {
1091     ent = eff -> effect.load.ent -> f_ent;
1092     VERBOSE_PRINT((stdout, "load from %s\n", get_entity_name(ent)));
1093   }
1094   else {
1095     VERBOSE_PRINT((stdout, "store to memory\n"));
1096     ent = NULL;
1097   }
1098
1099   addr = find_valueid_in_proc_effects(eff -> effect.load.ptrrefid, proc);
1100   assert(addr && "no address for load");
1101   /* if addr is Unknown, set proper mode */
1102   if(iro_Unknown == get_irn_opcode(addr -> firmnode)) {
1103     set_irn_mode(addr -> firmnode, mode_P);
1104   }
1105
1106   if(ent) {
1107     sel = new_simpleSel(get_store(), addr -> firmnode, ent);
1108     mode = get_type_mode(get_entity_type(ent));
1109   }
1110   else {
1111     sel = addr -> firmnode;
1112     mode = mode_ANY;
1113   }
1114   load = new_Load(get_store(), sel, mode);
1115   set_store(new_Proj(load, mode_M, 0));
1116   eff -> firmnode = new_Proj(load, mode, 2);
1117
1118   add_value_to_proc(proc, eff);
1119 }
1120
1121
1122 static void create_abstract_store(ir_graph *irg, proc_t *proc, eff_t *eff)
1123 {
1124   ir_node *sel, *store;
1125   ir_entity *ent;
1126   eff_t *addr, *val;
1127   (void) irg;
1128
1129   VERBOSE_PRINT((stdout, "create store in %s\n",
1130          get_id_str(proc -> proc_ident)));
1131
1132   if(eff -> effect.store.ent) {
1133     ent = eff -> effect.store.ent -> f_ent;
1134     VERBOSE_PRINT((stdout, "store to ir_entity %s\n", get_entity_name(ent)));
1135   }
1136   else {
1137     VERBOSE_PRINT((stdout, "store to memory\n"));
1138     ent = NULL;
1139   }
1140
1141   addr = find_valueid_in_proc_effects(eff -> effect.store.ptrrefid, proc);
1142   assert(addr && "no address for store");
1143   /* if addr is Unknown, set propper mode */
1144   if(iro_Unknown == get_irn_opcode(addr -> firmnode)) {
1145     set_irn_mode(addr -> firmnode, mode_P);
1146   }
1147
1148   val = find_valueid_in_proc_effects(eff -> effect.store.valrefid, proc);
1149   assert(val && "no address for store");
1150   /* if addr is Unknown, set propper mode */
1151   if(iro_Unknown == get_irn_opcode(val -> firmnode)) {
1152     set_irn_mode(val -> firmnode, get_type_mode(get_entity_type(ent)));
1153   }
1154
1155   if(ent) {
1156     sel = new_simpleSel(get_store(), addr -> firmnode, ent);
1157   }
1158   else {
1159     sel = addr -> firmnode;
1160   }
1161   store = new_Store(get_store(), sel, val -> firmnode);
1162   set_store(new_Proj(store, mode_M, 0));
1163   eff -> firmnode = store;
1164 }
1165
1166
1167 static void create_abstract_alloc(ir_graph *irg, proc_t *proc, eff_t *eff)
1168 {
1169   ir_type *ftype;
1170   ir_node *alloc;
1171   type_t *xtype;
1172   symconst_symbol sym;
1173   (void) irg;
1174
1175   VERBOSE_PRINT((stdout, "create alloc in %s\n",
1176          get_id_str(proc -> proc_ident)));
1177
1178   xtype = find_type_in_module(current_module, eff -> effect.alloc.tp_id);
1179   assert(xtype && "type not found");
1180   ftype = xtype -> f_tp;
1181
1182   sym.type_p = ftype;
1183   alloc = new_Alloc(get_store(), new_SymConst(mode_Is, sym, symconst_type_size), ftype,
1184             heap_alloc);
1185   set_store(new_Proj(alloc, mode_M, 0));
1186   eff -> firmnode = new_Proj(alloc, mode_P, 2);
1187
1188   add_value_to_proc(proc, eff);
1189 }
1190
1191
1192 static void create_abstract_unknown(ir_graph *irg, proc_t *proc, eff_t *eff)
1193 {
1194   ir_node *unknown;
1195   (void) irg;
1196
1197   VERBOSE_PRINT((stdout, "create unknown in %s\n",
1198          get_id_str(proc -> proc_ident)));
1199
1200   unknown = new_Unknown(mode_ANY);
1201   eff -> firmnode = unknown;
1202
1203   add_value_to_proc(proc, eff);
1204 }
1205
1206
1207 static void create_abstract_call(ir_graph *irg, proc_t *proc, eff_t *eff)
1208 {
1209   ir_node *sel, *call;
1210   ir_entity *ent;
1211   eff_t *addr;
1212   ir_node **irns;
1213   int i, num;
1214   ir_type *mtype;
1215   int mik; /* is method somehow known? */
1216   (void) irg;
1217
1218   VERBOSE_PRINT((stdout, "create call in %s\n",
1219          get_id_str(proc -> proc_ident)));
1220
1221   if(eff -> effect.call.ent) {
1222     ent = eff -> effect.call.ent -> f_ent;
1223     VERBOSE_PRINT((stdout, "call %s\n", get_entity_name(ent)));
1224   }
1225   else {
1226     ent = NULL;
1227     VERBOSE_PRINT((stdout, "call something in memory\n"));
1228   }
1229
1230   addr = find_valueid_in_proc_effects(eff -> effect.call.valrefid, proc);
1231   assert(addr && "no address for load");
1232   /* if addr is Unknown, set proper mode */
1233   if(iro_Unknown == get_irn_opcode(addr -> firmnode)) {
1234     set_irn_mode(addr -> firmnode, mode_P);
1235   }
1236
1237   if(ent) {
1238     /* the address */
1239     sel = new_simpleSel(get_store(), addr -> firmnode, ent);
1240     /* method type */
1241     mtype = get_entity_type(ent);
1242     mik = 1;
1243   }
1244   else {
1245     /* the address */
1246     sel = addr -> firmnode;
1247     /* method type */
1248     mtype = get_unknown_type();
1249     mik = 0;
1250   }
1251
1252   /* the args */
1253   num = eff -> effect.call.n_args;
1254   VERBOSE_PRINT((stdout, "number of args given: %d\n", num));
1255   if(mik) {
1256     VERBOSE_PRINT((stdout, "number of args expected: %d\n",
1257            get_method_n_params(mtype)));
1258   }
1259   irns = alloca(num * sizeof(ir_node*));
1260   for(i = 0; i < num; i++) {
1261     irns[i] = find_valueid_in_proc_effects(eff -> effect.call.args[i], proc)
1262       -> firmnode;
1263     if(iro_Unknown == get_irn_opcode(irns[i])) {
1264       if(mik) {
1265     set_irn_mode(irns[i], get_type_mode(get_method_param_type(mtype, i)));
1266       }
1267       else {
1268     set_irn_mode(irns[i], mode_ANY);
1269       }
1270     }
1271   }
1272   call = new_Call(get_store(), sel, num, irns, mtype);
1273   set_store(new_Proj(call, mode_M, 0));
1274   if(mik && (0 != get_method_n_ress(mtype))) {
1275     eff -> firmnode = new_Proj(call,
1276                    get_type_mode(get_method_res_type(mtype, 0)),
1277                    0);
1278     add_value_to_proc(proc, eff); /* result can be accessed */
1279   }
1280   else {
1281     eff -> firmnode = NULL; /* result can not be accessed */
1282   }
1283 }
1284
1285 static void create_abstract_join (ir_graph *irg, proc_t *proc, eff_t *eff)
1286 {
1287   ir_node **ins    = NULL;
1288   ir_node *unknown = NULL;
1289   ir_node *cond    = NULL;
1290   ir_node *block   = NULL;
1291   ir_node *c_block = NULL;
1292   ir_node *phi     = NULL;
1293   ir_mode *join_md = mode_ANY;
1294   int n_ins = -1;
1295   int i;
1296   (void) irg;
1297
1298   VERBOSE_PRINT((stdout, "create join in %s\n",
1299          get_id_str(proc -> proc_ident)));
1300
1301   assert (eff_join == eff->kind);
1302
1303   n_ins = eff->effect.join.n_ins;
1304
1305   /* seems like current_block is not always mature at this point */
1306   mature_immBlock (get_cur_block ());
1307
1308   block = get_cur_block ();     /* remember this so we can put the ProjXs into it */
1309
1310   /* jump based on an unknown condition so all values are possible */
1311   unknown = new_Unknown (mode_Iu);
1312   cond    = new_Cond (unknown);
1313
1314   c_block   = new_immBlock ();  /* for the Phi after the branch(es) */
1315
1316   ins = (ir_node**) xmalloc (n_ins * sizeof (ir_node*));
1317   for (i = 0; i < n_ins; i ++) {
1318     ir_node *projX   = NULL;
1319     ir_node *s_block = NULL;
1320     ir_node *jmp     = NULL;
1321     eff_t *in_eff;
1322
1323     /* make sure the projX is in the 'switch' block */
1324     set_cur_block (block);
1325     projX   = new_Proj (cond, mode_X, (long) i);
1326
1327     /* this also sets current_block, so the rest of the code ends up there: */
1328     s_block = new_immBlock ();
1329
1330     add_immBlock_pred (s_block, projX);
1331     mature_immBlock (s_block);
1332
1333     in_eff = find_valueid_in_proc_effects (eff->effect.join.ins [i], proc);
1334
1335     ins [i] = in_eff->firmnode;
1336
1337     /* need to find a suitable mode for the Phi node */
1338     if (mode_ANY != get_irn_mode (ins [i])) {
1339       join_md = get_irn_mode (ins [i]);
1340     }
1341
1342     jmp = new_Jmp ();
1343     add_immBlock_pred (c_block, jmp);
1344   }
1345
1346   set_cur_block (c_block);
1347
1348   phi = new_Phi (n_ins, ins, join_md);
1349
1350   mature_immBlock (c_block);
1351   memset (ins, 0x00, n_ins * sizeof (ir_node*));
1352   free (ins);
1353
1354   eff->firmnode = phi;
1355
1356   add_value_to_proc (proc, eff);
1357 }
1358
1359 static void create_abstract_raise (ir_graph *irg, proc_t *proc, eff_t *eff)
1360 {
1361   ir_node *block   = NULL;
1362   ir_node *unknown = NULL;
1363   ir_node *cond    = NULL;
1364
1365   /* seems like current_block is not always mature at this point */
1366   mature_immBlock (get_cur_block ());
1367   block = get_cur_block ();     /* remember this so we can put the ProjXs into it */
1368
1369   /* jump based on an unknown condition so both values are possible */
1370   unknown = new_Unknown (mode_Iu);
1371   cond    = new_Cond (unknown);
1372
1373   /* one branch for 'throw-exception' case */
1374   {
1375     ir_node *projX = new_Proj (cond, mode_X, 1L);
1376     ir_node *b_exc = new_immBlock ();
1377     ir_node *obj   = NULL;
1378     ir_node *thrw  = NULL;
1379     eff_t *thrw_eff = NULL;
1380
1381     add_immBlock_pred (b_exc, projX);
1382
1383     thrw_eff = find_valueid_in_proc_effects (eff->effect.raise.valref, proc);
1384     obj = thrw_eff->firmnode;
1385
1386     thrw = new_Raise (get_store (), obj);
1387     /* exc-jump to end block */
1388     thrw = new_Proj (thrw, mode_X, 0L);
1389
1390     add_immBlock_pred (get_irg_end_block (irg), thrw);
1391     mature_immBlock (get_cur_block ());
1392   }
1393
1394   set_cur_block (block);     /* back to the first block */
1395
1396   /* one branch for 'non-exception' case */
1397   {
1398     ir_node *projX = new_Proj (cond, mode_X, 0);
1399     new_immBlock ();            /* also sets current_block */
1400     add_immBlock_pred (get_cur_block (), projX);
1401     mature_immBlock (get_cur_block ());
1402     /* continue building in current_block */
1403   }
1404
1405 }
1406
1407 static void create_abstract_firm(module_t *module, proc_t *proc, ir_entity *fent)
1408 {
1409   eff_t *eff;
1410   ir_graph *irg;
1411   int i, num;
1412   (void) module;
1413
1414   /* test ir_entity */
1415   assert(visibility_external_allocated == get_entity_visibility(fent)
1416      && peculiarity_existent == get_entity_peculiarity(fent)
1417      && "not an abstract ir_entity");
1418   /* create irg in ir_entity */
1419   irg = new_pseudo_ir_graph(fent, 0);
1420   set_irg_inline_property(irg, irg_inline_forbidden);
1421
1422   /* @@@ If the spec says so: */
1423   set_entity_visibility(fent, visibility_local);
1424
1425   VERBOSE_PRINT((stdout, "create effects for %s\n",
1426          get_id_str(proc -> proc_ident)));
1427
1428   /* create effects in irg */
1429   num = proc -> n_effs;
1430   for(i = 0; i < num; i++) {
1431     eff = proc -> effs[i];
1432     VERBOSE_PRINT((stdout,
1433            "create effect \"%s\"\n", effect_string[(int)eff -> kind]));
1434     switch(eff -> kind) {
1435     case eff_ret:
1436       create_abstract_return(irg, proc, eff);
1437       break;
1438     case eff_arg:
1439       create_abstract_arg(irg, proc, eff);
1440       break;
1441     case eff_load:
1442       create_abstract_load(irg, proc, eff);
1443       break;
1444     case eff_store:
1445       create_abstract_store(irg, proc, eff);
1446       break;
1447     case eff_unknown:
1448       create_abstract_unknown(irg, proc, eff);
1449       break;
1450     case eff_alloc:
1451       create_abstract_alloc(irg, proc, eff);
1452       break;
1453     case eff_call:
1454       create_abstract_call(irg, proc, eff);
1455       break;
1456     case eff_join:
1457       create_abstract_join(irg, proc, eff);
1458       break;
1459     case eff_raise:
1460       create_abstract_raise(irg, proc, eff);
1461       break;
1462     default:
1463       assert(0 && "effect not implemented");
1464       break;
1465     }
1466   }
1467
1468   /* close irg in ir_entity */
1469   /* Now we can mature the end block as all it's predecessors are known. */
1470   mature_immBlock (get_irg_end_block(irg));
1471
1472   /* Verify the graph.  Finds some very bad errors in the graph. */
1473   VERBOSE_PRINT((stdout, "verify graph\n"));
1474   irg_vrfy(irg);
1475   VERBOSE_PRINT((stdout, "finalize construction\n"));
1476   irg_finalize_cons (irg);
1477 }
1478
1479 /********************************************************************/
1480
1481 static void assign_firm_entity(module_t *module, entity_t *xmlent)
1482 {
1483   int i, num;
1484   type_t *typ;
1485   ir_type *type;
1486   ir_entity *ent;
1487
1488   VERBOSE_PRINT((stdout, "assign ir_entity %s to typeid %s\n",
1489          get_id_str(xmlent -> ent_ident),
1490          get_id_str(xmlent -> owner)));
1491
1492   typ = find_type_in_module(module, xmlent -> owner);
1493   assert(typ && "class not found in module");
1494   type = typ -> f_tp;
1495   assert(is_Class_type(type));
1496
1497   num = get_class_n_members(type);
1498   ent = NULL;
1499   for(i = 0; i < num; i++) {
1500     ent = get_class_member(type, i);
1501     VERBOSE_PRINT((stdout, "compare ir_entity %s and %s\n",
1502            get_id_str(xmlent -> ent_ident), get_entity_name(ent)));
1503
1504     if(get_entity_ident(ent) == xmlent -> ent_ident) {
1505       break;
1506     }
1507     ent = NULL;
1508   }
1509   assert(ent && "did not find a ir_entity");
1510
1511   xmlent -> f_ent = ent;
1512 }
1513
1514 /********************************************************************/
1515 /* must be primitive type or class type */
1516 static void assign_firm_type(type_t *xmltype)
1517 {
1518   int i;
1519   ir_type *typ = NULL;
1520   int num;
1521
1522   VERBOSE_PRINT((stdout, "assign firm type to type %s\n",
1523                  get_id_str(xmltype -> type_ident)));
1524
1525   /* is it global type? */
1526   typ = get_glob_type();
1527   if(xmltype -> type_ident == get_type_ident(typ)) {
1528     /* yes */
1529     xmltype -> f_tp = typ;
1530     VERBOSE_PRINT((stdout, "is global type %s\n", get_type_name(typ)));
1531   } else {
1532     num = get_irp_n_types();
1533     for(i = 0; i < num; i++) {
1534       typ = get_irp_type(i);
1535       VERBOSE_PRINT((stdout, "test type %s\n", get_type_name(typ)));
1536       if(xmltype -> type_ident == get_type_ident(typ)) {
1537         VERBOSE_PRINT((stdout, "found type %s\n", get_type_name(typ)));
1538         xmltype -> f_tp = typ;
1539         break;
1540       }
1541       typ = NULL;
1542     }
1543   }
1544   assert(typ && "did not find a type");
1545 }
1546
1547 /********************************************************************/
1548 static
1549 void create_abstract_proc_effect(module_t *module, proc_t *proc)
1550 {
1551   int i, num;
1552   ir_type *class_typ = NULL;
1553   type_t *type;
1554   ir_entity *fent;
1555
1556   /* find the class of a procedure */
1557   VERBOSE_PRINT((stdout, "do find owner id %s\n", get_id_str(proc -> ownerid)));
1558   type = find_type_in_module(module, proc -> ownerid);
1559   assert(type && "class not found in module");
1560
1561   class_typ = get_glob_type();
1562   VERBOSE_PRINT((stdout, "test type %s\n", get_type_name(class_typ)));
1563   if(type -> type_ident != get_type_ident(class_typ)) {
1564     /* find module as class */
1565     num = get_irp_n_types();
1566     for(i = 0; i < num; i++) {
1567       class_typ = get_irp_type(i);
1568       VERBOSE_PRINT((stdout, "test type %s\n", get_type_name(class_typ)));
1569       if (is_Class_type(class_typ)
1570          && (type -> type_ident == get_type_ident(class_typ))) {
1571         /* found class type */
1572         VERBOSE_PRINT((stdout, "found type %s\n", get_type_name(class_typ)));
1573         break;
1574       }
1575       class_typ = NULL;
1576     }
1577   }
1578   else {
1579     VERBOSE_PRINT((stdout, "found global type %s\n", get_type_name(class_typ)));
1580   }
1581   assert(class_typ && "type not found");
1582   assert(is_Class_type(class_typ) && "is not a class type");
1583   type -> f_tp = class_typ;
1584
1585   /* find ir_entity for procedure in class */
1586   VERBOSE_PRINT((stdout, "find method %s\n",
1587          get_id_str(proc -> proc_ident)));
1588
1589   num = get_class_n_members(class_typ);
1590   fent = NULL;
1591   for(i = 0; i < num; i++) {
1592     fent = get_class_member(class_typ, i);
1593     VERBOSE_PRINT((stdout, "test proc %s\n", get_entity_name(fent)));
1594     if(proc -> proc_ident == get_entity_ident(fent)) {
1595       VERBOSE_PRINT((stdout, "found proc %s\n",
1596              get_id_str(proc -> proc_ident)));
1597       /* @@@ TODO check args types - not in xml yet */
1598       /* create Firm stuff */
1599       create_abstract_firm(module, proc, fent);
1600       return;
1601     }
1602     else {
1603       fent = NULL;
1604     }
1605   }
1606
1607   /* fail */
1608   fprintf(stderr,
1609       "method %s not found\nNo effects generated\nCandidates are:\n",
1610       get_id_str(proc -> proc_ident));
1611   for(i = 0; i < num; i++) {
1612     fent = get_class_member(class_typ, i);
1613     fprintf(stderr, "%s\n", get_entity_name(fent));
1614   }
1615   //assert(fent && "procedure not found in class");
1616 }
1617
1618 static
1619 void create_abstract_module(module_t *module)
1620 {
1621   proc_t *proc;
1622   type_t *type;
1623   entity_t *ent;
1624
1625   VERBOSE_PRINT((stdout, "create an abstraction for module %s\n",
1626          get_id_str(module -> id)));
1627
1628   VERBOSE_PRINT((stdout, "--handle types for module\n"));
1629   for(type = module -> types; type; type = type -> prev) {
1630     assign_firm_type(type);
1631   }
1632
1633   VERBOSE_PRINT((stdout, "--handle entities for module\n"));
1634   /* @@@ TODO */
1635   for(ent = module -> entities; ent; ent = ent -> prev) {
1636     assign_firm_entity(module, ent);
1637   }
1638
1639   VERBOSE_PRINT((stdout, "--handle procs for module\n"));
1640   for(proc = module -> procs; proc; proc = proc -> next) {
1641     create_abstract_proc_effect(module, proc);
1642   }
1643 }
1644
1645
1646 int create_abstraction(const char *filename)
1647 {
1648   module_t *module;
1649
1650   /* read and parse XML file */
1651   if (! read_extern(filename))
1652     return 0;
1653
1654   /* finished reading and parsing here */
1655   /* build FIRM graphs */
1656   module = modules;
1657   while(module) {
1658     current_module = module;
1659     create_abstract_module(module);
1660     module = module -> next;
1661   }
1662   current_module = NULL;
1663
1664   /* free data structures */
1665   free_data();
1666
1667   types = NULL;
1668   entities = NULL;
1669   procs = NULL;
1670   modules = NULL;
1671
1672   return 1;
1673 }
1674
1675
1676 void free_abstraction(void) {
1677   int i, n_pseudo_irgs = get_irp_n_pseudo_irgs();
1678   for (i = 0; i < n_pseudo_irgs; ++i) {
1679     ir_graph *p_irg = get_irp_pseudo_irg(i);
1680     set_entity_visibility(get_irg_entity(p_irg), visibility_external_allocated);
1681     // @@@ free_pseudo_ir_graph(p_irg);
1682   }
1683 }
1684
1685
1686 /********************************************************************/
1687
1688 \f
1689 /*
1690  * $Log$
1691  * Revision 1.27  2007/02/02 12:38:35  matze
1692  * entity is ir_entity now
1693  *
1694  * Revision 1.26  2006/12/15 12:37:40  matze
1695  * fix warnings
1696  *
1697  * Revision 1.25  2006/06/09 11:26:35  firm
1698  * renamed type to ir_type
1699  *
1700  * Revision 1.24  2006/05/29 13:34:49  beck
1701  * renamed symconst_size to symconst_type_size
1702  *
1703  * Revision 1.22  2005/08/16 10:18:35  beck
1704  * create_abstraction() now returns an error code if the file could not
1705  * be opened.
1706  *
1707  * Revision 1.21  2005/03/10 10:05:38  goetz
1708  * chanmged method name
1709  *
1710  * Revision 1.20  2005/01/05 14:28:35  beck
1711  * renames all is_x*_type() functions to is_X*_type() to prevent name clash with EDG frontend
1712  *
1713  * Revision 1.19  2004/12/10 15:14:34  beck
1714  * used xmalloc instead of malloc
1715  *
1716  * Revision 1.18  2004/12/02 16:21:42  beck
1717  * fixed config.h include
1718  *
1719  * Revision 1.17  2004/11/23 14:17:31  liekweg
1720  * fenced out currently unneeded static functions
1721  *
1722  * Revision 1.16  2004/11/11 12:24:52  goetz
1723  * fixes
1724  *
1725  * Revision 1.15  2004/11/11 09:28:32  goetz
1726  * treat pseudo irgs special
1727  * parse 'local' from xml files
1728  *
1729  * Revision 1.14  2004/11/10 14:42:00  boesler
1730  * be more helpful if a method does not exist
1731  *
1732  * Revision 1.13  2004/11/05 14:00:53  liekweg
1733  * added raise
1734  *
1735  * Revision 1.12  2004/11/02 14:30:31  liekweg
1736  * fixed multi-input join (thx, Boris) --flo
1737  *
1738  * Revision 1.11  2004/10/29 18:51:53  liekweg
1739  * Added Join
1740  *
1741  * Revision 1.10  2004/10/25 13:52:24  boesler
1742  * seperated read.h (public interface) and read_t.h (types)
1743  *
1744  * Revision 1.9  2004/10/22 13:51:35  boesler
1745  * prohibit inlining of pseudo ir_graphs
1746  *
1747  * Revision 1.8  2004/10/22 13:13:27  boesler
1748  * replaced char* by idents, minor fix in Firm codegen for call
1749  *
1750  * Revision 1.7  2004/10/21 15:31:55  boesler
1751  * added lots of stuff:
1752  * - build abstract syntax trees
1753  * - build Firm graphs for many effects, still todos
1754  *
1755  * Revision 1.5  2004/10/18 12:48:20  liekweg
1756  * avoid warning
1757  *
1758  * Revision 1.4  2004/10/14 11:31:53  liekweg
1759  * ...
1760  *
1761  * Revision 1.3  2004/10/13 13:36:28  rubino
1762  * fix for strdup
1763  *
1764  * Revision 1.2  2004/10/11 15:56:09  liekweg
1765  * Cleanup, comments ...
1766  * Added init func --flo
1767  *
1768  * Revision 1.1  2004/10/11 09:31:06  liekweg
1769  * First Import of XML reading procs --flo
1770  *
1771  */