[project @ 2000-05-12 13:34:06 by sewardj]
[ghc-hetmet.git] / ghc / interpreter / interface.c
index 817f345..0da2db3 100644 (file)
@@ -1,4 +1,4 @@
-/* -*- mode: hugs-c; -*- */
+
 /* --------------------------------------------------------------------------
  * GHC interface file processing for Hugs
  *
@@ -7,40 +7,24 @@
  * Hugs version 1.4, December 1997
  *
  * $RCSfile: interface.c,v $
- * $Revision: 1.2 $
- * $Date: 1998/12/02 13:22:15 $
+ * $Revision: 1.58 $
+ * $Date: 2000/05/12 13:34:07 $
  * ------------------------------------------------------------------------*/
 
-/* ToDo:
- * o use Z encoding
- * o use vectored CONSTR_entry when appropriate
- * o generate export list
- *
- * Needs GHC changes to generate member selectors,
- * superclass selectors, etc
- * o instance decls
- * o dictionary constructors ?
- *
- * o Get Hugs/GHC to agree on what interface files look like.
- * o figure out how to replace the Hugs Prelude with the GHC Prelude
- */
-
-#include "prelude.h"
+#include "hugsbasictypes.h"
 #include "storage.h"
 #include "connect.h"
-#include "static.h"
 #include "errors.h"
-#include "link.h"
-#include "modules.h"
-#include "machdep.h"   /* for Time                 */
-#include "input.h"     /* for parseInterface      */
-#include "type.h"      /* for offsetTyVarsIn      */
-#include "stg.h"       /* for wrapping GHC objects */
-#include "Assembler.h" /* for wrapping GHC objects */
-#include "interface.h"
-#include "dynamic.h"
+#include "object.h"
+
+#include "Rts.h"       /* to make StgPtr visible in Assembler.h */
+#include "Assembler.h"  /* for wrapping GHC objects */
+
+/*#define DEBUG_IFACE*/
+#define VERBOSE FALSE
 
 /* --------------------------------------------------------------------------
+ * (This comment is now out of date.  JRS, 991216).
  * The "addGHC*" functions act as "impedence matchers" between GHC
  * interface files and Hugs.  Their main job is to convert abstract
  * syntax trees into Hugs' internal representations.
  *
  * ------------------------------------------------------------------------*/
 
-/* --------------------------------------------------------------------------
- * local variables:
- * ------------------------------------------------------------------------*/
 
-static List ghcVarDecls;     
-static List ghcConDecls;     
-static List ghcSynonymDecls; 
-static List ghcClassDecls; 
-static List ghcInstanceDecls;
+/*
+New comment, 991216, explaining roughly how it all works.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Interfaces can contain references to unboxed types, and these need to
+be handled carefully.  The following is a summary of how the interface
+loader now works.  It is applied to groups of interfaces simultaneously,
+viz, the entire Prelude at once:
+
+0.  Parse interfaces, chasing imports until a complete
+    strongly-connected-component of ifaces has been parsed.
+    All interfaces in this scc are processed together, in
+    steps 1 .. 8 below.
+
+1.  Throw away any entity not mentioned in the export lists.
+
+2.  Delete type (not data or newtype) definitions which refer to 
+    unknown types in their right hand sides.  Because Hugs doesn't
+    know of any unboxed types, this has the side effect of removing
+    all type defns referring to unboxed types.  Repeat step 2 until
+    a fixed point is reached.
+
+3.  Make abstract all data/newtype defns which refer to an unknown
+    type.  eg, data Word = MkW Word# becomes data Word, because 
+    Word# is unknown.  Hugs is happy to know about abstract boxed
+    Words, but not about Word#s.
+
+4.  Step 2 could delete types referred to by values, instances and
+    classes.  So filter all entities, and delete those referring to
+    unknown types _or_ classes.  This could cause other entities
+    to become invalid, so iterate step 4 to a fixed point.
+
+    After step 4, the interfaces no longer contain anything
+    unpalatable to Hugs.
+
+5.  Steps 1-4 operate purely on the iface syntax trees.  We now start
+    creating symbol table entries.  First, create a module table
+    entry for each interface, and locate and read in the corresponding
+    object file.  This is done by the startGHCModule function.
+
+6.  Traverse all interfaces.  For each entity, create an entry in
+    the name, tycon, class or instance table, and fill in relevant
+    fields, but do not attempt to link tycon/class/instance/name uses
+    to their symbol table entries.  This is done by the startGHC*
+    functions.
+
+7.  Revisit all symbol table entries created in step 6.  We should
+    now be able to replace all references to tycons/classes/instances/
+    names with the relevant symbol table entries.  This is done by
+    the finishGHC* functions.
+
+8.  Traverse all interfaces.  For each iface, examine the export lists
+    and use it to build export lists in the module table.  Do the
+    implicit 'import Prelude' thing if necessary.  Finally, resolve
+    references in the object code for this module.  This is done
+    by the finishGHCModule function.
+*/
 
 /* --------------------------------------------------------------------------
  * local function prototypes:
  * ------------------------------------------------------------------------*/
 
-static List local addGHCConstrs Args((Int,List,List));
-static Name local addGHCSel     Args((Int,Pair,List));
-static Name local addGHCConstr  Args((Int,Int,Triple));
-
-
-static Void  local finishGHCVar      Args((Name));     
-static Void  local finishGHCCon      Args((Name));     
-static Void  local finishGHCSynonym  Args((Tycon)); 
-static Void  local finishGHCClass    Args((Class)); 
-static Void  local finishGHCInstance Args((Inst));
-
-static Name  local fixupSel              Args((Int,Pair,List));
-static Name  local fixupConstr           Args((Int,Int,Triple));
-static Name  local fixupMember           Args((Int,Int,Pair));
-static List  local fixupMembers          Args((Int,List));
-static Type  local fixupTypeVar          Args((Int,List,Text));
-static Class local fixupClass            Args((Int,Text));
-static Cell  local fixupPred             Args((Int,List,Pair));
-static List  local fixupContext          Args((Int,List,List));
-static Type  local fixupType             Args((Int,List,Type));
-static Type  local fixupConType          Args((Int,Type));
-
-static Void  local bindNameToClosure     Args((Name,AsmClosure));
-static Kinds local tvsToKind             Args((List));
-static Int   local arityFromType         Args((Type));
+static Void startGHCValue       ( Int,VarId,Type );
+static Void finishGHCValue      ( VarId );
+
+static Void startGHCSynonym     ( Int,Cell,List,Type );
+static Void finishGHCSynonym    ( Tycon ); 
+
+static Void  startGHCClass      ( Int,List,Cell,List,List );
+static Class finishGHCClass     ( Class ); 
+
+static Inst startGHCInstance    ( Int,List,Pair,VarId );
+static Void finishGHCInstance   ( Inst );
+
+static Void startGHCImports     ( ConId,List );
+static Void finishGHCImports    ( ConId,List );
+
+static Void startGHCExports     ( ConId,List );
+static Void finishGHCExports    ( ConId,List );
+
+static Void finishGHCFixdecl    ( Cell prec, Cell assoc, ConVarId name );
+
+static Void finishGHCModule     ( Cell );
+static Void startGHCModule      ( Text );
+
+static Void startGHCDataDecl    ( Int,List,Cell,List,List );
+static List finishGHCDataDecl   ( ConId tyc );
+/* Supporting stuff for {start|finish}GHCDataDecl */
+static List startGHCConstrs     ( Int,List,List );
+static Name startGHCSel         ( Int,Pair );
+static Name startGHCConstr      ( Int,Int,Triple );
+
+static Void startGHCNewType     ( Int,List,Cell,List,Cell );
+static Void finishGHCNewType    ( ConId tyc );
+
+
+
+static Kinds tvsToKind             ( List );
+static Int   arityFromType         ( Type );
+static Int   arityInclDictParams   ( Type );
+static Bool  allTypesKnown         ( Type type, 
+                                     List aktys /* [QualId] */,
+                                     ConId thisMod );
                                          
-static AsmClosure local lookupGHCClosure Args((Module,Text));
+static List  ifTyvarsIn            ( Type );
+static Type  tvsToOffsets          ( Int,Type,List );
+static Type  conidcellsToTycons    ( Int,Type );
+
+
+
+
 
 /* --------------------------------------------------------------------------
- * code:
+ * Top-level interface processing
  * ------------------------------------------------------------------------*/
 
-static List interfaces; /* Interface files that haven't been loaded yet */
+/* getIEntityName :: I_IMPORT..I_VALUE -> ConVarId | NIL */
+static ConVarId getIEntityName ( Cell c )
+{
+   switch (whatIs(c)) {
+      case I_IMPORT:     return NIL;
+      case I_INSTIMPORT: return NIL;
+      case I_EXPORT:     return NIL;
+      case I_FIXDECL:    return zthd3(unap(I_FIXDECL,c));
+      case I_INSTANCE:   return NIL;
+      case I_TYPE:       return zsel24(unap(I_TYPE,c));
+      case I_DATA:       return zsel35(unap(I_DATA,c));
+      case I_NEWTYPE:    return zsel35(unap(I_NEWTYPE,c));
+      case I_CLASS:      return zsel35(unap(I_CLASS,c));
+      case I_VALUE:      return zsnd3(unap(I_VALUE,c));
+      default:           internal("getIEntityName");
+   }
+}
+
 
-Void loadInterface(String fname)
+/* Filter the contents of an interface, using the supplied predicate.
+   For flexibility, the predicate is passed as a second arg the value
+   extraArgs.  This is a hack to get round the lack of partial applications
+   in C.  Pred should not have any side effects.  The dumpaction param
+   gives us the chance to print a message or some such for dumped items.
+   When a named entity is deleted, filterInterface also deletes the name
+   in the export lists.
+*/
+static Cell filterInterface ( Cell root, 
+                              Bool (*pred)(Cell,Cell), 
+                              Cell extraArgs,
+                              Void (*dumpAction)(Cell) )
 {
-    ghcVarDecls      = NIL;
-    ghcConDecls      = NIL;
-    ghcSynonymDecls  = NIL;
-    ghcClassDecls    = NIL;
-    ghcInstanceDecls = NIL;
+   List tops;
+   Cell iface       = unap(I_INTERFACE,root);
+   List tops2       = NIL;
+   List deleted_ids = NIL; /* :: [ConVarId] */
+
+   for (tops = zsnd(iface); nonNull(tops); tops=tl(tops)) {
+      if (pred(hd(tops),extraArgs)) {
+         tops2 = cons( hd(tops), tops2 );
+      } else {
+         ConVarId deleted_id = getIEntityName ( hd(tops) );
+         if (nonNull(deleted_id))
+            deleted_ids = cons ( deleted_id, deleted_ids );
+         if (dumpAction)
+            dumpAction ( hd(tops) );
+      }
+   }
+   tops2 = reverse(tops2);
+
+   /* Clean up the export list now. */
+   for (tops=tops2; nonNull(tops); tops=tl(tops)) {
+      if (whatIs(hd(tops))==I_EXPORT) {
+         Cell exdecl  = unap(I_EXPORT,hd(tops));
+         List exlist  = zsnd(exdecl);
+         List exlist2 = NIL;
+         for (; nonNull(exlist); exlist=tl(exlist)) {
+            Cell ex       = hd(exlist);
+            ConVarId exid = isZPair(ex) ? zfst(ex) : ex;
+            assert (isCon(exid) || isVar(exid));
+            if (!varIsMember(textOf(exid),deleted_ids))
+               exlist2 = cons(ex, exlist2);
+        }
+         hd(tops) = ap(I_EXPORT,zpair(zfst(exdecl),exlist2));
+      }
+   }
+
+   return ap(I_INTERFACE, zpair(zfst(iface),tops2));
+}
 
-    /* Note: interfaces is added to by addGHCImport which is called by
-     * parseInterface so each time round the loop we remove the 
-     * current interface from the list before calling parseInterface again.
-     */
-    interfaces=singleton(mkCon(findText(fname)));
-    while (nonNull(interfaces)) {
-        String fname = textToStr(textOf(hd(interfaces)));
-        Time timeStamp; /* not used */
-        Long fileSize;
-        getFileInfo(fname, &timeStamp, &fileSize);
-        interfaces=tl(interfaces);
-        parseInterface(fname,fileSize);
-    }
-
-    /* the order of these doesn't matter
-     * (ToDo: unless synonyms have to be eliminated??)
-     */
-    mapProc(finishGHCVar,      ghcVarDecls);     
-    mapProc(finishGHCCon,      ghcConDecls);     
-    mapProc(finishGHCSynonym,  ghcSynonymDecls); 
-    mapProc(finishGHCClass,    ghcClassDecls); 
-    mapProc(finishGHCInstance, ghcInstanceDecls);
-    ghcVarDecls      = NIL;
-    ghcConDecls      = NIL;
-    ghcSynonymDecls  = NIL;
-    ghcClassDecls    = NIL;
-    ghcInstanceDecls = NIL;
-}
-
-Void openGHCIface(t)
-Text t; {
-    Module m = findModule(t);
-    if (isNull(m)) {
-        m = newModule(t);
-    } else if (m != modulePreludeHugs) {
-        ERRMSG(0) "Module \"%s\" already loaded", textToStr(t)
-        EEND;
+
+List /* of CONID */ getInterfaceImports ( Cell iface )
+{
+    List  tops;
+    List  imports = NIL;
+
+    for (tops = zsnd(unap(I_INTERFACE,iface)); nonNull(tops); tops=tl(tops))
+       if (whatIs(hd(tops)) == I_IMPORT) {
+          ZPair imp_decl = unap(I_IMPORT,hd(tops));
+          ConId m_to_imp = zfst(imp_decl);
+          if (textOf(m_to_imp) != findText("PrelGHC")) {
+             imports = cons(m_to_imp,imports);
+#            ifdef DEBUG_IFACE
+             fprintf(stderr, "add iface %s\n", 
+                     textToStr(textOf(m_to_imp)));
+#            endif
+          }
+       }
+    return imports;
+}
+
+
+/* getExportDeclsInIFace :: I_INTERFACE -> [I_EXPORT] */
+static List getExportDeclsInIFace ( Cell root )
+{
+   Cell  iface   = unap(I_INTERFACE,root);
+   List  decls   = zsnd(iface);
+   List  exports = NIL;
+   List  ds;
+   for (ds=decls; nonNull(ds); ds=tl(ds))
+      if (whatIs(hd(ds))==I_EXPORT)
+         exports = cons(hd(ds), exports);
+   return exports;
+}
+
+
+/* Does t start with "$dm" ? */
+static Bool isIfaceDefaultMethodName ( Text t )
+{
+   String s = textToStr(t);
+   return (s && s[0]=='$' && s[1]=='d' && s[2]=='m' && s[3]);
+}
+      
+
+static Bool isExportedIFaceEntity ( Cell ife, List exlist_list )
+{
+   /* ife         :: I_IMPORT..I_VALUE                      */
+   /* exlist_list :: [[ ConVarId | ((ConId, [ConVarId])) ]] */
+   Text   tnm;
+   List   exlist;
+   List   t;
+   String s;
+
+   ConVarId ife_id = getIEntityName ( ife );
+
+   if (isNull(ife_id)) return TRUE;
+
+   tnm = textOf(ife_id);
+
+   /* Don't junk default methods, even tho the export list doesn't
+      mention them.
+   */
+   if (isIfaceDefaultMethodName(tnm)) goto retain;
+
+   /* for each export list ... */
+   for (; nonNull(exlist_list); exlist_list=tl(exlist_list)) {
+      exlist = hd(exlist_list);
+
+      /* for each entity in an export list ... */
+      for (t=exlist; nonNull(t); t=tl(t)) {
+         if (isZPair(hd(t))) {
+            /* A pair, which means an export entry 
+               of the form ClassName(foo,bar). */
+            List subents = cons(zfst(hd(t)),zsnd(hd(t)));
+            for (; nonNull(subents); subents=tl(subents))
+               if (textOf(hd(subents)) == tnm) goto retain;
+         } else {
+            /* Single name in the list. */
+            if (textOf(hd(t)) == tnm) goto retain;
+         }
+      }
+
+   }
+#  ifdef DEBUG_IFACE
+   fprintf ( stderr, "     dump %s\n", textToStr(tnm) );
+#  endif
+   return FALSE;
+
+ retain:
+#  ifdef DEBUG_IFACE
+   fprintf ( stderr, "   retain %s\n", textToStr(tnm) );
+#  endif
+   return TRUE;
+}
+
+
+static Bool isExportedAbstractly ( ConId ife_id, List exlist_list )
+{
+   /* ife_id      :: ConId                                  */
+   /* exlist_list :: [[ ConVarId | ((ConId, [ConVarId])) ]] */
+   Text  tnm;
+   List  exlist;
+   List  t;
+
+   assert (isCon(ife_id));
+   tnm = textOf(ife_id);
+
+   /* for each export list ... */
+   for (; nonNull(exlist_list); exlist_list=tl(exlist_list)) {
+      exlist = hd(exlist_list);
+
+      /* for each entity in an export list ... */
+      for (t=exlist; nonNull(t); t=tl(t)) {
+         if (isZPair(hd(t))) {
+            /* A pair, which means an export entry 
+               of the form ClassName(foo,bar). */
+            if (textOf(zfst(hd(t))) == tnm) return FALSE;
+         } else {
+            if (textOf(hd(t)) == tnm) return TRUE;
+         }
+      }
+   }
+   internal("isExportedAbstractly");
+   return FALSE; /*notreached*/
+}
+
+
+/* Remove entities not mentioned in any of the export lists. */
+static Cell deleteUnexportedIFaceEntities ( Cell root )
+{
+   Cell  iface       = unap(I_INTERFACE,root);
+   ConId iname       = zfst(iface);
+   List  decls       = zsnd(iface);
+   List  decls2      = NIL;
+   List  exlist_list = NIL;
+   List  t;
+
+#  ifdef DEBUG_IFACE
+   fprintf(stderr, "\ncleanIFace: %s\n", textToStr(textOf(iname)));
+#  endif
+
+   exlist_list = getExportDeclsInIFace ( root );
+   /* exlist_list :: [I_EXPORT] */
+   
+   for (t=exlist_list; nonNull(t); t=tl(t))
+      hd(t) = zsnd(unap(I_EXPORT,hd(t)));
+   /* exlist_list :: [[ ConVarId | ((ConId, [ConVarId])) ]] */
+
+#if 0
+   if (isNull(exlist_list)) {
+      ERRMSG(0) "Can't find any export lists in interface file"
+      EEND;
+   }
+#endif
+
+   return filterInterface ( root, isExportedIFaceEntity, 
+                            exlist_list, NULL );
+}
+
+
+/* addTyconsAndClassesFromIFace :: I_INTERFACE -> [QualId] -> [QualId] */
+static List addTyconsAndClassesFromIFace ( Cell root, List aktys )
+{
+   Cell iface = unap(I_INTERFACE,root);
+   Text mname = textOf(zfst(iface));
+   List defns = zsnd(iface);
+   for (; nonNull(defns); defns = tl(defns)) {
+      Cell defn = hd(defns);
+      Cell what = whatIs(defn);
+      if (what==I_TYPE || what==I_DATA 
+          || what==I_NEWTYPE || what==I_CLASS) {
+         QualId q = mkQCon ( mname, textOf(getIEntityName(defn)) );
+         if (!qualidIsMember ( q, aktys ))
+            aktys = cons ( q, aktys );
+      }
+   }
+   return aktys;
+}
+
+
+static Void ifentityAllTypesKnown_dumpmsg ( Cell entity )
+{
+   ConVarId id = getIEntityName ( entity );
+#  ifdef DEBUG_IFACE
+   fprintf ( stderr, 
+             "dumping %s because of unknown type(s)\n",
+             isNull(id) ? "(nameless entity?!)" : textToStr(textOf(id)) );
+#  endif
+}
+
+
+/* ifentityAllTypesKnown :: I_IMPORT..I_VALUE -> (([QualId], ConId)) -> Bool */
+/* mod is the current module being processed -- so we can qualify unqual'd
+   names.  Strange calling convention for aktys and mod is so we can call this
+   from filterInterface.
+*/
+static Bool ifentityAllTypesKnown ( Cell entity, ZPair aktys_mod )
+{
+   List  t, u;
+   List  aktys = zfst ( aktys_mod );
+   ConId mod   = zsnd ( aktys_mod );
+   switch (whatIs(entity)) {
+      case I_IMPORT:
+      case I_INSTIMPORT:
+      case I_EXPORT:
+      case I_FIXDECL: 
+         return TRUE;
+      case I_INSTANCE: {
+         Cell inst = unap(I_INSTANCE,entity);
+         List ctx  = zsel25 ( inst ); /* :: [((QConId,VarId))] */
+         Type cls  = zsel35 ( inst ); /* :: Type */
+         for (t = ctx; nonNull(t); t=tl(t))
+            if (!allTypesKnown(zfst(hd(t)),aktys,mod)) return FALSE;
+         if (!allTypesKnown(cls, aktys,mod)) return FALSE;
+         return TRUE;
+      }
+      case I_TYPE:
+         return allTypesKnown( zsel44(unap(I_TYPE,entity)), aktys,mod );
+      case I_DATA: {
+         Cell data    = unap(I_DATA,entity);
+         List ctx     = zsel25 ( data ); /* :: [((QConId,VarId))] */
+         List constrs = zsel55 ( data ); /* :: [ ((ConId, [((Type,VarId,Int))] )) ] */
+         for (t = ctx; nonNull(t); t=tl(t))
+            if (!allTypesKnown(zfst(hd(t)),aktys,mod)) return FALSE;
+         for (t = constrs; nonNull(t); t=tl(t))
+            for (u = zsnd(hd(t)); nonNull(u); u=tl(u))
+               if (!allTypesKnown(zfst3(hd(u)),aktys,mod)) return FALSE;
+         return TRUE;
+      }
+      case I_NEWTYPE: {
+         Cell  newty  = unap(I_NEWTYPE,entity);
+         List  ctx    = zsel25(newty);    /* :: [((QConId,VarId))] */
+         ZPair constr = zsel55 ( newty ); /* :: ((ConId,Type)) */
+         for (t = ctx; nonNull(t); t=tl(t))
+            if (!allTypesKnown(zfst(hd(t)),aktys,mod)) return FALSE;
+         if (nonNull(constr)
+             && !allTypesKnown(zsnd(constr),aktys,mod)) return FALSE;
+         return TRUE;
+      }
+      case I_CLASS: {
+         Cell klass = unap(I_CLASS,entity);
+         List ctx   = zsel25(klass);  /* :: [((QConId,VarId))] */
+         List sigs  = zsel55(klass);  /* :: [((VarId,Type))] */
+         for (t = ctx; nonNull(t); t=tl(t))
+            if (!allTypesKnown(zfst(hd(t)),aktys,mod)) return FALSE;
+         for (t = sigs; nonNull(t); t=tl(t)) 
+            if (!allTypesKnown(zsnd(hd(t)),aktys,mod)) return FALSE;
+         return TRUE;
+      }
+      case I_VALUE: 
+         return allTypesKnown( zthd3(unap(I_VALUE,entity)), aktys,mod );
+      default: 
+         internal("ifentityAllTypesKnown");
+   }
+}
+
+
+/* ifTypeDoesntRefUnknownTycon :: I_IMPORT..I_VALUE -> (([QualId], ConId)) -> Bool */
+/* mod is the current module being processed -- so we can qualify unqual'd
+   names.  Strange calling convention for aktys and mod is so we can call this
+   from filterInterface.
+*/
+static Bool ifTypeDoesntRefUnknownTycon ( Cell entity, ZPair aktys_mod )
+{
+   List  t, u;
+   List  aktys = zfst ( aktys_mod );
+   ConId mod   = zsnd ( aktys_mod );
+   if (whatIs(entity) != I_TYPE) {
+      return TRUE;
+   } else {
+      return allTypesKnown( zsel44(unap(I_TYPE,entity)), aktys,mod );
+   }
+}
+
+
+static Void ifTypeDoesntRefUnknownTycon_dumpmsg ( Cell entity )
+{
+   ConVarId id = getIEntityName ( entity );
+   assert (whatIs(entity)==I_TYPE);
+   assert (isCon(id));
+#  ifdef DEBUG_IFACE
+   fprintf ( stderr, 
+             "dumping type %s because of unknown tycon(s)\n",
+             textToStr(textOf(id)) );
+#  endif
+}
+
+
+/* abstractifyExport :: I_EXPORT -> ConId -> I_EXPORT
+*/
+static List abstractifyExDecl ( Cell root, ConId toabs )
+{
+   ZPair exdecl = unap(I_EXPORT,root);
+   List  exlist = zsnd(exdecl);
+   List  res    = NIL;
+   for (; nonNull(exlist); exlist = tl(exlist)) {
+      if (isZPair(hd(exlist)) 
+          && textOf(toabs) == textOf(zfst(hd(exlist)))) {
+         /* it's toabs, exported non-abstractly */
+         res = cons ( zfst(hd(exlist)), res );
+      } else {
+         res = cons ( hd(exlist), res );
+      }
+   }
+   return ap(I_EXPORT,zpair(zfst(exdecl),reverse(res)));
+}
+
+
+static Void ppModule ( Text modt )
+{
+#  ifdef DEBUG_IFACE
+   fflush(stderr); fflush(stdout);
+   fprintf(stderr, "---------------- MODULE %s ----------------\n", 
+                   textToStr(modt) );
+#  endif
+}
+
+
+static void* ifFindItblFor ( Name n )
+{
+   /* n is a constructor for which we want to find the GHC info table.
+      First look for a _con_info symbol.  If that doesn't exist, _and_
+      this is a nullary constructor, then it's safe to look for the
+      _static_info symbol instead.
+   */
+   void* p;
+   char  buf[1000];
+   Text  t;
+
+   sprintf ( buf, MAYBE_LEADING_UNDERSCORE_STR("%s_%s_con_info"), 
+                  textToStr( module(name(n).mod).text ),
+                  textToStr( name(n).text ) );
+   t = enZcodeThenFindText(buf);
+   p = lookupOTabName ( name(n).mod, textToStr(t) );
+
+   if (p) return p;
+
+   if (name(n).arity == 0) {
+      sprintf ( buf, MAYBE_LEADING_UNDERSCORE_STR("%s_%s_static_info"), 
+                     textToStr( module(name(n).mod).text ),
+                     textToStr( name(n).text ) );
+      t = enZcodeThenFindText(buf);
+      p = lookupOTabName ( name(n).mod, textToStr(t) );
+      if (p) return p;
+   }
+
+   ERRMSG(0) "Can't find info table %s", textToStr(t)
+   EEND;
+}
+
+
+void ifLinkConstrItbl ( Name n )
+{
+   /* name(n) is either a constructor or a field name.  
+      If the latter, ignore it.  If it is a non-nullary constructor,
+      find its info table in the object code.  If it's nullary,
+      we can skip the info table, since all accesses will go via
+      the _closure label.
+   */
+   if (islower(textToStr(name(n).text)[0])) return;
+   if (name(n).arity == 0) return;
+   name(n).itbl = ifFindItblFor(n);
+}
+
+
+static void ifSetClassDefaultsAndDCon ( Class c )
+{
+   char   buf[100];
+   char   buf2[1000];
+   String s;
+   Name   n;
+   Text   t;
+   void*  p;
+   List   defs;   /* :: [Name] */
+   List   mems;   /* :: [Name] */
+   Module m;
+   assert(isNull(cclass(c).defaults));
+
+   /* Create the defaults list by more-or-less cloning the members list. */   
+   defs = NIL;
+   for (mems=cclass(c).members; nonNull(mems); mems=tl(mems)) {
+      strcpy(buf, "$dm");
+      s = textToStr( name(hd(mems)).text );
+      assert(strlen(s) < 95);
+      strcat(buf, s);
+      n = findNameInAnyModule(findText(buf));
+      assert (nonNull(n));
+      defs = cons(n,defs);
+   }
+   defs = rev(defs);
+   cclass(c).defaults = defs;
+
+   /* Create a name table entry for the dictionary datacon.
+      Interface files don't mention them, so it had better not
+      already be present.
+   */
+   strcpy(buf, ":D");
+   s = textToStr( cclass(c).text );
+   assert( strlen(s) < 96 );
+   strcat(buf, s);
+   t = findText(buf);
+   n = findNameInAnyModule(t);
+   assert(isNull(n));
+
+   m = cclass(c).mod;
+   n = newName(t,NIL);
+   name(n).mod    = m;
+   name(n).arity  = cclass(c).numSupers + cclass(c).numMembers;
+   name(n).number = cfunNo(0);
+   cclass(c).dcon = n;
+
+   /* And finally ... set name(n).itbl to Mod_:DClass_con_info.
+      Because this happens right at the end of loading, we know
+      that we should actually be able to find the symbol in this
+      module's object symbol table.  Except that if the dictionary
+      has arity 1, we don't bother, since it will be represented as
+      a newtype and not as a data, so its itbl can remain NULL.
+   */ 
+   if (name(n).arity == 1) {
+      name(n).itbl = NULL;
+      name(n).defn = nameId;
+   } else {
+      p = ifFindItblFor ( n );
+      name(n).itbl = p;
+   }
+}
+
+
+void processInterfaces ( List /* of CONID */ iface_modnames )
+{
+    List    tmp;
+    List    xs;
+    ZTriple tr;
+    Cell    iface;
+    Int     sizeObj;
+    Text    nameObj;
+    Text    mname;
+    List    decls;
+    Module  mod;
+    List    all_known_types;
+    Int     num_known_types;
+    List    cls_list;         /* :: List Class */
+    List    constructor_list; /* :: List Name */
+
+    List ifaces       = NIL;  /* :: List I_INTERFACE */
+
+    if (isNull(iface_modnames)) return;
+
+#   ifdef DEBUG_IFACE
+    fprintf ( stderr, 
+              "processInterfaces: %d interfaces to process\n", 
+              length(ifaces_outstanding) );
+#   endif
+
+    for (xs = iface_modnames; nonNull(xs); xs=tl(xs)) {
+       mod = findModule(textOf(hd(xs)));
+       assert(nonNull(mod));
+       assert(module(mod).mode == FM_OBJECT);
+       ifaces = cons ( module(mod).tree, ifaces );
+    }
+    ifaces = reverse(ifaces);
+
+    /* Clean up interfaces -- dump non-exported value, class, type decls */
+    for (xs = ifaces; nonNull(xs); xs = tl(xs))
+       hd(xs) = deleteUnexportedIFaceEntities(hd(xs));
+
+
+    /* Iteratively delete any type declarations which refer to unknown
+       tycons. 
+    */
+    num_known_types = 999999999;
+    while (TRUE) {
+       Int i;
+
+       /* Construct a list of all known tycons.  This is a list of QualIds. 
+          Unfortunately it also has to contain all known class names, since
+          allTypesKnown cannot distinguish between tycons and classes -- a
+          deficiency of the iface abs syntax.
+       */
+       all_known_types = getAllKnownTyconsAndClasses();
+       for (xs = ifaces; nonNull(xs); xs=tl(xs))
+          all_known_types 
+             = addTyconsAndClassesFromIFace ( hd(xs), all_known_types );
+
+       /* Have we reached a fixed point? */
+       i = length(all_known_types);
+#      ifdef DEBUG_IFACE
+       fprintf ( stderr,
+                 "\n============= %d known types =============\n", i );
+#      endif
+       if (num_known_types == i) break;
+       num_known_types = i;
+
+       /* Delete all entities which refer to unknown tycons. */
+       for (xs = ifaces; nonNull(xs); xs = tl(xs)) {
+          ConId mod = zfst(unap(I_INTERFACE,hd(xs)));
+          assert(nonNull(mod));
+          hd(xs) = filterInterface ( hd(xs), 
+                                     ifTypeDoesntRefUnknownTycon,
+                                     zpair(all_known_types,mod),
+                                     ifTypeDoesntRefUnknownTycon_dumpmsg );
+       }
+    }
+
+    /* Now abstractify any datas and newtypes which refer to unknown tycons
+       -- including, of course, the type decls just deleted.
+    */
+    for (xs = ifaces; nonNull(xs); xs = tl(xs)) {
+       List  absify = NIL;                      /* :: [ConId] */
+       ZPair iface  = unap(I_INTERFACE,hd(xs)); /* ((ConId, [I_IMPORT..I_VALUE])) */
+       ConId mod    = zfst(iface);
+       List  aktys  = all_known_types;          /* just a renaming */
+       List  es,t,u;
+       List  exlist_list;
+
+       /* Compute into absify the list of all ConIds (tycons) we need to
+          abstractify. 
+       */
+       for (es = zsnd(iface); nonNull(es); es=tl(es)) {
+          Cell ent      = hd(es);
+          Bool allKnown = TRUE;
+
+          if (whatIs(ent)==I_DATA) {
+             Cell data    = unap(I_DATA,ent);
+             List ctx     = zsel25 ( data ); /* :: [((QConId,VarId))] */
+             List constrs = zsel55 ( data ); /* :: [ ((ConId, [((Type,VarId,Int))] )) ] */
+             for (t = ctx; nonNull(t); t=tl(t))
+                if (!allTypesKnown(zfst(hd(t)),aktys,mod)) allKnown = FALSE;
+             for (t = constrs; nonNull(t); t=tl(t))
+                for (u = zsnd(hd(t)); nonNull(u); u=tl(u))
+                    if (!allTypesKnown(zfst3(hd(u)),aktys,mod)) allKnown = FALSE;
+          }
+          else if (whatIs(ent)==I_NEWTYPE) {
+             Cell  newty  = unap(I_NEWTYPE,ent);
+             List  ctx    = zsel25(newty);    /* :: [((QConId,VarId))] */
+             ZPair constr = zsel55 ( newty ); /* :: ((ConId,Type)) */
+             for (t = ctx; nonNull(t); t=tl(t))
+                if (!allTypesKnown(zfst(hd(t)),aktys,mod)) allKnown = FALSE;
+             if (!allTypesKnown(zsnd(constr),aktys,mod)) allKnown = FALSE;
+          }
+
+          if (!allKnown) {
+             absify = cons ( getIEntityName(ent), absify );
+#            ifdef DEBUG_IFACE
+             fprintf ( stderr, 
+                       "abstractifying %s because it uses an unknown type\n",
+                       textToStr(textOf(getIEntityName(ent))) );
+#            endif
+          }
+       }
+
+       /* mark in exports as abstract all names in absify (modifies iface) */
+       for (; nonNull(absify); absify=tl(absify)) {
+          ConId toAbs = hd(absify);
+          for (es = zsnd(iface); nonNull(es); es=tl(es)) {
+             if (whatIs(hd(es)) != I_EXPORT) continue;
+             hd(es) = abstractifyExDecl ( hd(es), toAbs );
+          }
+       }
+
+       /* For each data/newtype in the export list marked as abstract,
+          remove the constructor lists.  This catches all abstractification
+          caused by the code above, and it also catches tycons which really
+          were exported abstractly.
+       */
+
+       exlist_list = getExportDeclsInIFace ( ap(I_INTERFACE,iface) );
+       /* exlist_list :: [I_EXPORT] */
+       for (t=exlist_list; nonNull(t); t=tl(t))
+          hd(t) = zsnd(unap(I_EXPORT,hd(t)));
+       /* exlist_list :: [[ ConVarId | ((ConId, [ConVarId])) ]] */
+
+       for (es = zsnd(iface); nonNull(es); es=tl(es)) {
+          Cell ent = hd(es);
+          if (whatIs(ent)==I_DATA
+              && isExportedAbstractly ( getIEntityName(ent),
+                                        exlist_list )) {
+             Cell data = unap(I_DATA,ent);
+             data = z5ble ( zsel15(data), zsel25(data), zsel35(data),
+                            zsel45(data), NIL /* the constr list */ );
+             hd(es) = ap(I_DATA,data);
+#            ifdef DEBUG_IFACE
+             fprintf(stderr, "abstractify data %s\n", 
+                     textToStr(textOf(getIEntityName(ent))) );
+#            endif
+         }
+          else if (whatIs(ent)==I_NEWTYPE
+              && isExportedAbstractly ( getIEntityName(ent), 
+                                        exlist_list )) {
+             Cell data = unap(I_NEWTYPE,ent);
+             data = z5ble ( zsel15(data), zsel25(data), zsel35(data),
+                            zsel45(data), NIL /* the constr-type pair */ );
+             hd(es) = ap(I_NEWTYPE,data);
+#            ifdef DEBUG_IFACE
+             fprintf(stderr, "abstractify newtype %s\n", 
+                     textToStr(textOf(getIEntityName(ent))) );
+#            endif
+          }
+       }
+
+       /* We've finally finished mashing this iface.  Update the iface list. */
+       hd(xs) = ap(I_INTERFACE,iface);
+    }
+
+
+    /* At this point, the interfaces are cleaned up so that no type, data or
+       newtype defn refers to a non-existant type.  However, there still may
+       be value defns, classes and instances which refer to unknown types.
+       Delete iteratively until a fixed point is reached.
+    */
+#   ifdef DEBUG_IFACE
+    fprintf(stderr,"\n");
+#   endif
+    num_known_types = 999999999;
+    while (TRUE) {
+       Int i;
+
+       /* Construct a list of all known tycons.  This is a list of QualIds. 
+          Unfortunately it also has to contain all known class names, since
+          allTypesKnown cannot distinguish between tycons and classes -- a
+          deficiency of the iface abs syntax.
+       */
+       all_known_types = getAllKnownTyconsAndClasses();
+       for (xs = ifaces; nonNull(xs); xs=tl(xs))
+          all_known_types = addTyconsAndClassesFromIFace ( hd(xs), all_known_types );
+
+       /* Have we reached a fixed point? */
+       i = length(all_known_types);
+#      ifdef DEBUG_IFACE
+       fprintf ( stderr,
+                 "\n------------- %d known types -------------\n", i );
+#      endif
+       if (num_known_types == i) break;
+       num_known_types = i;
+
+       /* Delete all entities which refer to unknown tycons. */
+       for (xs = ifaces; nonNull(xs); xs = tl(xs)) {
+          ConId mod = zfst(unap(I_INTERFACE,hd(xs)));
+          assert(nonNull(mod));
+
+          hd(xs) = filterInterface ( hd(xs),
+                                     ifentityAllTypesKnown,
+                                     zpair(all_known_types,mod), 
+                                     ifentityAllTypesKnown_dumpmsg );
+       }
     }
-    setCurrModule(m);
+
+
+    /* Allocate module table entries and read in object code. */
+    for (xs=ifaces; nonNull(xs); xs=tl(xs))
+       startGHCModule ( textOf(zfst(unap(I_INTERFACE,hd(xs)))) );
+
+
+    /* Now work through the decl lists of the modules, and call the
+       startGHC* functions on the entities.  This creates names in
+       various tables but doesn't bind them to anything.
+    */
+
+    for (xs = ifaces; nonNull(xs); xs = tl(xs)) {
+       iface   = unap(I_INTERFACE,hd(xs));
+       mname   = textOf(zfst(iface));
+       mod     = findModule(mname);
+       if (isNull(mod)) internal("processInterfaces(4)");
+       setCurrModule(mod);
+       ppModule ( module(mod).text );
+
+       for (decls = zsnd(iface); nonNull(decls); decls = tl(decls)) {
+          Cell decl = hd(decls);
+          switch(whatIs(decl)) {
+             case I_EXPORT: {
+                Cell exdecl = unap(I_EXPORT,decl);
+                startGHCExports ( zfst(exdecl), zsnd(exdecl) );
+                break;
+             }
+             case I_IMPORT: {
+                Cell imdecl = unap(I_IMPORT,decl);
+                startGHCImports ( zfst(imdecl), zsnd(imdecl) );
+                break;
+             }
+             case I_FIXDECL: {
+                break;
+             }
+             case I_INSTANCE: {
+                /* Trying to find the instance table location allocated by
+                   startGHCInstance in subsequent processing is a nightmare, so
+                   cache it on the tree. 
+                */
+                Cell instance = unap(I_INSTANCE,decl);
+                Inst in = startGHCInstance ( zsel15(instance), zsel25(instance),
+                                             zsel35(instance), zsel45(instance) );
+                hd(decls) = ap(I_INSTANCE,
+                               z5ble( zsel15(instance), zsel25(instance),
+                                      zsel35(instance), zsel45(instance), in ));
+                break;
+             }
+             case I_TYPE: {
+                Cell tydecl = unap(I_TYPE,decl);
+                startGHCSynonym ( zsel14(tydecl), zsel24(tydecl),
+                                  zsel34(tydecl), zsel44(tydecl) );
+                break;
+             }
+             case I_DATA: {
+                Cell ddecl = unap(I_DATA,decl);
+                startGHCDataDecl ( zsel15(ddecl), zsel25(ddecl), 
+                                   zsel35(ddecl), zsel45(ddecl), zsel55(ddecl) );
+                break;
+             }
+             case I_NEWTYPE: {
+                Cell ntdecl = unap(I_NEWTYPE,decl);
+                startGHCNewType ( zsel15(ntdecl), zsel25(ntdecl), 
+                                  zsel35(ntdecl), zsel45(ntdecl), 
+                                  zsel55(ntdecl) );
+                break;
+             }
+             case I_CLASS: {
+                Cell klass = unap(I_CLASS,decl);
+                startGHCClass ( zsel15(klass), zsel25(klass), 
+                                zsel35(klass), zsel45(klass), 
+                                zsel55(klass) );
+                break;
+             }
+             case I_VALUE: {
+                Cell value = unap(I_VALUE,decl);
+                startGHCValue ( zfst3(value), zsnd3(value), zthd3(value) );
+                break;
+             }
+             default:
+                internal("processInterfaces(1)");
+          }
+       }       
+    }
+
+#   ifdef DEBUG_IFACE
+    fprintf(stderr, "\n============================"
+                    "=============================\n");
+    fprintf(stderr, "=============================="
+                    "===========================\n");
+#   endif
+
+    /* Traverse again the decl lists of the modules, this time 
+       calling the finishGHC* functions.  But don't process
+       the export lists; those must wait for later.
+    */
+    cls_list         = NIL;
+    constructor_list = NIL;
+    for (xs = ifaces; nonNull(xs); xs = tl(xs)) {
+       iface   = unap(I_INTERFACE,hd(xs));
+       mname   = textOf(zfst(iface));
+       mod     = findModule(mname);
+       if (isNull(mod)) internal("processInterfaces(3)");
+       setCurrModule(mod);
+       ppModule ( module(mod).text );
+
+       for (decls = zsnd(iface); nonNull(decls); decls = tl(decls)) {
+          Cell decl = hd(decls);
+          switch(whatIs(decl)) {
+             case I_EXPORT: {
+                break;
+             }
+             case I_IMPORT: {
+                break;
+             }
+             case I_FIXDECL: {
+                Cell fixdecl = unap(I_FIXDECL,decl);
+                finishGHCFixdecl ( zfst3(fixdecl), zsnd3(fixdecl), zthd3(fixdecl) );
+                break;
+             }
+             case I_INSTANCE: {
+                Cell instance = unap(I_INSTANCE,decl);
+                finishGHCInstance ( zsel55(instance) );
+                break;
+             }
+             case I_TYPE: {
+                Cell tydecl = unap(I_TYPE,decl);
+                finishGHCSynonym ( zsel24(tydecl) );
+                break;
+             }
+             case I_DATA: {
+                Cell ddecl   = unap(I_DATA,decl);
+                List constrs = finishGHCDataDecl ( zsel35(ddecl) );
+                constructor_list = dupOnto ( constrs, constructor_list );
+                break;
+             }
+             case I_NEWTYPE: {
+                Cell ntdecl = unap(I_NEWTYPE,decl);
+                finishGHCNewType ( zsel35(ntdecl) );
+                break;
+             }
+             case I_CLASS: {
+                Cell  klass = unap(I_CLASS,decl);
+                Class cls   = finishGHCClass ( zsel35(klass) );
+                cls_list = cons(cls,cls_list);
+                break;
+             }
+             case I_VALUE: {
+                Cell value = unap(I_VALUE,decl);
+                finishGHCValue ( zsnd3(value) );
+                break;
+             }
+             default:
+                internal("processInterfaces(2)");
+          }
+       }       
+    }
+#   ifdef DEBUG_IFACE
+    fprintf(stderr, "\n+++++++++++++++++++++++++++++"
+                    "++++++++++++++++++++++++++++\n");
+    fprintf(stderr, "+++++++++++++++++++++++++++++++"
+                    "++++++++++++++++++++++++++\n");
+#   endif
+
+    /* Build the module(m).export lists for each module, by running
+       through the export lists in the iface.  Also, do the implicit
+       'import Prelude' thing.  And finally, do the object code 
+       linking.
+    */
+    for (xs = ifaces; nonNull(xs); xs = tl(xs))
+       finishGHCModule(hd(xs));
+
+    mapProc(visitClass,cls_list);
+    mapProc(ifSetClassDefaultsAndDCon,cls_list);
+    mapProc(ifLinkConstrItbl,constructor_list);
+
+    /* Finished! */
+    ifaces_outstanding = NIL;
 }
 
-Void addGHCImport(line,mn,fn)
-Int  line;
-Text mn;
-String fn; {
-#if 1 /* new */
-    Text   t = findText(fn);
-    Module m = findModule(mn);
-    if (isNull(m)) {
-        if (isNull(varIsMember(t,interfaces))) {
-            interfaces = cons(mkCon(t),interfaces);
-        }
+
+/* --------------------------------------------------------------------------
+ * Modules
+ * ------------------------------------------------------------------------*/
+
+static void startGHCModule_errMsg ( char* msg )
+{
+   fprintf ( stderr, "object error: %s\n", msg );
+}
+
+static void* startGHCModule_clientLookup ( char* sym )
+{
+#  ifdef DEBUG_IFACE
+   /* fprintf ( stderr, "CLIENTLOOKUP %s\n", sym ); */
+#  endif
+   return lookupObjName ( sym );
+}
+
+static int /*Bool*/ startGHCModule_clientWantsSymbol ( char* sym )
+{
+   if (strcmp(sym,"ghc_cc_ID")==0) return 0;
+   return 1;
+}
+
+static ObjectCode* startGHCModule_partial_load ( String objNm, Int objSz )
+{
+   ObjectCode* oc
+      = ocNew ( startGHCModule_errMsg,
+                startGHCModule_clientLookup,
+                startGHCModule_clientWantsSymbol,
+                objNm, objSz );
+    
+    if (!oc) {
+       ERRMSG(0) "Storage allocation for object file \"%s\" failed", objNm
+       EEND;
     }
-#else /* old - and probably wrong */
-    Module m = findModule(t);
-    if (isNull(m)) {
-        ERRMSG(0) "Unknown module \"%s\"", textToStr(t)
-        EEND;
+    if (!ocLoadImage(oc,VERBOSE)) {
+       ERRMSG(0) "Reading of object file \"%s\" failed", objNm
+       EEND;
     }
-    /* ToDo: what to do if there's a name conflict? */
-    {   /* copied from resolveImportList */
-        List es      = module(m).exports;
-        List imports = NIL;
-        for(; nonNull(es); es=tl(es)) {
-            Cell e = hd(es);
-            if (isName(e)) {
-                imports = cons(e,imports);
-            } else {
-                Cell c = fst(e);
-                List subentities = NIL;
-                imports = cons(c,imports);
-                if (isTycon(c)
-                    && (tycon(c).what == DATATYPE 
-                        || tycon(c).what == NEWTYPE)) {
-                    subentities = tycon(c).defn;
-                } else if (isClass(c)) {
-                    subentities = cclass(c).members;
-                }
-                if (DOTDOT == snd(e)) {
-                    imports = revDupOnto(subentities,imports);
-                }
-            }
-        }
-        map1Proc(importEntity,m,imports);
+    if (!ocVerifyImage(oc,VERBOSE)) {
+       ERRMSG(0) "Validation of object file \"%s\" failed", objNm
+       EEND;
     }
+    if (!ocGetNames(oc,VERBOSE)) {
+       ERRMSG(0) "Reading of symbol names in object file \"%s\" failed", objNm
+       EEND;
+    }
+    return oc;
+}
+
+static Void startGHCModule ( Text mname )
+{
+   List   xts;
+   Module m = findModule(mname);
+   assert(nonNull(m));
+
+#  ifdef DEBUG_IFACE
+   fprintf ( stderr, "startGHCIface: name %16s   objsize %d\n", 
+                      textToStr(mname), module(m).objSize );
+#  endif
+   if (module(m).fake)
+      module(m).fake = FALSE;
+
+   /* Get hold of the primary object for the module. */
+   module(m).object
+      = startGHCModule_partial_load ( textToStr(module(m).objName), 
+                                      module(m).objSize );
+
+   /* and any extras ... */
+   for (xts = module(m).objectExtraNames; nonNull(xts); xts=tl(xts)) {
+      Int         size;
+      ObjectCode* oc;
+      Text        xtt = hd(xts);
+      String      nm  = getExtraObjectInfo (
+                           textToStr(module(m).objName),
+                           textToStr(xtt),
+                           &size
+                        );
+      if (size == -1) {
+         ERRMSG(0) "Can't find extra object file \"%s\"", nm
+         EEND;
+      }
+      oc = startGHCModule_partial_load ( nm, size );
+      oc->next = module(m).objectExtras;
+      module(m).objectExtras = oc;
+   }
+}
+
+
+/* For the module mod, augment both the export environment (.exports) 
+   and the eval environment (.names, .tycons, .classes)
+   with the symbols mentioned in exlist.  We don't actually need
+   to modify the names, tycons, classes or instances in the eval 
+   environment, since previous processing of the
+   top-level decls in the iface should have done this already.
+
+   mn is the module mentioned in the export list; it is the "original"
+   module for the symbols in the export list.  We should also record
+   this info with the symbols, since references to object code need to
+   refer to the original module in which a symbol was defined, rather
+   than to some module it has been imported into and then re-exported.
+
+   We take the policy that if something mentioned in an export list
+   can't be found in the symbol tables, it is simply ignored.  After all,
+   previous processing of the iface syntax trees has already removed 
+   everything which Hugs can't handle, so if there is mention of these
+   things still lurking in export lists somewhere, about the only thing
+   to do is to ignore it.
+
+   Also do an implicit 'import Prelude' thingy for the module,
+   if appropriate.
+*/
+
+
+static Void finishGHCModule ( Cell root ) 
+{
+   /* root :: I_INTERFACE */
+   Cell        iface       = unap(I_INTERFACE,root);
+   ConId       iname       = zfst(iface);
+   Module      mod         = findModule(textOf(iname));
+   List        exlist_list = NIL;
+   List        t;
+   ObjectCode* oc;
+
+#  ifdef DEBUG_IFACE
+   fprintf(stderr, "begin finishGHCModule %s\n", textToStr(textOf(iname)));
+#  endif
+
+   if (isNull(mod)) internal("finishExports(1)");
+   setCurrModule(mod);
+
+   exlist_list = getExportDeclsInIFace ( root );
+   /* exlist_list :: [I_EXPORT] */
+   
+   for (; nonNull(exlist_list); exlist_list=tl(exlist_list)) {
+      ZPair exdecl = unap(I_EXPORT,hd(exlist_list));
+      ConId exmod  = zfst(exdecl);
+      List  exlist = zsnd(exdecl);
+      /* exlist :: [ ConVarId | ((ConId, [ConVarId])) ] */
+
+      for (; nonNull(exlist); exlist=tl(exlist)) {
+         Bool   abstract;
+         List   subents;
+         Cell   c;
+         QualId q;
+         Cell   ex = hd(exlist);
+
+         switch (whatIs(ex)) {
+
+            case VARIDCELL: /* variable */
+               q = mkQualId(exmod,ex);
+               c = findQualNameWithoutConsultingExportList ( q );
+               if (isNull(c)) goto notfound;
+#              ifdef DEBUG_IFACE
+               fprintf(stderr, "   var %s\n", textToStr(textOf(ex)) );
+#              endif
+               module(mod).exports = cons(c, module(mod).exports);
+               addName(c);
+               break;
+
+            case CONIDCELL: /* non data tycon */
+               q = mkQualId(exmod,ex);
+               c = findQualTyconWithoutConsultingExportList ( q );
+               if (isNull(c)) goto notfound;
+#              ifdef DEBUG_IFACE
+               fprintf(stderr, "   type %s\n", textToStr(textOf(ex)) );
+#              endif
+               module(mod).exports = cons(pair(c,NIL), module(mod).exports);
+               addTycon(c);
+               break;
+
+            case ZTUP2: /* data T = C1 ... Cn  or class C where f1 ... fn */
+               subents = zsnd(ex);  /* :: [ConVarId] */
+               ex      = zfst(ex);  /* :: ConId */
+               q       = mkQualId(exmod,ex);
+               c       = findQualTyconWithoutConsultingExportList ( q );
+
+               if (nonNull(c)) { /* data */
+#                 ifdef DEBUG_IFACE
+                  fprintf(stderr, "   data/newtype %s = { ", 
+                          textToStr(textOf(ex)) );
+#                 endif
+                  assert(tycon(c).what == DATATYPE || tycon(c).what==NEWTYPE);
+                  abstract = isNull(tycon(c).defn);
+                  /* This data/newtype could be abstract even tho the export list
+                     says to export it non-abstractly.  That happens if it was 
+                     imported from some other module and is now being re-exported,
+                     and previous cleanup phases have abstractified it in the 
+                     original (defining) module.
+                 */
+                  if (abstract) {
+                     module(mod).exports = cons(pair(c,NIL), module(mod).exports);
+                     addTycon(c);
+#                    ifdef DEBUG_IFACE
+                     fprintf ( stderr, "(abstract) ");
+#                    endif
+                 } else {
+                     module(mod).exports = cons(pair(c,DOTDOT), module(mod).exports);
+                     addTycon(c);
+                     for (; nonNull(subents); subents = tl(subents)) {
+                        Cell ent2 = hd(subents);
+                        assert(isCon(ent2) || isVar(ent2)); 
+                                              /* isVar since could be a field name */
+                        q = mkQualId(exmod,ent2);
+                        c = findQualNameWithoutConsultingExportList ( q );
+#                       ifdef DEBUG_IFACE
+                        fprintf(stderr, "%s ", textToStr(name(c).text));
+#                       endif
+                        assert(nonNull(c));
+                        /* module(mod).exports = cons(c, module(mod).exports); */
+                        addName(c);
+                     }
+                  }
+#                 ifdef DEBUG_IFACE
+                  fprintf(stderr, "}\n" );
+#                 endif
+               } else { /* class */
+                  q = mkQualId(exmod,ex);
+                  c = findQualClassWithoutConsultingExportList ( q );
+                  if (isNull(c)) goto notfound;
+#                 ifdef DEBUG_IFACE
+                  fprintf(stderr, "   class %s { ", textToStr(textOf(ex)) );
+#                 endif
+                  module(mod).exports = cons(pair(c,DOTDOT), module(mod).exports);
+                  addClass(c);
+                  for (; nonNull(subents); subents = tl(subents)) {
+                     Cell ent2 = hd(subents);
+                     assert(isVar(ent2));
+                     q = mkQualId(exmod,ent2);
+                     c = findQualNameWithoutConsultingExportList ( q );
+#                    ifdef DEBUG_IFACE
+                     fprintf(stderr, "%s ", textToStr(name(c).text));
+#                    endif
+                     if (isNull(c)) goto notfound;
+                     /* module(mod).exports = cons(c, module(mod).exports); */
+                     addName(c);
+                  }
+#                 ifdef DEBUG_IFACE
+                  fprintf(stderr, "}\n" );
+#                 endif
+               }
+               break;
+
+            default:
+               internal("finishExports(2)");
+
+         } /* switch */
+         continue;  /* so notfound: can be placed after this */
+  
+        notfound:
+         /* q holds what ain't found */
+         assert(whatIs(q)==QUALIDENT);
+#        ifdef DEBUG_IFACE
+         fprintf( stderr, "   ------ IGNORED: %s.%s\n",
+                  textToStr(qmodOf(q)), textToStr(qtextOf(q)) );
+#        endif
+         continue;
+      }
+   }
+
+#if 0
+   if (preludeLoaded) {
+      /* do the implicit 'import Prelude' thing */
+      List pxs = module(modulePrelude).exports;
+      for (; nonNull(pxs); pxs=tl(pxs)) {
+         Cell px = hd(pxs);
+         again:
+         switch (whatIs(px)) {
+            case AP: 
+               px = fst(px); 
+               goto again;
+            case NAME: 
+               module(mod).names = cons ( px, module(mod).names );
+               break;
+            case TYCON: 
+               module(mod).tycons = cons ( px, module(mod).tycons );
+               break;
+            case CLASS: 
+               module(mod).classes = cons ( px, module(mod).classes );
+               break;
+            default:               
+               fprintf(stderr, "finishGHCModule: unknown tag %d\n", whatIs(px));
+               internal("finishGHCModule -- implicit import Prelude");
+               break;
+         }
+      }
+   }
 #endif
+
+   /* Last, but by no means least ... */
+   if (!ocResolve(module(mod).object,VERBOSE))
+      internal("finishGHCModule: object resolution failed");
+
+   for (oc=module(mod).objectExtras; oc; oc=oc->next) {
+      if (!ocResolve(oc, VERBOSE))
+         internal("finishGHCModule: extra object resolution failed");
+   }
 }
 
-void addGHCVar(line,v,ty)
-Int  line;
-Text v;
-Type ty;
+
+/* --------------------------------------------------------------------------
+ * Exports
+ * ------------------------------------------------------------------------*/
+
+static Void startGHCExports ( ConId mn, List exlist )
 {
-    Name n = findName(v);
-    if (nonNull(n)) {
-        ERRMSG(0) "Attempt to redefine variable \"%s\"", textToStr(v)
+#   ifdef DEBUG_IFACE
+    fprintf(stderr,"startGHCExports %s\n", textToStr(textOf(mn)) );
+#   endif
+   /* Nothing to do. */
+}
+
+static Void finishGHCExports ( ConId mn, List exlist )
+{
+#   ifdef DEBUG_IFACE
+    fprintf(stderr,"finishGHCExports %s\n", textToStr(textOf(mn)) );
+#   endif
+   /* Nothing to do. */
+}
+
+
+/* --------------------------------------------------------------------------
+ * Imports
+ * ------------------------------------------------------------------------*/
+
+static Void startGHCImports ( ConId mn, List syms )
+/* nm     the module to import from */
+/* syms   [ConId | VarId] -- the names to import */
+{
+#  ifdef DEBUG_IFACE
+   fprintf(stderr,"startGHCImports %s\n", textToStr(textOf(mn)) );
+#  endif
+   /* Nothing to do. */
+}
+
+
+static Void finishGHCImports ( ConId nm, List syms )
+/* nm     the module to import from */
+/* syms   [ConId | VarId] -- the names to import */
+{
+#  ifdef DEBUG_IFACE
+   fprintf(stderr,"finishGHCImports %s\n", textToStr(textOf(nm)) );
+#  endif
+  /* Nothing to do. */
+}
+
+
+/* --------------------------------------------------------------------------
+ * Fixity decls
+ * ------------------------------------------------------------------------*/
+
+static Void finishGHCFixdecl ( Cell prec, Cell assoc, ConVarId name )
+{
+   Int  p = intOf(prec);
+   Int  a = intOf(assoc);
+   Name n = findName(textOf(name));
+   assert (nonNull(n));
+   name(n).syntax = mkSyntax ( a, p );
+}
+
+
+/* --------------------------------------------------------------------------
+ * Vars (values)
+ * ------------------------------------------------------------------------*/
+
+/* convert a leading run of DICTAPs into Hugs' internal Qualtype form, viz:
+   { C1 a } -> { C2 b } -> T            into
+   ap(QUALTYPE, ( [(C1,a),(C2,b)], T ))
+*/
+static Type dictapsToQualtype ( Type ty )
+{
+   List pieces = NIL;
+   List preds, dictaps;
+
+   /* break ty into pieces at the top-level arrows */
+   while (isAp(ty) && isAp(fun(ty)) && fun(fun(ty))==typeArrow) {
+      pieces = cons ( arg(fun(ty)), pieces );
+      ty     = arg(ty);
+   }
+   pieces = cons ( ty, pieces );
+   pieces = reverse ( pieces );
+
+   dictaps = NIL;
+   while (nonNull(pieces) && whatIs(hd(pieces))==DICTAP) {
+      dictaps = cons ( hd(pieces), dictaps );
+      pieces = tl(pieces);
+   }
+
+   /* dictaps holds the predicates, backwards */
+   /* pieces holds the remainder of the type, forwards */
+   assert(nonNull(pieces));
+   pieces = reverse(pieces);
+   ty = hd(pieces);
+   pieces = tl(pieces);
+   for (; nonNull(pieces); pieces=tl(pieces)) 
+      ty = fn(hd(pieces),ty);
+
+   preds = NIL;
+   for (; nonNull(dictaps); dictaps=tl(dictaps)) {
+      Cell da = hd(dictaps);
+      QualId cl = fst(unap(DICTAP,da));
+      Cell   arg = snd(unap(DICTAP,da));
+      preds = cons ( pair(cl,arg), preds );
+   }
+
+   if (nonNull(preds)) ty = ap(QUAL, pair(preds,ty));
+   return ty;
+}
+
+
+
+static void startGHCValue ( Int line, VarId vid, Type ty )
+{
+    Name   n;
+    List   tmp, tvs;
+    Text   v = textOf(vid);
+
+#   ifdef DEBUG_IFACE
+    fprintf(stderr,"begin startGHCValue %s\n", textToStr(v));
+#   endif
+
+    line = intOf(line);
+    n = findName(v);
+    if (nonNull(n) && name(n).defn != PREDEFINED) {
+        ERRMSG(line) "Attempt to redefine variable \"%s\"", textToStr(v)
         EEND;
     }
-    n = newName(v);
-    bindNameToClosure(n, lookupGHCClosure(name(n).mod,name(n).text));
+    if (isNull(n)) n = newName(v,NIL);
 
-    /* prepare for finishGHCVar */
-    name(n).type = ty;
-    ghcVarDecls = cons(n,ghcVarDecls);
+    ty = dictapsToQualtype(ty);
+
+    tvs = ifTyvarsIn(ty);
+    for (tmp=tvs; nonNull(tmp); tmp=tl(tmp))
+       hd(tmp) = zpair(hd(tmp),STAR);
+    if (nonNull(tvs))
+       ty = mkPolyType(tvsToKind(tvs),ty);
+
+    ty = tvsToOffsets(line,ty,tvs);
+    name(n).type  = ty;
+    name(n).arity = arityInclDictParams(ty);
+    name(n).line  = line;
+    name(n).defn  = NIL;
 }
 
-static Void local finishGHCVar(Name n)
+
+static void finishGHCValue ( VarId vid )
 {
+    Name n    = findName ( textOf(vid) );
     Int  line = name(n).line;
-    Type ty   = name(n).type;
-    setCurrModule(name(n).mod);
-    name(n).type = fixupType(line,NIL,ty);
+#   ifdef DEBUG_IFACE
+    fprintf(stderr, "begin finishGHCValue %s\n", textToStr(name(n).text) );
+#   endif
+    assert(currentModule == name(n).mod);
+    name(n).type = conidcellsToTycons(line,name(n).type);
+
+    if (isIfaceDefaultMethodName(name(n).text)) {
+       /* ... we need to set .parent to point to the class 
+          ... once we figure out what the class actually is :-)
+       */
+       Type t = name(n).type;
+       assert(isPolyType(t));
+       if (isPolyType(t)) t = monotypeOf(t);
+       assert(isQualType(t));
+       t = fst(snd(t));       /* t :: [(Class,Offset)] */
+       assert(nonNull(t));
+       assert(nonNull(hd(t)));
+       assert(isPair(hd(t)));
+       t = fst(hd(t));        /* t :: Class */
+       assert(isClass(t));
+       
+       name(n).parent = t;    /* phew! */
+    }
 }
 
-Void addGHCSynonym(line,tycon,tvs,ty)
-Int  line;
-Cell tycon;  /* ConId          */
-List tvs;    /* [(VarId,Kind)] */
-Type ty; {
-    /* ToDo: worry about being given a decl for (->) ?
-     * and worry about qualidents for ()
-     */
+
+/* --------------------------------------------------------------------------
+ * Type synonyms
+ * ------------------------------------------------------------------------*/
+
+static Void startGHCSynonym ( Int line, ConId tycon, List tvs, Type ty )
+{
+    /* tycon :: ConId             */
+    /* tvs   ::  [((VarId,Kind))] */
+    /* ty    :: Type              */ 
     Text t = textOf(tycon);
+#   ifdef DEBUG_IFACE
+    fprintf(stderr, "begin startGHCSynonym %s\n", textToStr(t) );
+#   endif
+    line = intOf(line);
     if (nonNull(findTycon(t))) {
         ERRMSG(line) "Repeated definition of type constructor \"%s\"",
                      textToStr(t)
@@ -262,86 +1571,195 @@ Type ty; {
         tycon(tc).kind  = tvsToKind(tvs);
 
         /* prepare for finishGHCSynonym */
-        tycon(tc).defn  = pair(tvs,ty);
-        ghcSynonymDecls = cons(tc,ghcSynonymDecls);
+        tycon(tc).defn  = tvsToOffsets(line,ty,tvs);
     }
 }
 
-static Void  local finishGHCSynonym(Tycon tc)
+
+static Void  finishGHCSynonym ( ConId tyc )
 {
-    Int  line = tycon(tc).line;
-    List tvs  = fst(tycon(tc).defn);
-    Type ty   = snd(tycon(tc).defn);
+    Tycon tc   = findTycon(textOf(tyc)); 
+    Int   line = tycon(tc).line;
+#   ifdef DEBUG_IFACE
+    fprintf(stderr, "begin finishGHCSynonym %s\n", textToStr(textOf(tyc)) );
+#   endif
 
-    setCurrModule(tycon(tc).mod);
-    tycon(tc).defn = fixupType(line,singleton(tvs),ty);
+    assert (currentModule == tycon(tc).mod);
+    //    setCurrModule(tycon(tc).mod);
+    tycon(tc).defn = conidcellsToTycons(line,tycon(tc).defn);
 
-    /* ToDo: can't really do this until I've done all synonyms
+    /* (ADR) ToDo: can't really do this until I've done all synonyms
      * and then I have to do them in order
      * tycon(tc).defn = fullExpand(ty);
+     * (JRS) What?!?!  i don't understand
      */
 }
 
-Void addGHCDataDecl(line,tycon,tvs,constrs,sels)
-Int  line;
-Cell tycon;     /* ConId | QualConId      */
-List tvs;       /* [(VarId,Kind)]         */
-List constrs;   /* [(ConId,[VarId],Type)] */
-List sels; {    /* [(VarId,Type)]         */
+
+/* --------------------------------------------------------------------------
+ * Data declarations
+ * ------------------------------------------------------------------------*/
+
+static Type qualifyIfaceType ( Type unqual, List ctx )
+{
+   /* ctx :: [((QConId,VarId))] */
+   /* ctx is a list of (class name, tyvar) pairs.  
+      Attach to unqual qualifiers taken from ctx
+      for each tyvar which appears in unqual.
+   */
+   List tyvarsMentioned; /* :: [VarId] */
+   List ctx2  = NIL;
+   Cell kinds = NIL;
+
+   if (isPolyType(unqual)) {
+      kinds  = polySigOf(unqual);
+      unqual = monotypeOf(unqual);
+   }
+
+   assert(!isQualType(unqual));
+   tyvarsMentioned = ifTyvarsIn ( unqual );
+   for (; nonNull(ctx); ctx=tl(ctx)) {
+      ZPair ctxElem = hd(ctx); /* :: ((QConId, VarId)) */
+      if (nonNull(varIsMember(textOf(zsnd(ctxElem)),tyvarsMentioned)))
+         ctx2 = cons(ctxElem, ctx2);
+   }
+   if (nonNull(ctx2))
+      unqual = ap(QUAL,pair(reverse(ctx2),unqual));
+   if (nonNull(kinds))
+      unqual = mkPolyType(kinds,unqual);
+   return unqual;
+}
+
+
+static Void startGHCDataDecl(line,ctx0,tycon,ktyvars,constrs0)
+Int   line;
+List  ctx0;      /* [((QConId,VarId))]                */
+Cell  tycon;     /* ConId                             */
+List  ktyvars;   /* [((VarId,Kind))]                  */
+List  constrs0;  /* [((ConId,[((Type,VarId,Int))]))]  */
+                 /* The Text is an optional field name
+                    The Int indicates strictness */
     /* ToDo: worry about being given a decl for (->) ?
      * and worry about qualidents for ()
      */
+{
+    Type    ty, resTy, selTy, conArgTy;
+    List    tmp, conArgs, sels, constrs, fields;
+    Triple  constr;
+    Cell    conid;
+    Pair    conArg, ctxElem;
+    Text    conArgNm;
+    Int     conArgStrictness;
+    Int     conStrictCompCount;
+
     Text t = textOf(tycon);
+#   ifdef DEBUG_IFACE
+    fprintf(stderr, "begin startGHCDataDecl %s\n",textToStr(t));
+#   endif
+
+    line = intOf(line);
     if (nonNull(findTycon(t))) {
         ERRMSG(line) "Repeated definition of type constructor \"%s\"",
                      textToStr(t)
         EEND;
     } else {
         Tycon tc        = newTycon(t);
+        tycon(tc).text  = t;
         tycon(tc).line  = line;
-        tycon(tc).arity = length(tvs);
+        tycon(tc).arity = length(ktyvars);
+        tycon(tc).kind  = tvsToKind(ktyvars);
         tycon(tc).what  = DATATYPE;
-        tycon(tc).kind  = tvsToKind(tvs);
-        tycon(tc).defn  = addGHCConstrs(line,constrs,sels);
+
+        /* a list to accumulate selectors in :: [((VarId,Type))] */
+        sels = NIL;
+
+        /* make resTy the result type of the constr, T v1 ... vn */
+        resTy = tycon;
+        for (tmp=ktyvars; nonNull(tmp); tmp=tl(tmp))
+           resTy = ap(resTy,zfst(hd(tmp)));
+
+        /* for each constructor ... */
+        for (constrs=constrs0; nonNull(constrs); constrs=tl(constrs)) {
+           constr = hd(constrs);
+           conid  = zfst(constr);
+           fields = zsnd(constr);
+
+           /* Build type of constr and handle any selectors found. */
+           ty = resTy;
+
+           conStrictCompCount = 0;
+           conArgs = reverse(fields);
+           for (; nonNull(conArgs); conArgs=tl(conArgs)) {
+              conArg           = hd(conArgs); /* (Type,Text) */
+              conArgTy         = zfst3(conArg);
+              conArgNm         = zsnd3(conArg);
+              conArgStrictness = intOf(zthd3(conArg));
+              if (conArgStrictness > 0) conStrictCompCount++;
+              ty = fn(conArgTy,ty);
+              if (nonNull(conArgNm)) {
+                 /* a field name is mentioned too */
+                 selTy = fn(resTy,conArgTy);
+                 if (whatIs(tycon(tc).kind) != STAR)
+                    selTy = pair(POLYTYPE,pair(tycon(tc).kind, selTy));
+                 selTy = qualifyIfaceType ( selTy, ctx0 );
+                 selTy = tvsToOffsets(line,selTy, ktyvars);
+                 sels = cons( zpair(conArgNm,selTy), sels);
+              }
+           }
+
+           /* Now ty is the constructor's type, not including context.
+              Throw away any parts of the context not mentioned in ty,
+              and use it to qualify ty.
+          */
+           ty = qualifyIfaceType ( ty, ctx0 );
+
+           /* stick the tycon's kind on, if not simply STAR */
+           if (whatIs(tycon(tc).kind) != STAR)
+              ty = pair(POLYTYPE,pair(tycon(tc).kind, ty));
+
+           ty = tvsToOffsets(line,ty, ktyvars);
+
+           /* Finally, stick the constructor's type onto it. */
+           hd(constrs) = z4ble(conid,fields,ty,mkInt(conStrictCompCount));
+        }
+
+        /* Final result is that 
+           constrs :: [((ConId,[((Type,Text))],Type,Int))]   
+                      lists the constructors, their types and # strict comps
+           sels :: [((VarId,Type))]
+                   lists the selectors and their types
+       */
+        tycon(tc).defn = startGHCConstrs(line,constrs0,sels);
     }
 }
 
-static List local addGHCConstrs(line,cons,sels)
-Int  line;
-List cons;   /* [(ConId,[VarId],Type)] */
-List sels; { /* [(VarId,Type)]         */
-    List uses = NIL; /* [(ConName,[VarId])] */
-    if (nonNull(cons) && isNull(tl(cons))) { /* Single constructor datatype? */
-        List fs  = snd3(hd(cons));
-        Name c   = addGHCConstr(line,0,hd(cons));
-        uses     = cons(pair(c,fs),uses);
-        hd(cons) = c;
-    } else {
-        Int  conNo = 0; /*  or maybe 1? */
-        List cs    = cons;
-        for(; nonNull(cs); cs=tl(cs), conNo++) {
-            List fs = snd3(hd(cs));
-            Name c  = addGHCConstr(line,conNo,hd(cs));
-            uses    = cons(pair(c,fs),uses);
-            hd(cs)  = c;
-        }
+
+static List startGHCConstrs ( Int line, List cons, List sels )
+{
+    /* cons :: [((ConId,[((Type,Text,Int))],Type,Int))] */
+    /* sels :: [((VarId,Type))]                         */
+    /* returns [Name]                                   */
+    List cs, ss;
+    Int  conNo = length(cons)>1 ? 1 : 0;
+    for(cs=cons; nonNull(cs); cs=tl(cs), conNo++) {
+        Name c  = startGHCConstr(line,conNo,hd(cs));
+        hd(cs)  = c;
     }
-    {
-        List ss    = sels;
-        for(; nonNull(ss); ss=tl(ss)) {
-            hd(ss) = addGHCSel(line,hd(ss),uses);
-        }
+    /* cons :: [Name] */
+
+    for(ss=sels; nonNull(ss); ss=tl(ss)) {
+        hd(ss) = startGHCSel(line,hd(ss));
     }
+    /* sels :: [Name] */
     return appendOnto(cons,sels);
 }
 
-static Name local addGHCSel(line,sel,uses)
-Int  line;
-Pair sel;    /* (VarId,Type)        */
-List uses; { /* [(ConName,[VarId])] */
-    Text t      = textOf(fst(sel));
-    Type type   = snd(sel);
-    List fields = NIL;
+
+static Name startGHCSel ( Int line, ZPair sel )
+{
+    /* sel :: ((VarId, Type))  */
+    Text t      = textOf(zfst(sel));
+    Type type   = zsnd(sel);
     
     Name n = findName(t);
     if (nonNull(n)) {
@@ -350,77 +1768,85 @@ List uses; { /* [(ConName,[VarId])] */
         EEND;
     }
 
-    n              = newName(t);
+    n              = newName(t,NIL);
     name(n).line   = line;
     name(n).number = SELNAME;
     name(n).arity  = 1;
-
-    for(; nonNull(uses); uses=tl(uses)) {
-        Int  fNo = 1;
-        Name c   = fst(hd(uses));
-        List fs  = snd(hd(uses));
-        for(; nonNull(fs); fs=tl(fs), fNo++) {
-            if (textOf(hd(fs)) == t) {
-                fields = cons(pair(c,mkInt(fNo)),fields);
-            }
-        }
-    }
-    name(n).defn   = fields;
-
-    /* prepare for finishGHCVar */
+    name(n).defn   = NIL;
     name(n).type = type;
-    ghcVarDecls = cons(n,ghcVarDecls);
-
     return n;
 }
 
-static Name local addGHCConstr(line,conNo,constr)
-Int    line;
-Int    conNo;
-Triple constr; { /* (ConId,[VarId],Type) */
-    /* ToDo: add rank2 annotation and existential annotation
+
+static Name startGHCConstr ( Int line, Int conNo, Z4Ble constr )
+{
+    /* constr :: ((ConId,[((Type,Text,Int))],Type,Int)) */
+    /* (ADR) ToDo: add rank2 annotation and existential annotation
      * these affect how constr can be used.
      */
-    Text con   = textOf(fst3(constr));
-    Type type  = thd3(constr);
-    Int  arity = arityFromType(type);
+    Text con     = textOf(zsel14(constr));
+    Type type    = zsel34(constr);
+    Int  arity   = arityFromType(type);
+    Int  nStrict = intOf(zsel44(constr));
     Name n = findName(con);     /* Allocate constructor fun name   */
     if (isNull(n)) {
-        n = newName(con);
+        n = newName(con,NIL);
     } else if (name(n).defn!=PREDEFINED) {
         ERRMSG(line) "Repeated definition for constructor \"%s\"",
             textToStr(con)
         EEND;
     }
-    name(n).arity  = arity;     /* Save constructor fun details    */
-    name(n).line   = line;
-    name(n).number = cfunNo(conNo);
-    bindNameToClosure(n, lookupGHCClosure(name(n).mod,name(n).text));
-
-    /* prepare for finishGHCCon */
-    name(n).type   = type;
-    ghcConDecls = cons(n,ghcConDecls);
-
+    name(n).arity     = arity;     /* Save constructor fun details    */
+    name(n).line      = line;
+    name(n).number    = cfunNo(conNo);
+    name(n).type      = type;
+    name(n).hasStrict = nStrict > 0;
     return n;
 }
 
-static Void local finishGHCCon(Name n)
+
+static List finishGHCDataDecl ( ConId tyc )
 {
-    Int  line = name(n).line;
-    Type ty   = name(n).type;
-    setCurrModule(name(n).mod);
-    name(n).type = fixupConType(line,ty);
+    List  nms;
+    Tycon tc = findTycon(textOf(tyc));
+#   ifdef DEBUG_IFACE
+    fprintf ( stderr, "begin finishGHCDataDecl %s\n", 
+              textToStr(textOf(tyc)) );
+#   endif
+    if (isNull(tc)) internal("finishGHCDataDecl");
+    
+    for (nms=tycon(tc).defn; nonNull(nms); nms=tl(nms)) {
+       Name n    = hd(nms);
+       Int  line = name(n).line;
+       assert(currentModule == name(n).mod);
+       name(n).type   = conidcellsToTycons(line,name(n).type);
+       name(n).parent = tc; //---????
+    }
+
+    return tycon(tc).defn;
 }
 
-Void addGHCNewType(line,tycon,tvs,constr)
-Int  line;
-Cell tycon;     /* ConId | QualConId     */
-List tvs;       /* [(VarId,Kind)]        */
-Cell constr; {
-    /* ToDo: worry about being given a decl for (->) ?
-     * and worry about qualidents for ()
-     */
+
+/* --------------------------------------------------------------------------
+ * Newtype decls
+ * ------------------------------------------------------------------------*/
+
+static Void startGHCNewType ( Int line, List ctx0, 
+                              ConId tycon, List tvs, Cell constr )
+{
+    /* ctx0   :: [((QConId,VarId))]                */
+    /* tycon  :: ConId                             */
+    /* tvs    :: [((VarId,Kind))]                  */
+    /* constr :: ((ConId,Type)) or NIL if abstract */
+    List tmp;
+    Type resTy;
     Text t = textOf(tycon);
+#   ifdef DEBUG_IFACE
+    fprintf(stderr, "begin startGHCNewType %s\n", textToStr(t) );
+#   endif
+
+    line = intOf(line);
+
     if (nonNull(findTycon(t))) {
         ERRMSG(line) "Repeated definition of type constructor \"%s\"",
                      textToStr(t)
@@ -434,44 +1860,94 @@ Cell constr; {
         /* can't really do this until I've read in all synonyms */
 
         if (isNull(constr)) {
-            tycon(tc).defn = NIL;
+           tycon(tc).defn = NIL;
         } else {
-            /* constr :: (ConId,Type) */
-            Text con   = textOf(fst(constr));
-            Type type  = snd(constr);
-            Name n = findName(con);     /* Allocate constructor fun name   */
-            if (isNull(n)) {
-                n = newName(con);
-            } else if (name(n).defn!=PREDEFINED) {
-                ERRMSG(line) "Repeated definition for constructor \"%s\"",
-                    textToStr(con)
-                EEND;
-            }
-            name(n).arity  = 1;         /* Save constructor fun details    */
-            name(n).line   = line;
-            name(n).number = cfunNo(0);
-            name(n).defn   = nameId;
-            tycon(tc).defn = singleton(n);
-
-            /* prepare for finishGHCCon */
-            /* ToDo: we use finishGHCCon instead of finishGHCVar in case
-             * there's any existential quantification in the newtype -
-             * but I don't think that's allowed in newtype constrs.
-             * Still, no harm done by doing it this way...
-             */
-            name(n).type   = type;
-            ghcConDecls = cons(n,ghcConDecls);
+           /* constr :: ((ConId,Type)) */
+           Text con   = textOf(zfst(constr));
+           Type type  = zsnd(constr);
+           Name n = findName(con);     /* Allocate constructor fun name   */
+           if (isNull(n)) {
+               n = newName(con,NIL);
+           } else if (name(n).defn!=PREDEFINED) {
+               ERRMSG(line) "Repeated definition for constructor \"%s\"",
+                  textToStr(con)
+               EEND;
+           }
+           name(n).arity  = 1;         /* Save constructor fun details    */
+           name(n).line   = line;
+           name(n).number = cfunNo(0);
+           name(n).defn   = nameId;
+           tycon(tc).defn = singleton(n);
+
+           /* make resTy the result type of the constr, T v1 ... vn */
+           resTy = tycon;
+           for (tmp=tvs; nonNull(tmp); tmp=tl(tmp))
+              resTy = ap(resTy,zfst(hd(tmp)));
+           type = fn(type,resTy);
+           if (nonNull(ctx0))
+              type = ap(QUAL,pair(ctx0,type));
+           type = tvsToOffsets(line,type,tvs);
+           name(n).type   = type;
         }
     }
 }
 
-Void addGHCClass(line,ctxt,tc_name,tvs,mems)
-Int  line;
-List ctxt;      /* [(ConId, [Type])]     */ 
-Cell tc_name;   /* ConId | QualConId     */
-List tvs;       /* [(VarId,Kind)]        */
-List mems; {
-    Text ct   = textOf(tc_name);
+
+static Void finishGHCNewType ( ConId tyc )
+{
+    Tycon tc = findTycon(textOf(tyc));
+#   ifdef DEBUG_IFACE
+    fprintf ( stderr, "begin finishGHCNewType %s\n", 
+              textToStr(textOf(tyc)) );
+#   endif
+    if (isNull(tc)) internal("finishGHCNewType");
+
+    if (isNull(tycon(tc).defn)) {
+       /* it's an abstract type */
+    }
+    else if (length(tycon(tc).defn) == 1) {
+       /* As we expect, has a single constructor */
+       Name n    = hd(tycon(tc).defn);
+       Int  line = name(n).line;
+       assert(currentModule == name(n).mod);
+       name(n).type = conidcellsToTycons(line,name(n).type);
+    } else {
+       internal("finishGHCNewType(2)");   
+    }
+}
+
+
+/* --------------------------------------------------------------------------
+ * Class declarations
+ * ------------------------------------------------------------------------*/
+
+static Void startGHCClass(line,ctxt,tc_name,kinded_tvs,mems0)
+Int   line;
+List  ctxt;       /* [((QConId, VarId))]   */ 
+ConId tc_name;    /* ConId                 */
+List  kinded_tvs; /* [((VarId, Kind))]     */
+List  mems0; {    /* [((VarId, Type))]     */
+
+    List mems;    /* [((VarId, Type))]     */
+    List tvsInT;  /* [VarId] and then [((VarId,Kind))] */
+    List tvs;     /* [((VarId,Kind))]      */
+    List ns;      /* [Name]                */
+    Int  mno;
+
+    ZPair kinded_tv = hd(kinded_tvs);
+    Text ct         = textOf(tc_name);
+    Pair newCtx     = pair(tc_name, zfst(kinded_tv));
+#   ifdef DEBUG_IFACE
+    fprintf ( stderr, "begin startGHCClass %s\n", textToStr(ct) );
+#   endif
+
+    line = intOf(line);
+    if (length(kinded_tvs) != 1) {
+        ERRMSG(line) "Cannot presently handle multiparam type classes in ifaces"
+        EEND;
+    }
+
     if (nonNull(findClass(ct))) {
         ERRMSG(line) "Repeated definition of class \"%s\"",
                      textToStr(ct)
@@ -481,308 +1957,453 @@ List mems; {
                      textToStr(ct)
         EEND;
     } else {
-        Class nw    = newClass(ct);
-        Int   arity = length(tvs);
-        Cell  head  = nw;
-        Int   i;
-        for(i=0; i < arity; ++i) {
-            head = ap(head,mkOffset(i));
-        }
+        Class nw              = newClass(ct);
+        cclass(nw).text       = ct;
         cclass(nw).line       = line;
-        cclass(nw).arity      = arity;
-        cclass(nw).head       = head;
-        cclass(nw).kinds      = tvsToKind(tvs);  /* ToDo: I don't think this is right */
+        cclass(nw).arity      = 1;
+        cclass(nw).head       = ap(nw,mkOffset(0));
+        cclass(nw).kinds      = singleton( zsnd(kinded_tv) );
         cclass(nw).instances  = NIL;
+        cclass(nw).numSupers  = length(ctxt);
+
+        /* Kludge to map the single tyvar in the context to Offset 0.
+           Need to do something better for multiparam type classes.
+        */
+        cclass(nw).supers     = tvsToOffsets(line,ctxt,
+                                             singleton(kinded_tv));
+
+
+        for (mems=mems0; nonNull(mems); mems=tl(mems)) {
+           ZPair mem  = hd(mems);
+           Type  memT = zsnd(mem);
+           Text  mnt  = textOf(zfst(mem));
+           Name  mn;
+
+           /* Stick the new context on the member type */
+           memT = dictapsToQualtype(memT);
+           if (whatIs(memT)==POLYTYPE) internal("startGHCClass");
+           if (whatIs(memT)==QUAL) {
+              memT = pair(QUAL,
+                          pair(cons(newCtx,fst(snd(memT))),snd(snd(memT))));
+           } else {
+              memT = pair(QUAL,
+                          pair(singleton(newCtx),memT));
+           }
+
+           /* Cook up a kind for the type. */
+           tvsInT = ifTyvarsIn(memT);
+           /* tvsInT :: [VarId] */
+
+           /* ToDo: maximally bogus.  We allow the class tyvar to
+              have the kind as supplied by the parser, but we just
+              assume that all others have kind *.  It's a kludge.
+           */
+           for (tvs=tvsInT; nonNull(tvs); tvs=tl(tvs)) {
+              Kind k;
+              if (textOf(hd(tvs)) == textOf(zfst(kinded_tv)))
+                 k = zsnd(kinded_tv); else
+                 k = STAR;
+              hd(tvs) = zpair(hd(tvs),k);
+           }
+           /* tvsIntT :: [((VarId,Kind))] */
+
+           memT = mkPolyType(tvsToKind(tvsInT),memT);
+           memT = tvsToOffsets(line,memT,tvsInT);
+
+           /* Park the type back on the member */
+           mem = zpair(zfst(mem),memT);
+
+           /* Bind code to the member */
+           mn = findName(mnt);
+           if (nonNull(mn)) {
+              ERRMSG(line) 
+                 "Repeated definition for class method \"%s\"",
+                 textToStr(mnt)
+              EEND;
+           }
+           mn = newName(mnt,NIL);
+
+           hd(mems) = mem;
+        }
 
-        /* prepare for finishGHCClass */
-        cclass(nw).supers  = pair(tvs,ctxt);    
-        cclass(nw).members = mems;
-        ghcClassDecls = cons(nw,ghcClassDecls);
+        cclass(nw).members    = mems0;
+        cclass(nw).numMembers = length(mems0);
 
-        /* ToDo: 
-         * cclass(nw).dsels    = ?;
-         * cclass(nw).dbuild   = ?;
-         * cclass(nm).dcon     = ?;
-         * cclass(nm).defaults = ?;
-         */
+        ns = NIL;
+        for (mno=0; mno<cclass(nw).numSupers; mno++) {
+           ns = cons(newDSel(nw,mno),ns);
+        }
+        cclass(nw).dsels = rev(ns);
     }
 }
 
-static Void  local finishGHCClass(Class nw)
-{
-    Int  line = cclass(nw).line;
-    List tvs  = fst(cclass(nw).supers);
-    List ctxt = snd(cclass(nw).supers);
-    List mems = cclass(nw).members;
 
-    setCurrModule(cclass(nw).mod);
+static Class finishGHCClass ( Tycon cls_tyc )
+{
+    List  mems;
+    Int   line;
+    Int   ctr;
+    Class nw = findClass ( textOf(cls_tyc) );
+#   ifdef DEBUG_IFACE
+    fprintf ( stderr, "begin finishGHCClass %s\n", textToStr(cclass(nw).text) );
+#   endif
+    if (isNull(nw)) internal("finishGHCClass");
+
+    line = cclass(nw).line;
+    ctr = -2;
+    assert (currentModule == cclass(nw).mod);
+
+    cclass(nw).level   = 0;
+    cclass(nw).head    = conidcellsToTycons(line,cclass(nw).head);
+    cclass(nw).supers  = conidcellsToTycons(line,cclass(nw).supers);
+    cclass(nw).members = conidcellsToTycons(line,cclass(nw).members);
+
+    for (mems=cclass(nw).members; nonNull(mems); mems=tl(mems)) {
+       Pair mem = hd(mems); /* (VarId, Type) */
+       Text txt = textOf(fst(mem));
+       Type ty  = snd(mem);
+       Name n   = findName(txt);
+       assert(nonNull(n));
+       name(n).text   = txt;
+       name(n).line   = cclass(nw).line;
+       name(n).type   = ty;
+       name(n).number = ctr--;
+       name(n).arity  = arityInclDictParams(name(n).type);
+       name(n).parent = nw;
+       hd(mems) = n;
+    }
 
-    cclass(nw).supers     = fixupContext(line,singleton(tvs),ctxt);
-    cclass(nw).numSupers  = length(cclass(nw).supers);
-    cclass(nw).members    = fixupMembers(line,mems);
-    cclass(nw).numMembers = length(cclass(nw).members);
-    cclass(nw).level      = 0;  /* ToDo: level = 1 + max (map level supers) */
+    return nw;
 }
 
-Void addGHCInstance (line,quant,cls,var)
-Int  line;
-Cell quant;
-Pair cls;   /* :: (ConId, [Type]) */
-Text var; {
+
+/* --------------------------------------------------------------------------
+ * Instances
+ * ------------------------------------------------------------------------*/
+
+static Inst startGHCInstance (line,ktyvars,cls,var)
+Int   line;
+List  ktyvars; /* [((VarId,Kind))] */
+Type  cls;     /* Type  */
+VarId var; {   /* VarId */
+    List tmp, tvs, ks, spec;
+
+    List xs1, xs2;
+    Kind k;
+
     Inst in = newInst();
+#   ifdef DEBUG_IFACE
+    fprintf ( stderr, "begin startGHCInstance\n" );
+#   endif
+
+    line = intOf(line);
+
+    tvs = ifTyvarsIn(cls);  /* :: [VarId] */
+    /* tvs :: [VarId].
+       The order of tvs is important for tvsToOffsets.
+       tvs should be a permutation of ktyvars.  Fish the tyvar kinds
+       out of ktyvars and attach them to tvs.
+    */
+    for (xs1=tvs; nonNull(xs1); xs1=tl(xs1)) {
+       k = NIL;
+       for (xs2=ktyvars; nonNull(xs2); xs2=tl(xs2))
+          if (textOf(hd(xs1)) == textOf(zfst(hd(xs2))))
+             k = zsnd(hd(xs2));
+       if (isNull(k)) internal("startGHCInstance: finding kinds");
+       hd(xs1) = zpair(hd(xs1),k);
+    }
 
-    List ctxt   = nonNull(quant) ? snd(quant) : NIL; /* [(ConId, [Type])] */
+    cls = tvsToOffsets(line,cls,tvs);
+    spec = NIL;
+    while (isAp(cls)) {
+       spec = cons(fun(cls),spec);
+       cls  = arg(cls);
+    }
+    spec = reverse(spec);
 
     inst(in).line         = line;
     inst(in).implements   = NIL;
+    inst(in).kinds        = simpleKind(length(tvs)); /* do this right */
+    inst(in).specifics    = spec;
+    inst(in).numSpecifics = length(spec);
+    inst(in).head         = cls;
+
+    /* Figure out the name of the class being instanced, and store it
+       at inst(in).c.  finishGHCInstance will resolve it to a real Class. */
+    { 
+       Cell cl = inst(in).head;
+       assert(whatIs(cl)==DICTAP);
+       cl = unap(DICTAP,cl);       
+       cl = fst(cl);
+       assert ( isQCon(cl) );
+       inst(in).c = cl;
+    }
 
     {
-        Name b         = newName(inventText());
+        Name b         = newName( /*inventText()*/ textOf(var),NIL);
         name(b).line   = line;
-        name(b).arity  = length(ctxt); /* unused? */
+        name(b).arity  = length(spec); /* unused? */ /* and surely wrong */
         name(b).number = DFUNNAME;
+        name(b).parent = in;
         inst(in).builder = b;
-        bindNameToClosure(b, lookupGHCClosure(inst(in).mod,var));
+        /* bindNameToClosure(b, lookupGHCClosure(inst(in).mod,var)); */
     }
 
-    /* prepare for finishGHCInstance */
-    inst(in).head      = cls;
-    inst(in).specifics = quant;
-    ghcInstanceDecls = cons(in,ghcInstanceDecls);
+    return in;
 }
 
-static Void  local finishGHCInstance(Inst in)
-{
-    Int  line   = inst(in).line;
-    Cell cl     = fst(inst(in).head);
-    List tys    = snd(inst(in).head);
-    Cell quant  = inst(in).specifics;
-    List tvs    = nonNull(quant) ? fst(quant) : NIL; /* [(VarId,Kind)]    */
-    List ctxt   = nonNull(quant) ? snd(quant) : NIL; /* [(ConId, [Type])] */
-    List tyvars = singleton(tvs);
-    Class c;
 
-    setCurrModule(inst(in).mod);
-    c = findClass(textOf(cl));
-    if (isNull(c)) {
-        ERRMSG(line) "Unknown class \"%s\" in instance",
-                     textToStr(textOf(cl))
-        EEND;
-    }
-    map2Over(fixupType,line,tyvars,tys);
-    inst(in).head         = applyToArgs(c,tys);
-    inst(in).specifics    = fixupContext(line,tyvars,ctxt);
-    inst(in).numSpecifics = length(inst(in).specifics);
-    cclass(c).instances = cons(in,cclass(c).instances);
+static Void finishGHCInstance ( Inst in )
+{
+    Int    line;
+    Class  c;
+    Type   cls;
+
+#   ifdef DEBUG_IFACE
+    fprintf ( stderr, "begin finishGHCInstance\n" );
+#   endif
+
+    assert (nonNull(in));
+    line = inst(in).line;
+    assert (currentModule==inst(in).mod);
+
+    /* inst(in).c is, prior to finishGHCInstance, a ConId or Tuple,
+       since startGHCInstance couldn't possibly have resolved it to
+       a Class at that point.  We convert it to a Class now.
+    */
+    c = inst(in).c;
+    assert(isQCon(c));
+    c = findQualClassWithoutConsultingExportList(c);
+    assert(nonNull(c));
+    inst(in).c = c;
+
+    inst(in).head         = conidcellsToTycons(line,inst(in).head);
+    inst(in).specifics    = conidcellsToTycons(line,inst(in).specifics);
+    cclass(c).instances   = cons(in,cclass(c).instances);
 }
 
+
 /* --------------------------------------------------------------------------
- * 
+ * Helper fns
  * ------------------------------------------------------------------------*/
 
-static Name local fixupMember(line,memNo,mem)
-Int  line;
-Int  memNo;
-Pair mem; { /* :: (Text,Type) */
-    Text t    = textOf(fst(mem));
-    Type type = snd(mem);
-    Name m    = findName(t);
-
-    if (isNull(m)) {
-        m = newName(t);
-    } else if (name(m).defn!=PREDEFINED) {
-        ERRMSG(line) "Repeated definition for member function \"%s\"",
-                     textToStr(t)
-        EEND;
-    }
-
-    name(m).line   = line;
-    name(m).arity  = 1;
-    name(m).number = mfunNo(memNo);
-    name(m).type   = fixupType(line,NIL,type);
-
-    /* ToDo: name(m).stgVar = ?; */
-
-    return m;
-}
-
-
-static List  local fixupMembers(line,ms)
-Int line;
-List ms; {
-    Int  memNo = 1;
-    List mems  = ms;
-    for(; nonNull(mems); mems=tl(mems), memNo++) {
-        hd(mems) = fixupMember(line,memNo,hd(mems));
-    }
-    return ms;
-}
-
-static Type local fixupTypeVar(line,tyvars,tv)
-Int  line;
-List tyvars; /* [[(VarId,Kind)]] */
-Text tv; {
-    Int  offset = 0;
-    for (; nonNull(tyvars); tyvars=tl(tyvars)) {
-        List tvs = hd(tyvars);
-        for (; nonNull(tvs); offset++, tvs=tl(tvs)) {
-            if (tv == textOf(fst(hd(tvs)))) {
-                return mkOffset(offset);
-            }
-        }
-    }
-    ERRMSG(line) "Undefined type variable \"%s\"", textToStr(tv)
-    EEND;
-}
+/* This is called from the startGHC* functions.  It traverses a structure
+   and converts varidcells, ie, type variables parsed by the interface
+   parser, into Offsets, which is how Hugs wants to see them internally.
+   The Offset for a type variable is determined by its place in the list
+   passed as the second arg; the associated kinds are irrelevant.
 
-static Class local fixupClass(line,cls)
-Int  line;
-Text cls; {
-    Class c = findClass(cls);
-    if (isNull(c)) {
-        ERRMSG(line)
-            "Undefined class \"%s\"", textToStr(cls)
-        EEND;
-    }
-    return c;
-}
+   ((t1,t2)) denotes the typed (z-)pair of t1 and t2.
+*/
 
-static Cell local fixupPred(line,tyvars,pred)
+/* tvsToOffsets :: LineNo -> Type -> [((VarId,Kind))] -> Type */
+static Type tvsToOffsets(line,type,ktyvars)
 Int  line;
-List tyvars; /* [[(VarId,Kind)]] */
-Pair pred; { /* (ConId,[Type])   */
-    Class c   = fixupClass(line,textOf(fst(pred)));
-    List  tys = snd(pred);
-
-    map2Over(fixupType,line,tyvars,tys);
-    return applyToArgs(c,tys);
+Type type;
+List ktyvars; { /* [((VarId,Kind))] */
+   switch (whatIs(type)) {
+      case NIL:
+      case TUPLE:
+      case QUALIDENT:
+      case CONIDCELL:
+      case TYCON:
+         return type;
+      case ZTUP2: /* convert to the untyped representation */
+         return ap( tvsToOffsets(line,zfst(type),ktyvars),
+                    tvsToOffsets(line,zsnd(type),ktyvars) );
+      case AP: 
+         return ap( tvsToOffsets(line,fun(type),ktyvars),
+                    tvsToOffsets(line,arg(type),ktyvars) );
+      case POLYTYPE: 
+         return mkPolyType ( 
+                   polySigOf(type),
+                   tvsToOffsets(line,monotypeOf(type),ktyvars)
+                );
+         break;
+      case QUAL:
+         return pair(QUAL,pair(tvsToOffsets(line,fst(snd(type)),ktyvars),
+                               tvsToOffsets(line,snd(snd(type)),ktyvars)));
+      case DICTAP: /* bogus ?? */
+         return ap(DICTAP, tvsToOffsets(line,snd(type),ktyvars));
+      case UNBOXEDTUP:  /* bogus?? */
+         return ap(UNBOXEDTUP, tvsToOffsets(line,snd(type),ktyvars));
+      case BANG:  /* bogus?? */
+         return ap(BANG, tvsToOffsets(line,snd(type),ktyvars));
+      case VARIDCELL: /* Ha! some real work to do! */
+       { Int i = 0;
+         Text tv = textOf(type);
+         for (; nonNull(ktyvars); i++,ktyvars=tl(ktyvars)) {
+            Cell varid;
+            Text tt;
+            assert(isZPair(hd(ktyvars)));
+            varid = zfst(hd(ktyvars));
+            tt    = textOf(varid);
+            if (tv == tt) return mkOffset(i);            
+         }
+         ERRMSG(line) "Undefined type variable \"%s\"", textToStr(tv)
+         EEND;
+         break;
+       }
+      default: 
+         fprintf(stderr, "tvsToOffsets: unknown stuff %d\n", whatIs(type));
+         print(type,20);
+         fprintf(stderr,"\n");
+         assert(0);
+   }
+   assert(0);
+   return NIL; /* NOTREACHED */
 }
 
-static List local fixupContext(line,tyvars,ctxt)
-Int  line;
-List tyvars; /* [[(VarId,Kind)]] */
-List ctxt; { /* [(ConId,[Type])] */
-    map2Over(fixupPred,line,tyvars,ctxt);
-    return ctxt;
-}
 
-static Type local fixupType(line,tyvars,type)
-Int  line;
-List tyvars; /* [[(VarId,Kind)]] */
-Type type; {
-    switch (whatIs(type)) {
-    case AP: 
-        {
-            fst(type) = fixupType(line,tyvars,fst(type));
-            snd(type) = fixupType(line,tyvars,snd(type));
-            break;
-        }
-    case DICTAP: 
-        {
-            /* Alternatively: raise an error.  These can only
-             * occur in the types of instance variables which
-             * we could easily separate from "real variables".
-             */
-            snd(type) = fixupPred(line,tyvars,snd(type));
-            break;
-        }
-    case VARIDCELL: 
-            return fixupTypeVar(line,tyvars,textOf(type));
-    case CONIDCELL: 
-        {   
-            Tycon tc = findQualTycon(type);
-            if (isNull(tc)) {
-                ERRMSG(line)
-                    "Undefined type constructor \"%s\"",
-                    identToStr(type)
-                EEND;
-            }
-            return tc;
-        }
-#if TREX
-    case EXT:
-#endif
-    case TYCON:
-    case TUPLE: 
-            break;
-    case POLYTYPE:
-        {   
-            List  tvs  = fst3(snd(type)); /* [(VarId, Kind)]   */
-            List  ctxt = snd3(snd(type)); /* [(ConId, [Type])] */ 
-            Type  ty   = thd3(snd(type)); 
-
-            if (nonNull(tvs)) {
-                tyvars = cons(tvs,tyvars);
-            }
-            type = fixupType(line,tyvars,ty);
-            
-            if (nonNull(ctxt)) {
-                type = ap(QUAL,pair(fixupContext(line,tyvars,ctxt),type));
-            }
-            if (nonNull(tvs)) {
-                type = mkPolyType(tvsToKind(tvs),type);
-            }
+/* This is called from the finishGHC* functions.  It traverses a structure
+   and converts conidcells, ie, type constructors parsed by the interface
+   parser, into Tycons (or Classes), which is how Hugs wants to see them
+   internally.  Calls to this fn have to be deferred to the second phase
+   of interface loading (finishGHC* rather than startGHC*) so that all relevant
+   Tycons or Classes have been loaded into the symbol tables and can be
+   looked up.
+*/
+static Type conidcellsToTycons ( Int line, Type type )
+{
+   switch (whatIs(type)) {
+      case NIL:
+      case OFFSET:
+      case TYCON:
+      case CLASS:
+      case VARIDCELL:
+      case TUPLE:
+      case STAR:
+         return type;
+      case QUALIDENT:
+       { Cell t;  /* Tycon or Class */
+         Text m     = qmodOf(type);
+         Module mod = findModule(m);
+         if (isNull(mod)) {
+            ERRMSG(line)
+               "Undefined module in qualified name \"%s\"",
+               identToStr(type)
+            EEND;
+            return NIL;
+         }
+         t = findQualTyconWithoutConsultingExportList(type);
+         if (nonNull(t)) return t;
+         t = findQualClassWithoutConsultingExportList(type);
+         if (nonNull(t)) return t;
+         ERRMSG(line)
+              "Undefined qualified class or type \"%s\"",
+              identToStr(type)
+         EEND;
+         return NIL;
+       }
+      case CONIDCELL:
+       { Tycon tc;
+         Class cl;
+         cl = findQualClass(type);
+         if (nonNull(cl)) return cl;
+         if (textOf(type)==findText("[]"))
+            /* a hack; magically qualify [] into PrelBase.[] */
+            return conidcellsToTycons(line, 
+                                      mkQualId(mkCon(findText("PrelBase")),type));
+         tc = findQualTycon(type);
+         if (nonNull(tc)) return tc;
+         ERRMSG(line)
+             "Undefined class or type constructor \"%s\"",
+             identToStr(type)
+         EEND;
+         return NIL;
+       }
+      case AP: 
+         return ap( conidcellsToTycons(line,fun(type)),
+                    conidcellsToTycons(line,arg(type)) );
+      case ZTUP2: /* convert to std pair */
+         return ap( conidcellsToTycons(line,zfst(type)),
+                    conidcellsToTycons(line,zsnd(type)) );
+
+      case POLYTYPE: 
+         return mkPolyType ( 
+                   polySigOf(type),
+                   conidcellsToTycons(line,monotypeOf(type))
+                );
+         break;
+      case QUAL:
+         return pair(QUAL,pair(conidcellsToTycons(line,fst(snd(type))),
+                               conidcellsToTycons(line,snd(snd(type)))));
+      case DICTAP: /* :: ap(DICTAP, pair(Class,Type))
+                      Not sure if this is really the right place to
+                      convert it to the form Hugs wants, but will do so anyway.
+                    */
+         /* return ap(DICTAP, conidcellsToTycons(line, snd(type))); */
+       {
+           Class cl   = fst(unap(DICTAP,type));
+           List  args = snd(unap(DICTAP,type));
+           return
+              conidcellsToTycons(line,pair(cl,args));
         }
-        break;
-    default:
-            internal("fixupType");
-    }
-    return type;
+      case UNBOXEDTUP:
+         return ap(UNBOXEDTUP, conidcellsToTycons(line, snd(type)));
+      case BANG:
+         return ap(BANG, conidcellsToTycons(line, snd(type)));
+      default: 
+         fprintf(stderr, "conidcellsToTycons: unknown stuff %d\n", 
+                 whatIs(type));
+         print(type,20);
+         fprintf(stderr,"\n");
+         assert(0);
+   }
+   assert(0);
+   return NIL; /* NOTREACHED */
 }
 
-/*    forall as bs. C1 as, C2 as bs => Ts as bs -> T as
- * => forall as. C1 as => exists bs. C2 as bs => Ts as bs -> T as
- */
-static Type local fixupConType(line,type)
-Int  line;
-Type type; {
-    List sig  = NIL;
-    List ctxt = NIL;
-    type = fixupType(line,NIL,type);
-
-    if (isPolyType(type)) {
-        sig = polySigOf(type);
-        type = monotypeOf(type);
-    }
-    if (whatIs(type) == QUAL) {
-        ctxt = fst(snd(type));
-        type = snd(snd(type));
-    }
-    { 
-        Type r_ty = type;
-        Int  nr2 = 0; /* maximum argnum which is a polytype */
-        Int  argnum = 1;
-        while (isAp(r_ty) && getHead(r_ty)==typeArrow) {
-            if (isPolyType(arg(fun(r_ty)))) {
-                nr2 = argnum;
-            }
-            argnum++;
-            r_ty = arg(r_ty);
-        }
 
-        if (nr2>0) {
-            type = ap(RANK2,pair(mkInt(nr2),type));
-        }
-        {   /* tyvars which don't appear in result are existentially quant'd */
-            List result_tvs = offsetTyvarsIn(r_ty,NIL);
-            List all_tvs    = offsetTyvarsIn(type,NIL);
-            Int etvs = length(all_tvs);
-            Int ntvs = length(result_tvs);
-            if (etvs>ntvs) {
-                /* ToDo: split the context into two parts */
-                type = ap(EXIST,pair(mkInt(etvs-ntvs),type));
-            }
-        }
-    }
-    if (nonNull(ctxt)) {
-        type = ap(QUAL,pair(ctxt,type));
-    }
-    if (nonNull(sig)) {
-        type = mkPolyType(sig,type);
-    }
-    return type;
+/* Find out if a type mentions a type constructor not present in 
+   the supplied list of qualified tycons.
+*/
+static Bool allTypesKnown ( Type  type, 
+                            List  aktys /* [QualId] */,
+                            ConId thisMod )
+{
+   switch (whatIs(type)) {
+      case NIL:
+      case OFFSET:
+      case VARIDCELL:
+      case TUPLE:
+         return TRUE;
+      case AP:
+         return allTypesKnown(fun(type),aktys,thisMod)
+                && allTypesKnown(arg(type),aktys,thisMod);
+      case ZTUP2:
+         return allTypesKnown(zfst(type),aktys,thisMod)
+                && allTypesKnown(zsnd(type),aktys,thisMod);
+      case DICTAP: 
+         return allTypesKnown(unap(DICTAP,type),aktys,thisMod);
+
+      case CONIDCELL:
+        if (textOf(type)==findText("[]"))
+            /* a hack; magically qualify [] into PrelBase.[] */
+            type = mkQualId(mkCon(findText("PrelBase")),type); else
+            type = mkQualId(thisMod,type);
+         /* fall through */
+      case QUALIDENT:
+         if (isNull(qualidIsMember(type,aktys))) goto missing;
+         return TRUE;
+      case TYCON:
+         return TRUE;
+
+      default: 
+         fprintf(stderr, "allTypesKnown: unknown stuff %d\n", whatIs(type));
+         print(type,10);printf("\n");
+         internal("allTypesKnown");
+         return TRUE; /*notreached*/
+   }
+  missing:
+#  ifdef DEBUG_IFACE
+   fprintf ( stderr,"allTypesKnown: unknown " ); print(type,10); 
+   fprintf(stderr,"\n");
+#  endif
+   return FALSE;
 }
 
+
 /* --------------------------------------------------------------------------
  * Utilities
  *
@@ -790,20 +2411,39 @@ Type type; {
  * so they can be performed while reading interfaces.
  * ------------------------------------------------------------------------*/
 
-static Kinds local tvsToKind(tvs)
-List tvs; { /* [(VarId,Kind)] */
-    List  rs = NIL;
-    Kinds r  = STAR; /* ToDo: hope this works */
-    for(; nonNull(tvs); tvs=tl(tvs)) { /* make reversed list of kinds */
-        rs = cons(snd(hd(tvs)),rs);
-    }
-    for(; nonNull(rs); rs=tl(rs)) { /* build full kind */
-        r = ap(hd(rs),r);
+/* tvsToKind :: [((VarId,Kind))] -> Kinds */
+static Kinds tvsToKind(tvs)
+List tvs; { /* [((VarId,Kind))] */
+    List  rs;
+    Kinds r  = STAR;
+    for (rs=reverse(tvs); nonNull(rs); rs=tl(rs)) {
+        if (whatIs(hd(rs)) != ZTUP2) internal("tvsToKind(1)");
+        if (whatIs(zfst(hd(rs))) != VARIDCELL) internal("tvsToKind(2)");
+        r = ap(zsnd(hd(rs)),r);
     }
     return r;
 }
 
-static Int local arityFromType(type) /* arity of a constructor with this type */
+
+static Int arityInclDictParams ( Type type )
+{
+   Int arity = 0;
+   if (isPolyType(type)) type = monotypeOf(type);
+   
+   if (whatIs(type) == QUAL)
+   {
+      arity += length ( fst(snd(type)) );
+      type = snd(snd(type));
+   }
+   while (isAp(type) && getHead(type)==typeArrow) {
+      arity++;
+      type = arg(type);
+   }
+   return arity;
+}
+
+/* arity of a constructor with this type */
+static Int arityFromType(type) 
 Type type; {
     Int arity = 0;
     if (isPolyType(type)) {
@@ -825,61 +2465,363 @@ Type type; {
     return arity;
 }
 
+
+/* ifTyvarsIn :: Type -> [VarId]
+   The returned list has no duplicates -- is a set.
+*/
+static List ifTyvarsIn(type)
+Type type; {
+    List vs = typeVarsIn(type,NIL,NIL,NIL);
+    List vs2 = vs;
+    for (; nonNull(vs2); vs2=tl(vs2))
+       if (whatIs(hd(vs2)) != VARIDCELL)
+          internal("ifTyvarsIn");
+    return vs;
+}
+
+
+
 /* --------------------------------------------------------------------------
- * Dynamic loading code (probably shouldn't be here)
- *
- * o .hi file explicitly says which .so file to load.
- *   This avoids the need for a 1-to-1 relationship between .hi and .so files.
- *
- *   ToDo: when doing a :reload, we ought to check the modification date 
- *         on the .so file.
- *
- * o module handles are unloaded (dlclosed) when we call dropScriptsFrom.
- *
- *   ToDo: do the same for foreign functions - but with complication that 
- *         there may be multiple .so files
+ * General object symbol query stuff
  * ------------------------------------------------------------------------*/
 
-/* ToDo: move some of this code (back) into dynamic.c and make it portable */
-#include <stdio.h>
+#define EXTERN_SYMS_ALLPLATFORMS     \
+      SymX(MainRegTable)              \
+      Sym(stg_gc_enter_1)            \
+      Sym(stg_gc_noregs)             \
+      Sym(stg_gc_seq_1)              \
+      Sym(stg_gc_d1)                 \
+      Sym(stg_gc_f1)                 \
+      Sym(stg_chk_0)                 \
+      Sym(stg_chk_1)                 \
+      Sym(stg_gen_chk)               \
+      SymX(stg_exit)                  \
+      SymX(stg_update_PAP)            \
+      SymX(stg_error_entry)           \
+      SymX(__ap_2_upd_info)           \
+      SymX(__ap_3_upd_info)           \
+      SymX(__ap_4_upd_info)           \
+      SymX(__ap_5_upd_info)           \
+      SymX(__ap_6_upd_info)           \
+      SymX(__ap_7_upd_info)           \
+      SymX(__ap_8_upd_info)           \
+      SymX(__sel_0_upd_info)          \
+      SymX(__sel_1_upd_info)          \
+      SymX(__sel_2_upd_info)          \
+      SymX(__sel_3_upd_info)          \
+      SymX(__sel_4_upd_info)          \
+      SymX(__sel_5_upd_info)          \
+      SymX(__sel_6_upd_info)          \
+      SymX(__sel_7_upd_info)          \
+      SymX(__sel_8_upd_info)          \
+      SymX(__sel_9_upd_info)          \
+      SymX(__sel_10_upd_info)         \
+      SymX(__sel_11_upd_info)         \
+      SymX(__sel_12_upd_info)         \
+      SymX(Upd_frame_info)            \
+      SymX(seq_frame_info)            \
+      SymX(CAF_BLACKHOLE_info)        \
+      SymX(IND_STATIC_info)           \
+      SymX(EMPTY_MVAR_info)           \
+      SymX(MUT_ARR_PTRS_FROZEN_info)  \
+      SymX(newCAF)                    \
+      SymX(putMVarzh_fast)            \
+      SymX(newMVarzh_fast)            \
+      SymX(takeMVarzh_fast)           \
+      SymX(catchzh_fast)              \
+      SymX(raisezh_fast)              \
+      SymX(delayzh_fast)              \
+      SymX(yieldzh_fast)              \
+      SymX(killThreadzh_fast)         \
+      SymX(waitReadzh_fast)           \
+      SymX(waitWritezh_fast)          \
+      SymX(CHARLIKE_closure)          \
+      SymX(INTLIKE_closure)           \
+      SymX(suspendThread)             \
+      SymX(resumeThread)              \
+      Sym(stackOverflow)             \
+      SymX(int2Integerzh_fast)        \
+      Sym(stg_gc_unbx_r1)            \
+      SymX(ErrorHdrHook)              \
+      SymX(mkForeignObjzh_fast)       \
+      SymX(__encodeDouble)            \
+      SymX(decodeDoublezh_fast)       \
+      SymX(isDoubleNaN)               \
+      SymX(isDoubleInfinite)          \
+      SymX(isDoubleDenormalized)      \
+      SymX(isDoubleNegativeZero)      \
+      SymX(__encodeFloat)             \
+      SymX(decodeFloatzh_fast)        \
+      SymX(isFloatNaN)                \
+      SymX(isFloatInfinite)           \
+      SymX(isFloatDenormalized)       \
+      SymX(isFloatNegativeZero)       \
+      SymX(__int_encodeFloat)         \
+      SymX(__int_encodeDouble)        \
+      SymX(mpz_cmp_si)                \
+      SymX(mpz_cmp)                   \
+      SymX(__mpn_gcd_1)               \
+      SymX(gcdIntegerzh_fast)         \
+      SymX(newArrayzh_fast)           \
+      SymX(unsafeThawArrayzh_fast)    \
+      SymX(newDoubleArrayzh_fast)     \
+      SymX(newFloatArrayzh_fast)      \
+      SymX(newAddrArrayzh_fast)       \
+      SymX(newWordArrayzh_fast)       \
+      SymX(newIntArrayzh_fast)        \
+      SymX(newCharArrayzh_fast)       \
+      SymX(newMutVarzh_fast)          \
+      SymX(quotRemIntegerzh_fast)     \
+      SymX(quotIntegerzh_fast)        \
+      SymX(remIntegerzh_fast)         \
+      SymX(divExactIntegerzh_fast)    \
+      SymX(divModIntegerzh_fast)      \
+      SymX(timesIntegerzh_fast)       \
+      SymX(minusIntegerzh_fast)       \
+      SymX(plusIntegerzh_fast)        \
+      SymX(addr2Integerzh_fast)       \
+      SymX(mkWeakzh_fast)             \
+      SymX(prog_argv)                 \
+      SymX(prog_argc)                 \
+      Sym(resetNonBlockingFd)        \
+      SymX(getStablePtr)              \
+      SymX(stable_ptr_table)          \
+      Sym(createAdjThunk)            \
+      SymX(shutdownHaskellAndExit)    \
+      Sym(stg_enterStackTop)         \
+      SymX(CAF_UNENTERED_entry)       \
+      Sym(stg_yield_to_Hugs)         \
+      Sym(StgReturn)                 \
+      Sym(init_stack)                \
+      SymX(blockAsyncExceptionszh_fast)    \
+      SymX(unblockAsyncExceptionszh_fast)  \
+                                     \
+      /* needed by libHS_cbits */    \
+      SymX(malloc)                   \
+      SymX(close)                    \
+      Sym(mkdir)                     \
+      SymX(close)                    \
+      Sym(opendir)                   \
+      Sym(closedir)                  \
+      Sym(readdir)                   \
+      Sym(tcgetattr)                 \
+      Sym(tcsetattr)                 \
+      SymX(isatty)                   \
+      SymX(read)                     \
+      SymX(lseek)                    \
+      SymX(write)                    \
+      Sym(getrusage)                 \
+      SymX(realloc)                  \
+      SymX(getcwd)                   \
+      SymX(free)                     \
+      SymX(strcpy)                   \
+      Sym(fcntl)                     \
+      SymX(fprintf)                  \
+      SymX(exit)                     \
+      Sym(open)                      \
+      SymX(unlink)                   \
+      SymX(memcpy)                   \
+      SymX(memchr)                   \
+      SymX(rmdir)                    \
+      SymX(rename)                   \
+      SymX(chdir)                    \
+      SymX(execl)                    \
+      Sym(waitpid)                   \
+      SymX(getenv)                   \
+
+#define EXTERN_SYMS_cygwin32         \
+      SymX(GetCurrentProcess)        \
+      SymX(GetProcessTimes)          \
+      Sym(__udivdi3)                 \
+      SymX(bzero)                    \
+      Sym(select)                    \
+      SymX(_impure_ptr)              \
+      Sym(lstat)                     \
+      Sym(setmode)                   \
+      SymX(system)                   \
+      SymX(sleep)                    \
+      SymX(__imp__tzname)            \
+      SymX(__imp__timezone)          \
+      SymX(tzset)                    \
+      SymX(log)                      \
+      SymX(exp)                      \
+      Sym(sqrt)                      \
+      Sym(sin)                       \
+      Sym(cos)                       \
+      SymX(pow)                      \
+      SymX(__errno)                  \
+      Sym(stat)                      \
+      Sym(fstat)                     \
+      Sym(gettimeofday)              \
+      SymX(localtime)                \
+      SymX(strftime)                 \
+      SymX(mktime)                   \
+      SymX(gmtime)
+
+
+#define EXTERN_SYMS_linux            \
+      SymX(__errno_location)         \
+      Sym(__xstat)                   \
+      Sym(__fxstat)                  \
+      Sym(__lxstat)                  \
+      SymX(select)                   \
+      SymX(stderr)                   \
+      SymX(vfork)                    \
+      SymX(_exit)                    \
+      SymX(tzname)                   \
+      SymX(localtime)                \
+      SymX(strftime)                 \
+      SymX(timezone)                 \
+      SymX(mktime)                   \
+      SymX(gmtime)                   \
+      Sym(setitimer)                 \
+      Sym(chmod)                     \
+      Sym(gettimeofday)              \
+
+#define EXTERN_SYMS_solaris2         \
+      SymX(gettimeofday)             \
+
+
+#if defined(linux_TARGET_OS)
+#define EXTERN_SYMS_THISPLATFORM EXTERN_SYMS_linux
+#endif
+
+#if defined(solaris2_TARGET_OS)
+#define EXTERN_SYMS_THISPLATFORM EXTERN_SYMS_solaris2
+#endif
+
+#if defined(cygwin32_TARGET_OS)
+#define EXTERN_SYMS_THISPLATFORM EXTERN_SYMS_cygwin32
+#endif
+
+
+
+/* entirely bogus claims about types of these symbols */
+#define Sym(vvv)  extern void (vvv);
+#define SymX(vvv) /**/
+EXTERN_SYMS_ALLPLATFORMS
+EXTERN_SYMS_THISPLATFORM
+#undef Sym
+#undef SymX
+
+
+#define Sym(vvv)  { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
+                    (void*)(&(vvv)) },
+#define SymX(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
+                    (void*)(&(vvv)) },
+OSym rtsTab[] 
+   = { 
+       EXTERN_SYMS_ALLPLATFORMS
+       EXTERN_SYMS_THISPLATFORM
+       {0,0} 
+     };
+#undef Sym
+#undef SymX
 
-static AsmClosure local lookupGHCClosure( Module m, Text t )
+
+
+
+/* A kludge to assist Win32 debugging. */
+char* nameFromStaticOPtr ( void* ptr )
 {
-    char symbol[100]; /* ToDo: arbitrary constants must die */
-    void *c;
-    sprintf(symbol,"%s_%s_closure",textToStr(module(m).text),textToStr(t));
-    if (module(m).objectFile == NULL) {
-        ERRMSG(0) "Interface file must \"require\" at least one file"
-        EEND;
-    }
-    c = lookupSymbol(module(m).objectFile,symbol);
-    if (NULL == c) {
-        ERRMSG(0) "Error %s while importing symbol \"%s\"", dlerror(), symbol
-        EEND;
-    }
-    return ((AsmClosure)c);
+   int k;
+   for (k = 0; rtsTab[k].nm; k++)
+      if (ptr == rtsTab[k].ad)
+         return rtsTab[k].nm;
+   return NULL;
 }
 
-Void loadSharedLib( String fn )
+
+void* lookupObjName ( char* nm )
 {
-    if (module(currentModule).objectFile != NULL) {
-        ERRMSG(0) "Interface file \"require\"s two files"
-        EEND;
-    }
-    module(currentModule).objectFile = loadLibrary(fn);
-    if (NULL == module(currentModule).objectFile) {
-        ERRMSG(0) "Error %s while importing DLL \"%s\"", dlerror(), fn
-        EEND;
-    }
+   int    k;
+   char*  pp;
+   void*  a;
+   Text   t;
+   Module m;
+   char   nm2[200];
+   int    first_real_char;
+
+   nm2[199] = 0;
+   strncpy(nm2,nm,200);
+
+   /*  first see if it's an RTS name */
+   for (k = 0; rtsTab[k].nm; k++)
+      if (0==strcmp(nm2,rtsTab[k].nm))
+         return rtsTab[k].ad;
+
+   /* perhaps an extra-symbol ? */
+   a = lookupOExtraTabName ( nm );
+   if (a) return a;
+
+#  if LEADING_UNDERSCORE
+   first_real_char = 1;
+#  else
+   first_real_char = 0;
+#  endif
+
+   /* Maybe it's an __init_Module thing? */
+   if (strlen(nm2+first_real_char) > 7
+       && strncmp(nm2+first_real_char, "__init_", 7)==0) {
+      t = unZcodeThenFindText(nm2+first_real_char+7);
+      if (t == findText("PrelGHC")) return (4+NULL); /* kludge */
+      m = findModule(t);
+      if (isNull(m)) goto dire_straits;
+      a = lookupOTabName ( m, nm );
+      if (a) return a;
+      goto dire_straits;
+   }
+
+   /* if not an RTS name, look in the 
+      relevant module's object symbol table
+   */
+   pp = strchr(nm2+first_real_char, '_');
+   if (!pp || !isupper(nm2[first_real_char])) goto dire_straits;
+   *pp = 0;
+   t = unZcodeThenFindText(nm2+first_real_char);
+   m = findModule(t);
+   if (isNull(m)) goto dire_straits;
+
+   a = lookupOTabName ( m, nm );  /* RATIONALISE */
+   if (a) return a;
+
+  dire_straits:
+   /* make a desperate, last-ditch attempt to find it */
+   a = lookupOTabNameAbsolutelyEverywhere ( nm );
+   if (a) return a;
+
+   fprintf ( stderr, 
+             "lookupObjName: can't resolve name `%s'\n", 
+             nm );
+   assert(0);
+   return NULL;
 }
 
-static void bindNameToClosure(n,c)
-Name n;
-AsmClosure c; {
-    StgVar v = mkStgVar(NIL,mkPtr(asmMkObject(c)));
-    name(n).stgVar = v;
+
+int is_dynamically_loaded_code_or_rodata_ptr ( char* p )
+{
+   OSectionKind sk = lookupSection(p);
+   assert (sk != HUGS_SECTIONKIND_NOINFOAVAIL);
+   return (sk == HUGS_SECTIONKIND_CODE_OR_RODATA);
+}
+
+
+int is_dynamically_loaded_rwdata_ptr ( char* p )
+{
+   OSectionKind sk = lookupSection(p);
+   assert (sk != HUGS_SECTIONKIND_NOINFOAVAIL);
+   return (sk == HUGS_SECTIONKIND_RWDATA);
 }
 
+
+int is_not_dynamically_loaded_ptr ( char* p )
+{
+   OSectionKind sk = lookupSection(p);
+   assert (sk != HUGS_SECTIONKIND_NOINFOAVAIL);
+   return (sk == HUGS_SECTIONKIND_OTHER);
+}
+
+
 /* --------------------------------------------------------------------------
  * Control:
  * ------------------------------------------------------------------------*/
@@ -887,24 +2829,16 @@ AsmClosure c; {
 Void interface(what)
 Int what; {
     switch (what) {
-    case RESET: 
-            interfaces       = NIL;
-            ghcVarDecls      = NIL;     
-            ghcConDecls      = NIL;     
-            ghcSynonymDecls  = NIL;
-            ghcClassDecls    = NIL;
-            ghcInstanceDecls = NIL;
-            break;
-    case MARK: 
-            mark(interfaces);
-            mark(ghcVarDecls);     
-            mark(ghcConDecls);     
-            mark(ghcSynonymDecls); 
-            mark(ghcClassDecls); 
-            mark(ghcInstanceDecls);
-            break;
+       case POSTPREL: break;
+
+       case PREPREL:
+       case RESET: 
+          ifaces_outstanding  = NIL;
+          break;
+       case MARK: 
+          mark(ifaces_outstanding);
+          break;
     }
 }
 
 /*-------------------------------------------------------------------------*/
-