[project @ 2000-03-22 18:14:22 by sewardj]
[ghc-hetmet.git] / ghc / interpreter / interface.c
1
2 /* --------------------------------------------------------------------------
3  * GHC interface file processing for Hugs
4  *
5  * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
6  * All rights reserved. See NOTICE for details and conditions of use etc...
7  * Hugs version 1.4, December 1997
8  *
9  * $RCSfile: interface.c,v $
10  * $Revision: 1.40 $
11  * $Date: 2000/03/22 18:14:22 $
12  * ------------------------------------------------------------------------*/
13
14 #include "prelude.h"
15 #include "storage.h"
16 #include "connect.h"
17 #include "errors.h"
18 #include "object.h"
19
20 #include "Assembler.h"  /* for wrapping GHC objects */
21
22
23 /*#define DEBUG_IFACE*/
24 #define VERBOSE FALSE
25
26 /* --------------------------------------------------------------------------
27  * (This comment is now out of date.  JRS, 991216).
28  * The "addGHC*" functions act as "impedence matchers" between GHC
29  * interface files and Hugs.  Their main job is to convert abstract
30  * syntax trees into Hugs' internal representations.
31  *
32  * The main trick here is how we deal with mutually recursive interface 
33  * files:
34  *
35  * o As we read an import decl, we add it to a list of required imports
36  *   (unless it's already loaded, of course).
37  *
38  * o Processing of declarations is split into two phases:
39  *
40  *   1) While reading the interface files, we construct all the Names,
41  *      Tycons, etc declared in the interface file but we don't try to
42  *      resolve references to any entities the declaration mentions.
43  *
44  *      This is done by the "addGHC*" functions.
45  *
46  *   2) After reading all the interface files, we finish processing the
47  *      declarations by resolving any references in the declarations
48  *      and doing any other processing that may be required.
49  *
50  *      This is done by the "finishGHC*" functions which use the 
51  *      "fixup*" functions to assist them.
52  *
53  *   The interface between these two phases are the "ghc*Decls" which
54  *   contain lists of decls that haven't been completed yet.
55  *
56  * ------------------------------------------------------------------------*/
57
58
59 /*
60 New comment, 991216, explaining roughly how it all works.
61 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
62
63 Interfaces can contain references to unboxed types, and these need to
64 be handled carefully.  The following is a summary of how the interface
65 loader now works.  It is applied to groups of interfaces simultaneously,
66 viz, the entire Prelude at once:
67
68 0.  Parse interfaces, chasing imports until a complete
69     strongly-connected-component of ifaces has been parsed.
70     All interfaces in this scc are processed together, in
71     steps 1 .. 8 below.
72
73 1.  Throw away any entity not mentioned in the export lists.
74
75 2.  Delete type (not data or newtype) definitions which refer to 
76     unknown types in their right hand sides.  Because Hugs doesn't
77     know of any unboxed types, this has the side effect of removing
78     all type defns referring to unboxed types.  Repeat step 2 until
79     a fixed point is reached.
80
81 3.  Make abstract all data/newtype defns which refer to an unknown
82     type.  eg, data Word = MkW Word# becomes data Word, because 
83     Word# is unknown.  Hugs is happy to know about abstract boxed
84     Words, but not about Word#s.
85
86 4.  Step 2 could delete types referred to by values, instances and
87     classes.  So filter all entities, and delete those referring to
88     unknown types _or_ classes.  This could cause other entities
89     to become invalid, so iterate step 4 to a fixed point.
90
91     After step 4, the interfaces no longer contain anything
92     unpalatable to Hugs.
93
94 5.  Steps 1-4 operate purely on the iface syntax trees.  We now start
95     creating symbol table entries.  First, create a module table
96     entry for each interface, and locate and read in the corresponding
97     object file.  This is done by the startGHCModule function.
98
99 6.  Traverse all interfaces.  For each entity, create an entry in
100     the name, tycon, class or instance table, and fill in relevant
101     fields, but do not attempt to link tycon/class/instance/name uses
102     to their symbol table entries.  This is done by the startGHC*
103     functions.
104
105 7.  Revisit all symbol table entries created in step 6.  We should
106     now be able to replace all references to tycons/classes/instances/
107     names with the relevant symbol table entries.  This is done by
108     the finishGHC* functions.
109
110 8.  Traverse all interfaces.  For each iface, examine the export lists
111     and use it to build export lists in the module table.  Do the
112     implicit 'import Prelude' thing if necessary.  Finally, resolve
113     references in the object code for this module.  This is done
114     by the finishGHCModule function.
115 */
116
117 /* --------------------------------------------------------------------------
118  * local function prototypes:
119  * ------------------------------------------------------------------------*/
120
121 static Void startGHCValue       ( Int,VarId,Type );
122 static Void finishGHCValue      ( VarId );
123
124 static Void startGHCSynonym     ( Int,Cell,List,Type );
125 static Void finishGHCSynonym    ( Tycon ); 
126
127 static Void  startGHCClass      ( Int,List,Cell,List,List );
128 static Class finishGHCClass     ( Class ); 
129
130 static Inst startGHCInstance    ( Int,List,Pair,VarId );
131 static Void finishGHCInstance   ( Inst );
132
133 static Void startGHCImports     ( ConId,List );
134 static Void finishGHCImports    ( ConId,List );
135
136 static Void startGHCExports     ( ConId,List );
137 static Void finishGHCExports    ( ConId,List );
138
139 static Void finishGHCFixdecl    ( Cell prec, Cell assoc, ConVarId name );
140
141 static Void finishGHCModule     ( Cell );
142 static Void startGHCModule      ( Text );
143
144 static Void startGHCDataDecl    ( Int,List,Cell,List,List );
145 static List finishGHCDataDecl   ( ConId tyc );
146 /* Supporting stuff for {start|finish}GHCDataDecl */
147 static List startGHCConstrs     ( Int,List,List );
148 static Name startGHCSel         ( Int,Pair );
149 static Name startGHCConstr      ( Int,Int,Triple );
150
151 static Void startGHCNewType     ( Int,List,Cell,List,Cell );
152 static Void finishGHCNewType    ( ConId tyc );
153
154
155
156 static Kinds tvsToKind             ( List );
157 static Int   arityFromType         ( Type );
158 static Int   arityInclDictParams   ( Type );
159 static Bool  allTypesKnown         ( Type type, 
160                                      List aktys /* [QualId] */,
161                                      ConId thisMod );
162                                          
163 static List  ifTyvarsIn            ( Type );
164 static Type  tvsToOffsets          ( Int,Type,List );
165 static Type  conidcellsToTycons    ( Int,Type );
166
167
168
169
170
171 /* --------------------------------------------------------------------------
172  * Top-level interface processing
173  * ------------------------------------------------------------------------*/
174
175 /* getIEntityName :: I_IMPORT..I_VALUE -> ConVarId | NIL */
176 static ConVarId getIEntityName ( Cell c )
177 {
178    switch (whatIs(c)) {
179       case I_IMPORT:     return NIL;
180       case I_INSTIMPORT: return NIL;
181       case I_EXPORT:     return NIL;
182       case I_FIXDECL:    return zthd3(unap(I_FIXDECL,c));
183       case I_INSTANCE:   return NIL;
184       case I_TYPE:       return zsel24(unap(I_TYPE,c));
185       case I_DATA:       return zsel35(unap(I_DATA,c));
186       case I_NEWTYPE:    return zsel35(unap(I_NEWTYPE,c));
187       case I_CLASS:      return zsel35(unap(I_CLASS,c));
188       case I_VALUE:      return zsnd3(unap(I_VALUE,c));
189       default:           internal("getIEntityName");
190    }
191 }
192
193
194 /* Filter the contents of an interface, using the supplied predicate.
195    For flexibility, the predicate is passed as a second arg the value
196    extraArgs.  This is a hack to get round the lack of partial applications
197    in C.  Pred should not have any side effects.  The dumpaction param
198    gives us the chance to print a message or some such for dumped items.
199    When a named entity is deleted, filterInterface also deletes the name
200    in the export lists.
201 */
202 static Cell filterInterface ( Cell root, 
203                               Bool (*pred)(Cell,Cell), 
204                               Cell extraArgs,
205                               Void (*dumpAction)(Cell) )
206 {
207    List tops;
208    Cell iface       = unap(I_INTERFACE,root);
209    List tops2       = NIL;
210    List deleted_ids = NIL; /* :: [ConVarId] */
211
212    for (tops = zsnd(iface); nonNull(tops); tops=tl(tops)) {
213       if (pred(hd(tops),extraArgs)) {
214          tops2 = cons( hd(tops), tops2 );
215       } else {
216          ConVarId deleted_id = getIEntityName ( hd(tops) );
217          if (nonNull(deleted_id))
218             deleted_ids = cons ( deleted_id, deleted_ids );
219          if (dumpAction)
220             dumpAction ( hd(tops) );
221       }
222    }
223    tops2 = reverse(tops2);
224
225    /* Clean up the export list now. */
226    for (tops=tops2; nonNull(tops); tops=tl(tops)) {
227       if (whatIs(hd(tops))==I_EXPORT) {
228          Cell exdecl  = unap(I_EXPORT,hd(tops));
229          List exlist  = zsnd(exdecl);
230          List exlist2 = NIL;
231          for (; nonNull(exlist); exlist=tl(exlist)) {
232             Cell ex       = hd(exlist);
233             ConVarId exid = isZPair(ex) ? zfst(ex) : ex;
234             assert (isCon(exid) || isVar(exid));
235             if (!varIsMember(textOf(exid),deleted_ids))
236                exlist2 = cons(ex, exlist2);
237          }
238          hd(tops) = ap(I_EXPORT,zpair(zfst(exdecl),exlist2));
239       }
240    }
241
242    return ap(I_INTERFACE, zpair(zfst(iface),tops2));
243 }
244
245
246 List /* of CONID */ getInterfaceImports ( Cell iface )
247 {
248     List  tops;
249     List  imports = NIL;
250
251     for (tops = zsnd(unap(I_INTERFACE,iface)); nonNull(tops); tops=tl(tops))
252        if (whatIs(hd(tops)) == I_IMPORT) {
253           ZPair imp_decl = unap(I_IMPORT,hd(tops));
254           ConId m_to_imp = zfst(imp_decl);
255           if (textOf(m_to_imp) != findText("PrelGHC")) {
256              imports = cons(m_to_imp,imports);
257 #            ifdef DEBUG_IFACE
258              fprintf(stderr, "add iface %s\n", 
259                      textToStr(textOf(m_to_imp)));
260 #            endif
261           }
262        }
263     return imports;
264 }
265
266
267 /* getExportDeclsInIFace :: I_INTERFACE -> [I_EXPORT] */
268 static List getExportDeclsInIFace ( Cell root )
269 {
270    Cell  iface   = unap(I_INTERFACE,root);
271    List  decls   = zsnd(iface);
272    List  exports = NIL;
273    List  ds;
274    for (ds=decls; nonNull(ds); ds=tl(ds))
275       if (whatIs(hd(ds))==I_EXPORT)
276          exports = cons(hd(ds), exports);
277    return exports;
278 }
279
280
281 /* Does t start with "$dm" ? */
282 static Bool isIfaceDefaultMethodName ( Text t )
283 {
284    String s = textToStr(t);
285    return (s && s[0]=='$' && s[1]=='d' && s[2]=='m' && s[3]);
286 }
287       
288
289 static Bool isExportedIFaceEntity ( Cell ife, List exlist_list )
290 {
291    /* ife         :: I_IMPORT..I_VALUE                      */
292    /* exlist_list :: [[ ConVarId | ((ConId, [ConVarId])) ]] */
293    Text   tnm;
294    List   exlist;
295    List   t;
296    String s;
297
298    ConVarId ife_id = getIEntityName ( ife );
299
300    if (isNull(ife_id)) return TRUE;
301
302    tnm = textOf(ife_id);
303
304    /* Don't junk default methods, even tho the export list doesn't
305       mention them.
306    */
307    if (isIfaceDefaultMethodName(tnm)) goto retain;
308
309    /* for each export list ... */
310    for (; nonNull(exlist_list); exlist_list=tl(exlist_list)) {
311       exlist = hd(exlist_list);
312
313       /* for each entity in an export list ... */
314       for (t=exlist; nonNull(t); t=tl(t)) {
315          if (isZPair(hd(t))) {
316             /* A pair, which means an export entry 
317                of the form ClassName(foo,bar). */
318             List subents = cons(zfst(hd(t)),zsnd(hd(t)));
319             for (; nonNull(subents); subents=tl(subents))
320                if (textOf(hd(subents)) == tnm) goto retain;
321          } else {
322             /* Single name in the list. */
323             if (textOf(hd(t)) == tnm) goto retain;
324          }
325       }
326
327    }
328 #  ifdef DEBUG_IFACE
329    fprintf ( stderr, "     dump %s\n", textToStr(tnm) );
330 #  endif
331    return FALSE;
332
333  retain:
334 #  ifdef DEBUG_IFACE
335    fprintf ( stderr, "   retain %s\n", textToStr(tnm) );
336 #  endif
337    return TRUE;
338 }
339
340
341 static Bool isExportedAbstractly ( ConId ife_id, List exlist_list )
342 {
343    /* ife_id      :: ConId                                  */
344    /* exlist_list :: [[ ConVarId | ((ConId, [ConVarId])) ]] */
345    Text  tnm;
346    List  exlist;
347    List  t;
348
349    assert (isCon(ife_id));
350    tnm = textOf(ife_id);
351
352    /* for each export list ... */
353    for (; nonNull(exlist_list); exlist_list=tl(exlist_list)) {
354       exlist = hd(exlist_list);
355
356       /* for each entity in an export list ... */
357       for (t=exlist; nonNull(t); t=tl(t)) {
358          if (isZPair(hd(t))) {
359             /* A pair, which means an export entry 
360                of the form ClassName(foo,bar). */
361             if (textOf(zfst(hd(t))) == tnm) return FALSE;
362          } else {
363             if (textOf(hd(t)) == tnm) return TRUE;
364          }
365       }
366    }
367    internal("isExportedAbstractly");
368    return FALSE; /*notreached*/
369 }
370
371
372 /* Remove entities not mentioned in any of the export lists. */
373 static Cell deleteUnexportedIFaceEntities ( Cell root )
374 {
375    Cell  iface       = unap(I_INTERFACE,root);
376    ConId iname       = zfst(iface);
377    List  decls       = zsnd(iface);
378    List  decls2      = NIL;
379    List  exlist_list = NIL;
380    List  t;
381
382 #  ifdef DEBUG_IFACE
383    fprintf(stderr, "\ncleanIFace: %s\n", textToStr(textOf(iname)));
384 #  endif
385
386    exlist_list = getExportDeclsInIFace ( root );
387    /* exlist_list :: [I_EXPORT] */
388    
389    for (t=exlist_list; nonNull(t); t=tl(t))
390       hd(t) = zsnd(unap(I_EXPORT,hd(t)));
391    /* exlist_list :: [[ ConVarId | ((ConId, [ConVarId])) ]] */
392
393    if (isNull(exlist_list)) {
394       ERRMSG(0) "Can't find any export lists in interface file"
395       EEND;
396    }
397
398    return filterInterface ( root, isExportedIFaceEntity, 
399                             exlist_list, NULL );
400 }
401
402
403 /* addTyconsAndClassesFromIFace :: I_INTERFACE -> [QualId] -> [QualId] */
404 static List addTyconsAndClassesFromIFace ( Cell root, List aktys )
405 {
406    Cell iface = unap(I_INTERFACE,root);
407    Text mname = textOf(zfst(iface));
408    List defns = zsnd(iface);
409    for (; nonNull(defns); defns = tl(defns)) {
410       Cell defn = hd(defns);
411       Cell what = whatIs(defn);
412       if (what==I_TYPE || what==I_DATA 
413           || what==I_NEWTYPE || what==I_CLASS) {
414          QualId q = mkQCon ( mname, textOf(getIEntityName(defn)) );
415          if (!qualidIsMember ( q, aktys ))
416             aktys = cons ( q, aktys );
417       }
418    }
419    return aktys;
420 }
421
422
423 static Void ifentityAllTypesKnown_dumpmsg ( Cell entity )
424 {
425    ConVarId id = getIEntityName ( entity );
426 #  ifdef DEBUG_IFACE
427    fprintf ( stderr, 
428              "dumping %s because of unknown type(s)\n",
429              isNull(id) ? "(nameless entity?!)" : textToStr(textOf(id)) );
430 #  endif
431 }
432
433
434 /* ifentityAllTypesKnown :: I_IMPORT..I_VALUE -> (([QualId], ConId)) -> Bool */
435 /* mod is the current module being processed -- so we can qualify unqual'd
436    names.  Strange calling convention for aktys and mod is so we can call this
437    from filterInterface.
438 */
439 static Bool ifentityAllTypesKnown ( Cell entity, ZPair aktys_mod )
440 {
441    List  t, u;
442    List  aktys = zfst ( aktys_mod );
443    ConId mod   = zsnd ( aktys_mod );
444    switch (whatIs(entity)) {
445       case I_IMPORT:
446       case I_INSTIMPORT:
447       case I_EXPORT:
448       case I_FIXDECL: 
449          return TRUE;
450       case I_INSTANCE: {
451          Cell inst = unap(I_INSTANCE,entity);
452          List ctx  = zsel25 ( inst ); /* :: [((QConId,VarId))] */
453          Type cls  = zsel35 ( inst ); /* :: Type */
454          for (t = ctx; nonNull(t); t=tl(t))
455             if (!allTypesKnown(zfst(hd(t)),aktys,mod)) return FALSE;
456          if (!allTypesKnown(cls, aktys,mod)) return FALSE;
457          return TRUE;
458       }
459       case I_TYPE:
460          return allTypesKnown( zsel44(unap(I_TYPE,entity)), aktys,mod );
461       case I_DATA: {
462          Cell data    = unap(I_DATA,entity);
463          List ctx     = zsel25 ( data ); /* :: [((QConId,VarId))] */
464          List constrs = zsel55 ( data ); /* :: [ ((ConId, [((Type,VarId,Int))] )) ] */
465          for (t = ctx; nonNull(t); t=tl(t))
466             if (!allTypesKnown(zfst(hd(t)),aktys,mod)) return FALSE;
467          for (t = constrs; nonNull(t); t=tl(t))
468             for (u = zsnd(hd(t)); nonNull(u); u=tl(u))
469                if (!allTypesKnown(zfst3(hd(u)),aktys,mod)) return FALSE;
470          return TRUE;
471       }
472       case I_NEWTYPE: {
473          Cell  newty  = unap(I_NEWTYPE,entity);
474          List  ctx    = zsel25(newty);    /* :: [((QConId,VarId))] */
475          ZPair constr = zsel55 ( newty ); /* :: ((ConId,Type)) */
476          for (t = ctx; nonNull(t); t=tl(t))
477             if (!allTypesKnown(zfst(hd(t)),aktys,mod)) return FALSE;
478          if (nonNull(constr)
479              && !allTypesKnown(zsnd(constr),aktys,mod)) return FALSE;
480          return TRUE;
481       }
482       case I_CLASS: {
483          Cell klass = unap(I_CLASS,entity);
484          List ctx   = zsel25(klass);  /* :: [((QConId,VarId))] */
485          List sigs  = zsel55(klass);  /* :: [((VarId,Type))] */
486          for (t = ctx; nonNull(t); t=tl(t))
487             if (!allTypesKnown(zfst(hd(t)),aktys,mod)) return FALSE;
488          for (t = sigs; nonNull(t); t=tl(t)) 
489             if (!allTypesKnown(zsnd(hd(t)),aktys,mod)) return FALSE;
490          return TRUE;
491       }
492       case I_VALUE: 
493          return allTypesKnown( zthd3(unap(I_VALUE,entity)), aktys,mod );
494       default: 
495          internal("ifentityAllTypesKnown");
496    }
497 }
498
499
500 /* ifTypeDoesntRefUnknownTycon :: I_IMPORT..I_VALUE -> (([QualId], ConId)) -> Bool */
501 /* mod is the current module being processed -- so we can qualify unqual'd
502    names.  Strange calling convention for aktys and mod is so we can call this
503    from filterInterface.
504 */
505 static Bool ifTypeDoesntRefUnknownTycon ( Cell entity, ZPair aktys_mod )
506 {
507    List  t, u;
508    List  aktys = zfst ( aktys_mod );
509    ConId mod   = zsnd ( aktys_mod );
510    if (whatIs(entity) != I_TYPE) {
511       return TRUE;
512    } else {
513       return allTypesKnown( zsel44(unap(I_TYPE,entity)), aktys,mod );
514    }
515 }
516
517
518 static Void ifTypeDoesntRefUnknownTycon_dumpmsg ( Cell entity )
519 {
520    ConVarId id = getIEntityName ( entity );
521    assert (whatIs(entity)==I_TYPE);
522    assert (isCon(id));
523 #  ifdef DEBUG_IFACE
524    fprintf ( stderr, 
525              "dumping type %s because of unknown tycon(s)\n",
526              textToStr(textOf(id)) );
527 #  endif
528 }
529
530
531 /* abstractifyExport :: I_EXPORT -> ConId -> I_EXPORT
532 */
533 static List abstractifyExDecl ( Cell root, ConId toabs )
534 {
535    ZPair exdecl = unap(I_EXPORT,root);
536    List  exlist = zsnd(exdecl);
537    List  res    = NIL;
538    for (; nonNull(exlist); exlist = tl(exlist)) {
539       if (isZPair(hd(exlist)) 
540           && textOf(toabs) == textOf(zfst(hd(exlist)))) {
541          /* it's toabs, exported non-abstractly */
542          res = cons ( zfst(hd(exlist)), res );
543       } else {
544          res = cons ( hd(exlist), res );
545       }
546    }
547    return ap(I_EXPORT,zpair(zfst(exdecl),reverse(res)));
548 }
549
550
551 static Void ppModule ( Text modt )
552 {
553 #  ifdef DEBUG_IFACE
554    fflush(stderr); fflush(stdout);
555    fprintf(stderr, "---------------- MODULE %s ----------------\n", 
556                    textToStr(modt) );
557 #  endif
558 }
559
560
561 static void* ifFindItblFor ( Name n )
562 {
563    /* n is a constructor for which we want to find the GHC info table.
564       First look for a _con_info symbol.  If that doesn't exist, _and_
565       this is a nullary constructor, then it's safe to look for the
566       _static_info symbol instead.
567    */
568    void* p;
569    char  buf[1000];
570    Text  t;
571
572    sprintf ( buf, MAYBE_LEADING_UNDERSCORE_STR("%s_%s_con_info"), 
573                   textToStr( module(name(n).mod).text ),
574                   textToStr( name(n).text ) );
575    t = enZcodeThenFindText(buf);
576    p = lookupOTabName ( name(n).mod, textToStr(t) );
577
578    if (p) return p;
579
580    if (name(n).arity == 0) {
581       sprintf ( buf, MAYBE_LEADING_UNDERSCORE_STR("%s_%s_static_info"), 
582                      textToStr( module(name(n).mod).text ),
583                      textToStr( name(n).text ) );
584       t = enZcodeThenFindText(buf);
585       p = lookupOTabName ( name(n).mod, textToStr(t) );
586       if (p) return p;
587    }
588
589    ERRMSG(0) "Can't find info table %s", textToStr(t)
590    EEND;
591 }
592
593
594 void ifLinkConstrItbl ( Name n )
595 {
596    /* name(n) is either a constructor or a field name.  
597       If the latter, ignore it.  If it is a non-nullary constructor,
598       find its info table in the object code.  If it's nullary,
599       we can skip the info table, since all accesses will go via
600       the _closure label.
601    */
602    if (islower(textToStr(name(n).text)[0])) return;
603    if (name(n).arity == 0) return;
604    name(n).itbl = ifFindItblFor(n);
605 }
606
607
608 static void ifSetClassDefaultsAndDCon ( Class c )
609 {
610    char   buf[100];
611    char   buf2[1000];
612    String s;
613    Name   n;
614    Text   t;
615    void*  p;
616    List   defs;   /* :: [Name] */
617    List   mems;   /* :: [Name] */
618    Module m;
619    assert(isNull(cclass(c).defaults));
620
621    /* Create the defaults list by more-or-less cloning the members list. */   
622    defs = NIL;
623    for (mems=cclass(c).members; nonNull(mems); mems=tl(mems)) {
624       strcpy(buf, "$dm");
625       s = textToStr( name(hd(mems)).text );
626       assert(strlen(s) < 95);
627       strcat(buf, s);
628       n = findNameInAnyModule(findText(buf));
629       assert (nonNull(n));
630       defs = cons(n,defs);
631    }
632    defs = rev(defs);
633    cclass(c).defaults = defs;
634
635    /* Create a name table entry for the dictionary datacon.
636       Interface files don't mention them, so it had better not
637       already be present.
638    */
639    strcpy(buf, ":D");
640    s = textToStr( cclass(c).text );
641    assert( strlen(s) < 96 );
642    strcat(buf, s);
643    t = findText(buf);
644    n = findNameInAnyModule(t);
645    assert(isNull(n));
646
647    m = cclass(c).mod;
648    n = newName(t,NIL);
649    name(n).mod    = m;
650    name(n).arity  = cclass(c).numSupers + cclass(c).numMembers;
651    name(n).number = cfunNo(0);
652    cclass(c).dcon = n;
653
654    /* And finally ... set name(n).itbl to Mod_:DClass_con_info.
655       Because this happens right at the end of loading, we know
656       that we should actually be able to find the symbol in this
657       module's object symbol table.  Except that if the dictionary
658       has arity 1, we don't bother, since it will be represented as
659       a newtype and not as a data, so its itbl can remain NULL.
660    */ 
661    if (name(n).arity == 1) {
662       name(n).itbl = NULL;
663       name(n).defn = nameId;
664    } else {
665       p = ifFindItblFor ( n );
666       name(n).itbl = p;
667    }
668 }
669
670
671 void processInterfaces ( List /* of CONID */ iface_modnames )
672 {
673     List    tmp;
674     List    xs;
675     ZTriple tr;
676     Cell    iface;
677     Int     sizeObj;
678     Text    nameObj;
679     Text    mname;
680     List    decls;
681     Module  mod;
682     List    all_known_types;
683     Int     num_known_types;
684     List    cls_list;         /* :: List Class */
685     List    constructor_list; /* :: List Name */
686
687     List ifaces       = NIL;  /* :: List I_INTERFACE */
688
689     if (isNull(iface_modnames)) return;
690
691 #   ifdef DEBUG_IFACE
692     fprintf ( stderr, 
693               "processInterfaces: %d interfaces to process\n", 
694               length(ifaces_outstanding) );
695 #   endif
696
697     for (xs = iface_modnames; nonNull(xs); xs=tl(xs)) {
698        mod = findModule(textOf(hd(xs)));
699        assert(nonNull(mod));
700        assert(!module(mod).fromSrc);
701        ifaces = cons ( module(mod).tree, ifaces );
702     }
703     ifaces = reverse(ifaces);
704
705     /* Clean up interfaces -- dump non-exported value, class, type decls */
706     for (xs = ifaces; nonNull(xs); xs = tl(xs))
707        hd(xs) = deleteUnexportedIFaceEntities(hd(xs));
708
709
710     /* Iteratively delete any type declarations which refer to unknown
711        tycons. 
712     */
713     num_known_types = 999999999;
714     while (TRUE) {
715        Int i;
716
717        /* Construct a list of all known tycons.  This is a list of QualIds. 
718           Unfortunately it also has to contain all known class names, since
719           allTypesKnown cannot distinguish between tycons and classes -- a
720           deficiency of the iface abs syntax.
721        */
722        all_known_types = getAllKnownTyconsAndClasses();
723        for (xs = ifaces; nonNull(xs); xs=tl(xs))
724           all_known_types 
725              = addTyconsAndClassesFromIFace ( hd(xs), all_known_types );
726
727        /* Have we reached a fixed point? */
728        i = length(all_known_types);
729 #      ifdef DEBUG_IFACE
730        fprintf ( stderr,
731                  "\n============= %d known types =============\n", i );
732 #      endif
733        if (num_known_types == i) break;
734        num_known_types = i;
735
736        /* Delete all entities which refer to unknown tycons. */
737        for (xs = ifaces; nonNull(xs); xs = tl(xs)) {
738           ConId mod = zfst(unap(I_INTERFACE,hd(xs)));
739           assert(nonNull(mod));
740           hd(xs) = filterInterface ( hd(xs), 
741                                      ifTypeDoesntRefUnknownTycon,
742                                      zpair(all_known_types,mod),
743                                      ifTypeDoesntRefUnknownTycon_dumpmsg );
744        }
745     }
746
747     /* Now abstractify any datas and newtypes which refer to unknown tycons
748        -- including, of course, the type decls just deleted.
749     */
750     for (xs = ifaces; nonNull(xs); xs = tl(xs)) {
751        List  absify = NIL;                      /* :: [ConId] */
752        ZPair iface  = unap(I_INTERFACE,hd(xs)); /* ((ConId, [I_IMPORT..I_VALUE])) */
753        ConId mod    = zfst(iface);
754        List  aktys  = all_known_types;          /* just a renaming */
755        List  es,t,u;
756        List  exlist_list;
757
758        /* Compute into absify the list of all ConIds (tycons) we need to
759           abstractify. 
760        */
761        for (es = zsnd(iface); nonNull(es); es=tl(es)) {
762           Cell ent      = hd(es);
763           Bool allKnown = TRUE;
764
765           if (whatIs(ent)==I_DATA) {
766              Cell data    = unap(I_DATA,ent);
767              List ctx     = zsel25 ( data ); /* :: [((QConId,VarId))] */
768              List constrs = zsel55 ( data ); /* :: [ ((ConId, [((Type,VarId,Int))] )) ] */
769              for (t = ctx; nonNull(t); t=tl(t))
770                 if (!allTypesKnown(zfst(hd(t)),aktys,mod)) allKnown = FALSE;
771              for (t = constrs; nonNull(t); t=tl(t))
772                 for (u = zsnd(hd(t)); nonNull(u); u=tl(u))
773                     if (!allTypesKnown(zfst3(hd(u)),aktys,mod)) allKnown = FALSE;
774           }
775           else if (whatIs(ent)==I_NEWTYPE) {
776              Cell  newty  = unap(I_NEWTYPE,ent);
777              List  ctx    = zsel25(newty);    /* :: [((QConId,VarId))] */
778              ZPair constr = zsel55 ( newty ); /* :: ((ConId,Type)) */
779              for (t = ctx; nonNull(t); t=tl(t))
780                 if (!allTypesKnown(zfst(hd(t)),aktys,mod)) allKnown = FALSE;
781              if (!allTypesKnown(zsnd(constr),aktys,mod)) allKnown = FALSE;
782           }
783
784           if (!allKnown) {
785              absify = cons ( getIEntityName(ent), absify );
786 #            ifdef DEBUG_IFACE
787              fprintf ( stderr, 
788                        "abstractifying %s because it uses an unknown type\n",
789                        textToStr(textOf(getIEntityName(ent))) );
790 #            endif
791           }
792        }
793
794        /* mark in exports as abstract all names in absify (modifies iface) */
795        for (; nonNull(absify); absify=tl(absify)) {
796           ConId toAbs = hd(absify);
797           for (es = zsnd(iface); nonNull(es); es=tl(es)) {
798              if (whatIs(hd(es)) != I_EXPORT) continue;
799              hd(es) = abstractifyExDecl ( hd(es), toAbs );
800           }
801        }
802
803        /* For each data/newtype in the export list marked as abstract,
804           remove the constructor lists.  This catches all abstractification
805           caused by the code above, and it also catches tycons which really
806           were exported abstractly.
807        */
808
809        exlist_list = getExportDeclsInIFace ( ap(I_INTERFACE,iface) );
810        /* exlist_list :: [I_EXPORT] */
811        for (t=exlist_list; nonNull(t); t=tl(t))
812           hd(t) = zsnd(unap(I_EXPORT,hd(t)));
813        /* exlist_list :: [[ ConVarId | ((ConId, [ConVarId])) ]] */
814
815        for (es = zsnd(iface); nonNull(es); es=tl(es)) {
816           Cell ent = hd(es);
817           if (whatIs(ent)==I_DATA
818               && isExportedAbstractly ( getIEntityName(ent),
819                                         exlist_list )) {
820              Cell data = unap(I_DATA,ent);
821              data = z5ble ( zsel15(data), zsel25(data), zsel35(data),
822                             zsel45(data), NIL /* the constr list */ );
823              hd(es) = ap(I_DATA,data);
824 #            ifdef DEBUG_IFACE
825              fprintf(stderr, "abstractify data %s\n", 
826                      textToStr(textOf(getIEntityName(ent))) );
827 #            endif
828           }
829           else if (whatIs(ent)==I_NEWTYPE
830               && isExportedAbstractly ( getIEntityName(ent), 
831                                         exlist_list )) {
832              Cell data = unap(I_NEWTYPE,ent);
833              data = z5ble ( zsel15(data), zsel25(data), zsel35(data),
834                             zsel45(data), NIL /* the constr-type pair */ );
835              hd(es) = ap(I_NEWTYPE,data);
836 #            ifdef DEBUG_IFACE
837              fprintf(stderr, "abstractify newtype %s\n", 
838                      textToStr(textOf(getIEntityName(ent))) );
839 #            endif
840           }
841        }
842
843        /* We've finally finished mashing this iface.  Update the iface list. */
844        hd(xs) = ap(I_INTERFACE,iface);
845     }
846
847
848     /* At this point, the interfaces are cleaned up so that no type, data or
849        newtype defn refers to a non-existant type.  However, there still may
850        be value defns, classes and instances which refer to unknown types.
851        Delete iteratively until a fixed point is reached.
852     */
853 #   ifdef DEBUG_IFACE
854     fprintf(stderr,"\n");
855 #   endif
856     num_known_types = 999999999;
857     while (TRUE) {
858        Int i;
859
860        /* Construct a list of all known tycons.  This is a list of QualIds. 
861           Unfortunately it also has to contain all known class names, since
862           allTypesKnown cannot distinguish between tycons and classes -- a
863           deficiency of the iface abs syntax.
864        */
865        all_known_types = getAllKnownTyconsAndClasses();
866        for (xs = ifaces; nonNull(xs); xs=tl(xs))
867           all_known_types = addTyconsAndClassesFromIFace ( hd(xs), all_known_types );
868
869        /* Have we reached a fixed point? */
870        i = length(all_known_types);
871 #      ifdef DEBUG_IFACE
872        fprintf ( stderr,
873                  "\n------------- %d known types -------------\n", i );
874 #      endif
875        if (num_known_types == i) break;
876        num_known_types = i;
877
878        /* Delete all entities which refer to unknown tycons. */
879        for (xs = ifaces; nonNull(xs); xs = tl(xs)) {
880           ConId mod = zfst(unap(I_INTERFACE,hd(xs)));
881           assert(nonNull(mod));
882
883           hd(xs) = filterInterface ( hd(xs),
884                                      ifentityAllTypesKnown,
885                                      zpair(all_known_types,mod), 
886                                      ifentityAllTypesKnown_dumpmsg );
887        }
888     }
889
890
891     /* Allocate module table entries and read in object code. */
892     for (xs=ifaces; nonNull(xs); xs=tl(xs))
893        startGHCModule ( textOf(zfst(unap(I_INTERFACE,hd(xs)))) );
894
895
896     /* Now work through the decl lists of the modules, and call the
897        startGHC* functions on the entities.  This creates names in
898        various tables but doesn't bind them to anything.
899     */
900
901     for (xs = ifaces; nonNull(xs); xs = tl(xs)) {
902        iface   = unap(I_INTERFACE,hd(xs));
903        mname   = textOf(zfst(iface));
904        mod     = findModule(mname);
905        if (isNull(mod)) internal("processInterfaces(4)");
906        setCurrModule(mod);
907        ppModule ( module(mod).text );
908
909        for (decls = zsnd(iface); nonNull(decls); decls = tl(decls)) {
910           Cell decl = hd(decls);
911           switch(whatIs(decl)) {
912              case I_EXPORT: {
913                 Cell exdecl = unap(I_EXPORT,decl);
914                 startGHCExports ( zfst(exdecl), zsnd(exdecl) );
915                 break;
916              }
917              case I_IMPORT: {
918                 Cell imdecl = unap(I_IMPORT,decl);
919                 startGHCImports ( zfst(imdecl), zsnd(imdecl) );
920                 break;
921              }
922              case I_FIXDECL: {
923                 break;
924              }
925              case I_INSTANCE: {
926                 /* Trying to find the instance table location allocated by
927                    startGHCInstance in subsequent processing is a nightmare, so
928                    cache it on the tree. 
929                 */
930                 Cell instance = unap(I_INSTANCE,decl);
931                 Inst in = startGHCInstance ( zsel15(instance), zsel25(instance),
932                                              zsel35(instance), zsel45(instance) );
933                 hd(decls) = ap(I_INSTANCE,
934                                z5ble( zsel15(instance), zsel25(instance),
935                                       zsel35(instance), zsel45(instance), in ));
936                 break;
937              }
938              case I_TYPE: {
939                 Cell tydecl = unap(I_TYPE,decl);
940                 startGHCSynonym ( zsel14(tydecl), zsel24(tydecl),
941                                   zsel34(tydecl), zsel44(tydecl) );
942                 break;
943              }
944              case I_DATA: {
945                 Cell ddecl = unap(I_DATA,decl);
946                 startGHCDataDecl ( zsel15(ddecl), zsel25(ddecl), 
947                                    zsel35(ddecl), zsel45(ddecl), zsel55(ddecl) );
948                 break;
949              }
950              case I_NEWTYPE: {
951                 Cell ntdecl = unap(I_NEWTYPE,decl);
952                 startGHCNewType ( zsel15(ntdecl), zsel25(ntdecl), 
953                                   zsel35(ntdecl), zsel45(ntdecl), 
954                                   zsel55(ntdecl) );
955                 break;
956              }
957              case I_CLASS: {
958                 Cell klass = unap(I_CLASS,decl);
959                 startGHCClass ( zsel15(klass), zsel25(klass), 
960                                 zsel35(klass), zsel45(klass), 
961                                 zsel55(klass) );
962                 break;
963              }
964              case I_VALUE: {
965                 Cell value = unap(I_VALUE,decl);
966                 startGHCValue ( zfst3(value), zsnd3(value), zthd3(value) );
967                 break;
968              }
969              default:
970                 internal("processInterfaces(1)");
971           }
972        }       
973     }
974
975 #   ifdef DEBUG_IFACE
976     fprintf(stderr, "\n============================"
977                     "=============================\n");
978     fprintf(stderr, "=============================="
979                     "===========================\n");
980 #   endif
981
982     /* Traverse again the decl lists of the modules, this time 
983        calling the finishGHC* functions.  But don't process
984        the export lists; those must wait for later.
985     */
986     cls_list         = NIL;
987     constructor_list = NIL;
988     for (xs = ifaces; nonNull(xs); xs = tl(xs)) {
989        iface   = unap(I_INTERFACE,hd(xs));
990        mname   = textOf(zfst(iface));
991        mod     = findModule(mname);
992        if (isNull(mod)) internal("processInterfaces(3)");
993        setCurrModule(mod);
994        ppModule ( module(mod).text );
995
996        for (decls = zsnd(iface); nonNull(decls); decls = tl(decls)) {
997           Cell decl = hd(decls);
998           switch(whatIs(decl)) {
999              case I_EXPORT: {
1000                 break;
1001              }
1002              case I_IMPORT: {
1003                 break;
1004              }
1005              case I_FIXDECL: {
1006                 Cell fixdecl = unap(I_FIXDECL,decl);
1007                 finishGHCFixdecl ( zfst3(fixdecl), zsnd3(fixdecl), zthd3(fixdecl) );
1008                 break;
1009              }
1010              case I_INSTANCE: {
1011                 Cell instance = unap(I_INSTANCE,decl);
1012                 finishGHCInstance ( zsel55(instance) );
1013                 break;
1014              }
1015              case I_TYPE: {
1016                 Cell tydecl = unap(I_TYPE,decl);
1017                 finishGHCSynonym ( zsel24(tydecl) );
1018                 break;
1019              }
1020              case I_DATA: {
1021                 Cell ddecl   = unap(I_DATA,decl);
1022                 List constrs = finishGHCDataDecl ( zsel35(ddecl) );
1023                 constructor_list = appendOnto ( constrs, constructor_list );
1024                 break;
1025              }
1026              case I_NEWTYPE: {
1027                 Cell ntdecl = unap(I_NEWTYPE,decl);
1028                 finishGHCNewType ( zsel35(ntdecl) );
1029                 break;
1030              }
1031              case I_CLASS: {
1032                 Cell  klass = unap(I_CLASS,decl);
1033                 Class cls   = finishGHCClass ( zsel35(klass) );
1034                 cls_list = cons(cls,cls_list);
1035                 break;
1036              }
1037              case I_VALUE: {
1038                 Cell value = unap(I_VALUE,decl);
1039                 finishGHCValue ( zsnd3(value) );
1040                 break;
1041              }
1042              default:
1043                 internal("processInterfaces(2)");
1044           }
1045        }       
1046     }
1047 #   ifdef DEBUG_IFACE
1048     fprintf(stderr, "\n+++++++++++++++++++++++++++++"
1049                     "++++++++++++++++++++++++++++\n");
1050     fprintf(stderr, "+++++++++++++++++++++++++++++++"
1051                     "++++++++++++++++++++++++++\n");
1052 #   endif
1053
1054     /* Build the module(m).export lists for each module, by running
1055        through the export lists in the iface.  Also, do the implicit
1056        'import Prelude' thing.  And finally, do the object code 
1057        linking.
1058     */
1059     for (xs = ifaces; nonNull(xs); xs = tl(xs))
1060        finishGHCModule(hd(xs));
1061
1062     mapProc(visitClass,cls_list);
1063     mapProc(ifSetClassDefaultsAndDCon,cls_list);
1064     mapProc(ifLinkConstrItbl,constructor_list);
1065
1066     /* Finished! */
1067     ifaces_outstanding = NIL;
1068 }
1069
1070
1071 /* --------------------------------------------------------------------------
1072  * Modules
1073  * ------------------------------------------------------------------------*/
1074
1075 static void startGHCModule_errMsg ( char* msg )
1076 {
1077    fprintf ( stderr, "object error: %s\n", msg );
1078 }
1079
1080 static void* startGHCModule_clientLookup ( char* sym )
1081 {
1082 #  ifdef DEBUG_IFACE
1083    /* fprintf ( stderr, "CLIENTLOOKUP %s\n", sym ); */
1084 #  endif
1085    return lookupObjName ( sym );
1086 }
1087
1088 static ObjectCode* startGHCModule_partial_load ( String objNm, Int objSz )
1089 {
1090    ObjectCode* oc
1091       = ocNew ( startGHCModule_errMsg,
1092                 startGHCModule_clientLookup,
1093                 objNm, objSz );
1094     
1095     if (!oc) {
1096        ERRMSG(0) "Storage allocation for object file \"%s\" failed", objNm
1097        EEND;
1098     }
1099     if (!ocLoadImage(oc,VERBOSE)) {
1100        ERRMSG(0) "Reading of object file \"%s\" failed", objNm
1101        EEND;
1102     }
1103     if (!ocVerifyImage(oc,VERBOSE)) {
1104        ERRMSG(0) "Validation of object file \"%s\" failed", objNm
1105        EEND;
1106     }
1107     if (!ocGetNames(oc,VERBOSE)) {
1108        ERRMSG(0) "Reading of symbol names in object file \"%s\" failed", objNm
1109        EEND;
1110     }
1111     return oc;
1112 }
1113
1114 static Void startGHCModule ( Text mname )
1115 {
1116    List   xts;
1117    Module m = findModule(mname);
1118    assert(nonNull(m));
1119
1120 #  ifdef DEBUG_IFACE
1121    fprintf ( stderr, "startGHCIface: name %16s   objsize %d\n", 
1122                       textToStr(mname), module(m).objSize );
1123 #  endif
1124    if (module(m).fake)
1125       module(m).fake = FALSE;
1126
1127    /* Get hold of the primary object for the module. */
1128    module(m).object
1129       = startGHCModule_partial_load ( textToStr(module(m).objName), 
1130                                       module(m).objSize );
1131
1132    /* and any extras ... */
1133    for (xts = module(m).objectExtraNames; nonNull(xts); xts=tl(xts)) {
1134       Int         size;
1135       ObjectCode* oc;
1136       Text        xtt = hd(xts);
1137       String      nm  = getExtraObjectInfo (
1138                            textToStr(module(m).objName),
1139                            textToStr(xtt),
1140                            &size
1141                         );
1142       if (size == -1) {
1143          ERRMSG(0) "Can't find extra object file \"%s\"", nm
1144          EEND;
1145       }
1146       oc = startGHCModule_partial_load ( nm, size );
1147       oc->next = module(m).objectExtras;
1148       module(m).objectExtras = oc;
1149    }
1150 }
1151
1152
1153 /* For the module mod, augment both the export environment (.exports) 
1154    and the eval environment (.names, .tycons, .classes)
1155    with the symbols mentioned in exlist.  We don't actually need
1156    to modify the names, tycons, classes or instances in the eval 
1157    environment, since previous processing of the
1158    top-level decls in the iface should have done this already.
1159
1160    mn is the module mentioned in the export list; it is the "original"
1161    module for the symbols in the export list.  We should also record
1162    this info with the symbols, since references to object code need to
1163    refer to the original module in which a symbol was defined, rather
1164    than to some module it has been imported into and then re-exported.
1165
1166    We take the policy that if something mentioned in an export list
1167    can't be found in the symbol tables, it is simply ignored.  After all,
1168    previous processing of the iface syntax trees has already removed 
1169    everything which Hugs can't handle, so if there is mention of these
1170    things still lurking in export lists somewhere, about the only thing
1171    to do is to ignore it.
1172
1173    Also do an implicit 'import Prelude' thingy for the module,
1174    if appropriate.
1175 */
1176
1177
1178 static Void finishGHCModule ( Cell root ) 
1179 {
1180    /* root :: I_INTERFACE */
1181    Cell        iface       = unap(I_INTERFACE,root);
1182    ConId       iname       = zfst(iface);
1183    Module      mod         = findModule(textOf(iname));
1184    List        exlist_list = NIL;
1185    List        t;
1186    ObjectCode* oc;
1187
1188 #  ifdef DEBUG_IFACE
1189    fprintf(stderr, "begin finishGHCModule %s\n", textToStr(textOf(iname)));
1190 #  endif
1191
1192    if (isNull(mod)) internal("finishExports(1)");
1193    setCurrModule(mod);
1194
1195    exlist_list = getExportDeclsInIFace ( root );
1196    /* exlist_list :: [I_EXPORT] */
1197    
1198    for (; nonNull(exlist_list); exlist_list=tl(exlist_list)) {
1199       ZPair exdecl = unap(I_EXPORT,hd(exlist_list));
1200       ConId exmod  = zfst(exdecl);
1201       List  exlist = zsnd(exdecl);
1202       /* exlist :: [ ConVarId | ((ConId, [ConVarId])) ] */
1203
1204       for (; nonNull(exlist); exlist=tl(exlist)) {
1205          Bool   abstract;
1206          List   subents;
1207          Cell   c;
1208          QualId q;
1209          Cell   ex = hd(exlist);
1210
1211          switch (whatIs(ex)) {
1212
1213             case VARIDCELL: /* variable */
1214                q = mkQualId(exmod,ex);
1215                c = findQualNameWithoutConsultingExportList ( q );
1216                if (isNull(c)) goto notfound;
1217 #              ifdef DEBUG_IFACE
1218                fprintf(stderr, "   var %s\n", textToStr(textOf(ex)) );
1219 #              endif
1220                module(mod).exports = cons(c, module(mod).exports);
1221                addName(c);
1222                break;
1223
1224             case CONIDCELL: /* non data tycon */
1225                q = mkQualId(exmod,ex);
1226                c = findQualTyconWithoutConsultingExportList ( q );
1227                if (isNull(c)) goto notfound;
1228 #              ifdef DEBUG_IFACE
1229                fprintf(stderr, "   type %s\n", textToStr(textOf(ex)) );
1230 #              endif
1231                module(mod).exports = cons(pair(c,NIL), module(mod).exports);
1232                addTycon(c);
1233                break;
1234
1235             case ZTUP2: /* data T = C1 ... Cn  or class C where f1 ... fn */
1236                subents = zsnd(ex);  /* :: [ConVarId] */
1237                ex      = zfst(ex);  /* :: ConId */
1238                q       = mkQualId(exmod,ex);
1239                c       = findQualTyconWithoutConsultingExportList ( q );
1240
1241                if (nonNull(c)) { /* data */
1242 #                 ifdef DEBUG_IFACE
1243                   fprintf(stderr, "   data/newtype %s = { ", 
1244                           textToStr(textOf(ex)) );
1245 #                 endif
1246                   assert(tycon(c).what == DATATYPE || tycon(c).what==NEWTYPE);
1247                   abstract = isNull(tycon(c).defn);
1248                   /* This data/newtype could be abstract even tho the export list
1249                      says to export it non-abstractly.  That happens if it was 
1250                      imported from some other module and is now being re-exported,
1251                      and previous cleanup phases have abstractified it in the 
1252                      original (defining) module.
1253                   */
1254                   if (abstract) {
1255                      module(mod).exports = cons(pair(c,NIL), module(mod).exports);
1256                      addTycon(c);
1257 #                    ifdef DEBUG_IFACE
1258                      fprintf ( stderr, "(abstract) ");
1259 #                    endif
1260                   } else {
1261                      module(mod).exports = cons(pair(c,DOTDOT), module(mod).exports);
1262                      addTycon(c);
1263                      for (; nonNull(subents); subents = tl(subents)) {
1264                         Cell ent2 = hd(subents);
1265                         assert(isCon(ent2) || isVar(ent2)); 
1266                                               /* isVar since could be a field name */
1267                         q = mkQualId(exmod,ent2);
1268                         c = findQualNameWithoutConsultingExportList ( q );
1269 #                       ifdef DEBUG_IFACE
1270                         fprintf(stderr, "%s ", textToStr(name(c).text));
1271 #                       endif
1272                         assert(nonNull(c));
1273                         /* module(mod).exports = cons(c, module(mod).exports); */
1274                         addName(c);
1275                      }
1276                   }
1277 #                 ifdef DEBUG_IFACE
1278                   fprintf(stderr, "}\n" );
1279 #                 endif
1280                } else { /* class */
1281                   q = mkQualId(exmod,ex);
1282                   c = findQualClassWithoutConsultingExportList ( q );
1283                   if (isNull(c)) goto notfound;
1284 #                 ifdef DEBUG_IFACE
1285                   fprintf(stderr, "   class %s { ", textToStr(textOf(ex)) );
1286 #                 endif
1287                   module(mod).exports = cons(pair(c,DOTDOT), module(mod).exports);
1288                   addClass(c);
1289                   for (; nonNull(subents); subents = tl(subents)) {
1290                      Cell ent2 = hd(subents);
1291                      assert(isVar(ent2));
1292                      q = mkQualId(exmod,ent2);
1293                      c = findQualNameWithoutConsultingExportList ( q );
1294 #                    ifdef DEBUG_IFACE
1295                      fprintf(stderr, "%s ", textToStr(name(c).text));
1296 #                    endif
1297                      if (isNull(c)) goto notfound;
1298                      /* module(mod).exports = cons(c, module(mod).exports); */
1299                      addName(c);
1300                   }
1301 #                 ifdef DEBUG_IFACE
1302                   fprintf(stderr, "}\n" );
1303 #                 endif
1304                }
1305                break;
1306
1307             default:
1308                internal("finishExports(2)");
1309
1310          } /* switch */
1311          continue;  /* so notfound: can be placed after this */
1312   
1313         notfound:
1314          /* q holds what ain't found */
1315          assert(whatIs(q)==QUALIDENT);
1316 #        ifdef DEBUG_IFACE
1317          fprintf( stderr, "   ------ IGNORED: %s.%s\n",
1318                   textToStr(qmodOf(q)), textToStr(qtextOf(q)) );
1319 #        endif
1320          continue;
1321       }
1322    }
1323
1324 #if 0
1325    if (preludeLoaded) {
1326       /* do the implicit 'import Prelude' thing */
1327       List pxs = module(modulePrelude).exports;
1328       for (; nonNull(pxs); pxs=tl(pxs)) {
1329          Cell px = hd(pxs);
1330          again:
1331          switch (whatIs(px)) {
1332             case AP: 
1333                px = fst(px); 
1334                goto again;
1335             case NAME: 
1336                module(mod).names = cons ( px, module(mod).names );
1337                break;
1338             case TYCON: 
1339                module(mod).tycons = cons ( px, module(mod).tycons );
1340                break;
1341             case CLASS: 
1342                module(mod).classes = cons ( px, module(mod).classes );
1343                break;
1344             default:               
1345                fprintf(stderr, "finishGHCModule: unknown tag %d\n", whatIs(px));
1346                internal("finishGHCModule -- implicit import Prelude");
1347                break;
1348          }
1349       }
1350    }
1351 #endif
1352
1353    /* Last, but by no means least ... */
1354    if (!ocResolve(module(mod).object,VERBOSE))
1355       internal("finishGHCModule: object resolution failed");
1356
1357    for (oc=module(mod).objectExtras; oc; oc=oc->next) {
1358       if (!ocResolve(oc, VERBOSE))
1359          internal("finishGHCModule: extra object resolution failed");
1360    }
1361 }
1362
1363
1364 /* --------------------------------------------------------------------------
1365  * Exports
1366  * ------------------------------------------------------------------------*/
1367
1368 static Void startGHCExports ( ConId mn, List exlist )
1369 {
1370 #   ifdef DEBUG_IFACE
1371     fprintf(stderr,"startGHCExports %s\n", textToStr(textOf(mn)) );
1372 #   endif
1373    /* Nothing to do. */
1374 }
1375
1376 static Void finishGHCExports ( ConId mn, List exlist )
1377 {
1378 #   ifdef DEBUG_IFACE
1379     fprintf(stderr,"finishGHCExports %s\n", textToStr(textOf(mn)) );
1380 #   endif
1381    /* Nothing to do. */
1382 }
1383
1384
1385 /* --------------------------------------------------------------------------
1386  * Imports
1387  * ------------------------------------------------------------------------*/
1388
1389 static Void startGHCImports ( ConId mn, List syms )
1390 /* nm     the module to import from */
1391 /* syms   [ConId | VarId] -- the names to import */
1392 {
1393 #  ifdef DEBUG_IFACE
1394    fprintf(stderr,"startGHCImports %s\n", textToStr(textOf(mn)) );
1395 #  endif
1396    /* Nothing to do. */
1397 }
1398
1399
1400 static Void finishGHCImports ( ConId nm, List syms )
1401 /* nm     the module to import from */
1402 /* syms   [ConId | VarId] -- the names to import */
1403 {
1404 #  ifdef DEBUG_IFACE
1405    fprintf(stderr,"finishGHCImports %s\n", textToStr(textOf(nm)) );
1406 #  endif
1407   /* Nothing to do. */
1408 }
1409
1410
1411 /* --------------------------------------------------------------------------
1412  * Fixity decls
1413  * ------------------------------------------------------------------------*/
1414
1415 static Void finishGHCFixdecl ( Cell prec, Cell assoc, ConVarId name )
1416 {
1417    Int  p = intOf(prec);
1418    Int  a = intOf(assoc);
1419    Name n = findName(textOf(name));
1420    assert (nonNull(n));
1421    name(n).syntax = mkSyntax ( a, p );
1422 }
1423
1424
1425 /* --------------------------------------------------------------------------
1426  * Vars (values)
1427  * ------------------------------------------------------------------------*/
1428
1429 /* convert a leading run of DICTAPs into Hugs' internal Qualtype form, viz:
1430    { C1 a } -> { C2 b } -> T            into
1431    ap(QUALTYPE, ( [(C1,a),(C2,b)], T ))
1432 */
1433 static Type dictapsToQualtype ( Type ty )
1434 {
1435    List pieces = NIL;
1436    List preds, dictaps;
1437
1438    /* break ty into pieces at the top-level arrows */
1439    while (isAp(ty) && isAp(fun(ty)) && fun(fun(ty))==typeArrow) {
1440       pieces = cons ( arg(fun(ty)), pieces );
1441       ty     = arg(ty);
1442    }
1443    pieces = cons ( ty, pieces );
1444    pieces = reverse ( pieces );
1445
1446    dictaps = NIL;
1447    while (nonNull(pieces) && whatIs(hd(pieces))==DICTAP) {
1448       dictaps = cons ( hd(pieces), dictaps );
1449       pieces = tl(pieces);
1450    }
1451
1452    /* dictaps holds the predicates, backwards */
1453    /* pieces holds the remainder of the type, forwards */
1454    assert(nonNull(pieces));
1455    pieces = reverse(pieces);
1456    ty = hd(pieces);
1457    pieces = tl(pieces);
1458    for (; nonNull(pieces); pieces=tl(pieces)) 
1459       ty = fn(hd(pieces),ty);
1460
1461    preds = NIL;
1462    for (; nonNull(dictaps); dictaps=tl(dictaps)) {
1463       Cell da = hd(dictaps);
1464       QualId cl = fst(unap(DICTAP,da));
1465       Cell   arg = snd(unap(DICTAP,da));
1466       preds = cons ( pair(cl,arg), preds );
1467    }
1468
1469    if (nonNull(preds)) ty = ap(QUAL, pair(preds,ty));
1470    return ty;
1471 }
1472
1473
1474
1475 static void startGHCValue ( Int line, VarId vid, Type ty )
1476 {
1477     Name   n;
1478     List   tmp, tvs;
1479     Text   v = textOf(vid);
1480
1481 #   ifdef DEBUG_IFACE
1482     fprintf(stderr,"begin startGHCValue %s\n", textToStr(v));
1483 #   endif
1484
1485     line = intOf(line);
1486     n = findName(v);
1487     if (nonNull(n) && name(n).defn != PREDEFINED) {
1488         ERRMSG(line) "Attempt to redefine variable \"%s\"", textToStr(v)
1489         EEND;
1490     }
1491     if (isNull(n)) n = newName(v,NIL);
1492
1493     ty = dictapsToQualtype(ty);
1494
1495     tvs = ifTyvarsIn(ty);
1496     for (tmp=tvs; nonNull(tmp); tmp=tl(tmp))
1497        hd(tmp) = zpair(hd(tmp),STAR);
1498     if (nonNull(tvs))
1499        ty = mkPolyType(tvsToKind(tvs),ty);
1500
1501     ty = tvsToOffsets(line,ty,tvs);
1502     name(n).type  = ty;
1503     name(n).arity = arityInclDictParams(ty);
1504     name(n).line  = line;
1505     name(n).defn  = NIL;
1506 }
1507
1508
1509 static void finishGHCValue ( VarId vid )
1510 {
1511     Name n    = findName ( textOf(vid) );
1512     Int  line = name(n).line;
1513 #   ifdef DEBUG_IFACE
1514     fprintf(stderr, "begin finishGHCValue %s\n", textToStr(name(n).text) );
1515 #   endif
1516     assert(currentModule == name(n).mod);
1517     name(n).type = conidcellsToTycons(line,name(n).type);
1518
1519     if (isIfaceDefaultMethodName(name(n).text)) {
1520        /* ... we need to set .parent to point to the class 
1521           ... once we figure out what the class actually is :-)
1522        */
1523        Type t = name(n).type;
1524        assert(isPolyType(t));
1525        if (isPolyType(t)) t = monotypeOf(t);
1526        assert(isQualType(t));
1527        t = fst(snd(t));       /* t :: [(Class,Offset)] */
1528        assert(nonNull(t));
1529        assert(nonNull(hd(t)));
1530        assert(isPair(hd(t)));
1531        t = fst(hd(t));        /* t :: Class */
1532        assert(isClass(t));
1533        
1534        name(n).parent = t;    /* phew! */
1535     }
1536 }
1537
1538
1539 /* --------------------------------------------------------------------------
1540  * Type synonyms
1541  * ------------------------------------------------------------------------*/
1542
1543 static Void startGHCSynonym ( Int line, ConId tycon, List tvs, Type ty )
1544 {
1545     /* tycon :: ConId             */
1546     /* tvs   ::  [((VarId,Kind))] */
1547     /* ty    :: Type              */ 
1548     Text t = textOf(tycon);
1549 #   ifdef DEBUG_IFACE
1550     fprintf(stderr, "begin startGHCSynonym %s\n", textToStr(t) );
1551 #   endif
1552     line = intOf(line);
1553     if (nonNull(findTycon(t))) {
1554         ERRMSG(line) "Repeated definition of type constructor \"%s\"",
1555                      textToStr(t)
1556         EEND;
1557     } else {
1558         Tycon tc        = newTycon(t);
1559         tycon(tc).line  = line;
1560         tycon(tc).arity = length(tvs);
1561         tycon(tc).what  = SYNONYM;
1562         tycon(tc).kind  = tvsToKind(tvs);
1563
1564         /* prepare for finishGHCSynonym */
1565         tycon(tc).defn  = tvsToOffsets(line,ty,tvs);
1566     }
1567 }
1568
1569
1570 static Void  finishGHCSynonym ( ConId tyc )
1571 {
1572     Tycon tc   = findTycon(textOf(tyc)); 
1573     Int   line = tycon(tc).line;
1574 #   ifdef DEBUG_IFACE
1575     fprintf(stderr, "begin finishGHCSynonym %s\n", textToStr(textOf(tyc)) );
1576 #   endif
1577
1578     assert (currentModule == tycon(tc).mod);
1579     //    setCurrModule(tycon(tc).mod);
1580     tycon(tc).defn = conidcellsToTycons(line,tycon(tc).defn);
1581
1582     /* (ADR) ToDo: can't really do this until I've done all synonyms
1583      * and then I have to do them in order
1584      * tycon(tc).defn = fullExpand(ty);
1585      * (JRS) What?!?!  i don't understand
1586      */
1587 }
1588
1589
1590 /* --------------------------------------------------------------------------
1591  * Data declarations
1592  * ------------------------------------------------------------------------*/
1593
1594 static Void startGHCDataDecl(line,ctx0,tycon,ktyvars,constrs0)
1595 Int   line;
1596 List  ctx0;      /* [((QConId,VarId))]                */
1597 Cell  tycon;     /* ConId                             */
1598 List  ktyvars;   /* [((VarId,Kind))]                  */
1599 List  constrs0;  /* [((ConId,[((Type,VarId,Int))]))]  */
1600                  /* The Text is an optional field name
1601                     The Int indicates strictness */
1602     /* ToDo: worry about being given a decl for (->) ?
1603      * and worry about qualidents for ()
1604      */
1605 {
1606     Type    ty, resTy, selTy, conArgTy;
1607     List    tmp, conArgs, sels, constrs, fields, tyvarsMentioned;
1608     List    ctx, ctx2;
1609     Triple  constr;
1610     Cell    conid;
1611     Pair    conArg, ctxElem;
1612     Text    conArgNm;
1613     Int     conArgStrictness;
1614
1615     Text t = textOf(tycon);
1616 #   ifdef DEBUG_IFACE
1617     fprintf(stderr, "begin startGHCDataDecl %s\n",textToStr(t));
1618 #   endif
1619
1620     line = intOf(line);
1621     if (nonNull(findTycon(t))) {
1622         ERRMSG(line) "Repeated definition of type constructor \"%s\"",
1623                      textToStr(t)
1624         EEND;
1625     } else {
1626         Tycon tc        = newTycon(t);
1627         tycon(tc).text  = t;
1628         tycon(tc).line  = line;
1629         tycon(tc).arity = length(ktyvars);
1630         tycon(tc).kind  = tvsToKind(ktyvars);
1631         tycon(tc).what  = DATATYPE;
1632
1633         /* a list to accumulate selectors in :: [((VarId,Type))] */
1634         sels = NIL;
1635
1636         /* make resTy the result type of the constr, T v1 ... vn */
1637         resTy = tycon;
1638         for (tmp=ktyvars; nonNull(tmp); tmp=tl(tmp))
1639            resTy = ap(resTy,zfst(hd(tmp)));
1640
1641         /* for each constructor ... */
1642         for (constrs=constrs0; nonNull(constrs); constrs=tl(constrs)) {
1643            constr = hd(constrs);
1644            conid  = zfst(constr);
1645            fields = zsnd(constr);
1646
1647            /* Build type of constr and handle any selectors found.
1648               Also collect up tyvars occurring in the constr's arg
1649               types, so we can throw away irrelevant parts of the
1650               context later.
1651            */
1652            ty = resTy;
1653            tyvarsMentioned = NIL;  
1654            /* tyvarsMentioned :: [VarId] */
1655
1656            conArgs = reverse(fields);
1657            for (; nonNull(conArgs); conArgs=tl(conArgs)) {
1658               conArg           = hd(conArgs); /* (Type,Text) */
1659               conArgTy         = zfst3(conArg);
1660               conArgNm         = zsnd3(conArg);
1661               conArgStrictness = intOf(zthd3(conArg));
1662               tyvarsMentioned = dupListOnto(ifTyvarsIn(conArgTy),
1663                                             tyvarsMentioned);
1664               if (conArgStrictness > 0) conArgTy = bang(conArgTy);
1665               ty = fn(conArgTy,ty);
1666               if (nonNull(conArgNm)) {
1667                  /* a field name is mentioned too */
1668                  selTy = fn(resTy,conArgTy);
1669                  if (whatIs(tycon(tc).kind) != STAR)
1670                     selTy = pair(POLYTYPE,pair(tycon(tc).kind, selTy));
1671                  selTy = tvsToOffsets(line,selTy, ktyvars);
1672                  sels = cons( zpair(conArgNm,selTy), sels);
1673               }
1674            }
1675
1676            /* Now ty is the constructor's type, not including context.
1677               Throw away any parts of the context not mentioned in 
1678               tyvarsMentioned, and use it to qualify ty.
1679            */
1680            ctx2 = NIL;
1681            for (ctx=ctx0; nonNull(ctx); ctx=tl(ctx)) {
1682               ctxElem = hd(ctx);     
1683               /* ctxElem :: ((QConId,VarId)) */
1684               if (nonNull(cellIsMember(textOf(zsnd(ctxElem)),tyvarsMentioned)))
1685                  ctx2 = cons(ctxElem, ctx2);
1686            }
1687            if (nonNull(ctx2))
1688               ty = ap(QUAL,pair(ctx2,ty));
1689
1690            /* stick the tycon's kind on, if not simply STAR */
1691            if (whatIs(tycon(tc).kind) != STAR)
1692               ty = pair(POLYTYPE,pair(tycon(tc).kind, ty));
1693
1694            ty = tvsToOffsets(line,ty, ktyvars);
1695
1696            /* Finally, stick the constructor's type onto it. */
1697            hd(constrs) = ztriple(conid,fields,ty);
1698         }
1699
1700         /* Final result is that 
1701            constrs :: [((ConId,[((Type,Text))],Type))]   
1702                       lists the constructors and their types
1703            sels :: [((VarId,Type))]
1704                    lists the selectors and their types
1705         */
1706         tycon(tc).defn = startGHCConstrs(line,constrs0,sels);
1707     }
1708 }
1709
1710
1711 static List startGHCConstrs ( Int line, List cons, List sels )
1712 {
1713     /* cons :: [((ConId,[((Type,Text,Int))],Type))] */
1714     /* sels :: [((VarId,Type))]                     */
1715     /* returns [Name]                               */
1716     List cs, ss;
1717     Int  conNo = length(cons)>1 ? 1 : 0;
1718     for(cs=cons; nonNull(cs); cs=tl(cs), conNo++) {
1719         Name c  = startGHCConstr(line,conNo,hd(cs));
1720         hd(cs)  = c;
1721     }
1722     /* cons :: [Name] */
1723
1724     for(ss=sels; nonNull(ss); ss=tl(ss)) {
1725         hd(ss) = startGHCSel(line,hd(ss));
1726     }
1727     /* sels :: [Name] */
1728     return appendOnto(cons,sels);
1729 }
1730
1731
1732 static Name startGHCSel ( Int line, ZPair sel )
1733 {
1734     /* sel :: ((VarId, Type))  */
1735     Text t      = textOf(zfst(sel));
1736     Type type   = zsnd(sel);
1737     
1738     Name n = findName(t);
1739     if (nonNull(n)) {
1740         ERRMSG(line) "Repeated definition for selector \"%s\"",
1741             textToStr(t)
1742         EEND;
1743     }
1744
1745     n              = newName(t,NIL);
1746     name(n).line   = line;
1747     name(n).number = SELNAME;
1748     name(n).arity  = 1;
1749     name(n).defn   = NIL;
1750     name(n).type = type;
1751     return n;
1752 }
1753
1754
1755 static Name startGHCConstr ( Int line, Int conNo, ZTriple constr )
1756 {
1757     /* constr :: ((ConId,[((Type,Text,Int))],Type)) */
1758     /* (ADR) ToDo: add rank2 annotation and existential annotation
1759      * these affect how constr can be used.
1760      */
1761     Text con   = textOf(zfst3(constr));
1762     Type type  = zthd3(constr);
1763     Int  arity = arityFromType(type);
1764     Name n = findName(con);     /* Allocate constructor fun name   */
1765     if (isNull(n)) {
1766         n = newName(con,NIL);
1767     } else if (name(n).defn!=PREDEFINED) {
1768         ERRMSG(line) "Repeated definition for constructor \"%s\"",
1769             textToStr(con)
1770         EEND;
1771     }
1772     name(n).arity  = arity;     /* Save constructor fun details    */
1773     name(n).line   = line;
1774     name(n).number = cfunNo(conNo);
1775     name(n).type   = type;
1776     return n;
1777 }
1778
1779
1780 static List finishGHCDataDecl ( ConId tyc )
1781 {
1782     List  nms;
1783     Tycon tc = findTycon(textOf(tyc));
1784 #   ifdef DEBUG_IFACE
1785     fprintf ( stderr, "begin finishGHCDataDecl %s\n", 
1786               textToStr(textOf(tyc)) );
1787 #   endif
1788     if (isNull(tc)) internal("finishGHCDataDecl");
1789     
1790     for (nms=tycon(tc).defn; nonNull(nms); nms=tl(nms)) {
1791        Name n    = hd(nms);
1792        Int  line = name(n).line;
1793        assert(currentModule == name(n).mod);
1794        name(n).type   = conidcellsToTycons(line,name(n).type);
1795        name(n).parent = tc; //---????
1796     }
1797
1798     return tycon(tc).defn;
1799 }
1800
1801
1802 /* --------------------------------------------------------------------------
1803  * Newtype decls
1804  * ------------------------------------------------------------------------*/
1805
1806 static Void startGHCNewType ( Int line, List ctx0, 
1807                               ConId tycon, List tvs, Cell constr )
1808 {
1809     /* ctx0   :: [((QConId,VarId))]                */
1810     /* tycon  :: ConId                             */
1811     /* tvs    :: [((VarId,Kind))]                  */
1812     /* constr :: ((ConId,Type)) or NIL if abstract */
1813     List tmp;
1814     Type resTy;
1815     Text t = textOf(tycon);
1816 #   ifdef DEBUG_IFACE
1817     fprintf(stderr, "begin startGHCNewType %s\n", textToStr(t) );
1818 #   endif
1819
1820     line = intOf(line);
1821
1822     if (nonNull(findTycon(t))) {
1823         ERRMSG(line) "Repeated definition of type constructor \"%s\"",
1824                      textToStr(t)
1825         EEND;
1826     } else {
1827         Tycon tc        = newTycon(t);
1828         tycon(tc).line  = line;
1829         tycon(tc).arity = length(tvs);
1830         tycon(tc).what  = NEWTYPE;
1831         tycon(tc).kind  = tvsToKind(tvs);
1832         /* can't really do this until I've read in all synonyms */
1833
1834         if (isNull(constr)) {
1835            tycon(tc).defn = NIL;
1836         } else {
1837            /* constr :: ((ConId,Type)) */
1838            Text con   = textOf(zfst(constr));
1839            Type type  = zsnd(constr);
1840            Name n = findName(con);     /* Allocate constructor fun name   */
1841            if (isNull(n)) {
1842                n = newName(con,NIL);
1843            } else if (name(n).defn!=PREDEFINED) {
1844                ERRMSG(line) "Repeated definition for constructor \"%s\"",
1845                   textToStr(con)
1846                EEND;
1847            }
1848            name(n).arity  = 1;         /* Save constructor fun details    */
1849            name(n).line   = line;
1850            name(n).number = cfunNo(0);
1851            name(n).defn   = nameId;
1852            tycon(tc).defn = singleton(n);
1853
1854            /* make resTy the result type of the constr, T v1 ... vn */
1855            resTy = tycon;
1856            for (tmp=tvs; nonNull(tmp); tmp=tl(tmp))
1857               resTy = ap(resTy,zfst(hd(tmp)));
1858            type = fn(type,resTy);
1859            if (nonNull(ctx0))
1860               type = ap(QUAL,pair(ctx0,type));
1861            type = tvsToOffsets(line,type,tvs);
1862            name(n).type   = type;
1863         }
1864     }
1865 }
1866
1867
1868 static Void finishGHCNewType ( ConId tyc )
1869 {
1870     Tycon tc = findTycon(textOf(tyc));
1871 #   ifdef DEBUG_IFACE
1872     fprintf ( stderr, "begin finishGHCNewType %s\n", 
1873               textToStr(textOf(tyc)) );
1874 #   endif
1875  
1876     if (isNull(tc)) internal("finishGHCNewType");
1877
1878     if (isNull(tycon(tc).defn)) {
1879        /* it's an abstract type */
1880     }
1881     else if (length(tycon(tc).defn) == 1) {
1882        /* As we expect, has a single constructor */
1883        Name n    = hd(tycon(tc).defn);
1884        Int  line = name(n).line;
1885        assert(currentModule == name(n).mod);
1886        name(n).type = conidcellsToTycons(line,name(n).type);
1887     } else {
1888        internal("finishGHCNewType(2)");   
1889     }
1890 }
1891
1892
1893 /* --------------------------------------------------------------------------
1894  * Class declarations
1895  * ------------------------------------------------------------------------*/
1896
1897 static Void startGHCClass(line,ctxt,tc_name,kinded_tvs,mems0)
1898 Int   line;
1899 List  ctxt;       /* [((QConId, VarId))]   */ 
1900 ConId tc_name;    /* ConId                 */
1901 List  kinded_tvs; /* [((VarId, Kind))]     */
1902 List  mems0; {    /* [((VarId, Type))]     */
1903
1904     List mems;    /* [((VarId, Type))]     */
1905     List tvsInT;  /* [VarId] and then [((VarId,Kind))] */
1906     List tvs;     /* [((VarId,Kind))]      */
1907     List ns;      /* [Name]                */
1908     Int  mno;
1909
1910     ZPair kinded_tv = hd(kinded_tvs);
1911     Text ct         = textOf(tc_name);
1912     Pair newCtx     = pair(tc_name, zfst(kinded_tv));
1913 #   ifdef DEBUG_IFACE
1914     fprintf ( stderr, "begin startGHCClass %s\n", textToStr(ct) );
1915 #   endif
1916
1917     line = intOf(line);
1918     if (length(kinded_tvs) != 1) {
1919         ERRMSG(line) "Cannot presently handle multiparam type classes in ifaces"
1920         EEND;
1921     }
1922
1923     if (nonNull(findClass(ct))) {
1924         ERRMSG(line) "Repeated definition of class \"%s\"",
1925                      textToStr(ct)
1926         EEND;
1927     } else if (nonNull(findTycon(ct))) {
1928         ERRMSG(line) "\"%s\" used as both class and type constructor",
1929                      textToStr(ct)
1930         EEND;
1931     } else {
1932         Class nw              = newClass(ct);
1933         cclass(nw).text       = ct;
1934         cclass(nw).line       = line;
1935         cclass(nw).arity      = 1;
1936         cclass(nw).head       = ap(nw,mkOffset(0));
1937         cclass(nw).kinds      = singleton( zsnd(kinded_tv) );
1938         cclass(nw).instances  = NIL;
1939         cclass(nw).numSupers  = length(ctxt);
1940
1941         /* Kludge to map the single tyvar in the context to Offset 0.
1942            Need to do something better for multiparam type classes.
1943         */
1944         cclass(nw).supers     = tvsToOffsets(line,ctxt,
1945                                              singleton(kinded_tv));
1946
1947
1948         for (mems=mems0; nonNull(mems); mems=tl(mems)) {
1949            ZPair mem  = hd(mems);
1950            Type  memT = zsnd(mem);
1951            Text  mnt  = textOf(zfst(mem));
1952            Name  mn;
1953
1954            /* Stick the new context on the member type */
1955            memT = dictapsToQualtype(memT);
1956            if (whatIs(memT)==POLYTYPE) internal("startGHCClass");
1957            if (whatIs(memT)==QUAL) {
1958               memT = pair(QUAL,
1959                           pair(cons(newCtx,fst(snd(memT))),snd(snd(memT))));
1960            } else {
1961               memT = pair(QUAL,
1962                           pair(singleton(newCtx),memT));
1963            }
1964
1965            /* Cook up a kind for the type. */
1966            tvsInT = ifTyvarsIn(memT);
1967            /* tvsInT :: [VarId] */
1968
1969            /* ToDo: maximally bogus.  We allow the class tyvar to
1970               have the kind as supplied by the parser, but we just
1971               assume that all others have kind *.  It's a kludge.
1972            */
1973            for (tvs=tvsInT; nonNull(tvs); tvs=tl(tvs)) {
1974               Kind k;
1975               if (textOf(hd(tvs)) == textOf(zfst(kinded_tv)))
1976                  k = zsnd(kinded_tv); else
1977                  k = STAR;
1978               hd(tvs) = zpair(hd(tvs),k);
1979            }
1980            /* tvsIntT :: [((VarId,Kind))] */
1981
1982            memT = mkPolyType(tvsToKind(tvsInT),memT);
1983            memT = tvsToOffsets(line,memT,tvsInT);
1984
1985            /* Park the type back on the member */
1986            mem = zpair(zfst(mem),memT);
1987
1988            /* Bind code to the member */
1989            mn = findName(mnt);
1990            if (nonNull(mn)) {
1991               ERRMSG(line) 
1992                  "Repeated definition for class method \"%s\"",
1993                  textToStr(mnt)
1994               EEND;
1995            }
1996            mn = newName(mnt,NIL);
1997
1998            hd(mems) = mem;
1999         }
2000
2001         cclass(nw).members    = mems0;
2002         cclass(nw).numMembers = length(mems0);
2003
2004         ns = NIL;
2005         for (mno=0; mno<cclass(nw).numSupers; mno++) {
2006            ns = cons(newDSel(nw,mno),ns);
2007         }
2008         cclass(nw).dsels = rev(ns);
2009     }
2010 }
2011
2012
2013 static Class finishGHCClass ( Tycon cls_tyc )
2014 {
2015     List  mems;
2016     Int   line;
2017     Int   ctr;
2018     Class nw = findClass ( textOf(cls_tyc) );
2019 #   ifdef DEBUG_IFACE
2020     fprintf ( stderr, "begin finishGHCClass %s\n", textToStr(cclass(nw).text) );
2021 #   endif
2022     if (isNull(nw)) internal("finishGHCClass");
2023
2024     line = cclass(nw).line;
2025     ctr = -2;
2026     assert (currentModule == cclass(nw).mod);
2027
2028     cclass(nw).level   = 0;
2029     cclass(nw).head    = conidcellsToTycons(line,cclass(nw).head);
2030     cclass(nw).supers  = conidcellsToTycons(line,cclass(nw).supers);
2031     cclass(nw).members = conidcellsToTycons(line,cclass(nw).members);
2032
2033     for (mems=cclass(nw).members; nonNull(mems); mems=tl(mems)) {
2034        Pair mem = hd(mems); /* (VarId, Type) */
2035        Text txt = textOf(fst(mem));
2036        Type ty  = snd(mem);
2037        Name n   = findName(txt);
2038        assert(nonNull(n));
2039        name(n).text   = txt;
2040        name(n).line   = cclass(nw).line;
2041        name(n).type   = ty;
2042        name(n).number = ctr--;
2043        name(n).arity  = arityInclDictParams(name(n).type);
2044        name(n).parent = nw;
2045        hd(mems) = n;
2046     }
2047
2048     return nw;
2049 }
2050
2051
2052 /* --------------------------------------------------------------------------
2053  * Instances
2054  * ------------------------------------------------------------------------*/
2055
2056 static Inst startGHCInstance (line,ktyvars,cls,var)
2057 Int   line;
2058 List  ktyvars; /* [((VarId,Kind))] */
2059 Type  cls;     /* Type  */
2060 VarId var; {   /* VarId */
2061     List tmp, tvs, ks, spec;
2062
2063     List xs1, xs2;
2064     Kind k;
2065
2066     Inst in = newInst();
2067 #   ifdef DEBUG_IFACE
2068     fprintf ( stderr, "begin startGHCInstance\n" );
2069 #   endif
2070
2071     line = intOf(line);
2072
2073     tvs = ifTyvarsIn(cls);  /* :: [VarId] */
2074     /* tvs :: [VarId].
2075        The order of tvs is important for tvsToOffsets.
2076        tvs should be a permutation of ktyvars.  Fish the tyvar kinds
2077        out of ktyvars and attach them to tvs.
2078     */
2079     for (xs1=tvs; nonNull(xs1); xs1=tl(xs1)) {
2080        k = NIL;
2081        for (xs2=ktyvars; nonNull(xs2); xs2=tl(xs2))
2082           if (textOf(hd(xs1)) == textOf(zfst(hd(xs2))))
2083              k = zsnd(hd(xs2));
2084        if (isNull(k)) internal("startGHCInstance: finding kinds");
2085        hd(xs1) = zpair(hd(xs1),k);
2086     }
2087
2088     cls = tvsToOffsets(line,cls,tvs);
2089     spec = NIL;
2090     while (isAp(cls)) {
2091        spec = cons(fun(cls),spec);
2092        cls  = arg(cls);
2093     }
2094     spec = reverse(spec);
2095
2096     inst(in).line         = line;
2097     inst(in).implements   = NIL;
2098     inst(in).kinds        = simpleKind(length(tvs)); /* do this right */
2099     inst(in).specifics    = spec;
2100     inst(in).numSpecifics = length(spec);
2101     inst(in).head         = cls;
2102
2103     /* Figure out the name of the class being instanced, and store it
2104        at inst(in).c.  finishGHCInstance will resolve it to a real Class. */
2105     { 
2106        Cell cl = inst(in).head;
2107        assert(whatIs(cl)==DICTAP);
2108        cl = unap(DICTAP,cl);       
2109        cl = fst(cl);
2110        assert ( isQCon(cl) );
2111        inst(in).c = cl;
2112     }
2113
2114     {
2115         Name b         = newName( /*inventText()*/ textOf(var),NIL);
2116         name(b).line   = line;
2117         name(b).arity  = length(spec); /* unused? */ /* and surely wrong */
2118         name(b).number = DFUNNAME;
2119         name(b).parent = in;
2120         inst(in).builder = b;
2121         /* bindNameToClosure(b, lookupGHCClosure(inst(in).mod,var)); */
2122     }
2123
2124     return in;
2125 }
2126
2127
2128 static Void finishGHCInstance ( Inst in )
2129 {
2130     Int    line;
2131     Class  c;
2132     Type   cls;
2133
2134 #   ifdef DEBUG_IFACE
2135     fprintf ( stderr, "begin finishGHCInstance\n" );
2136 #   endif
2137
2138     assert (nonNull(in));
2139     line = inst(in).line;
2140     assert (currentModule==inst(in).mod);
2141
2142     /* inst(in).c is, prior to finishGHCInstance, a ConId or Tuple,
2143        since startGHCInstance couldn't possibly have resolved it to
2144        a Class at that point.  We convert it to a Class now.
2145     */
2146     c = inst(in).c;
2147     assert(isQCon(c));
2148     c = findQualClassWithoutConsultingExportList(c);
2149     assert(nonNull(c));
2150     inst(in).c = c;
2151
2152     inst(in).head         = conidcellsToTycons(line,inst(in).head);
2153     inst(in).specifics    = conidcellsToTycons(line,inst(in).specifics);
2154     cclass(c).instances   = cons(in,cclass(c).instances);
2155 }
2156
2157
2158 /* --------------------------------------------------------------------------
2159  * Helper fns
2160  * ------------------------------------------------------------------------*/
2161
2162 /* This is called from the startGHC* functions.  It traverses a structure
2163    and converts varidcells, ie, type variables parsed by the interface
2164    parser, into Offsets, which is how Hugs wants to see them internally.
2165    The Offset for a type variable is determined by its place in the list
2166    passed as the second arg; the associated kinds are irrelevant.
2167
2168    ((t1,t2)) denotes the typed (z-)pair of t1 and t2.
2169 */
2170
2171 /* tvsToOffsets :: LineNo -> Type -> [((VarId,Kind))] -> Type */
2172 static Type tvsToOffsets(line,type,ktyvars)
2173 Int  line;
2174 Type type;
2175 List ktyvars; { /* [((VarId,Kind))] */
2176    switch (whatIs(type)) {
2177       case NIL:
2178       case TUPLE:
2179       case QUALIDENT:
2180       case CONIDCELL:
2181       case TYCON:
2182          return type;
2183       case ZTUP2: /* convert to the untyped representation */
2184          return ap( tvsToOffsets(line,zfst(type),ktyvars),
2185                     tvsToOffsets(line,zsnd(type),ktyvars) );
2186       case AP: 
2187          return ap( tvsToOffsets(line,fun(type),ktyvars),
2188                     tvsToOffsets(line,arg(type),ktyvars) );
2189       case POLYTYPE: 
2190          return mkPolyType ( 
2191                    polySigOf(type),
2192                    tvsToOffsets(line,monotypeOf(type),ktyvars)
2193                 );
2194          break;
2195       case QUAL:
2196          return pair(QUAL,pair(tvsToOffsets(line,fst(snd(type)),ktyvars),
2197                                tvsToOffsets(line,snd(snd(type)),ktyvars)));
2198       case DICTAP: /* bogus ?? */
2199          return ap(DICTAP, tvsToOffsets(line,snd(type),ktyvars));
2200       case UNBOXEDTUP:  /* bogus?? */
2201          return ap(UNBOXEDTUP, tvsToOffsets(line,snd(type),ktyvars));
2202       case BANG:  /* bogus?? */
2203          return ap(BANG, tvsToOffsets(line,snd(type),ktyvars));
2204       case VARIDCELL: /* Ha! some real work to do! */
2205        { Int i = 0;
2206          Text tv = textOf(type);
2207          for (; nonNull(ktyvars); i++,ktyvars=tl(ktyvars)) {
2208             Cell varid;
2209             Text tt;
2210             assert(isZPair(hd(ktyvars)));
2211             varid = zfst(hd(ktyvars));
2212             tt    = textOf(varid);
2213             if (tv == tt) return mkOffset(i);            
2214          }
2215          ERRMSG(line) "Undefined type variable \"%s\"", textToStr(tv)
2216          EEND;
2217          break;
2218        }
2219       default: 
2220          fprintf(stderr, "tvsToOffsets: unknown stuff %d\n", whatIs(type));
2221          print(type,20);
2222          fprintf(stderr,"\n");
2223          assert(0);
2224    }
2225    assert(0);
2226    return NIL; /* NOTREACHED */
2227 }
2228
2229
2230 /* This is called from the finishGHC* functions.  It traverses a structure
2231    and converts conidcells, ie, type constructors parsed by the interface
2232    parser, into Tycons (or Classes), which is how Hugs wants to see them
2233    internally.  Calls to this fn have to be deferred to the second phase
2234    of interface loading (finishGHC* rather than startGHC*) so that all relevant
2235    Tycons or Classes have been loaded into the symbol tables and can be
2236    looked up.
2237 */
2238 static Type conidcellsToTycons ( Int line, Type type )
2239 {
2240    switch (whatIs(type)) {
2241       case NIL:
2242       case OFFSET:
2243       case TYCON:
2244       case CLASS:
2245       case VARIDCELL:
2246       case TUPLE:
2247       case STAR:
2248          return type;
2249       case QUALIDENT:
2250        { Cell t;  /* Tycon or Class */
2251          Text m     = qmodOf(type);
2252          Module mod = findModule(m);
2253          if (isNull(mod)) {
2254             ERRMSG(line)
2255                "Undefined module in qualified name \"%s\"",
2256                identToStr(type)
2257             EEND;
2258             return NIL;
2259          }
2260          t = findQualTyconWithoutConsultingExportList(type);
2261          if (nonNull(t)) return t;
2262          t = findQualClassWithoutConsultingExportList(type);
2263          if (nonNull(t)) return t;
2264          ERRMSG(line)
2265               "Undefined qualified class or type \"%s\"",
2266               identToStr(type)
2267          EEND;
2268          return NIL;
2269        }
2270       case CONIDCELL:
2271        { Tycon tc;
2272          Class cl;
2273          cl = findQualClass(type);
2274          if (nonNull(cl)) return cl;
2275          if (textOf(type)==findText("[]"))
2276             /* a hack; magically qualify [] into PrelBase.[] */
2277             return conidcellsToTycons(line, 
2278                                       mkQualId(mkCon(findText("PrelBase")),type));
2279          tc = findQualTycon(type);
2280          if (nonNull(tc)) return tc;
2281          ERRMSG(line)
2282              "Undefined class or type constructor \"%s\"",
2283              identToStr(type)
2284          EEND;
2285          return NIL;
2286        }
2287       case AP: 
2288          return ap( conidcellsToTycons(line,fun(type)),
2289                     conidcellsToTycons(line,arg(type)) );
2290       case ZTUP2: /* convert to std pair */
2291          return ap( conidcellsToTycons(line,zfst(type)),
2292                     conidcellsToTycons(line,zsnd(type)) );
2293
2294       case POLYTYPE: 
2295          return mkPolyType ( 
2296                    polySigOf(type),
2297                    conidcellsToTycons(line,monotypeOf(type))
2298                 );
2299          break;
2300       case QUAL:
2301          return pair(QUAL,pair(conidcellsToTycons(line,fst(snd(type))),
2302                                conidcellsToTycons(line,snd(snd(type)))));
2303       case DICTAP: /* :: ap(DICTAP, pair(Class,Type))
2304                       Not sure if this is really the right place to
2305                       convert it to the form Hugs wants, but will do so anyway.
2306                     */
2307          /* return ap(DICTAP, conidcellsToTycons(line, snd(type))); */
2308         {
2309            Class cl   = fst(unap(DICTAP,type));
2310            List  args = snd(unap(DICTAP,type));
2311            return
2312               conidcellsToTycons(line,pair(cl,args));
2313         }
2314       case UNBOXEDTUP:
2315          return ap(UNBOXEDTUP, conidcellsToTycons(line, snd(type)));
2316       case BANG:
2317          return ap(BANG, conidcellsToTycons(line, snd(type)));
2318       default: 
2319          fprintf(stderr, "conidcellsToTycons: unknown stuff %d\n", 
2320                  whatIs(type));
2321          print(type,20);
2322          fprintf(stderr,"\n");
2323          assert(0);
2324    }
2325    assert(0);
2326    return NIL; /* NOTREACHED */
2327 }
2328
2329
2330 /* Find out if a type mentions a type constructor not present in 
2331    the supplied list of qualified tycons.
2332 */
2333 static Bool allTypesKnown ( Type  type, 
2334                             List  aktys /* [QualId] */,
2335                             ConId thisMod )
2336 {
2337    switch (whatIs(type)) {
2338       case NIL:
2339       case OFFSET:
2340       case VARIDCELL:
2341       case TUPLE:
2342          return TRUE;
2343       case AP:
2344          return allTypesKnown(fun(type),aktys,thisMod)
2345                 && allTypesKnown(arg(type),aktys,thisMod);
2346       case ZTUP2:
2347          return allTypesKnown(zfst(type),aktys,thisMod)
2348                 && allTypesKnown(zsnd(type),aktys,thisMod);
2349       case DICTAP: 
2350          return allTypesKnown(unap(DICTAP,type),aktys,thisMod);
2351
2352       case CONIDCELL:
2353         if (textOf(type)==findText("[]"))
2354             /* a hack; magically qualify [] into PrelBase.[] */
2355             type = mkQualId(mkCon(findText("PrelBase")),type); else
2356             type = mkQualId(thisMod,type);
2357          /* fall through */
2358       case QUALIDENT:
2359          if (isNull(qualidIsMember(type,aktys))) goto missing;
2360          return TRUE;
2361       case TYCON:
2362          return TRUE;
2363
2364       default: 
2365          fprintf(stderr, "allTypesKnown: unknown stuff %d\n", whatIs(type));
2366          print(type,10);printf("\n");
2367          internal("allTypesKnown");
2368          return TRUE; /*notreached*/
2369    }
2370   missing:
2371 #  ifdef DEBUG_IFACE
2372    fprintf ( stderr,"allTypesKnown: unknown " ); print(type,10); 
2373    fprintf(stderr,"\n");
2374 #  endif
2375    return FALSE;
2376 }
2377
2378
2379 /* --------------------------------------------------------------------------
2380  * Utilities
2381  *
2382  * None of these do lookups or require that lookups have been resolved
2383  * so they can be performed while reading interfaces.
2384  * ------------------------------------------------------------------------*/
2385
2386 /* tvsToKind :: [((VarId,Kind))] -> Kinds */
2387 static Kinds tvsToKind(tvs)
2388 List tvs; { /* [((VarId,Kind))] */
2389     List  rs;
2390     Kinds r  = STAR;
2391     for (rs=reverse(tvs); nonNull(rs); rs=tl(rs)) {
2392         if (whatIs(hd(rs)) != ZTUP2) internal("tvsToKind(1)");
2393         if (whatIs(zfst(hd(rs))) != VARIDCELL) internal("tvsToKind(2)");
2394         r = ap(zsnd(hd(rs)),r);
2395     }
2396     return r;
2397 }
2398
2399
2400 static Int arityInclDictParams ( Type type )
2401 {
2402    Int arity = 0;
2403    if (isPolyType(type)) type = monotypeOf(type);
2404    
2405    if (whatIs(type) == QUAL)
2406    {
2407       arity += length ( fst(snd(type)) );
2408       type = snd(snd(type));
2409    }
2410    while (isAp(type) && getHead(type)==typeArrow) {
2411       arity++;
2412       type = arg(type);
2413    }
2414    return arity;
2415 }
2416
2417 /* arity of a constructor with this type */
2418 static Int arityFromType(type) 
2419 Type type; {
2420     Int arity = 0;
2421     if (isPolyType(type)) {
2422         type = monotypeOf(type);
2423     }
2424     if (whatIs(type) == QUAL) {
2425         type = snd(snd(type));
2426     }
2427     if (whatIs(type) == EXIST) {
2428         type = snd(snd(type));
2429     }
2430     if (whatIs(type)==RANK2) {
2431         type = snd(snd(type));
2432     }
2433     while (isAp(type) && getHead(type)==typeArrow) {
2434         arity++;
2435         type = arg(type);
2436     }
2437     return arity;
2438 }
2439
2440
2441 /* ifTyvarsIn :: Type -> [VarId]
2442    The returned list has no duplicates -- is a set.
2443 */
2444 static List ifTyvarsIn(type)
2445 Type type; {
2446     List vs = typeVarsIn(type,NIL,NIL,NIL);
2447     List vs2 = vs;
2448     for (; nonNull(vs2); vs2=tl(vs2))
2449        if (whatIs(hd(vs2)) != VARIDCELL)
2450           internal("ifTyvarsIn");
2451     return vs;
2452 }
2453
2454
2455
2456 /* --------------------------------------------------------------------------
2457  * General object symbol query stuff
2458  * ------------------------------------------------------------------------*/
2459
2460 #define EXTERN_SYMS_ALLPLATFORMS     \
2461       Sym(MainRegTable)              \
2462       Sym(stg_gc_enter_1)            \
2463       Sym(stg_gc_noregs)             \
2464       Sym(stg_gc_seq_1)              \
2465       Sym(stg_gc_d1)                 \
2466       Sym(stg_gc_f1)                 \
2467       Sym(stg_chk_0)                 \
2468       Sym(stg_chk_1)                 \
2469       Sym(stg_gen_chk)               \
2470       Sym(stg_exit)                  \
2471       Sym(stg_update_PAP)            \
2472       Sym(stg_error_entry)           \
2473       Sym(__ap_2_upd_info)           \
2474       Sym(__ap_3_upd_info)           \
2475       Sym(__ap_4_upd_info)           \
2476       Sym(__ap_5_upd_info)           \
2477       Sym(__ap_6_upd_info)           \
2478       Sym(__ap_7_upd_info)           \
2479       Sym(__ap_8_upd_info)           \
2480       Sym(__sel_0_upd_info)          \
2481       Sym(__sel_1_upd_info)          \
2482       Sym(__sel_2_upd_info)          \
2483       Sym(__sel_3_upd_info)          \
2484       Sym(__sel_4_upd_info)          \
2485       Sym(__sel_5_upd_info)          \
2486       Sym(__sel_6_upd_info)          \
2487       Sym(__sel_7_upd_info)          \
2488       Sym(__sel_8_upd_info)          \
2489       Sym(__sel_9_upd_info)          \
2490       Sym(__sel_10_upd_info)         \
2491       Sym(__sel_11_upd_info)         \
2492       Sym(__sel_12_upd_info)         \
2493       Sym(Upd_frame_info)            \
2494       Sym(seq_frame_info)            \
2495       Sym(CAF_BLACKHOLE_info)        \
2496       Sym(IND_STATIC_info)           \
2497       Sym(EMPTY_MVAR_info)           \
2498       Sym(MUT_ARR_PTRS_FROZEN_info)  \
2499       Sym(newCAF)                    \
2500       Sym(putMVarzh_fast)            \
2501       Sym(newMVarzh_fast)            \
2502       Sym(takeMVarzh_fast)           \
2503       Sym(catchzh_fast)              \
2504       Sym(raisezh_fast)              \
2505       Sym(delayzh_fast)              \
2506       Sym(yieldzh_fast)              \
2507       Sym(killThreadzh_fast)         \
2508       Sym(waitReadzh_fast)           \
2509       Sym(waitWritezh_fast)          \
2510       Sym(CHARLIKE_closure)          \
2511       Sym(INTLIKE_closure)           \
2512       Sym(suspendThread)             \
2513       Sym(resumeThread)              \
2514       Sym(stackOverflow)             \
2515       Sym(int2Integerzh_fast)        \
2516       Sym(stg_gc_unbx_r1)            \
2517       Sym(ErrorHdrHook)              \
2518       Sym(makeForeignObjzh_fast)     \
2519       Sym(__encodeDouble)            \
2520       Sym(decodeDoublezh_fast)       \
2521       Sym(isDoubleNaN)               \
2522       Sym(isDoubleInfinite)          \
2523       Sym(isDoubleDenormalized)      \
2524       Sym(isDoubleNegativeZero)      \
2525       Sym(__encodeFloat)             \
2526       Sym(decodeFloatzh_fast)        \
2527       Sym(isFloatNaN)                \
2528       Sym(isFloatInfinite)           \
2529       Sym(isFloatDenormalized)       \
2530       Sym(isFloatNegativeZero)       \
2531       Sym(__int_encodeFloat)         \
2532       Sym(__int_encodeDouble)        \
2533       Sym(mpz_cmp_si)                \
2534       Sym(mpz_cmp)                   \
2535       Sym(__mpn_gcd_1)               \
2536       Sym(gcdIntegerzh_fast)         \
2537       Sym(newArrayzh_fast)           \
2538       Sym(unsafeThawArrayzh_fast)    \
2539       Sym(newDoubleArrayzh_fast)     \
2540       Sym(newFloatArrayzh_fast)      \
2541       Sym(newAddrArrayzh_fast)       \
2542       Sym(newWordArrayzh_fast)       \
2543       Sym(newIntArrayzh_fast)        \
2544       Sym(newCharArrayzh_fast)       \
2545       Sym(newMutVarzh_fast)          \
2546       Sym(quotRemIntegerzh_fast)     \
2547       Sym(quotIntegerzh_fast)        \
2548       Sym(remIntegerzh_fast)         \
2549       Sym(divExactIntegerzh_fast)    \
2550       Sym(divModIntegerzh_fast)      \
2551       Sym(timesIntegerzh_fast)       \
2552       Sym(minusIntegerzh_fast)       \
2553       Sym(plusIntegerzh_fast)        \
2554       Sym(addr2Integerzh_fast)       \
2555       Sym(mkWeakzh_fast)             \
2556       Sym(prog_argv)                 \
2557       Sym(prog_argc)                 \
2558       Sym(resetNonBlockingFd)        \
2559       Sym(getStablePtr)              \
2560       Sym(stable_ptr_table)          \
2561       Sym(createAdjThunk)            \
2562       Sym(shutdownHaskellAndExit)    \
2563       Sym(stg_enterStackTop)         \
2564       Sym(CAF_UNENTERED_entry)       \
2565       Sym(stg_yield_to_Hugs)         \
2566       Sym(StgReturn)                 \
2567       Sym(init_stack)                \
2568                                      \
2569       /* needed by libHS_cbits */    \
2570       SymX(malloc)                   \
2571       SymX(close)                    \
2572       Sym(mkdir)                     \
2573       SymX(close)                    \
2574       Sym(opendir)                   \
2575       Sym(closedir)                  \
2576       Sym(readdir)                   \
2577       Sym(tcgetattr)                 \
2578       Sym(tcsetattr)                 \
2579       SymX(isatty)                   \
2580       SymX(read)                     \
2581       SymX(lseek)                    \
2582       SymX(write)                    \
2583       Sym(getrusage)                 \
2584       Sym(gettimeofday)              \
2585       SymX(realloc)                  \
2586       SymX(getcwd)                   \
2587       SymX(free)                     \
2588       SymX(strcpy)                   \
2589       Sym(fcntl)                     \
2590       SymX(fprintf)                  \
2591       SymX(exit)                     \
2592       Sym(open)                      \
2593       SymX(unlink)                   \
2594       SymX(memcpy)                   \
2595       SymX(memchr)                   \
2596       SymX(rmdir)                    \
2597       SymX(rename)                   \
2598       SymX(chdir)                    \
2599       SymX(execl)                    \
2600       Sym(waitpid)                   \
2601       SymX(getenv)
2602
2603 #define EXTERN_SYMS_cygwin32         \
2604       SymX(GetCurrentProcess)        \
2605       SymX(GetProcessTimes)          \
2606       Sym(__udivdi3)                 \
2607       SymX(bzero)                    \
2608       Sym(select)                    \
2609       SymX(_impure_ptr)              \
2610       Sym(lstat)                     \
2611       Sym(setmode)                   \
2612       SymX(system)                   \
2613       SymX(sleep)                    \
2614       Sym(__imp__tzname)             \
2615       Sym(__imp__timezone)           \
2616       Sym(tzset)                     \
2617       Sym(log)                       \
2618       Sym(exp)                       \
2619       Sym(sqrt)                      \
2620       Sym(sin)                       \
2621       Sym(cos)                       \
2622       Sym(tan)                       \
2623       Sym(asin)                      \
2624       Sym(acos)                      \
2625       Sym(atan)                      \
2626       Sym(sinh)                      \
2627       Sym(cosh)                      \
2628       Sym(tanh)                      \
2629       Sym(pow)                       \
2630       Sym(__errno)                   \
2631       Sym(stat)                      \
2632       Sym(fstat)
2633
2634 #define EXTERN_SYMS_linux            \
2635       Sym(__errno_location)          \
2636       Sym(__xstat)                   \
2637       Sym(__fxstat)                  \
2638       Sym(__lxstat)                  \
2639       SymX(select)                   \
2640       SymX(stderr)                   \
2641       SymX(vfork)                    \
2642       SymX(_exit)                    \
2643       SymX(tzname)                   \
2644       SymX(localtime)                \
2645       SymX(strftime)                 \
2646       SymX(timezone)                 \
2647       SymX(mktime)                   \
2648       SymX(gmtime)                   \
2649
2650
2651
2652 #if defined(linux_TARGET_OS)
2653 #define EXTERN_SYMS_THISPLATFORM EXTERN_SYMS_linux
2654 #endif
2655
2656 #if defined(solaris2_TARGET_OS)
2657 #define EXTERN_SYMS_THISPLATFORM EXTERN_SYMS_solaris2
2658 #endif
2659
2660 #if defined(cygwin32_TARGET_OS)
2661 #define EXTERN_SYMS_THISPLATFORM EXTERN_SYMS_cygwin32
2662 #endif
2663
2664
2665
2666
2667 /* entirely bogus claims about types of these symbols */
2668 #define Sym(vvv)  extern void (vvv);
2669 #define SymX(vvv) /**/
2670 EXTERN_SYMS_ALLPLATFORMS
2671 EXTERN_SYMS_THISPLATFORM
2672 #undef Sym
2673 #undef SymX
2674
2675
2676 #define Sym(vvv)  { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
2677                     &(vvv) },
2678 #define SymX(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
2679                     &(vvv) },
2680 OSym rtsTab[] 
2681    = { 
2682        EXTERN_SYMS_ALLPLATFORMS
2683        EXTERN_SYMS_THISPLATFORM
2684        {0,0} 
2685      };
2686 #undef Sym
2687 #undef SymX
2688
2689
2690 void init_stack;
2691
2692
2693 /* A kludge to assist Win32 debugging. */
2694 char* nameFromStaticOPtr ( void* ptr )
2695 {
2696    int k;
2697    for (k = 0; rtsTab[k].nm; k++)
2698       if (ptr == rtsTab[k].ad)
2699          return rtsTab[k].nm;
2700    return NULL;
2701 }
2702
2703
2704 void* lookupObjName ( char* nm )
2705 {
2706    int    k;
2707    char*  pp;
2708    void*  a;
2709    Text   t;
2710    Module m;
2711    char   nm2[200];
2712    int    first_real_char;
2713
2714    nm2[199] = 0;
2715    strncpy(nm2,nm,200);
2716
2717    /*  first see if it's an RTS name */
2718    for (k = 0; rtsTab[k].nm; k++)
2719       if (0==strcmp(nm2,rtsTab[k].nm))
2720          return rtsTab[k].ad;
2721
2722    /* perhaps an extra-symbol ? */
2723    a = lookupOExtraTabName ( nm );
2724    if (a) return a;
2725
2726 #  if LEADING_UNDERSCORE
2727    first_real_char = 1;
2728 #  else
2729    first_real_char = 0;
2730 #  endif
2731
2732    /* Maybe it's an __init_Module thing? */
2733    if (strlen(nm2+first_real_char) > 7
2734        && strncmp(nm2+first_real_char, "__init_", 7)==0) {
2735       t = unZcodeThenFindText(nm2+first_real_char+7);
2736       if (t == findText("PrelGHC")) return (4+NULL); /* kludge */
2737       m = findModule(t);
2738       if (isNull(m)) goto not_found;
2739       a = lookupOTabName ( m, nm );
2740       if (a) return a;
2741       goto not_found;
2742    }
2743
2744    /* if not an RTS name, look in the 
2745       relevant module's object symbol table
2746    */
2747    pp = strchr(nm2+first_real_char, '_');
2748    if (!pp || !isupper(nm2[first_real_char])) goto not_found;
2749    *pp = 0;
2750    t = unZcodeThenFindText(nm2+first_real_char);
2751    m = findModule(t);
2752    if (isNull(m)) goto not_found;
2753
2754    a = lookupOTabName ( m, nm );  /* RATIONALISE */
2755    if (a) return a;
2756
2757   not_found:
2758    fprintf ( stderr, 
2759              "lookupObjName: can't resolve name `%s'\n", 
2760              nm );
2761    assert(4-4);
2762    return NULL;
2763 }
2764
2765
2766 int is_dynamically_loaded_code_or_rodata_ptr ( char* p )
2767 {
2768    OSectionKind sk = lookupSection(p);
2769    assert (sk != HUGS_SECTIONKIND_NOINFOAVAIL);
2770    return (sk == HUGS_SECTIONKIND_CODE_OR_RODATA);
2771 }
2772
2773
2774 int is_dynamically_loaded_rwdata_ptr ( char* p )
2775 {
2776    OSectionKind sk = lookupSection(p);
2777    assert (sk != HUGS_SECTIONKIND_NOINFOAVAIL);
2778    return (sk == HUGS_SECTIONKIND_RWDATA);
2779 }
2780
2781
2782 int is_not_dynamically_loaded_ptr ( char* p )
2783 {
2784    OSectionKind sk = lookupSection(p);
2785    assert (sk != HUGS_SECTIONKIND_NOINFOAVAIL);
2786    return (sk == HUGS_SECTIONKIND_OTHER);
2787 }
2788
2789
2790 /* --------------------------------------------------------------------------
2791  * Control:
2792  * ------------------------------------------------------------------------*/
2793
2794 Void interface(what)
2795 Int what; {
2796     switch (what) {
2797        case POSTPREL: break;
2798
2799        case PREPREL:
2800        case RESET: 
2801           ifaces_outstanding  = NIL;
2802           break;
2803        case MARK: 
2804           mark(ifaces_outstanding);
2805           break;
2806     }
2807 }
2808
2809 /*-------------------------------------------------------------------------*/