2 /* --------------------------------------------------------------------------
3 * GHC interface file processing for Hugs
5 * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
6 * All rights reserved. See NOTICE for details and conditions of use etc...
7 * Hugs version 1.4, December 1997
9 * $RCSfile: interface.c,v $
11 * $Date: 1999/07/06 15:24:38 $
12 * ------------------------------------------------------------------------*/
16 * o use vectored CONSTR_entry when appropriate
17 * o generate export list
19 * Needs GHC changes to generate member selectors,
20 * superclass selectors, etc
22 * o dictionary constructors ?
24 * o Get Hugs/GHC to agree on what interface files look like.
25 * o figure out how to replace the Hugs Prelude with the GHC Prelude
34 #include "Assembler.h" /* for wrapping GHC objects */
39 extern void print ( Cell, Int );
41 /* --------------------------------------------------------------------------
42 * The "addGHC*" functions act as "impedence matchers" between GHC
43 * interface files and Hugs. Their main job is to convert abstract
44 * syntax trees into Hugs' internal representations.
46 * The main trick here is how we deal with mutually recursive interface
49 * o As we read an import decl, we add it to a list of required imports
50 * (unless it's already loaded, of course).
52 * o Processing of declarations is split into two phases:
54 * 1) While reading the interface files, we construct all the Names,
55 * Tycons, etc declared in the interface file but we don't try to
56 * resolve references to any entities the declaration mentions.
58 * This is done by the "addGHC*" functions.
60 * 2) After reading all the interface files, we finish processing the
61 * declarations by resolving any references in the declarations
62 * and doing any other processing that may be required.
64 * This is done by the "finishGHC*" functions which use the
65 * "fixup*" functions to assist them.
67 * The interface between these two phases are the "ghc*Decls" which
68 * contain lists of decls that haven't been completed yet.
70 * ------------------------------------------------------------------------*/
72 /* --------------------------------------------------------------------------
74 * ------------------------------------------------------------------------*/
76 static List ghcVarDecls;
77 static List ghcConstrDecls;
78 static List ghcSynonymDecls;
79 static List ghcClassDecls;
80 static List ghcInstanceDecls;
82 /* --------------------------------------------------------------------------
83 * local function prototypes:
84 * ------------------------------------------------------------------------*/
86 static List local addGHCConstrs Args((Int,List,List));
87 static Name local addGHCSel Args((Int,Pair));
88 static Name local addGHCConstr Args((Int,Int,Triple));
91 static Void local finishGHCVar Args((Name));
92 static Void local finishGHCConstr Args((Name));
93 static Void local finishGHCSynonym Args((Tycon));
94 static Void local finishGHCClass Args((Class));
95 static Void local finishGHCInstance Args((Inst));
96 static Void local finishGHCImports Args((Triple));
97 static Void local finishGHCExports Args((Pair));
98 static Void local finishGHCModule Args((Module));
100 static Kinds local tvsToKind Args((List));
101 static Int local arityFromType Args((Type));
102 static Int local arityInclDictParams Args((Type));
105 static List local ifTyvarsIn Args((Type));
107 static Type local tvsToOffsets Args((Int,Type,List));
108 static Type local conidcellsToTycons Args((Int,Type));
110 static Void local resolveReferencesInObjectModule Args((Module,Bool));
111 static Bool local validateOImage Args((void*, Int, Bool));
112 static Void local readSyms Args((Module));
114 static void* local lookupObjName ( char* );
117 /* --------------------------------------------------------------------------
119 * ------------------------------------------------------------------------*/
121 List ifImports; /* [ConId] -- modules imported by current interface */
123 List ghcImports; /* [(Module, Text, [ConId|VarId])]
124 each (m1, m2, names) in this list
125 represents 'module m1 where ... import m2 ( names ) ...'
126 The list acts as a list of names to fix up in
130 List ghcExports; /* [(ConId, -- module name
131 [ ConId | VarId | pair(ConId,[ConId|VarId])] )]
135 List ghcModules; /* [Module] -- modules of the .his loaded in this group */
137 Void addGHCExports(mod,stuff)
140 ghcExports = cons( pair(mod,stuff), ghcExports );
143 static Void local finishGHCExports(paire)
145 Text modTxt = textOf(fst(paire));
146 List entities = snd(paire);
147 Module mod = findModule(modTxt);
149 ERRMSG(0) "Can't find module \"%s\" mentioned in export list",
153 fprintf(stderr, "----------------------------------finishexports\n");
154 /* Assume that each .hi file only contains one export decl */
155 if (nonNull(module(mod).exports))
156 internal("finishGHCExports: non-empty export list");
158 /* Run along what the parser gave us and make export list entries */
159 for (; nonNull(entities); entities=tl(entities)) {
160 Cell ent = hd(entities);
163 switch (whatIs(ent)) {
164 case VARIDCELL: /* variable */
165 c = findName ( snd(ent) );
167 fprintf(stderr, "var %s\n", textToStr(name(c).text));
168 module(mod).exports = cons(c, module(mod).exports);
170 case CONIDCELL: /* non data tycon */
171 c = findTycon ( snd(ent) );
173 fprintf(stderr, "non data tycon %s\n", textToStr(tycon(c).text));
174 module(mod).exports = cons(c, module(mod).exports);
176 default: /* data T = C1 ... Cn or class C where f1 ... fn */
177 if (!isPair(ent)) internal("finishExports(2)");
180 c = findTycon ( snd(ent) );
183 fprintf(stderr, "data %s = ", textToStr(tycon(c).text));
184 module(mod).exports = cons(pair(c,DOTDOT), module(mod).exports);
185 for (; nonNull(subents); subents = tl(subents)) {
186 Cell ent2 = hd(subents);
188 c = findName ( snd(ent2) );
189 fprintf(stderr, "%s ", textToStr(name(c).text));
191 module(mod).exports = cons(c, module(mod).exports);
193 fprintf(stderr, "\n" );
196 c = findClass ( snd(ent) );
198 fprintf(stderr, "class %s where ", textToStr(cclass(c).text));
199 module(mod).exports = cons(pair(c,DOTDOT), module(mod).exports);
201 for (; nonNull(subents); subents = tl(subents)) {
202 Cell ent2 = hd(subents);
204 c = findName ( snd(ent2) );
205 fprintf(stderr, "%s ", textToStr(name(c).text));
207 module(mod).exports = cons(c, module(mod).exports);
209 fprintf(stderr, "\n" );
217 static Void local finishGHCImports(triple)
220 Module dstMod = fst3(triple); // the importing module
221 Text srcTxt = snd3(triple);
222 List names = thd3(triple);
223 Module srcMod = findModule ( srcTxt );
224 Module tmpCurrentModule = currentModule;
230 //fprintf(stderr, "finishGHCImports: dst=%s src=%s\n",
231 // textToStr(module(dstMod).text),
232 // textToStr(srcTxt) );
235 /* for each nm in names
236 nm should be in module(src).exports -- if not, error
237 if nm notElem module(dst).names cons it on
240 if (isNull(srcMod)) {
241 /* I don't think this can actually ever happen, but still ... */
242 ERRMSG(0) "Interface for module \"%s\" imports unknown module \"%s\"",
243 textToStr(module(dstMod).text),
247 //printf ( "exports of %s are\n", textToStr(module(srcMod).text) );
248 //print( module(srcMod).exports, 100 );
251 setCurrModule ( srcMod ); // so that later lookups succeed
253 for (; nonNull(names); names=tl(names)) {
255 /* Check the exporting module really exports it. */
257 for (exps=module(srcMod).exports; nonNull(exps); exps=tl(exps)) {
259 //if (isPair(c)) c=fst(c);
260 assert(whatIs(c)==CONIDCELL || whatIs(c)==VARIDCELL);
261 assert(whatIs(nm)==CONIDCELL || whatIs(nm)==VARIDCELL);
262 //printf( " compare `%s' `%s'\n", textToStr(textOf(c)), textToStr(textOf(nm)));
263 if (textOf(c)==textOf(nm)) { found=TRUE; break; }
266 ERRMSG(0) "Interface for module \"%s\" imports \"%s\" from\n"
267 "module \"%s\", but the latter doesn't export it",
268 textToStr(module(dstMod).text), textToStr(textOf(nm)),
269 textToStr(module(srcMod).text)
272 /* Ok, it's exported. Now figure out what it is we're really
279 if (!cellIsMember(x,module(dstMod).names))
280 module(dstMod).names = cons(x, module(dstMod).names);
286 if (!cellIsMember(x,module(dstMod).tycons))
287 module(dstMod).tycons = cons(x, module(dstMod).tycons);
293 if (!cellIsMember(x,module(dstMod).classes))
294 module(dstMod).classes = cons(x, module(dstMod).classes);
298 fprintf(stderr, "\npanic: Can't figure out what this is in finishGHCImports\n"
299 "\t%s\n", textToStr(tnm) );
300 internal("finishGHCImports");
303 setCurrModule(tmpCurrentModule);
307 Void loadInterface(String fname, Long fileSize)
310 parseInterface(fname,fileSize);
311 if (nonNull(ifImports))
316 Void finishInterfaces ( void )
318 /* the order of these doesn't matter
319 * (ToDo: unless synonyms have to be eliminated??)
321 mapProc(finishGHCVar, ghcVarDecls);
322 mapProc(finishGHCConstr, ghcConstrDecls);
323 mapProc(finishGHCSynonym, ghcSynonymDecls);
324 mapProc(finishGHCClass, ghcClassDecls);
325 mapProc(finishGHCInstance, ghcInstanceDecls);
326 mapProc(finishGHCExports, ghcExports);
327 mapProc(finishGHCImports, ghcImports);
328 mapProc(finishGHCModule, ghcModules);
330 ghcConstrDecls = NIL;
331 ghcSynonymDecls = NIL;
333 ghcInstanceDecls = NIL;
340 static Void local finishGHCModule(mod)
342 // do the implicit 'import Prelude' thing
343 List pxs = module(modulePrelude).exports;
344 for (; nonNull(pxs); pxs=tl(pxs)) {
347 switch (whatIs(px)) {
352 module(mod).names = cons ( px, module(mod).names );
355 module(mod).tycons = cons ( px, module(mod).tycons );
358 module(mod).classes = cons ( px, module(mod).classes );
361 fprintf(stderr, "finishGHCModule: unknown tag %d\n", whatIs(px));
366 // Last, but by no means least ...
367 resolveReferencesInObjectModule ( mod, FALSE );
375 Module m = findModule(t);
378 printf ( "new module %s\n", textToStr(t) );
379 } else if (m != modulePrelude) {
380 ERRMSG(0) "Module \"%s\" already loaded", textToStr(t)
384 // sizeObj and nameObj will magically be set to the right
385 // thing when we arrive here.
386 // All this crud should be replaced with mmap when we do this
388 img = malloc ( sizeObj );
390 ERRMSG(0) "Can't allocate memory to load object file for module \"%s\"",
394 f = fopen( nameObj, "rb" );
396 // Really, this shouldn't happen, since makeStackEntry ensures the
397 // object is available. Nevertheless ...
398 ERRMSG(0) "Object file \"%s\" can't be opened to read -- oops!",
402 if (sizeObj != fread ( img, 1, sizeObj, f)) {
403 ERRMSG(0) "Read of object file \"%s\" failed", nameObj
406 if (!validateOImage(img,sizeObj,FALSE)) {
407 ERRMSG(0) "Validation of object file \"%s\" failed", nameObj
411 assert(!module(m).oImage);
412 module(m).oImage = img;
416 if (!cellIsMember(m, ghcModules))
417 ghcModules = cons(m, ghcModules);
423 Void addGHCImports(line,mn,syms)
425 Text mn; /* the module to import from */
426 List syms; { /* [ConId | VarId] -- the names to import */
430 printf("\naddGHCImport %s\n", textToStr(mn) );
433 // Hack to avoid chasing Prel* junk right now
434 if (strncmp(textToStr(mn), "Prel",4)==0) return;
437 for (t=ifImports; nonNull(t); t=tl(t)) {
438 if (textOf(hd(t)) == mn) {
444 ifImports = cons(mkCon(mn),ifImports);
445 ghcImports = cons( triple(currentModule,mn,syms), ghcImports );
449 void addGHCVar(line,v,ty)
457 /* if this var is the name of a ghc-compiled dictionary,
458 ie, starts zdfC where C is a capital,
463 printf("\nbegin addGHCVar %s\n", s);
465 if (s[0]=='z' && s[1]=='d' && s[2]=='f' && isupper((int)s[3])) {
467 printf(" ignoring %s\n", s);
473 ERRMSG(0) "Attempt to redefine variable \"%s\"", textToStr(v)
478 tvs = nubList(ifTyvarsIn(ty));
479 for (tmp=tvs; nonNull(tmp); tmp=tl(tmp))
480 hd(tmp) = pair(hd(tmp),STAR);
482 ty = mkPolyType(tvsToKind(tvs),ty);
484 ty = tvsToOffsets(line,ty,tvs);
486 /* prepare for finishGHCVar */
488 name(n).arity = arityInclDictParams(ty);
490 ghcVarDecls = cons(n,ghcVarDecls);
492 printf("end addGHCVar %s\n", s);
496 static Void local finishGHCVar(Name n)
498 Int line = name(n).line;
499 Type ty = name(n).type;
501 fprintf(stderr, "\nbegin finishGHCVar %s\n", textToStr(name(n).text) );
503 setCurrModule(name(n).mod);
504 name(n).type = conidcellsToTycons(line,ty);
506 fprintf(stderr, "end finishGHCVar %s\n", textToStr(name(n).text) );
510 Void addGHCSynonym(line,tycon,tvs,ty)
512 Cell tycon; /* ConId */
513 List tvs; /* [(VarId,Kind)] */
515 /* ToDo: worry about being given a decl for (->) ?
516 * and worry about qualidents for ()
518 Text t = textOf(tycon);
519 if (nonNull(findTycon(t))) {
520 ERRMSG(line) "Repeated definition of type constructor \"%s\"",
524 Tycon tc = newTycon(t);
525 tycon(tc).line = line;
526 tycon(tc).arity = length(tvs);
527 tycon(tc).what = SYNONYM;
528 tycon(tc).kind = tvsToKind(tvs);
530 /* prepare for finishGHCSynonym */
531 tycon(tc).defn = tvsToOffsets(line,ty,tvs);
532 ghcSynonymDecls = cons(tc,ghcSynonymDecls);
536 static Void local finishGHCSynonym(Tycon tc)
538 Int line = tycon(tc).line;
540 setCurrModule(tycon(tc).mod);
541 tycon(tc).defn = conidcellsToTycons(line,tycon(tc).defn);
543 /* ToDo: can't really do this until I've done all synonyms
544 * and then I have to do them in order
545 * tycon(tc).defn = fullExpand(ty);
549 Void addGHCDataDecl(line,ctx0,tycon,ktyvars,constrs0)
551 List ctx0; /* [(QConId,VarId)] */
552 Cell tycon; /* ConId */
553 List ktyvars; /* [(VarId,Kind)] */
554 List constrs0; /* [(ConId,[(Type,Text)],NIL)]
555 The NIL will become the constr's type
556 The Text is an optional field name */
557 /* ToDo: worry about being given a decl for (->) ?
558 * and worry about qualidents for ()
561 Type ty, resTy, selTy, conArgTy;
562 List tmp, conArgs, sels, constrs, fields, tyvarsMentioned;
566 Pair conArg, ctxElem;
569 Text t = textOf(tycon);
571 fprintf(stderr, "\nbegin addGHCDataDecl %s\n",textToStr(t));
573 if (nonNull(findTycon(t))) {
574 ERRMSG(line) "Repeated definition of type constructor \"%s\"",
578 Tycon tc = newTycon(t);
580 tycon(tc).line = line;
581 tycon(tc).arity = length(ktyvars);
582 tycon(tc).kind = tvsToKind(ktyvars);
583 tycon(tc).what = DATATYPE;
585 /* a list to accumulate selectors in :: [(VarId,Type)] */
588 /* make resTy the result type of the constr, T v1 ... vn */
590 for (tmp=ktyvars; nonNull(tmp); tmp=tl(tmp))
591 resTy = ap(resTy,fst(hd(tmp)));
593 /* for each constructor ... */
594 for (constrs=constrs0; nonNull(constrs); constrs=tl(constrs)) {
595 constr = hd(constrs);
596 conid = fst3(constr);
597 fields = snd3(constr);
598 assert(isNull(thd3(constr)));
600 /* Build type of constr and handle any selectors found.
601 Also collect up tyvars occurring in the constr's arg
602 types, so we can throw away irrelevant parts of the
606 tyvarsMentioned = NIL; /* [VarId] */
607 conArgs = reverse(fields);
608 for (; nonNull(conArgs); conArgs=tl(conArgs)) {
609 conArg = hd(conArgs); /* (Type,Text) */
610 conArgTy = fst(conArg);
611 conArgNm = snd(conArg);
612 tyvarsMentioned = dupListOnto(ifTyvarsIn(conArgTy),
614 ty = fn(conArgTy,ty);
615 if (nonNull(conArgNm)) {
616 /* a field name is mentioned too */
617 selTy = fn(resTy,conArgTy);
618 if (whatIs(tycon(tc).kind) != STAR)
619 selTy = pair(POLYTYPE,pair(tycon(tc).kind, selTy));
620 selTy = tvsToOffsets(line,selTy, ktyvars);
622 sels = cons( pair(conArgNm,selTy), sels);
626 /* Now ty is the constructor's type, not including context.
627 Throw away any parts of the context not mentioned in
628 tyvarsMentioned, and use it to qualify ty.
631 for (ctx=ctx0; nonNull(ctx); ctx=tl(ctx)) {
632 ctxElem = hd(ctx); /* (QConId,VarId) */
633 if (nonNull(cellIsMember(textOf(snd(ctxElem)),tyvarsMentioned)))
634 ctx2 = cons(ctxElem, ctx2);
637 ty = ap(QUAL,pair(ctx2,ty));
639 /* stick the tycon's kind on, if not simply STAR */
640 if (whatIs(tycon(tc).kind) != STAR)
641 ty = pair(POLYTYPE,pair(tycon(tc).kind, ty));
643 ty = tvsToOffsets(line,ty, ktyvars);
645 /* Finally, stick the constructor's type onto it. */
646 thd3(hd(constrs)) = ty;
649 /* Final result is that
650 constrs :: [(ConId,[(Type,Text)],Type)]
651 lists the constructors and their types
652 sels :: [(VarId,Type)]
653 lists the selectors and their types
655 tycon(tc).defn = addGHCConstrs(line,constrs0,sels);
658 fprintf(stderr, "end addGHCDataDecl %s\n",textToStr(t));
663 static List local addGHCConstrs(line,cons,sels)
665 List cons; /* [(ConId,[(Type,Text)],Type)] */
666 List sels; { /* [(VarId,Type)] */
668 Int conNo = 0; /* or maybe 1? */
669 for(cs=cons; nonNull(cs); cs=tl(cs), conNo++) {
670 Name c = addGHCConstr(line,conNo,hd(cs));
673 for(ss=sels; nonNull(ss); ss=tl(ss)) {
674 hd(ss) = addGHCSel(line,hd(ss));
676 return appendOnto(cons,sels);
679 static Name local addGHCSel(line,sel)
681 Pair sel; /* (VarId,Type) */
683 Text t = textOf(fst(sel));
684 Type type = snd(sel);
686 Name n = findName(t);
688 ERRMSG(line) "Repeated definition for selector \"%s\"",
695 name(n).number = SELNAME;
699 /* prepare for finishGHCVar */
701 ghcVarDecls = cons(n,ghcVarDecls);
706 static Name local addGHCConstr(line,conNo,constr)
709 Triple constr; { /* (ConId,[(Type,Text)],Type) */
710 /* ToDo: add rank2 annotation and existential annotation
711 * these affect how constr can be used.
713 Text con = textOf(fst3(constr));
714 Type type = thd3(constr);
715 Int arity = arityFromType(type);
716 Name n = findName(con); /* Allocate constructor fun name */
718 n = newName(con,NIL);
719 } else if (name(n).defn!=PREDEFINED) {
720 ERRMSG(line) "Repeated definition for constructor \"%s\"",
724 name(n).arity = arity; /* Save constructor fun details */
726 name(n).number = cfunNo(conNo);
728 /* prepare for finishGHCCon */
730 ghcConstrDecls = cons(n,ghcConstrDecls);
735 static Void local finishGHCConstr(Name n)
737 Int line = name(n).line;
738 Type ty = name(n).type;
739 setCurrModule(name(n).mod);
741 printf ( "\nbegin finishGHCConstr %s\n", textToStr(name(n).text));
743 name(n).type = conidcellsToTycons(line,ty);
745 printf ( "end finishGHCConstr %s\n", textToStr(name(n).text));
750 Void addGHCNewType(line,ctx0,tycon,tvs,constr)
752 List ctx0; /* [(QConId,VarId)] */
753 Cell tycon; /* ConId | QualConId */
754 List tvs; /* [(VarId,Kind)] */
755 Cell constr; { /* (ConId,Type) */
756 /* ToDo: worry about being given a decl for (->) ?
757 * and worry about qualidents for ()
761 Text t = textOf(tycon);
762 if (nonNull(findTycon(t))) {
763 ERRMSG(line) "Repeated definition of type constructor \"%s\"",
767 Tycon tc = newTycon(t);
768 tycon(tc).line = line;
769 tycon(tc).arity = length(tvs);
770 tycon(tc).what = NEWTYPE;
771 tycon(tc).kind = tvsToKind(tvs);
772 /* can't really do this until I've read in all synonyms */
774 assert(nonNull(constr));
775 if (isNull(constr)) {
776 tycon(tc).defn = NIL;
778 /* constr :: (ConId,Type) */
779 Text con = textOf(fst(constr));
780 Type type = snd(constr);
781 Name n = findName(con); /* Allocate constructor fun name */
783 n = newName(con,NIL);
784 } else if (name(n).defn!=PREDEFINED) {
785 ERRMSG(line) "Repeated definition for constructor \"%s\"",
789 name(n).arity = 1; /* Save constructor fun details */
791 name(n).number = cfunNo(0);
792 name(n).defn = nameId;
793 tycon(tc).defn = singleton(n);
795 /* prepare for finishGHCCon */
796 /* ToDo: we use finishGHCCon instead of finishGHCVar in case
797 * there's any existential quantification in the newtype -
798 * but I don't think that's allowed in newtype constrs.
799 * Still, no harm done by doing it this way...
802 /* make resTy the result type of the constr, T v1 ... vn */
804 for (tmp=tvs; nonNull(tmp); tmp=tl(tmp))
805 resTy = ap(resTy,fst(hd(tmp)));
806 type = fn(type,resTy);
808 type = ap(QUAL,pair(ctx0,type));
810 type = tvsToOffsets(line,type,tvs);
813 ghcConstrDecls = cons(n,ghcConstrDecls);
818 Void addGHCClass(line,ctxt,tc_name,tv,mems0)
820 List ctxt; /* [(QConId, VarId)] */
821 Cell tc_name; /* ConId */
823 List mems0; { /* [(VarId, Type)] */
824 List mems; /* [(VarId, Type)] */
825 List tvsInT; /* [VarId] and then [(VarId,Kind)] */
826 List tvs; /* [(VarId,Kind)] */
827 Text ct = textOf(tc_name);
828 Pair newCtx = pair(tc_name, tv);
830 printf ( "\nbegin addGHCclass %s\n", textToStr(ct) );
832 if (nonNull(findClass(ct))) {
833 ERRMSG(line) "Repeated definition of class \"%s\"",
836 } else if (nonNull(findTycon(ct))) {
837 ERRMSG(line) "\"%s\" used as both class and type constructor",
841 Class nw = newClass(ct);
842 cclass(nw).text = ct;
843 cclass(nw).line = line;
844 cclass(nw).arity = 1;
845 cclass(nw).head = ap(nw,mkOffset(0));
846 cclass(nw).kinds = singleton(STAR); /* absolutely no idea at all */
847 cclass(nw).instances = NIL; /* what the kind should be */
848 cclass(nw).numSupers = length(ctxt);
850 /* Kludge to map the single tyvar in the context to Offset 0.
851 Need to do something better for multiparam type classes.
853 cclass(nw).supers = tvsToOffsets(line,ctxt,
854 singleton(pair(tv,STAR)));
856 for (mems=mems0; nonNull(mems); mems=tl(mems)) {
858 Type memT = snd(mem);
859 Text mnt = textOf(fst(mem));
862 /* Stick the new context on the member type */
863 if (whatIs(memT)==POLYTYPE) internal("addGHCClass");
864 if (whatIs(memT)==QUAL) {
866 pair(cons(newCtx,fst(snd(memT))),snd(snd(memT))));
869 pair(singleton(newCtx),memT));
872 /* Cook up a kind for the type. */
873 tvsInT = nubList(ifTyvarsIn(memT));
875 /* ToDo: maximally bogus */
876 for (tvs=tvsInT; nonNull(tvs); tvs=tl(tvs))
877 hd(tvs) = pair(hd(tvs),STAR);
879 memT = mkPolyType(tvsToKind(tvsInT),memT);
880 memT = tvsToOffsets(line,memT,tvsInT);
882 /* Park the type back on the member */
885 /* Bind code to the member */
889 "Repeated definition for class method \"%s\"",
893 mn = newName(mnt,NIL);
896 cclass(nw).members = mems0;
897 cclass(nw).numMembers = length(mems0);
898 ghcClassDecls = cons(nw,ghcClassDecls);
901 * cclass(nw).dsels = ?;
902 * cclass(nw).dbuild = ?;
903 * cclass(nm).dcon = ?;
904 * cclass(nm).defaults = ?;
908 printf ( "end addGHCclass %s\n", textToStr(ct) );
912 static Void local finishGHCClass(Class nw)
915 Int line = cclass(nw).line;
916 Int ctr = - length(cclass(nw).members);
919 printf ( "\nbegin finishGHCclass %s\n", textToStr(cclass(nw).text) );
922 setCurrModule(cclass(nw).mod);
924 cclass(nw).level = 0; /* ToDo: 1 + max (map level supers) */
925 cclass(nw).head = conidcellsToTycons(line,cclass(nw).head);
926 cclass(nw).supers = conidcellsToTycons(line,cclass(nw).supers);
927 cclass(nw).members = conidcellsToTycons(line,cclass(nw).members);
929 for (mems=cclass(nw).members; nonNull(mems); mems=tl(mems)) {
930 Pair mem = hd(mems); /* (VarId, Type) */
931 Text txt = textOf(fst(mem));
933 Name n = findName(txt);
935 name(n).line = cclass(nw).line;
937 name(n).number = ctr++;
941 printf ( "end finishGHCclass %s\n", textToStr(cclass(nw).text) );
945 Void addGHCInstance (line,ctxt0,cls,var)
947 List ctxt0; /* [(QConId, Type)] */
948 Pair cls; /* (ConId, [Type]) */
949 Text var; { /* Text */
953 printf ( "\nbegin addGHCInstance\n" );
956 /* Make tvs into a list of tyvars with bogus kinds. */
957 tvs = nubList(ifTyvarsIn(snd(cls)));
959 for (tmp = tvs; nonNull(tmp); tmp=tl(tmp)) {
960 hd(tmp) = pair(hd(tmp),STAR);
964 inst(in).line = line;
965 inst(in).implements = NIL;
967 inst(in).specifics = tvsToOffsets(line,ctxt0,tvs);
968 inst(in).numSpecifics = length(ctxt0);
969 inst(in).head = tvsToOffsets(line,cls,tvs);
971 Is this still needed?
973 Name b = newName(inventText(),NIL);
975 name(b).arity = length(ctxt); /* unused? */
976 name(b).number = DFUNNAME;
977 inst(in).builder = b;
978 bindNameToClosure(b, lookupGHCClosure(inst(in).mod,var));
981 ghcInstanceDecls = cons(in, ghcInstanceDecls);
983 printf ( "end addGHCInstance\n" );
987 static Void local finishGHCInstance(Inst in)
989 Int line = inst(in).line;
990 Cell cl = fst(inst(in).head);
993 printf ( "\nbegin finishGHCInstance\n" );
996 setCurrModule(inst(in).mod);
997 c = findClass(textOf(cl));
999 ERRMSG(line) "Unknown class \"%s\" in instance",
1000 textToStr(textOf(cl))
1003 inst(in).head = conidcellsToTycons(line,inst(in).head);
1004 inst(in).specifics = conidcellsToTycons(line,inst(in).specifics);
1005 cclass(c).instances = cons(in,cclass(c).instances);
1007 printf ( "end finishGHCInstance\n" );
1011 /* --------------------------------------------------------------------------
1013 * ------------------------------------------------------------------------*/
1015 /* This is called from the addGHC* functions. It traverses a structure
1016 and converts varidcells, ie, type variables parsed by the interface
1017 parser, into Offsets, which is how Hugs wants to see them internally.
1018 The Offset for a type variable is determined by its place in the list
1019 passed as the second arg; the associated kinds are irrelevant.
1021 static Type local tvsToOffsets(line,type,ktyvars)
1024 List ktyvars; { /* [(VarId|Text,Kind)] */
1025 switch (whatIs(type)) {
1033 return ap( tvsToOffsets(line,fun(type),ktyvars),
1034 tvsToOffsets(line,arg(type),ktyvars) );
1038 tvsToOffsets(line,monotypeOf(type),ktyvars)
1042 return pair(QUAL,pair(tvsToOffsets(line,fst(snd(type)),ktyvars),
1043 tvsToOffsets(line,snd(snd(type)),ktyvars)));
1044 case VARIDCELL: /* Ha! some real work to do! */
1046 Text tv = textOf(type);
1047 for (; nonNull(ktyvars); i++,ktyvars=tl(ktyvars)) {
1048 Cell varid = fst(hd(ktyvars));
1049 Text tt = isVar(varid) ? textOf(varid) : varid;
1050 if (tv == tt) return mkOffset(i);
1052 ERRMSG(line) "Undefined type variable \"%s\"", textToStr(tv)
1057 fprintf(stderr, "tvsToOffsets: unknown stuff %d\n", whatIs(type));
1059 fprintf(stderr,"\n");
1062 assert(0); /* NOTREACHED */
1066 /* This is called from the finishGHC* functions. It traverses a structure
1067 and converts conidcells, ie, type constructors parsed by the interface
1068 parser, into Tycons (or Classes), which is how Hugs wants to see them
1069 internally. Calls to this fn have to be deferred to the second phase
1070 of interface loading (finishGHC* rather than addGHC*) so that all relevant
1071 Tycons or Classes have been loaded into the symbol tables and can be
1074 static Type local conidcellsToTycons(line,type)
1077 switch (whatIs(type)) {
1086 Text m = qmodOf(type);
1087 Text v = qtextOf(type);
1088 Module mod = findModule(m);
1089 printf ( "lookup qualident " ); print(type,100); printf("\n");
1092 "Undefined module in qualified name \"%s\"",
1097 for (t=module(mod).tycons; nonNull(t); t=tl(t))
1098 if (v == tycon(hd(t)).text) return hd(t);
1099 for (t=module(mod).classes; nonNull(t); t=tl(t))
1100 if (v == cclass(hd(t)).text) return hd(t);
1102 "Undefined qualified class or type \"%s\"",
1110 tc = findQualTycon(type);
1111 if (nonNull(tc)) return tc;
1112 cl = findQualClass(type);
1113 if (nonNull(cl)) return cl;
1115 "Undefined class or type constructor \"%s\"",
1121 return ap( conidcellsToTycons(line,fun(type)),
1122 conidcellsToTycons(line,arg(type)) );
1126 conidcellsToTycons(line,monotypeOf(type))
1130 return pair(QUAL,pair(conidcellsToTycons(line,fst(snd(type))),
1131 conidcellsToTycons(line,snd(snd(type)))));
1133 fprintf(stderr, "conidcellsToTycons: unknown stuff %d\n",
1136 fprintf(stderr,"\n");
1139 assert(0); /* NOTREACHED */
1143 /* --------------------------------------------------------------------------
1146 * None of these do lookups or require that lookups have been resolved
1147 * so they can be performed while reading interfaces.
1148 * ------------------------------------------------------------------------*/
1150 static Kinds local tvsToKind(tvs)
1151 List tvs; { /* [(VarId,Kind)] */
1154 for (rs=reverse(tvs); nonNull(rs); rs=tl(rs)) {
1155 r = ap(snd(hd(rs)),r);
1161 static Int local arityInclDictParams ( Type type )
1164 if (isPolyType(type)) type = monotypeOf(type);
1166 if (whatIs(type) == QUAL)
1168 arity += length ( fst(snd(type)) );
1169 type = snd(snd(type));
1171 while (isAp(type) && getHead(type)==typeArrow) {
1178 /* arity of a constructor with this type */
1179 static Int local arityFromType(type)
1182 if (isPolyType(type)) {
1183 type = monotypeOf(type);
1185 if (whatIs(type) == QUAL) {
1186 type = snd(snd(type));
1188 if (whatIs(type) == EXIST) {
1189 type = snd(snd(type));
1191 if (whatIs(type)==RANK2) {
1192 type = snd(snd(type));
1194 while (isAp(type) && getHead(type)==typeArrow) {
1202 static List local ifTyvarsIn(type)
1204 List vs = typeVarsIn(type,NIL,NIL);
1206 for (; nonNull(vs2); vs2=tl(vs2)) {
1208 if (whatIs(v)==VARIDCELL || whatIs(v)==VAROPCELL) {
1209 hd(vs2) = textOf(hd(vs2));
1211 internal("ifTyvarsIn");
1218 /* --------------------------------------------------------------------------
1220 * ------------------------------------------------------------------------*/
1224 static char* local findElfSection ( void* objImage, Elf32_Word sh_type )
1227 char* ehdrC = (char*)objImage;
1228 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1229 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1231 for (i = 0; i < ehdr->e_shnum; i++) {
1232 if (shdr[i].sh_type == sh_type &&
1233 i != ehdr->e_shstrndx) {
1234 ptr = ehdrC + shdr[i].sh_offset;
1242 static Void local resolveReferencesInObjectModule_elf ( Module m,
1245 char symbol[1000]; // ToDo
1249 char* ehdrC = (char*)(module(m).oImage);
1250 Elf32_Ehdr* ehdr = (Elf32_Ehdr*) ehdrC;
1251 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1253 // first find "the" symbol table
1254 //stab = findElfSection ( objImage, SHT_SYMTAB );
1256 // also go find the string table
1257 strtab = findElfSection ( ehdrC, SHT_STRTAB );
1259 if (!stab || !strtab)
1260 internal("resolveReferencesInObjectModule_elf");
1262 for (i = 0; i < ehdr->e_shnum; i++) {
1263 if (shdr[i].sh_type == SHT_REL ) {
1264 Elf32_Rel* rtab = (Elf32_Rel*) (ehdrC + shdr[i].sh_offset);
1265 Int nent = shdr[i].sh_size / sizeof(Elf32_Rel);
1266 Int target_shndx = shdr[i].sh_info;
1267 Int symtab_shndx = shdr[i].sh_link;
1268 stab = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1269 targ = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1272 "relocations for section %d using symtab %d\n",
1273 target_shndx, symtab_shndx );
1274 for (j = 0; j < nent; j++) {
1275 Elf32_Addr offset = rtab[j].r_offset;
1276 Elf32_Word info = rtab[j].r_info;
1278 Elf32_Addr P = ((Elf32_Addr)targ) + offset;
1279 Elf32_Word* pP = (Elf32_Word*)P;
1283 if (verb) fprintf ( stderr, "Rel entry %3d is raw(%6p %6p) ",
1284 j, (void*)offset, (void*)info );
1286 if (verb) fprintf ( stderr, " ZERO\n" );
1289 if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1290 if (verb) fprintf ( stderr, "(noname) ");
1291 /* nameless (local) symbol */
1292 S = (Elf32_Addr)(ehdrC
1293 + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1294 + stab[ELF32_R_SYM(info)].st_value
1296 strcpy ( symbol, "(noname)");
1298 strcpy ( symbol, strtab+stab[ ELF32_R_SYM(info)].st_name );
1299 if (verb) fprintf ( stderr, "`%s' ", symbol );
1300 S = (Elf32_Addr)lookupObjName ( symbol );
1302 if (verb) fprintf ( stderr, "resolves to %p\n", (void*)S );
1304 fprintf ( stderr, "link failure for `%s'\n",
1305 strtab+stab[ ELF32_R_SYM(info)].st_name );
1309 //fprintf ( stderr, "Reloc: P = %p S = %p A = %p\n\n",
1310 // (void*)P, (void*)S, (void*)A );
1311 switch (ELF32_R_TYPE(info)) {
1312 case R_386_32: *pP = S + A; break;
1313 case R_386_PC32: *pP = S + A - P; break;
1314 default: fprintf(stderr,
1315 "unhandled ELF relocation type %d\n",
1316 ELF32_R_TYPE(info));
1323 if (shdr[i].sh_type == SHT_RELA) {
1324 fprintf ( stderr, "RelA style reloc table -- not yet done" );
1331 static Bool local validateOImage_elf ( void* imgV,
1337 int i, j, nent, nstrtab, nsymtabs;
1341 char* ehdrC = (char*)imgV;
1342 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1344 if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
1345 ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
1346 ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
1347 ehdr->e_ident[EI_MAG3] != ELFMAG3) {
1348 if (verb) fprintf ( stderr, "Not an ELF header\n" );
1351 if (verb) fprintf ( stderr, "Is an ELF header\n" );
1353 if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
1354 if (verb) fprintf ( stderr, "Not 32 bit ELF\n" );
1357 if (verb) fprintf ( stderr, "Is 32 bit ELF\n" );
1359 if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {
1360 if (verb) fprintf ( stderr, "Is little-endian\n" );
1362 if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
1363 if (verb) fprintf ( stderr, "Is big-endian\n" );
1365 if (verb) fprintf ( stderr, "Unknown endiannness\n" );
1369 if (ehdr->e_type != ET_REL) {
1370 if (verb) fprintf ( stderr, "Not a relocatable object (.o) file\n" );
1373 if (verb) fprintf ( stderr, "Is a relocatable object (.o) file\n" );
1375 if (verb) fprintf ( stderr, "Architecture is " );
1376 switch (ehdr->e_machine) {
1377 case EM_386: if (verb) fprintf ( stderr, "x86\n" ); break;
1378 case EM_SPARC: if (verb) fprintf ( stderr, "sparc\n" ); break;
1379 default: if (verb) fprintf ( stderr, "unknown\n" ); return FALSE;
1384 "\nSection header table: start %d, n_entries %d, ent_size %d\n",
1385 ehdr->e_shoff, ehdr->e_shnum, ehdr->e_shentsize );
1387 assert (ehdr->e_shentsize == sizeof(Elf32_Shdr));
1389 shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1391 if (ehdr->e_shstrndx == SHN_UNDEF) {
1392 if (verb) fprintf ( stderr, "No section header string table\n" );
1396 if (verb) fprintf ( stderr,"Section header string table is section %d\n",
1398 sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1401 for (i = 0; i < ehdr->e_shnum; i++) {
1402 if (verb) fprintf ( stderr, "%2d: ", i );
1403 if (verb) fprintf ( stderr, "type=%2d ", shdr[i].sh_type );
1404 if (verb) fprintf ( stderr, "size=%4d ", shdr[i].sh_size );
1405 if (verb) fprintf ( stderr, "offs=%4d ", shdr[i].sh_offset );
1406 if (verb) fprintf ( stderr, " (%p .. %p) ",
1407 ehdrC + shdr[i].sh_offset,
1408 ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1);
1410 if (shdr[i].sh_type == SHT_REL && verb) fprintf ( stderr, "Rel " ); else
1411 if (shdr[i].sh_type == SHT_RELA && verb) fprintf ( stderr, "RelA " ); else
1412 if (verb) fprintf ( stderr, " " );
1413 if (sh_strtab && verb) fprintf ( stderr, "sname=%s", sh_strtab + shdr[i].sh_name );
1414 if (verb) fprintf ( stderr, "\n" );
1417 if (verb) fprintf ( stderr, "\n\nString tables\n" );
1420 for (i = 0; i < ehdr->e_shnum; i++) {
1421 if (shdr[i].sh_type == SHT_STRTAB &&
1422 i != ehdr->e_shstrndx) {
1423 if (verb) fprintf ( stderr, " section %d is a normal string table\n", i );
1424 strtab = ehdrC + shdr[i].sh_offset;
1429 if (verb) fprintf ( stderr, "WARNING: no string tables, or too many\n" );
1434 if (verb) fprintf ( stderr, "\n\nSymbol tables\n" );
1435 for (i = 0; i < ehdr->e_shnum; i++) {
1436 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1437 if (verb) fprintf ( stderr, "section %d is a symbol table\n", i );
1439 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1440 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1441 if (verb) fprintf ( stderr, " number of entries is apparently %d (%d rem)\n",
1443 shdr[i].sh_size % sizeof(Elf32_Sym)
1445 if (0 != shdr[i].sh_size % sizeof(Elf32_Sym)) {
1446 if (verb) fprintf ( stderr, "non-integral number of symbol table entries\n");
1449 for (j = 0; j < nent; j++) {
1450 if (verb) fprintf ( stderr, " %2d ", j );
1451 if (verb) fprintf ( stderr, " sec=%-5d size=%-3d val=%-5p ",
1452 (int)stab[j].st_shndx,
1453 (int)stab[j].st_size,
1454 (char*)stab[j].st_value );
1456 if (verb) fprintf ( stderr, "type=" );
1457 switch (ELF32_ST_TYPE(stab[j].st_info)) {
1458 case STT_NOTYPE: if (verb) fprintf ( stderr, "notype " ); break;
1459 case STT_OBJECT: if (verb) fprintf ( stderr, "object " ); break;
1460 case STT_FUNC : if (verb) fprintf ( stderr, "func " ); break;
1461 case STT_SECTION: if (verb) fprintf ( stderr, "section" ); break;
1462 case STT_FILE: if (verb) fprintf ( stderr, "file " ); break;
1463 default: if (verb) fprintf ( stderr, "? " ); break;
1465 if (verb) fprintf ( stderr, " " );
1467 if (verb) fprintf ( stderr, "bind=" );
1468 switch (ELF32_ST_BIND(stab[j].st_info)) {
1469 case STB_LOCAL : if (verb) fprintf ( stderr, "local " ); break;
1470 case STB_GLOBAL: if (verb) fprintf ( stderr, "global" ); break;
1471 case STB_WEAK : if (verb) fprintf ( stderr, "weak " ); break;
1472 default: if (verb) fprintf ( stderr, "? " ); break;
1474 if (verb) fprintf ( stderr, " " );
1476 if (verb) fprintf ( stderr, "name=%s\n", strtab + stab[j].st_name );
1480 if (nsymtabs == 0) {
1481 if (verb) fprintf ( stderr, "Didn't find any symbol tables\n" );
1489 static void readSyms_elf ( Module m )
1494 char* ehdrC = (char*)(module(m).oImage);
1495 Elf32_Ehdr* ehdr = (Elf32_Ehdr*)ehdrC;
1496 char* strtab = findElfSection ( ehdrC, SHT_STRTAB );
1497 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1498 char* sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1500 if (!strtab) internal("readSyms_elf");
1503 for (i = 0; i < ehdr->e_shnum; i++) {
1505 /* make a HugsDLSection entry for relevant sections */
1506 DLSect kind = HUGS_DL_SECTION_OTHER;
1507 if (0==strcmp(".data",sh_strtab+shdr[i].sh_name) ||
1508 0==strcmp(".data1",sh_strtab+shdr[i].sh_name))
1509 kind = HUGS_DL_SECTION_RWDATA;
1510 if (0==strcmp(".text",sh_strtab+shdr[i].sh_name) ||
1511 0==strcmp(".rodata",sh_strtab+shdr[i].sh_name) ||
1512 0==strcmp(".rodata1",sh_strtab+shdr[i].sh_name))
1513 kind = HUGS_DL_SECTION_CODE_OR_RODATA;
1514 if (kind != HUGS_DL_SECTION_OTHER)
1517 ehdrC + shdr[i].sh_offset,
1518 ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1,
1522 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1524 /* copy stuff into this module's object symbol table */
1525 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1526 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1527 for (j = 0; j < nent; j++) {
1528 if ( ( ELF32_ST_BIND(stab[j].st_info)==STB_GLOBAL ||
1529 ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL
1532 ( ELF32_ST_TYPE(stab[j].st_info)==STT_FUNC ||
1533 ELF32_ST_TYPE(stab[j].st_info)==STT_OBJECT )
1535 char* nm = strtab + stab[j].st_name;
1537 + shdr[ stab[j].st_shndx ].sh_offset
1541 /* fprintf(stderr, "addOTabName: %s %s %p\n",
1542 textToStr(module(m).text), nm, ad );
1544 addOTabName ( m, nm, ad );
1552 /* --------------------------------------------------------------------------
1553 * Arch-independent interface to the runtime linker
1554 * ------------------------------------------------------------------------*/
1556 static Bool local validateOImage ( void* img, Int size, Bool verb )
1559 validateOImage_elf ( img, size, verb );
1563 static Void local resolveReferencesInObjectModule ( Module m, Bool verb )
1565 resolveReferencesInObjectModule_elf ( m, verb );
1569 static Void local readSyms ( Module m )
1575 /* --------------------------------------------------------------------------
1576 * General object symbol query stuff
1577 * ------------------------------------------------------------------------*/
1579 /* entirely bogus claims about types of these symbols */
1580 extern int stg_gc_enter_1;
1581 extern int stg_chk_0;
1582 extern int stg_chk_1;
1583 extern int stg_update_PAP;
1584 extern int __ap_2_upd_info;
1585 extern int MainRegTable;
1586 extern int Upd_frame_info;
1590 { "stg_gc_enter_1", &stg_gc_enter_1 },
1591 { "stg_chk_0", &stg_chk_0 },
1592 { "stg_chk_1", &stg_chk_1 },
1593 { "stg_update_PAP", &stg_update_PAP },
1594 { "__ap_2_upd_info", &__ap_2_upd_info },
1595 { "MainRegTable", &MainRegTable },
1596 { "Upd_frame_info", &Upd_frame_info },
1601 void* lookupObjName ( char* nm )
1611 strncpy(nm2,nm,200);
1613 // first see if it's an RTS name
1614 for (k = 0; rtsTab[k].nm; k++)
1615 if (0==strcmp(nm2,rtsTab[k].nm))
1616 return rtsTab[k].ad;
1618 // if not an RTS name, look in the
1619 // relevant module's object symbol table
1620 pp = strchr(nm2, '_');
1621 if (!pp) goto not_found;
1625 if (isNull(m)) goto not_found;
1626 a = lookupOTabName ( m, nm );
1631 "lookupObjName: can't resolve name `%s'\n",
1637 int is_dynamically_loaded_code_or_rodata_ptr ( char* p )
1640 lookupDLSect(p) == HUGS_DL_SECTION_CODE_OR_RODATA;
1644 int is_dynamically_loaded_rwdata_ptr ( char* p )
1647 lookupDLSect(p) == HUGS_DL_SECTION_RWDATA;
1651 int is_not_dynamically_loaded_ptr ( char* p )
1654 lookupDLSect(p) == HUGS_DL_SECTION_OTHER;
1658 /* --------------------------------------------------------------------------
1660 * ------------------------------------------------------------------------*/
1662 Void interface(what)
1669 ghcConstrDecls = NIL;
1670 ghcSynonymDecls = NIL;
1671 ghcClassDecls = NIL;
1672 ghcInstanceDecls = NIL;
1680 mark(ghcConstrDecls);
1681 mark(ghcSynonymDecls);
1682 mark(ghcClassDecls);
1683 mark(ghcInstanceDecls);
1691 /*-------------------------------------------------------------------------*/