read.c 40.5 KB
Newer Older
1
2
3
/* -*- c -*- */

/*
Florian Liekweg's avatar
Florian Liekweg committed
4
5
6
7
 * Project:     libFIRM
 * File name:   ir/external/read.c
 * Purpose:     Read descriptions of external effects
 * Author:      Florian
Boris Boesler's avatar
Boris Boesler committed
8
 * Modified by: Boris Boesler
Florian Liekweg's avatar
Florian Liekweg committed
9
 * Created:     11.10.2004
Boris Boesler's avatar
Boris Boesler committed
10
 * CVS-ID:      $Id$
Florian Liekweg's avatar
Florian Liekweg committed
11
12
13
 * Copyright:   (c) 1999-2004 Universitt Karlsruhe
 * Licence:     This file is protected by GPL -  GNU GENERAL PUBLIC LICENSE.
 */
14

15
16
17
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
Boris Boesler's avatar
Boris Boesler committed
18

19
20
21
22
23
24
25
/* get prototype for alloca somehow */
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
Michael Beck's avatar
Michael Beck committed
26
#ifdef HAVE_STRING_H
Florian Liekweg's avatar
Florian Liekweg committed
27
# include <string.h>
Michael Beck's avatar
Michael Beck committed
28
#endif
Florian Liekweg's avatar
Florian Liekweg committed
29

30
31
#include "read_t.h"
#include "read.h"
Boris Boesler's avatar
Boris Boesler committed
32
33
#include "irprog.h"
#include "irgraph.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
34
#include "pseudo_irg.h"
Boris Boesler's avatar
Boris Boesler committed
35
36
37
38
39
40
41
#include "ircons.h"
#include "irmode.h"
#include "irdump.h"
#include "irvrfy.h"
#include "type.h"
#include "tv.h"

42
#define VERBOSE_PRINTING 0
43
44

#if VERBOSE_PRINTING
Boris Boesler's avatar
Boris Boesler committed
45
46
47
48
49
50
# define VERBOSE_PRINT(s) fprintf s
#else
# define VERBOSE_PRINT(s)
#endif

#define NO_ID NULL
51
52
53

static type_t *types = NULL;
static entity_t *entities = NULL;
Boris Boesler's avatar
Boris Boesler committed
54
55
56
57
58
59
static proc_t *procs = NULL;
static module_t *modules = NULL;

/* @@@ HACK */
static module_t *current_module = NULL;

Florian Liekweg's avatar
Florian Liekweg committed
60
61
#if VERBOSE_PRINTING
/* this is only used inside a VERBOSE_PRINT() call */
Boris Boesler's avatar
Boris Boesler committed
62
63
64
65
66
67
68
69
70
71
72
73
74
static char *effect_string[] = {
  "arg",
  "valref",
  "select",
  "load",
  "store",
  "alloc",
  "call",
  "unknown",
  "join",
  "raise",
  "ret"
};
Florian Liekweg's avatar
Florian Liekweg committed
75
#endif /* defined VERBOSE_PRINTING */
76

77
78
static const ident*
getNodeModuleIdent (xmlNodePtr node)
79
{
Rubino Geiß's avatar
Rubino Geiß committed
80
  const char *mod_str = (const char*) xmlGetProp (node, BAD_CAST "module");
81
82
83
84

  if (NULL == mod_str) {
    return (NULL);
  } else {
85
    const ident *res = new_id_from_str (mod_str);
86
87
88
89
    return (res);
  }
}

Boris Boesler's avatar
Boris Boesler committed
90
static const char*
91
92
getNodeProcName (xmlNodePtr node)
{
Boris Boesler's avatar
Boris Boesler committed
93
  const char *proc_str = (const char*) xmlGetProp (node, BAD_CAST "procname");
94
  assert (proc_str);
95
  return (proc_str);
Boris Boesler's avatar
Boris Boesler committed
96
}
97

98
# ifdef NEEDED
Boris Boesler's avatar
Boris Boesler committed
99
100
101
102
103
static char*
getNodeClassName (xmlNodePtr node)
{
  char *proc_str = (char*) xmlGetProp (node, BAD_CAST "class");
  assert (proc_str);
104
  return ( (proc_str));
105
}
106
# endif /* defined NEEDED */
107

Boris Boesler's avatar
Boris Boesler committed
108
static const char*
109
110
getNodeId (xmlNodePtr node)
{
Boris Boesler's avatar
Boris Boesler committed
111
  const char *id_str = (const char*) xmlGetProp (node, BAD_CAST "id");
112
  assert (id_str);
113
  return (id_str);
114
115
}

116
static const char *
117
118
getNodeRefId (xmlNodePtr node)
{
119
  const char *refid_str = (char*) xmlGetProp (node, BAD_CAST "refid");
120
  assert (refid_str);
121
  return ((refid_str));
122
123
}

124
static const char*
125
126
getNodeTypeId (xmlNodePtr node)
{
127
  const char *type_str = (char*) xmlGetProp (node, BAD_CAST "type");
128
  assert (type_str);
129
  return ((type_str));
130
131
132
133
134
135
136
137
138
139
}

static const char
*getNodeTypeStr (xmlNodePtr node)
{
  const char *type_str = (char*) xmlGetProp (node, BAD_CAST "type");
  assert (type_str);
  return (type_str);
}

Boris Boesler's avatar
Boris Boesler committed
140
141
142
143
144
145
146
147
static const char*
getNodeOwnerStr (xmlNodePtr node)
{
  const char *owner_str = (char*) xmlGetProp (node, BAD_CAST "owner");
  assert (owner_str);
  return (owner_str);
}

148
149
150
151
152
153
154
155
156
static const char
*getNodeEntityStr (xmlNodePtr node)
{
  const char *ent_str = (char*) xmlGetProp (node, BAD_CAST "entity");
  assert (ent_str);

  return (ent_str);
}

Boris Boesler's avatar
Boris Boesler committed
157
158
159
160

/*
  was Public Interface
*/
161
# ifdef NEEDED
Boris Boesler's avatar
Boris Boesler committed
162
static
163
type_t *getTypeByIdent (const ident *id)
Boris Boesler's avatar
Boris Boesler committed
164
{
165
  type_t *curr = types; // @@@ TODO module -> types
Boris Boesler's avatar
Boris Boesler committed
166
167

  while (NULL != curr) {
168
    if (id == curr -> type_ident) {
Boris Boesler's avatar
Boris Boesler committed
169
170
171
172
173
174
175
      return (curr);
    }
    curr = curr->prev;
  }

  return (NULL);
}
176
# endif /* defined NEEDED */
Boris Boesler's avatar
Boris Boesler committed
177

178
# ifdef NEEDED
Boris Boesler's avatar
Boris Boesler committed
179
static
180
type_t *getTypeById (const ident *id)
Boris Boesler's avatar
Boris Boesler committed
181
{
182
  type_t *curr = types; // which ones?
Boris Boesler's avatar
Boris Boesler committed
183
184

  while (NULL != curr) {
185
    if (id == curr -> id) {
Boris Boesler's avatar
Boris Boesler committed
186
187
188
189
190
191
192
      return (curr);
    }
    curr = curr->prev;
  }

  return (NULL);
}
193
# endif /* defined NEEDED */
Boris Boesler's avatar
Boris Boesler committed
194

195
# ifdef NEEDED
Boris Boesler's avatar
Boris Boesler committed
196
static
197
entity_t *getEntityByIdents (const ident *name, const ident *tp_ident)
Boris Boesler's avatar
Boris Boesler committed
198
{
199
  entity_t *curr = entities; // TODO module -> entities
Boris Boesler's avatar
Boris Boesler committed
200
201

  while (NULL != curr) {
202
    if ((name == curr -> ent_ident)
Florian Liekweg's avatar
Florian Liekweg committed
203
    && (tp_ident == curr -> tp_ident)) {
Boris Boesler's avatar
Boris Boesler committed
204
205
206
207
208
209
210
      return (curr);
    }
    curr = curr->prev;
  }

  return (NULL);
}
211
# endif /* defined NEEDED */
Boris Boesler's avatar
Boris Boesler committed
212
213

static
214
entity_t *getEntityById (const ident *id)
Boris Boesler's avatar
Boris Boesler committed
215
216
217
218
{
  entity_t *curr = entities;

  while (NULL != curr) {
219
    if (id == curr -> id) {
Boris Boesler's avatar
Boris Boesler committed
220
221
222
223
224
225
226
227
      return (curr);
    }
    curr = curr->prev;
  }

  return (NULL);
}

228
# ifdef NEEDED
Boris Boesler's avatar
Boris Boesler committed
229
static
230
proc_t *getEffectByName (const ident *proc_ident)
Boris Boesler's avatar
Boris Boesler committed
231
232
233
234
{
  proc_t *curr_effs = procs;

  while (NULL != curr_effs) {
235
    if (proc_ident == curr_effs -> proc_ident) {
Boris Boesler's avatar
Boris Boesler committed
236
237
238
239
240
241
242
      return (curr_effs);
    }
    curr_effs = curr_effs->next;
  }

  return (NULL);
}
243
# endif /* defined NEEDED */
Boris Boesler's avatar
Boris Boesler committed
244

245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
static
xmlNodePtr get_any_valid_child(xmlNodePtr elem)
{
  xmlNodePtr child;

  assert(elem && "no element");
  child = elem -> xmlChildrenNode;
  while(child && (NODE_NAME (child, comment))) {
    child = child -> next;
  }
  return(child);
}

static
xmlNodePtr get_valid_child(xmlNodePtr elem)
{
  xmlNodePtr child;

  child = get_any_valid_child(elem);
  assert(child && "lost child in deep black forest");
  return(child);
}
Boris Boesler's avatar
Boris Boesler committed
267
268
269
270
271

/*
 * parse XML structure and construct an additional structure
 */
static eff_t *
272
273
parseArg (xmlDocPtr doc, xmlNodePtr argelm)
{
Boris Boesler's avatar
Boris Boesler committed
274
275
  const char *id;
  const char *typeid;
276
277
  int num;
  char *num_str;
Boris Boesler's avatar
Boris Boesler committed
278
  eff_t *arg;
279
280

  CHECK_NAME (argelm, arg);
Boris Boesler's avatar
Boris Boesler committed
281
  VERBOSE_PRINT ((stdout, "arg node \t0x%08x\n", (int) argelm));
282
283

  id = getNodeId (argelm);
Boris Boesler's avatar
Boris Boesler committed
284
  VERBOSE_PRINT ((stdout, "arg->id = \"%s\"\n", id));
285
286
  num_str = (char*) xmlGetProp (argelm, BAD_CAST "number");
  num = atoi (num_str);
Boris Boesler's avatar
Boris Boesler committed
287
  VERBOSE_PRINT ((stdout, "arg->no = \"%d\"\n", num));
288

Boris Boesler's avatar
Boris Boesler committed
289
290
291
292
  typeid = getNodeTypeStr (argelm);

  arg = NEW (eff_t);
  arg -> kind = eff_arg;
293
  arg -> id = new_id_from_str(id);
Boris Boesler's avatar
Boris Boesler committed
294
  arg -> effect.arg.num = num;
295
  arg -> effect.arg.type_ident = new_id_from_str(typeid);
296
297
298
299

  return (arg);
}

Florian Liekweg's avatar
Florian Liekweg committed
300
301
static eff_t*
parseValref (xmlDocPtr doc, xmlNodePtr valelm)
302
{
303
  const char *ref_id;
Boris Boesler's avatar
Boris Boesler committed
304
305
  eff_t *valref;

306
  CHECK_NAME (valelm, valref);
Boris Boesler's avatar
Boris Boesler committed
307
  VERBOSE_PRINT ((stdout, "valref node \t0x%08x\n", (int) valelm));
308
309

  ref_id = getNodeRefId (valelm);
Boris Boesler's avatar
Boris Boesler committed
310
  VERBOSE_PRINT ((stdout, "val->refid = \"%s\"\n", ref_id));
311

Boris Boesler's avatar
Boris Boesler committed
312
  valref = NEW (eff_t);
313
  valref->kind = eff_valref;
314
  valref-> id = new_id_from_str(ref_id);
315
316
317
318

  return (valref);
}

Florian Liekweg's avatar
Florian Liekweg committed
319
320
static eff_t*
parseSelect (xmlDocPtr doc, xmlNodePtr selelm)
321
{
322
  const ident *entity_id = new_id_from_str(getNodeEntityStr (selelm));
323
324
  entity_t *ent;
  xmlNodePtr child;
Boris Boesler's avatar
Boris Boesler committed
325
326
  eff_t *valref = NULL;
  eff_t *sel = NEW (eff_t);
327
328
329
  sel->kind = eff_select;

  CHECK_NAME (selelm, select);
Boris Boesler's avatar
Boris Boesler committed
330
  VERBOSE_PRINT ((stdout, "select node \t0x%08x\n", (int) selelm));
331
332

  ent = getEntityById (entity_id);
Boris Boesler's avatar
Boris Boesler committed
333
  assert(ent && "entity not found");
334
  VERBOSE_PRINT ((stdout, "select entity %s\n", get_id_str(ent -> ent_ident)));
335
336
337
338
339
340
341

  child = selelm->xmlChildrenNode;

  if (child) {
    valref = parseValref (doc, child);
  }

Boris Boesler's avatar
Boris Boesler committed
342
343
  sel-> id = valref ? valref-> id : NO_ID;
  sel-> effect.select.ent = ent;
344
345
346
347
348
349
350
351

  if (valref) {
    free (valref);
  }

  return (sel);
}

Florian Liekweg's avatar
Florian Liekweg committed
352
353
static eff_t*
parseLoad (xmlDocPtr doc, xmlNodePtr loadelm)
354
{
355
  const ident *id;
356
  xmlNodePtr child;
Boris Boesler's avatar
Boris Boesler committed
357
358
  eff_t *sel;
  eff_t *load = NEW (eff_t);
359
360
361
  load->kind = eff_load;

  CHECK_NAME (loadelm, load);
Boris Boesler's avatar
Boris Boesler committed
362
  VERBOSE_PRINT ((stdout, "load node \t0x%08x\n", (int) loadelm));
363
  id = new_id_from_str(getNodeId (loadelm));
364

365
366
367
368
369
  child = get_valid_child(loadelm);
  if(NODE_NAME (child, select)) {
    sel = parseSelect (doc, child);
    load-> effect.load.ent = sel-> effect.select.ent;
    VERBOSE_PRINT ((stdout, "load entity \t%s\n",
Florian Liekweg's avatar
Florian Liekweg committed
370
            get_id_str(load -> effect.load.ent -> ent_ident)));
371
372
373
374
375
  }
  else {
    sel = parseValref (doc, child);
    load-> effect.load.ent = NULL;
  }
376

Boris Boesler's avatar
Boris Boesler committed
377
378
  load-> id = id;
  load-> effect.load.ptrrefid = sel-> id;
379
380
381
382
383
384

  free (sel);

  return (load);
}

Florian Liekweg's avatar
Florian Liekweg committed
385
386
static eff_t*
parseStore (xmlDocPtr doc, xmlNodePtr storeelm)
387
388
{
  xmlNodePtr child;
Boris Boesler's avatar
Boris Boesler committed
389
390
391
  eff_t *sel;
  eff_t *valref;
  eff_t *store = NEW (eff_t);
392
393
394
  store->kind = eff_store;

  CHECK_NAME (storeelm, store);
Boris Boesler's avatar
Boris Boesler committed
395
  VERBOSE_PRINT ((stdout, "store node \t0x%08x\n", (int) storeelm));
396

397
398
399
400
401
402
403
404
405
406
  child = get_valid_child(storeelm);
  if(NODE_NAME (child, select)) {
    sel = parseSelect (doc, child);
    store-> effect.store.ent = sel-> effect.select.ent;
  }
  else {
    sel = parseValref (doc, child);
    store-> effect.store.ent = NULL;
  }

407
408
409
  child = child->next;
  valref = parseValref (doc, child);

Boris Boesler's avatar
Boris Boesler committed
410
411
  store-> effect.store.ptrrefid = sel-> id;
  store-> effect.store.valrefid = valref-> id;
412
413
414
415
416
417
418

  free (sel);
  free (valref);

  return (store);
}

Florian Liekweg's avatar
Florian Liekweg committed
419
420
static eff_t*
parseAlloc (xmlDocPtr doc, xmlNodePtr allocelm)
421
{
422
423
  const ident *id;
  const ident *type_id;
Boris Boesler's avatar
Boris Boesler committed
424
  eff_t *alloc = NEW (eff_t); /* ...! */
425
426
427
  alloc->kind = eff_alloc;

  CHECK_NAME (allocelm, alloc);
Boris Boesler's avatar
Boris Boesler committed
428
  VERBOSE_PRINT ((stdout, "alloc node \t0x%08x\n", (int) allocelm));
429
430
431
432
  id = new_id_from_str(getNodeId (allocelm));
  VERBOSE_PRINT ((stdout, "alloc->id = \"%s\"\n", get_id_str(id)));
  type_id = new_id_from_str(getNodeTypeId (allocelm));
  VERBOSE_PRINT ((stdout, "alloc->type_id = \"%s\"\n", get_id_str(type_id)));
433

Boris Boesler's avatar
Boris Boesler committed
434
435
  alloc-> id = id;
  alloc-> effect.alloc.tp_id = type_id;
436
437
438
439

  return (alloc);
}

Florian Liekweg's avatar
Florian Liekweg committed
440
441
static eff_t*
parseCall (xmlDocPtr doc, xmlNodePtr callelm)
442
{
443
  const ident *id;
444
  xmlNodePtr child;
Boris Boesler's avatar
Boris Boesler committed
445
  eff_t *sel;
446
447
  xmlNodePtr arg;
  int n_args;
Boris Boesler's avatar
Boris Boesler committed
448
  eff_t *call = NEW (eff_t);
449
450
451
  call->kind = eff_call;

  CHECK_NAME (callelm, call);
Boris Boesler's avatar
Boris Boesler committed
452
  VERBOSE_PRINT ((stdout, "call node \t0x%08x\n", (int) callelm));
453
454
  id = new_id_from_str(getNodeId (callelm));
  VERBOSE_PRINT ((stdout, "call->id = \"%s\"\n", get_id_str(id)));
455

456
457
458
459
460
461
462
463
464
465
  child = get_valid_child(callelm);
  if(NODE_NAME (child, select)) {
    sel = parseSelect (doc, child);
    call-> effect.call.ent = sel-> effect.select.ent;
  }
  else {
    sel = parseValref (doc, child);
    call-> effect.call.ent = NULL;
  }

466
467
468
469
470
471
472
473
  arg = child = child->next;
  n_args = 0;

  while (NULL != child) {
    n_args ++;
    child = child->next;
  }

Boris Boesler's avatar
Boris Boesler committed
474
475
476
477
  call-> id = id;
  call-> effect.call.valrefid = sel-> id;
  call-> effect.call.n_args = n_args;
  call-> effect.call.args = NULL;
478
479
480
481

  free (sel);

  if (0 != n_args) {
482
    const ident **args = (const ident**) malloc(n_args * sizeof(const ident*));
483
484
485
    int i = 0;

    while (NULL != arg) {
Boris Boesler's avatar
Boris Boesler committed
486
487
      eff_t *valref = parseValref (doc, arg);
      args [i ++] = valref-> id;
488
489
490
491
      free (valref);
      arg = arg->next;
    }

Boris Boesler's avatar
Boris Boesler committed
492
    call-> effect.call.args = args;
493
494
495
496
497
  }

  return (call);
}

Florian Liekweg's avatar
Florian Liekweg committed
498
499
static eff_t*
parseJoin (xmlDocPtr doc, xmlNodePtr joinelm)
500
{
501
  const ident *id;
502
  int n_ins;
503
  const ident **ins;
504
505
  int i;
  xmlNodePtr child;
Boris Boesler's avatar
Boris Boesler committed
506
  eff_t *join = NEW (eff_t);
507
508
509
  join->kind = eff_join;

  CHECK_NAME (joinelm, join);
Boris Boesler's avatar
Boris Boesler committed
510
  VERBOSE_PRINT ((stdout, "join node \t0x%08x\n", (int) joinelm));
511
512
  id = new_id_from_str(getNodeId (joinelm));
  VERBOSE_PRINT ((stdout, "join->id = \"%s\"\n", get_id_str(id)));
513

514
  child = get_valid_child(joinelm);
515
516
517
518
519
520
521
  n_ins = 0;

  while (NULL != child) {
    n_ins ++;
    child = child->next;
  }

522
  ins = (const ident **) malloc (n_ins * sizeof (const ident *) );
523
  i = 0;
524
  child = get_valid_child(joinelm);
525
526

  while (NULL != child) {
Boris Boesler's avatar
Boris Boesler committed
527
528
529
    eff_t *valref = parseValref (doc, child);
    ins [i ++] = valref-> id;
    free(valref);
530
531
532
    child = child->next;
  }

Boris Boesler's avatar
Boris Boesler committed
533
534
535
  join-> id = id;
  join-> effect.join.n_ins = n_ins;
  join-> effect.join.ins = ins;
536
537
538
539

  return (join);
}

Florian Liekweg's avatar
Florian Liekweg committed
540
541
static eff_t*
parseUnknown (xmlDocPtr doc, xmlNodePtr unknownelm)
542
{
543
  const ident *id;
Boris Boesler's avatar
Boris Boesler committed
544
  eff_t *unknown = NEW (eff_t);
545
546
547
  unknown->kind = eff_unknown;

  CHECK_NAME (unknownelm, unknown);
Boris Boesler's avatar
Boris Boesler committed
548
  VERBOSE_PRINT ((stdout, "unknown node \t0x%08x\n", (int) unknownelm));
549
  id = new_id_from_str(getNodeId (unknownelm));
Boris Boesler's avatar
Boris Boesler committed
550
  unknown-> id = id;
551
552
553
554

  return (unknown);
}

Florian Liekweg's avatar
Florian Liekweg committed
555
556
static eff_t*
parseReturn (xmlDocPtr doc, xmlNodePtr retelm)
557
558
{
  xmlNodePtr child;
Boris Boesler's avatar
Boris Boesler committed
559
  eff_t *ret = NEW (eff_t);
560
561
562
  ret->kind = eff_ret;

  CHECK_NAME (retelm, ret);
Boris Boesler's avatar
Boris Boesler committed
563
  VERBOSE_PRINT ((stdout, "ret node \t0x%08x\n", (int) retelm));
564

565
  child = get_any_valid_child(retelm);
566
567

  if (child) {
Boris Boesler's avatar
Boris Boesler committed
568
569
    eff_t *valref = parseValref (doc, child);
    ret-> effect.ret.ret_id = valref-> id;
570
571
    free (valref);
  } else {
Boris Boesler's avatar
Boris Boesler committed
572
    ret-> effect.ret.ret_id = NO_ID;
573
574
575
576
577
  }

  return (ret);
}

Florian Liekweg's avatar
Florian Liekweg committed
578
579
static eff_t*
parseRaise (xmlDocPtr doc, xmlNodePtr raiseelm)
580
{
581
  const char *tp_id;
Boris Boesler's avatar
Boris Boesler committed
582
  eff_t *valref;
583
  xmlNodePtr child;
Boris Boesler's avatar
Boris Boesler committed
584
  eff_t *raise = NEW (eff_t);
585
586
587
  raise->kind = eff_raise;

  CHECK_NAME (raiseelm, raise);
Boris Boesler's avatar
Boris Boesler committed
588
  VERBOSE_PRINT ((stdout, "raise node \t0x%08x\n", (int) raiseelm));
589
  tp_id = getNodeTypeId (raiseelm);
Boris Boesler's avatar
Boris Boesler committed
590
  VERBOSE_PRINT ((stdout, "raise->type = \"%s\"\n", tp_id));
591
  child = get_valid_child(raiseelm);
592
593
594
595

  assert (NULL != child);

  valref = parseValref (doc, child);
Boris Boesler's avatar
Boris Boesler committed
596
  raise-> effect.raise.valref = valref-> id;
597
  raise-> effect.raise.tp_id = new_id_from_str(tp_id);
598
599
600
601
602
  free (valref);

  return (raise);
}

Boris Boesler's avatar
Boris Boesler committed
603

604
605
606
607
608
609
610
611
612
/*
  Types and Entities
*/

/** parse a type node and insert it into the list */
static void
parseType (xmlDocPtr doc, xmlNodePtr typeelm)
{
  type_t *type;
613
  const char *tp_id = getNodeId (typeelm);
Boris Boesler's avatar
Boris Boesler committed
614
615
  VERBOSE_PRINT ((stdout, "type node \t0x%08x (%s)\n", (int) typeelm, tp_id));
  VERBOSE_PRINT ((stdout, "type = \"%s\"\n", getNodeTypeStr (typeelm)));
616
617

  type = (type_t*) malloc (sizeof (type_t));
618
619
  type -> type_ident = new_id_from_str(getNodeTypeStr (typeelm));
  type -> id         = new_id_from_str(tp_id);
620
621
622
623
624
625
626
627
628
629
630
631

  type->prev = types;
  types = type;
}

/** parse an entity node and insert it into the list */
static void
parseEntity (xmlDocPtr doc, xmlNodePtr entelm)
{
  entity_t *ent = NEW (entity_t);

  /* parse it */
632
  const char *ent_id = getNodeId (entelm);
633
  /* fprintf (stdout, "entity node \t0x%08x (%d)\n", (int) entelm, ent_id); */
Boris Boesler's avatar
Boris Boesler committed
634
  VERBOSE_PRINT ((stdout, "ent  = \"%s.%s\"\n",
Florian Liekweg's avatar
Florian Liekweg committed
635
636
          getNodeTypeStr (entelm),
          getNodeEntityStr (entelm)));
637
638


639
640
641
642
  ent -> ent_ident = new_id_from_str (getNodeEntityStr (entelm));
  ent -> tp_ident  = new_id_from_str (getNodeTypeStr   (entelm));
  ent -> owner     = new_id_from_str (getNodeOwnerStr  (entelm));
  ent -> id = new_id_from_str(ent_id);
643
644
645
646
647
648
649
650
651

  ent->prev = entities;
  entities = ent;
}

/** parse any effect, and turn it into an eff_t (TODO) */
static void
parseEffect (xmlDocPtr doc, xmlNodePtr effelm)
{
Boris Boesler's avatar
Boris Boesler committed
652
653
  xmlNodePtr cur;
  const char *procname = getNodeProcName (effelm);
654
  const char *ownerid = getNodeOwnerStr (effelm);
Boris Boesler's avatar
Boris Boesler committed
655
  proc_t *curr_effs = NULL;
656
657
658
  int i = 0;
  int n_effs = 0;

Boris Boesler's avatar
Boris Boesler committed
659
  VERBOSE_PRINT ((stdout, "effect for method \"%s\"\n", procname));
660

Boris Boesler's avatar
Boris Boesler committed
661
  cur = effelm -> xmlChildrenNode;
662
663
664
665
  while (NULL != cur) {
    n_effs ++;
    cur = cur->next;
  }
Boris Boesler's avatar
Boris Boesler committed
666
  VERBOSE_PRINT ((stdout, "has %d effects\n", n_effs));
667

Boris Boesler's avatar
Boris Boesler committed
668
  curr_effs = NEW (proc_t);
669
  curr_effs -> proc_ident = new_id_from_str(procname);
670
  curr_effs -> ownerid = new_id_from_str(ownerid);
671
672
  curr_effs->effs = (eff_t**) malloc (n_effs * sizeof (eff_t*));

Boris Boesler's avatar
Boris Boesler committed
673
  cur = effelm -> xmlChildrenNode;
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
  while (NULL != cur) {
    eff_t *eff = NULL;

    if (NODE_NAME (cur, arg)) {
      eff = (eff_t*) parseArg (doc, cur);
    } else if (NODE_NAME (cur, load)) {
      eff = (eff_t*) parseLoad (doc, cur);
    } else if (NODE_NAME (cur, store)) {
      eff = (eff_t*) parseStore (doc, cur);
    } else if (NODE_NAME (cur, alloc)) {
      eff = (eff_t*) parseAlloc (doc, cur);
    } else if (NODE_NAME (cur, call)) {
      eff = (eff_t*) parseCall (doc, cur);
    } else if (NODE_NAME (cur, join)) {
      eff = (eff_t*) parseJoin (doc, cur);
    } else if (NODE_NAME (cur, unknown)) {
      eff = (eff_t*) parseUnknown (doc, cur);
    } else if (NODE_NAME (cur, ret)) {
      eff = (eff_t*) parseReturn (doc, cur);
    } else if (NODE_NAME (cur, raise)) {
      eff = (eff_t*) parseRaise (doc, cur);
    } else if (NODE_NAME (cur, comment)) {
      /* comment */
Boris Boesler's avatar
Boris Boesler committed
697
      --n_effs;
698
699
700
701
    } else {
      fprintf (stderr, "wrong element \"%s\"\n", BAD_CAST cur->name);
      exit (EXIT_FAILURE);
    }
Boris Boesler's avatar
Boris Boesler committed
702
703
704
705
706
707
708
709
710
711
712
    if(eff) {
      VERBOSE_PRINT ((stdout, "effect %p@%d\n", (void*)eff, i));
      curr_effs -> effs[i++] = eff;
    }
    cur = cur -> next;
  }
  assert((i == n_effs) && "incorrect number of effects");
  curr_effs -> n_effs = n_effs;
  curr_effs -> next = procs;
  procs = curr_effs;
}
713
714


Boris Boesler's avatar
Boris Boesler committed
715
716
717
718
719
720
static
void read_extern (const char *filename)
{
  /* xmlNsPtr ns = NULL; */           /* no namespace for us */
  xmlDocPtr doc;                /* whole document */
  xmlNodePtr cur;               /* current node */
721
  ident *mod_id;
Boris Boesler's avatar
Boris Boesler committed
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
  module_t *module;

  /* i've got no idea what the VERSION cast is all about. voodoo
     programming at its finest. */
  LIBXML_TEST_VERSION xmlKeepBlanksDefault (0);
  VERBOSE_PRINT((stdout, "read file %s\n", filename));
  doc = xmlParseFile (filename);
  CHECK (doc, "xmlParseFile");

  cur = xmlDocGetRootElement (doc);
  CHECK (cur, "xmlDocGetRootElement");

  if (! NODE_NAME (cur, effects)) {
    fprintf (stderr,"root node \"%s\" != \"effects\"\n", BAD_CAST cur->name);
    xmlFreeDoc (doc);
    exit (EXIT_FAILURE);
  }

740
741
742
  mod_id = getNodeModuleIdent (cur);
  if (NULL != mod_id) {
    VERBOSE_PRINT ((stdout, "effects for \"%s\"\n",
Florian Liekweg's avatar
Florian Liekweg committed
743
            get_id_str(mod_id)));
Boris Boesler's avatar
Boris Boesler committed
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
  }
  else {
    VERBOSE_PRINT ((stdout, "effects \t0x%08x\n", (int) cur));
  }

  /* parse entities */
  cur = cur->xmlChildrenNode;
  while (cur != NULL) {
    if (NODE_NAME (cur, type)) {
      parseType (doc, cur);
    } else if (NODE_NAME (cur, entity)) {
      parseEntity (doc, cur);
    } else if (NODE_NAME (cur, effect)) {
      parseEffect (doc, cur);
    } else if ((NODE_NAME (cur, comment))) {
      /* comment */
    } else {
      fprintf (stderr, "wrong element \"%s\"\n", BAD_CAST cur->name);
      exit (EXIT_FAILURE);
    }
    cur = cur->next;
765
766
  }

Boris Boesler's avatar
Boris Boesler committed
767
  module = NEW(module_t);
768
  module -> id = mod_id;
Boris Boesler's avatar
Boris Boesler committed
769
770
771
772
773
774
775
776
777
778
  module -> types = types;
  module -> entities = entities;
  module -> procs = procs;

  types = NULL;
  entities = NULL;
  procs = NULL;

  module -> next = modules;
  modules = module;
779
780
}

Boris Boesler's avatar
Boris Boesler committed
781
782
/********************************************************************/

783
/*
Boris Boesler's avatar
Boris Boesler committed
784
785
786
787
 * free additional structure
 */
static
void freeArg (eff_t *arg)
788
{
Boris Boesler's avatar
Boris Boesler committed
789
790
791
792
  VERBOSE_PRINT ((stdout, "free arg node \t0x%08x\n", (int) arg));
  free(arg);
  return;
}
793

Boris Boesler's avatar
Boris Boesler committed
794
795
796
797
798
799
800
static
void freeValref (eff_t *valref)
{
  VERBOSE_PRINT ((stdout, "free valref node \t0x%08x\n", (int) valref));
  free(valref);
  return;
}
801

Boris Boesler's avatar
Boris Boesler committed
802
803
804
805
806
807
808
static
void freeSelect (eff_t *sel)
{
  VERBOSE_PRINT ((stdout, "free select node \t0x%08x\n", (int) sel));
  free(sel);
  return;
}
809

Boris Boesler's avatar
Boris Boesler committed
810
811
812
813
814
815
static
void freeLoad (eff_t *load)
{
  VERBOSE_PRINT ((stdout, "free load node \t0x%08x\n", (int) load));
  free (load);
  return;
816
817
}

Boris Boesler's avatar
Boris Boesler committed
818
819
static
void freeStore (eff_t *store)
820
{
Boris Boesler's avatar
Boris Boesler committed
821
822
823
824
  VERBOSE_PRINT ((stdout, "free store node \t0x%08x\n", (int) store));
  free (store);
  return;
}
825

Boris Boesler's avatar
Boris Boesler committed
826
827
828
829
830
831
832
static
void freeAlloc (eff_t *alloc)
{
  VERBOSE_PRINT ((stdout, "free alloc node \t0x%08x\n", (int) alloc));
  free(alloc);
  return;
}
833

Boris Boesler's avatar
Boris Boesler committed
834
835
836
837
838
839
840
841
static
void freeCall (eff_t *call)
{
  VERBOSE_PRINT ((stdout, "free call node \t0x%08x\n", (int) call));
  free(call -> effect.call.args);
  free(call);
  return;
}
842

Boris Boesler's avatar
Boris Boesler committed
843
844
845
846
847
848
849
static
void freeJoin (eff_t *join)
{
  VERBOSE_PRINT ((stdout, "free join node \t0x%08x\n", (int) join));
  free(join -> effect.join.ins);
  free(join);
  return;
850
851
}

Boris Boesler's avatar
Boris Boesler committed
852
853
static
void freeUnknown (eff_t *unknown)
854
{
Boris Boesler's avatar
Boris Boesler committed
855
856
857
858
  VERBOSE_PRINT ((stdout, "free unknown node \t0x%08x\n", (int) unknown));
  free(unknown);
  return;
}
859

Boris Boesler's avatar
Boris Boesler committed
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
static
void freeReturn (eff_t *ret)
{
  VERBOSE_PRINT ((stdout, "free ret node \t0x%08x\n", (int) ret));
  free(ret);
  return;
}

static
void freeRaise (eff_t *raise)
{
  VERBOSE_PRINT ((stdout, "free raise node \t0x%08x\n", (int) raise));
  free (raise);
  return;
}


static
void freeProcEffs(proc_t *proc)
{
  int i;
  int num;

883
  VERBOSE_PRINT ((stdout, "free effect for method \"%s\"\n",
Florian Liekweg's avatar
Florian Liekweg committed
884
          get_id_str(proc -> proc_ident)));
885

Boris Boesler's avatar
Boris Boesler committed
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
  num = proc -> n_effs;
  for(i = 0; i < num; i++) {
    switch(proc -> effs[i] -> kind) {
    case eff_arg:
      freeArg(proc -> effs[i]);
      break;
    case eff_valref:
      freeValref(proc -> effs[i]);
      break;
    case eff_select:
      freeSelect(proc -> effs[i]);
      break;
    case eff_load:
      freeLoad(proc -> effs[i]);
      break;
    case eff_store:
      freeStore(proc -> effs[i]);
      break;
    case eff_alloc:
      freeAlloc(proc -> effs[i]);
      break;
    case eff_call:
      freeCall(proc -> effs[i]);
      break;
    case eff_unknown:
      freeUnknown(proc -> effs[i]);
      break;
    case eff_join:
      freeJoin(proc -> effs[i]);
      break;
    case eff_raise:
      freeRaise(proc -> effs[i]);
      break;
    case eff_ret:
      freeReturn(proc -> effs[i]);
      break;
    default:
      assert(0 && "try to free an unknown effect");
      break;
925
    }
Boris Boesler's avatar
Boris Boesler committed
926
927
928
929
  }
  free(proc -> effs);
  proc -> effs = NULL;
}
930

Boris Boesler's avatar
Boris Boesler committed
931
932
933
934
935
static
void freeModuleProcs(module_t *module)
{
  proc_t *next_proc, *proc;

936
  VERBOSE_PRINT ((stdout, "free procs for module \"%s\"\n",
Florian Liekweg's avatar
Florian Liekweg committed
937
          get_id_str(module -> id)));
938

Boris Boesler's avatar
Boris Boesler committed
939
940
941
942
943
944
  proc = module -> procs;
  while(proc) {
    next_proc = proc -> next;
    freeProcEffs(proc);
    free(proc);
    proc = next_proc;
945
  }
Boris Boesler's avatar
Boris Boesler committed
946
}
947

Boris Boesler's avatar
Boris Boesler committed
948
949
950
951
952
953
954
955
956
957
958
959
static
void free_data(void)
{
  module_t *module, *next_module;

  module = modules;
  while(module) {
    freeModuleProcs(module);
    next_module = module -> next;
    free(module);
    module = next_module;
  }
960
961
}

Boris Boesler's avatar
Boris Boesler committed
962
963
964
/********************************************************************/

static
965
type_t *find_type_in_module(module_t *module, const ident *typeid)
966
{
Boris Boesler's avatar
Boris Boesler committed
967
  type_t *type;
968

Boris Boesler's avatar
Boris Boesler committed
969
  for(type = module -> types; type; type = type -> prev) {
970
971
972
    VERBOSE_PRINT((stdout, "test typeid %s\n", get_id_str(type -> id)));
    if(type -> id == typeid) {
      VERBOSE_PRINT((stdout, "found\n"));
Boris Boesler's avatar
Boris Boesler committed
973
      return(type);
974
975
    }
  }
976
  VERBOSE_PRINT((stdout, "did not find type id %s\n", get_id_str(typeid)));
Boris Boesler's avatar
Boris Boesler committed
977
978
  return(NULL);
}
979

Boris Boesler's avatar
Boris Boesler committed
980
981
982
983
984
985
/********************************************************************/

static void add_value_to_proc(proc_t *proc, eff_t *eff)
{
  eff -> next = proc -> values;
  proc -> values = eff;
986
987
}

Boris Boesler's avatar
Boris Boesler committed
988

989
eff_t *find_valueid_in_proc_effects(const ident *id, proc_t *proc)
990
{
Boris Boesler's avatar
Boris Boesler committed
991
  eff_t *val;
992

Boris Boesler's avatar
Boris Boesler committed
993
994
  val = proc -> values;
  while(val) {
995
    if(id == val -> id) {
Boris Boesler's avatar
Boris Boesler committed
996
      return(val);
997
    }
Boris Boesler's avatar
Boris Boesler committed
998
999
1000
    val = val -> next;
  }
  return(NULL);
For faster browsing, not all history is shown. View entire blame