diff options
Diffstat (limited to 'src/cmd/gc/export.c')
-rw-r--r-- | src/cmd/gc/export.c | 726 |
1 files changed, 174 insertions, 552 deletions
diff --git a/src/cmd/gc/export.c b/src/cmd/gc/export.c index 0c17ad683..b3d3556de 100644 --- a/src/cmd/gc/export.c +++ b/src/cmd/gc/export.c @@ -5,6 +5,8 @@ #include "go.h" #include "y.tab.h" +void dumpsym(Sym*); + void addexportsym(Sym *s) { @@ -33,28 +35,21 @@ exportsym(Sym *s) addexportsym(s); } -void -makeexportsym(Type *t) -{ - Sym *s; - - if(t->sym == S) { - exportgen++; - snprint(namebuf, sizeof(namebuf), "_e%s_%.3ld", filename, exportgen); - s = lookup(namebuf); - s->lexical = LATYPE; - s->otype = t; - t->sym = s; - } -} void -reexport(Type *t) +dumpprereq(Type *t) { if(t == T) - fatal("reexport: type nil"); - makeexportsym(t); - dumpexporttype(t->sym); + return; + + if(t->printed) + return; + t->printed = 1; + + if(t->sym != S && t->etype != TFIELD && t->sym->name[0] != '_') + dumpsym(t->sym); + dumpprereq(t->type); + dumpprereq(t->down); } void @@ -63,24 +58,21 @@ dumpexportconst(Sym *s) Node *n; Type *t; - if(s->exported != 0) - return; - s->exported = 1; - n = s->oconst; if(n == N || n->op != OLITERAL) fatal("dumpexportconst: oconst nil: %S", s); t = n->type; // may or may not be specified if(t != T) - reexport(t); + dumpprereq(t); - Bprint(bout, "\tconst "); + Bprint(bout, "\t"); if(s->export != 0) - Bprint(bout, "!"); - Bprint(bout, "%lS ", s); + Bprint(bout, "export "); + Bprint(bout, "const %lS ", s); if(t != T) - Bprint(bout, "%lS ", t->sym); + Bprint(bout, "%#T ", t); + Bprint(bout, " = "); switch(n->val.ctype) { default: @@ -108,10 +100,6 @@ dumpexportvar(Sym *s) Node *n; Type *t; - if(s->exported != 0) - return; - s->exported = 1; - n = s->oname; if(n == N || n->type == T) { yyerror("variable exported but not defined: %S", s); @@ -119,148 +107,36 @@ dumpexportvar(Sym *s) } t = n->type; - reexport(t); + dumpprereq(t); - Bprint(bout, "\tvar "); + Bprint(bout, "\t"); if(s->export != 0) - Bprint(bout, "!"); - Bprint(bout, "%lS %lS\n", s, t->sym); + Bprint(bout, "export "); + if(t->etype == TFUNC) + Bprint(bout, "func "); + else + Bprint(bout, "var "); + Bprint(bout, "%lS %#T\n", s, t); } void dumpexporttype(Sym *s) { - Type *t, *f; - Sym *ts; - int et, forw; + Bprint(bout, "\t"); + if(s->export != 0) + Bprint(bout, "export "); + Bprint(bout, "type %lS %l#T\n", s, s->otype); +} + +void +dumpsym(Sym *s) +{ + Type *f; if(s->exported != 0) return; s->exported = 1; - t = s->otype; - if(t == T) { - yyerror("type exported but not defined: %S", s); - return; - } - - if(t->sym != s) - fatal("dumpexporttype: cross reference: %S", s); - - et = t->etype; - switch(et) { - default: - if(et < 0 || et >= nelem(types) || types[et] == T) - fatal("dumpexporttype: basic type: %S %E", s, et); - /* type 5 */ - Bprint(bout, "\ttype "); - if(s->export != 0) - Bprint(bout, "!"); - Bprint(bout, "%lS %d\n", s, et); - break; - - case TARRAY: - reexport(t->type); - - /* type 2 */ - Bprint(bout, "\ttype "); - if(s->export != 0) - Bprint(bout, "!"); - if(t->bound >= 0) - Bprint(bout, "%lS [%lud] %lS\n", s, t->bound, t->type->sym); - else - Bprint(bout, "%lS [] %lS\n", s, t->type->sym); - break; - - case TPTR32: - case TPTR64: - if(t->type == T) - fatal("dumpexporttype: ptr %S", s); - if(t->type->etype == TFORW) { - yyerror("export of a undefined forward reference: %S", s); - break; - } - makeexportsym(t->type); - ts = t->type->sym; - if(ts->exported == 0) - addexportsym(ts); - - /* type 6 */ - Bprint(bout, "\ttype "); - if(s->export != 0) - Bprint(bout, "!"); - Bprint(bout, "%lS *%lS\n", s, ts); - - break; - - case TFUNC: - for(f=t->type; f!=T; f=f->down) { - if(f->etype != TSTRUCT) - fatal("dumpexporttype: funct not field: %T", f); - reexport(f); - } - - /* type 3 */ - Bprint(bout, "\ttype "); - if(s->export != 0) - Bprint(bout, "!"); - Bprint(bout, "%lS (", s); - for(f=t->type; f!=T; f=f->down) { - if(f != t->type) - Bprint(bout, " "); - Bprint(bout, "%lS", f->sym); - } - Bprint(bout, ")\n"); - break; - - case TSTRUCT: - case TINTER: - for(f=t->type; f!=T; f=f->down) { - if(f->etype != TFIELD) - fatal("dumpexporttype: funct not field: %lT", f); - reexport(f->type); - } - - /* type 4 */ - Bprint(bout, "\ttype "); - if(s->export) - Bprint(bout, "!"); - Bprint(bout, "%lS %c", s, (et==TSTRUCT)? '{': '<'); - for(f=t->type; f!=T; f=f->down) { - ts = f->type->sym; - if(f != t->type) - Bprint(bout, " "); - Bprint(bout, "%s %lS", f->sym->name, ts); - } - Bprint(bout, "%c\n", (et==TSTRUCT)? '}': '>'); - break; - - case TMAP: - reexport(t->type); - reexport(t->down); - - /* type 1 */ - Bprint(bout, "\ttype "); - if(s->export != 0) - Bprint(bout, "!"); - Bprint(bout, "%lS [%lS] %lS\n", s, t->down->sym, t->type->sym); - break; - - case TCHAN: - reexport(t->type); - - /* type 8 */ - Bprint(bout, "\ttype "); - if(s->export != 0) - Bprint(bout, "!"); - Bprint(bout, "%lS %d %lS\n", s, t->chan, t->type->sym); - break; - } -} - -void -dumpe(Sym *s) -{ switch(s->lexical) { default: yyerror("unknown export symbol: %S", s); @@ -270,506 +146,252 @@ dumpe(Sym *s) break; case LATYPE: case LBASETYPE: -//print("TYPE %S\n", s); dumpexporttype(s); + for(f=s->otype->method; f!=T; f=f->down) { + dumpprereq(f); + Bprint(bout, "\tfunc (%#T) %hS %#T\n", + f->type->type->type, f->sym, f->type); + } break; case LNAME: -//print("VAR %S\n", s); dumpexportvar(s); break; case LACONST: -//print("CONST %S\n", s); dumpexportconst(s); break; } } void -dumpm(Sym *s) -{ - Type *t, *f; - Dcl *back, *d; - - switch(s->lexical) { - default: - return; - - case LATYPE: - case LBASETYPE: - break; - } - - t = s->otype; - if(t == T) { - yyerror("type exported but not defined: %S", s); - return; - } - - for(f=t->method; f!=T; f=f->down) { - back = exportlist->back; - - if(f->etype != TFIELD) - fatal("dumpexporttype: method not field: %lT", f); - reexport(f->type); - Bprint(bout, "\tfunc %S %lS\n", f->sym, f->type->sym); - - // redo first pass on new entries - for(d=back; d!=D; d=d->forw) { - lineno = d->lineno; - dumpe(d->dsym); - } - } -} - -void dumpexport(void) { Dcl *d; int32 lno; + char *pkg; + exporting = 1; lno = lineno; Bprint(bout, " import\n"); - Bprint(bout, " ((\n"); + Bprint(bout, " $$\n"); Bprint(bout, " package %s\n", package); + pkg = package; + package = "$nopkg"; - // first pass dump vars/types depth first for(d=exportlist->forw; d!=D; d=d->forw) { lineno = d->lineno; - dumpe(d->dsym); + dumpsym(d->dsym); } - // second pass dump methods - for(d=exportlist->forw; d!=D; d=d->forw) { - lineno = d->lineno; - dumpm(d->dsym); - } + package = pkg; - Bprint(bout, " ))\n"); + Bprint(bout, "\n$$\n"); lineno = lno; + exporting = 0; } /* - * ******* import ******* + * import */ -void -checkimports(void) +/* + * look up and maybe declare pkg.name, which should match lexical + */ +Sym* +pkgsym(char *name, char *pkg, int lexical) { Sym *s; - Type *t, *t1; - uint32 h; - int et; - -return; - - for(h=0; h<NHASH; h++) - for(s = hash[h]; s != S; s = s->link) { - t = s->otype; - if(t == T) - continue; - - et = t->etype; - switch(t->etype) { - case TFORW: - print("ci-1: %S %lT\n", s, t); - break; - case TPTR32: - case TPTR64: - if(t->type == T) { - print("ci-2: %S %lT\n", s, t); - break; - } - - t1 = t->type; - if(t1 == T) { - print("ci-3: %S %lT\n", s, t1); - break; - } - - et = t1->etype; - if(et == TFORW) { - print("%L: ci-4: %S %lT\n", lineno, s, t); - break; - } - break; - } + s = pkglookup(name, pkg); + switch(lexical) { + case LATYPE: + if(s->oname) + yyerror("%s.%s is not a type", name, pkg); + break; + case LNAME: + if(s->otype) + yyerror("%s.%s is not a name", name, pkg); + break; } + s->lexical = lexical; + return s; } -void -renamepkg(Node *n) -{ - if(n->psym == pkgimportname) - if(pkgmyname != S) - n->psym = pkgmyname; -} - +/* + * return the sym for ss, which should match lexical + */ Sym* -getimportsym(Node *ss) +importsym(Node *ss, int lexical) { - char *pkg; Sym *s; + renamepkg(ss); + if(ss->op != OIMPORT) - fatal("getimportsym: oops1 %N", ss); + fatal("importsym: oops1 %N", ss); - pkg = ss->psym->name; - s = pkglookup(ss->sym->name, pkg); + s = pkgsym(ss->sym->name, ss->psym->name, lexical); - /* botch - need some diagnostic checking for the following assignment */ + /* TODO botch - need some diagnostic checking for the following assignment */ s->opackage = ss->osym->name; return s; } -Type* -importlooktype(Node *n) -{ - Sym *s; - - s = getimportsym(n); - if(s->otype == T) - fatal("importlooktype: oops2 %S", s); - return s->otype; -} - -Type** -importstotype(Node *fl, Type **t, Type *uber) -{ - Type *f; - Iter save; - Node *n; - - n = listfirst(&save, &fl); - -loop: - if(n == N) { - *t = T; - return t; - } - f = typ(TFIELD); - f->type = importlooktype(n); - - if(n->fsym != S) { - f->nname = newname(n->fsym); - } else { - vargen++; - snprint(namebuf, sizeof(namebuf), "_m%.3ld", vargen); - f->nname = newname(lookup(namebuf)); - } - f->sym = f->nname->sym; - - *t = f; - t = &f->down; - - n = listnext(&save); - goto loop; -} - -int -importcount(Type *t) -{ - int i; - Type *f; - - if(t == T || t->etype != TSTRUCT) - fatal("importcount: not a struct: %N", t); - - i = 0; - for(f=t->type; f!=T; f=f->down) - i = i+1; - return i; -} - -void -importfuncnam(Type *t) -{ - Node *n; - Type *t1; - - if(t->etype != TFUNC) - fatal("importfuncnam: not func %T", t); - - if(t->thistuple > 0) { - t1 = t->type; - if(t1->sym == S) - fatal("importfuncnam: no this"); - n = newname(t1->sym); - vargen++; - n->vargen = vargen; - t1->nname = n; - } - if(t->outtuple > 0) { - t1 = t->type->down; - if(t1->sym == S) - fatal("importfuncnam: no output"); - n = newname(t1->sym); - vargen++; - n->vargen = vargen; - t1->nname = n; - } - if(t->intuple > 0) { - t1 = t->type->down->down; - if(t1->sym == S) - fatal("importfuncnam: no input"); - n = newname(t1->sym); - vargen++; - n->vargen = vargen; - t1->nname = n; - } -} - -void -importaddtyp(Node *ss, Type *t) -{ - Sym *s; - - s = getimportsym(ss); - if(s->otype != T) { - // here we should try to discover if - // the new type is the same as the old type - if(eqtype(t, s->otype, 0)) - return; - if(isptrto(t, TFORW)) { - return; // hard part - } - warn("redeclare import %S from %lT to %lT", - s, s->otype, t); - return; - } - addtyp(newtype(s), t, PEXTERN); -} - /* - * LCONST importsym LITERAL - * untyped constant + * return the type pkg.name, forward declaring if needed */ -void -doimportc1(Node *ss, Val *v) +Type* +pkgtype(char *name, char *pkg) { - Node *n; Sym *s; + Type *t; - n = nod(OLITERAL, N, N); - n->val = *v; - - s = getimportsym(ss); - if(s->oconst == N) { - // botch sould ask if already declared the same - dodclconst(newname(s), n); + // botch + // s = pkgsym(name, pkg, LATYPE); + Node *n; + n = nod(OIMPORT, N, N); + n->sym = lookup(name); + n->psym = lookup(pkg); + n->osym = n->psym; + renamepkg(n); + s = importsym(n, LATYPE); + + if(s->otype == T) { + t = typ(TFORW); + t->sym = s; + s->otype = t; } + return s->otype; } -/* - * LCONST importsym importsym LITERAL - * typed constant - */ void -doimportc2(Node *ss, Node *st, Val *v) +importconst(int export, Node *ss, Type *t, Val *v) { Node *n; - Type *t; Sym *s; n = nod(OLITERAL, N, N); n->val = *v; - - t = importlooktype(st); n->type = t; - s = getimportsym(ss); - if(s->oconst == N) { - // botch sould ask if already declared the same - dodclconst(newname(s), n); + s = importsym(ss, LNAME); + if(s->oconst != N) { + // TODO: check if already the same. + return; } -} -/* - * LVAR importsym importsym - * variable - */ -void -doimportv1(Node *ss, Node *st) -{ - Type *t; - Sym *s; + dodclconst(newname(s), n); - t = importlooktype(st); - s = getimportsym(ss); - if(s->oname == N || !eqtype(t, s->oname->type, 0)) { - addvar(newname(s), t, dclcontext); - } + if(debug['e']) + print("import const %S\n", s); } -/* - * LTYPE importsym [ importsym ] importsym - * array type - */ void -doimport1(Node *ss, Node *si, Node *st) +importvar(int export, Node *ss, Type *t) { - Type *t; Sym *s; - t = typ(TMAP); - s = pkglookup(si->sym->name, si->psym->name); - t->down = s->otype; - s = pkglookup(st->sym->name, st->psym->name); - t->type = s->otype; + s = importsym(ss, LNAME); + if(s->oname != N) { + if(eqtype(t, s->oname->type, 0)) + return; + warn("redeclare import var %S from %T to %T", + s, s->oname->type, t); + } + addvar(newname(s), t, PEXTERN); - importaddtyp(ss, t); + if(debug['e']) + print("import var %S %lT\n", s, t); } -/* - * LTYPE importsym [ LLITERAL ] importsym - * array type - */ void -doimport2(Node *ss, Val *b, Node *st) +importtype(int export, Node *ss, Type *t) { - Type *t; Sym *s; - t = typ(TARRAY); - t->bound = -1; - if(b != nil) - t->bound = mpgetfix(b->u.xval); - s = pkglookup(st->sym->name, st->psym->name); - t->type = s->otype; + s = importsym(ss, LATYPE); + if(s->otype != T) { + if(eqtype(t, s->otype, 0)) + return; + if(s->otype->etype != TFORW) { + warn("redeclare import type %S from %T to %T", + s, s->otype, t); + s->otype = typ(0); + } + } + if(s->otype == T) + s->otype = typ(0); + *s->otype = *t; + s->otype->sym = s; - importaddtyp(ss, t); + if(debug['e']) + print("import type %S %lT\n", s, t); } -/* - * LTYPE importsym '(' importsym_list ')' - * function/method type - */ void -doimport3(Node *ss, Node *n) +importmethod(Sym *s, Type *t) { - Type *t; - - t = typ(TFUNC); - - t->type = importlooktype(n->left); - t->type->down = importlooktype(n->right->left); - t->type->down->down = importlooktype(n->right->right); - - t->thistuple = importcount(t->type); - t->outtuple = importcount(t->type->down); - t->intuple = importcount(t->type->down->down); dowidth(t); - importfuncnam(t); - - importaddtyp(ss, t); + addmethod(newname(s), t, 0); } /* - * LTYPE importsym '{' importsym_list '}' - * structure type + * ******* import ******* */ -void -doimport4(Node *ss, Node *n) -{ - Type *t; - - t = typ(TSTRUCT); - importstotype(n, &t->type, t); - dowidth(t); - importaddtyp(ss, t); -} - -/* - * LTYPE importsym LLITERAL - * basic type - */ void -doimport5(Node *ss, Val *v) +checkimports(void) { + Sym *s; + Type *t, *t1; + uint32 h; int et; - Type *t; - - et = mpgetfix(v->u.xval); - if(et <= 0 || et >= nelem(types) || types[et] == T) - fatal("doimport5: bad type index: %E", et); - t = typ(et); - t->sym = S; - - importaddtyp(ss, t); -} - -/* - * LTYPE importsym * importsym - * pointer type - */ -void -doimport6(Node *ss, Node *st) -{ - Type *t; - Sym *s; +return; - s = pkglookup(st->sym->name, st->psym->name); - t = s->otype; - if(t == T) - t = forwdcl(s); - else - t = ptrto(t); + for(h=0; h<NHASH; h++) + for(s = hash[h]; s != S; s = s->link) { + t = s->otype; + if(t == T) + continue; - importaddtyp(ss, t); -} + et = t->etype; + switch(t->etype) { + case TFORW: + print("ci-1: %S %lT\n", s, t); + break; -/* - * LTYPE importsym '<' importsym '>' - * interface type - */ -void -doimport7(Node *ss, Node *n) -{ - Type *t; + case TPTR32: + case TPTR64: + if(t->type == T) { + print("ci-2: %S %lT\n", s, t); + break; + } - t = typ(TINTER); - importstotype(n, &t->type, t); - dowidth(t); + t1 = t->type; + if(t1 == T) { + print("ci-3: %S %lT\n", s, t1); + break; + } - importaddtyp(ss, t); + et = t1->etype; + if(et == TFORW) { + print("%L: ci-4: %S %lT\n", lineno, s, t); + break; + } + break; + } + } } -/* - * LTYPE importsym chdir importsym - * interface type - */ -void -doimport8(Node *ss, Val *v, Node *st) -{ - Type *t; - Sym *s; - int dir; - - s = pkglookup(st->sym->name, st->psym->name); - dir = mpgetfix(v->u.xval); - t = typ(TCHAN); - s = pkglookup(st->sym->name, st->psym->name); - t->type = s->otype; - t->chan = dir; - importaddtyp(ss, t); -} - -/* - * LFUNC importsym sym - * method type - */ void -doimport9(Sym *sf, Node *ss) +renamepkg(Node *n) { - Sym *sfun; - - sfun = getimportsym(ss); - addmethod(newname(sf), sfun->otype, 0); + if(n->psym == pkgimportname) + if(pkgmyname != S) + n->psym = pkgmyname; } |