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